ROMS
Loading...
Searching...
No Matches
roms_kernel_mod Module Reference

Functions/Subroutines

subroutine, public roms_initialize (first, mpicomm)
 
subroutine, public roms_run (runinterval)
 
subroutine, public roms_finalize
 
subroutine, private iram_error (info, icall, string)
 
subroutine, private iram_error (info, string)
 
subroutine, public roms_initializep1 (first, mpicomm, kernel)
 
subroutine, public roms_initializep2 (kernel)
 
subroutine, public roms_initializep3 (kernel)
 
subroutine, public roms_run (runinterval, kernel)
 
subroutine, private nlm_initial (phase)
 
subroutine, private tlm_initial (phase)
 
subroutine, private adm_initial (phase)
 
subroutine, public roms_run (runinterval)
 

Function/Subroutine Documentation

◆ adm_initial()

subroutine, private roms_kernel_mod::adm_initial ( integer, intent(in) phase)
private

Definition at line 1419 of file jedi_roms.h.

1420!
1421!=======================================================================
1422! !
1423! ROMSJEDI adjoint model (ADM) kernel initialization Phases: !
1424! !
1425! Phase 1: Set time-stepping parameters !
1426! !
1427! Phase 2: Computes masks and other configuration arrays. It reads !
1428! initial forcing snapshots. !
1429! !
1430!=======================================================================
1431!
1432! Imported variable declarations
1433!
1434 integer, intent(in) :: Phase
1435!
1436! Local variable declarations.
1437!
1438 integer :: Fcount
1439 integer :: ng, thread, tile
1440 integer :: lstr, ifile
1441
1442 integer, dimension(Ngrids) :: IniRec, Tindex
1443
1444# ifdef GENERIC_DSTART
1445!
1446 real(dp) :: my_dstart
1447# endif
1448!
1449 character (len=10) :: suffix
1450
1451 character (len=*), parameter :: MyFile = &
1452 & __FILE__//", adm_initial"
1453
1454# ifdef PROFILE
1455!
1456!-----------------------------------------------------------------------
1457! Start time wall clocks.
1458!-----------------------------------------------------------------------
1459!
1460 DO ng=1,ngrids
1461 DO thread=thread_range
1462 CALL wclock_on (ng, iadm, 2, __line__, myfile)
1463 END DO
1464 END DO
1465# endif
1466!
1467!=======================================================================
1468! ROMSJEDI ADM kernel, Phase 1 Initialization.
1469!=======================================================================
1470!
1471 phase1 : IF (phase.eq.1) THEN
1472!
1473 IF (master) THEN
1474 WRITE (stdout,10) 'ADM_INITIAL: Phase 1 Initialization: ', &
1475 & 'Configuring ROMS nonlinear kernel ...'
1476 END IF
1477!
1478! Initialize time stepping indices and counters.
1479!
1480 DO ng=1,ngrids
1481 iif(ng)=1
1482 indx1(ng)=1
1483 kstp(ng)=1
1484 krhs(ng)=3
1485 knew(ng)=2
1486 predictor_2d_step(ng)=.false.
1487!
1488 iic(ng)=0
1489# ifdef JEDI
1490 jic(ng)=0
1491# endif
1492# ifdef SOLVE3D
1493 nstp(ng)=1
1494 nnew(ng)=2
1495 nrhs(ng)=nstp(ng)
1496# endif
1497# ifdef FLOATS_NOT_YET
1498 nf(ng)=0
1499 nfp1(ng)=1
1500 nfm1(ng)=4
1501 nfm2(ng)=3
1502 nfm3(ng)=2
1503# endif
1504!
1505 synchro_flag(ng)=.true.
1506 first_time(ng)=0
1507 ad_ubar_xs=0.0_r8
1508
1509# ifdef GENERIC_DSTART
1510!
1511! Rarely, the adjoint model is initialized from a NetCDF file, so we do
1512! not know its actual initialization time. Usually, it is computed from
1513! DSTART, implying that its value is correct in the ROMS input script.
1514! Therefore, the user needs to check and update its value to every time
1515! that ROMS is executed. Alternatively, if available, we can use the
1516! initialization time from the nonlinear model, INItime. This variable
1517! is assigned when computing or processing the basic state trajectory
1518! needed to linearize the adjoint model.
1519!
1520 IF (initime(ng).lt.0.0_dp) THEN
1521 my_dstart=dstart ! ROMS input script
1522 ELSE
1523 my_dstart=initime(ng)/86400.0_dp ! NLM IC time is known
1524 END IF
1525 tdays(ng)=my_dstart+dt(ng)*real(ntimes(ng),r8)*sec2day
1526 time(ng)=tdays(ng)*day2sec
1527 ntstart(ng)=int((time(ng)-dstart*day2sec)/dt(ng))+1
1528 ntend(ng)=ntstart(ng)-ntimes(ng)
1529 ntfirst(ng)=ntend(ng)
1530# else
1531 tdays(ng)=dstart+ &
1532 & dt(ng)*real(ntimes(ng)-ntfirst(ng)+1,r8)*sec2day
1533 time(ng)=tdays(ng)*day2sec
1534 ntstart(ng)=ntimes(ng)+1
1535 ntend(ng)=ntfirst(ng)
1536 ntfirst(ng)=ntend(ng)
1537# endif
1538# ifdef JEDI
1539 time4jedi(ng)=time(ng)
1540# endif
1541 inirec(ng)=nrrec(ng)
1542 tindex(ng)=1
1543 END DO
1544!
1545! Initialize global diagnostics variables.
1546!
1547 avgke=0.0_dp
1548 avgpe=0.0_dp
1549 avgkp=0.0_dp
1550 volume=0.0_dp
1551
1552 END IF phase1
1553!
1554!=======================================================================
1555! ROMSJEDI ADM kernel, Phase 2 Initialization.
1556!=======================================================================
1557!
1558 phase2: IF (phase.eq.2) THEN
1559!
1560 IF (master) THEN
1561 WRITE (stdout,10) 'ADM_INITIAL: Phase 2 Initialization: ', &
1562 & 'Get/Set required applications fields ...'
1563 END IF
1564!
1565!-----------------------------------------------------------------------
1566! Initialize horizontal mixing coefficients. If applicable, scale
1567! mixing coefficients according to the grid size (smallest area).
1568# ifndef ANA_SPONGE
1569! Also increase their values in sponge areas using the "visc_factor"
1570! and/or "diff_factor" read from input Grid NetCDF file.
1571# endif
1572!-----------------------------------------------------------------------
1573!
1574 DO ng=1,ngrids
1575 DO tile=first_tile(ng),last_tile(ng),+1
1576 CALL ini_hmixcoef (ng, tile, iadm)
1577 END DO
1578 END DO
1579
1580# ifdef ANA_SPONGE
1581!
1582!-----------------------------------------------------------------------
1583! Increase horizontal mixing coefficients in sponge areas using
1584! analytical functions.
1585!-----------------------------------------------------------------------
1586!
1587 DO ng=1,ngrids
1588 IF (lsponge(ng)) THEN
1589 DO tile=first_tile(ng),last_tile(ng),+1
1590 CALL ana_sponge (ng, tile, iadm)
1591 END DO
1592 END IF
1593 END DO
1594# endif
1595
1596# ifdef WET_DRY
1597!
1598!-----------------------------------------------------------------------
1599! Process initial wet/dry masks.
1600!-----------------------------------------------------------------------
1601!
1602 DO ng=1,ngrids
1603 DO tile=first_tile(ng),last_tile(ng),+1
1604 CALL wetdry (ng, tile, tindex(ng), .true.)
1605 END DO
1606 END DO
1607# endif
1608
1609# ifdef FORWARD_FLUXES
1610!
1611!-----------------------------------------------------------------------
1612! Set the BLK structure to contain the nonlinear model surface fluxes
1613! needed by the tangent linear and adjoint models. Also, set switches
1614! to process that structure in routine "check_multifile". Notice that
1615! it is possible to split the solution into multiple NetCDF files to
1616! reduce their size.
1617!-----------------------------------------------------------------------
1618!
1619! Set the nonlinear model quicksave-history file as the basic state for
1620! the surface fluxes computed in "bulk_flux", which may be available at
1621! more frequent intervals while avoiding large files. Since the 4D-Var
1622! increment phase is calculated by a different executable and needs to
1623! know some of the QCK structure information.
1624!
1625 DO ng=1,ngrids
1626 WRITE (qck(ng)%name,"(a,'.nc')") trim(qck(ng)%head)
1627 lstr=len_trim(qck(ng)%name)
1628 qck(ng)%base=qck(ng)%name(1:lstr-3)
1629 IF (qck(ng)%Nfiles.gt.1) THEN
1630 DO ifile=1,qck(ng)%Nfiles
1631 WRITE (suffix,"('_',i4.4,'.nc')") ifile
1632 qck(ng)%files(ifile)=trim(qck(ng)%base)//trim(suffix)
1633 END DO
1634 qck(ng)%name=trim(qck(ng)%files(1))
1635 ELSE
1636 qck(ng)%files(1)=trim(qck(ng)%name)
1637 END IF
1638 END DO
1639!
1640! The switch LreadFRC is deactivated because all the atmospheric
1641! forcing, including shortwave radiation, is read from the NLM
1642! surface fluxes or is assigned during ESM coupling. Such fluxes
1643! are available from the QCK structure. There is no need for reading
1644! and processing from the FRC structure input forcing-files.
1645!
1646 CALL edit_multifile ('QCK2BLK')
1647 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1648 DO ng=1,ngrids
1649 lreadblk(ng)=.true.
1650 lreadfrc(ng)=.false.
1651 lreadqck(ng)=.false.
1652 END DO
1653# endif
1654!
1655!-----------------------------------------------------------------------
1656! If applicable, close all input boundary, climatology, and forcing
1657! NetCDF files and set associated parameters to the closed state. This
1658! step is essential in iterative algorithms that run the full TLM
1659! repetitively. Then, Initialize several parameters in their file
1660! structure, so the appropriate input single or multi-file is selected
1661! during initialization/restart.
1662!-----------------------------------------------------------------------
1663!
1664 DO ng=1,ngrids
1665 CALL close_inp (ng, iadm)
1666 CALL check_multifile (ng, iadm)
1667# ifdef DISTRIBUTE
1668 CALL mp_bcasti (ng, iadm, exit_flag)
1669# endif
1670 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1671 END DO
1672!
1673!-----------------------------------------------------------------------
1674! Read in initial forcing, climatology and assimilation data from
1675! input NetCDF files. It loads the first relevant data record for
1676! the time-interpolation between snapshots.
1677!-----------------------------------------------------------------------
1678!
1679 DO ng=1,ngrids
1680 CALL ad_get_idata (ng)
1681 CALL ad_get_data (ng)
1682# ifdef DISTRIBUTE
1683 CALL mp_bcasti (ng, iadm, exit_flag)
1684# endif
1685 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1686 END DO
1687
1688# ifdef MASKING
1689!
1690!-----------------------------------------------------------------------
1691! Set internal I/O mask arrays.
1692!-----------------------------------------------------------------------
1693!
1694 DO ng=1,ngrids
1695 DO tile=first_tile(ng),last_tile(ng),+1
1696 CALL set_masks (ng, tile, iadm)
1697 END DO
1698 END DO
1699# endif
1700
1701# if defined ANA_DRAG && defined UV_DRAG_GRID
1702!
1703!-----------------------------------------------------------------------
1704! Set analytical spatially varying bottom friction parameter.
1705!-----------------------------------------------------------------------
1706!
1707 IF (nrun.eq.erstr) THEN
1708 DO ng=1,ngrids
1709 DO tile=first_tile(ng),last_tile(ng),+1
1710 CALL ana_drag (ng, tile, iadm)
1711 END DO
1712 END DO
1713 END IF
1714# endif
1715!
1716!-----------------------------------------------------------------------
1717! Compute grid stiffness.
1718!-----------------------------------------------------------------------
1719!
1720 IF (lstiffness) THEN
1721 lstiffness=.false.
1722 DO ng=1,ngrids
1723 DO tile=first_tile(ng),last_tile(ng),+1
1724 CALL stiffness (ng, tile, iadm)
1725 END DO
1726 END DO
1727 END IF
1728
1729# if defined FLOATS_NOT_YET || defined STATIONS
1730!
1731!-----------------------------------------------------------------------
1732! If applicable, convert initial locations to fractional grid
1733! coordinates.
1734!-----------------------------------------------------------------------
1735!
1736 DO ng=1,ngrids
1737 CALL grid_coords (ng, iadm)
1738 END DO
1739# endif
1740!
1741!-----------------------------------------------------------------------
1742! Initialize time-stepping counter.
1743!-----------------------------------------------------------------------
1744!
1745 DO ng=1,ngrids
1746!! ntstart(ng)=ntstart(ng)-1
1747 iic(ng)=ntstart(ng)
1748# ifdef JEDI
1749 jic(ng)=ntstart(ng)+1
1750 time4jedi(ng)=time(ng)+dt(ng)
1751# endif
1752 CALL time_string (time(ng), time_code(ng))
1753 ldefadj(ng)=.true.
1754 lwrtadj(ng)=.true.
1755 END DO
1756
1757 END IF phase2
1758
1759# ifdef PROFILE
1760!
1761!-----------------------------------------------------------------------
1762! Turn off initialization time wall clock.
1763!-----------------------------------------------------------------------
1764!
1765 DO ng=1,ngrids
1766 DO thread=thread_range
1767 CALL wclock_off (ng, iadm, 2, __line__, myfile)
1768 END DO
1769 END DO
1770# endif
1771!
1772 10 FORMAT (/,1x,a,a,/,1x,'***********',/)
1773!
1774 RETURN
subroutine ad_get_data(ng)
Definition ad_get_data.F:4
subroutine ad_get_idata(ng)
Definition ad_get_idata.F:4
subroutine check_multifile(ng, model)
subroutine edit_multifile(task)
subroutine grid_coords(ng, model)
Definition grid_coords.F:4
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

References ad_get_data(), ad_get_idata(), mod_scalars::ad_ubar_xs, analytical_mod::ana_drag(), analytical_mod::ana_sponge(), mod_scalars::avgke, mod_scalars::avgkp, mod_scalars::avgpe, check_multifile(), close_io_mod::close_inp(), mod_scalars::day2sec, mod_scalars::dstart, mod_scalars::dt, edit_multifile(), mod_scalars::erstr, mod_scalars::exit_flag, mod_parallel::first_tile, mod_scalars::first_time, strings_mod::founderror(), grid_coords(), mod_param::iadm, mod_scalars::iic, mod_scalars::iif, mod_scalars::indx1, ini_hmixcoef_mod::ini_hmixcoef(), mod_scalars::initime, mod_scalars::jic, mod_stepping::knew, mod_stepping::krhs, mod_stepping::kstp, mod_parallel::last_tile, mod_scalars::ldefadj, mod_scalars::lreadblk, mod_scalars::lreadfrc, mod_scalars::lreadqck, mod_scalars::lsponge, mod_scalars::lstiffness, mod_scalars::lwrtadj, mod_parallel::master, mod_stepping::nf, mod_stepping::nfm1, mod_stepping::nfm2, mod_stepping::nfm3, mod_stepping::nfp1, mod_param::ngrids, mod_stepping::nnew, mod_scalars::noerror, mod_stepping::nrhs, mod_scalars::nrrec, mod_scalars::nrun, mod_stepping::nstp, mod_scalars::ntend, mod_scalars::ntfirst, mod_scalars::ntimes, mod_scalars::ntstart, mod_scalars::predictor_2d_step, mod_iounits::qck, mod_scalars::sec2day, set_masks_mod::set_masks(), mod_iounits::stdout, stiffness_mod::stiffness(), mod_scalars::synchro_flag, mod_scalars::tdays, mod_scalars::time, mod_scalars::time4jedi, mod_scalars::time_code, dateclock_mod::time_string(), mod_scalars::volume, wclock_off(), wclock_on(), and wetdry_mod::wetdry().

Referenced by roms_initializep1(), roms_initializep2(), and roms_initializep3().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ iram_error() [1/2]

subroutine private roms_kernel_mod::iram_error ( integer, intent(in) info,
integer, intent(in) icall,
character (len=*), intent(out) string )
private

Definition at line 861 of file afte_roms.h.

862!
863!=======================================================================
864! !
865! This routine decodes internal error messages from the Implicit !
866! Restarted Arnoldi Method (IRAM) for the computation of optimal !
867! perturbation Ritz eigenfunctions. !
868! !
869!=======================================================================
870!
871! imported variable declarations.
872!
873 integer, intent(in) :: info, icall
874!
875 character (len=*), intent(out) :: string
876!
877!-----------------------------------------------------------------------
878! Decode error message from IRAM.
879!-----------------------------------------------------------------------
880!
881 IF (info.eq.0) THEN
882 string='Normal exit '
883 ELSE IF (info.eq.1) THEN
884 IF (icall.eq.1) THEN
885 string='Maximum number of iterations taken '
886 ELSE
887 string='Could not reorder Schur vectors '
888 END IF
889 ELSE IF (info.eq.3) THEN
890 string='No shifts could be applied during an IRAM cycle '
891 ELSE IF (info.eq.-1) THEN
892 string='Nstate must be positive '
893 ELSE IF (info.eq.-2) THEN
894 string='NEV must be positive '
895 ELSE IF (info.eq.-3) THEN
896 string='NCV must be greater NEV and less than or equal Nstate '
897 ELSE IF (info.eq.-4) THEN
898 string='Maximum number of iterations must be greater than zero '
899 ELSE IF (info.eq.-5) THEN
900 string='WHICH must be one of LM, SM, LA, SA or BE '
901 ELSE IF (info.eq.-6) THEN
902 string='BMAT must be one of I or G '
903 ELSE IF (info.eq.-7) THEN
904 string='Length of private work array SworkL is not sufficient '
905 ELSE IF (info.eq.-8) THEN
906 IF (icall.eq.1) THEN
907 string='Error return from LAPACK eigenvalue calculation '
908 ELSE
909 string='Error in DLAHQR in the Shurn vectors calculation '
910 END IF
911 ELSE IF (info.eq.-9) THEN
912 IF (icall.eq.1) THEN
913 string='Starting vector is zero'
914 ELSE
915 string='Error in DTREVC in the eigenvectors calculation '
916 END IF
917 ELSE IF (info.eq.-10) THEN
918 string='IPARAM(7) must be 1, 2, 3, 4, 5 '
919 ELSE IF (info.eq.-11) THEN
920 string='IPARAM(7) = 1 and BMAT = G are incompatable '
921 ELSE IF (info.eq.-12) THEN
922 IF (icall.eq.1) THEN
923 string='IPARAM(1) must be equal to 0 or 1 '
924 ELSE
925 string='HOWMANY = S not yet implemented '
926 END IF
927 ELSE IF (info.eq.-13) THEN
928 string='HOWMANY must be one of A or P if Lrvec = .TRUE. '
929 ELSE IF (info.eq.-14) THEN
930 string='Did not find any eigenvalues to sufficient accuaracy '
931 ELSE IF (info.eq.-15) THEN
932 string='Different count of converge Ritz values in DNEUPD '
933 ELSE IF (info.eq.-9999) THEN
934 string='Could not build and Arnoldi factorization '
935 END IF
936!
937 RETURN

References mod_storage::info.

◆ iram_error() [2/2]

subroutine private roms_kernel_mod::iram_error ( integer, intent(in) info,
character (len=*), intent(out) string )
private

Definition at line 837 of file fsv_roms.h.

