/[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.17 - (show annotations) (download)
Fri May 12 02:17:03 2006 UTC (18 years ago) by heimbach
Branch: MAIN
CVS Tags: checkpoint58f_post, checkpoint58m_post, checkpoint58o_post, checkpoint58p_post, checkpoint58q_post, checkpoint58e_post, checkpoint58n_post, checkpoint58k_post, checkpoint58l_post, checkpoint58g_post, checkpoint58h_post, checkpoint58j_post, checkpoint58i_post
Changes since 1.16: +3 -2 lines
o Adding diffkr, kapgm to gradient check list
o Fix k-loop problem

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

  ViewVC Help
Powered by ViewVC 1.1.22