/[MITgcm]/MITgcm/pkg/grdchk/grdchk_main.F
ViewVC logotype

Annotation of /MITgcm/pkg/grdchk/grdchk_main.F

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.17 - (hide annotations) (download)
Fri May 12 02:17:03 2006 UTC (18 years, 1 month ago) by heimbach
Branch: MAIN
CVS Tags: checkpoint58f_post, checkpoint58m_post, checkpoint58o_post, checkpoint58p_post, checkpoint58q_post, checkpoint58e_post, checkpoint58n_post, checkpoint58k_post, checkpoint58l_post, checkpoint58g_post, checkpoint58h_post, checkpoint58j_post, checkpoint58i_post
Changes since 1.16: +3 -2 lines
o Adding diffkr, kapgm to gradient check list
o Fix k-loop problem

1 edhill 1.10 C
2 heimbach 1.17 C $Header: /u/gcmpack/MITgcm/pkg/grdchk/grdchk_main.F,v 1.16 2005/07/28 13:54:36 heimbach Exp $
3 heimbach 1.11 C $Name: $
4 heimbach 1.2
5 edhill 1.10 #include "AD_CONFIG.h"
6 heimbach 1.2 #include "CPP_OPTIONS.h"
7    
8 heimbach 1.3 CBOI
9     C
10     C !TITLE: GRADIENT CHECK
11     C !AUTHORS: mitgcm developers ( support@mitgcm.org )
12     C !AFFILIATION: Massachussetts Institute of Technology
13     C !DATE:
14     C !INTRODUCTION: gradient check package
15     c \bv
16     c Compare the gradients calculated by the adjoint model with
17     c finite difference approximations.
18     c
19     C !CALLING SEQUENCE:
20     c
21     c the_model_main
22     c |
23     c |-- ctrl_unpack
24     c |-- adthe_main_loop - unperturbed cost function and
25     c |-- ctrl_pack adjoint gradient are computed here
26     c |
27     c |-- grdchk_main
28     c |
29     c |-- grdchk_init
30     c |-- do icomp=... - loop over control vector elements
31     c |
32     c |-- grdchk_loc - determine location of icomp on grid
33     c |
34     c |-- grdchk_getxx - get control vector component from file
35     c | perturb it and write back to file
36     c |-- grdchk_getadxx - get gradient component calculated
37     c | via adjoint
38     c |-- the_main_loop - forward run and cost evaluation
39     c | with perturbed control vector element
40     c |-- calculate ratio of adj. vs. finite difference gradient
41     c |
42     c |-- grdchk_setxx - Reset control vector element
43     c |
44     c |-- grdchk_print - print results
45     c \ev
46     CEOI
47    
48     CBOP
49     C !ROUTINE: grdchk_main
50     C !INTERFACE:
51     subroutine grdchk_main( mythid )
52 heimbach 1.2
53 heimbach 1.3 C !DESCRIPTION: \bv
54 heimbach 1.2 c ==================================================================
55     c SUBROUTINE grdchk_main
56     c ==================================================================
57     c o Compare the gradients calculated by the adjoint model with
58     c finite difference approximations.
59     c started: Christian Eckert eckert@mit.edu 24-Feb-2000
60 heimbach 1.4 c continued&finished: heimbach@mit.edu: 13-Jun-2001
61     c changed: mlosch@ocean.mit.edu: 09-May-2002
62     c - added centered difference vs. 1-sided difference option
63     c - improved output format for readability
64     c - added control variable hFacC
65 heimbach 1.7 c heimbach@mit.edu 24-Feb-2003
66     c - added tangent linear gradient checks
67     c - fixes for multiproc. gradient checks
68     c - added more control variables
69 heimbach 1.4 c
70 heimbach 1.2 c ==================================================================
71     c SUBROUTINE grdchk_main
72     c ==================================================================
73 heimbach 1.3 C \ev
74 heimbach 1.2
75 heimbach 1.3 C !USES:
76 heimbach 1.2 implicit none
77    
78     c == global variables ==
79     #include "SIZE.h"
80     #include "EEPARAMS.h"
81     #include "PARAMS.h"
82     #include "grdchk.h"
83     #include "cost.h"
84 heimbach 1.9 #ifdef ALLOW_TANGENTLINEAR_RUN
85     #include "g_cost.h"
86     #endif
87 heimbach 1.2
88 heimbach 1.3 C !INPUT/OUTPUT PARAMETERS:
89 heimbach 1.2 c == routine arguments ==
90     integer mythid
91    
92 heimbach 1.11 #ifdef ALLOW_GRDCHK
93 heimbach 1.3 C !LOCAL VARIABLES:
94 heimbach 1.2 c == local variables ==
95     integer myiter
96     _RL mytime
97     integer bi, itlo, ithi
98     integer bj, jtlo, jthi
99     integer i, imin, imax
100     integer j, jmin, jmax
101     integer k
102    
103     integer icomp
104     integer ichknum
105     integer icvrec
106     integer jtile
107     integer itile
108     integer layer
109 heimbach 1.8 integer obcspos
110 heimbach 1.2 integer itilepos
111     integer jtilepos
112     integer itest
113     integer ierr
114     integer ierr_grdchk
115     _RL gfd
116     _RL fcref
117 heimbach 1.4 _RL fcpertplus, fcpertminus
118 heimbach 1.6 _RL ratio_ad
119     _RL ratio_ftl
120 heimbach 1.2 _RL xxmemo_ref
121     _RL xxmemo_pert
122     _RL adxxmemo
123 heimbach 1.6 _RL ftlxxmemo
124     _RL localEps
125     _RL grdchk_epsfac
126    
127 heimbach 1.7 _RL tmpplot1(1-olx:snx+olx,1-oly:sny+oly,nr,nsx,nsy)
128     _RL tmpplot2(1-olx:snx+olx,1-oly:sny+oly,nr,nsx,nsy)
129     _RL tmpplot3(1-olx:snx+olx,1-oly:sny+oly,nr,nsx,nsy)
130    
131 heimbach 1.12 CHARACTER*(MAX_LEN_MBUF) msgBuf
132    
133 heimbach 1.2 c == end of interface ==
134 heimbach 1.3 CEOP
135 heimbach 1.2
136     c-- Set the loop ranges.
137     jtlo = mybylo(mythid)
138     jthi = mybyhi(mythid)
139     itlo = mybxlo(mythid)
140     ithi = mybxhi(mythid)
141     jmin = 1
142     jmax = sny
143     imin = 1
144     imax = snx
145    
146 heimbach 1.16 print *, 'ph-check entering grdchk_main '
147    
148 heimbach 1.2 c-- initialise variables
149     call grdchk_init( mythid )
150    
151     c-- Compute the adjoint models' gradients.
152     c-- Compute the unperturbed cost function.
153 heimbach 1.7 cph Gradient via adjoint has already been computed,
154     cph and so has unperturbed cost function,
155     cph assuming all xx_ fields are initialised to zero.
156 heimbach 1.2
157 heimbach 1.9 ierr_grdchk = 0
158     cphadmtlm(
159 heimbach 1.2 fcref = fc
160 heimbach 1.15 cphadmtlm fcref = objf_state_final(45,4,1,1,1)
161 heimbach 1.9 cphadmtlm)
162    
163     print *, 'ph-check fcref = ', fcref
164 heimbach 1.2
165     do bj = jtlo, jthi
166     do bi = itlo, ithi
167     do k = 1, nr
168     do j = jmin, jmax
169     do i = imin, imax
170     tmpplot1(i,j,k,bi,bj) = 0. _d 0
171     tmpplot2(i,j,k,bi,bj) = 0. _d 0
172 heimbach 1.6 tmpplot3(i,j,k,bi,bj) = 0. _d 0
173 heimbach 1.2 end do
174     end do
175     end do
176     end do
177     end do
178    
179 heimbach 1.4 if ( useCentralDiff ) then
180     grdchk_epsfac = 2. _d 0
181     else
182     grdchk_epsfac = 1. _d 0
183     end if
184    
185 heimbach 1.12 print *, 'grad-res -------------------------------'
186 heimbach 1.7 print ('(2a)'),
187 heimbach 1.12 & ' grad-res proc # i j k fc ref',
188 heimbach 1.7 & ' fc + eps fc - eps'
189     #ifdef ALLOW_TANGENTLINEAR_RUN
190     print ('(2a)'),
191 heimbach 1.12 & ' grad-res proc # i j k tlm grad',
192 heimbach 1.7 & ' fd grad 1 - fd/tlm'
193     #else
194     print ('(2a)'),
195 heimbach 1.12 & ' grad-res proc # i j k adj grad',
196 heimbach 1.7 & ' fd grad 1 - fd/adj'
197     #endif
198    
199 heimbach 1.2 c-- Compute the finite difference approximations.
200     c-- Cycle through all processes doing NINT(nend-nbeg+1)/nstep
201     c-- gradient checks.
202 heimbach 1.14
203 heimbach 1.17 if ( nbeg .EQ. 0 )
204     & call grdchk_get_position( mythid )
205 heimbach 1.2
206 heimbach 1.7 do icomp = nbeg, nend, nstep
207 heimbach 1.2
208 heimbach 1.7 ichknum = (icomp - nbeg)/nstep + 1
209 heimbach 1.2
210 heimbach 1.7 if (ichknum .le. maxgrdchecks ) then
211 heimbach 1.2
212 heimbach 1.7 c-- Determine the location of icomp on the grid.
213     if ( myProcId .EQ. grdchkwhichproc ) then
214     call grdchk_loc( icomp, ichknum,
215 heimbach 1.8 & icvrec, itile, jtile, layer, obcspos,
216 heimbach 1.7 & itilepos, jtilepos, itest, ierr,
217     & mythid )
218     endif
219     _BARRIER
220 heimbach 1.2
221 heimbach 1.6 c******************************************************
222     c-- (A): get gradient component calculated via adjoint
223     c******************************************************
224 heimbach 1.7
225     c-- get gradient component calculated via adjoint
226     if ( myProcId .EQ. grdchkwhichproc .AND.
227     & ierr .EQ. 0 ) then
228     call grdchk_getadxx( icvrec,
229     & itile, jtile, layer,
230     & itilepos, jtilepos,
231     & adxxmemo, mythid )
232     endif
233     _BARRIER
234 heimbach 1.4
235 heimbach 1.6 #ifdef ALLOW_TANGENTLINEAR_RUN
236     c******************************************************
237     c-- (B): Get gradient component g_fc from tangent linear run:
238     c******************************************************
239     c--
240     c-- 1. perturb control vector component: xx(i)=1.
241    
242 heimbach 1.7 if ( myProcId .EQ. grdchkwhichproc .AND.
243     & ierr .EQ. 0 ) then
244     localEps = 1. _d 0
245     call grdchk_getxx( icvrec, TANGENT_SIMULATION,
246     & itile, jtile, layer,
247     & itilepos, jtilepos,
248     & xxmemo_ref, xxmemo_pert, localEps,
249     & mythid )
250     endif
251     _BARRIER
252 heimbach 1.6
253     c--
254     c-- 2. perform tangent linear run
255 heimbach 1.7 mytime = starttime
256     myiter = niter0
257 heimbach 1.9 cphadmtlm(
258 heimbach 1.7 g_fc = 0.
259 heimbach 1.9 cphadmtlm do j=1,sny
260     cphadmtlm do i=1,snx
261 heimbach 1.15 cphadmtlm g_objf_state_final(i,j,1,1,1) = 0.
262     cphadmtlm g_objf_state_final(i,j,1,1,2) = 0.
263 heimbach 1.9 cphadmtlm enddo
264     cphadmtlm enddo
265     cphadmtlm)
266 heimbach 1.7 call g_the_main_loop( mytime, myiter, mythid )
267 heimbach 1.9 cphadmtlm(
268 heimbach 1.7 ftlxxmemo = g_fc
269 heimbach 1.15 cphadmtlm ftlxxmemo = g_objf_state_final(45,4,1,1,1)
270 heimbach 1.9 cphadmtlm)
271 heimbach 1.7 _BARRIER
272 heimbach 1.6 c--
273     c-- 3. reset control vector
274 heimbach 1.7 if ( myProcId .EQ. grdchkwhichproc .AND.
275     & ierr .EQ. 0 ) then
276     call grdchk_setxx( icvrec, TANGENT_SIMULATION,
277     & itile, jtile, layer,
278     & itilepos, jtilepos,
279     & xxmemo_ref, mythid )
280     endif
281     _BARRIER
282    
283     #endif /* ALLOW_TANGENTLINEAR_RUN */
284    
285 heimbach 1.6
286     c******************************************************
287     c-- (C): Get gradient via finite difference perturbation
288     c******************************************************
289    
290 heimbach 1.2 c-- get control vector component from file
291 heimbach 1.7 c-- perturb it and write back to file
292 heimbach 1.6 c-- positive perturbation
293 heimbach 1.7 localEps = abs(grdchk_eps)
294     if ( myProcId .EQ. grdchkwhichproc .AND.
295     & ierr .EQ. 0 ) then
296     call grdchk_getxx( icvrec, FORWARD_SIMULATION,
297     & itile, jtile, layer,
298     & itilepos, jtilepos,
299     & xxmemo_ref, xxmemo_pert, localEps,
300     & mythid )
301     endif
302     _BARRIER
303 heimbach 1.2
304 heimbach 1.4 c-- forward run with perturbed control vector
305 heimbach 1.7 mytime = starttime
306     myiter = niter0
307     call the_main_loop( mytime, myiter, mythid )
308 heimbach 1.9 cphadmtlm(
309 heimbach 1.7 fcpertplus = fc
310 heimbach 1.15 cphadmtlm fcpertplus = objf_state_final(45,4,1,1,1)
311 heimbach 1.9 cphadmtlm)
312 heimbach 1.13 print *, 'ph-check fcpertplus = ', fcpertplus
313 heimbach 1.7 _BARRIER
314 heimbach 1.4
315     c-- Reset control vector.
316 heimbach 1.7 if ( myProcId .EQ. grdchkwhichproc .AND.
317     & ierr .EQ. 0 ) then
318     call grdchk_setxx( icvrec, FORWARD_SIMULATION,
319     & itile, jtile, layer,
320     & itilepos, jtilepos,
321     & xxmemo_ref, mythid )
322     endif
323     _BARRIER
324 heimbach 1.2
325 heimbach 1.7 fcpertminus = fcref
326 heimbach 1.13 print *, 'ph-check fcpertminus = ', fcpertminus
327 heimbach 1.4
328 heimbach 1.7 if ( useCentralDiff ) then
329 heimbach 1.4
330 heimbach 1.6 c-- get control vector component from file
331 heimbach 1.7 c-- perturb it and write back to file
332 heimbach 1.4 c-- repeat the proceedure for a negative perturbation
333 heimbach 1.7 if ( myProcId .EQ. grdchkwhichproc .AND.
334     & ierr .EQ. 0 ) then
335     localEps = - abs(grdchk_eps)
336     call grdchk_getxx( icvrec, FORWARD_SIMULATION,
337     & itile, jtile, layer,
338     & itilepos, jtilepos,
339     & xxmemo_ref, xxmemo_pert, localEps,
340     & mythid )
341     endif
342     _BARRIER
343 heimbach 1.4
344 heimbach 1.2 c-- forward run with perturbed control vector
345 heimbach 1.7 mytime = starttime
346     myiter = niter0
347     call the_main_loop( mytime, myiter, mythid )
348     _BARRIER
349     fcpertminus = fc
350 heimbach 1.2
351 heimbach 1.4 c-- Reset control vector.
352 heimbach 1.7 if ( myProcId .EQ. grdchkwhichproc .AND.
353     & ierr .EQ. 0 ) then
354     call grdchk_setxx( icvrec, FORWARD_SIMULATION,
355     & itile, jtile, layer,
356     & itilepos, jtilepos,
357     & xxmemo_ref, mythid )
358     endif
359     _BARRIER
360    
361     c-- end of if useCentralDiff ...
362     end if
363 heimbach 1.4
364 heimbach 1.6 c******************************************************
365     c-- (D): calculate relative differences between gradients
366     c******************************************************
367    
368 heimbach 1.7 if ( myProcId .EQ. grdchkwhichproc .AND.
369     & ierr .EQ. 0 ) then
370 heimbach 1.2
371 heimbach 1.7 if ( grdchk_eps .eq. 0. ) then
372     gfd = (fcpertplus-fcpertminus)
373     else
374     gfd = (fcpertplus-fcpertminus)
375     & /(grdchk_epsfac*grdchk_eps)
376     endif
377 heimbach 1.2
378 heimbach 1.7 if ( adxxmemo .eq. 0. ) then
379     ratio_ad = abs( adxxmemo - gfd )
380     else
381     ratio_ad = 1. - gfd/adxxmemo
382     endif
383    
384     if ( ftlxxmemo .eq. 0. ) then
385     ratio_ftl = abs( ftlxxmemo - gfd )
386 heimbach 1.2 else
387 heimbach 1.7 ratio_ftl = 1. - gfd/ftlxxmemo
388 heimbach 1.2 endif
389 heimbach 1.7
390     tmpplot1(itilepos,jtilepos,layer,itile,jtile)
391     & = gfd
392     tmpplot2(itilepos,jtilepos,layer,itile,jtile)
393     & = ratio_ad
394     tmpplot3(itilepos,jtilepos,layer,itile,jtile)
395     & = ratio_ftl
396    
397     fcrmem ( ichknum ) = fcref
398     fcppmem ( ichknum ) = fcpertplus
399     fcpmmem ( ichknum ) = fcpertminus
400     xxmemref ( ichknum ) = xxmemo_ref
401     xxmempert ( ichknum ) = xxmemo_pert
402     gfdmem ( ichknum ) = gfd
403     adxxmem ( ichknum ) = adxxmemo
404     ftlxxmem ( ichknum ) = ftlxxmemo
405     ratioadmem ( ichknum ) = ratio_ad
406     ratioftlmem ( ichknum ) = ratio_ftl
407    
408     irecmem ( ichknum ) = icvrec
409     bimem ( ichknum ) = itile
410     bjmem ( ichknum ) = jtile
411     ilocmem ( ichknum ) = itilepos
412     jlocmem ( ichknum ) = jtilepos
413     klocmem ( ichknum ) = layer
414 heimbach 1.8 iobcsmem ( ichknum ) = obcspos
415 heimbach 1.7 icompmem ( ichknum ) = icomp
416     ichkmem ( ichknum ) = ichknum
417     itestmem ( ichknum ) = itest
418     ierrmem ( ichknum ) = ierr
419    
420 heimbach 1.12 print *, 'grad-res -------------------------------'
421     print '(a,5I5,2x,3(1x,E15.9))', ' grad-res ',
422 heimbach 1.7 & myprocid,ichknum,itilepos,jtilepos,layer,
423     & fcref, fcpertplus, fcpertminus
424     #ifdef ALLOW_TANGENTLINEAR_RUN
425 heimbach 1.12 print '(a,5I5,2x,3(1x,E15.9))', ' grad-res ',
426 heimbach 1.7 & myprocid,ichknum,ichkmem(ichknum),
427     & icompmem(ichknum),itestmem(ichknum),
428     & ftlxxmemo, gfd, ratio_ftl
429 heimbach 1.12 WRITE(msgBuf,'(A34,2(1PE24.14,X))')
430     & 'precision_grdchk_result TLM ', fcref, ftlxxmemo
431     CALL PRINT_MESSAGE
432     & (msgBuf,standardMessageUnit,SQUEEZE_RIGHT,1)
433 heimbach 1.7 #else
434 heimbach 1.12 print '(a,5I5,2x,3(1x,E15.9))', ' grad-res ',
435 heimbach 1.7 & myprocid,ichknum,ichkmem(ichknum),
436     & icompmem(ichknum),itestmem(ichknum),
437     & adxxmemo, gfd, ratio_ad
438 heimbach 1.12 WRITE(msgBuf,'(A34,2(1PE24.14,X))')
439     & 'precision_grdchk_result ADM ', fcref, adxxmemo
440     CALL PRINT_MESSAGE
441     & (msgBuf,standardMessageUnit,SQUEEZE_RIGHT,1)
442 heimbach 1.7 #endif
443    
444     endif
445    
446     print *, 'ph-grd ierr ---------------------------'
447     print *, 'ph-grd ierr = ', ierr, ', icomp = ', icomp,
448     & ', ichknum = ', ichknum
449    
450     _BARRIER
451    
452     c-- else of if ( ichknum ...
453     else
454     ierr_grdchk = -1
455    
456     c-- end of if ( ichknum ...
457 heimbach 1.2 endif
458    
459 heimbach 1.7 c-- end of do icomp = ...
460     enddo
461 heimbach 1.2
462 heimbach 1.7 if ( myProcId .EQ. grdchkwhichproc ) then
463     CALL WRITE_REC_XYZ_RL(
464     & 'grd_findiff' , tmpplot1, 1, 0, myThid)
465     CALL WRITE_REC_XYZ_RL(
466     & 'grd_ratio_ad' , tmpplot2, 1, 0, myThid)
467     CALL WRITE_REC_XYZ_RL(
468     & 'grd_ratio_ftl' , tmpplot3, 1, 0, myThid)
469     endif
470 heimbach 1.2
471 heimbach 1.7 c-- Everyone has to wait for the component to be reset.
472     _BARRIER
473 heimbach 1.2
474     c-- Print the results of the gradient check.
475     call grdchk_print( ichknum, ierr_grdchk, mythid )
476    
477 heimbach 1.11 #endif /* ALLOW_GRDCHK */
478 heimbach 1.2
479     end

  ViewVC Help
Powered by ViewVC 1.1.22