ROMS
Loading...
Searching...
No Matches
adsen_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 Adjoint Sensitivity Analysis Driver: !
11! !
12! This driver computes the adjoint sensitivity of a function or !
13! index, J, in terms of space and/or time integrals of the model !
14! state, S(zeta,u,v,T,...). Small changes, dS, in S will lead to !
15! changes dJ in J: !
16! !
17! dJ = (dJ/dzeta) dzeta + (dJ/du) du + (dJ/dv) dv + (dJ/dt) dT ... !
18! !
19! and !
20! !
21! dJ/dS = transpose(R) S !
22! !
23! where transpose(R) is the adjoint propagator. It implies that !
24! the sensitivity for ALL variables, parameters, and space-time !
25! points can be computed from a single integration of the adjoint !
26! model. !
27! !
28! These routines control the initialization, time-stepping, and !
29! finalization of ROMS model following ESMF conventions: !
30! !
31! ROMS_initialize !
32! ROMS_run !
33! ROMS_finalize !
34! !
35! Reference: !
36! !
37! Moore, A.M., H.G. Arango, E. Di Lorenzo, A.J. Miller, and B.D. !
38! Cornuelle, 2009: An Adjoint Sensitivity Analysis of the !
39! Southern California Current Circulation and Ecosystem, J. !
40! Phys. Oceanogr., 39, 702-720, coi: 10.1175/2008JPO3740.1 !
41! !
42!=======================================================================
43!
44 USE mod_param
45 USE mod_parallel
46 USE mod_arrays
47 USE mod_iounits
48 USE mod_ncparam
49 USE mod_scalars
50!
52 USE inp_par_mod, ONLY : inp_par
53#ifdef MCT_LIB
54# ifdef ATM_COUPLING
55 USE mct_coupler_mod, ONLY : initialize_ocn2atm_coupling
56# endif
57# ifdef WAV_COUPLING
58 USE mct_coupler_mod, ONLY : initialize_ocn2wav_coupling
59# endif
60#endif
62 USE strings_mod, ONLY : founderror
63 USE wrt_rst_mod, ONLY : wrt_rst
64!
65 implicit none
66!
67 PUBLIC :: roms_initialize
68 PUBLIC :: roms_run
69 PUBLIC :: roms_finalize
70!
71 CONTAINS
72!
73 SUBROUTINE roms_initialize (first, mpiCOMM)
74!
75!=======================================================================
76! !
77! This routine allocates and initializes ROMS state variables !
78! and internal and external parameters. !
79! !
80!=======================================================================
81!
82! Imported variable declarations.
83!
84 logical, intent(inout) :: first
85
86 integer, intent(in), optional :: mpiCOMM
87!
88! Local variable declarations.
89!
90 logical :: allocate_vars = .true.
91!
92#ifdef DISTRIBUTE
93 integer :: MyError, MySize
94#endif
95 integer :: chunk_size, ng, thread
96#ifdef _OPENMP
97 integer :: my_threadnum
98#endif
99!
100 real (r8) :: str_day, end_day
101!
102 character (len=*), parameter :: MyFile = &
103 & __FILE__//", ROMS_initialize"
104
105#ifdef DISTRIBUTE
106!
107!-----------------------------------------------------------------------
108! Set distribute-memory (mpi) world communictor.
109!-----------------------------------------------------------------------
110!
111 IF (PRESENT(mpicomm)) THEN
112 ocn_comm_world=mpicomm
113 ELSE
114 ocn_comm_world=mpi_comm_world
115 END IF
116 CALL mpi_comm_rank (ocn_comm_world, myrank, myerror)
117 CALL mpi_comm_size (ocn_comm_world, mysize, myerror)
118#endif
119!
120!-----------------------------------------------------------------------
121! On first pass, initialize model parameters a variables for all
122! nested/composed grids. Notice that the logical switch "first"
123! is used to allow multiple calls to this routine during ensemble
124! configurations.
125!-----------------------------------------------------------------------
126!
127 IF (first) THEN
128 first=.false.
129!
130! Initialize parallel control switches. These scalars switches are
131! independent from standard input parameters.
132!
134!
135! Set the ROMS standard output unit to write verbose execution info.
136! Notice that the default standard out unit in Fortran is 6.
137!
138! In some applications like coupling or disjointed mpi-communications,
139! it is advantageous to write standard output to a specific filename
140! instead of the default Fortran standard output unit 6. If that is
141! the case, it opens such formatted file for writing.
142!
143 IF (set_stdoutunit) THEN
145 set_stdoutunit=.false.
146 END IF
147!
148! Read in model tunable parameters from standard input. Allocate and
149! initialize variables in several modules after the number of nested
150! grids and dimension parameters are known.
151!
152 CALL inp_par (inlm)
153 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
154!
155! Set domain decomposition tile partition range. This range is
156! computed only once since the "first_tile" and "last_tile" values
157! are private for each parallel thread/node.
158!
159#if defined _OPENMP
160 mythread=my_threadnum()
161#elif defined DISTRIBUTE
163#else
164 mythread=0
165#endif
166 DO ng=1,ngrids
167 chunk_size=(ntilex(ng)*ntilee(ng)+numthreads-1)/numthreads
168 first_tile(ng)=mythread*chunk_size
169 last_tile(ng)=first_tile(ng)+chunk_size-1
170 END DO
171!
172! Initialize internal wall clocks. Notice that the timings does not
173! includes processing standard input because several parameters are
174! needed to allocate clock variables.
175!
176 IF (master) THEN
177 WRITE (stdout,10)
178 END IF
179!
180 DO ng=1,ngrids
181 DO thread=thread_range
182 CALL wclock_on (ng, iadm, 0, __line__, myfile)
183 END DO
184 END DO
185!
186! Allocate and initialize modules variables.
187!
188 CALL roms_allocate_arrays (allocate_vars)
190 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
191
192 END IF
193
194#if defined MCT_LIB && (defined ATM_COUPLING || defined WAV_COUPLING)
195!
196!-----------------------------------------------------------------------
197! Initialize coupling streams between model(s).
198!-----------------------------------------------------------------------
199!
200 DO ng=1,ngrids
201# ifdef ATM_COUPLING
202 CALL initialize_ocn2atm_coupling (ng, myrank)
203# endif
204# ifdef WAV_COUPLING
205 CALL initialize_ocn2wav_coupling (ng, myrank)
206# endif
207 END DO
208#endif
209!
210!-----------------------------------------------------------------------
211! Initialize adjoint model state variables over all nested grids, if
212! applicable. Define adjoint sensitivity functional.
213!-----------------------------------------------------------------------
214
215#ifdef FORWARD_FLUXES
216!
217! Set the BLK structure to contain the nonlinear model surface fluxes
218! needed by the tangent linear and adjoint models. Also, set switches
219! to process that structure in routine "check_multifile". Notice that
220! it is possible to split the solution into multiple NetCDF files to
221! reduce their size.
222!
223! The switch LreadFRC is deactivated because all the atmospheric
224! forcing, including shortwave radiation, is read from the NLM
225! surface fluxes or is assigned during ESM coupling. Such fluxes
226! are available from the QCK structure. There is no need for reading
227! and processing from the FRC structure input forcing-files.
228!
229 CALL edit_multifile ('QCK2BLK')
230 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
231 DO ng=1,ngrids
232 lreadblk(ng)=.true.
233 lreadfrc(ng)=.false.
234 END DO
235#endif
236!
237! Initialize adjoint model with sensitivity functional.
238!
239 lstiffness=.false.
240 DO ng=1,ngrids
241 lreadfwd(ng)=.true.
242 CALL ad_initial (ng)
243 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
244 END DO
245!
246! Initialize run or ensemble counter.
247!
248 nrun=1
249!
250! Activate adjoint output.
251!
252 DO ng=1,ngrids
253 ldefadj(ng)=.true.
254 lwrtadj(ng)=.true.
255 lcycleadj(ng)=.false.
256 END DO
257!
258! Add a time-step to model time after initialization because the
259! main time-stepping driver always substracts a single time-step.
260!
261 DO ng=1,ngrids
262 str_day=time(ng)*sec2day
263 end_day=str_day-ntimes(ng)*dt(ng)*sec2day
264 IF ((dstrs(ng).eq.0.0_r8).and.(dends(ng).eq.0.0_r8)) THEN
265 dstrs(ng)=end_day
266 dends(ng)=str_day
267 END IF
268 IF (master) THEN
269 WRITE (stdout,20) dends(ng), dstrs(ng)
270 END IF
271 IF ((dstrs(ng).gt.str_day).or.(dstrs(ng).lt.end_day)) THEN
272 IF (master) WRITE (stdout,30) 'DstrS = ', dstrs(ng), &
273 & end_day, str_day
274 exit_flag=7
275 RETURN
276 END IF
277 IF ((dends(ng).gt.str_day).or.(dends(ng).lt.end_day)) THEN
278 IF (master) WRITE (stdout,30) 'DendS = ', dends(ng), &
279 & end_day, str_day
280 exit_flag=7
281 RETURN
282 END IF
283 END DO
284!
285 10 FORMAT (' Process Information:',/)
286 20 FORMAT (14x,'adjoint forcing time range: ',f12.4,' - ',f12.4 ,/)
287 30 FORMAT (/,' Out of range adjoint forcing time, ',a,f12.4,/, &
288 & ' It must be between ',f12.4,' and ',f12.4)
289!
290 RETURN
291 END SUBROUTINE roms_initialize
292!
293 SUBROUTINE roms_run (RunInterval)
294!
295!=======================================================================
296! !
297! This routine computes the adjoint sensitivity analysis, dJ/dS, !
298! to the specified functional J. The sensitivity masking arrays !
299! Rscope, Uscope, and Vscope are used to evaluate the functional !
300! in the desired spatial area. !
301! !
302!=======================================================================
303!
304! Imported variable declarations.
305!
306 real(dp), intent(in) :: RunInterval ! seconds
307!
308! Local variable declarations.
309!
310 integer :: ng
311!
312 character (len=*), parameter :: MyFile = &
313 & __FILE__//", ROMS_run"
314!
315!-----------------------------------------------------------------------
316! Time-step adjoint model over all nested grids, if applicable.
317!-----------------------------------------------------------------------
318!
319 DO ng=1,ngrids
320 IF (master) THEN
321 WRITE (stdout,10) 'AD', ng, ntstart(ng), ntend(ng)
322 END IF
323 END DO
324!
325#ifdef SOLVE3D
326 CALL ad_main3d (runinterval)
327#else
328 CALL ad_main2d (runinterval)
329#endif
330
331 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
332!
333 10 FORMAT (/,1x,a,1x,'ROMS: started time-stepping:', &
334 & ' (Grid: ',i2.2,' TimeSteps: ',i8.8,' - ',i8.8,')',/)
335!
336 RETURN
337 END SUBROUTINE roms_run
338!
339 SUBROUTINE roms_finalize
340!
341!=======================================================================
342! !
343! This routine terminates ROMS adjoint model execution. !
344! !
345!=======================================================================
346!
347! Local variable declarations.
348!
349 integer :: Fcount, ng, thread
350!
351 character (len=*), parameter :: MyFile = &
352 & __FILE__//", ROMS_finalize"
353!
354!-----------------------------------------------------------------------
355! If blowing-up, save latest model state into RESTART NetCDF file.
356!-----------------------------------------------------------------------
357!
358! If cycling restart records, write solution into the next record.
359!
360 IF (exit_flag.eq.1) THEN
361 DO ng=1,ngrids
362 IF (lwrtrst(ng)) THEN
363 IF (master) WRITE (stdout,10)
364 10 FORMAT (/,' Blowing-up: Saving latest model state into ', &
365 & ' RESTART file',/)
366 fcount=rst(ng)%load
367 IF (lcyclerst(ng).and.(rst(ng)%Nrec(fcount).ge.2)) THEN
368 rst(ng)%Rindex=2
369 lcyclerst(ng)=.false.
370 END IF
373#ifdef DISTRIBUTE
374 CALL wrt_rst (ng, myrank)
375#else
376 CALL wrt_rst (ng, -1)
377#endif
378 END IF
379 END DO
380 END IF
381!
382!-----------------------------------------------------------------------
383! Stop model and time profiling clocks, report memory requirements, and
384! close output NetCDF files.
385!-----------------------------------------------------------------------
386!
387! Stop time clocks.
388!
389 IF (master) THEN
390 WRITE (stdout,20)
391 20 FORMAT (/,'Elapsed wall CPU time for each process (seconds):',/)
392 END IF
393!
394 DO ng=1,ngrids
395 DO thread=thread_range
396 CALL wclock_off (ng, iadm, 0, __line__, myfile)
397 END DO
398 END DO
399!
400! Report dynamic memory and automatic memory requirements.
401!
402 CALL memory
403!
404! Close IO files.
405!
406 DO ng=1,ngrids
407 CALL close_inp (ng, iadm)
408 END DO
409 CALL close_out
410!
411 RETURN
412 END SUBROUTINE roms_finalize
413
414 END MODULE roms_kernel_mod
subroutine ad_initial(ng)
Definition ad_initial.F:4
subroutine ad_main2d
Definition ad_main2d.F:586
subroutine ad_main3d(runinterval)
Definition ad_main3d.F:4
subroutine edit_multifile(task)
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 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
type(t_io), dimension(:), allocatable rst
integer stdout
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, parameter iadm
Definition mod_param.F:665
integer ngrids
Definition mod_param.F:113
integer, dimension(:), allocatable ntilee
Definition mod_param.F:686
integer, dimension(:), allocatable ntimes
real(dp), dimension(:), allocatable dt
logical lstiffness
integer blowup
logical, dimension(:), allocatable lreadfrc
real(r8), dimension(:), allocatable dends
logical, dimension(:), allocatable ldefadj
logical, dimension(:), allocatable lcycleadj
logical, dimension(:), allocatable lwrtadj
real(dp), parameter sec2day
integer, dimension(:), allocatable ntend
integer exit_flag
real(r8), dimension(:), allocatable dstrs
logical, dimension(:), allocatable lwrtrst
real(dp), dimension(:), allocatable time
integer, dimension(:), allocatable ntstart
integer nrun
logical, dimension(:), allocatable lreadfwd
integer noerror
logical, dimension(:), allocatable lcyclerst
logical, dimension(:), allocatable lreadblk
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
integer function, public stdout_unit(mymaster)
Definition stdout_mod.F:48
logical, save set_stdoutunit
Definition stdout_mod.F:41
logical function, public founderror(flag, noerr, line, routine)
Definition strings.F:52
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