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

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

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


Revision 1.13 - (show annotations) (download)
Mon Feb 23 19:16:16 2004 UTC (20 years, 3 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 C
2 C $Header: /u/gcmpack/MITgcm/pkg/grdchk/grdchk_main.F,v 1.12 2003/11/04 20:47:42 heimbach Exp $
3 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 integer itest
113 integer ierr
114 integer ierr_grdchk
115 _RL gfd
116 _RL fcref
117 _RL fcpertplus, fcpertminus
118 _RL ratio_ad
119 _RL ratio_ftl
120 _RL xxmemo_ref
121 _RL xxmemo_pert
122 _RL adxxmemo
123 _RL ftlxxmemo
124 _RL localEps
125 _RL grdchk_epsfac
126
127 _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 CHARACTER*(MAX_LEN_MBUF) msgBuf
132
133 c == end of interface ==
134 CEOP
135
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 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
155 ierr_grdchk = 0
156 cphadmtlm(
157 fcref = fc
158 cphadmtlm fcref = objf_state_final(45,4,1,1)
159 cphadmtlm)
160
161 print *, 'ph-check fcref = ', fcref
162
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 tmpplot3(i,j,k,bi,bj) = 0. _d 0
171 end do
172 end do
173 end do
174 end do
175 end do
176
177 if ( useCentralDiff ) then
178 grdchk_epsfac = 2. _d 0
179 else
180 grdchk_epsfac = 1. _d 0
181 end if
182
183 print *, 'grad-res -------------------------------'
184 print ('(2a)'),
185 & ' grad-res proc # i j k fc ref',
186 & ' fc + eps fc - eps'
187 #ifdef ALLOW_TANGENTLINEAR_RUN
188 print ('(2a)'),
189 & ' grad-res proc # i j k tlm grad',
190 & ' fd grad 1 - fd/tlm'
191 #else
192 print ('(2a)'),
193 & ' grad-res proc # i j k adj grad',
194 & ' fd grad 1 - fd/adj'
195 #endif
196
197 c-- Compute the finite difference approximations.
198 c-- Cycle through all processes doing NINT(nend-nbeg+1)/nstep
199 c-- gradient checks.
200
201 do icomp = nbeg, nend, nstep
202
203 ichknum = (icomp - nbeg)/nstep + 1
204
205 if (ichknum .le. maxgrdchecks ) then
206
207 c-- Determine the location of icomp on the grid.
208 if ( myProcId .EQ. grdchkwhichproc ) then
209 call grdchk_loc( icomp, ichknum,
210 & icvrec, itile, jtile, layer, obcspos,
211 & itilepos, jtilepos, itest, ierr,
212 & mythid )
213 endif
214 _BARRIER
215
216 c******************************************************
217 c-- (A): get gradient component calculated via adjoint
218 c******************************************************
219
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
230 #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 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
248 c--
249 c-- 2. perform tangent linear run
250 mytime = starttime
251 myiter = niter0
252 cphadmtlm(
253 g_fc = 0.
254 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 call g_the_main_loop( mytime, myiter, mythid )
261 cphadmtlm(
262 ftlxxmemo = g_fc
263 cphadmtlm ftlxxmemo = g_objf_state_final(45,4,1,1)
264 cphadmtlm)
265 _BARRIER
266 c--
267 c-- 3. reset control vector
268 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
280 c******************************************************
281 c-- (C): Get gradient via finite difference perturbation
282 c******************************************************
283
284 c-- get control vector component from file
285 c-- perturb it and write back to file
286 c-- positive perturbation
287 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
298 c-- forward run with perturbed control vector
299 mytime = starttime
300 myiter = niter0
301 call the_main_loop( mytime, myiter, mythid )
302 cphadmtlm(
303 fcpertplus = fc
304 cphadmtlm fcpertplus = objf_state_final(45,4,1,1)
305 cphadmtlm)
306 print *, 'ph-check fcpertplus = ', fcpertplus
307 _BARRIER
308
309 c-- Reset control vector.
310 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
319 fcpertminus = fcref
320 print *, 'ph-check fcpertminus = ', fcpertminus
321
322 if ( useCentralDiff ) then
323
324 c-- get control vector component from file
325 c-- perturb it and write back to file
326 c-- repeat the proceedure for a negative perturbation
327 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
338 c-- forward run with perturbed control vector
339 mytime = starttime
340 myiter = niter0
341 call the_main_loop( mytime, myiter, mythid )
342 _BARRIER
343 fcpertminus = fc
344
345 c-- Reset control vector.
346 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
358 c******************************************************
359 c-- (D): calculate relative differences between gradients
360 c******************************************************
361
362 if ( myProcId .EQ. grdchkwhichproc .AND.
363 & ierr .EQ. 0 ) then
364
365 if ( grdchk_eps .eq. 0. ) then
366 gfd = (fcpertplus-fcpertminus)
367 else
368 gfd = (fcpertplus-fcpertminus)
369 & /(grdchk_epsfac*grdchk_eps)
370 endif
371
372 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 else
381 ratio_ftl = 1. - gfd/ftlxxmemo
382 endif
383
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 iobcsmem ( ichknum ) = obcspos
409 icompmem ( ichknum ) = icomp
410 ichkmem ( ichknum ) = ichknum
411 itestmem ( ichknum ) = itest
412 ierrmem ( ichknum ) = ierr
413
414 print *, 'grad-res -------------------------------'
415 print '(a,5I5,2x,3(1x,E15.9))', ' grad-res ',
416 & myprocid,ichknum,itilepos,jtilepos,layer,
417 & fcref, fcpertplus, fcpertminus
418 #ifdef ALLOW_TANGENTLINEAR_RUN
419 print '(a,5I5,2x,3(1x,E15.9))', ' grad-res ',
420 & myprocid,ichknum,ichkmem(ichknum),
421 & icompmem(ichknum),itestmem(ichknum),
422 & ftlxxmemo, gfd, ratio_ftl
423 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 #else
428 print '(a,5I5,2x,3(1x,E15.9))', ' grad-res ',
429 & myprocid,ichknum,ichkmem(ichknum),
430 & icompmem(ichknum),itestmem(ichknum),
431 & adxxmemo, gfd, ratio_ad
432 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 #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 endif
452
453 c-- end of do icomp = ...
454 enddo
455
456 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
465 c-- Everyone has to wait for the component to be reset.
466 _BARRIER
467
468 c-- Print the results of the gradient check.
469 call grdchk_print( ichknum, ierr_grdchk, mythid )
470
471 #endif /* ALLOW_GRDCHK */
472
473 end

  ViewVC Help
Powered by ViewVC 1.1.22