ROMS
Loading...
Searching...
No Matches
split_rbl4dvar_roms.h
Go to the documentation of this file.
1 MODULE roms_kernel_mod
2!
3!git $Id$
4!================================================== Hernan G. Arango ===
5! Copyright (c) 2002-2025 The ROMS Group Andrew M. Moore !
6! Licensed under a MIT/X style license !
7! See License_ROMS.md !
8!=======================================================================
9! !
10! ROMS Strong/Weak Constraint Split 4-Dimensional Variational Data !
11! Assimilation Driver: Restricted, B-preconditoned Lanczos !
12! (RBL4D-Var) !
13! !
14! This driver is used for the dual formulation (observation space), !
15! strong or weak constraint 4D-Var where errors may be considered !
16! in both model and observations. !
17! !
18! The RBL4D-Var algorithm is split into multiple executables to !
19! facilitate various configurations: !
20! !
21! (1) Executable A computes ROMS nonlinear trajectory used to !
22! linearize the tangent linear and adjoint models used in !
23! the iterations of the inner loop for the minimization of !
24! the cost function. It allows the nonlinear trajectory to !
25! be part of a coupling system and or include nested grids. !
26! It calls either the RBL4D-Var "background" or "analysis" !
27! routines. !
28! !
29! (2) Executable B calls either RBL4D-Var "increment" or !
30! "posterior_error". The RBL4D-Var increment is obtained !
31! by minimizing the cost function over Ninner loops. It is !
32! possible to use a coarser grid resolution in the inner !
33! loop. If so, the finer background trajectory needs to !
34! be interpolated into the coarser grid. Then, at the end !
35! of inner loops, the coarse grid increment needs to be !
36! interpolated to the finer grid. The increment phase !
37! may be run at a lower precision. !
38! !
39! The routines in this driver control the initialization, time- !
40! stepping, and finalization of ROMS model following ESMF/NUOPC !
41! conventions: !
42! !
43! ROMS_initialize !
44! ROMS_run !
45! ROMS_finalize !
46! !
47! References: !
48! !
49! Moore, A.M., H.G. Arango, G. Broquet, B.S. Powell, A.T. Weaver, !
50! and J. Zavala-Garay, 2011: The Regional Ocean Modeling System !
51! (ROMS) 4-dimensional variational data assimilations systems, !
52! Part I - System overview and formulation, Prog. Oceanogr., 91, !
53! 34-49, doi:10.1016/j.pocean.2011.05.004. !
54! !
55! Moore, A.M., H.G. Arango, G. Broquet, C. Edward, M. Veneziani, !
56! B. Powell, D. Foley, J.D. Doyle, D. Costa, and P. Robinson, !
57! 2011: The Regional Ocean Modeling System (ROMS) 4-dimensional !
58! variational data assimilations systems, Part II - Performance !
59! and application to the California Current System, Prog. !
60! Oceanogr., 91, 50-73, doi:10.1016/j.pocean.2011.05.003. !
61! !
62! Gurol, S., A.T. Weaver, A.M. Moore, A. Piacentini, H.G. Arango, !
63! S. Gratton, 2014: B-preconditioned minimization algorithms for !
64! data assimilation with the dual formulation, QJRMS, 140, !
65! 539-556. !
66! !
67!=======================================================================
68!
69 USE mod_param
70 USE mod_parallel
71 USE mod_arrays
72 USE mod_fourdvar
73 USE mod_iounits
74 USE mod_ncparam
75 USE mod_scalars
76 USE mod_stepping
77!
78 USE rbl4dvar_mod
79!
81 USE def_dai_mod, ONLY : def_dai
82 USE inp_par_mod, ONLY : inp_par
83#ifdef MCT_LIB
84# ifdef ATM_COUPLING
85 USE mct_coupler_mod, ONLY : initialize_ocn2atm_coupling
86# endif
87# ifdef WAV_COUPLING
88 USE mct_coupler_mod, ONLY : initialize_ocn2wav_coupling
89# endif
90#endif
92 USE stdinp_mod, ONLY : getpar_i, getpar_s
95 USE wrt_dai_mod, ONLY : wrt_dai
96 USE wrt_rst_mod, ONLY : wrt_rst
97!
98 implicit none
99!
100 PUBLIC :: roms_initialize
101 PUBLIC :: roms_run
102 PUBLIC :: roms_finalize
103!
104 CONTAINS
105!
106 SUBROUTINE roms_initialize (first, mpiCOMM)
107!
108!=======================================================================
109! !
110! This routine allocates and initializes ROMS state variables and !
111! internal parameters. It reads standard input parameters. !
112! !
113!=======================================================================
114!
115! Imported variable declarations.
116!
117 logical, intent(inout) :: first
118
119 integer, intent(in), optional :: mpiCOMM
120!
121! Local variable declarations.
122!
123 logical :: allocate_vars = .true.
124!
125#ifdef DISTRIBUTE
126 integer :: MyError, MySize
127#endif
128 integer :: chunk_size, ng, thread
129#if defined MODEL_COUPLING && defined ESMF_LIB
130 integer :: my_outer
131#endif
132#ifdef _OPENMP
133 integer :: my_threadnum
134#endif
135!
136 character (len=*), parameter :: MyFile = &
137 & __FILE__//", ROMS_initialize"
138
139#ifdef DISTRIBUTE
140!
141!-----------------------------------------------------------------------
142! Set distribute-memory (mpi) world communictor.
143!-----------------------------------------------------------------------
144!
145 IF (PRESENT(mpicomm)) THEN
146 ocn_comm_world=mpicomm
147 ELSE
148 ocn_comm_world=mpi_comm_world
149 END IF
150 CALL mpi_comm_rank (ocn_comm_world, myrank, myerror)
151 CALL mpi_comm_size (ocn_comm_world, mysize, myerror)
152#endif
153!
154!-----------------------------------------------------------------------
155! On first pass, initialize model parameters a variables for all
156! nested/composed grids. Notice that the logical switch "first"
157! is used to allow multiple calls to this routine during ensemble
158! configurations.
159!-----------------------------------------------------------------------
160!
161 IF (first) THEN
162 first=.false.
163!
164! Initialize parallel control switches. These scalars switches are
165! independent from standard input parameters.
166!
168!
169! Set the ROMS standard output unit to write verbose execution info.
170! Notice that the default standard out unit in Fortran is 6.
171!
172! In some applications like coupling or disjointed mpi-communications,
173! it is advantageous to write standard output to a specific filename
174! instead of the default Fortran standard output unit 6. If that is
175! the case, it opens such formatted file for writing.
176!
177 IF (set_stdoutunit) THEN
179 set_stdoutunit=.false.
180 END IF
181!
182! Get 4D-Var phase from APARNAM input script file.
183!
184 CALL getpar_s (master, aparnam, 'APARNAM')
185 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
186!
187 CALL getpar_i (master, outerloop, 'OuterLoop', aparnam)
188 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
189!
190 CALL getpar_s (master, phase4dvar, 'Phase4DVAR', aparnam)
191 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
192!
193! Determine ROMS standard output append switch. It is only relevant if
194! "ROMS_STDINP" is activated. The standard output is created in the
195! "background" phase and open to append in the other phases. Set
196! switch so the "stiffness" routine is only called in the "background"
197! phase.
198!
199 IF (index(trim(uppercase(phase4dvar)),'BACKG').ne.0) THEN
200 lappend=.false.
201 lstiffness=.true.
202 ELSE
203 lappend=.true.
204 lstiffness=.false.
205 END IF
206!
207! Read in model tunable parameters from standard input. Allocate and
208! initialize variables in several modules after the number of nested
209! grids and dimension parameters are known.
210!
211 CALL inp_par (inlm)
212 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
213!
214! Initialize counters. The 'Nrun' counter will be recomputed in the
215! RBL4D-Var phases to process the obervation operator correctly.
216!
217 nrun=1 ! run counter
218 erstr=1 ! ensemble start counter
219 erend=nouter ! ensemble end counter
220!
221! Set domain decomposition tile partition range. This range is
222! computed only once since the "first_tile" and "last_tile" values
223! are private for each parallel thread/node.
224!
225#if defined _OPENMP
226 mythread=my_threadnum()
227#elif defined DISTRIBUTE
229#else
230 mythread=0
231#endif
232 DO ng=1,ngrids
233 chunk_size=(ntilex(ng)*ntilee(ng)+numthreads-1)/numthreads
234 first_tile(ng)=mythread*chunk_size
235 last_tile(ng)=first_tile(ng)+chunk_size-1
236 END DO
237!
238! Initialize internal wall clocks. Notice that the timings does not
239! includes processing standard input because several parameters are
240! needed to allocate clock variables.
241!
242 IF (master) THEN
243 WRITE (stdout,10)
244 10 FORMAT (/,' Process Information:',/)
245 END IF
246!
247 DO ng=1,ngrids
248 DO thread=thread_range
249 CALL wclock_on (ng, inlm, 0, __line__, myfile)
250 END DO
251 END DO
252!
253! Allocate and initialize modules variables.
254!
255 CALL roms_allocate_arrays (allocate_vars)
257 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
258
259 END IF
260
261#if defined MCT_LIB && (defined ATM_COUPLING || defined WAV_COUPLING)
262!
263!-----------------------------------------------------------------------
264! Initialize coupling streams between model(s).
265!-----------------------------------------------------------------------
266!
267 DO ng=1,ngrids
268# ifdef ATM_COUPLING
269 CALL initialize_ocn2atm_coupling (ng, myrank)
270# endif
271# ifdef WAV_COUPLING
272 CALL initialize_ocn2wav_coupling (ng, myrank)
273# endif
274 END DO
275#endif
276
277#if defined MODEL_COUPLING && defined ESMF_LIB
278!
279!-----------------------------------------------------------------------
280! In ESM couppling applications that use generic methods for
281! 'initialize', 'run', and 'finalize', the initialization of the
282! nonlinear model kernel is separated from the 'background' and
283! 'analysis' 4D-Var phases.
284!-----------------------------------------------------------------------
285!
286 SELECT CASE (uppercase(phase4dvar(1:6)))
287 CASE ('BACKGR')
288 my_outer=outerloop
289 outer=0
290 inner=0
291 CALL background_initialize (my_outer)
292 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
293 CASE ('ANALYS')
294 my_outer=outerloop
297 CALL analysis_initialize (my_outer)
298 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
299 CASE DEFAULT
300 IF (master) THEN
301 WRITE (stdout,20) trim(phase4dvar)
302 20 FORMAT (' ROMS_initialize - illegal 4D-Var phase: ''', &
303 & a,'''')
304 END IF
305 exit_flag=5
306 RETURN
307 END SELECT
308#endif
309!
310!-----------------------------------------------------------------------
311! Set application grid, metrics, and associated variables. Then,
312! proccess background and model prior error covariance standard
313! deviations and normalization coefficients.
314!-----------------------------------------------------------------------
315!
316 DO ng=1,ngrids
317#ifdef STD_MODEL
318 lwrtstd(ng)=.true.
319 IF (index(trim(uppercase(phase4dvar)),'BACKG').ne.0) THEN
320 ldefstd(ng)=.true.
321 lreadstd(ng)=.false.
322 ELSE
323 ldefstd(ng)=.false.
324 lreadstd(ng)=.true.
325 END IF
326#else
327 lreadstd(ng)=.true.
328#endif
329 CALL prior_error (ng)
330 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
331 setgridconfig(ng)=.false.
332 END DO
333!
334 RETURN
335 END SUBROUTINE roms_initialize
336!
337 SUBROUTINE roms_run (RunInterval)
338!
339!=======================================================================
340! !
341! This routine runs the Strong or Weak constraint, Restricted, !
342! B-preconditioned Lanczos 4D-Var data assimilation (W4D-RBLancsos) !
343! algorithm. It time-steps ROMS nonlinear, tangent linear and !
344! adjoint kernels. !
345! !
346! On Input: !
347! !
348! RunInterval Execution time stepping window (seconds) !
349! !
350!=======================================================================
351!
352! Imported variable declarations
353!
354 real(dp), intent(in) :: RunInterval
355!
356! Local variable declarations.
357!
358 integer :: my_outer, ng
359
360 character (len=*), parameter :: MyFile = &
361 & __FILE__//", ROMS_run"
362!
363 sourcefile=myfile
364!
365!=======================================================================
366! Run Split RBL4D-Var Data Assimilation algorithm.
367!=======================================================================
368!
369! Initialize several global parameters.
370!
371 DO ng=1,ngrids
372#if defined ADJUST_STFLUX || defined ADJUST_WSTRESS
373 lfinp(ng)=1 ! forcing index for input
374 lfout(ng)=1 ! forcing index for output history files
375#endif
376#ifdef ADJUST_BOUNDARY
377 lbinp(ng)=1 ! boundary index for input
378 lbout(ng)=1 ! boundary index for output history files
379#endif
380 lold(ng)=1 ! old minimization time index
381 lnew(ng)=2 ! new minimization time index
382 END DO
383!
384 ldone=.false. ! 4D-Var cycle finish switch
385!
386! Select RBL4D-Var phase to execute.
387!
388 SELECT CASE (uppercase(phase4dvar(1:6)))
389!
390! Compute nonlinear background state trajectory, Xb(t)|n-1. Interpolate
391! the background at the observation locations, and compute the quality
392! control accept/reject flag, ObsScale. The background state is used
393! to linearize the tangent linear and adjoint models during the
394! minimization.
395!
396 CASE ('BACKGR')
397
398 my_outer=0
399 outer=0
400 inner=0
401
402 CALL background (outer, runinterval)
403 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
404!
405! Compute 4D-Var data assimilation increment, dXa, by iterating over
406! the inner loops, and minimizing the cost function.
407!
408 CASE ('INCREM')
409
410 my_outer=outerloop
412 inner=0
413
414 CALL increment (my_outer, runinterval)
415 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
416!
417! Compute 4D-Var data assimilation analysis, Xa = Xb + dXa. Set
418! nonlinear model initial conditions for next outer loop.
419!
420 CASE ('ANALYS')
421
422 my_outer=outerloop
425
426 CALL analysis (my_outer, runinterval)
427 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
428
429#if defined POSTERIOR_ERROR_I || \
430 defined posterior_error_f || \
431 defined posterior_eofs
432!
433! Compute full (diagonal) posterior analysis error covariance matrix.
434! (NOTE: Currently, this code only works for a single outer-loop).
435!
436 CASE ('POST_E')
437
438 CALL posterior_error (runinterval)
439 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
440#endif
441!
442! Issue an error if incorrect 4D-Var phase.
443!
444 CASE DEFAULT
445
446 IF (master) THEN
447 WRITE (stdout,10) trim(phase4dvar)
448 10 FORMAT (' ROMS_run - illegal 4D-Var phase: ''',a,'''')
449 END IF
450 exit_flag=5
451 RETURN
452
453 END SELECT
454!
455! Set finish RBL4D-Var cycle switch.
456!
457 IF ((my_outer.eq.nouter).and. &
458#if defined POSTERIOR_ERROR_I || \
459 defined posterior_error_f || \
460 defined posterior_eofs
461 & (index(trim(uppercase(phase4dvar)),'POST_E').ne.0)) THEN
462 ldone=.true.
463#else
464 & (index(trim(uppercase(phase4dvar)),'ANALYS').ne.0)) THEN
465 ldone=.true.
466#endif
467 END IF
468!
469 RETURN
470 END SUBROUTINE roms_run
471!
472 SUBROUTINE roms_finalize
473!
474!=======================================================================
475! !
476! This routine terminates ROMS W4D-RBLanczos execution. !
477! !
478!=======================================================================
479!
480! Local variable declarations.
481!
482 integer :: Fcount, ng, thread
483!
484 character (len=*), parameter :: MyFile = &
485 & __FILE__//", ROMS_finalize"
486!
487!-----------------------------------------------------------------------
488! Create DAI NetCDF file and write out 4D-Var analysis fields that
489! used as initial conditions for the next data assimilation cycle.
490!-----------------------------------------------------------------------
491!
492 IF (ldone.and.(exit_flag.eq.noerror)) THEN
493 DO ng=1,ngrids
494 ldefdai(ng)=.true.
495 CALL def_dai (ng)
496 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
497!
498#ifdef DISTRIBUTE
499 CALL wrt_dai (ng, myrank)
500#else
501 CALL wrt_dai (ng, -1)
502#endif
503 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
504 END DO
505 END IF
506!
507!-----------------------------------------------------------------------
508! Compute and report model-observation comparison statistics.
509!-----------------------------------------------------------------------
510!
511 IF (ldone.or.(exit_flag.eq.1)) THEN
512 DO ng=1,ngrids
513#ifdef DISTRIBUTE
514 CALL stats_modobs (ng, myrank)
515#else
516 CALL stats_modobs (ng, -1)
517#endif
518 END DO
519 END IF
520!
521!-----------------------------------------------------------------------
522! If blowing-up, save latest model state into RESTART NetCDF file.
523!-----------------------------------------------------------------------
524!
525! If cycling restart records, write solution into record 3.
526!
527 IF (exit_flag.eq.1) THEN
528 DO ng=1,ngrids
529 IF (lwrtrst(ng)) THEN
530 IF (master) WRITE (stdout,10)
531 10 FORMAT (/,' Blowing-up: Saving latest model state into ', &
532 & ' RESTART file',/)
533 fcount=rst(ng)%load
534 IF (lcyclerst(ng).and.(rst(ng)%Nrec(fcount).ge.2)) THEN
535 rst(ng)%Rindex=2
536 lcyclerst(ng)=.false.
537 END IF
540#ifdef DISTRIBUTE
541 CALL wrt_rst (ng, myrank)
542#else
543 CALL wrt_rst (ng, -1)
544#endif
545 END IF
546 END DO
547 END IF
548!
549!-----------------------------------------------------------------------
550! Stop model and time profiling clocks, report memory requirements,
551! and close output NetCDF files.
552!-----------------------------------------------------------------------
553!
554! Stop time clocks.
555!
556 IF (master) THEN
557 WRITE (stdout,20)
558 20 FORMAT (/,'Elapsed wall CPU time for each process (seconds):',/)
559 END IF
560!
561 DO ng=1,ngrids
562 DO thread=thread_range
563 CALL wclock_off (ng, inlm, 0, __line__, myfile)
564 END DO
565 END DO
566!
567! Report dynamic memory and automatic memory requirements.
568!
569 CALL memory
570!
571! Close IO files.
572!
573 DO ng=1,ngrids
574 CALL close_inp (ng, inlm)
575 END DO
576 CALL close_out
577!
578 RETURN
579 END SUBROUTINE roms_finalize
580
581 END MODULE roms_kernel_mod
subroutine memory
Definition memory.F:3
subroutine, public close_out
Definition close_io.F:175
subroutine, public close_inp(ng, model)
Definition close_io.F:92
subroutine, public def_dai(ng)
Definition def_dai.F:52
subroutine, public inp_par(model)
Definition inp_par.F:56
subroutine, public roms_initialize_arrays
Definition mod_arrays.F:351
subroutine, public roms_allocate_arrays(allocate_vars)
Definition mod_arrays.F:114
character(len=256) aparnam
type(t_io), dimension(:), allocatable rst
integer stdout
character(len=256) sourcefile
subroutine, public initialize_parallel
integer numthreads
integer, dimension(:), allocatable first_tile
integer mythread
logical master
integer, dimension(:), allocatable last_tile
integer ocn_comm_world
integer, parameter inlm
Definition mod_param.F:662
integer, dimension(:), allocatable ntilex
Definition mod_param.F:685
integer ngrids
Definition mod_param.F:113
integer, dimension(:), allocatable ntilee
Definition mod_param.F:686
integer ninner
integer nouter
logical, dimension(:), allocatable lreadstd
logical lappend
logical, dimension(:), allocatable setgridconfig
logical lstiffness
integer blowup
integer outerloop
integer erend
integer exit_flag
integer erstr
character(len=20) phase4dvar
logical, dimension(:), allocatable lwrtrst
integer nrun
logical, dimension(:), allocatable ldefdai
integer inner
integer noerror
logical, dimension(:), allocatable lcyclerst
integer outer
integer, dimension(:), allocatable lold
integer, dimension(:), allocatable lbout
integer, dimension(:), allocatable lfinp
integer, dimension(:), allocatable lbinp
integer, dimension(:), allocatable lnew
integer, dimension(:), allocatable lfout
subroutine, public increment(my_outer, runinterval)
Definition rbl4dvar.F:634
logical ldone
Definition rbl4dvar.F:196
subroutine, public background(my_outer, runinterval)
Definition rbl4dvar.F:400
subroutine, public posterior_error(runinterval)
Definition rbl4dvar.F:2807
subroutine, public background_initialize(my_outer)
Definition rbl4dvar.F:212
subroutine, public prior_error(ng)
Definition rbl4dvar.F:2636
subroutine, public analysis(my_outer, runinterval)
Definition rbl4dvar.F:2373
subroutine, public analysis_initialize(my_outer)
Definition rbl4dvar.F:2067
subroutine, public roms_finalize
Definition ad_roms.h:283
subroutine, public roms_run(runinterval)
Definition ad_roms.h:239
subroutine, public roms_initialize(first, mpicomm)
Definition ad_roms.h:52
subroutine, public stats_modobs(ng, tile)
integer function, public stdout_unit(mymaster)
Definition stdout_mod.F:48
logical, save set_stdoutunit
Definition stdout_mod.F:41
character(len(sinp)) function, public uppercase(sinp)
Definition strings.F:582
logical function, public founderror(flag, noerr, line, routine)
Definition strings.F:52
subroutine, public wrt_dai(ng, tile)
Definition wrt_dai.F:46
subroutine, public wrt_rst(ng, tile)
Definition wrt_rst.F:63
recursive subroutine wclock_off(ng, model, region, line, routine)
Definition timers.F:148
recursive subroutine wclock_on(ng, model, region, line, routine)
Definition timers.F:3