/[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.22 - (hide annotations) (download)
Fri Jul 27 22:18:57 2007 UTC (16 years, 9 months ago) by heimbach
Branch: MAIN
Changes since 1.21: +2 -1 lines
Comment all relevant #ifndef ALLOW_AUTODIFF_TAMC
that used to hide exch2 or cubed-sphere specific code
(commented via 'cph-exch2')

1 edhill 1.10 C
2 heimbach 1.22 C $Header: /u/gcmpack/MITgcm/pkg/grdchk/grdchk_main.F,v 1.21 2007/04/20 19:26:43 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.21 #include "ctrl.h"
85 heimbach 1.9 #ifdef ALLOW_TANGENTLINEAR_RUN
86     #include "g_cost.h"
87     #endif
88 heimbach 1.2
89 heimbach 1.3 C !INPUT/OUTPUT PARAMETERS:
90 heimbach 1.2 c == routine arguments ==
91     integer mythid
92    
93 heimbach 1.11 #ifdef ALLOW_GRDCHK
94 heimbach 1.3 C !LOCAL VARIABLES:
95 heimbach 1.2 c == local variables ==
96     integer myiter
97     _RL mytime
98     integer bi, itlo, ithi
99     integer bj, jtlo, jthi
100     integer i, imin, imax
101     integer j, jmin, jmax
102     integer k
103    
104     integer icomp
105     integer ichknum
106     integer icvrec
107     integer jtile
108     integer itile
109     integer layer
110 heimbach 1.8 integer obcspos
111 heimbach 1.2 integer itilepos
112     integer jtilepos
113 heimbach 1.19 integer icglo
114 heimbach 1.2 integer itest
115     integer ierr
116     integer ierr_grdchk
117     _RL gfd
118     _RL fcref
119 heimbach 1.4 _RL fcpertplus, fcpertminus
120 heimbach 1.6 _RL ratio_ad
121     _RL ratio_ftl
122 heimbach 1.2 _RL xxmemo_ref
123     _RL xxmemo_pert
124     _RL adxxmemo
125 heimbach 1.6 _RL ftlxxmemo
126     _RL localEps
127     _RL grdchk_epsfac
128    
129 heimbach 1.7 _RL tmpplot1(1-olx:snx+olx,1-oly:sny+oly,nr,nsx,nsy)
130     _RL tmpplot2(1-olx:snx+olx,1-oly:sny+oly,nr,nsx,nsy)
131     _RL tmpplot3(1-olx:snx+olx,1-oly:sny+oly,nr,nsx,nsy)
132    
133 heimbach 1.12 CHARACTER*(MAX_LEN_MBUF) msgBuf
134    
135 heimbach 1.2 c == end of interface ==
136 heimbach 1.3 CEOP
137 heimbach 1.2
138     c-- Set the loop ranges.
139     jtlo = mybylo(mythid)
140     jthi = mybyhi(mythid)
141     itlo = mybxlo(mythid)
142     ithi = mybxhi(mythid)
143     jmin = 1
144     jmax = sny
145     imin = 1
146     imax = snx
147    
148 heimbach 1.16 print *, 'ph-check entering grdchk_main '
149    
150 heimbach 1.2 c-- initialise variables
151     call grdchk_init( mythid )
152    
153     c-- Compute the adjoint models' gradients.
154     c-- Compute the unperturbed cost function.
155 heimbach 1.7 cph Gradient via adjoint has already been computed,
156     cph and so has unperturbed cost function,
157     cph assuming all xx_ fields are initialised to zero.
158 heimbach 1.2
159 heimbach 1.9 ierr_grdchk = 0
160 heimbach 1.21 #ifdef ALLOW_ADMTLM
161     fcref = objf_state_final(idep,jdep,1,1,1)
162     #else
163 heimbach 1.2 fcref = fc
164 heimbach 1.21 #endif
165 heimbach 1.9
166     print *, 'ph-check fcref = ', fcref
167 heimbach 1.2
168     do bj = jtlo, jthi
169     do bi = itlo, ithi
170     do k = 1, nr
171     do j = jmin, jmax
172     do i = imin, imax
173     tmpplot1(i,j,k,bi,bj) = 0. _d 0
174     tmpplot2(i,j,k,bi,bj) = 0. _d 0
175 heimbach 1.6 tmpplot3(i,j,k,bi,bj) = 0. _d 0
176 heimbach 1.2 end do
177     end do
178     end do
179     end do
180     end do
181    
182 heimbach 1.4 if ( useCentralDiff ) then
183     grdchk_epsfac = 2. _d 0
184     else
185     grdchk_epsfac = 1. _d 0
186     end if
187    
188 heimbach 1.12 print *, 'grad-res -------------------------------'
189 heimbach 1.20 print '(2a)',
190 heimbach 1.19 & ' grad-res proc # i j k bi bj iobc',
191 heimbach 1.18 & ' fc ref fc + eps fc - eps'
192 heimbach 1.7 #ifdef ALLOW_TANGENTLINEAR_RUN
193 heimbach 1.20 print '(2a)',
194 heimbach 1.19 & ' grad-res proc # i j k bi bj iobc',
195 heimbach 1.18 & ' tlm grad fd grad 1 - fd/tlm'
196 heimbach 1.7 #else
197 heimbach 1.20 print '(2a)',
198 heimbach 1.19 & ' grad-res proc # i j k bi bj iobc',
199 heimbach 1.18 & ' adj grad fd grad 1 - fd/adj'
200 heimbach 1.7 #endif
201    
202 heimbach 1.2 c-- Compute the finite difference approximations.
203     c-- Cycle through all processes doing NINT(nend-nbeg+1)/nstep
204     c-- gradient checks.
205 heimbach 1.14
206 heimbach 1.17 if ( nbeg .EQ. 0 )
207     & call grdchk_get_position( mythid )
208 heimbach 1.2
209 heimbach 1.7 do icomp = nbeg, nend, nstep
210 heimbach 1.2
211 heimbach 1.7 ichknum = (icomp - nbeg)/nstep + 1
212 heimbach 1.2
213 heimbach 1.19 cph(
214     cph-print print *, 'ph-grd _main: nbeg, icomp, ichknum ',
215     cph-print & nbeg, icomp, ichknum
216     cph)
217 heimbach 1.7 if (ichknum .le. maxgrdchecks ) then
218 heimbach 1.2
219 heimbach 1.7 c-- Determine the location of icomp on the grid.
220     if ( myProcId .EQ. grdchkwhichproc ) then
221     call grdchk_loc( icomp, ichknum,
222 heimbach 1.8 & icvrec, itile, jtile, layer, obcspos,
223 heimbach 1.19 & itilepos, jtilepos, icglo, itest, ierr,
224 heimbach 1.7 & mythid )
225 heimbach 1.18 cph(
226 heimbach 1.19 cph-print print *, 'ph-grd ----- back from loc -----',
227     cph-print & icvrec, itilepos, jtilepos, layer, obcspos
228 heimbach 1.18 cph)
229 heimbach 1.7 endif
230     _BARRIER
231 heimbach 1.2
232 heimbach 1.6 c******************************************************
233     c-- (A): get gradient component calculated via adjoint
234     c******************************************************
235 heimbach 1.7
236     c-- get gradient component calculated via adjoint
237     if ( myProcId .EQ. grdchkwhichproc .AND.
238     & ierr .EQ. 0 ) then
239     call grdchk_getadxx( icvrec,
240     & itile, jtile, layer,
241     & itilepos, jtilepos,
242     & adxxmemo, mythid )
243     endif
244     _BARRIER
245 heimbach 1.4
246 heimbach 1.6 #ifdef ALLOW_TANGENTLINEAR_RUN
247     c******************************************************
248     c-- (B): Get gradient component g_fc from tangent linear run:
249     c******************************************************
250     c--
251     c-- 1. perturb control vector component: xx(i)=1.
252 heimbach 1.22 ftlxxmemo = 0.
253 heimbach 1.6
254 heimbach 1.7 if ( myProcId .EQ. grdchkwhichproc .AND.
255     & ierr .EQ. 0 ) then
256     localEps = 1. _d 0
257     call grdchk_getxx( icvrec, TANGENT_SIMULATION,
258     & itile, jtile, layer,
259     & itilepos, jtilepos,
260     & xxmemo_ref, xxmemo_pert, localEps,
261     & mythid )
262     endif
263     _BARRIER
264 heimbach 1.6
265     c--
266     c-- 2. perform tangent linear run
267 heimbach 1.7 mytime = starttime
268     myiter = niter0
269 heimbach 1.21 #ifdef ALLOW_ADMTLM
270     do k=1,4*Nr+1
271     do j=1,sny
272     do i=1,snx
273     g_objf_state_final(i,j,1,1,k) = 0.
274     enddo
275     enddo
276     enddo
277     #else
278 heimbach 1.7 g_fc = 0.
279 heimbach 1.21 #endif
280    
281 heimbach 1.7 call g_the_main_loop( mytime, myiter, mythid )
282 heimbach 1.21 _BARRIER
283     #ifdef ALLOW_ADMTLM
284     ftlxxmemo = g_objf_state_final(idep,jdep,1,1,1)
285     #else
286 heimbach 1.7 ftlxxmemo = g_fc
287 heimbach 1.21 #endif
288    
289 heimbach 1.6 c--
290     c-- 3. reset control vector
291 heimbach 1.7 if ( myProcId .EQ. grdchkwhichproc .AND.
292     & ierr .EQ. 0 ) then
293     call grdchk_setxx( icvrec, TANGENT_SIMULATION,
294     & itile, jtile, layer,
295     & itilepos, jtilepos,
296     & xxmemo_ref, mythid )
297     endif
298     _BARRIER
299    
300     #endif /* ALLOW_TANGENTLINEAR_RUN */
301    
302 heimbach 1.6
303     c******************************************************
304     c-- (C): Get gradient via finite difference perturbation
305     c******************************************************
306    
307 heimbach 1.2 c-- get control vector component from file
308 heimbach 1.7 c-- perturb it and write back to file
309 heimbach 1.6 c-- positive perturbation
310 heimbach 1.7 localEps = abs(grdchk_eps)
311     if ( myProcId .EQ. grdchkwhichproc .AND.
312     & ierr .EQ. 0 ) then
313     call grdchk_getxx( icvrec, FORWARD_SIMULATION,
314     & itile, jtile, layer,
315     & itilepos, jtilepos,
316     & xxmemo_ref, xxmemo_pert, localEps,
317     & mythid )
318     endif
319     _BARRIER
320 heimbach 1.2
321 heimbach 1.4 c-- forward run with perturbed control vector
322 heimbach 1.7 mytime = starttime
323     myiter = niter0
324     call the_main_loop( mytime, myiter, mythid )
325 heimbach 1.21 #ifdef ALLOW_ADMTLM
326     fcpertplus = objf_state_final(idep,jdep,1,1,1)
327     #else
328 heimbach 1.7 fcpertplus = fc
329 heimbach 1.21 #endif
330 heimbach 1.13 print *, 'ph-check fcpertplus = ', fcpertplus
331 heimbach 1.7 _BARRIER
332 heimbach 1.4
333     c-- Reset control vector.
334 heimbach 1.7 if ( myProcId .EQ. grdchkwhichproc .AND.
335     & ierr .EQ. 0 ) then
336     call grdchk_setxx( icvrec, FORWARD_SIMULATION,
337     & itile, jtile, layer,
338     & itilepos, jtilepos,
339     & xxmemo_ref, mythid )
340     endif
341     _BARRIER
342 heimbach 1.2
343 heimbach 1.7 fcpertminus = fcref
344 heimbach 1.13 print *, 'ph-check fcpertminus = ', fcpertminus
345 heimbach 1.4
346 heimbach 1.7 if ( useCentralDiff ) then
347 heimbach 1.4
348 heimbach 1.6 c-- get control vector component from file
349 heimbach 1.7 c-- perturb it and write back to file
350 heimbach 1.4 c-- repeat the proceedure for a negative perturbation
351 heimbach 1.7 if ( myProcId .EQ. grdchkwhichproc .AND.
352     & ierr .EQ. 0 ) then
353     localEps = - abs(grdchk_eps)
354     call grdchk_getxx( icvrec, FORWARD_SIMULATION,
355     & itile, jtile, layer,
356     & itilepos, jtilepos,
357     & xxmemo_ref, xxmemo_pert, localEps,
358     & mythid )
359     endif
360     _BARRIER
361 heimbach 1.4
362 heimbach 1.2 c-- forward run with perturbed control vector
363 heimbach 1.7 mytime = starttime
364     myiter = niter0
365     call the_main_loop( mytime, myiter, mythid )
366     _BARRIER
367 heimbach 1.21 #ifdef ALLOW_ADMTLM
368     fcpertminus = objf_state_final(idep,jdep,1,1,1)
369     #else
370 heimbach 1.7 fcpertminus = fc
371 heimbach 1.21 #endif
372 heimbach 1.2
373 heimbach 1.4 c-- Reset control vector.
374 heimbach 1.7 if ( myProcId .EQ. grdchkwhichproc .AND.
375     & ierr .EQ. 0 ) then
376     call grdchk_setxx( icvrec, FORWARD_SIMULATION,
377     & itile, jtile, layer,
378     & itilepos, jtilepos,
379     & xxmemo_ref, mythid )
380     endif
381     _BARRIER
382    
383     c-- end of if useCentralDiff ...
384     end if
385 heimbach 1.4
386 heimbach 1.6 c******************************************************
387     c-- (D): calculate relative differences between gradients
388     c******************************************************
389    
390 heimbach 1.7 if ( myProcId .EQ. grdchkwhichproc .AND.
391     & ierr .EQ. 0 ) then
392 heimbach 1.2
393 heimbach 1.7 if ( grdchk_eps .eq. 0. ) then
394     gfd = (fcpertplus-fcpertminus)
395     else
396     gfd = (fcpertplus-fcpertminus)
397     & /(grdchk_epsfac*grdchk_eps)
398     endif
399 heimbach 1.2
400 heimbach 1.7 if ( adxxmemo .eq. 0. ) then
401     ratio_ad = abs( adxxmemo - gfd )
402     else
403     ratio_ad = 1. - gfd/adxxmemo
404     endif
405    
406     if ( ftlxxmemo .eq. 0. ) then
407     ratio_ftl = abs( ftlxxmemo - gfd )
408 heimbach 1.2 else
409 heimbach 1.7 ratio_ftl = 1. - gfd/ftlxxmemo
410 heimbach 1.2 endif
411 heimbach 1.7
412     tmpplot1(itilepos,jtilepos,layer,itile,jtile)
413     & = gfd
414     tmpplot2(itilepos,jtilepos,layer,itile,jtile)
415     & = ratio_ad
416     tmpplot3(itilepos,jtilepos,layer,itile,jtile)
417     & = ratio_ftl
418    
419     fcrmem ( ichknum ) = fcref
420     fcppmem ( ichknum ) = fcpertplus
421     fcpmmem ( ichknum ) = fcpertminus
422     xxmemref ( ichknum ) = xxmemo_ref
423     xxmempert ( ichknum ) = xxmemo_pert
424     gfdmem ( ichknum ) = gfd
425     adxxmem ( ichknum ) = adxxmemo
426     ftlxxmem ( ichknum ) = ftlxxmemo
427     ratioadmem ( ichknum ) = ratio_ad
428     ratioftlmem ( ichknum ) = ratio_ftl
429    
430     irecmem ( ichknum ) = icvrec
431     bimem ( ichknum ) = itile
432     bjmem ( ichknum ) = jtile
433     ilocmem ( ichknum ) = itilepos
434     jlocmem ( ichknum ) = jtilepos
435     klocmem ( ichknum ) = layer
436 heimbach 1.8 iobcsmem ( ichknum ) = obcspos
437 heimbach 1.7 icompmem ( ichknum ) = icomp
438     ichkmem ( ichknum ) = ichknum
439     itestmem ( ichknum ) = itest
440     ierrmem ( ichknum ) = ierr
441 heimbach 1.19 icglomem ( ichknum ) = icglo
442    
443 heimbach 1.12 print *, 'grad-res -------------------------------'
444 heimbach 1.19 print '(a,8I5,2x,3(1x,E18.12))', ' grad-res ',
445     & myprocid,ichknum,itilepos,jtilepos,
446     & layer,itile,jtile,obcspos,
447 heimbach 1.7 & fcref, fcpertplus, fcpertminus
448     #ifdef ALLOW_TANGENTLINEAR_RUN
449 heimbach 1.19 print '(a,8I5,2x,3(1x,E18.12))', ' grad-res ',
450 heimbach 1.7 & myprocid,ichknum,ichkmem(ichknum),
451 heimbach 1.19 & icompmem(ichknum),itestmem(ichknum),
452     & bimem(ichknum),bjmem(ichknum),iobcsmem(ichknum),
453 heimbach 1.7 & ftlxxmemo, gfd, ratio_ftl
454 heimbach 1.12 WRITE(msgBuf,'(A34,2(1PE24.14,X))')
455     & 'precision_grdchk_result TLM ', fcref, ftlxxmemo
456     CALL PRINT_MESSAGE
457     & (msgBuf,standardMessageUnit,SQUEEZE_RIGHT,1)
458 heimbach 1.7 #else
459 heimbach 1.19 print '(a,8I5,2x,3(1x,E18.12))', ' grad-res ',
460 heimbach 1.7 & myprocid,ichknum,ichkmem(ichknum),
461 heimbach 1.19 & icompmem(ichknum),itestmem(ichknum),
462     & bimem(ichknum),bjmem(ichknum),obcspos,
463 heimbach 1.7 & adxxmemo, gfd, ratio_ad
464 heimbach 1.12 WRITE(msgBuf,'(A34,2(1PE24.14,X))')
465     & 'precision_grdchk_result ADM ', fcref, adxxmemo
466     CALL PRINT_MESSAGE
467     & (msgBuf,standardMessageUnit,SQUEEZE_RIGHT,1)
468 heimbach 1.7 #endif
469    
470     endif
471    
472     print *, 'ph-grd ierr ---------------------------'
473     print *, 'ph-grd ierr = ', ierr, ', icomp = ', icomp,
474     & ', ichknum = ', ichknum
475    
476     _BARRIER
477    
478     c-- else of if ( ichknum ...
479     else
480     ierr_grdchk = -1
481    
482     c-- end of if ( ichknum ...
483 heimbach 1.2 endif
484    
485 heimbach 1.7 c-- end of do icomp = ...
486     enddo
487 heimbach 1.2
488 heimbach 1.7 if ( myProcId .EQ. grdchkwhichproc ) then
489     CALL WRITE_REC_XYZ_RL(
490     & 'grd_findiff' , tmpplot1, 1, 0, myThid)
491     CALL WRITE_REC_XYZ_RL(
492     & 'grd_ratio_ad' , tmpplot2, 1, 0, myThid)
493     CALL WRITE_REC_XYZ_RL(
494     & 'grd_ratio_ftl' , tmpplot3, 1, 0, myThid)
495     endif
496 heimbach 1.2
497 heimbach 1.7 c-- Everyone has to wait for the component to be reset.
498     _BARRIER
499 heimbach 1.2
500     c-- Print the results of the gradient check.
501     call grdchk_print( ichknum, ierr_grdchk, mythid )
502    
503 heimbach 1.11 #endif /* ALLOW_GRDCHK */
504 heimbach 1.2
505     end

  ViewVC Help
Powered by ViewVC 1.1.22