838!
839!=======================================================================
840! !
841! This routine decodes internal error messages from the Implicit !
842! Restarted Arnoldi Method (IRAM) for the computation of optimal !
843! perturbation Ritz eigenfunctions. !
844! !
845!=======================================================================
846!
847! imported variable declarations.
848!
849 integer, intent(in) :: info
850!
851 character (len=*), intent(out) :: string
852!
853!-----------------------------------------------------------------------
854! Decode error message from IRAM.
855!-----------------------------------------------------------------------
856!
857 IF (info.eq.0) THEN
858 string='Normal exit '
859 ELSE IF (info.eq.1) THEN
860 string='Maximum number of iterations taken '
861 ELSE IF (info.eq.3) THEN
862 string='No shifts could be applied during an IRAM cycle '
863 ELSE IF (info.eq.-1) THEN
864 string='Nstate must be positive '
865 ELSE IF (info.eq.-2) THEN
866 string='NEV must be positive '
867 ELSE IF (info.eq.-3) THEN
868 string='NCV must be greater NEV and less than or equal Nstate '
869 ELSE IF (info.eq.-4) THEN
870 string='Maximum number of iterations must be greater than zero '
871 ELSE IF (info.eq.-5) THEN
872 string='WHICH must be one of LM, SM, LA, SA or BE '
873 ELSE IF (info.eq.-6) THEN
874 string='BMAT must be one of I or G '
875 ELSE IF (info.eq.-7) THEN
876 string='Length of private work array SworkL is not sufficient '
877 ELSE IF (info.eq.-8) THEN
878 string='Error in DSTEQR in the eigenvalue calculation '
879 ELSE IF (info.eq.-9) THEN
880 string='Starting vector is zero '
881 ELSE IF (info.eq.-10) THEN
882 string='IPARAM(7) must be 1, 2, 3, 4, 5 '
883 ELSE IF (info.eq.-11) THEN
884 string='IPARAM(7) = 1 and BMAT = G are incompatable '
885 ELSE IF (info.eq.-12) THEN
886 string='IPARAM(1) must be equal to 0 or 1 '
887 ELSE IF (info.eq.-13) THEN
888 string='NEV and WHICH = BE are incompatable '
889 ELSE IF (info.eq.-14) THEN
890 string='Did not find any eigenvalues to sufficient accuaracy '
891 ELSE IF (info.eq.-15) THEN
892 string='HOWMANY must be one of A or S if RVEC = .TRUE. '
893 ELSE IF (info.eq.-16) THEN
894 string='HOWMANY = S not yet implemented '
895 ELSE IF (info.eq.-17) THEN
896 string='Different count of converge Ritz values in DSEUPD '
897 ELSE IF (info.eq.-9999) THEN
898 string='Could not build and Arnoldi factorization '
899 END IF
900!
901 RETURN

References mod_storage::info.

◆ nlm_initial()

subroutine, private roms_kernel_mod::nlm_initial ( integer, intent(in) phase)
private

Definition at line 529 of file jedi_roms.h.

530!
531!=======================================================================
532! !
533! ROMSJEDI nonlinear model (NLM) kernel initialization Phases: !
534! !
535! Phase 1: Set time-stepping parameters !
536! !
537! Phase 2: Computes initial depths, density, horizontal mass !
538! fluxes, and other configuration arrays. It reads !
539! forcing snapshots. !
540! !
541! Phase 3: Computes the initial depths and level thicknesses from !
542! the initial time-averaged free-surface field, Zt_avg1. !
543! Additionally, it initializes the state variables for !
544! all time levels and applies lateral boundary conditions.!
545! !
546!=======================================================================
547!
548! Imported variable declarations
549!
550 integer, intent(in) :: Phase
551!
552! Local variable declarations.
553!
554 integer :: Fcount
555 integer :: ng, thread, tile
556#ifdef NESTING
557 integer :: ig, nl
558 integer :: cr, i, m
559#endif
560 integer, dimension(Ngrids) :: IniRec, Tindex
561!
562 character (len=*), parameter :: MyFile = &
563 & __FILE__//", nlm_initial"
564
565#ifdef PROFILE
566!
567!-----------------------------------------------------------------------
568! Start time wall clocks.
569!-----------------------------------------------------------------------
570!
571 DO ng=1,ngrids
572 DO thread=thread_range
573 CALL wclock_on (ng, inlm, 2, __line__, myfile)
574 END DO
575 END DO
576#endif
577!
578!=======================================================================
579! ROMSJEDI NLM kernel, Phase 1 Initialization.
580!=======================================================================
581!
582 phase1 : IF (phase.eq.1) THEN
583!
584 IF (master) THEN
585 WRITE (stdout,10) 'NLM_INITIAL: Phase 1 Initialization: ', &
586 & 'Configuring ROMS nonlinear kernel ...'
587 END IF
588!
589! Initialize time stepping indices and counters.
590!
591 DO ng=1,ngrids
592 iif(ng)=1
593 indx1(ng)=1
594 kstp(ng)=1
595 krhs(ng)=1
596 knew(ng)=1
597 predictor_2d_step(ng)=.false.
598!
599 iic(ng)=0
600# ifdef JEDI
601 jic(ng)=0
602# endif
603 nstp(ng)=1
604 nrhs(ng)=1
605 nnew(ng)=1
606#ifdef FLOATS
607 nf(ng)=0
608 nfp1(ng)=1
609 nfm1(ng)=4
610 nfm2(ng)=3
611 nfm3(ng)=2
612#endif
613!
614 inirec(ng)=nrrec(ng)
615 tindex(ng)=1
616!
617 synchro_flag(ng)=.true.
618 first_time(ng)=0
619 tdays(ng)=dstart
620 time(ng)=tdays(ng)*day2sec
621#ifdef JEDI
622 time4jedi(ng)=time(ng)
623#endif
624 ntstart(ng)=int((time(ng)-dstart*day2sec)/dt(ng))+1
625 ntfirst(ng)=ntstart(ng)
626 step_counter(ng)=0
627 END DO
628!
629! Initialize global diagnostics variables.
630!
631 avgke=0.0_dp
632 avgpe=0.0_dp
633 avgkp=0.0_dp
634 volume=0.0_dp
635!
636! Reset output history files time record counters. These counters are
637! reset on every iteration pass. This file is created on the first
638! iteration pass.
639!
640 DO ng=1,ngrids
641 ldefhis(ng)=.true.
642 lwrthis(ng)=.true.
643 his(ng)%Rindex=0
644 fcount=his(ng)%Fcount
645 his(ng)%Nrec(fcount)=0
646
647 ldefqck(ng)=.true.
648 lwrtqck(ng)=.true.
649 qck(ng)%Rindex=0
650 fcount=qck(ng)%Fcount
651 qck(ng)%Nrec(fcount)=0
652
653 ldefrst(ng)=.true.
654 lwrtrst(ng)=.true.
655 rst(ng)%Rindex=0
656 fcount=rst(ng)%Fcount
657 rst(ng)%Nrec(fcount)=0
658 END DO
659
660 END IF phase1
661!
662!=======================================================================
663! ROMSJEDI NLM kernel, Phase 2 Initialization.
664!=======================================================================
665!
666 phase2: IF (phase.eq.2) THEN
667!
668 IF (master) THEN
669 WRITE (stdout,10) 'NLM_INITIAL: Phase 2 Initialization: ', &
670 & 'Get/Set required applications fields ...'
671 END IF
672!
673!-----------------------------------------------------------------------
674! Initialize horizontal mixing coefficients. If applicable, scale
675! mixing coefficients according to the grid size (smallest area).
676#ifndef ANA_SPONGE
677! Also increase their values in sponge areas using the "visc_factor"
678! and/or "diff_factor" read from input Grid NetCDF file.
679#endif
680!-----------------------------------------------------------------------
681!
682 DO ng=1,ngrids
683 DO tile=first_tile(ng),last_tile(ng),+1
684 CALL ini_hmixcoef (ng, tile, inlm)
685 END DO
686 END DO
687
688#ifdef ANA_SPONGE
689!
690!-----------------------------------------------------------------------
691! Increase horizontal mixing coefficients in sponge areas using
692! analytical functions.
693!-----------------------------------------------------------------------
694!
695 DO ng=1,ngrids
696 IF (lsponge(ng)) THEN
697 DO tile=first_tile(ng),last_tile(ng),+1
698 CALL ana_sponge (ng, tile, inlm)
699 END DO
700 END IF
701 END DO
702#endif
703
704#ifdef WET_DRY
705!
706!-----------------------------------------------------------------------
707! Process initial wet/dry masks.
708!-----------------------------------------------------------------------
709!
710 DO ng=1,ngrids
711 DO tile=first_tile(ng),last_tile(ng),+1
712 CALL wetdry (ng, tile, tindex(ng), .true.)
713 END DO
714 END DO
715#endif
716
717#ifdef SOLVE3D
718!
719!-----------------------------------------------------------------------
720! Compute time independent (Zt_avg1=0) and initial time dependent
721! depths and level thicknesses.
722!-----------------------------------------------------------------------
723!
724 DO ng=1,ngrids
725 DO tile=first_tile(ng),last_tile(ng),+1
726 CALL set_depth0 (ng, tile, inlm)
727 CALL set_depth (ng, tile, inlm)
728 END DO
729 END DO
730!
731!-----------------------------------------------------------------------
732! Compute initial horizontal mass fluxes, Hz*u/n and Hz*v/m.
733!-----------------------------------------------------------------------
734!
735 DO ng=1,ngrids
736 DO tile=first_tile(ng),last_tile(ng),+1
737 CALL set_massflux (ng, tile, inlm)
738 END DO
739 END DO
740!
741!-----------------------------------------------------------------------
742! Compute initial S-coordinates vertical velocity. Compute initial
743! density anomaly from potential temperature and salinity via equation
744! of state for seawater. Also compute other equation of state related
745! quatities.
746!-----------------------------------------------------------------------
747!
748 DO ng=1,ngrids
749 DO tile=first_tile(ng),last_tile(ng),+1
750 CALL omega (ng, tile, inlm)
751 CALL rho_eos (ng, tile, inlm)
752 END DO
753 END DO
754#endif
755
756#ifdef ANA_PSOURCE
757!
758!-----------------------------------------------------------------------
759! Set point Sources/Sinks position, direction, special flag, and mass
760! transport nondimensional shape profile with analytcal expressions.
761! Point sources are at U- and V-points. We need to get their positions
762! to process internal Land/Sea masking arrays during initialization.
763!-----------------------------------------------------------------------
764!
765 DO ng=1,ngrids
766 IF (luvsrc(ng).or.lwsrc(ng).or.any(ltracersrc(:,ng))) THEN
767 DO tile=first_tile(ng),last_tile(ng),+1
768 CALL ana_psource (ng, tile, inlm)
769 END DO
770 END IF
771 END DO
772#endif
773!
774!-----------------------------------------------------------------------
775! If applicable, close all input boundary, climatology, and forcing
776! NetCDF files and set associated parameters to the closed state. This
777! step is essential in iterative algorithms that run the full TLM
778! repetitively. Then, Initialize several parameters in their file
779! structure, so the appropriate input single or multi-file is selected
780! during initialization/restart.
781!-----------------------------------------------------------------------
782!
783 DO ng=1,ngrids
784 CALL close_inp (ng, inlm)
785 CALL check_multifile (ng, inlm)
786#ifdef DISTRIBUTE
787 CALL mp_bcasti (ng, inlm, exit_flag)
788#endif
789 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
790 END DO
791!
792! If applicable, read in input data.
793!
794 DO ng=1,ngrids
795 CALL get_idata (ng)
796 CALL get_data (ng)
797#ifdef DISTRIBUTE
798 CALL mp_bcasti (ng, inlm, exit_flag)
799#endif
800 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
801 END DO
802
803#ifdef MASKING
804!
805!-----------------------------------------------------------------------
806! Set internal I/O mask arrays.
807!-----------------------------------------------------------------------
808!
809 DO ng=1,ngrids
810 DO tile=first_tile(ng),last_tile(ng),+1
811 CALL set_masks (ng, tile, inlm)
812 END DO
813 END DO
814#endif
815
816#ifdef NESTING
817# if defined MASKING || defined WET_DRY
818!
819!-----------------------------------------------------------------------
820! If nesting and Land/Sea masking, scale horizontal interpolation
821! weights to account for land contact points.
822!-----------------------------------------------------------------------
823!
824 DO ng=1,ngrids
825 CALL nesting (ng, inlm, nmask)
826 END DO
827# endif
828!
829!-----------------------------------------------------------------------
830! If nesting, process state fields initial conditions in the contact
831! regions.
832!-----------------------------------------------------------------------
833!
834! Free-surface and 2D-momentum.
835!
836 DO nl=1,nestlayers
837 DO ig=1,gridsinlayer(nl)
838 ng=gridnumber(ig,nl)
839 IF (any(compositegrid(:,ng))) THEN
840 CALL nesting (ng, inlm, nfsic) ! free-surface
841# ifndef SOLVE3D
842 CALL nesting (ng, inlm, n2dic) ! 2d momentum
843# endif
844 END IF
845 END DO
846 END DO
847
848# ifdef SOLVE3D
849!
850! Determine vertical indices and vertical interpolation weights in
851! the contact zone using initial unperturbed depth arrays.
852!
853 DO ng=1,ngrids
854 CALL nesting (ng, inlm, nzwgt)
855 END DO
856!
857! 3D-momentum and tracers.
858!
859 DO nl=1,nestlayers
860 DO ig=1,gridsinlayer(nl)
861 ng=gridnumber(ig,nl)
862 IF (any(compositegrid(:,ng))) THEN
863 CALL nesting (ng, inlm, n3dic) ! 3D momentum
864 CALL nesting (ng, inlm, ntvic) ! Tracer variables
865 END IF
866 END DO
867 END DO
868# endif
869#endif
870
871#if defined ANA_DRAG && defined UV_DRAG_GRID
872!
873!-----------------------------------------------------------------------
874! Set analytical spatially varying bottom friction parameter.
875!-----------------------------------------------------------------------
876!
877 IF (nrun.eq.erstr) THEN
878 DO ng=1,ngrids
879 DO tile=first_tile(ng),last_tile(ng),+1
880 CALL ana_drag (ng, tile, inlm)
881 END DO
882 END DO
883 END IF
884#endif
885!
886!-----------------------------------------------------------------------
887! Compute grid stiffness.
888!-----------------------------------------------------------------------
889!
890 IF (lstiffness) THEN
891 lstiffness=.false.
892 DO ng=1,ngrids
893 DO tile=first_tile(ng),last_tile(ng),+1
894 CALL stiffness (ng, tile, inlm)
895 END DO
896 END DO
897 END IF
898
899#if defined FLOATS || defined STATIONS
900!
901!-----------------------------------------------------------------------
902! If applicable, convert initial locations to fractional grid
903! coordinates.
904!-----------------------------------------------------------------------
905!
906 DO ng=1,ngrids
907 CALL grid_coords (ng, inlm)
908 END DO
909#endif
910 END IF phase2
911!
912!=======================================================================
913! ROMSJEDI NLM kernel, Phase 3 Initialization.
914!=======================================================================
915!
916 phase3: IF (phase.eq.3) THEN
917!
918 IF (master) THEN
919 WRITE (stdout,10) 'NLM_INITIAL: Phase 3 Initialization: ', &
920 & 'State Lateral Boundary Conditions ...'
921 END IF
922!
923!-----------------------------------------------------------------------
924! Initialize time-stepping counter and time/date string. Save NLM
925! initial conditions time.
926!
927! Notice that it is allowed to modify the "simulation length" in the
928! roms-jedi YAML file, which will affect the values of "ntimes" and
929! "ntend".
930!-----------------------------------------------------------------------
931!
932 DO ng=1,ngrids
933 initime(ng)=time(ng)
934 iic(ng)=ntstart(ng)
935 ntend(ng)=ntstart(ng)+ntimes(ng)-1
936#ifdef JEDI
937 jic(ng)=ntstart(ng)
938 time4jedi(ng)=time(ng)
939#endif
940 CALL time_string (time(ng), time_code(ng))
941 END DO
942!
943!-----------------------------------------------------------------------
944! Read in required data, if any, from input NetCDF files.
945!-----------------------------------------------------------------------
946!
947 DO ng=1,ngrids
948 CALL get_data (ng)
949 IF (founderror(exit_flag, noerror, &
950 & __line__, myfile)) RETURN
951 END DO
952!
953!-----------------------------------------------------------------------
954! If applicable, process input data: time interpolate between data
955! snapshots.
956!-----------------------------------------------------------------------
957!
958 DO ng=1,ngrids
959 DO tile=first_tile(ng),last_tile(ng),+1
960 CALL set_data (ng, tile)
961 END DO
962 END DO
963 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
964!
965!-----------------------------------------------------------------------
966! Computes the initial depths and level thicknesses from the initial
967! time=averaged free-surface field, Zt_avg1 . Additionally, it
968! initializes the nonlinear state variables for all time levels and
969! applies lateral boundary conditions.
970!-----------------------------------------------------------------------
971!
972 DO ng=1,ngrids
973 CALL post_initial (ng, inlm)
974 END DO
975 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
976
977 END IF phase3
978
979#ifdef PROFILE
980!
981!-----------------------------------------------------------------------
982! Turn off initialization time wall clock.
983!-----------------------------------------------------------------------
984!
985 DO ng=1,ngrids
986 DO thread=thread_range
987 CALL wclock_off (ng, inlm, 2, __line__, myfile)
988 END DO
989 END DO
990#endif
991!
992 10 FORMAT (/,1x,a,a,/,1x,'***********',/)
993!
994 RETURN
subroutine get_data(ng)
Definition get_data.F:3
subroutine get_idata(ng)
Definition get_idata.F:3
subroutine set_data(ng, tile)
Definition set_data.F:4

References analytical_mod::ana_drag(), analytical_mod::ana_psource(), analytical_mod::ana_sponge(), mod_scalars::avgke, mod_scalars::avgkp, mod_scalars::avgpe, check_multifile(), close_io_mod::close_inp(), mod_scalars::compositegrid, mod_scalars::day2sec, mod_scalars::dstart, mod_scalars::dt, mod_scalars::erstr, mod_scalars::exit_flag, mod_parallel::first_tile, mod_scalars::first_time, strings_mod::founderror(), get_data(), get_idata(), grid_coords(), mod_param::gridnumber, mod_param::gridsinlayer, mod_iounits::his, mod_scalars::iic, mod_scalars::iif, mod_scalars::indx1, ini_hmixcoef_mod::ini_hmixcoef(), mod_scalars::initime, mod_param::inlm, mod_scalars::jic, mod_stepping::knew, mod_stepping::krhs, mod_stepping::kstp, mod_parallel::last_tile, mod_scalars::ldefhis, mod_scalars::ldefqck, mod_scalars::ldefrst, mod_scalars::lsponge, mod_scalars::lstiffness, mod_scalars::ltracersrc, mod_scalars::luvsrc, mod_scalars::lwrthis, mod_scalars::lwrtqck, mod_scalars::lwrtrst, mod_scalars::lwsrc, mod_parallel::master, mod_nesting::n2dic, mod_nesting::n3dic, nesting_mod::nesting(), mod_param::nestlayers, mod_stepping::nf, mod_stepping::nfm1, mod_stepping::nfm2, mod_stepping::nfm3, mod_stepping::nfp1, mod_nesting::nfsic, mod_param::ngrids, mod_nesting::nmask, mod_stepping::nnew, mod_scalars::noerror, mod_stepping::nrhs, mod_scalars::nrrec, mod_scalars::nrun, mod_stepping::nstp, mod_scalars::ntend, mod_scalars::ntfirst, mod_scalars::ntimes, mod_scalars::ntstart, mod_nesting::ntvic, mod_nesting::nzwgt, omega_mod::omega(), post_initial_mod::post_initial(), mod_scalars::predictor_2d_step, mod_iounits::qck, rho_eos_mod::rho_eos(), mod_iounits::rst, set_data(), set_depth_mod::set_depth(), set_depth_mod::set_depth0(), set_masks_mod::set_masks(), set_massflux_mod::set_massflux(), mod_iounits::stdout, mod_scalars::step_counter, stiffness_mod::stiffness(), mod_scalars::synchro_flag, mod_scalars::tdays, mod_scalars::time, mod_scalars::time4jedi, mod_scalars::time_code, dateclock_mod::time_string(), mod_scalars::volume, wclock_off(), wclock_on(), and wetdry_mod::wetdry().

