/[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.13 - (hide annotations) (download)
Mon Feb 23 19:16:16 2004 UTC (20 years, 2 months ago) by heimbach
Branch: MAIN
CVS Tags: checkpoint52l_pre, hrcube5, checkpoint52l_post, checkpoint52k_post
Changes since 1.12: +3 -1 lines
added output

1 edhill 1.10 C
2 heimbach 1.13 C $Header: /u/gcmpack/MITgcm/pkg/grdchk/grdchk_main.F,v 1.12 2003/11/04 20:47:42 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     c-- initialise variables
147     call grdchk_init( mythid )
148    
149     c-- Compute the adjoint models' gradients.
150     c-- Compute the unperturbed cost function.
151 heimbach 1.7 cph Gradient via adjoint has already been computed,
152     cph and so has unperturbed cost function,
153     cph assuming all xx_ fields are initialised to zero.
154 heimbach 1.2
155 heimbach 1.9 ierr_grdchk = 0
156     cphadmtlm(
157 heimbach 1.2 fcref = fc
158 heimbach 1.9 cphadmtlm fcref = objf_state_final(45,4,1,1)
159     cphadmtlm)
160    
161     print *, 'ph-check fcref = ', fcref
162 heimbach 1.2
163     do bj = jtlo, jthi
164     do bi = itlo, ithi
165     do k = 1, nr
166     do j = jmin, jmax
167     do i = imin, imax
168     tmpplot1(i,j,k,bi,bj) = 0. _d 0
169     tmpplot2(i,j,k,bi,bj) = 0. _d 0
170 heimbach 1.6 tmpplot3(i,j,k,bi,bj) = 0. _d 0
171 heimbach 1.2 end do
172     end do
173     end do
174     end do
175     end do
176    
177 heimbach 1.4 if ( useCentralDiff ) then
178     grdchk_epsfac = 2. _d 0
179     else
180     grdchk_epsfac = 1. _d 0
181     end if
182    
183 heimbach 1.12 print *, 'grad-res -------------------------------'
184 heimbach 1.7 print ('(2a)'),
185 heimbach 1.12 & ' grad-res proc # i j k fc ref',
186 heimbach 1.7 & ' fc + eps fc - eps'
187     #ifdef ALLOW_TANGENTLINEAR_RUN
188     print ('(2a)'),
189 heimbach 1.12 & ' grad-res proc # i j k tlm grad',
190 heimbach 1.7 & ' fd grad 1 - fd/tlm'
191     #else
192     print ('(2a)'),
193 heimbach 1.12 & ' grad-res proc # i j k adj grad',
194 heimbach 1.7 & ' fd grad 1 - fd/adj'
195     #endif
196    
197 heimbach 1.2 c-- Compute the finite difference approximations.
198     c-- Cycle through all processes doing NINT(nend-nbeg+1)/nstep
199     c-- gradient checks.
200    
201 heimbach 1.7 do icomp = nbeg, nend, nstep
202 heimbach 1.2
203 heimbach 1.7 ichknum = (icomp - nbeg)/nstep + 1
204 heimbach 1.2
205 heimbach 1.7 if (ichknum .le. maxgrdchecks ) then
206 heimbach 1.2
207 heimbach 1.7 c-- Determine the location of icomp on the grid.
208     if ( myProcId .EQ. grdchkwhichproc ) then
209     call grdchk_loc( icomp, ichknum,
210 heimbach 1.8 & icvrec, itile, jtile, layer, obcspos,
211 heimbach 1.7 & itilepos, jtilepos, itest, ierr,
212     & mythid )
213     endif
214     _BARRIER
215 heimbach 1.2
216 heimbach 1.6 c******************************************************
217     c-- (A): get gradient component calculated via adjoint
218     c******************************************************
219 heimbach 1.7
220     c-- get gradient component calculated via adjoint
221     if ( myProcId .EQ. grdchkwhichproc .AND.
222     & ierr .EQ. 0 ) then
223     call grdchk_getadxx( icvrec,
224     & itile, jtile, layer,
225     & itilepos, jtilepos,
226     & adxxmemo, mythid )
227     endif
228     _BARRIER
229 heimbach 1.4
230 heimbach 1.6 #ifdef ALLOW_TANGENTLINEAR_RUN
231     c******************************************************
232     c-- (B): Get gradient component g_fc from tangent linear run:
233     c******************************************************
234     c--
235     c-- 1. perturb control vector component: xx(i)=1.
236    
237 heimbach 1.7 if ( myProcId .EQ. grdchkwhichproc .AND.
238     & ierr .EQ. 0 ) then
239     localEps = 1. _d 0
240     call grdchk_getxx( icvrec, TANGENT_SIMULATION,
241     & itile, jtile, layer,
242     & itilepos, jtilepos,
243     & xxmemo_ref, xxmemo_pert, localEps,
244     & mythid )
245     endif
246     _BARRIER
247 heimbach 1.6
248     c--
249     c-- 2. perform tangent linear run
250 heimbach 1.7 mytime = starttime
251     myiter = niter0
252 heimbach 1.9 cphadmtlm(
253 heimbach 1.7 g_fc = 0.
254 heimbach 1.9 cphadmtlm do j=1,sny
255     cphadmtlm do i=1,snx
256     cphadmtlm g_objf_state_final(i,j,1,1) = 0.
257     cphadmtlm enddo
258     cphadmtlm enddo
259     cphadmtlm)
260 heimbach 1.7 call g_the_main_loop( mytime, myiter, mythid )
261 heimbach 1.9 cphadmtlm(
262 heimbach 1.7 ftlxxmemo = g_fc
263 heimbach 1.9 cphadmtlm ftlxxmemo = g_objf_state_final(45,4,1,1)
264     cphadmtlm)
265 heimbach 1.7 _BARRIER
266 heimbach 1.6 c--
267     c-- 3. reset control vector
268 heimbach 1.7 if ( myProcId .EQ. grdchkwhichproc .AND.
269     & ierr .EQ. 0 ) then
270     call grdchk_setxx( icvrec, TANGENT_SIMULATION,
271     & itile, jtile, layer,
272     & itilepos, jtilepos,
273     & xxmemo_ref, mythid )
274     endif
275     _BARRIER
276    
277     #endif /* ALLOW_TANGENTLINEAR_RUN */
278    
279 heimbach 1.6
280     c******************************************************
281     c-- (C): Get gradient via finite difference perturbation
282     c******************************************************
283    
284 heimbach 1.2 c-- get control vector component from file
285 heimbach 1.7 c-- perturb it and write back to file
286 heimbach 1.6 c-- positive perturbation
287 heimbach 1.7 localEps = abs(grdchk_eps)
288     if ( myProcId .EQ. grdchkwhichproc .AND.
289     & ierr .EQ. 0 ) then
290     call grdchk_getxx( icvrec, FORWARD_SIMULATION,
291     & itile, jtile, layer,
292     & itilepos, jtilepos,
293     & xxmemo_ref, xxmemo_pert, localEps,
294     & mythid )
295     endif
296     _BARRIER
297 heimbach 1.2
298 heimbach 1.4 c-- forward run with perturbed control vector
299 heimbach 1.7 mytime = starttime
300     myiter = niter0
301     call the_main_loop( mytime, myiter, mythid )
302 heimbach 1.9 cphadmtlm(
303 heimbach 1.7 fcpertplus = fc
304 heimbach 1.9 cphadmtlm fcpertplus = objf_state_final(45,4,1,1)
305     cphadmtlm)
306 heimbach 1.13 print *, 'ph-check fcpertplus = ', fcpertplus
307 heimbach 1.7 _BARRIER
308 heimbach 1.4
309     c-- Reset control vector.
310 heimbach 1.7 if ( myProcId .EQ. grdchkwhichproc .AND.
311     & ierr .EQ. 0 ) then
312     call grdchk_setxx( icvrec, FORWARD_SIMULATION,
313     & itile, jtile, layer,
314     & itilepos, jtilepos,
315     & xxmemo_ref, mythid )
316     endif
317     _BARRIER
318 heimbach 1.2
319 heimbach 1.7 fcpertminus = fcref
320 heimbach 1.13 print *, 'ph-check fcpertminus = ', fcpertminus
321 heimbach 1.4
322 heimbach 1.7 if ( useCentralDiff ) then
323 heimbach 1.4
324 heimbach 1.6 c-- get control vector component from file
325 heimbach 1.7 c-- perturb it and write back to file
326 heimbach 1.4 c-- repeat the proceedure for a negative perturbation
327 heimbach 1.7 if ( myProcId .EQ. grdchkwhichproc .AND.
328     & ierr .EQ. 0 ) then
329     localEps = - abs(grdchk_eps)
330     call grdchk_getxx( icvrec, FORWARD_SIMULATION,
331     & itile, jtile, layer,
332     & itilepos, jtilepos,
333     & xxmemo_ref, xxmemo_pert, localEps,
334     & mythid )
335     endif
336     _BARRIER
337 heimbach 1.4
338 heimbach 1.2 c-- forward run with perturbed control vector
339 heimbach 1.7 mytime = starttime
340     myiter = niter0
341     call the_main_loop( mytime, myiter, mythid )
342     _BARRIER
343     fcpertminus = fc
344 heimbach 1.2
345 heimbach 1.4 c-- Reset control vector.
346 heimbach 1.7 if ( myProcId .EQ. grdchkwhichproc .AND.
347     & ierr .EQ. 0 ) then
348     call grdchk_setxx( icvrec, FORWARD_SIMULATION,
349     & itile, jtile, layer,
350     & itilepos, jtilepos,
351     & xxmemo_ref, mythid )
352     endif
353     _BARRIER
354    
355     c-- end of if useCentralDiff ...
356     end if
357 heimbach 1.4
358 heimbach 1.6 c******************************************************
359     c-- (D): calculate relative differences between gradients
360     c******************************************************
361    
362 heimbach 1.7 if ( myProcId .EQ. grdchkwhichproc .AND.
363     & ierr .EQ. 0 ) then
364 heimbach 1.2
365 heimbach 1.7 if ( grdchk_eps .eq. 0. ) then
366     gfd = (fcpertplus-fcpertminus)
367     else
368     gfd = (fcpertplus-fcpertminus)
369     & /(grdchk_epsfac*grdchk_eps)
370     endif
371 heimbach 1.2
372 heimbach 1.7 if ( adxxmemo .eq. 0. ) then
373     ratio_ad = abs( adxxmemo - gfd )
374     else
375     ratio_ad = 1. - gfd/adxxmemo
376     endif
377    
378     if ( ftlxxmemo .eq. 0. ) then
379     ratio_ftl = abs( ftlxxmemo - gfd )
380 heimbach 1.2 else
381 heimbach 1.7 ratio_ftl = 1. - gfd/ftlxxmemo
382 heimbach 1.2 endif
383 heimbach 1.7
384     tmpplot1(itilepos,jtilepos,layer,itile,jtile)
385     & = gfd
386     tmpplot2(itilepos,jtilepos,layer,itile,jtile)
387     & = ratio_ad
388     tmpplot3(itilepos,jtilepos,layer,itile,jtile)
389     & = ratio_ftl
390    
391     fcrmem ( ichknum ) = fcref
392     fcppmem ( ichknum ) = fcpertplus
393     fcpmmem ( ichknum ) = fcpertminus
394     xxmemref ( ichknum ) = xxmemo_ref
395     xxmempert ( ichknum ) = xxmemo_pert
396     gfdmem ( ichknum ) = gfd
397     adxxmem ( ichknum ) = adxxmemo
398     ftlxxmem ( ichknum ) = ftlxxmemo
399     ratioadmem ( ichknum ) = ratio_ad
400     ratioftlmem ( ichknum ) = ratio_ftl
401    
402     irecmem ( ichknum ) = icvrec
403     bimem ( ichknum ) = itile
404     bjmem ( ichknum ) = jtile
405     ilocmem ( ichknum ) = itilepos
406     jlocmem ( ichknum ) = jtilepos
407     klocmem ( ichknum ) = layer
408 heimbach 1.8 iobcsmem ( ichknum ) = obcspos
409 heimbach 1.7 icompmem ( ichknum ) = icomp
410     ichkmem ( ichknum ) = ichknum
411     itestmem ( ichknum ) = itest
412     ierrmem ( ichknum ) = ierr
413    
414 heimbach 1.12 print *, 'grad-res -------------------------------'
415     print '(a,5I5,2x,3(1x,E15.9))', ' grad-res ',
416 heimbach 1.7 & myprocid,ichknum,itilepos,jtilepos,layer,
417     & fcref, fcpertplus, fcpertminus
418     #ifdef ALLOW_TANGENTLINEAR_RUN
419 heimbach 1.12 print '(a,5I5,2x,3(1x,E15.9))', ' grad-res ',
420 heimbach 1.7 & myprocid,ichknum,ichkmem(ichknum),
421     & icompmem(ichknum),itestmem(ichknum),
422     & ftlxxmemo, gfd, ratio_ftl
423 heimbach 1.12 WRITE(msgBuf,'(A34,2(1PE24.14,X))')
424     & 'precision_grdchk_result TLM ', fcref, ftlxxmemo
425     CALL PRINT_MESSAGE
426     & (msgBuf,standardMessageUnit,SQUEEZE_RIGHT,1)
427 heimbach 1.7 #else
428 heimbach 1.12 print '(a,5I5,2x,3(1x,E15.9))', ' grad-res ',
429 heimbach 1.7 & myprocid,ichknum,ichkmem(ichknum),
430     & icompmem(ichknum),itestmem(ichknum),
431     & adxxmemo, gfd, ratio_ad
432 heimbach 1.12 WRITE(msgBuf,'(A34,2(1PE24.14,X))')
433     & 'precision_grdchk_result ADM ', fcref, adxxmemo
434     CALL PRINT_MESSAGE
435     & (msgBuf,standardMessageUnit,SQUEEZE_RIGHT,1)
436 heimbach 1.7 #endif
437    
438     endif
439    
440     print *, 'ph-grd ierr ---------------------------'
441     print *, 'ph-grd ierr = ', ierr, ', icomp = ', icomp,
442     & ', ichknum = ', ichknum
443    
444     _BARRIER
445    
446     c-- else of if ( ichknum ...
447     else
448     ierr_grdchk = -1
449    
450     c-- end of if ( ichknum ...
451 heimbach 1.2 endif
452    
453 heimbach 1.7 c-- end of do icomp = ...
454     enddo
455 heimbach 1.2
456 heimbach 1.7 if ( myProcId .EQ. grdchkwhichproc ) then
457     CALL WRITE_REC_XYZ_RL(
458     & 'grd_findiff' , tmpplot1, 1, 0, myThid)
459     CALL WRITE_REC_XYZ_RL(
460     & 'grd_ratio_ad' , tmpplot2, 1, 0, myThid)
461     CALL WRITE_REC_XYZ_RL(
462     & 'grd_ratio_ftl' , tmpplot3, 1, 0, myThid)
463     endif
464 heimbach 1.2
465 heimbach 1.7 c-- Everyone has to wait for the component to be reset.
466     _BARRIER
467 heimbach 1.2
468     c-- Print the results of the gradient check.
469     call grdchk_print( ichknum, ierr_grdchk, mythid )
470    
471 heimbach 1.11 #endif /* ALLOW_GRDCHK */
472 heimbach 1.2
473     end

  ViewVC Help
Powered by ViewVC 1.1.22