ROMS
Loading...
Searching...
No Matches
hessian_op_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 Optimal Pertubations (Singular Vectors) Driver: !
11! !
12! This driver computes the singular vectors of the propagator R(0,t) !
13! which measure the fastest growing of all possible perturbations !
14! over a given time interval. They are usually used to study the !
15! dynamics, sensitivity, and stability of the ocean circulation to !
16! naturally occurring pertubations in the prediction system. !
17! !
18! These routines control the initialization, time-stepping, and !
19! finalization of ROMS model following ESMF conventions: !
20! !
21! ROMS_initialize !
22! ROMS_run !
23! ROMS_finalize !
24! !
25! Reference: !
26! !
27! Moore, A.M. et al., 2004: A comprehensive ocean prediction and !
28! analysis system based on the tangent linear and adjoint of a !
29! regional ocean model, Ocean Modelling, 7, 227-258. !
30! !
31!=======================================================================
32!
33 USE mod_param
34 USE mod_parallel
35 USE mod_arrays
36 USE mod_fourdvar
37 USE mod_iounits
38 USE mod_ncparam
39 USE mod_netcdf
40#if defined PIO_LIB && defined DISTRIBUTE
42#endif
43 USE mod_scalars
44 USE mod_stepping
45 USE mod_storage
46 USE mod_netcdf
47!
49!
51#ifdef CHECKPOINTING
52 USE def_gst_mod, ONLY : def_gst
53 USE get_gst_mod, ONLY : get_gst
54#endif
55#ifdef DISTRIBUTE
57#endif
58 USE inp_par_mod, ONLY : inp_par
59#ifdef MCT_LIB
60# ifdef ATM_COUPLING
61 USE mct_coupler_mod, ONLY : initialize_ocn2atm_coupling
62# endif
63# ifdef WAV_COUPLING
64 USE mct_coupler_mod, ONLY : initialize_ocn2wav_coupling
65# endif
66#endif
67 USE packing_mod, ONLY : r_norm2
69 USE strings_mod, ONLY : founderror
70#ifdef CHECKPOINTING
71 USE wrt_gst_mod, ONLY : wrt_gst
72#endif
73 USE wrt_rst_mod, ONLY : wrt_rst
74!
75 implicit none
76!
77 PRIVATE :: iram_error
78 PUBLIC :: roms_initialize
79 PUBLIC :: roms_run
80 PUBLIC :: roms_finalize
81!
82 CONTAINS
83!
84 SUBROUTINE roms_initialize (first, mpiCOMM)
85!
86!=======================================================================
87! !
88! This routine allocates and initializes ROMS state variables !
89! and internal and external parameters. !
90! !
91!=======================================================================
92!
93! Imported variable declarations.
94!
95 logical, intent(inout) :: first
96!
97 integer, intent(in), optional :: mpiCOMM
98!
99! Local variable declarations.
100!
101 logical :: allocate_vars = .true.
102!
103#ifdef DISTRIBUTE
104 integer :: MyError, MySize
105#endif
106 integer :: chunk_size, ng, thread
107#ifdef _OPENMP
108 integer :: my_threadnum
109#endif
110!
111 character (len=*), parameter :: MyFile = &
112 & __FILE__//", ROMS_initialize"
113
114#ifdef DISTRIBUTE
115!
116!-----------------------------------------------------------------------
117! Set distribute-memory (mpi) world communictor.
118!-----------------------------------------------------------------------
119!
120 IF (PRESENT(mpicomm)) THEN
121 ocn_comm_world=mpicomm
122 ELSE
123 ocn_comm_world=mpi_comm_world
124 END IF
125 CALL mpi_comm_rank (ocn_comm_world, myrank, myerror)
126 CALL mpi_comm_size (ocn_comm_world, mysize, myerror)
127#endif
128!
129!-----------------------------------------------------------------------
130! On first pass, initialize model parameters a variables for all
131! nested/composed grids. Notice that the logical switch "first"
132! is used to allow multiple calls to this routine during ensemble
133! configurations.
134!-----------------------------------------------------------------------
135!
136 IF (first) THEN
137 first=.false.
138!
139! Initialize parallel control switches. These scalars switches are
140! independent from standard input parameters.
141!
143!
144! Set the ROMS standard output unit to write verbose execution info.
145! Notice that the default standard out unit in Fortran is 6.
146!
147! In some applications like coupling or disjointed mpi-communications,
148! it is advantageous to write standard output to a specific filename
149! instead of the default Fortran standard output unit 6. If that is
150! the case, it opens such formatted file for writing.
151!
152 IF (set_stdoutunit) THEN
154 set_stdoutunit=.false.
155 END IF
156!
157! Read in model tunable parameters from standard input. Allocate and
158! initialize variables in several modules after the number of nested
159! grids and dimension parameters are known.
160!
161 CALL inp_par (itlm)
162 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
163!
164! Set domain decomposition tile partition range. This range is
165! computed only once since the "first_tile" and "last_tile" values
166! are private for each parallel thread/node.
167!
168#if defined _OPENMP
169 mythread=my_threadnum()
170#elif defined DISTRIBUTE
172#else
173 mythread=0
174#endif
175 DO ng=1,ngrids
176 chunk_size=(ntilex(ng)*ntilee(ng)+numthreads-1)/numthreads
177 first_tile(ng)=mythread*chunk_size
178 last_tile(ng)=first_tile(ng)+chunk_size-1
179 END DO
180!
181! Initialize internal wall clocks. Notice that the timings does not
182! includes processing standard input because several parameters are
183! needed to allocate clock variables.
184!
185 IF (master) THEN
186 WRITE (stdout,10)
187 10 FORMAT (/,' Process Information:',/)
188 END IF
189!
190 DO ng=1,ngrids
191 DO thread=thread_range
192 CALL wclock_on (ng, itlm, 0, __line__, myfile)
193 END DO
194 END DO
195!
196! Allocate and initialize modules variables.
197!
198 CALL roms_allocate_arrays (allocate_vars)
200 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
201
202 END IF
203
204#if defined MCT_LIB && (defined ATM_COUPLING || defined WAV_COUPLING)
205!
206!-----------------------------------------------------------------------
207! Initialize coupling streams between model(s).
208!-----------------------------------------------------------------------
209!
210 DO ng=1,ngrids
211# ifdef ATM_COUPLING
212 CALL initialize_ocn2atm_coupling (ng, myrank)
213# endif
214# ifdef WAV_COUPLING
215 CALL initialize_ocn2wav_coupling (ng, myrank)
216# endif
217 END DO
218#endif
219!
220!-----------------------------------------------------------------------
221! Initialize tangent linear for all grids first in order to compute
222! the size of the state vector, Nstate. This size is computed in
223! routine "wpoints".
224!-----------------------------------------------------------------------
225
226#ifdef FORWARD_FLUXES
227!
228! Set the BLK structure to contain the nonlinear model surface fluxes
229! needed by the tangent linear and adjoint models. Also, set switches
230! to process that structure in routine "check_multifile". Notice that
231! it is possible to split the solution into multiple NetCDF files to
232! reduce their size.
233!
234! The switch LreadFRC is deactivated because all the atmospheric
235! forcing, including shortwave radiation, is read from the NLM
236! surface fluxes or is assigned during ESM coupling. Such fluxes
237! are available from the QCK structure. There is no need for reading
238! and processing from the FRC structure input forcing-files.
239!
240 CALL edit_multifile ('QCK2BLK')
241 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
242 DO ng=1,ngrids
243 lreadblk(ng)=.true.
244 lreadfrc(ng)=.false.
245 END DO
246#endif
247!
248! Initialize perturbation tangent linear model.
249!
250 DO ng=1,ngrids
251 lreadfwd(ng)=.true.
252 CALL tl_initial (ng)
253 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
254 END DO
255!
256!-----------------------------------------------------------------------
257! Read in Lanczos algorithm coefficients (cg_beta, cg_delta) from
258! file LCZ(ng)%name NetCDF (I4D-Var adjoint file), as computed in the
259! I4D-Var Lanczos data assimilation algorithm for the first outer
260! loop. They are needed here, in routine "tl_inner2state", to compute
261! the tangent linear model initial conditions as the weighted sum
262! of the Lanczos vectors. The weighting coefficient are computed
263! by solving a tri-diagonal system that uses "cg_beta" and "cg_gamma".
264!-----------------------------------------------------------------------
265!
266 sourcefile=myfile
267 DO ng=1,ngrids
268 SELECT CASE (lcz(ng)%IOtype)
269 CASE (io_nf90)
270 CALL netcdf_get_fvar (ng, iadm, lcz(ng)%name, &
271 & 'cg_beta', cg_beta)
272 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
273!
274 CALL netcdf_get_fvar (ng, iadm, lcz(ng)%name, &
275 & 'cg_delta', cg_delta)
276 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
277
278#if defined PIO_LIB && defined DISTRIBUTE
279 CASE (io_pio)
280 CALL pio_netcdf_get_fvar (ng, iadm, lcz(ng)%name, &
281 & 'cg_beta', cg_beta)
282 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
283!
284 CALL pio_netcdf_get_fvar (ng, iadm, lcz(ng)%name, &
285 & 'cg_delta', cg_delta)
286 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
287#endif
288 END SELECT
289 END DO
290!
291! Allocate arrays associated with Generalized Stability Theory (GST)
292! analysis.
293!
295!
296! Initialize various IO flags.
297!
298 nrun=0
299 DO ng=1,ngrids
300 ldefadj(ng)=.true.
301 lwrtadj(ng)=.true.
302 ldeftlm(ng)=.true.
303 lwrttlm(ng)=.true.
304 lwrtper(ng)=.false.
305 lcycletlm(ng)=.false.
306 lcycleadj(ng)=.false.
307 nadj(ng)=ntimes(ng)
308 ntlm(ng)=ntimes(ng)
309 END DO
310!
311! Initialize ARPACK parameters.
312!
313 lrvec=.true. ! Compute Ritz vectors
314 bmat='I' ! standard eigenvalue problem
315 which='LM' ! compute NEV largest eigenvalues
316 howmany='A' ! compute NEV Ritz vectors
317 DO ng=1,ngrids
318 ido(ng)=0 ! reverse communication flag
319 info(ng)=0 ! random initial residual vector
320 iparam(1,ng)=1 ! exact shifts
321 iparam(3,ng)=maxitergst ! maximum number of Arnoldi iterations
322 iparam(4,ng)=1 ! block size in the recurrence
323 iparam(7,ng)=1 ! type of eigenproblem being solved
324 END DO
325!
326! ARPACK debugging parameters.
327!
328 logfil=stdout ! output logical unit
329 ndigit=-3 ! number of decimal digits
330 msaupd=1 ! iterations, timings, Ritz
331 msaup2=1 ! norms, Ritz values
332 msaitr=0
333 mseigt=0
334 msapps=0
335 msgets=0
336 mseupd=0
337!
338! Determine size of the eigenproblem (Nsize) and size of work space
339! array SworkL (LworkL).
340!
341 DO ng=1,ngrids
342 nconv(ng)=0
343 nsize(ng)=ninner
344 END DO
345
346#ifdef CHECKPOINTING
347!
348! If restart, read in checkpointing data GST restart NetCDF file.
349! Otherwise, create checkpointing restart NetCDF file.
350!
351 DO ng=1,ngrids
352 IF (lrstgst) THEN
353 CALL get_gst (ng, itlm)
354 ido(ng)=-2
355 laup2(1)=.false. ! cnorm
356 laup2(2)=.false. ! getv0
357 laup2(3)=.false. ! initv
358 laup2(4)=.false. ! update
359 laup2(5)=.true. ! ushift
360 ELSE
361 CALL def_gst (ng, itlm)
362 END IF
363 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
364 END DO
365#endif
366!
367 RETURN
368 END SUBROUTINE roms_initialize
369!
370 SUBROUTINE roms_run (RunInterval)
371!
372!=======================================================================
373! !
374! This routine computes the singular vectors of R(0,t) by a single !
375! integration of a perturbation "u" forward in time with the !
376! tangent linear model over [0,t], multiplication of the result !
377! by "X", followed by an integration of the result backwards in !
378! time with the adjoint model over [t,0]. This is equivalmet to !
379! the matrix-vector operation: !
380! !
381! transpose[R(t,0)] X R(0,t) u !
382! !
383! The above operator is symmetric and the ARPACK library is used !
384! to select eigenvectors and eigenvalues: !
385! !
386! Lehoucq, R.B., D.C. Sorensen, and C. Yang, 1997: ARPACK user's !
387! guide: solution of large scale eigenvalue problems with !
388! implicit restarted Arnoldi Methods, Rice University, 140p. !
389! !
390!=======================================================================
391!
392! Imported variable declarations
393!
394 real(dp), intent(in) :: RunInterval ! seconds
395!
396! Local variable declarations.
397!
398 logical :: ITERATE
399#ifdef CHECKPOINTING
400 logical :: LwrtGST
401#endif
402!
403 integer :: Fcount, Is, Ie, i, iter, ng
404 integer :: NconvRitz(Ngrids)
405!
406 real(r8) :: Enorm
407
408 real(r8), dimension(2) :: my_norm, my_value
409!
410 TYPE (T_GST), allocatable :: ad_state(:)
411 TYPE (T_GST), allocatable :: state(:)
412!
413 character (len=55) :: string
414
415 character (len=*), parameter :: MyFile = &
416 & __FILE__//", ROMS_run"
417!
418!-----------------------------------------------------------------------
419! Implicit Restarted Arnoldi Method (IRAM) for the computation of
420! optimal perturbation Ritz eigenfunctions.
421!-----------------------------------------------------------------------
422!
423! Allocate nested grid pointers for state vectors.
424!
425 IF (.not.allocated(ad_state)) THEN
426 allocate ( ad_state(ngrids) )
427 END IF
428 IF (.not.allocated(state)) THEN
429 allocate ( state(ngrids) )
430 END IF
431!
432! Iterate until either convergence or maximum iterations has been
433! exceeded.
434!
435 iter=0
436 iterate=.true.
437#ifdef CHECKPOINTING
438 lwrtgst=.true.
439#endif
440!
441 iter_loop : DO WHILE (iterate)
442 iter=iter+1
443!
444! Reverse communication interface.
445!
446 DO ng=1,ngrids
447#ifdef PROFILE
448 CALL wclock_on (ng, itlm, 38, __line__, myfile)
449#endif
450 IF (master) THEN
451 CALL dsaupd (ido(ng), bmat, nsize(ng), which, nev, &
452 & ritz_tol, &
453 & storage(ng)%resid, ncv, &
454 & storage(ng)%Bvec, nsize(ng), &
455 & iparam(1,ng), ipntr(1,ng), &
456 & storage(ng)%SworkD, &
457 & sworkl(1,ng), lworkl, info(ng))
458 nconv(ng)=iaup2(4)
459 END IF
460#ifdef PROFILE
461 CALL wclock_off (ng, itlm, 38, __line__, myfile)
462#endif
463#ifdef DISTRIBUTE
464!
465! Broadcast various Arnoldi iteration variables to all member in the
466! group. The Arnoldi problem solved here is very small so the ARPACK
467! library is run by the master node and all relevant variables are
468! broadcasted to all nodes.
469!
470 CALL mp_bcasti (ng, itlm, nconv(ng))
471 CALL mp_bcasti (ng, itlm, ido(ng))
472 CALL mp_bcasti (ng, itlm, info(ng))
473 CALL mp_bcasti (ng, itlm, iparam(:,ng))
474 CALL mp_bcasti (ng, itlm, ipntr(:,ng))
475 CALL mp_bcastf (ng, itlm, storage(ng)%SworkD)
476#endif
477#ifdef CHECKPOINTING
478!
479! If appropriate, write out check point data into GST restart NetCDF
480! file. Notice that the restart data is always saved if MaxIterGST
481! is reached without convergence. It is also saved when convergence
482! is achieved (ido=99).
483!
484 IF ((mod(iter,ngst).eq.0).or.(iter.ge.maxitergst).or. &
485 & (any(ido.eq.99))) THEN
486 CALL wrt_gst (ng, itlm)
487 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
488 END IF
489#endif
490 END DO
491!
492! Terminate computations if maximum number of iterations is reached.
493! This will faciliate splitting the analysis in several computational
494! cycles using the restart option.
495!
496 IF ((iter.ge.maxitergst).and.any(ido.ne.99)) THEN
497 iterate=.false.
498 EXIT iter_loop
499 END IF
500!
501! Perform matrix-vector operation: R`(t,0)XR(0,t)u
502!
503 IF (any(abs(ido).eq.1)) THEN
504 DO ng=1,ngrids
505 fcount=adm(ng)%load
506 adm(ng)%Nrec(fcount)=0
507 fcount=tlm(ng)%load
508 tlm(ng)%Nrec(fcount)=0
509 adm(ng)%Rindex=0
510 tlm(ng)%Rindex=0
511 END DO
512!
513! Set state vectors to process by the propagator via pointer
514! equivalence.
515!
516 DO ng=1,ngrids
517 IF (ASSOCIATED(state(ng)%vector)) THEN
518 nullify (state(ng)%vector)
519 END IF
520 is=ipntr(1,ng)
521 ie=is+nsize(ng)-1
522 state(ng)%vector => storage(ng)%SworkD(is:ie)
523
524 IF (ASSOCIATED(ad_state(ng)%vector)) THEN
525 nullify (ad_state(ng)%vector)
526 END IF
527 is=ipntr(2,ng)
528 ie=is+nsize(ng)-1
529 ad_state(ng)%vector => storage(ng)%SworkD(is:ie)
530 END DO
531!
532 CALL propagator_hop (runinterval, state, ad_state)
533 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
534 ELSE
535 IF (any(info.ne.0)) THEN
536 DO ng=1,ngrids
537 IF (info(ng).ne.0) THEN
538 IF (master) THEN
539 CALL iram_error (info(ng), string)
540 WRITE (stdout,10) 'DSAUPD', trim(string), &
541 & ', info = ', info(ng)
542 END IF
543 RETURN
544 END IF
545 END DO
546 ELSE
547!
548! Compute Ritz vectors (the only choice left is IDO=99). They are
549! generated in ARPACK in decreasing magnitude of its eigenvalue.
550! The most significant is first.
551!
552 DO ng=1,ngrids
553 nconvritz(ng)=iparam(5,ng)
554 IF (master) THEN
555 WRITE (stdout,20) 'Number of converged Ritz values:', &
556 & iparam(5,ng)
557 WRITE (stdout,20) 'Number of Arnoldi iterations:', &
558 & iparam(3,ng)
559 END IF
560#ifdef PROFILE
561 CALL wclock_on (ng, itlm, 38, __line__, myfile)
562#endif
563 IF (master) THEN
564 CALL dseupd (lrvec, howmany, pick(1,ng), &
565 & rvaluer(1,ng), &
566 & storage(ng)%Rvector, nsize(ng), &
568 & storage(ng)%resid, ncv, &
569 & storage(ng)%Bvec, nsize(ng), &
570 & iparam(1,ng), ipntr(1,ng), &
571 & storage(ng)%SworkD, &
572 & sworkl(1,ng), lworkl, info(ng))
573 END IF
574#ifdef DISTRIBUTE
575!
576! Broadcast various Arnoldi iteration variables to all member in the
577! group.
578!
579 CALL mp_bcasti (ng, itlm, info(ng))
580 CALL mp_bcasti (ng, itlm, iparam(:,ng))
581 CALL mp_bcasti (ng, itlm, ipntr(:,ng))
582 CALL mp_bcastf (ng, itlm, rvaluer(:,ng))
583 CALL mp_bcastf (ng, itlm, storage(ng)%Rvector)
584#endif
585#ifdef PROFILE
586 CALL wclock_off (ng, itlm, 38, __line__, myfile)
587#endif
588 END DO
589
590 IF (any(info.ne.0)) THEN
591 DO ng=1,ngrids
592 IF (info(ng).ne.0) THEN
593 IF (master) THEN
594 CALL iram_error (info(ng), string)
595 WRITE (stdout,10) 'DSEUPD', trim(string), &
596 & ', info = ', info(ng)
597 END IF
598 RETURN
599 END IF
600 END DO
601 ELSE
602!
603! Activate writing of each eigenvector into the adjoint and tangent
604! linear history NetCDF files. The "ocean_time" is the eigenvector
605! number.
606!
607 nrun=0
608
609 DO i=1,maxval(nconvritz)
610 DO ng=1,ngrids
611 IF ((i.eq.1).or.lmultigst) THEN
612 fcount=adm(ng)%load
613 adm(ng)%Nrec(fcount)=0
614 fcount=tlm(ng)%load
615 tlm(ng)%Nrec(fcount)=0
616 adm(ng)%Rindex=0
617 tlm(ng)%Rindex=0
618 END IF
619 IF (lmultigst) THEN
620 ldefadj(ng)=.true.
621 ldeftlm(ng)=.true.
622 WRITE (adm(ng)%name,30) trim(adm(ng)%base), i
623 WRITE (tlm(ng)%name,30) trim(tlm(ng)%base), i
624 END IF
625 END DO
626!
627! Compute and write Ritz eigenvectors.
628!
629 DO ng=1,ngrids
630 is=1
631 ie=ninner
632 IF (ASSOCIATED(state(ng)%vector)) THEN
633 nullify (state(ng)%vector)
634 END IF
635
636 IF (ASSOCIATED(ad_state(ng)%vector)) THEN
637 nullify (ad_state(ng)%vector)
638 END IF
639 state(ng)%vector => storage(ng)%Rvector(is:ie,i)
640 ad_state(ng)%vector => sworkr(is:ie)
641 END DO
642!
643 CALL propagator_hop (runinterval, state, ad_state)
645 & __line__, myfile)) RETURN
646!
647 DO ng=1,ngrids
648 CALL r_norm2 (ng, itlm, 1, ninner, &
649 & -rvaluer(i,ng), &
650 & state(ng)%vector, &
651 & ad_state(ng)%vector, enorm)
652 norm(i,ng)=enorm
653 IF (master) THEN
654 WRITE (stdout,40) i, norm(i,ng), rvaluer(i,ng), i
655 END IF
656 END DO
657!
658! Write out Ritz eigenvalues and Ritz eigenvector Euclidean norm
659! (residual) to NetCDF file(s). Notice that we write the same value
660! twice in the TLM file for the initial and final perturbation of
661! the eigenvector.
662!
663 sourcefile=myfile
664 DO ng=1,ngrids
665 my_norm(1)=norm(i,ng)
666 my_norm(2)=my_norm(1)
667 my_value(1)=rvaluer(i,ng)
668 my_value(2)=my_value(1)
669!
670 IF (lwrttlm(ng)) THEN
671 SELECT CASE (tlm(ng)%IOtype)
672 CASE (io_nf90)
673 CALL netcdf_put_fvar (ng, itlm, &
674 & tlm(ng)%name, &
675 & 'Ritz_rvalue', &
676 & my_value, &
677 & start = (/tlm(ng)%Rindex-1/), &
678 & total = (/2/), &
679 & ncid = tlm(ng)%ncid)
680
682 & __line__, myfile)) RETURN
683!
684 CALL netcdf_put_fvar (ng, itlm, &
685 & tlm(ng)%name, &
686 & 'Ritz_norm', &
687 & my_norm, &
688 & start = (/tlm(ng)%Rindex-1/), &
689 & total = (/2/), &
690 & ncid = tlm(ng)%ncid)
691
693 & __line__, myfile)) RETURN
694
695#if defined PIO_LIB && defined DISTRIBUTE
696 CASE (io_pio)
697 CALL pio_netcdf_put_fvar (ng, itlm, &
698 & tlm(ng)%name, &
699 & 'Ritz_rvalue', &
700 & my_value, &
701 & start = (/tlm(ng)%Rindex-1/), &
702 & total = (/2/), &
703 & piofile = tlm(ng)%pioFile)
704
706 & __line__, myfile)) RETURN
707!
708 CALL pio_netcdf_put_fvar (ng, itlm, &
709 & tlm(ng)%name, &
710 & 'Ritz_norm', &
711 & my_norm, &
712 & start = (/tlm(ng)%Rindex-1/), &
713 & total = (/2/), &
714 & piofile = tlm(ng)%pioFile)
715
717 & __line__, myfile)) RETURN
718#endif
719 END SELECT
720!
721 IF (lmultigst) THEN
722 CALL close_file (ng, itlm, tlm(ng), tlm(ng)%name)
724 & __line__, myfile)) RETURN
725 END IF
726 END IF
727!
728 IF (lwrtadj(ng)) THEN
729 SELECT CASE (adm(ng)%IOtype)
730 CASE (io_nf90)
731 CALL netcdf_put_fvar (ng, iadm, &
732 & adm(ng)%name, &
733 & 'Ritz_rvalue', &
734 & rvaluer(i:,ng), &
735 & start = (/adm(ng)%Rindex/), &
736 & total = (/1/), &
737 & ncid = adm(ng)%ncid)
738
740 & __line__, myfile)) RETURN
741!
742 CALL netcdf_put_fvar (ng, iadm, &
743 & adm(ng)%name, &
744 & 'Ritz_norm', &
745 & norm(i:,ng), &
746 & start = (/adm(ng)%Rindex/), &
747 & total = (/1/), &
748 & ncid = adm(ng)%ncid)
749
751 & __line__, myfile)) RETURN
752
753#if defined PIO_LIB && defined DISTRIBUTE
754 CASE (io_pio)
755 CALL pio_netcdf_put_fvar (ng, iadm, &
756 & adm(ng)%name, &
757 & 'Ritz_rvalue', &
758 & rvaluer(i:,ng), &
759 & start = (/adm(ng)%Rindex/), &
760 & total = (/1/), &
761 & piofile = adm(ng)%pioFile)
762
764 & __line__, myfile)) RETURN
765!
766 CALL pio_netcdf_put_fvar (ng, iadm, &
767 & adm(ng)%name, &
768 & 'Ritz_norm', &
769 & norm(i:,ng), &
770 & start = (/adm(ng)%Rindex/), &
771 & total = (/1/), &
772 & piofile = adm(ng)%pioFile)
773
775 & __line__, myfile)) RETURN
776#endif
777 END SELECT
778!
779 IF (lmultigst) THEN
780 CALL netcdf_close (ng, iadm, adm(ng)%ncid, &
781 & adm(ng)%name)
783 & __line__, myfile)) RETURN
784 END IF
785 END IF
786 END DO
787 END DO
788 END IF
789 END IF
790 iterate=.false.
791 END IF
792
793 END DO iter_loop
794!
795 10 FORMAT (/,1x,'Error in ',a,1x,a,a,1x,i5,/)
796 20 FORMAT (/,a,1x,i2,/)
797 30 FORMAT (a,'_',i3.3,'.nc')
798 40 FORMAT (1x,i4.4,'-th residual',1p,e14.6,0p, &
799 & ' Ritz value',1pe14.6,0p,2x,i4.4)
800!
801 RETURN
802 END SUBROUTINE roms_run
803!
804 SUBROUTINE roms_finalize
805!
806!=======================================================================
807! !
808! This routine terminates ROMS nonlinear and adjoint models !
809! execution. !
810! !
811!=======================================================================
812!
813! Local variable declarations.
814!
815 integer :: Fcount, ng, thread
816!
817 character (len=*), parameter :: MyFile = &
818 & __FILE__//", ROMS_finalize"
819!
820!-----------------------------------------------------------------------
821! If blowing-up, save latest model state into RESTART NetCDF file.
822!-----------------------------------------------------------------------
823!
824! If cycling restart records, write solution into the next record.
825!
826 IF (exit_flag.eq.1) THEN
827 DO ng=1,ngrids
828 IF (lwrtrst(ng)) THEN
829 IF (master) WRITE (stdout,10)
830 10 FORMAT (/,' Blowing-up: Saving latest model state into ', &
831 & ' RESTART file',/)
832 fcount=rst(ng)%load
833 IF (lcyclerst(ng).and.(rst(ng)%Nrec(fcount).ge.2)) THEN
834 rst(ng)%Rindex=2
835 lcyclerst(ng)=.false.
836 END IF
839#ifdef DISTRIBUTE
840 CALL wrt_rst (ng, myrank)
841#else
842 CALL wrt_rst (ng, -1)
843#endif
844 END IF
845 END DO
846 END IF
847!
848!-----------------------------------------------------------------------
849! Stop model and time profiling clocks, report memory requirements, and
850! close output NetCDF files.
851!-----------------------------------------------------------------------
852!
853! Stop time clocks.
854!
855 IF (master) THEN
856 WRITE (stdout,20)
857 20 FORMAT (/,'Elapsed wall CPU time for each process (seconds):',/)
858 END IF
859!
860 DO ng=1,ngrids
861 DO thread=thread_range
862 CALL wclock_off (ng, itlm, 0, __line__, myfile)
863 END DO
864 END DO
865!
866! Report dynamic memory and automatic memory requirements.
867!
868 CALL memory
869!
870! Close IO files.
871!
872 DO ng=1,ngrids
873 CALL close_inp (ng, itlm)
874 END DO
875 CALL close_out
876!
877 RETURN
878 END SUBROUTINE roms_finalize
879!
880 SUBROUTINE iram_error (info, string)
881!
882!=======================================================================
883! !
884! This routine decodes internal error messages from the Implicit !
885! Restarted Arnoldi Method (IRAM) for the computation of optimal !
886! perturbation Ritz eigenfunctions. !
887! !
888!=======================================================================
889!
890! imported variable declarations.
891!
892 integer, intent(in) :: info
893!
894 character (len=*), intent(out) :: string
895!
896!-----------------------------------------------------------------------
897! Decode error message from IRAM.
898!-----------------------------------------------------------------------
899!
900 IF (info.eq.0) THEN
901 string='Normal exit '
902 ELSE IF (info.eq.1) THEN
903 string='Maximum number of iterations taken '
904 ELSE IF (info.eq.3) THEN
905 string='No shifts could be applied during an IRAM cycle '
906 ELSE IF (info.eq.-1) THEN
907 string='Nstate must be positive '
908 ELSE IF (info.eq.-2) THEN
909 string='NEV must be positive '
910 ELSE IF (info.eq.-3) THEN
911 string='NCV must be greater NEV and less than or equal Nstate '
912 ELSE IF (info.eq.-4) THEN
913 string='Maximum number of iterations must be greater than zero '
914 ELSE IF (info.eq.-5) THEN
915 string='WHICH must be one of LM, SM, LA, SA or BE '
916 ELSE IF (info.eq.-6) THEN
917 string='BMAT must be one of I or G '
918 ELSE IF (info.eq.-7) THEN
919 string='Length of private work array SworkL is not sufficient '
920 ELSE IF (info.eq.-8) THEN
921 string='Error in DSTEQR in the eigenvalue calculation '
922 ELSE IF (info.eq.-9) THEN
923 string='Starting vector is zero '
924 ELSE IF (info.eq.-10) THEN
925 string='IPARAM(7) must be 1, 2, 3, 4, 5 '
926 ELSE IF (info.eq.-11) THEN
927 string='IPARAM(7) = 1 and BMAT = G are incompatable '
928 ELSE IF (info.eq.-12) THEN
929 string='IPARAM(1) must be equal to 0 or 1 '
930 ELSE IF (info.eq.-13) THEN
931 string='NEV and WHICH = BE are incompatable '
932 ELSE IF (info.eq.-14) THEN
933 string='Did not find any eigenvalues to sufficient accuaracy '
934 ELSE IF (info.eq.-15) THEN
935 string='HOWMANY must be one of A or S if RVEC = .TRUE. '
936 ELSE IF (info.eq.-16) THEN
937 string='HOWMANY = S not yet implemented '
938 ELSE IF (info.eq.-17) THEN
939 string='Different count of converge Ritz values in DSEUPD '
940 ELSE IF (info.eq.-9999) THEN
941 string='Could not build and Arnoldi factorization '
942 END IF
943!
944 RETURN
945 END SUBROUTINE iram_error
946
947 END MODULE roms_kernel_mod
subroutine edit_multifile(task)
subroutine memory
Definition memory.F:3
subroutine, public close_out
Definition close_io.F:175
subroutine, public close_file(ng, model, s, ncname, lupdate)
Definition close_io.F:43
subroutine, public close_inp(ng, model)
Definition close_io.F:92
subroutine, public def_gst(ng, model)
Definition def_gst.F:45
subroutine, public get_gst(ng, model)
Definition get_gst.F:38
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
real(dp), dimension(:,:), allocatable cg_beta
real(dp), dimension(:,:), allocatable cg_delta
type(t_io), dimension(:), allocatable lcz
type(t_io), dimension(:), allocatable adm
type(t_io), dimension(:), allocatable tlm
type(t_io), dimension(:), allocatable rst
integer stdout
character(len=256) sourcefile
integer, parameter io_nf90
Definition mod_ncparam.F:95
integer, parameter io_pio
Definition mod_ncparam.F:96
subroutine, public netcdf_close(ng, model, ncid, ncname, lupdate)
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, dimension(:), allocatable ntilex
Definition mod_param.F:685
integer, parameter iadm
Definition mod_param.F:665
integer, dimension(:), allocatable nsize
Definition mod_param.F:648
integer ngrids
Definition mod_param.F:113
integer, dimension(:), allocatable ntilee
Definition mod_param.F:686
integer, parameter itlm
Definition mod_param.F:663
integer ninner
integer, dimension(:), allocatable ntimes
integer, dimension(:), allocatable ntlm
logical lmultigst
integer, dimension(:), allocatable nconv
integer blowup
logical, dimension(:), allocatable lreadfrc
logical, dimension(:), allocatable ldefadj
logical, dimension(:), allocatable lcycleadj
logical, dimension(:), allocatable lwrtadj
logical lrstgst
logical, dimension(:), allocatable lcycletlm
integer exit_flag
real(dp) ritz_tol
logical, dimension(:), allocatable lwrtper
integer maxitergst
logical, dimension(:), allocatable lwrttlm
logical, dimension(:), allocatable lwrtrst
logical, dimension(:), allocatable ldeftlm
integer nrun
integer, dimension(:), allocatable nadj
logical, dimension(:), allocatable lreadfwd
integer noerror
logical, dimension(:), allocatable lcyclerst
logical, dimension(:), allocatable lreadblk
integer msaup2
integer, dimension(8) iaup2
integer, dimension(:), allocatable ido
real(r8), dimension(:,:), allocatable sworkl
integer, dimension(:,:), allocatable ipntr
integer ncv
character(len=1) howmany
logical, dimension(5) laup2
logical lrvec
Definition mod_storage.F:95
integer msaupd
character(len=1) bmat
integer nev
type(t_storage), dimension(:), allocatable storage
Definition mod_storage.F:91
real(r8), dimension(:,:), allocatable norm
integer, dimension(:), allocatable info
subroutine, public allocate_storage
character(len=2) which
integer lworkl
integer, dimension(:,:), allocatable iparam
integer mseigt
integer msapps
integer ndigit
integer msgets
logical, dimension(:,:), allocatable pick
Definition mod_storage.F:96
real(r8) sigmar
integer logfil
real(r8), dimension(:), pointer sworkr
real(r8), dimension(:,:), allocatable rvaluer
integer msaitr
integer mseupd
subroutine, public propagator_hop(runinterval, state, ad_state)
subroutine, public roms_finalize
Definition ad_roms.h:283
subroutine, public roms_run(runinterval)
Definition ad_roms.h:239
subroutine, private iram_error(info, icall, string)
Definition afte_roms.h:862
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_gst(ng, model)
Definition wrt_gst.F:39
subroutine, public wrt_rst(ng, tile)
Definition wrt_rst.F:63
subroutine r_norm2(ng, model, mstr, mend, evalue, evector, state, norm2)
Definition packing.F:175
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
subroutine tl_initial(ng)
Definition tl_initial.F:4