Referenced by roms_initializep1(), roms_initializep2(), and roms_initializep3().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ roms_finalize()

subroutine public roms_kernel_mod::roms_finalize

Definition at line 282 of file ad_roms.h.

283!
284!=======================================================================
285! !
286! This routine terminates ROMS adjoint model execution. !
287! !
288!=======================================================================
289!
290! Local variable declarations.
291!
292 integer :: Fcount, ng, thread
293!
294 character (len=*), parameter :: MyFile = &
295 & __FILE__//", ROMS_finalize"
296!
297!-----------------------------------------------------------------------
298! If blowing-up, save latest model state into RESTART NetCDF file.
299!-----------------------------------------------------------------------
300!
301! If cycling restart records, write solution into the next record.
302!
303 IF (exit_flag.eq.1) THEN
304 DO ng=1,ngrids
305 IF (lwrtrst(ng)) THEN
306 IF (master) WRITE (stdout,10)
307 10 FORMAT (/,' Blowing-up: Saving latest model state into ', &
308 & ' RESTART file',/)
309 fcount=rst(ng)%load
310 IF (lcyclerst(ng).and.(rst(ng)%Nrec(fcount).ge.2)) THEN
311 rst(ng)%Rindex=2
312 lcyclerst(ng)=.false.
313 END IF
314 blowup=exit_flag
315 exit_flag=noerror
316#ifdef DISTRIBUTE
317 CALL wrt_rst (ng, myrank)
318#else
319 CALL wrt_rst (ng, -1)
320#endif
321 END IF
322 END DO
323 END IF
324!
325!-----------------------------------------------------------------------
326! Stop model and time profiling clocks, report memory requirements, and
327! close output NetCDF files.
328!-----------------------------------------------------------------------
329!
330! Stop time clocks.
331!
332 IF (master) THEN
333 WRITE (stdout,20)
334 20 FORMAT (/,'Elapsed wall CPU time for each process (seconds):',/)
335 END IF
336!
337 DO ng=1,ngrids
338 DO thread=thread_range
339 CALL wclock_off (ng, iadm, 0, __line__, myfile)
340 END DO
341 END DO
342!
343! Report dynamic memory and automatic memory requirements.
344!
345 CALL memory
346!
347! Close IO files.
348!
349 DO ng=1,ngrids
350 CALL close_inp (ng, iadm)
351 END DO
352 CALL close_out
353!
354 RETURN
subroutine memory
Definition memory.F:3

References mod_scalars::blowup, close_io_mod::close_inp(), close_io_mod::close_out(), mod_scalars::exit_flag, mod_param::iadm, mod_scalars::lcyclerst, mod_scalars::lwrtrst, mod_parallel::master, memory(), mod_parallel::myrank, mod_param::ngrids, mod_scalars::noerror, mod_iounits::rst, mod_iounits::stdout, wclock_off(), and wrt_rst_mod::wrt_rst().

Referenced by mct_driver(), myroms(), cmeps_roms_mod::roms_modeladvance(), esmf_roms_mod::roms_modeladvance(), cmeps_roms_mod::roms_setfinalize(), and esmf_roms_mod::roms_setfinalize().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ roms_initialize()

subroutine public roms_kernel_mod::roms_initialize ( logical, intent(inout) first,
integer, intent(in), optional mpicomm )

Definition at line 51 of file ad_roms.h.

52!
53!=======================================================================
54! !
55! This routine allocates and initializes ROMS state variables !
56! and internal and external parameters. !
57! !
58!=======================================================================
59!
60! Imported variable declarations.
61!
62 logical, intent(inout) :: first
63!
64 integer, intent(in), optional :: mpiCOMM
65!
66! Local variable declarations.
67!
68 logical :: allocate_vars = .true.
69!
70#ifdef DISTRIBUTE
71 integer :: MyError, MySize
72#endif
73 integer :: chunk_size, ng, thread
74#ifdef _OPENMP
75 integer :: my_threadnum
76#endif
77!
78 character (len=*), parameter :: MyFile = &
79 & __FILE__//", ROMS_initialize"
80
81#ifdef DISTRIBUTE
82!
83!-----------------------------------------------------------------------
84! Set distribute-memory (mpi) world communictor.
85!-----------------------------------------------------------------------
86!
87 IF (PRESENT(mpicomm)) THEN
88 ocn_comm_world=mpicomm
89 ELSE
90 ocn_comm_world=mpi_comm_world
91 END IF
92 CALL mpi_comm_rank (ocn_comm_world, myrank, myerror)
93 CALL mpi_comm_size (ocn_comm_world, mysize, myerror)
94#endif
95!
96!-----------------------------------------------------------------------
97! On first pass, initialize model parameters a variables for all
98! nested/composed grids. Notice that the logical switch "first"
99! is used to allow multiple calls to this routine during ensemble
100! configurations.
101!-----------------------------------------------------------------------
102!
103 IF (first) THEN
104 first=.false.
105!
106! Initialize parallel control switches. These scalars switches are
107! independent from standard input parameters.
108!
109 CALL initialize_parallel
110!
111! Set the ROMS standard output unit to write verbose execution info.
112! Notice that the default standard out unit in Fortran is 6.
113!
114! In some applications like coupling or disjointed mpi-communications,
115! it is advantageous to write standard output to a specific filename
116! instead of the default Fortran standard output unit 6. If that is
117! the case, it opens such formatted file for writing.
118!
119 IF (set_stdoutunit) THEN
120 stdout=stdout_unit(master)
121 set_stdoutunit=.false.
122 END IF
123!
124! Read in model tunable parameters from standard input. Allocate and
125! initialize variables in several modules after the number of nested
126! grids and dimension parameters are known.
127!
128 CALL inp_par (iadm)
129 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
130!
131! Set domain decomposition tile partition range. This range is
132! computed only once since the "first_tile" and "last_tile" values
133! are private for each parallel thread/node.
134!
135#if defined _OPENMP
136 mythread=my_threadnum()
137#elif defined DISTRIBUTE
138 mythread=myrank
139#else
140 mythread=0
141#endif
142 DO ng=1,ngrids
143 chunk_size=(ntilex(ng)*ntilee(ng)+numthreads-1)/numthreads
144 first_tile(ng)=mythread*chunk_size
145 last_tile(ng)=first_tile(ng)+chunk_size-1
146 END DO
147!
148! Initialize internal wall clocks. Notice that the timings does not
149! includes processing standard input because several parameters are
150! needed to allocate clock variables.
151!
152 IF (master) THEN
153 WRITE (stdout,10)
154 10 FORMAT (/,' Process Information:',/)
155 END IF
156!
157 DO ng=1,ngrids
158 DO thread=thread_range
159 CALL wclock_on (ng, iadm, 0, __line__, myfile)
160 END DO
161 END DO
162!
163! Allocate and initialize modules variables.
164!
165 CALL roms_allocate_arrays (allocate_vars)
166 CALL roms_initialize_arrays
167 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
168
169 END IF
170
171#if defined MCT_LIB && (defined ATM_COUPLING || defined WAV_COUPLING)
172!
173!-----------------------------------------------------------------------
174! Initialize coupling streams between model(s).
175!-----------------------------------------------------------------------
176!
177 DO ng=1,ngrids
178# ifdef ATM_COUPLING
179 CALL initialize_ocn2atm_coupling (ng, myrank)
180# endif
181# ifdef WAV_COUPLING
182 CALL initialize_ocn2wav_coupling (ng, myrank)
183# endif
184 END DO
185#endif
186!
187!-----------------------------------------------------------------------
188! Initialize adjoint model state variables over all nested grids, if
189! applicable.
190!-----------------------------------------------------------------------
191
192#ifdef FORWARD_FLUXES
193!
194! Set the BLK structure to contain the nonlinear model surface fluxes
195! needed by the tangent linear and adjoint models. Also, set switches
196! to process that structure in routine "check_multifile". Notice that
197! it is possible to split the solution into multiple NetCDF files to
198! reduce their size.
199!
200! The switch LreadFRC is deactivated because all the atmospheric
201! forcing, including shortwave radiation, is read from the NLM
202! surface fluxes or is assigned during ESM coupling. Such fluxes
203! are available from the QCK structure. There is no need for reading
204! and processing from the FRC structure input forcing-files.
205!
206 CALL edit_multifile ('QCK2BLK')
207 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
208 DO ng=1,ngrids
209 lreadblk(ng)=.true.
210 lreadfrc(ng)=.false.
211 END DO
212#endif
213!
214! Initialize adjoint model.
215!
216 lstiffness=.false.
217 DO ng=1,ngrids
218 lreadfwd(ng)=.true.
219 CALL ad_initial (ng)
220 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
221 END DO
222!
223! Initialize run or ensemble counter.
224!
225 nrun=1
226!
227! Activate adjoint output.
228!
229 DO ng=1,ngrids
230 ldefadj(ng)=.true.
231 lwrtadj(ng)=.true.
232 lcycleadj(ng)=.false.
233 END DO
234!
235 RETURN
subroutine ad_initial(ng)
Definition ad_initial.F:4
integer function my_threadnum()

References ad_initial(), edit_multifile(), mod_scalars::exit_flag, mod_parallel::first_tile, strings_mod::founderror(), mod_param::iadm, mod_parallel::initialize_parallel(), inp_par_mod::inp_par(), mod_parallel::last_tile, mod_scalars::lcycleadj, mod_scalars::ldefadj, mod_scalars::lreadblk, mod_scalars::lreadfrc, mod_scalars::lreadfwd, mod_scalars::lstiffness, mod_scalars::lwrtadj, mod_parallel::master, my_threadnum(), mod_parallel::myrank, mod_parallel::mythread, mod_param::ngrids, mod_scalars::noerror, mod_scalars::nrun, mod_param::ntilee, mod_param::ntilex, mod_parallel::numthreads, mod_parallel::ocn_comm_world, mod_arrays::roms_allocate_arrays(), mod_arrays::roms_initialize_arrays(), stdout_mod::set_stdoutunit, mod_iounits::stdout, stdout_mod::stdout_unit(), and wclock_on().

Referenced by mct_driver(), myroms(), cmeps_roms_mod::roms_setinitializep2(), and esmf_roms_mod::roms_setinitializep2().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ roms_initializep1()

subroutine, public roms_kernel_mod::roms_initializep1 ( logical, intent(inout) first,
integer, intent(in), optional mpicomm,
integer, intent(in), optional kernel )

Definition at line 95 of file jedi_roms.h.

96!
97!=======================================================================
98! !
99! ROMSJEDI phase 2 initialization. It allocates and initializes ROMS !
100! state variables and internal parameters. It reads standard input !
101! parameters. !
102! !
103!=======================================================================
104!
105! Imported variable declarations.
106!
107 logical, intent(inout) :: first
108!
109 integer, intent(in), optional :: mpiCOMM
110 integer, intent(in), optional :: kernel
111!
112! Local variable declarations.
113!
114 logical :: allocate_vars = .true.
115
116#ifdef DISTRIBUTE
117 integer :: MyError, MySize
118#endif
119 integer :: Phase, chunk_size, ng, thread, tile
120!
121 character (len=*), parameter :: MyFile = &
122 & __FILE__//", ROMS_initialize"
123
124#ifdef DISTRIBUTE
125!
126!-----------------------------------------------------------------------
127! Set distribute-memory (mpi) world communictor.
128!-----------------------------------------------------------------------
129!
130 IF (PRESENT(mpicomm)) THEN
131 ocn_comm_world=mpicomm
132 ELSE
133 ocn_comm_world=mpi_comm_world
134 END IF
135 CALL mpi_comm_rank (ocn_comm_world, myrank, myerror)
136 CALL mpi_comm_size (ocn_comm_world, mysize, myerror)
137#endif
138!
139!-----------------------------------------------------------------------
140! On first pass, initialize model parameters a variables for all
141! nested/composed grids. Notice that the logical switch "first"
142! is used to allow multiple calls to this routine during ensemble
143! configurations.
144!-----------------------------------------------------------------------
145!
146 IF (first) THEN
147 first=.false.
148!
149! Initialize parallel control switches. These scalars switches are
150! independent from standard input parameters.
151!
152 CALL initialize_parallel
153!
154! Set the ROMS standard output unit to write verbose execution info.
155! Notice that the default standard out unit in Fortran is 6.
156!
157! In some applications like coupling or disjointed mpi-communications,
158! it is advantageous to write standard output to a specific filename
159! instead of the default Fortran standard output unit 6. If that is
160! the case, it opens such formatted file for writing.
161!
162 IF (set_stdoutunit) THEN
163 stdout=stdout_unit(master)
164 set_stdoutunit=.false.
165 END IF
166!
167! Read in model tunable parameters from standard input. Allocate and
168! initialize variables in several modules after the number of nested
169! grids and dimension parameters are known.
170!
171 CALL inp_par (inlm)
172 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
173!
174! Initialize counters.
175!
176 nrun=1 ! run counter
177!
178! Set domain decomposition tile partition range. This range is
179! computed only once since the "first_tile" and "last_tile" values
180! are private for each parallel thread/node.
181!
182#if defined DISTRIBUTE
183 mythread=myrank
184#else
185 mythread=0
186#endif
187 DO ng=1,ngrids
188 chunk_size=(ntilex(ng)*ntilee(ng)+numthreads-1)/numthreads
189 first_tile(ng)=mythread*chunk_size
190 last_tile(ng)=first_tile(ng)+chunk_size-1
191 END DO
192!
193! Initialize internal wall clocks. Notice that the timings does not
194! includes processing standard input because several parameters are
195! needed to allocate clock variables.
196!
197 IF (master) THEN
198 WRITE (stdout,10)
199 10 FORMAT (/,' Process Information:',/)
200 END IF
201!
202 DO ng=1,ngrids
203 DO thread=thread_range
204 CALL wclock_on (ng, inlm, 0, __line__, myfile)
205 END DO
206 END DO
207!
208! Allocate and initialize modules variables.
209!
210 CALL roms_allocate_arrays (allocate_vars)
211 CALL roms_initialize_arrays
212 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
213
214 END IF
215!
216!-----------------------------------------------------------------------
217! Initialize ROMS, phase 1.
218!-----------------------------------------------------------------------
219!
220 phase=1
221!
222 SELECT CASE (kernel)
223 CASE (inlm)
224 CALL nlm_initial (phase)
225#ifdef TANGENT
226 CASE (itlm)
227 CALL tlm_initial (phase)
228#endif
229#ifdef ADJOINT
230 CASE (iadm)
231 CALL adm_initial (phase)
232#endif
233 END SELECT
234!
235!-----------------------------------------------------------------------
236! Set ROMS application grid configuration. It is done once.
237!-----------------------------------------------------------------------
238!
239 DO ng=1,ngrids
240 IF (setgridconfig(ng)) THEN
241 CALL set_grid (ng, inlm)
242 setgridconfig(ng)=.false.
243 END IF
244 END DO
245!
246 RETURN
subroutine set_grid(ng, model)
Definition set_grid.F:3

References adm_initial(), mod_scalars::exit_flag, mod_parallel::first_tile, strings_mod::founderror(), mod_param::iadm, mod_parallel::initialize_parallel(), mod_param::inlm, inp_par_mod::inp_par(), mod_param::itlm, mod_parallel::last_tile, mod_parallel::master, mod_parallel::myrank, mod_parallel::mythread, mod_param::ngrids, nlm_initial(), mod_scalars::noerror, mod_scalars::nrun, mod_param::ntilee, mod_param::ntilex, mod_parallel::numthreads, mod_parallel::ocn_comm_world, mod_arrays::roms_allocate_arrays(), mod_arrays::roms_initialize_arrays(), set_grid(), stdout_mod::set_stdoutunit, mod_scalars::setgridconfig, mod_iounits::stdout, stdout_mod::stdout_unit(), tlm_initial(), and wclock_on().

Here is the call graph for this function:

◆ roms_initializep2()

subroutine, public roms_kernel_mod::roms_initializep2 ( integer, intent(in) kernel)

Definition at line 249 of file jedi_roms.h.

250!
251!=======================================================================
252! !
253! ROMSJEDI phase 2 initialization. It requires the initial state !
254! (set elsewhere) to complete the full initialization of the kernel. !
255! It computes depths, density, and horizontal mass fluxes. !
256! !
257!=======================================================================
258!
259! Imported variable declarations
260!
261 integer, intent(in) :: kernel
262!
263! Local variable declarations.
264!
265 integer :: Phase
266!
267!-----------------------------------------------------------------------
268! Initialize ROMSJEDI, Phase 2.
269!-----------------------------------------------------------------------
270!
271 phase=2
272!
273 SELECT CASE (kernel)
274 CASE (inlm)
275 CALL nlm_initial (phase)
276#ifdef TANGENT
277 CASE (itlm)
278 CALL tlm_initial (phase)
279#endif
280#ifdef ADJOINT
281 CASE (iadm)
282 CALL adm_initial (phase)
283#endif
284 END SELECT
285!
286 RETURN

References adm_initial(), mod_param::iadm, mod_param::inlm, mod_param::itlm, nlm_initial(), and tlm_initial().

Here is the call graph for this function:

◆ roms_initializep3()

subroutine, public roms_kernel_mod::roms_initializep3 ( integer, intent(in) kernel)

Definition at line 289 of file jedi_roms.h.

290!
291!=======================================================================
292! !
293! ROMSJEDI phase 3 initialization. It computes the initial depths !
294! and level thicknesses from the time-averaged free-surface, Zt_avg1, !
295! which are needed to calculate initial vertically integrated !
296! momentum. !
297! !
298! Also, it initializes the state variables for all time levels and !
299! applies lateral boundary conditions. !
300! !
301! Notice that the second data snapshot needs to be processed because !
302! it is necessary for the initial lateral boundary conditions. !
303! !
304!=======================================================================
305!
306! Imported variable declarations
307!
308 integer, intent(in) :: kernel
309!
310! Local variable declarations.
311!
312 integer :: Phase
313!
314!-----------------------------------------------------------------------
315! Initialize ROMSJEDI, Phase 3.
316!-----------------------------------------------------------------------
317!
318 phase=3
319!
320 SELECT CASE (kernel)
321 CASE (inlm)
322 CALL nlm_initial (phase)
323#ifdef TANGENT
324 CASE (itlm)
325 CALL tlm_initial (phase)
326#endif
327#ifdef ADJOINT
328 CASE (iadm)
329 CALL adm_initial (phase)
330#endif
331 END SELECT
332!
333 RETURN

References adm_initial(), mod_param::iadm, mod_param::inlm, mod_param::itlm, nlm_initial(), and tlm_initial().

Here is the call graph for this function:

◆ roms_run() [1/3]

subroutine public roms_kernel_mod::roms_run ( real(dp), intent(in) runinterval)

Definition at line 238 of file ad_roms.h.

