/[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.12 - (show annotations) (download)
Tue Nov 4 20:47:42 2003 UTC (20 years, 7 months ago) by heimbach
Branch: MAIN
CVS Tags: hrcube4, checkpoint52d_pre, checkpoint52j_pre, checkpoint52, checkpoint52f_post, checkpoint51t_post, checkpoint52i_pre, hrcube_1, hrcube_2, hrcube_3, checkpoint51s_post, checkpoint52e_pre, checkpoint52e_post, checkpoint52b_pre, checkpoint52b_post, checkpoint52c_post, checkpoint52f_pre, checkpoint52d_post, checkpoint52a_pre, checkpoint52i_post, checkpoint52h_pre, checkpoint52j_post, branch-netcdf, checkpoint52a_post, ecco_c52_e35, checkpoint51u_post
Branch point for: netcdf-sm0
Changes since 1.11: +19 -9 lines
o merged from ecco-branch
  (remaining bug fixes for obcs gradient checks)
o additional high-precision output for testreport
  (grep for precision_grdchk_result)

1 C
2 C $Header: /u/gcmpack/MITgcm/pkg/grdchk/grdchk_main.F,v 1.11 2003/10/27 22:32:55 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 _BARRIER
307
308 c-- Reset control vector.
309 if ( myProcId .EQ. grdchkwhichproc .AND.
310 & ierr .EQ. 0 ) then
311 call grdchk_setxx( icvrec, FORWARD_SIMULATION,
312 & itile, jtile, layer,
313 & itilepos, jtilepos,
314 & xxmemo_ref, mythid )
315 endif
316 _BARRIER
317
318 fcpertminus = fcref
319
320 if ( useCentralDiff ) then
321
322 c-- get control vector component from file
323 c-- perturb it and write back to file
324 c-- repeat the proceedure for a negative perturbation
325 if ( myProcId .EQ. grdchkwhichproc .AND.
326 & ierr .EQ. 0 ) then
327 localEps = - abs(grdchk_eps)
328 call grdchk_getxx( icvrec, FORWARD_SIMULATION,
329 & itile, jtile, layer,
330 & itilepos, jtilepos,
331 & xxmemo_ref, xxmemo_pert, localEps,
332 & mythid )
333 endif
334 _BARRIER
335
336 c-- forward run with perturbed control vector
337 mytime = starttime
338 myiter = niter0
339 call the_main_loop( mytime, myiter, mythid )
340 _BARRIER
341 fcpertminus = fc
342
343 c-- Reset control vector.
344 if ( myProcId .EQ. grdchkwhichproc .AND.
345 & ierr .EQ. 0 ) then
346 call grdchk_setxx( icvrec, FORWARD_SIMULATION,
347 & itile, jtile, layer,
348 & itilepos, jtilepos,
349 & xxmemo_ref, mythid )
350 endif
351 _BARRIER
352
353 c-- end of if useCentralDiff ...
354 end if
355
356 c******************************************************
357 c-- (D): calculate relative differences between gradients
358 c******************************************************
359
360 if ( myProcId .EQ. grdchkwhichproc .AND.
361 & ierr .EQ. 0 ) then
362
363 if ( grdchk_eps .eq. 0. ) then
364 gfd = (fcpertplus-fcpertminus)
365 else
366 gfd = (fcpertplus-fcpertminus)
367 & /(grdchk_epsfac*grdchk_eps)
368 endif
369
370 if ( adxxmemo .eq. 0. ) then
371 ratio_ad = abs( adxxmemo - gfd )
372 else
373 ratio_ad = 1. - gfd/adxxmemo
374 endif
375
376 if ( ftlxxmemo .eq. 0. ) then
377 ratio_ftl = abs( ftlxxmemo - gfd )
378 else
379 ratio_ftl = 1. - gfd/ftlxxmemo
380 endif
381
382 tmpplot1(itilepos,jtilepos,layer,itile,jtile)
383 & = gfd
384 tmpplot2(itilepos,jtilepos,layer,itile,jtile)
385 & = ratio_ad
386 tmpplot3(itilepos,jtilepos,layer,itile,jtile)
387 & = ratio_ftl
388
389 fcrmem ( ichknum ) = fcref
390 fcppmem ( ichknum ) = fcpertplus
391 fcpmmem ( ichknum ) = fcpertminus
392 xxmemref ( ichknum ) = xxmemo_ref
393 xxmempert ( ichknum ) = xxmemo_pert
394 gfdmem ( ichknum ) = gfd
395 adxxmem ( ichknum ) = adxxmemo
396 ftlxxmem ( ichknum ) = ftlxxmemo
397 ratioadmem ( ichknum ) = ratio_ad
398 ratioftlmem ( ichknum ) = ratio_ftl
399
400 irecmem ( ichknum ) = icvrec
401 bimem ( ichknum ) = itile
402 bjmem ( ichknum ) = jtile
403 ilocmem ( ichknum ) = itilepos
404 jlocmem ( ichknum ) = jtilepos
405 klocmem ( ichknum ) = layer
406 iobcsmem ( ichknum ) = obcspos
407 icompmem ( ichknum ) = icomp
408 ichkmem ( ichknum ) = ichknum
409 itestmem ( ichknum ) = itest
410 ierrmem ( ichknum ) = ierr
411
412 print *, 'grad-res -------------------------------'
413 print '(a,5I5,2x,3(1x,E15.9))', ' grad-res ',
414 & myprocid,ichknum,itilepos,jtilepos,layer,
415 & fcref, fcpertplus, fcpertminus
416 #ifdef ALLOW_TANGENTLINEAR_RUN
417 print '(a,5I5,2x,3(1x,E15.9))', ' grad-res ',
418 & myprocid,ichknum,ichkmem(ichknum),
419 & icompmem(ichknum),itestmem(ichknum),
420 & ftlxxmemo, gfd, ratio_ftl
421 WRITE(msgBuf,'(A34,2(1PE24.14,X))')
422 & 'precision_grdchk_result TLM ', fcref, ftlxxmemo
423 CALL PRINT_MESSAGE
424 & (msgBuf,standardMessageUnit,SQUEEZE_RIGHT,1)
425 #else
426 print '(a,5I5,2x,3(1x,E15.9))', ' grad-res ',
427 & myprocid,ichknum,ichkmem(ichknum),
428 & icompmem(ichknum),itestmem(ichknum),
429 & adxxmemo, gfd, ratio_ad
430 WRITE(msgBuf,'(A34,2(1PE24.14,X))')
431 & 'precision_grdchk_result ADM ', fcref, adxxmemo
432 CALL PRINT_MESSAGE
433 & (msgBuf,standardMessageUnit,SQUEEZE_RIGHT,1)
434 #endif
435
436 endif
437
438 print *, 'ph-grd ierr ---------------------------'
439 print *, 'ph-grd ierr = ', ierr, ', icomp = ', icomp,
440 & ', ichknum = ', ichknum
441
442 _BARRIER
443
444 c-- else of if ( ichknum ...
445 else
446 ierr_grdchk = -1
447
448 c-- end of if ( ichknum ...
449 endif
450
451 c-- end of do icomp = ...
452 enddo
453
454 if ( myProcId .EQ. grdchkwhichproc ) then
455 CALL WRITE_REC_XYZ_RL(
456 & 'grd_findiff' , tmpplot1, 1, 0, myThid)
457 CALL WRITE_REC_XYZ_RL(
458 & 'grd_ratio_ad' , tmpplot2, 1, 0, myThid)
459 CALL WRITE_REC_XYZ_RL(
460 & 'grd_ratio_ftl' , tmpplot3, 1, 0, myThid)
461 endif
462
463 c-- Everyone has to wait for the component to be reset.
464 _BARRIER
465
466 c-- Print the results of the gradient check.
467 call grdchk_print( ichknum, ierr_grdchk, mythid )
468
469 #endif /* ALLOW_GRDCHK */
470
471 end

  ViewVC Help
Powered by ViewVC 1.1.22