/[MITgcm]/MITgcm_contrib/heimbach/OpenAD/code_shallow_openad/grdchk_main.F
ViewVC logotype

Annotation of /MITgcm_contrib/heimbach/OpenAD/code_shallow_openad/grdchk_main.F

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


Revision 1.3 - (hide annotations) (download)
Tue Mar 27 21:56:51 2007 UTC (19 years, 7 months ago) by utke
Branch: MAIN
Changes since 1.2: +28 -14 lines
resync with main

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

  ViewVC Help
Powered by ViewVC 1.1.22