239!
240!=======================================================================
241! !
242! This routine runs ROMS adjoint model backwards for the !
243! specified time interval (seconds), RunInterval. !
244! !
245!=======================================================================
246!
247! Imported variable declarations.
248!
249 real(dp), intent(in) :: RunInterval ! seconds
250!
251! Local variable declarations.
252!
253 integer :: ng
254!
255 character (len=*), parameter :: MyFile = &
256 & __FILE__//", ROMS_run"
257!
258!-----------------------------------------------------------------------
259! Time-step adjoint model over all nested grids, if applicable.
260!-----------------------------------------------------------------------
261!
262 DO ng=1,ngrids
263 IF (master) THEN
264 WRITE (stdout,10) 'AD', ng, ntstart(ng), ntend(ng)
265 END IF
266 END DO
267!
268#ifdef SOLVE3D
269 CALL ad_main3d (runinterval)
270#else
271 CALL ad_main2d (runinterval)
272#endif
273
274 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
275!
276 10 FORMAT (/,1x,a,1x,'ROMS: started time-stepping:', &
277 & ' (Grid: ',i2.2,' TimeSteps: ',i8.8,' - ',i8.8,')',/)
278!
279 RETURN
subroutine ad_main2d
Definition ad_main2d.F:586
subroutine ad_main3d(runinterval)
Definition ad_main3d.F:4

References ad_main2d(), ad_main3d(), mod_scalars::exit_flag, strings_mod::founderror(), mod_parallel::master, mod_param::ngrids, mod_scalars::noerror, mod_scalars::ntend, mod_scalars::ntstart, and mod_iounits::stdout.

Referenced by mct_driver(), myroms(), cmeps_roms_mod::roms_modeladvance(), and esmf_roms_mod::roms_modeladvance().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ roms_run() [2/3]

subroutine, public roms_kernel_mod::roms_run ( real(dp), intent(inout) runinterval)

Definition at line 493 of file obs_sen_rbl4dvar_forecast.h.

