/[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.7 - (show annotations) (download)
Fri Feb 28 02:34:56 2003 UTC (21 years, 3 months ago) by heimbach
Branch: MAIN
CVS Tags: checkpoint50c_post, checkpoint50c_pre, checkpoint48i_post, checkpoint50, checkpoint50d_post, checkpoint50b_pre, checkpoint50f_post, checkpoint50a_post, checkpoint50f_pre, checkpoint50g_post, checkpoint50h_post, checkpoint50e_pre, checkpoint50i_post, checkpoint50e_post, checkpoint50d_pre, checkpoint49, checkpoint50b_post
Changes since 1.6: +215 -161 lines
Committing updated and merged grdchk package
- has both ADM and TLM checks
- works for single- and multi-proc.
- output cleaned
- worked successfully for parallel DIVA

1 C $Header: /u/gcmpack/MITgcm/pkg/grdchk/grdchk_main.F,v 1.3.6.1 2002/05/30 19:55:17 heimbach Exp $
2
3 #include "CPP_OPTIONS.h"
4
5 CBOI
6 C
7 C !TITLE: GRADIENT CHECK
8 C !AUTHORS: mitgcm developers ( support@mitgcm.org )
9 C !AFFILIATION: Massachussetts Institute of Technology
10 C !DATE:
11 C !INTRODUCTION: gradient check package
12 c \bv
13 c Compare the gradients calculated by the adjoint model with
14 c finite difference approximations.
15 c
16 C !CALLING SEQUENCE:
17 c
18 c the_model_main
19 c |
20 c |-- ctrl_unpack
21 c |-- adthe_main_loop - unperturbed cost function and
22 c |-- ctrl_pack adjoint gradient are computed here
23 c |
24 c |-- grdchk_main
25 c |
26 c |-- grdchk_init
27 c |-- do icomp=... - loop over control vector elements
28 c |
29 c |-- grdchk_loc - determine location of icomp on grid
30 c |
31 c |-- grdchk_getxx - get control vector component from file
32 c | perturb it and write back to file
33 c |-- grdchk_getadxx - get gradient component calculated
34 c | via adjoint
35 c |-- the_main_loop - forward run and cost evaluation
36 c | with perturbed control vector element
37 c |-- calculate ratio of adj. vs. finite difference gradient
38 c |
39 c |-- grdchk_setxx - Reset control vector element
40 c |
41 c |-- grdchk_print - print results
42 c \ev
43 CEOI
44
45 CBOP
46 C !ROUTINE: grdchk_main
47 C !INTERFACE:
48 subroutine grdchk_main( mythid )
49
50 C !DESCRIPTION: \bv
51 c ==================================================================
52 c SUBROUTINE grdchk_main
53 c ==================================================================
54 c o Compare the gradients calculated by the adjoint model with
55 c finite difference approximations.
56 c started: Christian Eckert eckert@mit.edu 24-Feb-2000
57 c continued&finished: heimbach@mit.edu: 13-Jun-2001
58 c changed: mlosch@ocean.mit.edu: 09-May-2002
59 c - added centered difference vs. 1-sided difference option
60 c - improved output format for readability
61 c - added control variable hFacC
62 c heimbach@mit.edu 24-Feb-2003
63 c - added tangent linear gradient checks
64 c - fixes for multiproc. gradient checks
65 c - added more control variables
66 c
67 c ==================================================================
68 c SUBROUTINE grdchk_main
69 c ==================================================================
70 C \ev
71
72 C !USES:
73 implicit none
74
75 c == global variables ==
76 #include "SIZE.h"
77 #include "EEPARAMS.h"
78 #include "PARAMS.h"
79 #include "grdchk.h"
80 #include "cost.h"
81
82 C !INPUT/OUTPUT PARAMETERS:
83 c == routine arguments ==
84 integer mythid
85
86 #ifdef ALLOW_GRADIENT_CHECK
87 C !LOCAL VARIABLES:
88 c == local variables ==
89 integer myiter
90 _RL mytime
91 integer bi, itlo, ithi
92 integer bj, jtlo, jthi
93 integer i, imin, imax
94 integer j, jmin, jmax
95 integer k
96
97 integer icomp
98 integer ichknum
99 integer icvrec
100 integer jtile
101 integer itile
102 integer layer
103 integer itilepos
104 integer jtilepos
105 integer itest
106 integer ierr
107 integer ierr_grdchk
108 _RL gfd
109 _RL fcref
110 _RL fcpertplus, fcpertminus
111 _RL ratio_ad
112 _RL ratio_ftl
113 _RL xxmemo_ref
114 _RL xxmemo_pert
115 _RL adxxmemo
116 _RL ftlxxmemo
117 _RL localEps
118 _RL grdchk_epsfac
119
120 _RL tmpplot1(1-olx:snx+olx,1-oly:sny+oly,nr,nsx,nsy)
121 _RL tmpplot2(1-olx:snx+olx,1-oly:sny+oly,nr,nsx,nsy)
122 _RL tmpplot3(1-olx:snx+olx,1-oly:sny+oly,nr,nsx,nsy)
123
124 #ifdef ALLOW_TANGENTLINEAR_RUN
125 _RL g_fc
126 common /g_cost_r/ g_fc
127 #endif
128
129 c == end of interface ==
130 CEOP
131
132 c-- Set the loop ranges.
133 jtlo = mybylo(mythid)
134 jthi = mybyhi(mythid)
135 itlo = mybxlo(mythid)
136 ithi = mybxhi(mythid)
137 jmin = 1
138 jmax = sny
139 imin = 1
140 imax = snx
141
142 c-- initialise variables
143 call grdchk_init( mythid )
144
145 c-- Compute the adjoint models' gradients.
146 c-- Compute the unperturbed cost function.
147 cph Gradient via adjoint has already been computed,
148 cph and so has unperturbed cost function,
149 cph assuming all xx_ fields are initialised to zero.
150
151 fcref = fc
152 ierr_grdchk = 0
153
154 do bj = jtlo, jthi
155 do bi = itlo, ithi
156 do k = 1, nr
157 do j = jmin, jmax
158 do i = imin, imax
159 tmpplot1(i,j,k,bi,bj) = 0. _d 0
160 tmpplot2(i,j,k,bi,bj) = 0. _d 0
161 tmpplot3(i,j,k,bi,bj) = 0. _d 0
162 end do
163 end do
164 end do
165 end do
166 end do
167
168 if ( useCentralDiff ) then
169 grdchk_epsfac = 2. _d 0
170 else
171 grdchk_epsfac = 1. _d 0
172 end if
173
174 print *, 'ph-grd 3 -------------------------------'
175 print ('(2a)'),
176 & ' ph-grd 3 proc # i j k fc ref',
177 & ' fc + eps fc - eps'
178 #ifdef ALLOW_TANGENTLINEAR_RUN
179 print ('(2a)'),
180 & ' ph-grd 3 proc # i j k tlm grad',
181 & ' fd grad 1 - fd/tlm'
182 #else
183 print ('(2a)'),
184 & ' ph-grd 3 proc # i j k adj grad',
185 & ' fd grad 1 - fd/adj'
186 #endif
187
188 c-- Compute the finite difference approximations.
189 c-- Cycle through all processes doing NINT(nend-nbeg+1)/nstep
190 c-- gradient checks.
191
192 do icomp = nbeg, nend, nstep
193
194 ichknum = (icomp - nbeg)/nstep + 1
195
196 if (ichknum .le. maxgrdchecks ) then
197
198 c-- Determine the location of icomp on the grid.
199 if ( myProcId .EQ. grdchkwhichproc ) then
200 call grdchk_loc( icomp, ichknum,
201 & icvrec, itile, jtile, layer,
202 & itilepos, jtilepos, itest, ierr,
203 & mythid )
204 endif
205 _BARRIER
206
207 c******************************************************
208 c-- (A): get gradient component calculated via adjoint
209 c******************************************************
210
211 c-- get gradient component calculated via adjoint
212 if ( myProcId .EQ. grdchkwhichproc .AND.
213 & ierr .EQ. 0 ) then
214 call grdchk_getadxx( icvrec,
215 & itile, jtile, layer,
216 & itilepos, jtilepos,
217 & adxxmemo, mythid )
218 endif
219 _BARRIER
220
221 #ifdef ALLOW_TANGENTLINEAR_RUN
222 c******************************************************
223 c-- (B): Get gradient component g_fc from tangent linear run:
224 c******************************************************
225 c--
226 c-- 1. perturb control vector component: xx(i)=1.
227
228 if ( myProcId .EQ. grdchkwhichproc .AND.
229 & ierr .EQ. 0 ) then
230 localEps = 1. _d 0
231 call grdchk_getxx( icvrec, TANGENT_SIMULATION,
232 & itile, jtile, layer,
233 & itilepos, jtilepos,
234 & xxmemo_ref, xxmemo_pert, localEps,
235 & mythid )
236 endif
237 _BARRIER
238
239 c--
240 c-- 2. perform tangent linear run
241 mytime = starttime
242 myiter = niter0
243 g_fc = 0.
244 call g_the_main_loop( mytime, myiter, mythid )
245 ftlxxmemo = g_fc
246 _BARRIER
247 c--
248 c-- 3. reset control vector
249 if ( myProcId .EQ. grdchkwhichproc .AND.
250 & ierr .EQ. 0 ) then
251 call grdchk_setxx( icvrec, TANGENT_SIMULATION,
252 & itile, jtile, layer,
253 & itilepos, jtilepos,
254 & xxmemo_ref, mythid )
255 endif
256 _BARRIER
257
258 #endif /* ALLOW_TANGENTLINEAR_RUN */
259
260
261 c******************************************************
262 c-- (C): Get gradient via finite difference perturbation
263 c******************************************************
264
265 c-- get control vector component from file
266 c-- perturb it and write back to file
267 c-- positive perturbation
268 localEps = abs(grdchk_eps)
269 if ( myProcId .EQ. grdchkwhichproc .AND.
270 & ierr .EQ. 0 ) then
271 call grdchk_getxx( icvrec, FORWARD_SIMULATION,
272 & itile, jtile, layer,
273 & itilepos, jtilepos,
274 & xxmemo_ref, xxmemo_pert, localEps,
275 & mythid )
276 endif
277 _BARRIER
278
279 c-- forward run with perturbed control vector
280 mytime = starttime
281 myiter = niter0
282 call the_main_loop( mytime, myiter, mythid )
283 fcpertplus = fc
284 _BARRIER
285
286 c-- Reset control vector.
287 if ( myProcId .EQ. grdchkwhichproc .AND.
288 & ierr .EQ. 0 ) then
289 call grdchk_setxx( icvrec, FORWARD_SIMULATION,
290 & itile, jtile, layer,
291 & itilepos, jtilepos,
292 & xxmemo_ref, mythid )
293 endif
294 _BARRIER
295
296 fcpertminus = fcref
297
298 if ( useCentralDiff ) then
299
300 c-- get control vector component from file
301 c-- perturb it and write back to file
302 c-- repeat the proceedure for a negative perturbation
303 if ( myProcId .EQ. grdchkwhichproc .AND.
304 & ierr .EQ. 0 ) then
305 localEps = - abs(grdchk_eps)
306 call grdchk_getxx( icvrec, FORWARD_SIMULATION,
307 & itile, jtile, layer,
308 & itilepos, jtilepos,
309 & xxmemo_ref, xxmemo_pert, localEps,
310 & mythid )
311 endif
312 _BARRIER
313
314 c-- forward run with perturbed control vector
315 mytime = starttime
316 myiter = niter0
317 call the_main_loop( mytime, myiter, mythid )
318 _BARRIER
319 fcpertminus = fc
320
321 c-- Reset control vector.
322 if ( myProcId .EQ. grdchkwhichproc .AND.
323 & ierr .EQ. 0 ) then
324 call grdchk_setxx( icvrec, FORWARD_SIMULATION,
325 & itile, jtile, layer,
326 & itilepos, jtilepos,
327 & xxmemo_ref, mythid )
328 endif
329 _BARRIER
330
331 c-- end of if useCentralDiff ...
332 end if
333
334 c******************************************************
335 c-- (D): calculate relative differences between gradients
336 c******************************************************
337
338 if ( myProcId .EQ. grdchkwhichproc .AND.
339 & ierr .EQ. 0 ) then
340
341 if ( grdchk_eps .eq. 0. ) then
342 gfd = (fcpertplus-fcpertminus)
343 else
344 gfd = (fcpertplus-fcpertminus)
345 & /(grdchk_epsfac*grdchk_eps)
346 endif
347
348 if ( adxxmemo .eq. 0. ) then
349 ratio_ad = abs( adxxmemo - gfd )
350 else
351 ratio_ad = 1. - gfd/adxxmemo
352 endif
353
354 if ( ftlxxmemo .eq. 0. ) then
355 ratio_ftl = abs( ftlxxmemo - gfd )
356 else
357 ratio_ftl = 1. - gfd/ftlxxmemo
358 endif
359
360 tmpplot1(itilepos,jtilepos,layer,itile,jtile)
361 & = gfd
362 tmpplot2(itilepos,jtilepos,layer,itile,jtile)
363 & = ratio_ad
364 tmpplot3(itilepos,jtilepos,layer,itile,jtile)
365 & = ratio_ftl
366
367 fcrmem ( ichknum ) = fcref
368 fcppmem ( ichknum ) = fcpertplus
369 fcpmmem ( ichknum ) = fcpertminus
370 xxmemref ( ichknum ) = xxmemo_ref
371 xxmempert ( ichknum ) = xxmemo_pert
372 gfdmem ( ichknum ) = gfd
373 adxxmem ( ichknum ) = adxxmemo
374 ftlxxmem ( ichknum ) = ftlxxmemo
375 ratioadmem ( ichknum ) = ratio_ad
376 ratioftlmem ( ichknum ) = ratio_ftl
377
378 irecmem ( ichknum ) = icvrec
379 bimem ( ichknum ) = itile
380 bjmem ( ichknum ) = jtile
381 ilocmem ( ichknum ) = itilepos
382 jlocmem ( ichknum ) = jtilepos
383 klocmem ( ichknum ) = layer
384 icompmem ( ichknum ) = icomp
385 ichkmem ( ichknum ) = ichknum
386 itestmem ( ichknum ) = itest
387 ierrmem ( ichknum ) = ierr
388
389 print *, 'ph-grd 3 -------------------------------'
390 print '(a,5I5,2x,3(1x,E15.9))', ' ph-grd 3 ',
391 & myprocid,ichknum,itilepos,jtilepos,layer,
392 & fcref, fcpertplus, fcpertminus
393 #ifdef ALLOW_TANGENTLINEAR_RUN
394 print '(a,5I5,2x,3(1x,E15.9))', ' ph-grd 3 ',
395 & myprocid,ichknum,ichkmem(ichknum),
396 & icompmem(ichknum),itestmem(ichknum),
397 & ftlxxmemo, gfd, ratio_ftl
398 #else
399 print '(a,5I5,2x,3(1x,E15.9))', ' ph-grd 3 ',
400 & myprocid,ichknum,ichkmem(ichknum),
401 & icompmem(ichknum),itestmem(ichknum),
402 & adxxmemo, gfd, ratio_ad
403 #endif
404
405 endif
406
407 print *, 'ph-grd ierr ---------------------------'
408 print *, 'ph-grd ierr = ', ierr, ', icomp = ', icomp,
409 & ', ichknum = ', ichknum
410
411 _BARRIER
412
413 c-- else of if ( ichknum ...
414 else
415 ierr_grdchk = -1
416
417 c-- end of if ( ichknum ...
418 endif
419
420 c-- end of do icomp = ...
421 enddo
422
423 if ( myProcId .EQ. grdchkwhichproc ) then
424 CALL WRITE_REC_XYZ_RL(
425 & 'grd_findiff' , tmpplot1, 1, 0, myThid)
426 CALL WRITE_REC_XYZ_RL(
427 & 'grd_ratio_ad' , tmpplot2, 1, 0, myThid)
428 CALL WRITE_REC_XYZ_RL(
429 & 'grd_ratio_ftl' , tmpplot3, 1, 0, myThid)
430 endif
431
432 c-- Everyone has to wait for the component to be reset.
433 _BARRIER
434
435 c-- Print the results of the gradient check.
436 call grdchk_print( ichknum, ierr_grdchk, mythid )
437
438 #endif /* ALLOW_GRADIENT_CHECK */
439
440 end

  ViewVC Help
Powered by ViewVC 1.1.22