/[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.10 - (show annotations) (download)
Thu Oct 23 04:41:40 2003 UTC (20 years, 6 months ago) by edhill
Branch: MAIN
CVS Tags: checkpoint51o_pre, checkpoint51n_post, checkpoint51n_pre
Branch point for: checkpoint51n_branch
Changes since 1.9: +4 -1 lines
 o added the [#include "AD_CONFIG.h"] statement to all files that need
   it for adjoint/tl #defines
 o re-worked the build logic in genmake2 to support AD_CONFIG.h
 o removed tools/genmake since it no longer works

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

  ViewVC Help
Powered by ViewVC 1.1.22