494!
495!=======================================================================
496! !
497! This routine time-steps ROMS nonlinear, tangent linear and !
498! adjoint models. !
499! !
500!=======================================================================
501!
502! Imported variable declarations
503!
504 real(dp), intent(inout) :: RunInterval ! seconds
505!
506! Local variable declarations.
507!
508 logical :: Lcgini, Linner, Lposterior, add
509!
510 integer :: my_inner, my_outer
511 integer :: Lbck, Lini, Rec1, Rec2, ImpOrd
512 integer :: i, lstr, ng, status, tile
513 integer :: Fcount, NRMrec
514
515 integer, dimension(Ngrids) :: indxSave
516 integer, dimension(Ngrids) :: Nrec
517!
518 real(r8) :: str_day, end_day, dstartS, rtime
519!
520 character (len=1) :: charA, charB
521#ifdef OBS_SPACE
522 character (len=1) :: charC
523#endif
524 character (len=25) :: driver
525 character (len=20) :: string
526
527 character (len=*), parameter :: MyFile = &
528 & __FILE__//", ROMS_run"
529!
530!=======================================================================
531! Run model for all nested grids, if any.
532!=======================================================================
533!
534! Initialize relevant parameters.
535!
536 DO ng=1,ngrids
537#if defined ADJUST_STFLUX || defined ADJUST_WSTRESS
538 lfinp(ng)=1 ! forcing index for input
539 lfout(ng)=1 ! forcing index for output history files
540#endif
541#ifdef ADJUST_BOUNDARY
542 lbinp(ng)=1 ! boundary index for input
543 lbout(ng)=1 ! boundary index for output history files
544#endif
545 lold(ng)=1 ! old minimization time index
546 lnew(ng)=2 ! new minimization time index
547 END DO
548 lini=1 ! NLM initial conditions record in INI
549 lbck=2 ! background record in INI
550 rec1=1
551 rec2=2
552 nrun=1
553 outer=0
554 inner=0
555 erstr=1
556 erend=nouter
557 driver='obs_sen_rbl4dvar_forecast'
558 chara='A'
559 charb='B'
560#ifdef OBS_SPACE
561 charc='C'
562#endif
563!
564! Choose the desired order approximation of the forecast impact
565! calculations:
566!
567! ImpOrd: 1 (1st order)
568! 2 (2nd order) or
569! 3 (3rd order)
570!
571! ImpOrd=1 is the least accurate and can be in error by a factor of 2.
572!
573 impord=3
574!
575! For this driver DSTART is assumed to be the start time of the
576! analysis cycle that yields the analysis for the subsequent forecast
577! cycle. The number of time steps in the analysis cycle is NTIMES_ANA,
578! and the number of time steps in the forecast cycle is NTIMES_FCT.
579!
580! Initially we will be running the adjoint model over the forecast
581! time interval so we temporarily reset dstart and RunInterval to
582! reflect the forecast interval start and run time.
583!
584 dstarts=dstart
585 rtime=0.0_r8
586 DO ng=1,ngrids
587 rtime=max(rtime, dt(ng)*ntimes_ana(ng))
588 END DO
589 dstart=dstart+rtime*sec2day
590!
591 rtime=0.0_r8
592 DO ng=1,ngrids
593 rtime=max(rtime, dt(ng)*ntimes_fct(ng))
594 ntimes(ng)=ntimes_fct(ng)
595 END DO
596 runinterval=rtime
597!
598!-----------------------------------------------------------------------
599! Configure weak constraint RBL4D-Var algorithm.
600!-----------------------------------------------------------------------
601!
602! Initialize the switch to gather weak constraint forcing.
603!
604 DO ng=1,ngrids
605 wrtforce(ng)=.false.
606 END DO
607!
608! Initialize and set nonlinear model initial conditions.
609!
610 DO ng=1,ngrids
611 lreadfwd(ng)=.false.
612 lreadblk(ng)=.false.
613 wrtnlmod(ng)=.true.
614 wrtrpmod(ng)=.false.
615 wrttlmod(ng)=.false.
616 lsen4dvar(ng)=.false.
617#ifdef OBS_SPACE
618 lobspace(ng)=.false.
619# ifndef OBS_IMPACT
620 ladjvar(ng)=.false.
621# endif
622#endif
623 END DO
624
625 CALL initial
626 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
627!
628! Save nonlinear initial conditions (currently in time index 1,
629! background) into record "Lbck" of INI(ng)%name NetCDF file. The
630! record "Lbck" becomes the background state record and the record
631! "Lini" becomes current nonlinear initial conditions.
632!
633 DO ng=1,ngrids
634 ini(ng)%Rindex=1
635 fcount=ini(ng)%load
636 ini(ng)%Nrec(fcount)=1
637#ifdef DISTRIBUTE
638 CALL wrt_ini (ng, myrank, 1)
639#else
640 CALL wrt_ini (ng, -1, 1)
641#endif
642 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
643 END DO
644!
645! The FWD structure is used several times and contains the nonnlinear
646! background trajectories (RBL4DVAR, FCTA, and FCTB) used to linearize
647! the tangent linear and adjoint models. These trajectories can be
648! split into multi-files. If so, the user needs to specified such
649! multiple files in the standard input script (roms.in). Since the HIS
650! structure is not used here, copy the original FWD containing the
651! trajectory information loaded during configuration in "inp_par",
652! which has the values for the regular RBL4D-Var at specified outer
653! loop into the HIS structure.
654!
655 CALL edit_multifile ('FWD2HIS')
656 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
657!
658!:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
659! Model-error covariance normalization and stardard deviation factors.
660!:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
661!
662! Compute or read in the error covariance normalization factors.
663! If computing, write out factors to NetCDF. This is an expensive
664! computation that needs to be computed only once for a particular
665! application grid and decorrelation scales.
666!
667 DO ng=1,ngrids
668 IF (any(lwrtnrm(:,ng))) THEN
669 CALL def_norm (ng, inlm, 1)
670 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
671
672 IF (nsa.eq.2) THEN
673 CALL def_norm (ng, inlm, 2)
674 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
675 END IF
676
677#ifdef ADJUST_BOUNDARY
678 CALL def_norm (ng, inlm, 3)
679 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
680#endif
681
682#if defined ADJUST_WSTRESS || defined ADJUST_STFLUX
683 CALL def_norm (ng, inlm, 4)
684 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
685#endif
686
687 DO tile=first_tile(ng),last_tile(ng),+1
688 CALL normalization (ng, tile, 2)
689 END DO
690
691 ldefnrm(1:4,ng)=.false.
692 lwrtnrm(1:4,ng)=.false.
693 ELSE
694 nrmrec=1
695 CALL get_state (ng, 14, 14, nrm(1,ng), nrmrec, 1)
696 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
697
698 IF (nsa.eq.2) THEN
699 CALL get_state (ng, 15, 15, nrm(2,ng), nrmrec, 2)
700 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
701 END IF
702
703#ifdef ADJUST_BOUNDARY
704 CALL get_state (ng, 16, 16, nrm(3,ng), nrmrec, 1)
705 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
706#endif
707
708#if defined ADJUST_WSTRESS || defined ADJUST_STFLUX
709 CALL get_state (ng, 17, 17, nrm(4,ng), nrmrec, 1)
710 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
711#endif
712 END IF
713 END DO
714
715#if defined BALANCE_OPERATOR && defined ZETA_ELLIPTIC
716!
717! Compute the reference zeta and biconjugate gradient arrays
718! required for the balance of free surface.
719!
720 IF (balance(isfsur)) THEN
721 DO ng=1,ngrids
722 CALL get_state (ng, inlm, 2, ini(ng), lini, lini)
723 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
724!
725 DO tile=first_tile(ng),last_tile(ng),+1
726 CALL balance_ref (ng, tile, lini)
727 CALL biconj (ng, tile, inlm, lini)
728 END DO
729 wrtzetaref(ng)=.true.
730 END DO
731 END IF
732#endif
733!
734! Define tangent linear initial conditions file.
735!
736 DO ng=1,ngrids
737 ldefitl(ng)=.true.
738 CALL tl_def_ini (ng)
739 ldefitl(ng)=.false.
740 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
741 END DO
742!
743! Define impulse forcing NetCDF file.
744!
745 DO ng=1,ngrids
746 ldeftlf(ng)=.true.
747 CALL def_impulse (ng)
748 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
749 END DO
750
751#ifndef OBS_SPACE
752!
753! Define output 4DVAR NetCDF file containing all processed data
754! at observation locations.
755!
756 DO ng=1,ngrids
757 ldefmod(ng)=.true.
758 CALL def_mod (ng)
759 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
760 END DO
761!
762! Write out outer loop beeing processed.
763!
764 sourcefile=myfile
765 DO ng=1,ngrids
766 SELECT CASE (dav(ng)%IOtype)
767 CASE (io_nf90)
768 CALL netcdf_put_ivar (ng, inlm, dav(ng)%name, &
769 & 'Nimpact', nimpact, &
770 & (/0/), (/0/), &
771 & ncid = dav(ng)%ncid)
772 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
773
774# if defined PIO_LIB && defined DISTRIBUTE
775 CASE (io_pio)
776 CALL pio_netcdf_put_ivar (ng, inlm, dav(ng)%name, &
777 & 'Nimpact', nimpact, &
778 & (/0/), (/0/), &
779 & piofile = dav(ng)%pioFile)
780 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
781# endif
782 END SELECT
783 END DO
784#endif
785!
786!|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
787! Run the adjoint model forced by forecast minus analysis difference
788! using appropriate solution trajectories.
789!|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
790!
791! Reset the start and end times for the adjoint forcing.
792!
793 DO ng=1,ngrids
794 str_day=tdays(ng)+ntimes(ng)*dt(ng)*sec2day
795 end_day=tdays(ng)
796 IF ((dstrs(ng).eq.0.0_r8).and.(dends(ng).eq.0.0_r8)) THEN
797 dstrs(ng)=end_day
798 dends(ng)=str_day
799 END IF
800 IF (master) THEN
801 WRITE (stdout,70) 'AD', dends(ng), dstrs(ng)
802 END IF
803 END DO
804!
805! Set basic state trajectory and adjoint forcing file.
806!
807! ads_xxxx_a.nc if obs_space is off
808! ads_xxxx_b.nc
809!
810! obs_xxxx_a.nc if obs_space is on
811! obs_xxxx_b.nc
812!
813 sourcefile=myfile
814 DO ng=1,ngrids
815#ifdef OBS_SPACE
816 CALL close_file (ng, inlm, obs(ng), obs(ng)%name)
817 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
818
819 IF (impord.ne.2) THEN
820 WRITE (obs(ng)%name,90) trim(oifb(ng)%head)
821 ELSE
822 WRITE (obs(ng)%name,90) trim(oifa(ng)%head)
823 END IF
824#else
825 CALL close_file (ng, inlm, ads(ng), ads(ng)%name)
826 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
827
828 IF (impord.ne.2) THEN
829 WRITE (ads(ng)%name,90) trim(foib(ng)%head)
830 ELSE
831 WRITE (ads(ng)%name,90) trim(foia(ng)%head)
832 END IF
833#endif
834 END DO
835!
836! Set structure for the nonlinear forward trajectory to be processed
837! by the tangent linear and adjoint models. Also, set switches to
838! process the FWD structure in routine "check_multifile". Notice that
839! it is possible to split solution into multiple NetCDF files to reduce
840! their size.
841!
842 CALL edit_multifile ('FCTB2FWD')
843 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
844 DO ng=1,ngrids
845 lreadfwd(ng)=.true.
846 END DO
847!
848! Set structure for the nonlinear surface fluxes to be processed by
849! by the tangent linear and adjoint models. Also, set switches to
850! process the BLK structure in routine "check_multifile". Notice that
851! it is possible to split solution into multiple NetCDF files to reduce
852! their size.
853!
854 CALL edit_multifile ('FCTB2BLK')
855 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
856 DO ng=1,ngrids
857 lreadblk(ng)=.true.
858 END DO
859!
860 IF (master) THEN
861 WRITE (stdout,50)
862 END IF
863!
864! Initialize the adjoint model: initialize using dI/dxf is appropriate.
865!
866! TODO: There is problem with the "haveObsMeta" flag. It is always
867! FALSE on the first call to OBS_READ, so "ObsMeta" is zero
868! for the radials. The reason this is happening is because that
869! NetCDF file had already been opened somewhere prior to calling
870! OBS_INITIAL in TL_INITIAL (and AD_INITIAL when appropriate),
871! so the obs arrays were not getting initialized properly by
872! these routines. For now, the solution is to close the NetCDF
873! file before each call to TL_INITIAL and AD_INITIAL.
874!
875 DO ng=1,ngrids
876 lstiffness=.false.
877#ifdef OBS_SPACE
878 lsen4dvar(ng)=.false.
879 lsenfct(ng)=.true.
880 lobspace(ng)=.true.
881# ifndef OBS_IMPACT
882 ladjvar(ng)=.false.
883# endif
884#else
885 lsen4dvar(ng)=.true.
886 lsenfct(ng)=.false.
887#endif
888 CALL close_file (ng, iadm, obs(ng), obs(ng)%name)
889 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
890!
891 CALL ad_initial (ng)
892 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
893 END DO
894!
895! Set adjoint history NetCDF parameters. Define adjoint history
896! file once to avoid opening to many files.
897!
898 DO ng=1,ngrids
899 wrtforce=.true.
900 IF (adm(ng)%ncid.ne.-1) ldefadj(ng)=.false.
901 fcount=adm(ng)%load
902 adm(ng)%Nrec(fcount)=0
903 adm(ng)%Rindex=0
904 END DO
905
906! Time-step adjoint model backwards.
907!
908 DO ng=1,ngrids
909 IF (master) THEN
910 WRITE (stdout,20) 'AD', ng, ntstart(ng), ntend(ng)
911 END IF
912 END DO
913!
914#ifdef SOLVE3D
915 CALL ad_main3d (runinterval)
916#else
917 CALL ad_main2d (runinterval)
918#endif
919 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
920!
921! Write out last weak-constraint forcing (WRTforce is still .TRUE.)
922! record into the adjoint history file. Note that the weak-constraint
923! forcing is delayed by nADJ time-steps.
924!
925 DO ng=1,ngrids
926#ifdef DISTRIBUTE
927 CALL ad_wrt_his (ng, myrank)
928#else
929 CALL ad_wrt_his (ng, -1)
930#endif
931 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
932 END DO
933!
934! Write out adjoint initial condition record into the adjoint
935! history file.
936!
937 DO ng=1,ngrids
938 wrtforce(ng)=.false.
939 lwrtstate2d(ng)=.false.
940#ifdef DISTRIBUTE
941 CALL ad_wrt_his (ng, myrank)
942#else
943 CALL ad_wrt_his (ng, -1)
944#endif
945 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
946 END DO
947!
948! Retrieve adjoint solution into tl_var(1).
949!
950 DO ng=1,ngrids
951 CALL get_state (ng, itlm, 4, adm(ng), adm(ng)%Rindex, rec1)
952 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
953 END DO
954!
955! Set basic state trajectory and adjoint forcing file.
956!
957 IF (impord.gt.1) THEN
958 sourcefile=myfile
959 DO ng=1,ngrids
960#ifdef OBS_SPACE
961 CALL close_file (ng, inlm, obs(ng), obs(ng)%name)
962 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
963
964 IF (impord.eq.2) THEN
965 WRITE (obs(ng)%name,90) trim(oifb(ng)%head)
966 ELSE
967 WRITE (obs(ng)%name,90) trim(oifa(ng)%head)
968 END IF
969#else
970 CALL close_file (ng, inlm, ads(ng), ads(ng)%name)
971 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
972
973 IF (impord.eq.2) THEN
974 WRITE (ads(ng)%name,90) trim(foib(ng)%head)
975 ELSE
976 WRITE (ads(ng)%name,90) trim(foia(ng)%head)
977 END IF
978#endif
979 END DO
980!
981! Set structure for the nonlinear forward trajectory to be processed
982! by the tangent linear and adjoint models. Also, set switches to
983! process the FWD structure in routine "check_multifile". Notice that
984! it is possible to split solution into multiple NetCDF files to reduce
985! their size.
986!
987 CALL edit_multifile ('FCTA2FWD')
988 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
989 DO ng=1,ngrids
990 lreadfwd(ng)=.true.
991 END DO
992!
993! Set structure for the nonlinear surface fluxes to be processed by
994! by the tangent linear and adjoint models. Also, set switches to
995! process the BLK structure in routine "check_multifile". Notice that
996! it is possible to split solution into multiple NetCDF files to reduce
997! their size.
998!
999 CALL edit_multifile ('FCTA2BLK')
1000 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1001 DO ng=1,ngrids
1002 lreadblk(ng)=.true.
1003 END DO
1004!
1005 IF (master) THEN
1006 WRITE (stdout,50)
1007 END IF
1008!
1009! Initialize the adjoint model: initialize using dI/dxf is appropriate.
1010!
1011 DO ng=1,ngrids
1012 lstiffness=.false.
1013#ifdef OBS_SPACE
1014 lsen4dvar(ng)=.false.
1015 lsenfct(ng)=.true.
1016 lobspace(ng)=.true.
1017# ifndef OBS_IMPACT
1018 ladjvar(ng)=.false.
1019# endif
1020#else
1021 lsen4dvar(ng)=.true.
1022 lsenfct(ng)=.false.
1023#endif
1024 CALL close_file (ng, iadm, obs(ng), obs(ng)%name)
1025 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1026!
1027 CALL ad_initial (ng)
1028 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1029 END DO
1030!
1031! Set adjoint history NetCDF parameters. Define adjoint history
1032! file once to avoid opening to many files.
1033!
1034 DO ng=1,ngrids
1035 wrtforce=.true.
1036 IF (adm(ng)%ncid.ne.-1) ldefadj(ng)=.false.
1037 fcount=adm(ng)%load
1038 adm(ng)%Nrec(fcount)=0
1039 adm(ng)%Rindex=0
1040 END DO
1041!
1042! Time-step adjoint model backwards.
1043!
1044 DO ng=1,ngrids
1045 IF (master) THEN
1046 WRITE (stdout,20) 'AD', ng, ntstart(ng), ntend(ng)
1047 END IF
1048 END DO
1049!
1050#ifdef SOLVE3D
1051 CALL ad_main3d (runinterval)
1052#else
1053 CALL ad_main2d (runinterval)
1054#endif
1055 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1056!
1057! Write out last weak-constraint forcing (WRTforce is still .TRUE.)
1058! record into the adjoint history file. Note that the weak-constraint
1059! forcing is delayed by nADJ time-steps.
1060!
1061 DO ng=1,ngrids
1062#ifdef DISTRIBUTE
1063 CALL ad_wrt_his (ng, myrank)
1064#else
1065 CALL ad_wrt_his (ng, -1)
1066#endif
1067 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1068 END DO
1069!
1070! Write out adjoint initial condition record into the adjoint
1071! history file.
1072!
1073 DO ng=1,ngrids
1074 wrtforce(ng)=.false.
1075 lwrtstate2d(ng)=.false.
1076#ifdef DISTRIBUTE
1077 CALL ad_wrt_his (ng, myrank)
1078#else
1079 CALL ad_wrt_his (ng, -1)
1080#endif
1081 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1082 END DO
1083!
1084! Retrieve adjoint solution.
1085!
1086 DO ng=1,ngrids
1087 CALL get_state (ng, iadm, 4, adm(ng), adm(ng)%Rindex, rec1)
1088 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1089 END DO
1090!
1091! Add the retrieved adjoint solution to the previous solution saved
1092! in tl_var(1).
1093!
1094 add=.true.
1095 DO ng=1,ngrids
1096 DO tile=first_tile(ng),last_tile(ng),+1
1097 CALL load_adtotl (ng, tile, rec1, rec1, add)
1098 END DO
1099 END DO
1100!
1101 END IF
1102!
1103!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1104!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1105! Adjoint of RBL4D-Var to compute the observation sensitivity.
1106!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1107!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1108!
1109! Reset the start and end times for the adjoint forcing.
1110!
1111 DO ng=1,ngrids
1112 str_day=tdays(ng)+ntimes(ng)*dt(ng)*sec2day
1113 end_day=tdays(ng)
1114 IF ((dstrs(ng).eq.0.0_r8).and.(dends(ng).eq.0.0_r8)) THEN
1115 dstrs(ng)=end_day
1116 dends(ng)=str_day
1117 END IF
1118 IF (master) THEN
1119 WRITE (stdout,70) 'AD', dends(ng), dstrs(ng)
1120 END IF
1121 END DO
1122!
1123! WARNING: ONLY one outer loop can be used for this application.
1124! ======= For more than 1 outer-loop, we require the second
1125! derivative of each model operator (i.e. the tangent linear
1126! of the tangent linear operator).
1127!
1128 ad_outer_loop : DO my_outer=nimpact,nimpact
1129 outer=my_outer
1130 inner=0
1131!
1132!-----------------------------------------------------------------------
1133! Run the adjoint model initialized and forced by dI/dx where I is the
1134! chosen function of the analysis/forecast state x.
1135!-----------------------------------------------------------------------
1136!
1137! Reset DSTART and RunIterval for the analysis cycle interval using
1138! NTIMES_ANA.
1139!
1140 dstart=dstarts
1141!
1142 rtime=0.0_r8
1143 DO ng=1,ngrids
1144 rtime=max(rtime, dt(ng)*ntimes_ana(ng))
1145 ntimes(ng)=ntimes_ana(ng)
1146 END DO
1147 runinterval=rtime
1148!
1149#if defined ADJUST_WSTRESS || defined ADJUST_STFLUX || \
1150 defined adjust_boundary
1151!
1152! Call initial again to reset the forcing and obc adjustment time
1153! counters.
1154!
1155 DO ng=1,ngrids
1156 lreadfwd(ng)=.false.
1157 lreadblk(ng)=.false.
1158 END DO
1159!
1160 CALL initial
1161#endif
1162!
1163! Set basic state trajectory.
1164!
1165 DO ng=1,ngrids
1166 WRITE (fwd(ng)%name,10) trim(his(ng)%head), outer-1
1167 END DO
1168!
1169! Set structure for the nonlinear forward trajectory (from regular
1170! RBL4DVAR) to be processed by the tangent linear and adjoint models.
1171! Also, set switches to process the FWD structure in routine
1172! "check_multifile". Notice that it is possible to split solution
1173! into multiple NetCDF files to reduce their size.
1174!
1175 CALL edit_multifile ('HIS2FWD')
1176 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1177 DO ng=1,ngrids
1178 lreadfwd(ng)=.true.
1179 END DO
1180
1181#ifdef FORWARD_FLUXES
1182!
1183! Set the BLK structure to contain the nonlinear model surface fluxes
1184! needed by the tangent linear and adjoint models. Also, set switches
1185! to process that structure in routine "check_multifile". Notice that
1186! it is possible to split the solution into multiple NetCDF files to
1187! reduce their size.
1188!
1189! The switch LreadFRC is deactivated because all the atmospheric
1190! forcing, including shortwave radiation, is read from the NLM
1191! surface fluxes or is assigned during ESM coupling. Such fluxes
1192! are available from the QCK structure. There is no need for reading
1193! and processing from the FRC structure input forcing-files.
1194!
1195 CALL edit_multifile ('QCK2BLK')
1196 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1197 DO ng=1,ngrids
1198 lreadblk(ng)=.true.
1199 lreadfrc(ng)=.false.
1200 lreadqck(ng)=.false.
1201 END DO
1202#endif
1203!
1204 IF (master) THEN
1205 WRITE (stdout,50)
1206 END IF
1207!
1208! Initialize the adjoint model: initialize using dI/dxf is
1209! appropriate.
1210!
1211 DO ng=1,ngrids
1212 lstiffness=.false.
1213!!AMM
1214#ifdef OBS_SPACE
1215 lsen4dvar(ng)=.true.
1216 lsenfct(ng)=.false.
1217 lobspace(ng)=.false.
1218# ifndef OBS_IMPACT
1219 ladjvar(ng)=.false.
1220# endif
1221#else
1222 lsen4dvar(ng)=.false.
1223 lsenfct(ng)=.false.
1224#endif
1225!!AMM
1226 CALL close_file (ng, iadm, obs(ng), obs(ng)%name)
1227 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1228!
1229 CALL ad_initial (ng)
1230 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1231 END DO
1232!
1233! Copy tl_var(1) solution to ad_var(1).
1234! It is important to clear the tl surface forcing and boundary
1235! arrays first since only the initial fields must be used to
1236! initialize the next run of the adjoint.
1237!
1238 add=.false.
1239 DO ng=1,ngrids
1240 DO tile=first_tile(ng),last_tile(ng),+1
1241#if defined ADJUST_WSTRESS || defined ADJUST_STFLUX
1242 CALL initialize_forces (ng, tile, itlm)
1243#endif
1244#ifdef ADJUST_BOUNDARY
1245 CALL initialize_boundary (ng, tile, itlm)
1246#endif
1247 CALL load_tltoad (ng, tile, rec1, rec1, add)
1248 END DO
1249 END DO
1250
1251#if defined ADJUST_WSTRESS || defined ADJUST_STFLUX || \
1252 defined adjust_boundary
1253!
1254! Clear the adjoint forcing and open boundary arrays
1255!
1256 DO ng=1,ngrids
1257 DO tile=first_tile(ng),last_tile(ng),+1
1258 CALL initialize_forces (ng, tile, iadm)
1259# ifdef ADJUST_BOUNDARY
1260 CALL initialize_boundary (ng, tile, iadm)
1261# endif
1262 END DO
1263 END DO
1264#endif
1265!
1266! Set adjoint history NetCDF parameters. Define adjoint history
1267! file one to avoid opening to many files.
1268!
1269 DO ng=1,ngrids
1270 wrtforce=.true.
1271 IF (adm(ng)%ncid.ne.-1) ldefadj(ng)=.false.
1272 fcount=adm(ng)%load
1273 adm(ng)%Nrec(fcount)=0
1274 adm(ng)%Rindex=0
1275 END DO
1276!
1277! Time-step adjoint model backwards.
1278! ??? What do we do in the case of model error? Save forcing for TLM?
1279!
1280 DO ng=1,ngrids
1281 IF (master) THEN
1282 WRITE (stdout,20) 'AD', ng, ntstart(ng), ntend(ng)
1283 END IF
1284 END DO
1285!
1286#ifdef SOLVE3D
1287 CALL ad_main3d (runinterval)
1288#else
1289 CALL ad_main2d (runinterval)
1290#endif
1291 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1292!
1293! Write out last weak-constraint forcing (WRTforce is still .TRUE.)
1294! record into the adjoint history file. Note that the weak-constraint
1295! forcing is delayed by nADJ time-steps.
1296!
1297 DO ng=1,ngrids
1298#ifdef DISTRIBUTE
1299 CALL ad_wrt_his (ng, myrank)
1300#else
1301 CALL ad_wrt_his (ng, -1)
1302#endif
1303 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1304 END DO
1305!
1306! Write out adjoint initial condition record into the adjoint
1307! history file.
1308!
1309 DO ng=1,ngrids
1310 wrtforce(ng)=.false.
1311 lwrtstate2d(ng)=.false.
1312#ifdef DISTRIBUTE
1313 CALL ad_wrt_his (ng, myrank)
1314#else
1315 CALL ad_wrt_his (ng, -1)
1316#endif
1317 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1318 END DO
1319!
1320! Convolve adjoint trajectory with error covariances.
1321!
1322 lposterior=.false.
1323 CALL error_covariance (itlm, driver, outer, inner, &
1324 & lbck, lini, lold, lnew, &
1325 & rec1, rec2, lposterior)
1326 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1327!
1328! Convert the current adjoint solution in ADM(ng)%name to impulse
1329! forcing. Write out impulse forcing into TLF(ng)%name NetCDF file.
1330! To facilitate the forcing to the TLM and RPM, the forcing is
1331! processed and written in increasing time coordinates (recall that
1332! the adjoint solution in ADM(ng)%name is backwards in time).
1333!
1334! AMM: Do not know what to do in the weak constraint case yet.
1335!
1336!! IF (Master) THEN
1337!! WRITE (stdout,40) outer, inner
1338!! END IF
1339!! DO ng=1,Ngrids
1340!! TLF(ng)%Rindex=0
1341#ifdef DISTRIBUTE
1342!! CALL wrt_impulse (ng, MyRank, iADM, ADM(ng)%name)
1343#else
1344!! CALL wrt_impulse (ng, -1, iADM, ADM(ng)%name)
1345#endif
1346!! IF (FoundError(exit_flag, NoError, __LINE__, MyFile)) RETURN
1347!! END DO
1348!
1349!:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1350! Integrate tangent linear model forced by the convolved adjoint
1351! trajectory.
1352!:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1353!
1354#ifdef OBS_SPACE
1355!
1356! Reinitialize fourdvar arrays using the analysis interval observation
1357! file.
1358!
1359 DO ng=1,ngrids
1360 CALL close_file (ng, inlm, obs(ng), obs(ng)%name)
1361 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1362
1363 WRITE (obs(ng)%name,80) trim(obs(ng)%head), charc
1364 END DO
1365!
1366 CALL deallocate_fourdvar
1367 CALL initialize_fourdvar
1368!
1369!-----------------------------------------------------------------------
1370! If the required vectors and arrays from congrad from a previous
1371! run of the assimilation cycle are available, read them here from
1372! LCZ(ng)%name NetCDF file.
1373!-----------------------------------------------------------------------
1374!
1375 sourcefile=myfile
1376 DO ng=1,ngrids
1377 SELECT CASE (lcz(ng)%IOtype)
1378 CASE (io_nf90)
1379 CALL netcdf_get_fvar (ng, itlm, lcz(ng)%name, &
1380 & 'cg_beta', cg_beta)
1381 IF (founderror(exit_flag, noerror, &
1382 & __line__, myfile)) RETURN
1383
1384 CALL netcdf_get_fvar (ng, itlm, lcz(ng)%name, &
1385 & 'cg_delta', cg_delta)
1386 IF (founderror(exit_flag, noerror, &
1387 & __line__, myfile)) RETURN
1388
1389 CALL netcdf_get_fvar (ng, itlm, lcz(ng)%name, &
1390 & 'cg_Gnorm_v', cg_gnorm_v)
1391 IF (founderror(exit_flag, noerror, &
1392 & __line__, myfile)) RETURN
1393
1394 CALL netcdf_get_fvar (ng, itlm, lcz(ng)%name, &
1395 & 'cg_dla', cg_dla)
1396 IF (founderror(exit_flag, noerror, &
1397 & __line__, myfile)) RETURN
1398
1399 CALL netcdf_get_fvar (ng, itlm, lcz(ng)%name, &
1400 & 'cg_QG', cg_qg)
1401 IF (founderror(exit_flag, noerror, &
1402 & __line__, myfile)) RETURN
1403
1404 CALL netcdf_get_fvar (ng, itlm, lcz(ng)%name, &
1405 & 'zgrad0', zgrad0)
1406 IF (founderror(exit_flag, noerror, &
1407 & __line__, myfile)) RETURN
1408
1409 CALL netcdf_get_fvar (ng, itlm, lcz(ng)%name, &
1410 & 'zcglwk', zcglwk)
1411 IF (founderror(exit_flag, noerror, &
1412 & __line__, myfile)) RETURN
1413
1414 CALL netcdf_get_fvar (ng, itlm, lcz(ng)%name, &
1415 & 'TLmodVal_S', tlmodval_s, &
1416 & broadcast = .false.) ! Master only
1417 IF (founderror(exit_flag, noerror, &
1418 & __line__, myfile)) RETURN
1419
1420# ifdef RPCG
1421 CALL netcdf_get_fvar (ng, itlm, lcz(ng)%name, &
1422 & 'Hbk', hbk)
1423 IF (founderror(exit_flag, noerror, &
1424 & __line__, myfile)) RETURN
1425
1426 CALL netcdf_get_fvar (ng, itlm, lcz(ng)%name, &
1427 & 'Jb0', jb0)
1428 IF (founderror(exit_flag, noerror, &
1429 & __line__, myfile)) RETURN
1430
1431 CALL netcdf_get_fvar (ng, itlm, lcz(ng)%name, &
1432 & 'vcglwk', vcglwk)
1433 IF (founderror(exit_flag, noerror, &
1434 & __line__, myfile)) RETURN
1435# endif
1436
1437# if defined PIO_LIB && defined DISTRIBUTE
1438 CASE (io_pio)
1439 CALL pio_netcdf_get_fvar (ng, itlm, lcz(ng)%name, &
1440 & 'cg_beta', cg_beta)
1441 IF (founderror(exit_flag, noerror, &
1442 & __line__, myfile)) RETURN
1443
1444 CALL pio_netcdf_get_fvar (ng, itlm, lcz(ng)%name, &
1445 & 'cg_delta', cg_delta)
1446 IF (founderror(exit_flag, noerror, &
1447 & __line__, myfile)) RETURN
1448
1449 CALL pio_netcdf_get_fvar (ng, itlm, lcz(ng)%name, &
1450 & 'cg_Gnorm_v', cg_gnorm_v)
1451 IF (founderror(exit_flag, noerror, &
1452 & __line__, myfile)) RETURN
1453
1454 CALL pio_netcdf_get_fvar (ng, itlm, lcz(ng)%name, &
1455 & 'cg_dla', cg_dla)
1456 IF (founderror(exit_flag, noerror, &
1457 & __line__, myfile)) RETURN
1458
1459 CALL pio_netcdf_get_fvar (ng, itlm, lcz(ng)%name, &
1460 & 'cg_QG', cg_qg)
1461 IF (founderror(exit_flag, noerror, &
1462 & __line__, myfile)) RETURN
1463
1464 CALL pio_netcdf_get_fvar (ng, itlm, lcz(ng)%name, &
1465 & 'zgrad0', zgrad0)
1466 IF (founderror(exit_flag, noerror, &
1467 & __line__, myfile)) RETURN
1468
1469 CALL pio_netcdf_get_fvar (ng, itlm, lcz(ng)%name, &
1470 & 'zcglwk', zcglwk)
1471 IF (founderror(exit_flag, noerror, &
1472 & __line__, myfile)) RETURN
1473
1474 CALL pio_netcdf_get_fvar (ng, itlm, lcz(ng)%name, &
1475 & 'TLmodVal_S', tlmodval_s)
1476 IF (founderror(exit_flag, noerror, &
1477 & __line__, myfile)) RETURN
1478
1479# ifdef RPCG
1480 CALL pio_netcdf_get_fvar (ng, itlm, lcz(ng)%name, &
1481 & 'Hbk', hbk)
1482 IF (founderror(exit_flag, noerror, &
1483 & __line__, myfile)) RETURN
1484
1485 CALL pio_netcdf_get_fvar (ng, itlm, lcz(ng)%name, &
1486 & 'Jb0', jb0)
1487 IF (founderror(exit_flag, noerror, &
1488 & __line__, myfile)) RETURN
1489
1490 CALL pio_netcdf_get_fvar (ng, itlm, lcz(ng)%name, &
1491 & 'vcglwk', vcglwk)
1492 IF (founderror(exit_flag, noerror, &
1493 & __line__, myfile)) RETURN
1494# endif
1495# endif
1496 END SELECT
1497 END DO
1498!
1499!-----------------------------------------------------------------------
1500! If skiping runing nonlinear model, read in observation screening and
1501! quality control flag.
1502!-----------------------------------------------------------------------
1503!
1504 sourcefile=myfile
1505 wrtobsscale(1:ngrids)=.false.
1506 DO ng=1,ngrids
1507 SELECT CASE (lcz(ng)%IOtype)
1508 CASE (io_nf90)
1509 CALL netcdf_get_fvar (ng, itlm, lcz(ng)%name, &
1510 & vname(1,idobss), obsscale)
1511 IF (founderror(exit_flag, &
1512 & noerror, __line__, myfile)) RETURN
1513
1514# if defined PIO_LIB && defined DISTRIBUTE
1515 CASE (io_pio)
1516 CALL pio_netcdf_get_fvar (ng, itlm, lcz(ng)%name, &
1517 & vname(1,idobss), obsscale)
1518 IF (founderror(exit_flag, &
1519 & noerror, __line__, myfile)) RETURN
1520# endif
1521 END SELECT
1522 END DO
1523!
1524! Define output 4DVAR NetCDF file containing all processed data
1525! at observation locations.
1526!
1527 DO ng=1,ngrids
1528 ldefmod(ng)=.true.
1529 CALL def_mod (ng)
1530 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1531 END DO
1532#endif /* OBS_SPACE */
1533!
1534 DO ng=1,ngrids
1535 wrtnlmod(ng)=.false.
1536 wrttlmod(ng)=.true.
1537 lwrttlm(ng)=.false.
1538 END DO
1539!
1540! Clear tangent linear forcing arrays before entering inner-loop.
1541! This is very important.
1542!
1543 DO ng=1,ngrids
1544 DO tile=first_tile(ng),last_tile(ng),+1
1545 CALL initialize_forces (ng, tile, itlm)
1546#ifdef ADJUST_BOUNDARY
1547 CALL initialize_boundary (ng, tile, itlm)
1548#endif
1549 END DO
1550 END DO
1551!
1552! Set basic state trajectory.
1553!
1554 DO ng=1,ngrids
1555 WRITE (fwd(ng)%name,10) trim(his(ng)%head), outer-1
1556 lstr=len_trim(fwd(ng)%name)
1557 fwd(ng)%base=fwd(ng)%name(1:lstr-3)
1558 END DO
1559!
1560! If weak constraint, the impulses are time-interpolated at each
1561! time-steps.
1562!
1563 DO ng=1,ngrids
1564 IF (frcrec(ng).gt.3) THEN
1565 frequentimpulse(ng)=.true.
1566 END IF
1567 END DO
1568!
1569! Initialize tangent linear model from ITL(ng)%name, record Rec1.
1570!
1571 DO ng=1,ngrids
1572 itl(ng)%Rindex=rec1
1573 CALL close_file (ng, itlm, obs(ng), obs(ng)%name)
1574 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1575!
1576 CALL tl_initial (ng)
1577 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1578 END DO
1579!
1580! Run tangent linear model forward and force with convolved adjoint
1581! trajectory impulses. Compute (HMBM'H')_n * PSI at observation points
1582! which are used in the conjugate gradient algorithm.
1583!
1584 DO ng=1,ngrids
1585 IF (master) THEN
1586 WRITE (stdout,20) 'TL', ng, ntstart(ng), ntend(ng)
1587 END IF
1588 END DO
1589!
1590#ifdef SOLVE3D
1591 CALL tl_main3d (runinterval)
1592#else
1593 CALL tl_main2d (runinterval)
1594#endif
1595 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1596!
1597 DO ng=1,ngrids
1598 wrtnlmod(ng)=.false.
1599 wrttlmod(ng)=.false.
1600 END DO
1601
1602#ifdef OBS_IMPACT
1603!
1604! Compute observation impact to the data assimilation system.
1605!
1606 DO ng=1,ngrids
1607# ifdef RPCG
1608 CALL rep_matrix (ng, itlm, outer, ninner-1)
1609# else
1610 CALL rep_matrix (ng, itlm, outer, ninner)
1611# endif
1612 END DO
1613#else
1614!
1615! Set basic state trajectory for adjoint inner-loops.
1616!
1617 DO ng=1,ngrids
1618 WRITE (fwd(ng)%name,10) trim(his(ng)%head), outer-1
1619 lstr=len_trim(fwd(ng)%name)
1620 fwd(ng)%base=fwd(ng)%name(1:lstr-3)
1621 END DO
1622!
1623! Clear tangent linear forcing arrays before entering inner-loop.
1624!
1625 DO ng=1,ngrids
1626 DO tile=first_tile(ng),last_tile(ng),+1
1627 CALL initialize_forces (ng, tile, itlm)
1628# ifdef ADJUST_BOUNDARY
1629 CALL initialize_boundary (ng, tile, itlm)
1630# endif
1631 END DO
1632 END DO
1633!
1634# ifdef RPCG
1635 ad_inner_loop : DO my_inner=ninner,0,-1
1636# else
1637 ad_inner_loop : DO my_inner=ninner,1,-1
1638# endif
1639 inner=my_inner
1640
1641# ifdef RPCG
1642!
1643! Retrieve NLmodVal when inner=0 for use as BCKmodVal.
1644!
1645 IF (inner.eq.0) THEN
1646 DO ng=1,ngrids
1647 SELECT CASE (dav(ng)%IOtype)
1648 CASE (io_nf90)
1649 CALL netcdf_get_fvar (ng, itlm, dav(ng)%name, &
1650 & 'NLmodel_value', nlmodval)
1651 IF (founderror(exit_flag, noerror, &
1652 & __line__, myfile)) RETURN
1653
1654# if defined PIO_LIB && defined DISTRIBUTE
1655 CASE (io_pio)
1656 CALL pio_netcdf_get_fvar (ng, itlm, dav(ng)%name, &
1657 & 'NLmodel_value', nlmodval)
1658 IF (founderror(exit_flag, noerror, &
1659 & __line__, myfile)) RETURN
1660# endif
1661 END SELECT
1662 END DO
1663 END IF
1664 IF (inner.ne.ninner) THEN
1665 linner=.true.
1666 ELSE
1667 linner=.false.
1668 END IF
1669# endif
1670 IF (master) THEN
1671 WRITE (stdout,60) 'Adjoint of', uppercase('rbl4dvar'), &
1672 & outer, inner
1673 END IF
1674# ifdef RPCG
1675!
1676 inner_compute : IF (linner) THEN
1677!
1678# else
1679!
1680! Call adjoint conjugate gradient algorithm.
1681!
1682 lcgini=.false.
1683 DO ng=1,ngrids
1684 CALL ad_congrad (ng, itlm, outer, inner, ninner, lcgini)
1685 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1686 END DO
1687# endif
1688!
1689! Initialize the adjoint model from rest.
1690!
1691 DO ng=1,ngrids
1692 lsen4dvar(ng)=.false.
1693 lsenfct(ng)=.true.
1694# ifdef OBS_SPACE
1695 lobspace(ng)=.true.
1696# ifndef OBS_IMPACT
1697 ladjvar(ng)=.true.
1698# endif
1699# endif
1700 CALL close_file (ng, iadm, obs(ng), obs(ng)%name)
1701 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1702!
1703 CALL ad_initial (ng)
1704 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1705 wrtmisfit(ng)=.false.
1706 END DO
1707!
1708! Set adjoint history NetCDF parameters. Define adjoint history
1709! file only once to avoid opening too many files.
1710!
1711 DO ng=1,ngrids
1712 wrtforce(ng)=.true.
1713 IF (adm(ng)%ncid.ne.-1) ldefadj(ng)=.false.
1714 fcount=adm(ng)%load
1715 adm(ng)%Nrec(fcount)=0
1716 adm(ng)%Rindex=0
1717 END DO
1718!
1719! Time-step adjoint model backwards forced with current PSI vector.
1720!
1721 DO ng=1,ngrids
1722 IF (master) THEN
1723 WRITE (stdout,20) 'AD', ng, ntstart(ng), ntend(ng)
1724 END IF
1725 END DO
1726!
1727# ifdef SOLVE3D
1728 CALL ad_main3d (runinterval)
1729# else
1730 CALL ad_main2d (runinterval)
1731# endif
1732 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1733!
1734! Write out last weak-constraint forcing (WRTforce is still .TRUE.)
1735! record into the adjoint history file. Note that the weak-constraint
1736! forcing is delayed by nADJ time-steps.
1737!
1738 DO ng=1,ngrids
1739# ifdef DISTRIBUTE
1740 CALL ad_wrt_his (ng, myrank)
1741# else
1742 CALL ad_wrt_his (ng, -1)
1743# endif
1744 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1745 END DO
1746!
1747! Write out adjoint initial condition record into the adjoint
1748! history file.
1749!
1750 DO ng=1,ngrids
1751 wrtforce(ng)=.false.
1752 lwrtstate2d(ng)=.false.
1753# ifdef DISTRIBUTE
1754 CALL ad_wrt_his (ng, myrank)
1755# else
1756 CALL ad_wrt_his (ng, -1)
1757# endif
1758 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1759 END DO
1760!
1761! Convolve adjoint trajectory with error covariances.
1762!
1763 lposterior=.false.
1764 CALL error_covariance (itlm, driver, outer, inner, &
1765 & lbck, lini, lold, lnew, &
1766 & rec1, rec2, lposterior)
1767 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1768!
1769! Convert the current adjoint solution in ADM(ng)%name to impulse
1770! forcing. Write out impulse forcing into TLF(ng)%name NetCDF file.
1771! To facilitate the forcing to the TLM and RPM, the forcing is
1772! processed and written in increasing time coordinates (recall that
1773! the adjoint solution in ADM(ng)%name is backwards in time).
1774!
1775!!
1776!! AMM: Do not know what to do in the weak constraint case yet.
1777!!
1778!! IF (Master) THEN
1779!! WRITE (stdout,40) outer, inner
1780!! END IF
1781!! DO ng=1,Ngrids
1782!! TLF(ng)%Rindex=0
1783# ifdef DISTRIBUTE
1784!! CALL wrt_impulse (ng, MyRank, iADM, ADM(ng)%name)
1785# else
1786!! CALL wrt_impulse (ng, -1, iADM, ADM(ng)%name)
1787# endif
1788!! IF (FoundError(exit_flag, NoError, __LINE__, MyFile)) RETURN
1789!! END DO
1790!
1791!:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1792! Integrate tangent linear model.
1793!:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1794!
1795! Initialize tangent linear model from initial impulse which is now
1796! stored in file ITL(ng)%name.
1797!
1798 DO ng=1,ngrids
1799 wrtnlmod(ng)=.false.
1800 wrttlmod(ng)=.true.
1801 END DO
1802!
1803! If weak constraint, the impulses are time-interpolated at each
1804! time-steps.
1805!
1806 DO ng=1,ngrids
1807 IF (frcrec(ng).gt.3) THEN
1808 frequentimpulse(ng)=.true.
1809 END IF
1810 END DO
1811!
1812! Initialize tangent linear model from ITL(ng)%name, record 1.
1813!
1814 DO ng=1,ngrids
1815 itl(ng)%Rindex=rec1
1816 CALL close_file (ng, itlm, obs(ng), obs(ng)%name)
1817!
1818 CALL tl_initial (ng)
1819 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1820 END DO
1821!
1822! Set tangent linear history NetCDF parameters. Define tangent linear
1823! history file at the beggining of each inner loop to avoid opening
1824! too many NetCDF files.
1825!
1826 DO ng=1,ngrids
1827 IF (inner.gt.ninner) ldeftlm(ng)=.false.
1828 fcount=tlm(ng)%load
1829 tlm(ng)%Nrec(fcount)=0
1830 tlm(ng)%Rindex=0
1831 END DO
1832!
1833! Run tangent linear model forward and force with convolved adjoint
1834! trajectory impulses.
1835!
1836 DO ng=1,ngrids
1837 IF (master) THEN
1838 WRITE (stdout,20) 'TL', ng, ntstart(ng), ntend(ng)
1839 END IF
1840 END DO
1841!
1842# ifdef SOLVE3D
1843 CALL tl_main3d (runinterval)
1844# else
1845 CALL tl_main2d (runinterval)
1846# endif
1847 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1848
1849 DO ng=1,ngrids
1850 wrtnlmod(ng)=.false.
1851 wrttlmod(ng)=.false.
1852 END DO
1853# ifdef RPCG
1854 END IF inner_compute
1855!
1856 DO ng=1,ngrids
1857 CALL ad_rpcg_lanczos (ng, irpm, outer, inner, ninner, &
1858 & lcgini)
1859 END DO
1860# endif
1861
1862 END DO ad_inner_loop
1863# ifndef RPCG
1864!
1865! Call adjoint conjugate gradient algorithm.
1866!
1867 inner=0
1868 lcgini=.true.
1869 DO ng=1,ngrids
1870 CALL ad_congrad (ng, itlm, outer, inner, ninner, lcgini)
1871 END DO
1872# endif
1873
1874#endif /* !OBS_IMPACT */
1875
1876#ifdef OBS_IMPACT
1877!
1878! Write out total observation impact.
1879!
1880 sourcefile=myfile
1881 DO ng=1,ngrids
1882 SELECT CASE (dav(ng)%IOtype)
1883 CASE (io_nf90)
1884 CALL netcdf_put_fvar (ng, inlm, dav(ng)%name, &
1885 & 'ObsImpact_total', ad_obsval, &
1886# ifdef IMPACT_INNER
1887 & (/1,1/), (/mobs,ninner/), &
1888# else
1889 & (/1/), (/mobs/), &
1890# endif
1891 & ncid = dav(ng)%ncid)
1892 IF (founderror(exit_flag, noerror, &
1893 & __line__, myfile)) RETURN
1894!
1895 CALL netcdf_sync (ng, inlm, dav(ng)%name, dav(ng)%ncid)
1896 IF (founderror(exit_flag, noerror, &
1897 & __line__, myfile)) RETURN
1898
1899# if defined PIO_LIB && defined DISTRIBUTE
1900 CASE (io_pio)
1901 CALL pio_netcdf_put_fvar (ng, inlm, dav(ng)%name, &
1902 & 'ObsImpact_total', ad_obsval, &
1903# ifdef IMPACT_INNER
1904 & (/1,1/), (/mobs,ninner/), &
1905# else
1906 & (/1/), (/mobs/), &
1907# endif
1908 & piofile = dav(ng)%pioFile)
1909 IF (founderror(exit_flag, noerror, &
1910 & __line__, myfile)) RETURN
1911!
1912 CALL pio_netcdf_sync (ng, inlm, dav(ng)%name, &
1913 & dav(ng)%pioFile)
1914 IF (founderror(exit_flag, noerror, &
1915 & __line__, myfile)) RETURN
1916# endif
1917 END SELECT
1918 END DO
1919#else
1920!
1921! Write out observation sensitivity.
1922!
1923 sourcefile=myfile
1924 DO ng=1,ngrids
1925 SELECT CASE (dav(ng)%IOtype)
1926 CASE (io_nf90)
1927 CALL netcdf_put_fvar (ng, itlm, dav(ng)%name, &
1928 & 'ObsSens_total', ad_obsval, &
1929# ifdef IMPACT_INNER
1930 & (/1,1/), (/mobs,ninner/), &
1931# else
1932 & (/1/), (/mobs/), &
1933# endif
1934 & ncid = dav(ng)%ncid)
1935 IF (founderror(exit_flag, noerror, &
1936 & __line__, myfile)) RETURN
1937!
1938 CALL netcdf_sync (ng, inlm, dav(ng)%name, dav(ng)%ncid)
1939 IF (founderror(exit_flag, noerror, &
1940 & __line__, myfile)) RETURN
1941
1942# if defined PIO_LIB && defined DISTRIBUTE
1943 CASE (io_pio)
1944 CALL pio_netcdf_put_fvar (ng, itlm, dav(ng)%name, &
1945 & 'ObsSens_total', ad_obsval, &
1946# ifdef IMPACT_INNER
1947 & (/1,1/), (/mobs,ninner/), &
1948# else
1949 & (/1/), (/mobs/), &
1950# endif
1951 & piofile = dav(ng)%pioFile)
1952 IF (founderror(exit_flag, noerror, &
1953 & __line__, myfile)) RETURN
1954!
1955 CALL pio_netcdf_sync (ng, inlm, dav(ng)%name, &
1956 & dav(ng)%pioFile)
1957 IF (founderror(exit_flag, noerror, &
1958 & __line__, myfile)) RETURN
1959# endif
1960 END SELECT
1961 END DO
1962#endif
1963!
1964! Close tangent linear NetCDF file.
1965!
1966 sourcefile=myfile
1967 DO ng=1,ngrids
1968 CALL close_file (ng, itlm, tlm(ng), tlm(ng)%name)
1969 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1970 END DO
1971
1972#if defined OBS_IMPACT && defined OBS_IMPACT_SPLIT
1973!
1974!:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1975! Integrate tangent linear model with initial condition increments
1976! only to compute the observation impact associated with the initial
1977! conditions.
1978!:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1979!
1980 DO ng=1,ngrids
1981 wrtnlmod(ng)=.false.
1982 wrttlmod(ng)=.true.
1983 lwrttlm(ng)=.false.
1984 END DO
1985!
1986! Clear tangent linear forcing arrays before entering inner-loop.
1987! This is very important since these arrays are non-zero after
1988! running the representer model and must be zero when running the
1989! tangent linear model.
1990!
1991 DO ng=1,ngrids
1992 DO tile=first_tile(ng),last_tile(ng),+1
1993 CALL initialize_forces (ng, tile, itlm)
1994# ifdef ADJUST_BOUNDARY
1995 CALL initialize_boundary (ng, tile, itlm)
1996# endif
1997 END DO
1998 END DO
1999!
2000! Set basic state trajectory.
2001!
2002 DO ng=1,ngrids
2003 WRITE (fwd(ng)%name,10) trim(his(ng)%head), outer-1
2004 lstr=len_trim(fwd(ng)%name)
2005 fwd(ng)%base=fwd(ng)%name(1:lstr-3)
2006 END DO
2007!
2008! If weak constraint, the impulses are time-interpolated at each
2009! time-steps.
2010!
2011 DO ng=1,ngrids
2012 IF (frcrec(ng).gt.3) THEN
2013 frequentimpulse(ng)=.true.
2014 END IF
2015 END DO
2016!
2017! Initialize tangent linear model from ITL(ng)%name, record 1.
2018!
2019 DO ng=1,ngrids
2020 itl(ng)%Rindex=rec1
2021 CALL close_file (ng, itlm, obs(ng), obs(ng)%name)
2022 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
2023!
2024 CALL tl_initial (ng)
2025 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
2026 END DO
2027!
2028! Clear tangent linear forcing arrays and boundary arrays
2029! before the obs impact initial condition calculation.
2030!
2031 DO ng=1,ngrids
2032 DO tile=first_tile(ng),last_tile(ng),+1
2033 CALL initialize_forces (ng, tile, itlm)
2034# ifdef ADJUST_BOUNDARY
2035 CALL initialize_boundary (ng, tile, itlm)
2036# endif
2037 END DO
2038 END DO
2039!
2040! Run tangent linear model forward and force with convolved adjoint
2041! trajectory impulses. Compute (HMBM'H')_n * PSI at observation points
2042! which are used in the conjugate gradient algorithm.
2043!
2044 DO ng=1,ngrids
2045 IF (master) THEN
2046 WRITE (stdout,20) 'TL', ng, ntstart(ng), ntend(ng)
2047 END IF
2048 END DO
2049!
2050# ifdef SOLVE3D
2051 CALL tl_main3d (runinterval)
2052# else
2053 CALL tl_main2d (runinterval)
2054# endif
2055 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
2056!
2057 DO ng=1,ngrids
2058 wrtnlmod(ng)=.false.
2059 wrttlmod(ng)=.false.
2060 END DO
2061!
2062! Compute observation impact to the data assimilation system.
2063!
2064 DO ng=1,ngrids
2065# ifdef RPCG
2066 CALL rep_matrix (ng, itlm, outer, ninner-1)
2067# else
2068 CALL rep_matrix (ng, itlm, outer, ninner)
2069# endif
2070 END DO
2071!
2072! Write out observation sentivity.
2073!
2074 sourcefile=myfile
2075 DO ng=1,ngrids
2076 SELECT CASE (dav(ng)%IOtype)
2077 CASE (io_nf90)
2078 CALL netcdf_put_fvar (ng, itlm, dav(ng)%name, &
2079 & 'ObsImpact_IC', ad_obsval, &
2080# ifdef IMPACT_INNER
2081 & (/1,1/), (/mobs,ninner/), &
2082# else
2083 & (/1/), (/mobs/), &
2084# endif
2085 & ncid = dav(ng)%ncid)
2086 IF (founderror(exit_flag, noerror, &
2087 & __line__, myfile)) RETURN
2088!
2089 CALL netcdf_sync (ng, inlm, dav(ng)%name, dav(ng)%ncid)
2090 IF (founderror(exit_flag, noerror, &
2091 & __line__, myfile)) RETURN
2092
2093# if defined PIO_LIB && defined DISTRIBUTE
2094 CASE (io_pio)
2095 CALL pio_netcdf_put_fvar (ng, itlm, dav(ng)%name, &
2096 & 'ObsImpact_IC', ad_obsval, &
2097# ifdef IMPACT_INNER
2098 & (/1,1/), (/mobs,ninner/), &
2099# else
2100 & (/1/), (/mobs/), &
2101# endif
2102 & piofile = dav(ng)%pioFile)
2103 IF (founderror(exit_flag, noerror, &
2104 & __line__, myfile)) RETURN
2105!
2106 CALL pio_netcdf_sync (ng, inlm, dav(ng)%name, &
2107 & dav(ng)%pioFile)
2108 IF (founderror(exit_flag, noerror, &
2109 & __line__, myfile)) RETURN
2110# endif
2111 END SELECT
2112 END DO
2113
2114# if defined ADJUST_WSTRESS || defined ADJUST_STFLUX
2115!
2116!:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
2117! Integrate tangent linear model with surface forcing increments
2118! only to compute the observation impact associated with the surface
2119! forcing.
2120!:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
2121!
2122 DO ng=1,ngrids
2123 wrtnlmod(ng)=.false.
2124 wrttlmod(ng)=.true.
2125 lwrttlm(ng)=.false.
2126 END DO
2127!
2128! Clear tangent linear forcing arrays before entering inner-loop.
2129! This is very important since these arrays are non-zero after
2130! running the representer model and must be zero when running the
2131! tangent linear model.
2132!
2133 DO ng=1,ngrids
2134 DO tile=first_tile(ng),last_tile(ng),+1
2135 CALL initialize_forces (ng, tile, itlm)
2136# ifdef ADJUST_BOUNDARY
2137 CALL initialize_boundary (ng, tile, itlm)
2138# endif
2139 END DO
2140 END DO
2141!
2142! Set basic state trajectory.
2143!
2144 DO ng=1,ngrids
2145 WRITE (fwd(ng)%name,10) trim(his(ng)%head), outer-1
2146 lstr=len_trim(fwd(ng)%name)
2147 fwd(ng)%base=fwd(ng)%name(1:lstr-3)
2148 END DO
2149!
2150! If weak constraint, the impulses are time-interpolated at each
2151! time-steps.
2152!
2153 DO ng=1,ngrids
2154 IF (frcrec(ng).gt.3) THEN
2155 frequentimpulse(ng)=.true.
2156 END IF
2157 END DO
2158!
2159! Initialize tangent linear model from ITL(ng)%name, record 1.
2160!
2161 DO ng=1,ngrids
2162 itl(ng)%Rindex=rec1
2163 CALL close_file (ng, itlm, obs(ng), obs(ng)%name)
2164 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
2165!
2166 CALL tl_initial (ng)
2167 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
2168 END DO
2169!
2170! Clear tangent initial condition arrays and boundary arrays
2171! before the obs impact initial condition calculation.
2172!
2173 DO ng=1,ngrids
2174 DO tile=first_tile(ng),last_tile(ng),+1
2175 CALL initialize_ocean (ng, tile, itlm)
2176# ifdef ADJUST_BOUNDARY
2177 CALL initialize_boundary (ng, tile, itlm)
2178# endif
2179 END DO
2180 END DO
2181!
2182! Run tangent linear model forward and force with convolved adjoint
2183! trajectory impulses. Compute (HMBM'H')_n * PSI at observation points
2184! which are used in the conjugate gradient algorithm.
2185!
2186 DO ng=1,ngrids
2187 IF (master) THEN
2188 WRITE (stdout,20) 'TL', ng, ntstart(ng), ntend(ng)
2189 END IF
2190 END DO
2191!
2192# ifdef SOLVE3D
2193 CALL tl_main3d (runinterval)
2194# else
2195 CALL tl_main2d (runinterval)
2196# endif
2197 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
2198!
2199 DO ng=1,ngrids
2200 wrtnlmod(ng)=.false.
2201 wrttlmod(ng)=.false.
2202 END DO
2203!
2204! Compute observation impact to the data assimilation system.
2205!
2206 DO ng=1,ngrids
2207# ifdef RPCG
2208 CALL rep_matrix (ng, itlm, outer, ninner-1)
2209# else
2210 CALL rep_matrix (ng, itlm, outer, ninner)
2211# endif
2212 END DO
2213!
2214! Write out observation sentivity.
2215!
2216 sourcefile=myfile
2217 DO ng=1,ngrids
2218 SELECT CASE (dav(ng)%IOtype)
2219 CASE (io_nf90)
2220 CALL netcdf_put_fvar (ng, itlm, dav(ng)%name, &
2221 & 'ObsImpact_FC', ad_obsval, &
2222# ifdef IMPACT_INNER
2223 & (/1,1/), (/mobs,ninner/), &
2224# else
2225 & (/1/), (/mobs/), &
2226# endif
2227 & ncid = dav(ng)%ncid)
2228 IF (founderror(exit_flag, noerror, &
2229 & __line__, myfile)) RETURN
2230!
2231 CALL netcdf_sync (ng, inlm, dav(ng)%name, dav(ng)%ncid)
2232 IF (founderror(exit_flag, noerror, &
2233 & __line__, myfile)) RETURN
2234
2235# if defined PIO_LIB && defined DISTRIBUTE
2236 CASE (io_pio)
2237 CALL pio_netcdf_put_fvar (ng, itlm, dav(ng)%name, &
2238 & 'ObsImpact_FC', ad_obsval, &
2239# ifdef IMPACT_INNER
2240 & (/1,1/), (/mobs,ninner/), &
2241# else
2242 & (/1/), (/mobs/), &
2243# endif
2244 & piofile = dav(ng)%pioFile)
2245 IF (founderror(exit_flag, noerror, &
2246 & __line__, myfile)) RETURN
2247!
2248 CALL pio_netcdf_sync (ng, inlm, dav(ng)%name, &
2249 & dav(ng)%pioFile)
2250 IF (founderror(exit_flag, noerror, &
2251 & __line__, myfile)) RETURN
2252# endif
2253 END SELECT
2254 END DO
2255# endif
2256
2257# if defined ADJUST_BOUNDARY
2258!
2259!:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
2260! Integrate tangent linear model with boundary condition increments
2261! only to compute the observation impact associated with the boundary
2262! conditions.
2263!:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
2264!
2265 DO ng=1,ngrids
2266 wrtnlmod(ng)=.false.
2267 wrttlmod(ng)=.true.
2268 lwrttlm(ng)=.false.
2269 END DO
2270!
2271! Clear tangent linear forcing arrays before entering inner-loop.
2272! This is very important since these arrays are non-zero after
2273! running the representer model and must be zero when running the
2274! tangent linear model.
2275!
2276 DO ng=1,ngrids
2277 DO tile=first_tile(ng),last_tile(ng),+1
2278 CALL initialize_forces (ng, tile, itlm)
2279# ifdef ADJUST_BOUNDARY
2280 CALL initialize_boundary (ng, tile, itlm)
2281# endif
2282 END DO
2283 END DO
2284!
2285! Set basic state trajectory.
2286!
2287 DO ng=1,ngrids
2288 WRITE (fwd(ng)%name,10) trim(his(ng)%head), outer-1
2289 lstr=len_trim(fwd(ng)%name)
2290 fwd(ng)%base=fwd(ng)%name(1:lstr-3)
2291 END DO
2292!
2293! If weak constraint, the impulses are time-interpolated at each
2294! time-steps.
2295!
2296 DO ng=1,ngrids
2297 IF (frcrec(ng).gt.3) THEN
2298 frequentimpulse(ng)=.true.
2299 END IF
2300 END DO
2301!
2302! Initialize tangent linear model from ITL(ng)%name, record Rec1.
2303!
2304 DO ng=1,ngrids
2305 itl(ng)%Rindex=rec1
2306 CALL close_file (ng, itlm, obs(ng), obs(ng)%name)
2307 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
2308!
2309 CALL tl_initial (ng)
2310 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
2311 END DO
2312!
2313! Clear tangent linear initial condition and forcing arrays
2314! before the obs impact initial condition calculation.
2315!
2316 DO ng=1,ngrids
2317 DO tile=first_tile(ng),last_tile(ng),+1
2318 CALL initialize_ocean (ng, tile, itlm)
2319 CALL initialize_forces (ng, tile, itlm)
2320 END DO
2321 END DO
2322!
2323! Run tangent linear model forward and force with convolved adjoint
2324! trajectory impulses. Compute (HMBM'H')_n * PSI at observation points
2325! which are used in the conjugate gradient algorithm.
2326!
2327 DO ng=1,ngrids
2328 IF (master) THEN
2329 WRITE (stdout,20) 'TL', ng, ntstart(ng), ntend(ng)
2330 END IF
2331 END DO
2332!
2333# ifdef SOLVE3D
2334 CALL tl_main3d (runinterval)
2335# else
2336 CALL tl_main2d (runinterval)
2337# endif
2338 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
2339!
2340 DO ng=1,ngrids
2341 wrtnlmod(ng)=.false.
2342 wrttlmod(ng)=.false.
2343 END DO
2344!
2345! Compute observation impact to the data assimilation system.
2346!
2347 DO ng=1,ngrids
2348# ifdef RPCG
2349 CALL rep_matrix (ng, itlm, outer, ninner-1)
2350# else
2351 CALL rep_matrix (ng, itlm, outer, ninner)
2352# endif
2353 END DO
2354!
2355! Write out observation sentivity.
2356!
2357 sourcefile=myfile
2358 DO ng=1,ngrids
2359 SELECT CASE (dav(ng)%IOtype)
2360 CASE (io_nf90)
2361 CALL netcdf_put_fvar (ng, itlm, dav(ng)%name, &
2362 & 'ObsImpact_BC', ad_obsval, &
2363# ifdef IMPACT_INNER
2364 & (/1,1/), (/mobs,ninner/), &
2365# else
2366 & (/1/), (/mobs/), &
2367# endif
2368 & ncid = dav(ng)%ncid)
2369 IF (founderror(exit_flag, noerror, &
2370 & __line__, myfile)) RETURN
2371!
2372 CALL netcdf_sync (ng, inlm, dav(ng)%name, dav(ng)%ncid)
2373 IF (founderror(exit_flag, noerror,
2374 & __line__, myfile)) RETURN
2375
2376# if defined PIO_LIB && defined DISTRIBUTE
2377 CASE (io_pio)
2378 CALL pio_netcdf_put_fvar (ng, itlm, dav(ng)%name, &
2379 & 'ObsImpact_BC', ad_obsval, &
2380# ifdef IMPACT_INNER
2381 & (/1,1/), (/mobs,ninner/), &
2382# else
2383 & (/1/), (/mobs/), &
2384# endif
2385 & piofile = dav(ng)%pioFile)
2386 IF (founderror(exit_flag, noerror, &
2387 & __line__, myfile)) RETURN
2388!
2389 CALL pio_netcdf_sync (ng, inlm, dav(ng)%name, &
2390 & dav(ng)%pioFile)
2391 IF (founderror(exit_flag, noerror,
2392 & __line__, myfile)) RETURN
2393# endif
2394 END SELECT
2395 END DO
2396# endif
2397#endif /* OBS_IMPACT_SPLIT */
2398!
2399! Close current forward NetCDF file.
2400!
2401 sourcefile=myfile
2402 DO ng=1,ngrids
2403 CALL close_file (ng, inlm, fwd(ng), fwd(ng)%name)
2404 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
2405!
2406 IF (his(ng)%IOtype.eq.io_nf90) THEN
2407 his(ng)%ncid=-1
2408#if defined PIO_LIB && defined DISTRIBUTE
2409 ELSE IF (his(ng)%IOtype.eq.io_pio) THEN
2410 his(ng)%pioFile%fh=-1
2411#endif
2412 END IF
2413 END DO
2414
2415 END DO ad_outer_loop
2416!
2417 10 FORMAT (a,'_outer',i0,'.nc')
2418 20 FORMAT (/,1x,a,1x,'ROMS: started time-stepping:', &
2419 & ' (Grid: ',i2.2,' TimeSteps: ',i8.8,' - ',i8.8,')',/)
2420 30 FORMAT (' (',i3.3,',',i3.3,'): ',a,' data penalty, Jdata = ', &
2421 & 1p,e17.10,0p,t68,a)
2422 40 FORMAT (/,' Converting Convolved Adjoint Trajectory to', &
2423 & ' Impulses: Outer = ',i3.3,' Inner = ',i3.3,/)
2424 50 FORMAT (/,'ROMS: Started adjoint Sensitivity calculation', &
2425 & ' ...',/)
2426 60 FORMAT (/,'ROMS: ',a,1x,a,', Outer = ',i3.3, &
2427 & ' Inner = ',i3.3,/)
2428 70 FORMAT (/,1x,a,1x,'ROMS: adjoint forcing time range: ', &
2429 & f12.4,' - ',f12.4 ,/)
2430 80 FORMAT (a,'_',a,'.nc')
2431 90 FORMAT (a,'.nc')
2432!
2433 RETURN
subroutine ad_congrad
subroutine initial
Definition initial.F:3
subroutine rep_matrix(ng, model, outloop, ninnloop)
Definition rep_matrix.F:4
subroutine tl_initial(ng)
Definition tl_initial.F:4
subroutine tl_main2d
Definition tl_main2d.F:429
subroutine tl_main3d(runinterval)
Definition tl_main3d.F:4

