LCOV - code coverage report
Current view: top level - physics/cam - nudging.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 154 843 18.3 %
Date: 2025-01-13 21:54:50 Functions: 1 9 11.1 %

          Line data    Source code
       1             : module nudging
       2             : !=====================================================================
       3             : !
       4             : ! Purpose: Implement Nudging of the model state of U,V,T,Q, and/or PS
       5             : !          toward specified values from analyses.
       6             : !
       7             : ! Author: Patrick Callaghan
       8             : !
       9             : ! Description:
      10             : !
      11             : !    This module assumes that the user has {U,V,T,Q,PS} values from analyses
      12             : !    which have been preprocessed onto the current model grid and adjusted
      13             : !    for differences in topography. It is also assumed that these resulting
      14             : !    values and are stored in individual files which are indexed with respect
      15             : !    to year, month, day, and second of the day. When the model is inbetween
      16             : !    the given begining and ending times, a relaxation forcing is added to
      17             : !    nudge the model toward the analyses values determined from the forcing
      18             : !    option specified. After the model passes the ending analyses time, the
      19             : !    forcing discontinues.
      20             : !
      21             : !    Some analyses products can have gaps in the available data, where values
      22             : !    are missing for some interval of time. When files are missing, the nudging
      23             : !    force is switched off for that interval of time, so we effectively 'coast'
      24             : !    thru the gap.
      25             : !
      26             : !    Currently, the nudging module is set up to accomodate nudging of PS
      27             : !    values, however that functionality requires forcing that is applied in
      28             : !    the selected dycore and is not yet implemented.
      29             : !
      30             : !    The nudging of the model toward the analyses data is controlled by
      31             : !    the 'nudging_nl' namelist in 'user_nl_cam'; whose variables control the
      32             : !    time interval over which nudging is applied, the strength of the nudging
      33             : !    tendencies, and its spatial distribution.
      34             : !
      35             : !    FORCING:
      36             : !    --------
      37             : !    Nudging tendencies are applied as a relaxation force between the current
      38             : !    model state values and target state values derived from the avalilable
      39             : !    analyses. The form of the target values is selected by the 'Nudge_Force_Opt'
      40             : !    option, the timescale of the forcing is determined from the given
      41             : !    'Nudge_TimeScale_Opt', and the nudging strength Alpha=[0.,1.] for each
      42             : !    variable is specified by the 'Nudge_Xcoef' values. Where X={U,V,T,Q,PS}
      43             : !
      44             : !           F_nudge = Alpha*((Target-Model(t_curr))/TimeScale
      45             : !
      46             : !
      47             : !    WINDOWING:
      48             : !    ----------
      49             : !    The region of applied nudging can be limited using Horizontal/Vertical
      50             : !    window functions that are constructed using a parameterization of the
      51             : !    Heaviside step function.
      52             : !
      53             : !    The Heaviside window function is the product of separate horizonal and vertical
      54             : !    windows that are controled via 12 parameters:
      55             : !
      56             : !        Nudge_Hwin_lat0:     Specify the horizontal center of the window in degrees.
      57             : !        Nudge_Hwin_lon0:     The longitude must be in the range [0,360] and the
      58             : !                             latitude should be [-90,+90].
      59             : !        Nudge_Hwin_latWidth: Specify the lat and lon widths of the window as positive
      60             : !        Nudge_Hwin_lonWidth: values in degrees.Setting a width to a large value (e.g. 999)
      61             : !                             renders the window a constant in that direction.
      62             : !        Nudge_Hwin_latDelta: Controls the sharpness of the window transition with a
      63             : !        Nudge_Hwin_lonDelta: length in degrees. Small non-zero values yeild a step
      64             : !                             function while a large value yeilds a smoother transition.
      65             : !        Nudge_Hwin_Invert  : A logical flag used to invert the horizontal window function
      66             : !                             to get its compliment.(e.g. to nudge outside a given window).
      67             : !
      68             : !        Nudge_Vwin_Lindex:   In the vertical, the window is specified in terms of model
      69             : !        Nudge_Vwin_Ldelta:   level indcies. The High and Low transition levels should
      70             : !        Nudge_Vwin_Hindex:   range from [0,(NLEV+1)]. The transition lengths are also
      71             : !        Nudge_Vwin_Hdelta:   specified in terms of model indices. For a window function
      72             : !                             constant in the vertical, the Low index should be set to 0,
      73             : !                             the High index should be set to (NLEV+1), and the transition
      74             : !                             lengths should be set to 0.001
      75             : !        Nudge_Vwin_Invert  : A logical flag used to invert the vertical window function
      76             : !                             to get its compliment.
      77             : !
      78             : !        EXAMPLE: For a channel window function centered at the equator and independent
      79             : !                 of the vertical (30 levels):
      80             : !                        Nudge_Hwin_lat0     = 0.         Nudge_Vwin_Lindex = 0.
      81             : !                        Nudge_Hwin_latWidth = 30.        Nudge_Vwin_Ldelta = 0.001
      82             : !                        Nudge_Hwin_latDelta = 5.0        Nudge_Vwin_Hindex = 31.
      83             : !                        Nudge_Hwin_lon0     = 180.       Nudge_Vwin_Hdelta = 0.001
      84             : !                        Nudge_Hwin_lonWidth = 999.       Nudge_Vwin_Invert = .false.
      85             : !                        Nudge_Hwin_lonDelta = 1.0
      86             : !                        Nudge_Hwin_Invert   = .false.
      87             : !
      88             : !                 If on the other hand one wanted to apply nudging at the poles and
      89             : !                 not at the equator, the settings would be similar but with:
      90             : !                        Nudge_Hwin_Invert = .true.
      91             : !
      92             : !    A user can preview the window resulting from a given set of namelist values before
      93             : !    running the model. Lookat_NudgeWindow.ncl is a script avalable in the tools directory
      94             : !    which will read in the values for a given namelist and display the resulting window.
      95             : !
      96             : !    The module is currently configured for only 1 window function. It can readily be
      97             : !    extended for multiple windows if the need arises.
      98             : !
      99             : !
     100             : ! Input/Output Values:
     101             : !    Forcing contributions are available for history file output by
     102             : !    the names:    {'Nudge_U','Nudge_V','Nudge_T',and 'Nudge_Q'}
     103             : !    The target values that the model state is nudged toward are available for history
     104             : !    file output via the variables:  {'Target_U','Target_V','Target_T',and 'Target_Q'}
     105             : !
     106             : !    &nudging_nl
     107             : !      Nudge_Model         - LOGICAL toggle to activate nudging.
     108             : !                              TRUE  -> Nudging is on.
     109             : !                              FALSE -> Nudging is off.                            [DEFAULT]
     110             : !
     111             : !      Nudge_Path          - CHAR path to the analyses files.
     112             : !                              (e.g. '/glade/scratch/USER/inputdata/nudging/ERAI-Data/')
     113             : !
     114             : !      Nudge_File_Template - CHAR Analyses filename with year, month, day, and second
     115             : !                                 values replaced by %y, %m, %d, and %s respectively.
     116             : !                              (e.g. '%y/ERAI_ne30np4_L30.cam2.i.%y-%m-%d-%s.nc')
     117             : !
     118             : !      Nudge_Times_Per_Day - INT Number of analyses files available per day.
     119             : !                              1 --> daily analyses.
     120             : !                              4 --> 6 hourly analyses.
     121             : !                              8 --> 3 hourly.
     122             : !
     123             : !      Model_Times_Per_Day - INT Number of times to update the model state (used for nudging)
     124             : !                                each day. The value is restricted to be longer than the
     125             : !                                current model timestep and shorter than the analyses
     126             : !                                timestep. As this number is increased, the nudging
     127             : !                                force has the form of newtonian cooling.
     128             : !                              48 --> 1800 Second timestep.
     129             : !                              96 -->  900 Second timestep.
     130             : !
     131             : !      Nudge_Beg_Year      - INT nudging begining year.  [1979- ]
     132             : !      Nudge_Beg_Month     - INT nudging begining month. [1-12]
     133             : !      Nudge_Beg_Day       - INT nudging begining day.   [1-31]
     134             : !      Nudge_End_Year      - INT nudging ending year.    [1979-]
     135             : !      Nudge_End_Month     - INT nudging ending month.   [1-12]
     136             : !      Nudge_End_Day       - INT nudging ending day.     [1-31]
     137             : !
     138             : !      Nudge_Force_Opt     - INT Index to select the nudging Target for a relaxation
     139             : !                                forcing of the form:
     140             : !                                where (t'==Analysis times ; t==Model Times)
     141             : !
     142             : !                              0 -> NEXT-OBS: Target=Anal(t'_next)                 [DEFAULT]
     143             : !                              1 -> LINEAR:   Target=(F*Anal(t'_curr) +(1-F)*Anal(t'_next))
     144             : !                                                 F =(t'_next - t_curr )/Tdlt_Anal
     145             : !
     146             : !      Nudge_TimeScale_Opt - INT Index to select the timescale for nudging.
     147             : !                                where (t'==Analysis times ; t==Model Times)
     148             : !
     149             : !                              0 -->  TimeScale = 1/Tdlt_Anal                      [DEFAULT]
     150             : !                              1 -->  TimeScale = 1/(t'_next - t_curr )
     151             : !
     152             : !      Nudge_Uprof         - INT index of profile structure to use for U.  [0,1,2]
     153             : !      Nudge_Vprof         - INT index of profile structure to use for V.  [0,1,2]
     154             : !      Nudge_Tprof         - INT index of profile structure to use for T.  [0,1,2]
     155             : !      Nudge_Qprof         - INT index of profile structure to use for Q.  [0,1,2]
     156             : !      Nudge_PSprof        - INT index of profile structure to use for PS. [0,N/A]
     157             : !
     158             : !                                The spatial distribution is specified with a profile index.
     159             : !                                 Where:  0 == OFF      (No Nudging of this variable)
     160             : !                                         1 == CONSTANT (Spatially Uniform Nudging)
     161             : !                                         2 == HEAVISIDE WINDOW FUNCTION
     162             : !
     163             : !      Nudge_Ucoef         - REAL fractional nudging coeffcient for U.
     164             : !      Nudge_Vcoef         - REAL fractional nudging coeffcient for V.
     165             : !      Nudge_Tcoef         - REAL fractional nudging coeffcient for T.
     166             : !      Nudge_Qcoef         - REAL fractional nudging coeffcient for Q.
     167             : !      Nudge_PScoef        - REAL fractional nudging coeffcient for PS.
     168             : !
     169             : !                                 The strength of the nudging is specified as a fractional
     170             : !                                 coeffcient between [0,1].
     171             : !
     172             : !      Nudge_Hwin_lat0     - REAL latitudinal center of window in degrees.
     173             : !      Nudge_Hwin_lon0     - REAL longitudinal center of window in degrees.
     174             : !      Nudge_Hwin_latWidth - REAL latitudinal width of window in degrees.
     175             : !      Nudge_Hwin_lonWidth - REAL longitudinal width of window in degrees.
     176             : !      Nudge_Hwin_latDelta - REAL latitudinal transition length of window in degrees.
     177             : !      Nudge_Hwin_lonDelta - REAL longitudinal transition length of window in degrees.
     178             : !      Nudge_Hwin_Invert   - LOGICAL FALSE= value=1 inside the specified window, 0 outside
     179             : !                                    TRUE = value=0 inside the specified window, 1 outside
     180             : !      Nudge_Vwin_Lindex   - REAL LO model index of transition
     181             : !      Nudge_Vwin_Hindex   - REAL HI model index of transition
     182             : !      Nudge_Vwin_Ldelta   - REAL LO transition length
     183             : !      Nudge_Vwin_Hdelta   - REAL HI transition length
     184             : !      Nudge_Vwin_Invert   - LOGICAL FALSE= value=1 inside the specified window, 0 outside
     185             : !                                    TRUE = value=0 inside the specified window, 1 outside
     186             : !    /
     187             : !
     188             : !================
     189             : !
     190             : ! TO DO:
     191             : ! -----------
     192             : !    ** Implement Ps Nudging????
     193             : !
     194             : !=====================================================================
     195             :   ! Useful modules
     196             :   !------------------
     197             :   use shr_kind_mod,   only: r8=>SHR_KIND_R8, cs=>SHR_KIND_CS, cl=>SHR_KIND_CL
     198             :   use time_manager,   only: timemgr_time_ge, timemgr_time_inc, get_curr_date
     199             :   use time_manager,   only: get_step_size
     200             :   use cam_abortutils, only: endrun
     201             :   use spmd_utils,     only: masterproc, mstrid=>masterprocid, mpicom, mpi_success
     202             :   use spmd_utils,     only: mpi_integer, mpi_real8, mpi_logical, mpi_character
     203             :   use cam_logfile,    only: iulog
     204             :   use zonal_mean_mod, only: ZonalMean_t
     205             : 
     206             :   ! Set all Global values and routines to private by default
     207             :   ! and then explicitly set their exposure.
     208             :   !----------------------------------------------------------
     209             :   implicit none
     210             :   private
     211             : 
     212             :   public  :: Nudge_Model,Nudge_ON
     213             :   public  :: nudging_readnl
     214             :   public  :: nudging_init
     215             :   public  :: nudging_timestep_init
     216             :   public  :: nudging_timestep_tend
     217             :   private :: nudging_update_analyses
     218             :   private :: nudging_set_PSprofile
     219             :   private :: nudging_set_profile
     220             :   private :: calc_DryStaticEnergy
     221             :   public  :: nudging_final
     222             : 
     223             :   ! Nudging Parameters
     224             :   !--------------------
     225             :   logical           :: Nudge_Model       =.false.
     226             :   logical           :: Nudge_ON          =.false.
     227             :   logical           :: Nudge_Initialized =.false.
     228             :   character(len=cl) :: Nudge_Path
     229             :   character(len=cs) :: Nudge_File,Nudge_File_Template
     230             :   integer           :: Nudge_Force_Opt
     231             :   integer           :: Nudge_TimeScale_Opt
     232             :   integer           :: Nudge_TSmode
     233             :   integer           :: Nudge_Times_Per_Day
     234             :   integer           :: Model_Times_Per_Day
     235             :   real(r8)          :: Nudge_Ucoef,Nudge_Vcoef
     236             :   integer           :: Nudge_Uprof,Nudge_Vprof
     237             :   real(r8)          :: Nudge_Qcoef,Nudge_Tcoef
     238             :   integer           :: Nudge_Qprof,Nudge_Tprof
     239             :   real(r8)          :: Nudge_PScoef
     240             :   integer           :: Nudge_PSprof
     241             :   integer           :: Nudge_Beg_Year ,Nudge_Beg_Month
     242             :   integer           :: Nudge_Beg_Day  ,Nudge_Beg_Sec
     243             :   integer           :: Nudge_End_Year ,Nudge_End_Month
     244             :   integer           :: Nudge_End_Day  ,Nudge_End_Sec
     245             :   integer           :: Nudge_Curr_Year,Nudge_Curr_Month
     246             :   integer           :: Nudge_Curr_Day ,Nudge_Curr_Sec
     247             :   integer           :: Nudge_Next_Year,Nudge_Next_Month
     248             :   integer           :: Nudge_Next_Day ,Nudge_Next_Sec
     249             :   integer           :: Nudge_Step
     250             :   integer           :: Model_Curr_Year,Model_Curr_Month
     251             :   integer           :: Model_Curr_Day ,Model_Curr_Sec
     252             :   integer           :: Model_Next_Year,Model_Next_Month
     253             :   integer           :: Model_Next_Day ,Model_Next_Sec
     254             :   integer           :: Model_Step
     255             :   real(r8)          :: Nudge_Hwin_lat0
     256             :   real(r8)          :: Nudge_Hwin_latWidth
     257             :   real(r8)          :: Nudge_Hwin_latDelta
     258             :   real(r8)          :: Nudge_Hwin_lon0
     259             :   real(r8)          :: Nudge_Hwin_lonWidth
     260             :   real(r8)          :: Nudge_Hwin_lonDelta
     261             :   logical           :: Nudge_Hwin_Invert = .false.
     262             :   real(r8)          :: Nudge_Hwin_lo
     263             :   real(r8)          :: Nudge_Hwin_hi
     264             :   real(r8)          :: Nudge_Vwin_Hindex
     265             :   real(r8)          :: Nudge_Vwin_Hdelta
     266             :   real(r8)          :: Nudge_Vwin_Lindex
     267             :   real(r8)          :: Nudge_Vwin_Ldelta
     268             :   logical           :: Nudge_Vwin_Invert =.false.
     269             :   real(r8)          :: Nudge_Vwin_lo
     270             :   real(r8)          :: Nudge_Vwin_hi
     271             :   real(r8)          :: Nudge_Hwin_latWidthH
     272             :   real(r8)          :: Nudge_Hwin_lonWidthH
     273             :   real(r8)          :: Nudge_Hwin_max
     274             :   real(r8)          :: Nudge_Hwin_min
     275             : 
     276             :   ! Nudging Zonal Filter variables
     277             :   !---------------------------------
     278             :   logical             :: Nudge_ZonalFilter =.false.
     279             :   integer             :: Nudge_ZonalNbasis = -1
     280             :   type(ZonalMean_t)   :: ZM
     281             :   real(r8),allocatable:: Zonal_Bamp2d(:)
     282             :   real(r8),allocatable:: Zonal_Bamp3d(:,:)
     283             : 
     284             :   ! Nudging State Arrays
     285             :   !-----------------------
     286             :   integer :: Nudge_nlon,Nudge_nlat,Nudge_ncol,Nudge_nlev
     287             :   real(r8),allocatable:: Target_U    (:,:,:)  !(pcols,pver,begchunk:endchunk)
     288             :   real(r8),allocatable:: Target_V    (:,:,:)  !(pcols,pver,begchunk:endchunk)
     289             :   real(r8),allocatable:: Target_T    (:,:,:)  !(pcols,pver,begchunk:endchunk)
     290             :   real(r8),allocatable:: Target_S    (:,:,:)  !(pcols,pver,begchunk:endchunk)
     291             :   real(r8),allocatable:: Target_Q    (:,:,:)  !(pcols,pver,begchunk:endchunk)
     292             :   real(r8),allocatable:: Target_PS   (:,:)    !(pcols,begchunk:endchunk)
     293             :   real(r8),allocatable:: Model_U     (:,:,:)  !(pcols,pver,begchunk:endchunk)
     294             :   real(r8),allocatable:: Model_V     (:,:,:)  !(pcols,pver,begchunk:endchunk)
     295             :   real(r8),allocatable:: Model_T     (:,:,:)  !(pcols,pver,begchunk:endchunk)
     296             :   real(r8),allocatable:: Model_S     (:,:,:)  !(pcols,pver,begchunk:endchunk)
     297             :   real(r8),allocatable:: Model_Q     (:,:,:)  !(pcols,pver,begchunk:endchunk)
     298             :   real(r8),allocatable:: Model_PS    (:,:)    !(pcols,begchunk:endchunk)
     299             :   real(r8),allocatable:: Nudge_Utau  (:,:,:)  !(pcols,pver,begchunk:endchunk)
     300             :   real(r8),allocatable:: Nudge_Vtau  (:,:,:)  !(pcols,pver,begchunk:endchunk)
     301             :   real(r8),allocatable:: Nudge_Stau  (:,:,:)  !(pcols,pver,begchunk:endchunk)
     302             :   real(r8),allocatable:: Nudge_Qtau  (:,:,:)  !(pcols,pver,begchunk:endchunk)
     303             :   real(r8),allocatable:: Nudge_PStau (:,:)    !(pcols,begchunk:endchunk)
     304             :   real(r8),allocatable:: Nudge_Ustep (:,:,:)  !(pcols,pver,begchunk:endchunk)
     305             :   real(r8),allocatable:: Nudge_Vstep (:,:,:)  !(pcols,pver,begchunk:endchunk)
     306             :   real(r8),allocatable:: Nudge_Sstep (:,:,:)  !(pcols,pver,begchunk:endchunk)
     307             :   real(r8),allocatable:: Nudge_Qstep (:,:,:)  !(pcols,pver,begchunk:endchunk)
     308             :   real(r8),allocatable:: Nudge_PSstep(:,:)    !(pcols,begchunk:endchunk)
     309             : 
     310             :   ! Nudging Observation Arrays
     311             :   !-----------------------------
     312             :   integer :: Nudge_NumObs
     313             :   integer,allocatable:: Nudge_ObsInd(:)
     314             :   logical ,allocatable::Nudge_File_Present(:)
     315             :   real(r8),allocatable::Nobs_U (:,:,:,:) !(pcols,pver,begchunk:endchunk,Nudge_NumObs)
     316             :   real(r8),allocatable::Nobs_V (:,:,:,:) !(pcols,pver,begchunk:endchunk,Nudge_NumObs)
     317             :   real(r8),allocatable::Nobs_T (:,:,:,:) !(pcols,pver,begchunk:endchunk,Nudge_NumObs)
     318             :   real(r8),allocatable::Nobs_Q (:,:,:,:) !(pcols,pver,begchunk:endchunk,Nudge_NumObs)
     319             :   real(r8),allocatable::Nobs_PS(:,:,:)   !(pcols,begchunk:endchunk,Nudge_NumObs)
     320             : 
     321             : contains
     322             :   !================================================================
     323        1536 :   subroutine nudging_readnl(nlfile)
     324             :    !
     325             :    ! NUDGING_READNL: Initialize default values controlling the Nudging
     326             :    !                 process. Then read namelist values to override
     327             :    !                 them.
     328             :    !===============================================================
     329             :    use ppgrid,         only: pver
     330             :    use namelist_utils, only:find_group_name
     331             :    !
     332             :    ! Arguments
     333             :    !-------------
     334             :    character(len=*), intent(in) :: nlfile
     335             :    !
     336             :    ! Local Values
     337             :    !---------------
     338             :    integer :: ierr, unitn
     339             : 
     340             :    character(len=*), parameter :: prefix = 'nudging_readnl: '
     341             : 
     342             :    namelist /nudging_nl/ Nudge_Model, Nudge_Path,                             &
     343             :                          Nudge_File_Template, Nudge_Force_Opt,                &
     344             :                          Nudge_TimeScale_Opt,                                 &
     345             :                          Nudge_Times_Per_Day, Model_Times_Per_Day,            &
     346             :                          Nudge_Ucoef , Nudge_Uprof,                           &
     347             :                          Nudge_Vcoef , Nudge_Vprof,                           &
     348             :                          Nudge_Qcoef , Nudge_Qprof,                           &
     349             :                          Nudge_Tcoef , Nudge_Tprof,                           &
     350             :                          Nudge_PScoef, Nudge_PSprof,                          &
     351             :                          Nudge_Beg_Year, Nudge_Beg_Month, Nudge_Beg_Day,      &
     352             :                          Nudge_End_Year, Nudge_End_Month, Nudge_End_Day,      &
     353             :                          Nudge_Hwin_lat0, Nudge_Hwin_lon0,                    &
     354             :                          Nudge_Hwin_latWidth, Nudge_Hwin_lonWidth,            &
     355             :                          Nudge_Hwin_latDelta, Nudge_Hwin_lonDelta,            &
     356             :                          Nudge_Hwin_Invert,                                   &
     357             :                          Nudge_Vwin_Lindex, Nudge_Vwin_Hindex,                &
     358             :                          Nudge_Vwin_Ldelta, Nudge_Vwin_Hdelta,                &
     359             :                          Nudge_Vwin_Invert
     360             : 
     361             :    ! For Zonal Mean Filtering
     362             :    namelist /nudging_nl/ Nudge_ZonalFilter, Nudge_ZonalNbasis
     363             : 
     364             :    ! Nudging is NOT initialized yet, For now
     365             :    ! Nudging will always begin/end at midnight.
     366             :    !--------------------------------------------
     367        1536 :    Nudge_Initialized =.false.
     368        1536 :    Nudge_ON          =.false.
     369        1536 :    Nudge_Beg_Sec=0
     370        1536 :    Nudge_End_Sec=0
     371             : 
     372             :    ! Set Default Namelist values
     373             :    !-----------------------------
     374        1536 :    Nudge_Model         = .false.
     375        1536 :    Nudge_Path          = './Data/YOTC_ne30np4_001/'
     376        1536 :    Nudge_File_Template = 'YOTC_ne30np4_L30.cam2.i.%y-%m-%d-%s.nc'
     377        1536 :    Nudge_Force_Opt     = 0
     378        1536 :    Nudge_TimeScale_Opt = 0
     379        1536 :    Nudge_TSmode        = 0
     380        1536 :    Nudge_Times_Per_Day = 4
     381        1536 :    Model_Times_Per_Day = 4
     382        1536 :    Nudge_Ucoef         = 0._r8
     383        1536 :    Nudge_Vcoef         = 0._r8
     384        1536 :    Nudge_Qcoef         = 0._r8
     385        1536 :    Nudge_Tcoef         = 0._r8
     386        1536 :    Nudge_PScoef        = 0._r8
     387        1536 :    Nudge_Uprof         = 0
     388        1536 :    Nudge_Vprof         = 0
     389        1536 :    Nudge_Qprof         = 0
     390        1536 :    Nudge_Tprof         = 0
     391        1536 :    Nudge_PSprof        = 0
     392        1536 :    Nudge_Beg_Year      = 2008
     393        1536 :    Nudge_Beg_Month     = 5
     394        1536 :    Nudge_Beg_Day       = 1
     395        1536 :    Nudge_End_Year      = 2008
     396        1536 :    Nudge_End_Month     = 9
     397        1536 :    Nudge_End_Day       = 1
     398        1536 :    Nudge_Hwin_lat0     = 0._r8
     399        1536 :    Nudge_Hwin_latWidth = 9999._r8
     400        1536 :    Nudge_Hwin_latDelta = 1.0_r8
     401        1536 :    Nudge_Hwin_lon0     = 180._r8
     402        1536 :    Nudge_Hwin_lonWidth = 9999._r8
     403        1536 :    Nudge_Hwin_lonDelta = 1.0_r8
     404        1536 :    Nudge_Hwin_Invert   = .false.
     405        1536 :    Nudge_Hwin_lo       = 0.0_r8
     406        1536 :    Nudge_Hwin_hi       = 1.0_r8
     407        1536 :    Nudge_Vwin_Hindex   = float(pver+1)
     408        1536 :    Nudge_Vwin_Hdelta   = 0.001_r8
     409        1536 :    Nudge_Vwin_Lindex   = 0.0_r8
     410        1536 :    Nudge_Vwin_Ldelta   = 0.001_r8
     411        1536 :    Nudge_Vwin_Invert   = .false.
     412        1536 :    Nudge_Vwin_lo       = 0.0_r8
     413        1536 :    Nudge_Vwin_hi       = 1.0_r8
     414             : 
     415             :    ! Read in namelist values
     416             :    !------------------------
     417        1536 :    if(masterproc) then
     418           2 :       open(newunit=unitn, file=trim(nlfile), status='old')
     419           2 :       call find_group_name(unitn, 'nudging_nl', status=ierr)
     420           2 :       if(ierr == 0) then
     421           0 :          read(unitn,nudging_nl,iostat=ierr)
     422           0 :          if(ierr /= 0) then
     423           0 :             call endrun('nudging_readnl:: ERROR reading namelist')
     424             :          end if
     425             :       end if
     426           2 :       close(unitn)
     427             :    end if
     428             : 
     429             :    ! Set hi/lo values according to the given '_Invert' parameters
     430             :    !--------------------------------------------------------------
     431        1536 :    if(Nudge_Hwin_Invert) then
     432           0 :       Nudge_Hwin_lo = 1.0_r8
     433           0 :       Nudge_Hwin_hi = 0.0_r8
     434             :    else
     435        1536 :       Nudge_Hwin_lo = 0.0_r8
     436        1536 :       Nudge_Hwin_hi = 1.0_r8
     437             :    end if
     438             : 
     439        1536 :    if(Nudge_Vwin_Invert) then
     440           0 :       Nudge_Vwin_lo = 1.0_r8
     441           0 :       Nudge_Vwin_hi = 0.0_r8
     442             :    else
     443        1536 :       Nudge_Vwin_lo = 0.0_r8
     444        1536 :       Nudge_Vwin_hi = 1.0_r8
     445             :    end if
     446             : 
     447             :    ! Check for valid namelist values
     448             :    !----------------------------------
     449        1536 :    if((Nudge_Hwin_lat0 < -90._r8) .or. (Nudge_Hwin_lat0 > +90._r8)) then
     450           0 :      write(iulog,*) 'NUDGING: Window lat0 must be in [-90,+90]'
     451           0 :      write(iulog,*) 'NUDGING:  Nudge_Hwin_lat0=',Nudge_Hwin_lat0
     452           0 :      call endrun('nudging_readnl:: ERROR in namelist')
     453             :    endif
     454             : 
     455        1536 :    if((Nudge_Hwin_lon0 < 0._r8) .or. (Nudge_Hwin_lon0 >= 360._r8)) then
     456           0 :      write(iulog,*) 'NUDGING: Window lon0 must be in [0,+360)'
     457           0 :      write(iulog,*) 'NUDGING:  Nudge_Hwin_lon0=',Nudge_Hwin_lon0
     458           0 :      call endrun('nudging_readnl:: ERROR in namelist')
     459             :    endif
     460             : 
     461             :    if((Nudge_Vwin_Lindex > Nudge_Vwin_Hindex)                          .or.   &
     462             :       (Nudge_Vwin_Hindex > float(pver+1)) .or. (Nudge_Vwin_Hindex < 0._r8) .or.  &
     463        1536 :       (Nudge_Vwin_Lindex > float(pver+1)) .or. (Nudge_Vwin_Lindex < 0._r8)   ) then
     464           0 :      write(iulog,*) 'NUDGING: Window Lindex must be in [0,pver+1]'
     465           0 :      write(iulog,*) 'NUDGING: Window Hindex must be in [0,pver+1]'
     466           0 :      write(iulog,*) 'NUDGING: Lindex must be LE than Hindex'
     467           0 :      write(iulog,*) 'NUDGING:  Nudge_Vwin_Lindex=',Nudge_Vwin_Lindex
     468           0 :      write(iulog,*) 'NUDGING:  Nudge_Vwin_Hindex=',Nudge_Vwin_Hindex
     469           0 :      call endrun('nudging_readnl:: ERROR in namelist')
     470             :    endif
     471             : 
     472             :    if((Nudge_Hwin_latDelta <= 0._r8) .or. (Nudge_Hwin_lonDelta <= 0._r8) .or. &
     473        1536 :       (Nudge_Vwin_Hdelta <= 0._r8) .or. (Nudge_Vwin_Ldelta <= 0._r8)    ) then
     474           0 :      write(iulog,*) 'NUDGING: Window Deltas must be positive'
     475           0 :      write(iulog,*) 'NUDGING:  Nudge_Hwin_latDelta=',Nudge_Hwin_latDelta
     476           0 :      write(iulog,*) 'NUDGING:  Nudge_Hwin_lonDelta=',Nudge_Hwin_lonDelta
     477           0 :      write(iulog,*) 'NUDGING:  Nudge_Vwin_Hdelta=',Nudge_Vwin_Hdelta
     478           0 :      write(iulog,*) 'NUDGING:  Nudge_Vwin_Ldelta=',Nudge_Vwin_Ldelta
     479           0 :      call endrun('nudging_readnl:: ERROR in namelist')
     480             : 
     481             :    endif
     482             : 
     483        1536 :    if((Nudge_Hwin_latWidth <= 0._r8) .or. (Nudge_Hwin_lonWidth <= 0._r8)) then
     484           0 :      write(iulog,*) 'NUDGING: Window widths must be positive'
     485           0 :      write(iulog,*) 'NUDGING:  Nudge_Hwin_latWidth=',Nudge_Hwin_latWidth
     486           0 :      write(iulog,*) 'NUDGING:  Nudge_Hwin_lonWidth=',Nudge_Hwin_lonWidth
     487           0 :      call endrun('nudging_readnl:: ERROR in namelist')
     488             :    endif
     489             : 
     490             :    ! Broadcast namelist variables
     491             :    !------------------------------
     492             :    call MPI_bcast(Nudge_Path         , len(Nudge_Path),                       &
     493        1536 :         mpi_character, mstrid, mpicom, ierr)
     494        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Path ')
     495             :    call MPI_bcast(Nudge_File_Template,len(Nudge_File_Template),               &
     496        1536 :         mpi_character, mstrid, mpicom, ierr)
     497        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_File_Template')
     498        1536 :    call MPI_bcast(Nudge_Model        , 1, mpi_logical, mstrid, mpicom, ierr)
     499        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Model')
     500        1536 :    call MPI_bcast(Nudge_Initialized  , 1, mpi_logical, mstrid, mpicom, ierr)
     501        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Initialized')
     502        1536 :    call MPI_bcast(Nudge_ON           , 1, mpi_logical, mstrid, mpicom, ierr)
     503        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_ON')
     504        1536 :    call MPI_bcast(Nudge_Force_Opt    , 1, mpi_integer, mstrid, mpicom, ierr)
     505        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Force_Opt')
     506        1536 :    call MPI_bcast(Nudge_TimeScale_Opt, 1, mpi_integer, mstrid, mpicom, ierr)
     507        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_TimeScale_Opt')
     508        1536 :    call MPI_bcast(Nudge_TSmode       , 1, mpi_integer, mstrid, mpicom, ierr)
     509        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_TSmode')
     510        1536 :    call MPI_bcast(Nudge_Times_Per_Day, 1, mpi_integer, mstrid, mpicom, ierr)
     511        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Times_Per_Day')
     512        1536 :    call MPI_bcast(Model_Times_Per_Day, 1, mpi_integer, mstrid, mpicom, ierr)
     513        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Model_Times_Per_Day')
     514        1536 :    call MPI_bcast(Nudge_Ucoef        , 1, mpi_real8 ,  mstrid, mpicom, ierr)
     515        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Ucoef')
     516        1536 :    call MPI_bcast(Nudge_Vcoef        , 1, mpi_real8 ,  mstrid, mpicom, ierr)
     517        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Vcoef')
     518        1536 :    call MPI_bcast(Nudge_Tcoef        , 1, mpi_real8 ,  mstrid, mpicom, ierr)
     519        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Tcoef')
     520        1536 :    call MPI_bcast(Nudge_Qcoef        , 1, mpi_real8 ,  mstrid, mpicom, ierr)
     521        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Qcoef')
     522        1536 :    call MPI_bcast(Nudge_PScoef       , 1, mpi_real8 ,  mstrid, mpicom, ierr)
     523        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_PScoef')
     524        1536 :    call MPI_bcast(Nudge_Uprof        , 1, mpi_integer, mstrid, mpicom, ierr)
     525        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Uprof')
     526        1536 :    call MPI_bcast(Nudge_Vprof        , 1, mpi_integer, mstrid, mpicom, ierr)
     527        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Vprof')
     528        1536 :    call MPI_bcast(Nudge_Tprof        , 1, mpi_integer, mstrid, mpicom, ierr)
     529        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Tprof')
     530        1536 :    call MPI_bcast(Nudge_Qprof        , 1, mpi_integer, mstrid, mpicom, ierr)
     531        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Qprof')
     532        1536 :    call MPI_bcast(Nudge_PSprof       , 1, mpi_integer, mstrid, mpicom, ierr)
     533        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_PSprof')
     534        1536 :    call MPI_bcast(Nudge_Beg_Year     , 1, mpi_integer, mstrid, mpicom, ierr)
     535        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Beg_Year')
     536        1536 :    call MPI_bcast(Nudge_Beg_Month    , 1, mpi_integer, mstrid, mpicom, ierr)
     537        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Beg_Month')
     538        1536 :    call MPI_bcast(Nudge_Beg_Day      , 1, mpi_integer, mstrid, mpicom, ierr)
     539        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Beg_Day')
     540        1536 :    call MPI_bcast(Nudge_Beg_Sec      , 1, mpi_integer, mstrid, mpicom, ierr)
     541        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Beg_Sec')
     542        1536 :    call MPI_bcast(Nudge_End_Year     , 1, mpi_integer, mstrid, mpicom, ierr)
     543        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_End_Year')
     544        1536 :    call MPI_bcast(Nudge_End_Month    , 1, mpi_integer, mstrid, mpicom, ierr)
     545        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_End_Month')
     546        1536 :    call MPI_bcast(Nudge_End_Day      , 1, mpi_integer, mstrid, mpicom, ierr)
     547        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_End_Day')
     548        1536 :    call MPI_bcast(Nudge_End_Sec      , 1, mpi_integer, mstrid, mpicom, ierr)
     549        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_End_Sec')
     550        1536 :    call MPI_bcast(Nudge_Hwin_lo      , 1, mpi_real8 ,  mstrid, mpicom, ierr)
     551        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Hwin_lo')
     552        1536 :    call MPI_bcast(Nudge_Hwin_hi      , 1, mpi_real8 ,  mstrid, mpicom, ierr)
     553        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Hwin_hi')
     554        1536 :    call MPI_bcast(Nudge_Hwin_lat0    , 1, mpi_real8 ,  mstrid, mpicom, ierr)
     555        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Hwin_lat0')
     556        1536 :    call MPI_bcast(Nudge_Hwin_latWidth, 1, mpi_real8 ,  mstrid, mpicom, ierr)
     557        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Hwin_latWidth')
     558        1536 :    call MPI_bcast(Nudge_Hwin_latDelta, 1, mpi_real8 ,  mstrid, mpicom, ierr)
     559        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Hwin_latDelta')
     560        1536 :    call MPI_bcast(Nudge_Hwin_lon0    , 1, mpi_real8 ,  mstrid, mpicom, ierr)
     561        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Hwin_lon0')
     562        1536 :    call MPI_bcast(Nudge_Hwin_lonWidth, 1, mpi_real8 ,  mstrid, mpicom, ierr)
     563        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Hwin_lonWidth')
     564        1536 :    call MPI_bcast(Nudge_Hwin_lonDelta, 1, mpi_real8 ,  mstrid, mpicom, ierr)
     565        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Hwin_lonDelta')
     566        1536 :    call MPI_bcast(Nudge_Hwin_Invert,   1, mpi_logical, mstrid, mpicom, ierr)
     567        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Hwin_Invert')
     568        1536 :    call MPI_bcast(Nudge_Vwin_lo      , 1, mpi_real8 ,  mstrid, mpicom, ierr)
     569        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Vwin_lo')
     570        1536 :    call MPI_bcast(Nudge_Vwin_hi      , 1, mpi_real8 ,  mstrid, mpicom, ierr)
     571        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Vwin_hi')
     572        1536 :    call MPI_bcast(Nudge_Vwin_Hindex  , 1, mpi_real8 ,  mstrid, mpicom, ierr)
     573        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Vwin_Hindex')
     574        1536 :    call MPI_bcast(Nudge_Vwin_Hdelta  , 1, mpi_real8 ,  mstrid, mpicom, ierr)
     575        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Vwin_Hdelta')
     576        1536 :    call MPI_bcast(Nudge_Vwin_Lindex  , 1, mpi_real8 ,  mstrid, mpicom, ierr)
     577        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Vwin_Lindex')
     578        1536 :    call MPI_bcast(Nudge_Vwin_Ldelta  , 1, mpi_real8 ,  mstrid, mpicom, ierr)
     579        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Vwin_Ldelta')
     580        1536 :    call MPI_bcast(Nudge_Vwin_Invert,   1, mpi_logical, mstrid, mpicom, ierr)
     581        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Vwin_Invert')
     582        1536 :    call MPI_bcast(Nudge_ZonalFilter,   1, mpi_logical, mstrid, mpicom, ierr)
     583        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_ZonalFilter')
     584        1536 :    call MPI_bcast(Nudge_ZonalNbasis,   1, mpi_integer, mstrid, mpicom, ierr)
     585        1536 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_ZonalNbasis')
     586             : 
     587             :    ! End Routine
     588             :    !------------
     589             : 
     590        1536 :   end subroutine nudging_readnl
     591             :   !================================================================
     592             : 
     593             : 
     594             :   !================================================================
     595           0 :   subroutine nudging_init
     596             :    !
     597             :    ! NUDGING_INIT: Allocate space and initialize Nudging values
     598             :    !===============================================================
     599             :    use ppgrid        ,only: pver,pcols,begchunk,endchunk
     600             :    use error_messages,only: alloc_err
     601             :    use dycore        ,only: dycore_is
     602             :    use dyn_grid      ,only: get_horiz_grid_dim_d
     603             :    use phys_grid     ,only: get_rlat_p,get_rlon_p,get_ncols_p
     604             :    use cam_history   ,only: addfld
     605             :    use shr_const_mod ,only: SHR_CONST_PI
     606             :    use filenames     ,only: interpret_filename_spec
     607             : 
     608             :    ! Local values
     609             :    !----------------
     610             :    integer :: Year,Month,Day,Sec
     611             :    integer :: YMD1,YMD
     612             :    logical :: After_Beg,Before_End
     613             :    integer :: istat,lchnk,ncol,icol,ilev
     614             :    integer :: hdim1_d,hdim2_d
     615             :    integer :: ierr
     616             :    integer :: dtime
     617             :    real(r8) :: rlat,rlon
     618             :    real(r8) :: Wprof(pver)
     619             :    real(r8) :: lonp,lon0,lonn,latp,lat0,latn
     620             :    real(r8) :: Val1_p,Val2_p,Val3_p,Val4_p
     621             :    real(r8) :: Val1_0,Val2_0,Val3_0,Val4_0
     622             :    real(r8) :: Val1_n,Val2_n,Val3_n,Val4_n
     623             :    integer :: nn
     624             : 
     625             :    character(len=*), parameter :: prefix = 'nudging_init: '
     626             : 
     627             :    ! Get the time step size
     628             :    !------------------------
     629           0 :    dtime = get_step_size()
     630             : 
     631             :    ! Allocate Space for Nudging data arrays
     632             :    !-----------------------------------------
     633           0 :    allocate(Target_U(pcols,pver,begchunk:endchunk),stat=istat)
     634           0 :    call alloc_err(istat,'nudging_init','Target_U',pcols*pver*((endchunk-begchunk)+1))
     635           0 :    allocate(Target_V(pcols,pver,begchunk:endchunk),stat=istat)
     636           0 :    call alloc_err(istat,'nudging_init','Target_V',pcols*pver*((endchunk-begchunk)+1))
     637           0 :    allocate(Target_T(pcols,pver,begchunk:endchunk),stat=istat)
     638           0 :    call alloc_err(istat,'nudging_init','Target_T',pcols*pver*((endchunk-begchunk)+1))
     639           0 :    allocate(Target_S(pcols,pver,begchunk:endchunk),stat=istat)
     640           0 :    call alloc_err(istat,'nudging_init','Target_S',pcols*pver*((endchunk-begchunk)+1))
     641           0 :    allocate(Target_Q(pcols,pver,begchunk:endchunk),stat=istat)
     642           0 :    call alloc_err(istat,'nudging_init','Target_Q',pcols*pver*((endchunk-begchunk)+1))
     643           0 :    allocate(Target_PS(pcols,begchunk:endchunk),stat=istat)
     644           0 :    call alloc_err(istat,'nudging_init','Target_PS',pcols*((endchunk-begchunk)+1))
     645             : 
     646           0 :    allocate(Model_U(pcols,pver,begchunk:endchunk),stat=istat)
     647           0 :    call alloc_err(istat,'nudging_init','Model_U',pcols*pver*((endchunk-begchunk)+1))
     648           0 :    allocate(Model_V(pcols,pver,begchunk:endchunk),stat=istat)
     649           0 :    call alloc_err(istat,'nudging_init','Model_V',pcols*pver*((endchunk-begchunk)+1))
     650           0 :    allocate(Model_T(pcols,pver,begchunk:endchunk),stat=istat)
     651           0 :    call alloc_err(istat,'nudging_init','Model_T',pcols*pver*((endchunk-begchunk)+1))
     652           0 :    allocate(Model_S(pcols,pver,begchunk:endchunk),stat=istat)
     653           0 :    call alloc_err(istat,'nudging_init','Model_S',pcols*pver*((endchunk-begchunk)+1))
     654           0 :    allocate(Model_Q(pcols,pver,begchunk:endchunk),stat=istat)
     655           0 :    call alloc_err(istat,'nudging_init','Model_Q',pcols*pver*((endchunk-begchunk)+1))
     656           0 :    allocate(Model_PS(pcols,begchunk:endchunk),stat=istat)
     657           0 :    call alloc_err(istat,'nudging_init','Model_PS',pcols*((endchunk-begchunk)+1))
     658             : 
     659             :    ! Allocate Space for spatial dependence of
     660             :    ! Nudging Coefs and Nudging Forcing.
     661             :    !-------------------------------------------
     662           0 :    allocate(Nudge_Utau(pcols,pver,begchunk:endchunk),stat=istat)
     663           0 :    call alloc_err(istat,'nudging_init','Nudge_Utau',pcols*pver*((endchunk-begchunk)+1))
     664           0 :    allocate(Nudge_Vtau(pcols,pver,begchunk:endchunk),stat=istat)
     665           0 :    call alloc_err(istat,'nudging_init','Nudge_Vtau',pcols*pver*((endchunk-begchunk)+1))
     666           0 :    allocate(Nudge_Stau(pcols,pver,begchunk:endchunk),stat=istat)
     667           0 :    call alloc_err(istat,'nudging_init','Nudge_Stau',pcols*pver*((endchunk-begchunk)+1))
     668           0 :    allocate(Nudge_Qtau(pcols,pver,begchunk:endchunk),stat=istat)
     669           0 :    call alloc_err(istat,'nudging_init','Nudge_Qtau',pcols*pver*((endchunk-begchunk)+1))
     670           0 :    allocate(Nudge_PStau(pcols,begchunk:endchunk),stat=istat)
     671           0 :    call alloc_err(istat,'nudging_init','Nudge_PStau',pcols*((endchunk-begchunk)+1))
     672             : 
     673           0 :    allocate(Nudge_Ustep(pcols,pver,begchunk:endchunk),stat=istat)
     674           0 :    call alloc_err(istat,'nudging_init','Nudge_Ustep',pcols*pver*((endchunk-begchunk)+1))
     675           0 :    allocate(Nudge_Vstep(pcols,pver,begchunk:endchunk),stat=istat)
     676           0 :    call alloc_err(istat,'nudging_init','Nudge_Vstep',pcols*pver*((endchunk-begchunk)+1))
     677           0 :    allocate(Nudge_Sstep(pcols,pver,begchunk:endchunk),stat=istat)
     678           0 :    call alloc_err(istat,'nudging_init','Nudge_Sstep',pcols*pver*((endchunk-begchunk)+1))
     679           0 :    allocate(Nudge_Qstep(pcols,pver,begchunk:endchunk),stat=istat)
     680           0 :    call alloc_err(istat,'nudging_init','Nudge_Qstep',pcols*pver*((endchunk-begchunk)+1))
     681           0 :    allocate(Nudge_PSstep(pcols,begchunk:endchunk),stat=istat)
     682           0 :    call alloc_err(istat,'nudging_init','Nudge_PSstep',pcols*((endchunk-begchunk)+1))
     683             : 
     684             :    ! Register output fields with the cam history module
     685             :    !-----------------------------------------------------
     686           0 :    call addfld( 'Nudge_U',(/ 'lev' /),'A','m/s/s'  ,'U Nudging Tendency')
     687           0 :    call addfld( 'Nudge_V',(/ 'lev' /),'A','m/s/s'  ,'V Nudging Tendency')
     688           0 :    call addfld( 'Nudge_T',(/ 'lev' /),'A','K/s'    ,'T Nudging Tendency')
     689           0 :    call addfld( 'Nudge_Q',(/ 'lev' /),'A','kg/kg/s','Q Nudging Tendency')
     690           0 :    call addfld('Target_U',(/ 'lev' /),'A','m/s'    ,'U Nudging Target'  )
     691           0 :    call addfld('Target_V',(/ 'lev' /),'A','m/s'    ,'V Nudging Target'  )
     692           0 :    call addfld('Target_T',(/ 'lev' /),'A','K'      ,'T Nudging Target'  )
     693           0 :    call addfld('Target_Q',(/ 'lev' /),'A','kg/kg'  ,'Q Nudging Target  ')
     694             : 
     695             :    !-----------------------------------------
     696             :    ! Values initialized only by masterproc
     697             :    !-----------------------------------------
     698           0 :    if(masterproc) then
     699             : 
     700             :      ! Set the Stepping intervals for Model and Nudging values
     701             :      ! Ensure that the Model_Step is not smaller then one timestep
     702             :      !  and not larger then the Nudge_Step.
     703             :      !--------------------------------------------------------
     704           0 :      Model_Step=86400/Model_Times_Per_Day
     705           0 :      Nudge_Step=86400/Nudge_Times_Per_Day
     706           0 :      if(Model_Step < dtime) then
     707           0 :        write(iulog,*) ' '
     708           0 :        write(iulog,*) 'NUDGING: Model_Step cannot be less than a model timestep'
     709           0 :        write(iulog,*) 'NUDGING:  Setting Model_Step=dtime , dtime=',dtime
     710           0 :        write(iulog,*) ' '
     711           0 :        Model_Step=dtime
     712             :      endif
     713           0 :      if(Model_Step > Nudge_Step) then
     714           0 :        write(iulog,*) ' '
     715           0 :        write(iulog,*) 'NUDGING: Model_Step cannot be more than Nudge_Step'
     716           0 :        write(iulog,*) 'NUDGING:  Setting Model_Step=Nudge_Step, Nudge_Step=',Nudge_Step
     717           0 :        write(iulog,*) ' '
     718           0 :        Model_Step=Nudge_Step
     719             :      endif
     720             : 
     721             :      ! Initialize column and level dimensions
     722             :      !--------------------------------------------------------
     723           0 :      call get_horiz_grid_dim_d(hdim1_d,hdim2_d)
     724           0 :      Nudge_nlon=hdim1_d
     725           0 :      Nudge_nlat=hdim2_d
     726           0 :      Nudge_ncol=hdim1_d*hdim2_d
     727           0 :      Nudge_nlev=pver
     728             : 
     729             :      ! Check the time relative to the nudging window
     730             :      !------------------------------------------------
     731           0 :      call get_curr_date(Year,Month,Day,Sec)
     732           0 :      YMD=(Year*10000) + (Month*100) + Day
     733           0 :      YMD1=(Nudge_Beg_Year*10000) + (Nudge_Beg_Month*100) + Nudge_Beg_Day
     734             :      call timemgr_time_ge(YMD1,Nudge_Beg_Sec,                                 &
     735           0 :                           YMD ,Sec          ,After_Beg)
     736           0 :      YMD1=(Nudge_End_Year*10000) + (Nudge_End_Month*100) + Nudge_End_Day
     737             :      call timemgr_time_ge(YMD ,Sec          ,                                 &
     738           0 :                           YMD1,Nudge_End_Sec,Before_End)
     739             : 
     740           0 :      if((After_Beg) .and. (Before_End)) then
     741             :        ! Set Time indicies so that the next call to
     742             :        ! timestep_init will initialize the data arrays.
     743             :        !--------------------------------------------
     744           0 :        Model_Next_Year =Year
     745           0 :        Model_Next_Month=Month
     746           0 :        Model_Next_Day  =Day
     747           0 :        Model_Next_Sec  =(Sec/Model_Step)*Model_Step
     748           0 :        Nudge_Next_Year =Year
     749           0 :        Nudge_Next_Month=Month
     750           0 :        Nudge_Next_Day  =Day
     751           0 :        Nudge_Next_Sec  =(Sec/Nudge_Step)*Nudge_Step
     752           0 :      elseif(.not.After_Beg) then
     753             :        ! Set Time indicies to Nudging start,
     754             :        ! timestep_init will initialize the data arrays.
     755             :        !--------------------------------------------
     756           0 :        Model_Next_Year =Nudge_Beg_Year
     757           0 :        Model_Next_Month=Nudge_Beg_Month
     758           0 :        Model_Next_Day  =Nudge_Beg_Day
     759           0 :        Model_Next_Sec  =Nudge_Beg_Sec
     760           0 :        Nudge_Next_Year =Nudge_Beg_Year
     761           0 :        Nudge_Next_Month=Nudge_Beg_Month
     762           0 :        Nudge_Next_Day  =Nudge_Beg_Day
     763           0 :        Nudge_Next_Sec  =Nudge_Beg_Sec
     764           0 :      elseif(.not.Before_End) then
     765             :        ! Nudging will never occur, so switch it off
     766             :        !--------------------------------------------
     767           0 :        Nudge_Model=.false.
     768           0 :        Nudge_ON   =.false.
     769           0 :        write(iulog,*) ' '
     770           0 :        write(iulog,*) 'NUDGING: WARNING - Nudging has been requested by it will'
     771           0 :        write(iulog,*) 'NUDGING:           never occur for the given time values'
     772           0 :        write(iulog,*) ' '
     773             :      endif
     774             : 
     775             :      ! Initialize values for window function
     776             :      !----------------------------------------
     777           0 :      lonp= 180._r8
     778           0 :      lon0=   0._r8
     779           0 :      lonn=-180._r8
     780           0 :      latp=  90._r8-Nudge_Hwin_lat0
     781           0 :      lat0=   0._r8
     782           0 :      latn= -90._r8-Nudge_Hwin_lat0
     783             : 
     784           0 :      Nudge_Hwin_lonWidthH=Nudge_Hwin_lonWidth/2._r8
     785           0 :      Nudge_Hwin_latWidthH=Nudge_Hwin_latWidth/2._r8
     786             : 
     787           0 :      Val1_p=(1._r8+tanh((Nudge_Hwin_lonWidthH+lonp)/Nudge_Hwin_lonDelta))/2._r8
     788           0 :      Val2_p=(1._r8+tanh((Nudge_Hwin_lonWidthH-lonp)/Nudge_Hwin_lonDelta))/2._r8
     789           0 :      Val3_p=(1._r8+tanh((Nudge_Hwin_latWidthH+latp)/Nudge_Hwin_latDelta))/2._r8
     790           0 :      Val4_p=(1._r8+tanh((Nudge_Hwin_latWidthH-latp)/Nudge_Hwin_latDelta))/2_r8
     791           0 :      Val1_0=(1._r8+tanh((Nudge_Hwin_lonWidthH+lon0)/Nudge_Hwin_lonDelta))/2._r8
     792           0 :      Val2_0=(1._r8+tanh((Nudge_Hwin_lonWidthH-lon0)/Nudge_Hwin_lonDelta))/2._r8
     793           0 :      Val3_0=(1._r8+tanh((Nudge_Hwin_latWidthH+lat0)/Nudge_Hwin_latDelta))/2._r8
     794           0 :      Val4_0=(1._r8+tanh((Nudge_Hwin_latWidthH-lat0)/Nudge_Hwin_latDelta))/2._r8
     795             : 
     796           0 :      Val1_n=(1._r8+tanh((Nudge_Hwin_lonWidthH+lonn)/Nudge_Hwin_lonDelta))/2._r8
     797           0 :      Val2_n=(1._r8+tanh((Nudge_Hwin_lonWidthH-lonn)/Nudge_Hwin_lonDelta))/2._r8
     798           0 :      Val3_n=(1._r8+tanh((Nudge_Hwin_latWidthH+latn)/Nudge_Hwin_latDelta))/2._r8
     799           0 :      Val4_n=(1._r8+tanh((Nudge_Hwin_latWidthH-latn)/Nudge_Hwin_latDelta))/2._r8
     800             : 
     801           0 :      Nudge_Hwin_max=     Val1_0*Val2_0*Val3_0*Val4_0
     802             :      Nudge_Hwin_min=min((Val1_p*Val2_p*Val3_n*Val4_n),                        &
     803             :                         (Val1_p*Val2_p*Val3_p*Val4_p),                        &
     804             :                         (Val1_n*Val2_n*Val3_n*Val4_n),                        &
     805           0 :                         (Val1_n*Val2_n*Val3_p*Val4_p))
     806             : 
     807             :      ! Initialize number of nudging observation values to keep track of.
     808             :      ! Allocate and initialize observation indices
     809             :      !-----------------------------------------------------------------
     810           0 :      if((Nudge_Force_Opt >= 0) .and. (Nudge_Force_Opt <= 1)) then
     811           0 :        Nudge_NumObs=2
     812             :      else
     813             :        ! Additional Options may need OBS values at more times.
     814             :        !------------------------------------------------------
     815           0 :        Nudge_NumObs=2
     816           0 :        write(iulog,*) 'NUDGING: Setting Nudge_NumObs=2'
     817           0 :        write(iulog,*) 'NUDGING: WARNING: Unknown Nudge_Force_Opt=',Nudge_Force_Opt
     818           0 :        call endrun('NUDGING: Unknown Forcing Option')
     819             :      endif
     820           0 :      allocate(Nudge_ObsInd(Nudge_NumObs),stat=istat)
     821           0 :      call alloc_err(istat,'nudging_init','Nudge_ObsInd',Nudge_NumObs)
     822           0 :      allocate(Nudge_File_Present(Nudge_NumObs),stat=istat)
     823           0 :      call alloc_err(istat,'nudging_init','Nudge_File_Present',Nudge_NumObs)
     824           0 :      do nn=1,Nudge_NumObs
     825           0 :        Nudge_ObsInd(nn) = Nudge_NumObs+1-nn
     826             :      end do
     827           0 :      Nudge_File_Present(:) = .false.
     828             : 
     829             :      ! Initialization is done,
     830             :      !--------------------------
     831           0 :      Nudge_Initialized = .true.
     832             : 
     833             :      ! Informational Output
     834             :      !---------------------------
     835           0 :      write(iulog,*) ' '
     836           0 :      write(iulog,*) '---------------------------------------------------------'
     837           0 :      write(iulog,*) '  MODEL NUDGING INITIALIZED WITH THE FOLLOWING SETTINGS: '
     838           0 :      write(iulog,*) '---------------------------------------------------------'
     839           0 :      write(iulog,*) 'NUDGING: Nudge_Model=',Nudge_Model
     840           0 :      write(iulog,*) 'NUDGING: Nudge_Path=',Nudge_Path
     841           0 :      write(iulog,*) 'NUDGING: Nudge_File_Template =',Nudge_File_Template
     842           0 :      write(iulog,*) 'NUDGING: Nudge_Force_Opt=',Nudge_Force_Opt
     843           0 :      write(iulog,*) 'NUDGING: Nudge_TimeScale_Opt=',Nudge_TimeScale_Opt
     844           0 :      write(iulog,*) 'NUDGING: Nudge_TSmode=',Nudge_TSmode
     845           0 :      write(iulog,*) 'NUDGING: Nudge_Times_Per_Day=',Nudge_Times_Per_Day
     846           0 :      write(iulog,*) 'NUDGING: Model_Times_Per_Day=',Model_Times_Per_Day
     847           0 :      write(iulog,*) 'NUDGING: Nudge_Step=',Nudge_Step
     848           0 :      write(iulog,*) 'NUDGING: Model_Step=',Model_Step
     849           0 :      write(iulog,*) 'NUDGING: Nudge_ZonalFilter=',Nudge_ZonalFilter
     850           0 :      write(iulog,*) 'NUDGING: Nudge_ZonalNbasis=',Nudge_ZonalNbasis
     851           0 :      write(iulog,*) 'NUDGING: Nudge_Ucoef  =',Nudge_Ucoef
     852           0 :      write(iulog,*) 'NUDGING: Nudge_Vcoef  =',Nudge_Vcoef
     853           0 :      write(iulog,*) 'NUDGING: Nudge_Qcoef  =',Nudge_Qcoef
     854           0 :      write(iulog,*) 'NUDGING: Nudge_Tcoef  =',Nudge_Tcoef
     855           0 :      write(iulog,*) 'NUDGING: Nudge_PScoef =',Nudge_PScoef
     856           0 :      write(iulog,*) 'NUDGING: Nudge_Uprof  =',Nudge_Uprof
     857           0 :      write(iulog,*) 'NUDGING: Nudge_Vprof  =',Nudge_Vprof
     858           0 :      write(iulog,*) 'NUDGING: Nudge_Qprof  =',Nudge_Qprof
     859           0 :      write(iulog,*) 'NUDGING: Nudge_Tprof  =',Nudge_Tprof
     860           0 :      write(iulog,*) 'NUDGING: Nudge_PSprof =',Nudge_PSprof
     861           0 :      write(iulog,*) 'NUDGING: Nudge_Beg_Year =',Nudge_Beg_Year
     862           0 :      write(iulog,*) 'NUDGING: Nudge_Beg_Month=',Nudge_Beg_Month
     863           0 :      write(iulog,*) 'NUDGING: Nudge_Beg_Day  =',Nudge_Beg_Day
     864           0 :      write(iulog,*) 'NUDGING: Nudge_End_Year =',Nudge_End_Year
     865           0 :      write(iulog,*) 'NUDGING: Nudge_End_Month=',Nudge_End_Month
     866           0 :      write(iulog,*) 'NUDGING: Nudge_End_Day  =',Nudge_End_Day
     867           0 :      write(iulog,*) 'NUDGING: Nudge_Hwin_lat0     =',Nudge_Hwin_lat0
     868           0 :      write(iulog,*) 'NUDGING: Nudge_Hwin_latWidth =',Nudge_Hwin_latWidth
     869           0 :      write(iulog,*) 'NUDGING: Nudge_Hwin_latDelta =',Nudge_Hwin_latDelta
     870           0 :      write(iulog,*) 'NUDGING: Nudge_Hwin_lon0     =',Nudge_Hwin_lon0
     871           0 :      write(iulog,*) 'NUDGING: Nudge_Hwin_lonWidth =',Nudge_Hwin_lonWidth
     872           0 :      write(iulog,*) 'NUDGING: Nudge_Hwin_lonDelta =',Nudge_Hwin_lonDelta
     873           0 :      write(iulog,*) 'NUDGING: Nudge_Hwin_Invert   =',Nudge_Hwin_Invert
     874           0 :      write(iulog,*) 'NUDGING: Nudge_Hwin_lo       =',Nudge_Hwin_lo
     875           0 :      write(iulog,*) 'NUDGING: Nudge_Hwin_hi       =',Nudge_Hwin_hi
     876           0 :      write(iulog,*) 'NUDGING: Nudge_Vwin_Hindex   =',Nudge_Vwin_Hindex
     877           0 :      write(iulog,*) 'NUDGING: Nudge_Vwin_Hdelta   =',Nudge_Vwin_Hdelta
     878           0 :      write(iulog,*) 'NUDGING: Nudge_Vwin_Lindex   =',Nudge_Vwin_Lindex
     879           0 :      write(iulog,*) 'NUDGING: Nudge_Vwin_Ldelta   =',Nudge_Vwin_Ldelta
     880           0 :      write(iulog,*) 'NUDGING: Nudge_Vwin_Invert   =',Nudge_Vwin_Invert
     881           0 :      write(iulog,*) 'NUDGING: Nudge_Vwin_lo       =',Nudge_Vwin_lo
     882           0 :      write(iulog,*) 'NUDGING: Nudge_Vwin_hi       =',Nudge_Vwin_hi
     883           0 :      write(iulog,*) 'NUDGING: Nudge_Hwin_latWidthH=',Nudge_Hwin_latWidthH
     884           0 :      write(iulog,*) 'NUDGING: Nudge_Hwin_lonWidthH=',Nudge_Hwin_lonWidthH
     885           0 :      write(iulog,*) 'NUDGING: Nudge_Hwin_max      =',Nudge_Hwin_max
     886           0 :      write(iulog,*) 'NUDGING: Nudge_Hwin_min      =',Nudge_Hwin_min
     887           0 :      write(iulog,*) 'NUDGING: Nudge_Initialized   =',Nudge_Initialized
     888           0 :      write(iulog,*) ' '
     889           0 :      write(iulog,*) 'NUDGING: Nudge_NumObs=',Nudge_NumObs
     890           0 :      write(iulog,*) ' '
     891             : 
     892             :    endif ! (masterproc) then
     893             : 
     894             :    ! Broadcast other variables that have changed
     895             :    !---------------------------------------------
     896           0 :    call MPI_bcast(Model_Step          , 1, mpi_real8 ,  mstrid, mpicom, ierr)
     897           0 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Model_Step')
     898           0 :    call MPI_bcast(Nudge_Step          , 1, mpi_real8 ,  mstrid, mpicom, ierr)
     899           0 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Step')
     900           0 :    call MPI_bcast(Model_Next_Year     , 1, mpi_integer, mstrid, mpicom, ierr)
     901           0 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Model_Next_Year')
     902           0 :    call MPI_bcast(Model_Next_Month    , 1, mpi_integer, mstrid, mpicom, ierr)
     903           0 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Model_Next_Month')
     904           0 :    call MPI_bcast(Model_Next_Day      , 1, mpi_integer, mstrid, mpicom, ierr)
     905           0 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Model_Next_Day')
     906           0 :    call MPI_bcast(Model_Next_Sec      , 1, mpi_integer, mstrid, mpicom, ierr)
     907           0 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Model_Next_Sec')
     908           0 :    call MPI_bcast(Nudge_Next_Year     , 1, mpi_integer, mstrid, mpicom, ierr)
     909           0 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Next_Year')
     910           0 :    call MPI_bcast(Nudge_Next_Month    , 1, mpi_integer, mstrid, mpicom, ierr)
     911           0 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Next_Month')
     912           0 :    call MPI_bcast(Nudge_Next_Day      , 1, mpi_integer, mstrid, mpicom, ierr)
     913           0 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Next_Day')
     914           0 :    call MPI_bcast(Nudge_Next_Sec      , 1, mpi_integer, mstrid, mpicom, ierr)
     915           0 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Next_Sec')
     916           0 :    call MPI_bcast(Nudge_Model         , 1, mpi_logical, mstrid, mpicom, ierr)
     917           0 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Model')
     918           0 :    call MPI_bcast(Nudge_ON            , 1, mpi_logical, mstrid, mpicom, ierr)
     919           0 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_ON')
     920           0 :    call MPI_bcast(Nudge_Initialized   , 1, mpi_logical, mstrid, mpicom, ierr)
     921           0 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Initialized')
     922           0 :    call MPI_bcast(Nudge_ncol          , 1, mpi_integer, mstrid, mpicom, ierr)
     923           0 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_ncol')
     924           0 :    call MPI_bcast(Nudge_nlev          , 1, mpi_integer, mstrid, mpicom, ierr)
     925           0 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_nlev')
     926           0 :    call MPI_bcast(Nudge_nlon          , 1, mpi_integer, mstrid, mpicom, ierr)
     927           0 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_nlon')
     928           0 :    call MPI_bcast(Nudge_nlat          , 1, mpi_integer, mstrid, mpicom, ierr)
     929           0 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_nlat')
     930           0 :    call MPI_bcast(Nudge_Hwin_max      , 1, mpi_real8 ,  mstrid, mpicom, ierr)
     931           0 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Hwin_max')
     932           0 :    call MPI_bcast(Nudge_Hwin_min      , 1, mpi_real8 ,  mstrid, mpicom, ierr)
     933           0 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Hwin_min')
     934           0 :    call MPI_bcast(Nudge_Hwin_lonWidthH, 1, mpi_real8 ,  mstrid, mpicom, ierr)
     935           0 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Hwin_lonWidthH')
     936           0 :    call MPI_bcast(Nudge_Hwin_latWidthH, 1, mpi_real8 ,  mstrid, mpicom, ierr)
     937           0 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_Hwin_latWidthH')
     938           0 :    call MPI_bcast(Nudge_NumObs        , 1, mpi_integer, mstrid, mpicom, ierr)
     939           0 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_NumObs')
     940             : 
     941             :    ! All non-masterproc processes also need to allocate space
     942             :    ! before the broadcast of Nudge_NumObs dependent data.
     943             :    !------------------------------------------------------------
     944           0 :    if(.not.masterproc) then
     945           0 :      allocate(Nudge_ObsInd(Nudge_NumObs),stat=istat)
     946           0 :      call alloc_err(istat,'nudging_init','Nudge_ObsInd',Nudge_NumObs)
     947           0 :      allocate(Nudge_File_Present(Nudge_NumObs),stat=istat)
     948           0 :      call alloc_err(istat,'nudging_init','Nudge_File_Present',Nudge_NumObs)
     949             :    endif
     950             : 
     951           0 :    call MPI_bcast(Nudge_ObsInd      , Nudge_NumObs, mpi_integer, mstrid, mpicom, ierr)
     952           0 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: ')
     953           0 :    call MPI_bcast(Nudge_File_Present, Nudge_NumObs, mpi_logical, mstrid, mpicom, ierr)
     954           0 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: ')
     955             : 
     956             :    ! Allocate Space for Nudging observation arrays, initialize with 0's
     957             :    !---------------------------------------------------------------------
     958           0 :    allocate(Nobs_U(pcols,pver,begchunk:endchunk,Nudge_NumObs),stat=istat)
     959           0 :    call alloc_err(istat,'nudging_init','Nobs_U',pcols*pver*((endchunk-begchunk)+1)*Nudge_NumObs)
     960           0 :    allocate(Nobs_V(pcols,pver,begchunk:endchunk,Nudge_NumObs),stat=istat)
     961           0 :    call alloc_err(istat,'nudging_init','Nobs_V',pcols*pver*((endchunk-begchunk)+1)*Nudge_NumObs)
     962           0 :    allocate(Nobs_T(pcols,pver,begchunk:endchunk,Nudge_NumObs),stat=istat)
     963           0 :    call alloc_err(istat,'nudging_init','Nobs_T',pcols*pver*((endchunk-begchunk)+1)*Nudge_NumObs)
     964           0 :    allocate(Nobs_Q(pcols,pver,begchunk:endchunk,Nudge_NumObs),stat=istat)
     965           0 :    call alloc_err(istat,'nudging_init','Nobs_Q',pcols*pver*((endchunk-begchunk)+1)*Nudge_NumObs)
     966           0 :    allocate(Nobs_PS(pcols,begchunk:endchunk,Nudge_NumObs),stat=istat)
     967           0 :    call alloc_err(istat,'nudging_init','Nobs_PS',pcols*((endchunk-begchunk)+1)*Nudge_NumObs)
     968             : 
     969           0 :    Nobs_U(:pcols,:pver,begchunk:endchunk,:Nudge_NumObs)=0._r8
     970           0 :    Nobs_V(:pcols,:pver,begchunk:endchunk,:Nudge_NumObs)=0._r8
     971           0 :    Nobs_T(:pcols,:pver,begchunk:endchunk,:Nudge_NumObs)=0._r8
     972           0 :    Nobs_Q(:pcols,:pver,begchunk:endchunk,:Nudge_NumObs)=0._r8
     973           0 :    Nobs_PS(:pcols     ,begchunk:endchunk,:Nudge_NumObs)=0._r8
     974             : 
     975             : !!DIAG
     976           0 :    if(masterproc) then
     977           0 :      write(iulog,*) 'NUDGING: nudging_init() OBS arrays allocated and initialized'
     978           0 :      write(iulog,*) 'NUDGING: nudging_init() SIZE#',(9*pcols*pver*((endchunk-begchunk)+1)*Nudge_NumObs)
     979           0 :      write(iulog,*) 'NUDGING: nudging_init() MB:',float(8*9*pcols*pver*((endchunk-begchunk)+1)*Nudge_NumObs)/(1024._r8*1024._r8)
     980           0 :      write(iulog,*) 'NUDGING: nudging_init() pcols=',pcols,' pver=',pver
     981           0 :      write(iulog,*) 'NUDGING: nudging_init() begchunk:',begchunk,' endchunk=',endchunk
     982           0 :      write(iulog,*) 'NUDGING: nudging_init() chunk:',(endchunk-begchunk+1),' Nudge_NumObs=',Nudge_NumObs
     983           0 :      write(iulog,*) 'NUDGING: nudging_init() Nudge_ObsInd=',Nudge_ObsInd
     984           0 :      write(iulog,*) 'NUDGING: nudging_init() Nudge_File_Present=',Nudge_File_Present
     985             :    endif
     986             : !!DIAG
     987             : 
     988             :    ! Initialize the Zonal Mean type if needed
     989             :    !------------------------------------------
     990           0 :    if(Nudge_ZonalFilter) then
     991           0 :      call ZM%init(Nudge_ZonalNbasis)
     992           0 :      allocate(Zonal_Bamp2d(Nudge_ZonalNbasis),stat=istat)
     993           0 :      call alloc_err(istat,'nudging_init','Zonal_Bamp2d',Nudge_ZonalNbasis)
     994           0 :      allocate(Zonal_Bamp3d(Nudge_ZonalNbasis,pver),stat=istat)
     995           0 :      call alloc_err(istat,'nudging_init','Zonal_Bamp3d',Nudge_ZonalNbasis*pver)
     996             :    endif
     997             : 
     998             :    ! Initialize the analysis filename at the NEXT time for startup.
     999             :    !---------------------------------------------------------------
    1000             :    Nudge_File=interpret_filename_spec(Nudge_File_Template      , &
    1001             :                                        yr_spec=Nudge_Next_Year , &
    1002             :                                       mon_spec=Nudge_Next_Month, &
    1003             :                                       day_spec=Nudge_Next_Day  , &
    1004           0 :                                       sec_spec=Nudge_Next_Sec    )
    1005           0 :    if(masterproc) then
    1006           0 :     write(iulog,*) 'NUDGING: Reading analyses:',trim(Nudge_Path)//trim(Nudge_File)
    1007             :    endif
    1008             : 
    1009             :    ! Rotate Nudge_ObsInd() indices for new data, then update
    1010             :    ! the Nudge observation arrays with analysis data at the
    1011             :    ! NEXT==Nudge_ObsInd(1) time.
    1012             :    !----------------------------------------------------------
    1013           0 :    call nudging_update_analyses (trim(Nudge_Path)//trim(Nudge_File))
    1014             : 
    1015             :    ! Initialize Nudging Coeffcient profiles in local arrays
    1016             :    ! Load zeros into nudging arrays
    1017             :    !------------------------------------------------------
    1018           0 :    do lchnk=begchunk,endchunk
    1019           0 :      ncol=get_ncols_p(lchnk)
    1020           0 :      do icol=1,ncol
    1021           0 :        rlat=get_rlat_p(lchnk,icol)*180._r8/SHR_CONST_PI
    1022           0 :        rlon=get_rlon_p(lchnk,icol)*180._r8/SHR_CONST_PI
    1023             : 
    1024           0 :        call nudging_set_profile(rlat,rlon,Nudge_Uprof,Wprof,pver)
    1025           0 :        Nudge_Utau(icol,:,lchnk)=Wprof(:)
    1026           0 :        call nudging_set_profile(rlat,rlon,Nudge_Vprof,Wprof,pver)
    1027           0 :        Nudge_Vtau(icol,:,lchnk)=Wprof(:)
    1028           0 :        call nudging_set_profile(rlat,rlon,Nudge_Tprof,Wprof,pver)
    1029           0 :        Nudge_Stau(icol,:,lchnk)=Wprof(:)
    1030           0 :        call nudging_set_profile(rlat,rlon,Nudge_Qprof,Wprof,pver)
    1031           0 :        Nudge_Qtau(icol,:,lchnk)=Wprof(:)
    1032             : 
    1033           0 :        Nudge_PStau(icol,lchnk)=nudging_set_PSprofile(rlat,rlon,Nudge_PSprof)
    1034             :      end do
    1035             :      Nudge_Utau(:ncol,:pver,lchnk) =                             &
    1036           0 :      Nudge_Utau(:ncol,:pver,lchnk) * Nudge_Ucoef/float(Nudge_Step)
    1037             :      Nudge_Vtau(:ncol,:pver,lchnk) =                             &
    1038           0 :      Nudge_Vtau(:ncol,:pver,lchnk) * Nudge_Vcoef/float(Nudge_Step)
    1039             :      Nudge_Stau(:ncol,:pver,lchnk) =                             &
    1040           0 :      Nudge_Stau(:ncol,:pver,lchnk) * Nudge_Tcoef/float(Nudge_Step)
    1041             :      Nudge_Qtau(:ncol,:pver,lchnk) =                             &
    1042           0 :      Nudge_Qtau(:ncol,:pver,lchnk) * Nudge_Qcoef/float(Nudge_Step)
    1043             :      Nudge_PStau(:ncol,lchnk)=                             &
    1044           0 :      Nudge_PStau(:ncol,lchnk)* Nudge_PScoef/float(Nudge_Step)
    1045             : 
    1046           0 :      Nudge_Ustep(:pcols,:pver,lchnk)=0._r8
    1047           0 :      Nudge_Vstep(:pcols,:pver,lchnk)=0._r8
    1048           0 :      Nudge_Sstep(:pcols,:pver,lchnk)=0._r8
    1049           0 :      Nudge_Qstep(:pcols,:pver,lchnk)=0._r8
    1050           0 :      Nudge_PSstep(:pcols,lchnk)=0._r8
    1051           0 :      Target_U(:pcols,:pver,lchnk)=0._r8
    1052           0 :      Target_V(:pcols,:pver,lchnk)=0._r8
    1053           0 :      Target_T(:pcols,:pver,lchnk)=0._r8
    1054           0 :      Target_S(:pcols,:pver,lchnk)=0._r8
    1055           0 :      Target_Q(:pcols,:pver,lchnk)=0._r8
    1056           0 :      Target_PS(:pcols,lchnk)=0._r8
    1057             :    end do
    1058             : 
    1059             :    ! End Routine
    1060             :    !------------
    1061             : 
    1062           0 :   end subroutine nudging_init
    1063             :   !================================================================
    1064             : 
    1065             : 
    1066             :   !================================================================
    1067           0 :   subroutine nudging_timestep_init(phys_state)
    1068             :    !
    1069             :    ! NUDGING_TIMESTEP_INIT:
    1070             :    !                 Check the current time and update Model/Nudging
    1071             :    !                 arrays when necessary. Toggle the Nudging flag
    1072             :    !                 when the time is withing the nudging window.
    1073             :    !===============================================================
    1074           0 :    use physconst    ,only: cpair
    1075             :    use physics_types,only: physics_state
    1076             :    use constituents ,only: cnst_get_ind
    1077             :    use dycore       ,only: dycore_is
    1078             :    use ppgrid       ,only: pver,pcols,begchunk,endchunk
    1079             :    use filenames    ,only: interpret_filename_spec
    1080             :    use ESMF
    1081             : 
    1082             :    ! Arguments
    1083             :    !-----------
    1084             :    type(physics_state),intent(in):: phys_state(begchunk:endchunk)
    1085             : 
    1086             :    ! Local values
    1087             :    !----------------
    1088             :    integer :: Year,Month,Day,Sec
    1089             :    integer :: YMD1,YMD2,YMD
    1090             :    logical :: Update_Model,Update_Nudge,Sync_Error
    1091             :    logical :: After_Beg   ,Before_End
    1092             :    integer :: lchnk,ncol,indw
    1093             : 
    1094             :    type(ESMF_Time)         :: Date1,Date2
    1095             :    type(ESMF_TimeInterval) :: DateDiff
    1096             :    integer                 :: DeltaT
    1097             :    real(r8)                :: Tscale
    1098             :    real(r8)                :: Tfrac
    1099             :    integer                 :: rc
    1100             :    integer                 :: nn
    1101             :    integer                 :: kk
    1102             :    real(r8)                :: Sbar,Qbar,Wsum
    1103             :    integer                 :: dtime
    1104             : 
    1105             :    ! Check if Nudging is initialized
    1106             :    !---------------------------------
    1107           0 :    if(.not.Nudge_Initialized) then
    1108           0 :      call endrun('nudging_timestep_init:: Nudging NOT Initialized')
    1109             :    endif
    1110             : 
    1111             :    ! Get time step size
    1112             :    !--------------------
    1113           0 :    dtime = get_step_size()
    1114             : 
    1115             :    ! Get Current time
    1116             :    !--------------------
    1117           0 :    call get_curr_date(Year,Month,Day,Sec)
    1118           0 :    YMD=(Year*10000) + (Month*100) + Day
    1119             : 
    1120             :    !-------------------------------------------------------
    1121             :    ! Determine if the current time is AFTER the begining time
    1122             :    ! and if it is BEFORE the ending time.
    1123             :    !-------------------------------------------------------
    1124           0 :    YMD1=(Nudge_Beg_Year*10000) + (Nudge_Beg_Month*100) + Nudge_Beg_Day
    1125             :    call timemgr_time_ge(YMD1,Nudge_Beg_Sec,         &
    1126           0 :                         YMD ,Sec          ,After_Beg)
    1127             : 
    1128           0 :    YMD1=(Nudge_End_Year*10000) + (Nudge_End_Month*100) + Nudge_End_Day
    1129             :    call timemgr_time_ge(YMD ,Sec,                    &
    1130           0 :                         YMD1,Nudge_End_Sec,Before_End)
    1131             : 
    1132             :    !--------------------------------------------------------------
    1133             :    ! When past the NEXT time, Update Model Arrays and time indices
    1134             :    !--------------------------------------------------------------
    1135           0 :    YMD1=(Model_Next_Year*10000) + (Model_Next_Month*100) + Model_Next_Day
    1136             :    call timemgr_time_ge(YMD1,Model_Next_Sec,            &
    1137           0 :                         YMD ,Sec           ,Update_Model)
    1138             : 
    1139           0 :    if((Before_End) .and. (Update_Model)) then
    1140             :      ! Increment the Model times by the current interval
    1141             :      !---------------------------------------------------
    1142           0 :      Model_Curr_Year =Model_Next_Year
    1143           0 :      Model_Curr_Month=Model_Next_Month
    1144           0 :      Model_Curr_Day  =Model_Next_Day
    1145           0 :      Model_Curr_Sec  =Model_Next_Sec
    1146           0 :      YMD1=(Model_Curr_Year*10000) + (Model_Curr_Month*100) + Model_Curr_Day
    1147             :      call timemgr_time_inc(YMD1,Model_Curr_Sec,              &
    1148           0 :                            YMD2,Model_Next_Sec,Model_Step,0,0)
    1149             : 
    1150             :      ! Check for Sync Error where NEXT model time after the update
    1151             :      ! is before the current time. If so, reset the next model
    1152             :      ! time to a Model_Step after the current time.
    1153             :      !--------------------------------------------------------------
    1154             :      call timemgr_time_ge(YMD2,Model_Next_Sec,            &
    1155           0 :                           YMD ,Sec           ,Sync_Error)
    1156           0 :      if(Sync_Error) then
    1157           0 :        Model_Curr_Year =Year
    1158           0 :        Model_Curr_Month=Month
    1159           0 :        Model_Curr_Day  =Day
    1160           0 :        Model_Curr_Sec  =Sec
    1161             :        call timemgr_time_inc(YMD ,Model_Curr_Sec,              &
    1162           0 :                              YMD2,Model_Next_Sec,Model_Step,0,0)
    1163           0 :        write(iulog,*) 'NUDGING: WARNING - Model_Time Sync ERROR... CORRECTED'
    1164             :      endif
    1165           0 :      Model_Next_Year =(YMD2/10000)
    1166           0 :      YMD2            = YMD2-(Model_Next_Year*10000)
    1167           0 :      Model_Next_Month=(YMD2/100)
    1168           0 :      Model_Next_Day  = YMD2-(Model_Next_Month*100)
    1169             : 
    1170             :      ! Load values at Current into the Model arrays
    1171             :      !-----------------------------------------------
    1172           0 :      call cnst_get_ind('Q',indw)
    1173           0 :      do lchnk=begchunk,endchunk
    1174           0 :        ncol=phys_state(lchnk)%ncol
    1175           0 :        Model_U(:ncol,:pver,lchnk)=phys_state(lchnk)%u(:ncol,:pver)
    1176           0 :        Model_V(:ncol,:pver,lchnk)=phys_state(lchnk)%v(:ncol,:pver)
    1177           0 :        Model_T(:ncol,:pver,lchnk)=phys_state(lchnk)%t(:ncol,:pver)
    1178           0 :        Model_Q(:ncol,:pver,lchnk)=phys_state(lchnk)%q(:ncol,:pver,indw)
    1179           0 :        Model_PS(:ncol,lchnk)=phys_state(lchnk)%ps(:ncol)
    1180             :      end do
    1181             : 
    1182             :      ! Load Dry Static Energy values for Model
    1183             :      !-----------------------------------------
    1184           0 :      if(Nudge_TSmode == 0) then
    1185             :        ! DSE tendencies from Temperature only
    1186             :        !---------------------------------------
    1187           0 :        do lchnk=begchunk,endchunk
    1188           0 :          ncol=phys_state(lchnk)%ncol
    1189           0 :          Model_S(:ncol,:pver,lchnk)=cpair*Model_T(:ncol,:pver,lchnk)
    1190             :        end do
    1191           0 :      elseif(Nudge_TSmode == 1) then
    1192             :        ! Caluculate DSE tendencies from Temperature, Water Vapor, and Surface Pressure
    1193             :        !------------------------------------------------------------------------------
    1194           0 :        do lchnk=begchunk,endchunk
    1195           0 :          ncol=phys_state(lchnk)%ncol
    1196             :          call calc_DryStaticEnergy(Model_T(:,:,lchnk)  , Model_Q(:,:,lchnk), &
    1197             :                                  phys_state(lchnk)%phis,  Model_PS(:,lchnk), &
    1198           0 :                                                   Model_S(:,:,lchnk), ncol)
    1199             :        end do
    1200             :      endif
    1201             : 
    1202             :      ! Optionally: Apply Zonal Filtering to Model state data
    1203             :      !-------------------------------------------------------
    1204           0 :      if(Nudge_ZonalFilter) then
    1205           0 :        call ZM%calc_amps(Model_U,Zonal_Bamp3d)
    1206           0 :        call ZM%eval_grid(Zonal_Bamp3d,Model_U)
    1207             : 
    1208           0 :        call ZM%calc_amps(Model_V,Zonal_Bamp3d)
    1209           0 :        call ZM%eval_grid(Zonal_Bamp3d,Model_V)
    1210             : 
    1211           0 :        call ZM%calc_amps(Model_T,Zonal_Bamp3d)
    1212           0 :        call ZM%eval_grid(Zonal_Bamp3d,Model_T)
    1213             : 
    1214           0 :        call ZM%calc_amps(Model_S,Zonal_Bamp3d)
    1215           0 :        call ZM%eval_grid(Zonal_Bamp3d,Model_S)
    1216             : 
    1217           0 :        call ZM%calc_amps(Model_Q,Zonal_Bamp3d)
    1218           0 :        call ZM%eval_grid(Zonal_Bamp3d,Model_Q)
    1219             : 
    1220           0 :        call ZM%calc_amps(Model_PS,Zonal_Bamp2d)
    1221           0 :        call ZM%eval_grid(Zonal_Bamp2d,Model_PS)
    1222             :      endif
    1223             :    endif ! ((Before_End) .and. (Update_Model)) then
    1224             : 
    1225             :    !----------------------------------------------------------------
    1226             :    ! When past the NEXT time, Update Nudging Arrays and time indices
    1227             :    !----------------------------------------------------------------
    1228           0 :    YMD1=(Nudge_Next_Year*10000) + (Nudge_Next_Month*100) + Nudge_Next_Day
    1229             :    call timemgr_time_ge(YMD1,Nudge_Next_Sec,            &
    1230           0 :                         YMD ,Sec           ,Update_Nudge)
    1231             : 
    1232           0 :    if((Before_End) .and. (Update_Nudge)) then
    1233             :      ! Increment the Nudge times by the current interval
    1234             :      !---------------------------------------------------
    1235           0 :      Nudge_Curr_Year =Nudge_Next_Year
    1236           0 :      Nudge_Curr_Month=Nudge_Next_Month
    1237           0 :      Nudge_Curr_Day  =Nudge_Next_Day
    1238           0 :      Nudge_Curr_Sec  =Nudge_Next_Sec
    1239           0 :      YMD1=(Nudge_Curr_Year*10000) + (Nudge_Curr_Month*100) + Nudge_Curr_Day
    1240             :      call timemgr_time_inc(YMD1,Nudge_Curr_Sec,              &
    1241           0 :                            YMD2,Nudge_Next_Sec,Nudge_Step,0,0)
    1242           0 :      Nudge_Next_Year =(YMD2/10000)
    1243           0 :      YMD2            = YMD2-(Nudge_Next_Year*10000)
    1244           0 :      Nudge_Next_Month=(YMD2/100)
    1245           0 :      Nudge_Next_Day  = YMD2-(Nudge_Next_Month*100)
    1246             : 
    1247             :      ! Set the analysis filename at the NEXT time.
    1248             :      !---------------------------------------------------------------
    1249             :      Nudge_File=interpret_filename_spec(Nudge_File_Template      , &
    1250             :                                          yr_spec=Nudge_Next_Year , &
    1251             :                                         mon_spec=Nudge_Next_Month, &
    1252             :                                         day_spec=Nudge_Next_Day  , &
    1253           0 :                                         sec_spec=Nudge_Next_Sec    )
    1254           0 :      if(masterproc) then
    1255           0 :       write(iulog,*) 'NUDGING: Reading analyses:',trim(Nudge_Path)//trim(Nudge_File)
    1256             :      endif
    1257             : 
    1258             :      ! Rotate Nudge_ObsInd() indices for new data, then update
    1259             :      ! the Nudge observation arrays with analysis data at the
    1260             :      ! NEXT==Nudge_ObsInd(1) time.
    1261             :      !----------------------------------------------------------
    1262           0 :      call nudging_update_analyses (trim(Nudge_Path)//trim(Nudge_File))
    1263             :    endif ! ((Before_End) .and. (Update_Nudge)) then
    1264             : 
    1265             :    !----------------------------------------------------------------
    1266             :    ! Toggle Nudging flag when the time interval is between
    1267             :    ! beginning and ending times, and all of the analyses files exist.
    1268             :    !----------------------------------------------------------------
    1269           0 :    if((After_Beg) .and. (Before_End)) then
    1270           0 :      if(Nudge_Force_Opt == 0) then
    1271             :        ! Verify that the NEXT analyses are available
    1272             :        !---------------------------------------------
    1273           0 :        Nudge_ON=Nudge_File_Present(Nudge_ObsInd(1))
    1274           0 :      elseif(Nudge_Force_Opt == 1) then
    1275             :        ! Verify that the CURR and NEXT analyses are available
    1276             :        !-----------------------------------------------------
    1277           0 :        Nudge_ON=(Nudge_File_Present(Nudge_ObsInd(1)) .and.  &
    1278           0 :                  Nudge_File_Present(Nudge_ObsInd(2))      )
    1279             :      else
    1280             :        ! Verify that the ALL analyses are available
    1281             :        !---------------------------------------------
    1282           0 :        Nudge_ON=.true.
    1283           0 :        do nn=1,Nudge_NumObs
    1284           0 :          if(.not.Nudge_File_Present(nn)) Nudge_ON=.false.
    1285             :        end do
    1286             :      endif
    1287           0 :      if(.not.Nudge_ON) then
    1288           0 :        if(masterproc) then
    1289           0 :          write(iulog,*) 'NUDGING: WARNING - analyses file NOT FOUND. Switching '
    1290           0 :          write(iulog,*) 'NUDGING:           nudging OFF to coast thru the gap. '
    1291             :        endif
    1292             :      endif
    1293             :    else
    1294           0 :      Nudge_ON=.false.
    1295             :    endif
    1296             : 
    1297             :    !-------------------------------------------------------
    1298             :    ! HERE Implement time dependence of Nudging Coefs HERE
    1299             :    !-------------------------------------------------------
    1300             : 
    1301             : 
    1302             :    !---------------------------------------------------
    1303             :    ! If Data arrays have changed update stepping arrays
    1304             :    !---------------------------------------------------
    1305           0 :    if((Before_End) .and. ((Update_Nudge) .or. (Update_Model))) then
    1306             : 
    1307             :      ! Now Load the Target values for nudging tendencies
    1308             :      !---------------------------------------------------
    1309           0 :      if(Nudge_Force_Opt == 0) then
    1310             :        ! Target is OBS data at NEXT time
    1311             :        !----------------------------------
    1312           0 :        do lchnk=begchunk,endchunk
    1313           0 :          ncol=phys_state(lchnk)%ncol
    1314           0 :          Target_U(:ncol,:pver,lchnk)=Nobs_U(:ncol,:pver,lchnk,Nudge_ObsInd(1))
    1315           0 :          Target_V(:ncol,:pver,lchnk)=Nobs_V(:ncol,:pver,lchnk,Nudge_ObsInd(1))
    1316           0 :          Target_T(:ncol,:pver,lchnk)=Nobs_T(:ncol,:pver,lchnk,Nudge_ObsInd(1))
    1317           0 :          Target_Q(:ncol,:pver,lchnk)=Nobs_Q(:ncol,:pver,lchnk,Nudge_ObsInd(1))
    1318           0 :          Target_PS(:ncol     ,lchnk)=Nobs_PS(:ncol     ,lchnk,Nudge_ObsInd(1))
    1319             :        end do
    1320           0 :      elseif(Nudge_Force_Opt == 1) then
    1321             :        ! Target is linear interpolation of OBS data CURR<-->NEXT time
    1322             :        !---------------------------------------------------------------
    1323           0 :        call ESMF_TimeSet(Date1,YY=Year,MM=Month,DD=Day,S=Sec)
    1324             :        call ESMF_TimeSet(Date2,YY=Nudge_Next_Year,MM=Nudge_Next_Month, &
    1325           0 :                                DD=Nudge_Next_Day , S=Nudge_Next_Sec    )
    1326           0 :        DateDiff =Date2-Date1
    1327           0 :        call ESMF_TimeIntervalGet(DateDiff,S=DeltaT,rc=rc)
    1328           0 :        Tfrac= float(DeltaT)/float(Nudge_Step)
    1329           0 :        do lchnk=begchunk,endchunk
    1330           0 :          ncol=phys_state(lchnk)%ncol
    1331           0 :          Target_U(:ncol,:pver,lchnk)=(1._r8-Tfrac)*Nobs_U(:ncol,:pver,lchnk,Nudge_ObsInd(1)) &
    1332           0 :                                            +Tfrac *Nobs_U(:ncol,:pver,lchnk,Nudge_ObsInd(2))
    1333           0 :          Target_V(:ncol,:pver,lchnk)=(1._r8-Tfrac)*Nobs_V(:ncol,:pver,lchnk,Nudge_ObsInd(1)) &
    1334           0 :                                            +Tfrac *Nobs_V(:ncol,:pver,lchnk,Nudge_ObsInd(2))
    1335           0 :          Target_T(:ncol,:pver,lchnk)=(1._r8-Tfrac)*Nobs_T(:ncol,:pver,lchnk,Nudge_ObsInd(1)) &
    1336           0 :                                            +Tfrac *Nobs_T(:ncol,:pver,lchnk,Nudge_ObsInd(2))
    1337           0 :          Target_Q(:ncol,:pver,lchnk)=(1._r8-Tfrac)*Nobs_Q(:ncol,:pver,lchnk,Nudge_ObsInd(1)) &
    1338           0 :                                            +Tfrac *Nobs_Q(:ncol,:pver,lchnk,Nudge_ObsInd(2))
    1339           0 :          Target_PS(:ncol     ,lchnk)=(1._r8-Tfrac)*Nobs_PS(:ncol     ,lchnk,Nudge_ObsInd(1)) &
    1340           0 :                                            +Tfrac *Nobs_PS(:ncol     ,lchnk,Nudge_ObsInd(2))
    1341             :        end do
    1342             :      else
    1343           0 :        write(iulog,*) 'NUDGING: Unknown Nudge_Force_Opt=',Nudge_Force_Opt
    1344           0 :        call endrun('nudging_timestep_init:: ERROR unknown Nudging_Force_Opt')
    1345             :      endif
    1346             : 
    1347             :      ! Now load Dry Static Energy values for Target
    1348             :      !---------------------------------------------
    1349           0 :      if(Nudge_TSmode == 0) then
    1350             :        ! DSE tendencies from Temperature only
    1351             :        !---------------------------------------
    1352           0 :        do lchnk=begchunk,endchunk
    1353           0 :          ncol=phys_state(lchnk)%ncol
    1354           0 :          Target_S(:ncol,:pver,lchnk)=cpair*Target_T(:ncol,:pver,lchnk)
    1355             :        end do
    1356           0 :      elseif(Nudge_TSmode == 1) then
    1357             :        ! Caluculate DSE tendencies from Temperature, Water Vapor, and Surface Pressure
    1358             :        !------------------------------------------------------------------------------
    1359           0 :        do lchnk=begchunk,endchunk
    1360           0 :          ncol=phys_state(lchnk)%ncol
    1361             :          call calc_DryStaticEnergy(Target_T(:,:,lchnk), Target_Q(:,:,lchnk), &
    1362             :                                  phys_state(lchnk)%phis, Target_PS(:,lchnk), &
    1363           0 :                                                   Target_S(:,:,lchnk), ncol)
    1364             :        end do
    1365             :      endif
    1366             : 
    1367             :      ! Set Tscale for the specified Forcing Option
    1368             :      !-----------------------------------------------
    1369           0 :      if(Nudge_TimeScale_Opt == 0) then
    1370             :        Tscale=1._r8
    1371           0 :      elseif(Nudge_TimeScale_Opt == 1) then
    1372           0 :        call ESMF_TimeSet(Date1,YY=Year,MM=Month,DD=Day,S=Sec)
    1373             :        call ESMF_TimeSet(Date2,YY=Nudge_Next_Year,MM=Nudge_Next_Month, &
    1374           0 :                                DD=Nudge_Next_Day , S=Nudge_Next_Sec    )
    1375           0 :        DateDiff =Date2-Date1
    1376           0 :        call ESMF_TimeIntervalGet(DateDiff,S=DeltaT,rc=rc)
    1377           0 :        Tscale=float(Nudge_Step)/float(DeltaT)
    1378             :      else
    1379           0 :        write(iulog,*) 'NUDGING: Unknown Nudge_TimeScale_Opt=',Nudge_TimeScale_Opt
    1380           0 :        call endrun('nudging_timestep_init:: ERROR unknown Nudging_TimeScale_Opt')
    1381             :      endif
    1382             : 
    1383             :      ! Update the nudging tendencies
    1384             :      !--------------------------------
    1385           0 :      do lchnk=begchunk,endchunk
    1386           0 :        ncol=phys_state(lchnk)%ncol
    1387           0 :        Nudge_Ustep(:ncol,:pver,lchnk)=(  Target_U(:ncol,:pver,lchnk)      &
    1388           0 :                                          -Model_U(:ncol,:pver,lchnk))     &
    1389           0 :                                       *Tscale*Nudge_Utau(:ncol,:pver,lchnk)
    1390           0 :        Nudge_Vstep(:ncol,:pver,lchnk)=(  Target_V(:ncol,:pver,lchnk)      &
    1391           0 :                                          -Model_V(:ncol,:pver,lchnk))     &
    1392           0 :                                       *Tscale*Nudge_Vtau(:ncol,:pver,lchnk)
    1393           0 :        Nudge_Sstep(:ncol,:pver,lchnk)=(  Target_S(:ncol,:pver,lchnk)      &
    1394           0 :                                          -Model_S(:ncol,:pver,lchnk))     &
    1395           0 :                                       *Tscale*Nudge_Stau(:ncol,:pver,lchnk)
    1396           0 :        Nudge_Qstep(:ncol,:pver,lchnk)=(  Target_Q(:ncol,:pver,lchnk)      &
    1397           0 :                                          -Model_Q(:ncol,:pver,lchnk))     &
    1398           0 :                                       *Tscale*Nudge_Qtau(:ncol,:pver,lchnk)
    1399           0 :        Nudge_PSstep(:ncol,     lchnk)=(  Target_PS(:ncol,lchnk)      &
    1400           0 :                                          -Model_PS(:ncol,lchnk))     &
    1401           0 :                                       *Tscale*Nudge_PStau(:ncol,lchnk)
    1402             :      end do
    1403             : 
    1404             :      !******************
    1405             :      ! DIAG
    1406             :      !******************
    1407             : !    if(masterproc) then
    1408             : !      write(iulog,*) 'PFC: Target_T(1,:pver,begchunk)=',Target_T(1,:pver,begchunk)
    1409             : !      write(iulog,*) 'PFC:  Model_T(1,:pver,begchunk)=',Model_T(1,:pver,begchunk)
    1410             : !      write(iulog,*) 'PFC: Target_S(1,:pver,begchunk)=',Target_S(1,:pver,begchunk)
    1411             : !      write(iulog,*) 'PFC:  Model_S(1,:pver,begchunk)=',Model_S(1,:pver,begchunk)
    1412             : !      write(iulog,*) 'PFC:      Target_PS(1,begchunk)=',Target_PS(1,begchunk)
    1413             : !      write(iulog,*) 'PFC:       Model_PS(1,begchunk)=',Model_PS(1,begchunk)
    1414             : !      write(iulog,*) 'PFC: Nudge_Sstep(1,:pver,begchunk)=',Nudge_Sstep(1,:pver,begchunk)
    1415             : !      write(iulog,*) 'PFC: Nudge_Xstep arrays updated:'
    1416             : !    endif
    1417             :    endif ! ((Before_End) .and. ((Update_Nudge) .or. (Update_Model))) then
    1418             : 
    1419             :    ! End Routine
    1420             :    !------------
    1421             : 
    1422           0 :   end subroutine nudging_timestep_init
    1423             :   !================================================================
    1424             : 
    1425             : 
    1426             :   !================================================================
    1427           0 :   subroutine nudging_timestep_tend(phys_state,phys_tend)
    1428             :    !
    1429             :    ! NUDGING_TIMESTEP_TEND:
    1430             :    !                If Nudging is ON, return the Nudging contributions
    1431             :    !                to forcing using the current contents of the Nudge
    1432             :    !                arrays. Send output to the cam history module as well.
    1433             :    !===============================================================
    1434           0 :    use physconst    ,only: cpair
    1435             :    use physics_types,only: physics_state,physics_ptend,physics_ptend_init
    1436             :    use constituents ,only: cnst_get_ind,pcnst
    1437             :    use ppgrid       ,only: pver,pcols,begchunk,endchunk
    1438             :    use cam_history  ,only: outfld
    1439             : 
    1440             :    ! Arguments
    1441             :    !-------------
    1442             :    type(physics_state), intent(in) :: phys_state
    1443             :    type(physics_ptend), intent(out):: phys_tend
    1444             : 
    1445             :    ! Local values
    1446             :    !--------------------
    1447             :    integer :: indw,ncol,lchnk
    1448             :    logical :: lq(pcnst)
    1449             : 
    1450           0 :    call cnst_get_ind('Q',indw)
    1451           0 :    lq(:)   =.false.
    1452           0 :    lq(indw)=.true.
    1453           0 :    call physics_ptend_init(phys_tend,phys_state%psetcols,'nudging',lu=.true.,lv=.true.,ls=.true.,lq=lq)
    1454             : 
    1455           0 :    if(Nudge_ON) then
    1456           0 :      lchnk=phys_state%lchnk
    1457           0 :      ncol =phys_state%ncol
    1458           0 :      phys_tend%u(:ncol,:pver)     =Nudge_Ustep(:ncol,:pver,lchnk)
    1459           0 :      phys_tend%v(:ncol,:pver)     =Nudge_Vstep(:ncol,:pver,lchnk)
    1460           0 :      phys_tend%s(:ncol,:pver)     =Nudge_Sstep(:ncol,:pver,lchnk)
    1461           0 :      phys_tend%q(:ncol,:pver,indw)=Nudge_Qstep(:ncol,:pver,lchnk)
    1462             : 
    1463           0 :      call outfld( 'Nudge_U',phys_tend%u                ,pcols,lchnk)
    1464           0 :      call outfld( 'Nudge_V',phys_tend%v                ,pcols,lchnk)
    1465           0 :      call outfld( 'Nudge_T',phys_tend%s/cpair          ,pcols,lchnk)
    1466           0 :      call outfld( 'Nudge_Q',phys_tend%q(1,1,indw)      ,pcols,lchnk)
    1467           0 :      call outfld('Target_U',Target_U(:,:,lchnk),pcols,lchnk)
    1468           0 :      call outfld('Target_V',Target_V(:,:,lchnk),pcols,lchnk)
    1469           0 :      call outfld('Target_T',Target_T(:,:,lchnk),pcols,lchnk)
    1470           0 :      call outfld('Target_Q',Target_Q(:,:,lchnk),pcols,lchnk)
    1471             :    endif
    1472             : 
    1473             :    ! End Routine
    1474             :    !------------
    1475             : 
    1476           0 :   end subroutine nudging_timestep_tend
    1477             :   !================================================================
    1478             : 
    1479             :   !================================================================
    1480           0 :   subroutine nudging_update_analyses(anal_file)
    1481             :    !
    1482             :    ! NUDGING_UPDATE_ANALYSES:
    1483             :    !                 Open the given analyses data file, read in
    1484             :    !                 U,V,T,Q, and PS values and then distribute
    1485             :    !                 the values to all of the chunks.
    1486             :    !===============================================================
    1487           0 :    use ppgrid          ,only: pcols,pver,begchunk,endchunk
    1488             :    use cam_pio_utils   ,only: cam_pio_openfile
    1489             :    use pio             ,only: PIO_BCAST_ERROR,PIO_INTERNAL_ERROR
    1490             :    use pio             ,only: pio_closefile,pio_seterrorhandling,file_desc_t
    1491             :    use ncdio_atm       ,only: infld
    1492             :    use cam_grid_support,only: cam_grid_id,cam_grid_get_dim_names,DLEN=>max_hcoordname_len
    1493             : 
    1494             :    ! Arguments
    1495             :    !-------------
    1496             :    character(len=*),intent(in):: anal_file
    1497             : 
    1498             :    ! Local values
    1499             :    !-------------
    1500             :    type(file_desc_t)  :: fileID
    1501             :    integer            :: nn,Nindex
    1502             :    logical            :: VARflag
    1503             :    integer            :: grid_id
    1504             :    integer            :: ierr
    1505             :    character(len=DLEN):: dim1name,dim2name
    1506             :    integer            :: err_handling
    1507             : 
    1508           0 :    real(r8),allocatable:: Tmp3D(:,:,:)
    1509           0 :    real(r8),allocatable:: Tmp2D(:,:)
    1510             : 
    1511             :    character(len=*), parameter :: prefix = 'nudging_update_analyses: '
    1512             : 
    1513             :    ! Rotate Nudge_ObsInd() indices, then check the existence of the analyses
    1514             :    ! file; broadcast the updated indices and file status to all the other MPI nodes.
    1515             :    ! If the file is not there, then just return.
    1516             :    !------------------------------------------------------------------------
    1517           0 :    if(masterproc) then
    1518           0 :      Nindex=Nudge_ObsInd(Nudge_NumObs)
    1519           0 :      do nn=Nudge_NumObs,2,-1
    1520           0 :        Nudge_ObsInd(nn)=Nudge_ObsInd(nn-1)
    1521             :      end do
    1522           0 :      Nudge_ObsInd(1)=Nindex
    1523           0 :      inquire(FILE=trim(anal_file),EXIST=Nudge_File_Present(Nudge_ObsInd(1)))
    1524           0 :      write(iulog,*)'NUDGING: Nudge_ObsInd=',Nudge_ObsInd
    1525           0 :      write(iulog,*)'NUDGING: Nudge_File_Present=',Nudge_File_Present
    1526             :    endif
    1527             : 
    1528           0 :    call MPI_bcast(Nudge_File_Present, Nudge_NumObs, mpi_logical, mstrid, mpicom, ierr)
    1529           0 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_File_Present')
    1530           0 :    call MPI_bcast(Nudge_ObsInd      , Nudge_NumObs, mpi_integer, mstrid, mpicom, ierr)
    1531           0 :    if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_ObsInd')
    1532             : 
    1533           0 :    if(.not. Nudge_File_Present(Nudge_ObsInd(1))) then
    1534           0 :       return
    1535             :    end if
    1536             : 
    1537             :    ! Open the file and get the fileID.
    1538             :    !-------------------------------------
    1539           0 :    call cam_pio_openfile(fileID,trim(anal_file),0)
    1540           0 :    call pio_seterrorhandling(fileID,PIO_BCAST_ERROR,oldmethod=err_handling)
    1541           0 :    if(masterproc) write(iulog,*)'PIO_OPEN: file=',trim(anal_file)
    1542             : 
    1543           0 :    grid_id = cam_grid_id('physgrid')
    1544           0 :    call cam_grid_get_dim_names(grid_id,dim1name,dim2name)
    1545             : 
    1546           0 :    allocate(Tmp3D(pcols,pver,begchunk:endchunk))
    1547           0 :    allocate(Tmp2D(pcols,begchunk:endchunk))
    1548             : 
    1549             :    ! Read in, U,V,T,Q, and PS
    1550             :    !----------------------------------
    1551             :    call infld('U',fileID,dim1name,'lev',dim2name,     &
    1552             :               1,pcols,1,pver,begchunk,endchunk,Tmp3D, &
    1553           0 :               VARflag,gridname='physgrid',timelevel=1 )
    1554           0 :    if(VARflag) then
    1555           0 :      if(Nudge_ZonalFilter) then
    1556           0 :        call ZM%calc_amps(Tmp3D,Zonal_Bamp3d)
    1557           0 :        call ZM%eval_grid(Zonal_Bamp3d,Tmp3D)
    1558             :      endif
    1559           0 :      Nobs_U(:,:,begchunk:endchunk,Nudge_ObsInd(1)) = Tmp3D(:,:,begchunk:endchunk)
    1560             :    else
    1561           0 :      call endrun('Variable "U" is missing in '//trim(anal_file))
    1562             :    endif
    1563             : 
    1564             :    call infld('V',fileID,dim1name,'lev',dim2name,     &
    1565             :               1,pcols,1,pver,begchunk,endchunk,Tmp3D, &
    1566           0 :               VARflag,gridname='physgrid',timelevel=1 )
    1567           0 :    if(VARflag) then
    1568           0 :      if(Nudge_ZonalFilter) then
    1569           0 :        call ZM%calc_amps(Tmp3D,Zonal_Bamp3d)
    1570           0 :        call ZM%eval_grid(Zonal_Bamp3d,Tmp3D)
    1571             :      endif
    1572           0 :      Nobs_V(:,:,begchunk:endchunk,Nudge_ObsInd(1)) = Tmp3D(:,:,begchunk:endchunk)
    1573             :    else
    1574           0 :      call endrun('Variable "V" is missing in '//trim(anal_file))
    1575             :    endif
    1576             : 
    1577             :    call infld('T',fileID,dim1name,'lev',dim2name,     &
    1578             :               1,pcols,1,pver,begchunk,endchunk,Tmp3D, &
    1579           0 :               VARflag,gridname='physgrid',timelevel=1 )
    1580           0 :    if(VARflag) then
    1581           0 :      if(Nudge_ZonalFilter) then
    1582           0 :        call ZM%calc_amps(Tmp3D,Zonal_Bamp3d)
    1583           0 :        call ZM%eval_grid(Zonal_Bamp3d,Tmp3D)
    1584             :      endif
    1585           0 :      Nobs_T(:,:,begchunk:endchunk,Nudge_ObsInd(1)) = Tmp3D(:,:,begchunk:endchunk)
    1586             :    else
    1587           0 :      call endrun('Variable "T" is missing in '//trim(anal_file))
    1588             :    endif
    1589             : 
    1590             :    call infld('Q',fileID,dim1name,'lev',dim2name,     &
    1591             :               1,pcols,1,pver,begchunk,endchunk,Tmp3D, &
    1592           0 :               VARflag,gridname='physgrid',timelevel=1 )
    1593           0 :    if(VARflag) then
    1594           0 :      if(Nudge_ZonalFilter) then
    1595           0 :        call ZM%calc_amps(Tmp3D,Zonal_Bamp3d)
    1596           0 :        call ZM%eval_grid(Zonal_Bamp3d,Tmp3D)
    1597             :      endif
    1598           0 :      Nobs_Q(:,:,begchunk:endchunk,Nudge_ObsInd(1)) = Tmp3D(:,:,begchunk:endchunk)
    1599             :    else
    1600           0 :      call endrun('Variable "Q" is missing in '//trim(anal_file))
    1601             :    endif
    1602             : 
    1603             :    call infld('PS',fileID,dim1name,dim2name,          &
    1604             :               1,pcols,begchunk,endchunk,Tmp2D,        &
    1605           0 :               VARflag,gridname='physgrid',timelevel=1 )
    1606           0 :    if(VARflag) then
    1607           0 :      if(Nudge_ZonalFilter) then
    1608           0 :        call ZM%calc_amps(Tmp2D,Zonal_Bamp2d)
    1609           0 :        call ZM%eval_grid(Zonal_Bamp2d,Tmp2D)
    1610             :      endif
    1611           0 :      Nobs_PS(:,begchunk:endchunk,Nudge_ObsInd(1)) = Tmp2D(:,begchunk:endchunk)
    1612             :    else
    1613           0 :      call endrun('Variable "PS" is missing in '//trim(anal_file))
    1614             :    endif
    1615             : 
    1616             :    ! Restore old error handling
    1617             :    !----------------------------
    1618           0 :    call pio_seterrorhandling(fileID,err_handling)
    1619             : 
    1620             :    ! Close the analyses file
    1621             :    !-----------------------
    1622           0 :    deallocate(Tmp3D)
    1623           0 :    deallocate(Tmp2D)
    1624           0 :    call pio_closefile(fileID)
    1625             : 
    1626             :    ! End Routine
    1627             :    !------------
    1628             : 
    1629           0 :   end subroutine nudging_update_analyses
    1630             :   !================================================================
    1631             : 
    1632             : 
    1633             :   !================================================================
    1634           0 :   subroutine nudging_set_profile(rlat,rlon,Nudge_prof,Wprof,nlev)
    1635             :    !
    1636             :    ! NUDGING_SET_PROFILE: for the given lat,lon, and Nudging_prof, set
    1637             :    !                      the verical profile of window coeffcients.
    1638             :    !                      Values range from 0. to 1. to affect spatial
    1639             :    !                      variations on nudging strength.
    1640             :    !===============================================================
    1641             : 
    1642             :    ! Arguments
    1643             :    !--------------
    1644             :    integer :: nlev,Nudge_prof
    1645             :    real(r8) :: rlat,rlon
    1646             :    real(r8) :: Wprof(nlev)
    1647             : 
    1648             :    ! Local values
    1649             :    !----------------
    1650             :    integer :: ilev
    1651             :    real(r8) :: Hcoef,latx,lonx,Vmax,Vmin
    1652             :    real(r8) :: lon_lo,lon_hi,lat_lo,lat_hi,lev_lo,lev_hi
    1653             : 
    1654             :    !---------------
    1655             :    ! set coeffcient
    1656             :    !---------------
    1657           0 :    if(Nudge_prof == 0) then
    1658             :      ! No Nudging
    1659             :      !-------------
    1660           0 :      Wprof(:)=0.0_r8
    1661           0 :    elseif(Nudge_prof == 1) then
    1662             :      ! Uniform Nudging
    1663             :      !-----------------
    1664           0 :      Wprof(:)=1.0_r8
    1665           0 :    elseif(Nudge_prof == 2) then
    1666             :      ! Localized Nudging with specified Heaviside window function
    1667             :      !------------------------------------------------------------
    1668           0 :      if(Nudge_Hwin_max <= Nudge_Hwin_min) then
    1669             :        ! For a constant Horizontal window function,
    1670             :        ! just set Hcoef to the maximum of Hlo/Hhi.
    1671             :        !--------------------------------------------
    1672           0 :        Hcoef=max(Nudge_Hwin_lo,Nudge_Hwin_hi)
    1673             :      else
    1674             :        ! get lat/lon relative to window center
    1675             :        !------------------------------------------
    1676           0 :        latx=rlat-Nudge_Hwin_lat0
    1677           0 :        lonx=rlon-Nudge_Hwin_lon0
    1678           0 :        if(lonx > 180._r8) lonx=lonx-360._r8
    1679           0 :        if(lonx <= -180._r8) lonx=lonx+360._r8
    1680             : 
    1681             :        ! Calcualte RAW window value
    1682             :        !-------------------------------
    1683           0 :        lon_lo=(Nudge_Hwin_lonWidthH+lonx)/Nudge_Hwin_lonDelta
    1684           0 :        lon_hi=(Nudge_Hwin_lonWidthH-lonx)/Nudge_Hwin_lonDelta
    1685           0 :        lat_lo=(Nudge_Hwin_latWidthH+latx)/Nudge_Hwin_latDelta
    1686           0 :        lat_hi=(Nudge_Hwin_latWidthH-latx)/Nudge_Hwin_latDelta
    1687             :        Hcoef=((1._r8+tanh(lon_lo))/2._r8)*((1._r8+tanh(lon_hi))/2._r8) &
    1688           0 :             *((1._r8+tanh(lat_lo))/2._r8)*((1._r8+tanh(lat_hi))/2._r8)
    1689             : 
    1690             :        ! Scale the horizontal window coef for specfied range of values.
    1691             :        !--------------------------------------------------------
    1692           0 :        Hcoef=(Hcoef-Nudge_Hwin_min)/(Nudge_Hwin_max-Nudge_Hwin_min)
    1693           0 :        Hcoef=(1._r8-Hcoef)*Nudge_Hwin_lo + Hcoef*Nudge_Hwin_hi
    1694             :      endif
    1695             : 
    1696             :      ! Load the RAW vertical window
    1697             :      !------------------------------
    1698           0 :      do ilev=1,nlev
    1699           0 :        lev_lo=(float(ilev)-Nudge_Vwin_Lindex)/Nudge_Vwin_Ldelta
    1700           0 :        lev_hi=(Nudge_Vwin_Hindex-float(ilev))/Nudge_Vwin_Hdelta
    1701           0 :        Wprof(ilev)=((1._r8+tanh(lev_lo))/2._r8)*((1._r8+tanh(lev_hi))/2._r8)
    1702             :      end do
    1703             : 
    1704             :      ! Scale the Window function to span the values between Vlo and Vhi:
    1705             :      !-----------------------------------------------------------------
    1706           0 :      Vmax=maxval(Wprof)
    1707           0 :      Vmin=minval(Wprof)
    1708           0 :      if((Vmax <= Vmin) .or. ((Nudge_Vwin_Hindex >= (nlev+1)) .and.  &
    1709             :                            (Nudge_Vwin_Lindex <= 0      )     )) then
    1710             :        ! For a constant Vertical window function,
    1711             :        ! load maximum of Vlo/Vhi into Wprof()
    1712             :        !--------------------------------------------
    1713           0 :        Vmax=max(Nudge_Vwin_lo,Nudge_Vwin_hi)
    1714           0 :        Wprof(:)=Vmax
    1715             :      else
    1716             :        ! Scale the RAW vertical window for specfied range of values.
    1717             :        !--------------------------------------------------------
    1718           0 :        Wprof(:)=(Wprof(:)-Vmin)/(Vmax-Vmin)
    1719           0 :        Wprof(:)=Nudge_Vwin_lo + Wprof(:)*(Nudge_Vwin_hi-Nudge_Vwin_lo)
    1720             :      endif
    1721             : 
    1722             :      ! The desired result is the product of the vertical profile
    1723             :      ! and the horizontal window coeffcient.
    1724             :      !----------------------------------------------------
    1725           0 :      Wprof(:)=Hcoef*Wprof(:)
    1726             :    else
    1727           0 :      call endrun('nudging_set_profile:: Unknown Nudge_prof value')
    1728             :    endif
    1729             : 
    1730             :    ! End Routine
    1731             :    !------------
    1732             : 
    1733           0 :   end subroutine nudging_set_profile
    1734             :   !================================================================
    1735             : 
    1736             :   !================================================================
    1737           0 :   subroutine nudging_final
    1738             : 
    1739           0 :     if (allocated(Target_U)) deallocate(Target_U)
    1740           0 :     if (allocated(Target_V)) deallocate(Target_V)
    1741           0 :     if (allocated(Target_T)) deallocate(Target_T)
    1742           0 :     if (allocated(Target_S)) deallocate(Target_S)
    1743           0 :     if (allocated(Target_Q)) deallocate(Target_Q)
    1744           0 :     if (allocated(Target_PS)) deallocate(Target_PS)
    1745           0 :     if (allocated(Model_U)) deallocate(Model_U)
    1746           0 :     if (allocated(Model_V)) deallocate(Model_V)
    1747           0 :     if (allocated(Model_T)) deallocate(Model_T)
    1748           0 :     if (allocated(Model_S)) deallocate(Model_S)
    1749           0 :     if (allocated(Model_Q)) deallocate(Model_Q)
    1750           0 :     if (allocated(Model_PS)) deallocate(Model_PS)
    1751           0 :     if (allocated(Nudge_Utau)) deallocate(Nudge_Utau)
    1752           0 :     if (allocated(Nudge_Vtau)) deallocate(Nudge_Vtau)
    1753           0 :     if (allocated(Nudge_Stau)) deallocate(Nudge_Stau)
    1754           0 :     if (allocated(Nudge_Qtau)) deallocate(Nudge_Qtau)
    1755           0 :     if (allocated(Nudge_PStau)) deallocate(Nudge_PStau)
    1756           0 :     if (allocated(Nudge_Ustep)) deallocate(Nudge_Ustep)
    1757           0 :     if (allocated(Nudge_Vstep)) deallocate(Nudge_Vstep)
    1758           0 :     if (allocated(Nudge_Sstep)) deallocate(Nudge_Sstep)
    1759           0 :     if (allocated(Nudge_Qstep)) deallocate(Nudge_Qstep)
    1760           0 :     if (allocated(Nudge_PSstep)) deallocate(Nudge_PSstep)
    1761             : 
    1762           0 :     if (allocated(Nudge_ObsInd)) deallocate(Nudge_ObsInd)
    1763           0 :     if (allocated(Nudge_File_Present)) deallocate(Nudge_File_Present)
    1764           0 :     if (allocated(Nobs_U)) deallocate(Nobs_U)
    1765           0 :     if (allocated(Nobs_V)) deallocate(Nobs_V)
    1766           0 :     if (allocated(Nobs_T)) deallocate(Nobs_T)
    1767           0 :     if (allocated(Nobs_Q)) deallocate(Nobs_Q)
    1768           0 :     if (allocated(Nobs_PS)) deallocate(Nobs_PS)
    1769           0 :     if (allocated(Zonal_Bamp2d)) deallocate(Zonal_Bamp2d)
    1770           0 :     if (allocated(Zonal_Bamp3d)) deallocate(Zonal_Bamp3d)
    1771             : 
    1772           0 :     call ZM%final()
    1773             : 
    1774           0 :   end subroutine nudging_final
    1775             :   !================================================================
    1776             : 
    1777             :   !================================================================
    1778           0 :   real(r8) function nudging_set_PSprofile(rlat,rlon,Nudge_PSprof)
    1779             :    !
    1780             :    ! NUDGING_SET_PSPROFILE: for the given lat and lon set the surface
    1781             :    !                      pressure profile value for the specified index.
    1782             :    !                      Values range from 0. to 1. to affect spatial
    1783             :    !                      variations on nudging strength.
    1784             :    !===============================================================
    1785             : 
    1786             :    ! Arguments
    1787             :    !--------------
    1788             :    real(r8) :: rlat,rlon
    1789             :    integer  :: Nudge_PSprof
    1790             : 
    1791             :    ! Local values
    1792             :    !----------------
    1793             : 
    1794             :    !---------------
    1795             :    ! set coeffcient
    1796             :    !---------------
    1797           0 :    if(Nudge_PSprof == 0) then
    1798             :      ! No Nudging
    1799             :      !-------------
    1800             :      nudging_set_PSprofile=0.0_r8
    1801           0 :    elseif(Nudge_PSprof == 1) then
    1802             :      ! Uniform Nudging
    1803             :      !-----------------
    1804             :      nudging_set_PSprofile=1.0_r8
    1805             :    else
    1806           0 :      call endrun('nudging_set_PSprofile:: Unknown Nudge_prof value')
    1807             :    endif
    1808             : 
    1809             :    ! End Routine
    1810             :    !------------
    1811             : 
    1812           0 :   end function nudging_set_PSprofile
    1813             :   !================================================================
    1814             : 
    1815             : 
    1816             :   !================================================================
    1817           0 :   subroutine calc_DryStaticEnergy(t, q, phis, ps, dse, ncol)
    1818             :    !
    1819             :    ! calc_DryStaticEnergy: Given the temperature, specific humidity, surface pressure,
    1820             :    !                       and surface geopotential for a chunk containing 'ncol' columns,
    1821             :    !                       calculate and return the corresponding dry static energy values.
    1822             :    !--------------------------------------------------------------------------------------
    1823             :    use shr_kind_mod, only: r8 => shr_kind_r8
    1824             :    use ppgrid,       only: pver, pverp
    1825             :    use dycore,       only: dycore_is
    1826             :    use hycoef,       only: hyai, hybi, ps0, hyam, hybm
    1827             :    use physconst,    only: zvir, gravit, cpair, rair
    1828             :    !
    1829             :    ! Input/Output arguments
    1830             :    !-----------------------
    1831             :    integer , intent(in) :: ncol      ! Number of columns in chunk
    1832             :    real(r8), intent(in) :: t(:,:)    ! (pcols,pver) - temperature
    1833             :    real(r8), intent(in) :: q(:,:)    ! (pcols,pver) - specific humidity
    1834             :    real(r8), intent(in) :: ps(:)     ! (pcols)      - surface pressure
    1835             :    real(r8), intent(in) :: phis(:)   ! (pcols)      - surface geopotential
    1836             :    real(r8), intent(out):: dse(:,:)  ! (pcols,pver)  - dry static energy
    1837             :    !
    1838             :    ! Local variables
    1839             :    !------------------
    1840             :    logical  :: fvdyn                 ! finite volume dynamics
    1841             :    integer  :: ii,kk                 ! Lon, level, level indices
    1842             :    real(r8) :: tvfac                 ! Virtual temperature factor
    1843           0 :    real(r8) :: hkk(ncol)             ! diagonal element of hydrostatic matrix
    1844           0 :    real(r8) :: hkl(ncol)             ! off-diagonal element
    1845           0 :    real(r8) :: pint(ncol,pverp)      ! Interface pressures
    1846           0 :    real(r8) :: pmid(ncol,pver )      ! Midpoint pressures
    1847           0 :    real(r8) :: zi(ncol,pverp)        ! Height above surface at interfaces
    1848           0 :    real(r8) :: zm(ncol,pver )        ! Geopotential height at mid level
    1849             : 
    1850             :    ! Set dynamics flag
    1851             :    !-------------------
    1852           0 :    fvdyn = dycore_is ('LR')
    1853             : 
    1854             :    ! Load Pressure values and midpoint pressures
    1855             :    !----------------------------------------------
    1856           0 :    do kk=1,pverp
    1857           0 :      do ii=1,ncol
    1858           0 :        pint(ii,kk)=(hyai(kk)*ps0)+(hybi(kk)*ps(ii))
    1859             :      end do
    1860             :    end do
    1861           0 :    do kk=1,pver
    1862           0 :      do ii=1,ncol
    1863           0 :        pmid(ii,kk)=(hyam(kk)*ps0)+(hybm(kk)*ps(ii))
    1864             :      end do
    1865             :    end do
    1866             : 
    1867             :    ! The surface height is zero by definition.
    1868             :    !-------------------------------------------
    1869           0 :    do ii = 1,ncol
    1870           0 :      zi(ii,pverp) = 0.0_r8
    1871             :    end do
    1872             : 
    1873             :    ! Compute the dry static energy, zi, zm from bottom up
    1874             :    ! Note, zi(i,k) is the interface above zm(i,k)
    1875             :    !---------------------------------------------------------
    1876           0 :    do kk=pver,1,-1
    1877             : 
    1878             :      ! First set hydrostatic elements consistent with dynamics
    1879             :      !--------------------------------------------------------
    1880           0 :      if(fvdyn) then
    1881           0 :        do ii=1,ncol
    1882           0 :          hkl(ii)=log(pint(ii,kk+1))-log(pint(ii,kk))
    1883           0 :          hkk(ii)=1._r8-(hkl(ii)*pint(ii,kk)/(pint(ii,kk+1)-pint(ii,kk)))
    1884             :        end do
    1885             :      else
    1886           0 :        do ii=1,ncol
    1887           0 :          hkl(ii)=(pint(ii,kk+1)-pint(ii,kk))/pmid(ii,kk)
    1888           0 :          hkk(ii)=0.5_r8*hkl(ii)
    1889             :        end do
    1890             :      endif
    1891             : 
    1892             :      ! Now compute zm, zi, and dse  (WACCM-X vars rairv/zairv/cpairv not used!)
    1893             :      !------------------------------------------------------------------------
    1894           0 :      do ii=1,ncol
    1895           0 :        tvfac=t(ii,kk)*rair*(1._r8+(zvir*q(ii,kk)))/gravit
    1896           0 :        zm (ii,kk)=zi(ii,kk+1) + (tvfac*hkk(ii))
    1897           0 :        zi (ii,kk)=zi(ii,kk+1) + (tvfac*hkl(ii))
    1898           0 :        dse(ii,kk)=(t(ii,kk)*cpair) + phis(ii) + (gravit*zm(ii,kk))
    1899             :      end do
    1900             : 
    1901             :    end do ! kk=pver,1,-1
    1902             : 
    1903             :    ! End Routine
    1904             :    !-----------
    1905             : 
    1906           0 :   end subroutine calc_DryStaticEnergy
    1907             :   !================================================================
    1908             : 
    1909             : end module nudging

Generated by: LCOV version 1.14