References ad_congrad(), ad_initial(), ad_main2d(), ad_main3d(), mod_fourdvar::ad_obsval, ad_wrt_his_mod::ad_wrt_his(), mod_iounits::adm, mod_iounits::ads, mod_scalars::balance, zeta_balance_mod::balance_ref(), zeta_balance_mod::biconj(), mod_scalars::blowup, mod_fourdvar::cg_beta, mod_fourdvar::cg_delta, mod_fourdvar::cg_dla, mod_fourdvar::cg_gnorm_v, mod_fourdvar::cg_qg, close_io_mod::close_file(), close_io_mod::close_inp(), close_io_mod::close_out(), mod_iounits::dav, mod_fourdvar::deallocate_fourdvar(), def_impulse_mod::def_impulse(), def_mod_mod::def_mod(), def_norm_mod::def_norm(), mod_scalars::dends, mod_scalars::dstart, mod_scalars::dstarts, mod_scalars::dstrs, mod_scalars::dt, edit_multifile(), mod_scalars::erend, convolve_mod::error_covariance(), mod_scalars::erstr, mod_scalars::exit_flag, mod_parallel::first_tile, strings_mod::founderror(), mod_scalars::frcrec, mod_scalars::frequentimpulse, mod_iounits::fwd, get_state_mod::get_state(), mod_iounits::his, mod_param::iadm, mod_ncparam::idobss, mod_iounits::ini, initial(), mod_boundary::initialize_boundary(), mod_forces::initialize_forces(), mod_fourdvar::initialize_fourdvar(), mod_ocean::initialize_ocean(), mod_param::inlm, mod_scalars::inner, mod_ncparam::io_nf90, mod_ncparam::io_pio, mod_param::irpm, mod_ncparam::isfsur, mod_iounits::itl, mod_param::itlm, mod_fourdvar::jb0, mod_parallel::last_tile, mod_stepping::lbinp, mod_stepping::lbout, mod_scalars::lcyclerst, mod_iounits::lcz, mod_scalars::ldefadj, mod_scalars::ldefitl, mod_scalars::ldefmod, mod_scalars::ldefnrm, mod_scalars::ldeftlf, mod_scalars::ldeftlm, mod_stepping::lfinp, mod_stepping::lfout, mod_stepping::lnew, ini_adjust_mod::load_adtotl(), ini_adjust_mod::load_tltoad(), mod_fourdvar::lobspace, mod_stepping::lold, mod_scalars::lreadblk, mod_scalars::lreadfrc, mod_scalars::lreadfwd, mod_scalars::lreadqck, mod_fourdvar::lsen4dvar, mod_fourdvar::lsenfct, mod_scalars::lstiffness, mod_scalars::lwrtnrm, mod_scalars::lwrtrst, mod_scalars::lwrtstate2d, mod_scalars::lwrttlm, mod_parallel::master, memory(), mod_fourdvar::mobs, mod_parallel::myrank, mod_netcdf::netcdf_sync(), mod_param::ngrids, mod_fourdvar::nimpact, mod_scalars::ninner, mod_fourdvar::nlmodval, mod_scalars::noerror, normalization_mod::normalization(), mod_scalars::nouter, mod_iounits::nrm, mod_scalars::nrun, mod_param::nsa, mod_scalars::ntend, mod_scalars::ntimes, mod_fourdvar::ntimes_ana, mod_fourdvar::ntimes_fct, mod_scalars::ntstart, mod_iounits::obs, mod_fourdvar::obsscale, mod_iounits::oifa, mod_iounits::oifb, mod_scalars::outer, mod_pio_netcdf::pio_netcdf_sync(), rep_matrix(), mod_iounits::rst, mod_scalars::sec2day, mod_iounits::sourcefile, stats_modobs_mod::stats_modobs(), mod_iounits::stdout, mod_scalars::tdays, tl_def_ini_mod::tl_def_ini(), tl_initial(), tl_main2d(), tl_main3d(), mod_iounits::tlm, strings_mod::uppercase(), mod_fourdvar::vcglwk, mod_ncparam::vname, wclock_off(), wrt_ini_mod::wrt_ini(), wrt_rst_mod::wrt_rst(), mod_fourdvar::wrtforce, mod_fourdvar::wrtmisfit, mod_fourdvar::wrtnlmod, mod_fourdvar::wrtobsscale, mod_fourdvar::wrtrpmod, mod_fourdvar::wrttlmod, mod_fourdvar::wrtzetaref, mod_fourdvar::zcglwk, and mod_fourdvar::zgrad0.

Here is the call graph for this function:

◆ roms_run() [3/3]

subroutine, public roms_kernel_mod::roms_run ( real(dp), intent(in) runinterval,
integer, intent(in), optional kernel )

Definition at line 336 of file jedi_roms.h.

337!
338!=======================================================================
339! !
340! This routine advance ROMS kernel for the specified time interval. !
341! !
342! On Input: !
343! !
344! RunInterval Execution time stepping window (seconds) !
345! kernel Dynamical/numerical kernel (integer) !
346! !
347!=======================================================================
348!
349! Imported variable declarations
350!
351 integer, intent(in), optional :: kernel
352!
353 real(dp), intent(in) :: RunInterval
354!
355! Local variable declarations.
356!
357 integer :: ng
358 integer :: NstrStep, NendStep, extra
359!
360 real(dp) :: ENDtime, NEXTtime
361!
362 character (len=2), dimension(4) :: MID = (/'NL','TL','RP','AD'/)
363
364 character (len=*), parameter :: MyFile = &
365 & __FILE__//", ROMS_run"
366!
367 sourcefile=myfile
368!
369!=======================================================================
370! Advance ROMS dynamical/numerical kernel: NLM, TLM, or ADM
371!=======================================================================
372!
373! OOPS will advance ROMS kernels by smaller intervals, usually a single
374! timestep. The strategy here is different to that used for coupling
375! since ROMS delayed output. The delayed ouput last half timestep will
376! affect the OOPS trajectory logic needed to save the NLM background
377! fields needed to linearize the TLM and ADM kernels.
378!
379 myruninterval=runinterval
380 IF (master) WRITE (stdout,'(1x)')
381!
382 SELECT CASE (kernel)
383 CASE (inlm)
384 DO ng=1,ngrids
385 nexttime=time(ng)+runinterval
386 endtime=initime(ng)+ntimes(ng)*dt(ng)
387 extra=1
388 step_counter(ng)=0
389 nstrstep=iic(ng)-1
390 nendstep=nstrstep+int((myruninterval)/dt(ng))-extra
391 IF (iic(ng).eq.ntstart(ng)) THEN
392 processinputdata(ng)=.false. ! because Phase 3
393 ELSE
394 processinputdata(ng)=.true.
395 END IF
396 IF (master) WRITE (stdout,10) mid(kernel), ng, &
397 & nstrstep, max(0,nendstep)
398 END DO
399 IF (master) WRITE (stdout,'(1x)')
400 CASE (itlm)
401 DO ng=1,ngrids
402 nexttime=time(ng)+runinterval
403 endtime=initime(ng)+ntimes(ng)*dt(ng)
404 extra=1
405 step_counter(ng)=0
406 nstrstep=iic(ng)-1
407 nendstep=nstrstep+int((myruninterval)/dt(ng))-extra
408 IF (iic(ng).eq.ntstart(ng)) THEN
409 processinputdata(ng)=.false. ! because Phase 3
410 ELSE
411 processinputdata(ng)=.true.
412 END IF
413 IF (master) WRITE (stdout,10) mid(kernel), ng, &
414 & nstrstep, max(0,nendstep)
415 END DO
416 IF (master) WRITE (stdout,'(1x)')
417 CASE (iadm)
418 DO ng=1,ngrids
419 nexttime=time(ng)-runinterval
420 endtime=initime(ng)+ntimes(ng)*dt(ng)
421 extra=1
422 step_counter(ng)=0
423 nstrstep=iic(ng)-1
424 nendstep=nstrstep-int((myruninterval)/dt(ng))+extra
425 IF (master) WRITE (stdout,10) mid(kernel), ng, &
426 & nstrstep, max(0,nendstep)
427 END DO
428 IF (master) WRITE (stdout,'(1x)')
429 END SELECT
430!
431! Time-step ROMS kernel.
432!
433 SELECT CASE (kernel)
434 CASE (inlm)
435 CALL main3d (runinterval)
436#ifdef TANGENT
437 CASE (itlm)
438 CALL tl_main3d (runinterval)
439#endif
440#ifdef ADJOINT
441 CASE (iadm)
442 CALL ad_main3d (runinterval)
443#endif
444 END SELECT
445!
446 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
447!
448 10 FORMAT (1x,a,1x,'ROMS: started time-stepping:', &
449 & ' (Grid: ',i2.2,' TimeSteps: ',i0,' - ',i0,')')
450!
451 RETURN
subroutine main3d(runinterval)
Definition main3d.F:4

References ad_main3d(), mod_scalars::blowup, close_io_mod::close_inp(), close_io_mod::close_out(), mod_scalars::dt, mod_scalars::exit_flag, strings_mod::founderror(), mod_param::iadm, mod_scalars::iic, mod_scalars::initime, mod_param::inlm, mod_param::itlm, mod_scalars::lcyclerst, mod_scalars::lwrtrst, main3d(), mod_parallel::master, memory(), mod_parallel::myrank, mod_scalars::myruninterval, mod_param::ngrids, mod_scalars::noerror, mod_scalars::ntimes, mod_scalars::ntstart, mod_scalars::processinputdata, mod_iounits::rst, mod_iounits::sourcefile, mod_iounits::stdout, mod_scalars::step_counter, mod_scalars::time, tl_main3d(), wclock_off(), and wrt_rst_mod::wrt_rst().

Here is the call graph for this function:

◆ tlm_initial()

subroutine, private roms_kernel_mod::tlm_initial ( integer, intent(in) phase)
private

Definition at line 999 of file jedi_roms.h.

1000!
1001!=======================================================================
1002! !
1003! ROMSJEDI tangent linear model (TLM) kernel initialization Phases: !
1004! !
1005! Phase 1: Set time-stepping parameters !
1006! !
1007! Phase 2: Computes masks and other configuration arrays. It reads !
1008! initial forcing snapshots. !
1009! !
1010!=======================================================================
1011!
1012! Imported variable declarations
1013!
1014 integer, intent(in) :: Phase
1015!
1016! Local variable declarations.
1017!
1018 integer :: Fcount
1019 integer :: ng, thread, tile
1020 integer :: lstr, ifile
1021
1022 integer, dimension(Ngrids) :: IniRec, Tindex
1023
1024# ifdef GENERIC_DSTART
1025!
1026 real(dp) :: my_dstart
1027# endif
1028!
1029 character (len=10) :: suffix
1030
1031 character (len=*), parameter :: MyFile = &
1032 & __FILE__//", tlm_initial"
1033
1034# ifdef PROFILE
1035!
1036!-----------------------------------------------------------------------
1037! Start time wall clocks.
1038!-----------------------------------------------------------------------
1039!
1040 DO ng=1,ngrids
1041 DO thread=thread_range
1042 CALL wclock_on (ng, itlm, 2, __line__, myfile)
1043 END DO
1044 END DO
1045# endif
1046!
1047!=======================================================================
1048! ROMSJEDI TLM kernel, Phase 1 Initialization.
1049!=======================================================================
1050!
1051 phase1 : IF (phase.eq.1) THEN
1052!
1053 IF (master) THEN
1054 WRITE (stdout,10) 'TLM_INITIAL: Phase 1 Initialization: ', &
1055 & 'Configuring ROMS tangent linear kernel ...'
1056 END IF
1057!
1058! Initialize time stepping indices and counters.
1059!
1060 DO ng=1,ngrids
1061 iif(ng)=1
1062 indx1(ng)=1
1063 kstp(ng)=1
1064 krhs(ng)=1
1065 knew(ng)=1
1066 predictor_2d_step(ng)=.false.
1067!
1068 iic(ng)=0
1069# ifdef JEDI
1070 jic(ng)=0
1071# endif
1072 nstp(ng)=1
1073 nrhs(ng)=1
1074 nnew(ng)=1
1075# ifdef FLOATS_NOT_YET
1076 nf(ng)=0
1077 nfp1(ng)=1
1078 nfm1(ng)=4
1079 nfm2(ng)=3
1080 nfm3(ng)=2
1081# endif
1082!
1083 synchro_flag(ng)=.true.
1084 first_time(ng)=0
1085 IF (any(tl_volcons(:,ng))) THEN
1086 tl_ubar_xs=0.0_r8
1087 END IF
1088
1089# if defined GENERIC_DSTART
1090!
1091! Rarely, the tangent linear model is initialized from a NetCDF file,
1092! so we do not know its actual initialization time. Usually, it is
1093! computed from DSTART, implying that its value is correct in the ROMS
1094! input script. Therefore, the user needs to check and update its value
1095! to every time that ROMS is executed. Alternatively, if available, we
1096! can use the initialization time from the nonlinear model, INItime.
1097! This variable is assigned when computing or processing the basic
1098! state trajectory needed to linearize the adjoint model.
1099!
1100 IF (initime(ng).lt.0.0_dp) THEN
1101 my_dstart=dstart ! ROMS input script
1102 ELSE
1103 my_dstart=initime(ng)/86400.0_dp ! NLM IC time is known
1104 END IF
1105 tdays(ng)=my_dstart
1106# else
1107 tdays(ng)=dstart
1108# endif
1109 time(ng)=tdays(ng)*day2sec
1110# ifdef JEDI
1111 time4jedi(ng)=time(ng)
1112# endif
1113 ntstart(ng)=int((time(ng)-dstart*day2sec)/dt(ng))+1
1114 ntend(ng)=ntstart(ng)+ntimes(ng)-1
1115 ntfirst(ng)=ntstart(ng)
1116!
1117 inirec(ng)=nrrec(ng)
1118 tindex(ng)=1
1119 END DO
1120!
1121! Initialize global diagnostics variables.
1122!
1123 avgke=0.0_dp
1124 avgpe=0.0_dp
1125 avgkp=0.0_dp
1126 volume=0.0_dp
1127
1128 END IF phase1
1129!
1130!=======================================================================
1131! ROMSJEDI TLM kernel, Phase 2 Initialization.
1132!=======================================================================
1133!
1134 phase2: IF (phase.eq.2) THEN
1135!
1136 IF (master) THEN
1137 WRITE (stdout,10) 'TLM_INITIAL: Phase 2 Initialization: ', &
1138 & 'Get/Set required applications fields ...'
1139 END IF
1140!
1141!-----------------------------------------------------------------------
1142! Initialize horizontal mixing coefficients. If applicable, scale
1143! mixing coefficients according to the grid size (smallest area).
1144# ifndef ANA_SPONGE
1145! Also increase their values in sponge areas using the "visc_factor"
1146! and/or "diff_factor" read from input Grid NetCDF file.
1147# endif
1148!-----------------------------------------------------------------------
1149!
1150 DO ng=1,ngrids
1151 DO tile=first_tile(ng),last_tile(ng),+1
1152 CALL ini_hmixcoef (ng, tile, itlm)
1153 END DO
1154 END DO
1155
1156# ifdef ANA_SPONGE
1157!
1158!-----------------------------------------------------------------------
1159! Increase horizontal mixing coefficients in sponge areas using
1160! analytical functions.
1161!-----------------------------------------------------------------------
1162!
1163 DO ng=1,ngrids
1164 IF (lsponge(ng)) THEN
1165 DO tile=first_tile(ng),last_tile(ng),+1
1166 CALL ana_sponge (ng, tile, itlm)
1167 END DO
1168 END IF
1169 END DO
1170# endif
1171!
1172!-----------------------------------------------------------------------
1173! Initialize tangent linear bathymetry to zero.
1174!-----------------------------------------------------------------------
1175!
1176 DO ng=1,ngrids
1177 DO tile=first_tile(ng),last_tile(ng),+1
1178 CALL tl_bath (ng, tile)
1179 END DO
1180 END DO
1181
1182# ifdef WET_DRY
1183!
1184!-----------------------------------------------------------------------
1185! Process initial wet/dry masks.
1186!-----------------------------------------------------------------------
1187!
1188 DO ng=1,ngrids
1189 DO tile=first_tile(ng),last_tile(ng),+1
1190 CALL wetdry (ng, tile, tindex(ng), .true.)
1191 END DO
1192 END DO
1193# endif
1194
1195# ifdef FORWARD_FLUXES
1196!
1197!-----------------------------------------------------------------------
1198! Set the BLK structure to contain the nonlinear model surface fluxes
1199! needed by the tangent linear and adjoint models. Also, set switches
1200! to process that structure in routine "check_multifile". Notice that
1201! it is possible to split the solution into multiple NetCDF files to
1202! reduce their size.
1203!-----------------------------------------------------------------------
1204!
1205! Set the nonlinear model quicksave-history file as the basic state for
1206! the surface fluxes computed in "bulk_flux", which may be available at
1207! more frequent intervals while avoiding large files. Since the 4D-Var
1208! increment phase is calculated by a different executable and needs to
1209! know some of the QCK structure information.
1210!
1211 DO ng=1,ngrids
1212 WRITE (qck(ng)%name,"(a,'.nc')") trim(qck(ng)%head)
1213 lstr=len_trim(qck(ng)%name)
1214 qck(ng)%base=qck(ng)%name(1:lstr-3)
1215 IF (qck(ng)%Nfiles.gt.1) THEN
1216 DO ifile=1,qck(ng)%Nfiles
1217 WRITE (suffix,"('_',i4.4,'.nc')") ifile
1218 qck(ng)%files(ifile)=trim(qck(ng)%base)//trim(suffix)
1219 END DO
1220 qck(ng)%name=trim(qck(ng)%files(1))
1221 ELSE
1222 qck(ng)%files(1)=trim(qck(ng)%name)
1223 END IF
1224 END DO
1225!
1226! The switch LreadFRC is deactivated because all the atmospheric
1227! forcing, including shortwave radiation, is read from the NLM
1228! surface fluxes or is assigned during ESM coupling. Such fluxes
1229! are available from the QCK structure. There is no need for reading
1230! and processing from the FRC structure input forcing-files.
1231!
1232 CALL edit_multifile ('QCK2BLK')
1233 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1234 DO ng=1,ngrids
1235 lreadblk(ng)=.true.
1236 lreadfrc(ng)=.false.
1237 lreadqck(ng)=.false.
1238 END DO
1239# endif
1240!
1241!-----------------------------------------------------------------------
1242! If applicable, close all input boundary, climatology, and forcing
1243! NetCDF files and set associated parameters to the closed state. This
1244! step is essential in iterative algorithms that run the full TLM
1245! repetitively. Then, Initialize several parameters in their file
1246! structure, so the appropriate input single or multi-file is selected
1247! during initialization/restart.
1248!-----------------------------------------------------------------------
1249!
1250 DO ng=1,ngrids
1251 CALL close_inp (ng, itlm)
1252 CALL check_multifile (ng, itlm)
1253# ifdef DISTRIBUTE
1254 CALL mp_bcasti (ng, itlm, exit_flag)
1255# endif
1256 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1257 END DO
1258!
1259!-----------------------------------------------------------------------
1260! Read in initial forcing, climatology and assimilation data from
1261! input NetCDF files. It loads the first relevant data record for
1262! the time-interpolation between snapshots.
1263!-----------------------------------------------------------------------
1264!
1265 DO ng=1,ngrids
1266 CALL tl_get_idata (ng)
1267 CALL tl_get_data (ng)
1268# ifdef DISTRIBUTE
1269 CALL mp_bcasti (ng, itlm, exit_flag)
1270# endif
1271 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1272 END DO
1273
1274# ifdef MASKING
1275!
1276!-----------------------------------------------------------------------
1277! Set internal I/O mask arrays.
1278!-----------------------------------------------------------------------
1279!
1280 DO ng=1,ngrids
1281 DO tile=first_tile(ng),last_tile(ng),+1
1282 CALL set_masks (ng, tile, itlm)
1283 END DO
1284 END DO
1285# endif
1286
1287# if defined ANA_DRAG && defined UV_DRAG_GRID
1288!
1289!-----------------------------------------------------------------------
1290! Set analytical spatially varying bottom friction parameter.
1291!-----------------------------------------------------------------------
1292!
1293 IF (nrun.eq.erstr) THEN
1294 DO ng=1,ngrids
1295 DO tile=first_tile(ng),last_tile(ng),+1
1296 CALL ana_drag (ng, tile, itlm)
1297 END DO
1298 END DO
1299 END IF
1300# endif
1301!
1302!-----------------------------------------------------------------------
1303! Compute grid stiffness.
1304!-----------------------------------------------------------------------
1305!
1306 IF (lstiffness) THEN
1307 lstiffness=.false.
1308 DO ng=1,ngrids
1309 DO tile=first_tile(ng),last_tile(ng),+1
1310 CALL stiffness (ng, tile, itlm)
1311 END DO
1312 END DO
1313 END IF
1314
1315# if defined FLOATS_NOT_YET || defined STATIONS
1316!
1317!-----------------------------------------------------------------------
1318! If applicable, convert initial locations to fractional grid
1319! coordinates.
1320!-----------------------------------------------------------------------
1321!
1322 DO ng=1,ngrids
1323 CALL grid_coords (ng, itlm)
1324 END DO
1325# endif
1326 END IF phase2
1327!
1328!=======================================================================
1329! ROMSJEDI TLM kernel, Phase 3 Initialization.
1330!=======================================================================
1331!
1332 phase3: IF (phase.eq.3) THEN
1333!
1334 IF (master) THEN
1335 WRITE (stdout,10) 'TLM_INITIAL: Phase 3 Initialization: ', &
1336 & 'State Lateral Boundary Conditions ...'
1337 END IF
1338!
1339!-----------------------------------------------------------------------
1340! Initialize time-stepping counter and time/date string.
1341!
1342! Notice that it is allowed to modify the "simulation length" in the
1343! roms-jedi YAML file, which will affect the values of "ntimes" and
1344! "ntend".
1345!-----------------------------------------------------------------------
1346!
1347! Subsract one time unit to avoid special case due to initialization
1348! in the main time-stepping routine.
1349!
1350 DO ng=1,ngrids
1351 iic(ng)=ntstart(ng)
1352 ntend(ng)=ntstart(ng)+ntimes(ng)-1
1353#ifdef JEDI
1354 jic(ng)=ntstart(ng)
1355 time4jedi(ng)=time(ng)
1356#endif
1357 CALL time_string (time(ng), time_code(ng))
1358 ldeftlm(ng)=.true.
1359 lwrttlm(ng)=.true.
1360 END DO
1361!
1362!-----------------------------------------------------------------------
1363! Read in required data, if any, from input NetCDF files.
1364!-----------------------------------------------------------------------
1365!
1366 DO ng=1,ngrids
1367 CALL tl_get_data (ng)
1368 IF (founderror(exit_flag, noerror, &
1369 & __line__, myfile)) RETURN
1370 END DO
1371!
1372!-----------------------------------------------------------------------
1373! If applicable, process input data: time interpolate between data
1374! snapshots.
1375!-----------------------------------------------------------------------
1376!
1377 DO ng=1,ngrids
1378 DO tile=first_tile(ng),last_tile(ng),+1
1379 CALL tl_set_data (ng, tile)
1380 END DO
1381 END DO
1382 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1383!
1384!-----------------------------------------------------------------------
1385! Computes the initial depths and level thicknesses from the initial
1386! time-averaged free-surface field, Zt_avg1. Additionally, it
1387! initializes the nonlinear state variables for all time levels and
1388! applies lateral boundary conditions.
1389!-----------------------------------------------------------------------
1390!
1391 DO ng=1,ngrids
1392 CALL tl_post_initial (ng, itlm)
1393 END DO
1394 IF (founderror(exit_flag, noerror, __line__, myfile)) RETURN
1395
1396 END IF phase3
1397
1398# ifdef PROFILE
1399!
1400!-----------------------------------------------------------------------
1401! Turn off initialization time wall clock.
1402!-----------------------------------------------------------------------
1403!
1404 DO ng=1,ngrids
1405 DO thread=thread_range
1406 CALL wclock_off (ng, itlm, 2, __line__, myfile)
1407 END DO
1408 END DO
1409# endif
1410!
1411 10 FORMAT (/,1x,a,a,/,1x,'***********',/)
1412!
1413 RETURN
subroutine tl_get_data(ng)
Definition tl_get_data.F:4
subroutine tl_get_idata(ng)
Definition tl_get_idata.F:4
subroutine tl_set_data(ng, tile)
Definition tl_set_data.F:4

References analytical_mod::ana_drag(), analytical_mod::ana_sponge(), mod_scalars::avgke, mod_scalars::avgkp, mod_scalars::avgpe, check_multifile(), close_io_mod::close_inp(), mod_scalars::day2sec, mod_scalars::dstart, mod_scalars::dt, edit_multifile(), mod_scalars::erstr, mod_scalars::exit_flag, mod_parallel::first_tile, mod_scalars::first_time, strings_mod::founderror(), grid_coords(), mod_scalars::iic, mod_scalars::iif, mod_scalars::indx1, ini_hmixcoef_mod::ini_hmixcoef(), mod_scalars::initime, mod_param::itlm, mod_scalars::jic, mod_stepping::knew, mod_stepping::krhs, mod_stepping::kstp, mod_parallel::last_tile, mod_scalars::ldeftlm, mod_scalars::lreadblk, mod_scalars::lreadfrc, mod_scalars::lreadqck, mod_scalars::lsponge, mod_scalars::lstiffness, mod_scalars::lwrttlm, mod_parallel::master, mod_stepping::nf, mod_stepping::nfm1, mod_stepping::nfm2, mod_stepping::nfm3, mod_stepping::nfp1, mod_param::ngrids, mod_stepping::nnew, mod_scalars::noerror, mod_stepping::nrhs, mod_scalars::nrrec, mod_scalars::nrun, mod_stepping::nstp, mod_scalars::ntend, mod_scalars::ntfirst, mod_scalars::ntimes, mod_scalars::ntstart, mod_scalars::predictor_2d_step, mod_iounits::qck, set_masks_mod::set_masks(), mod_iounits::stdout, stiffness_mod::stiffness(), mod_scalars::synchro_flag, mod_scalars::tdays, mod_scalars::time, mod_scalars::time4jedi, mod_scalars::time_code, dateclock_mod::time_string(), tl_set_depth_mod::tl_bath(), tl_get_data(), tl_get_idata(), tl_post_initial_mod::tl_post_initial(), tl_set_data(), mod_scalars::tl_ubar_xs, mod_scalars::tl_volcons, mod_scalars::volume, wclock_off(), wclock_on(), and wetdry_mod::wetdry().

Referenced by roms_initializep1(), roms_initializep2(), and roms_initializep3().

Here is the call graph for this function:
Here is the caller graph for this function: