LCOV - code coverage report
Current view: top level - cicecore/cicedyn/general - ice_forcing.F90 (source / functions) Hit Total Coverage
Test: 231018-211459:8916b9ff2c:1:quick Lines: 299 1933 15.47 %
Date: 2023-10-18 15:30:36 Functions: 12 52 23.08 %

          Line data    Source code
       1             : #ifdef ncdf
       2             : #define USE_NETCDF
       3             : #endif
       4             : !=======================================================================
       5             : !
       6             : ! Reads and interpolates forcing data for atmosphere and ocean quantities.
       7             : !
       8             : ! authors: Elizabeth C. Hunke and William H. Lipscomb, LANL
       9             : !
      10             : ! 2004 WHL: Block structure added
      11             : ! 2005 WHL: ECMWF option added
      12             : ! 2006 ECH: LY option added
      13             : ! 2006 WHL: Module name changed from ice_flux_in
      14             : ! 2006 ECH: Fixed bugs, rearranged routines, edited comments, etc.
      15             : !           Added NCAR ocean forcing file
      16             : !           Converted to free source form (F90)
      17             : ! 2007: netcdf version of read_data added by Alison McLaren, Met Office
      18             : !
      19             :       module ice_forcing
      20             : 
      21             :       use ice_kinds_mod
      22             :       use ice_boundary, only: ice_HaloUpdate
      23             :       use ice_blocks, only: nx_block, ny_block
      24             :       use ice_domain, only: halo_info
      25             :       use ice_domain_size, only: ncat, max_blocks, nx_global, ny_global, nfreq
      26             :       use ice_communicate, only: my_task, master_task
      27             :       use ice_calendar, only: istep, istep1, &
      28             :                               msec, mday, mmonth, myear, yday, daycal, &   ! LCOV_EXCL_LINE
      29             :                               daymo, days_per_year, compute_days_between
      30             :       use ice_fileunits, only: nu_diag, nu_forcing
      31             :       use ice_exit, only: abort_ice
      32             :       use ice_read_write, only: ice_open, ice_read, &
      33             :                                 ice_get_ncvarsize, ice_read_vec_nc, &   ! LCOV_EXCL_LINE
      34             :                                 ice_open_nc, ice_read_nc, ice_close_nc
      35             :       use ice_timers, only: ice_timer_start, ice_timer_stop, timer_readwrite, &
      36             :                             timer_bound, timer_forcing
      37             :       use ice_arrays_column, only: oceanmixed_ice, restore_bgc
      38             :       use ice_constants, only: c0, c1, c2, c3, c4, c5, c8, c10, c12, c15, c20, &
      39             :                                c180, c360, c365, c1000, c3600
      40             :       use ice_constants, only: p001, p01, p1, p2, p25, p5, p6
      41             :       use ice_constants, only: cm_to_m
      42             :       use ice_constants, only: field_loc_center, field_type_scalar, &
      43             :                                field_type_vector, field_loc_NEcorner
      44             :       use icepack_intfc, only: icepack_warnings_flush, icepack_warnings_aborted
      45             :       use icepack_intfc, only: icepack_sea_freezing_temperature
      46             :       use icepack_intfc, only: icepack_init_wave, icepack_init_parameters
      47             :       use icepack_intfc, only: icepack_query_tracer_indices, icepack_query_parameters
      48             : 
      49             :       implicit none
      50             :       private
      51             :       public :: init_forcing_atmo, init_forcing_ocn, alloc_forcing, &
      52             :                 get_forcing_atmo, get_forcing_ocn, get_wave_spec, &   ! LCOV_EXCL_LINE
      53             :                 read_clim_data, read_clim_data_nc, &   ! LCOV_EXCL_LINE
      54             :                 interpolate_data, interp_coeff_monthly, &   ! LCOV_EXCL_LINE
      55             :                 read_data_nc_point, interp_coeff, &   ! LCOV_EXCL_LINE
      56             :                 init_snowtable
      57             : 
      58             :       integer (kind=int_kind), public :: &
      59             :          ycycle          , & ! number of years in forcing cycle, set by namelist   ! LCOV_EXCL_LINE
      60             :          fyear_init      , & ! first year of data in forcing cycle, set by namelist   ! LCOV_EXCL_LINE
      61             :          fyear           , & ! current year in forcing cycle, varying during the run   ! LCOV_EXCL_LINE
      62             :          fyear_final         ! last year in cycle, computed at init
      63             : 
      64             :       character (char_len_long) :: &        ! input data file names
      65             :           uwind_file, &  ! this is also used a generic file containing all fields for JRA55   ! LCOV_EXCL_LINE
      66             :           vwind_file, &   ! LCOV_EXCL_LINE
      67             :            wind_file, &   ! LCOV_EXCL_LINE
      68             :           strax_file, &   ! LCOV_EXCL_LINE
      69             :           stray_file, &   ! LCOV_EXCL_LINE
      70             :            tair_file, &   ! LCOV_EXCL_LINE
      71             :           humid_file, &   ! LCOV_EXCL_LINE
      72             :            rhoa_file, &   ! LCOV_EXCL_LINE
      73             :             fsw_file, &   ! LCOV_EXCL_LINE
      74             :             flw_file, &   ! LCOV_EXCL_LINE
      75             :            rain_file, &   ! LCOV_EXCL_LINE
      76             :             sst_file, &   ! LCOV_EXCL_LINE
      77             :             sss_file, &   ! LCOV_EXCL_LINE
      78             :          sublim_file, &   ! LCOV_EXCL_LINE
      79             :            snow_file
      80             : 
      81             :       character (char_len_long), dimension(:), allocatable, public :: &  ! input data file names
      82             :         topmelt_file, &   ! LCOV_EXCL_LINE
      83             :         botmelt_file
      84             : 
      85             :       real (kind=dbl_kind), public  :: &
      86             :            c1intp, c2intp     ! interpolation coefficients
      87             : 
      88             :       integer (kind=int_kind) :: &
      89             :            oldrecnum = 0  , & ! old record number (save between steps)   ! LCOV_EXCL_LINE
      90             :            oldrecnum4X = 0    !
      91             : 
      92             :       real (kind=dbl_kind), dimension(:,:,:), allocatable, public :: &
      93             :           cldf                ! cloud fraction
      94             : 
      95             :       real (kind=dbl_kind), dimension(:,:,:,:), allocatable, public :: &
      96             :             fsw_data, & ! field values at 2 temporal data points   ! LCOV_EXCL_LINE
      97             :            cldf_data, &   ! LCOV_EXCL_LINE
      98             :           fsnow_data, &   ! LCOV_EXCL_LINE
      99             :            Tair_data, &   ! LCOV_EXCL_LINE
     100             :            uatm_data, &   ! LCOV_EXCL_LINE
     101             :            vatm_data, &   ! LCOV_EXCL_LINE
     102             :            wind_data, &   ! LCOV_EXCL_LINE
     103             :           strax_data, &   ! LCOV_EXCL_LINE
     104             :           stray_data, &   ! LCOV_EXCL_LINE
     105             :              Qa_data, &   ! LCOV_EXCL_LINE
     106             :            rhoa_data, &   ! LCOV_EXCL_LINE
     107             :             flw_data, &   ! LCOV_EXCL_LINE
     108             :             sst_data, &   ! LCOV_EXCL_LINE
     109             :             sss_data, &   ! LCOV_EXCL_LINE
     110             :            uocn_data, &   ! LCOV_EXCL_LINE
     111             :            vocn_data, &   ! LCOV_EXCL_LINE
     112             :          sublim_data, &   ! LCOV_EXCL_LINE
     113             :           frain_data
     114             : 
     115             :       real (kind=dbl_kind), dimension(:,:,:,:,:), allocatable, public :: &
     116             :         topmelt_data, &   ! LCOV_EXCL_LINE
     117             :         botmelt_data
     118             : 
     119             :       real (kind=dbl_kind), dimension(:,:,:,:,:), allocatable :: &
     120             :           wave_spectrum_data ! field values at 2 temporal data points
     121             : 
     122             :       character(char_len), public :: &
     123             :          atm_data_format, & ! 'bin'=binary or 'nc'=netcdf   ! LCOV_EXCL_LINE
     124             :          ocn_data_format, & ! 'bin'=binary or 'nc'=netcdf   ! LCOV_EXCL_LINE
     125             :          atm_data_type, & ! 'default', 'monthly', 'ncar', 'box2001'   ! LCOV_EXCL_LINE
     126             :                           ! 'hadgem', 'oned', 'calm', 'uniform'
     127             :                           ! 'JRA55' or 'JRA55do'
     128             :          bgc_data_type, & ! 'default', 'clim'
     129             :          ocn_data_type, & ! 'default', 'clim', 'ncar', 'oned', 'calm', 'box2001'   ! LCOV_EXCL_LINE
     130             :                           ! 'hadgem_sst' or 'hadgem_sst_uvocn', 'uniform'
     131             :          ice_data_type, & ! 'latsst', 'box2001', 'boxslotcyl', etc
     132             :          ice_data_conc, & ! 'p5','p8','p9','c1','parabolic', 'box2001', etc   ! LCOV_EXCL_LINE
     133             :          ice_data_dist, & ! 'box2001','gauss', 'uniform', etc   ! LCOV_EXCL_LINE
     134             :          precip_units     ! 'mm_per_month', 'mm_per_sec', 'mks','m_per_sec'
     135             : 
     136             :       logical (kind=log_kind), public :: &
     137             :          rotate_wind      ! rotate wind/stress to computational grid from true north directed
     138             : 
     139             :       character(char_len_long), public :: &
     140             :          atm_data_dir , & ! top directory for atmospheric data   ! LCOV_EXCL_LINE
     141             :          ocn_data_dir , & ! top directory for ocean data   ! LCOV_EXCL_LINE
     142             :          wave_spec_dir, & ! dir name for wave spectrum   ! LCOV_EXCL_LINE
     143             :          wave_spec_file,& ! file name for wave spectrum   ! LCOV_EXCL_LINE
     144             :          oceanmixed_file  ! file name for ocean forcing data
     145             : 
     146             :       integer (kind=int_kind), parameter :: &
     147             :          nfld = 8   ! number of fields to search for in forcing file
     148             : 
     149             :       ! as in the dummy atm (latm)
     150             :       real (kind=dbl_kind), parameter, public :: &
     151             :          frcvdr = 0.28_dbl_kind, & ! frac of incoming sw in vis direct band   ! LCOV_EXCL_LINE
     152             :          frcvdf = 0.24_dbl_kind, & ! frac of incoming sw in vis diffuse band   ! LCOV_EXCL_LINE
     153             :          frcidr = 0.31_dbl_kind, & ! frac of incoming sw in near IR direct band   ! LCOV_EXCL_LINE
     154             :          frcidf = 0.17_dbl_kind    ! frac of incoming sw in near IR diffuse band
     155             : 
     156             :       real (kind=dbl_kind), dimension (:,:,:,:,:), allocatable, public :: &
     157             :          ocn_frc_m   ! ocn data for 12 months
     158             : 
     159             :       logical (kind=log_kind), public :: &
     160             :          restore_ocn                 ! restore sst if true
     161             : 
     162             :       integer (kind=int_kind), public :: &
     163             :          trestore                    ! restoring time scale (days)
     164             : 
     165             :       real (kind=dbl_kind), public :: &
     166             :          trest                       ! restoring time scale (sec)
     167             : 
     168             :       logical (kind=log_kind), public :: &
     169             :          debug_forcing               ! prints forcing debugging output if true
     170             : 
     171             :       real (dbl_kind), dimension(:), allocatable, public :: &
     172             :          jday_atm  ! jday time vector from atm forcing files
     173             : 
     174             :       integer (kind=int_kind), public :: &
     175             :          Njday_atm ! Number of atm forcing timesteps
     176             : 
     177             :       character (len=char_len_long), public :: &
     178             :          snw_filename        ! filename for snow lookup table
     179             : 
     180             :       character (char_len), public :: &
     181             :          snw_rhos_fname , &  ! snow table 1d rhos field name   ! LCOV_EXCL_LINE
     182             :          snw_Tgrd_fname , &  ! snow table 1d Tgrd field name   ! LCOV_EXCL_LINE
     183             :          snw_T_fname    , &  ! snow table 1d T field name   ! LCOV_EXCL_LINE
     184             :          snw_tau_fname  , &  ! snow table 3d tau field name   ! LCOV_EXCL_LINE
     185             :          snw_kappa_fname, &  ! snow table 3d kappa field name   ! LCOV_EXCL_LINE
     186             :          snw_drdt0_fname     ! snow table 3d drdt0 field name
     187             : 
     188             :       ! PRIVATE:
     189             : 
     190             :       real (dbl_kind), parameter :: &
     191             :          mixed_layer_depth_default = c20  ! default mixed layer depth in m
     192             : 
     193             :       logical (kind=log_kind), parameter :: &
     194             :          local_debug = .false.   ! local debug flag
     195             : 
     196             : !=======================================================================
     197             : 
     198             :       contains
     199             : 
     200             : !=======================================================================
     201             : !
     202             : ! Allocate space for all variables
     203             : !
     204          37 :       subroutine alloc_forcing
     205             :       integer (int_kind) :: ierr
     206             :       character(len=*), parameter :: subname = '(alloc_forcing)'
     207             : 
     208             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
     209             : 
     210             :       allocate ( &
     211             :                  cldf(nx_block,ny_block, max_blocks), & ! cloud fraction   ! LCOV_EXCL_LINE
     212             :             fsw_data(nx_block,ny_block,2,max_blocks), & ! field values at 2 temporal data points   ! LCOV_EXCL_LINE
     213             :            cldf_data(nx_block,ny_block,2,max_blocks), &   ! LCOV_EXCL_LINE
     214             :           fsnow_data(nx_block,ny_block,2,max_blocks), &   ! LCOV_EXCL_LINE
     215             :            Tair_data(nx_block,ny_block,2,max_blocks), &   ! LCOV_EXCL_LINE
     216             :            uatm_data(nx_block,ny_block,2,max_blocks), &   ! LCOV_EXCL_LINE
     217             :            vatm_data(nx_block,ny_block,2,max_blocks), &   ! LCOV_EXCL_LINE
     218             :            wind_data(nx_block,ny_block,2,max_blocks), &   ! LCOV_EXCL_LINE
     219             :           strax_data(nx_block,ny_block,2,max_blocks), &   ! LCOV_EXCL_LINE
     220             :           stray_data(nx_block,ny_block,2,max_blocks), &   ! LCOV_EXCL_LINE
     221             :              Qa_data(nx_block,ny_block,2,max_blocks), &   ! LCOV_EXCL_LINE
     222             :            rhoa_data(nx_block,ny_block,2,max_blocks), &   ! LCOV_EXCL_LINE
     223             :             flw_data(nx_block,ny_block,2,max_blocks), &   ! LCOV_EXCL_LINE
     224             :             sst_data(nx_block,ny_block,2,max_blocks), &   ! LCOV_EXCL_LINE
     225             :             sss_data(nx_block,ny_block,2,max_blocks), &   ! LCOV_EXCL_LINE
     226             :            uocn_data(nx_block,ny_block,2,max_blocks), &   ! LCOV_EXCL_LINE
     227             :            vocn_data(nx_block,ny_block,2,max_blocks), &   ! LCOV_EXCL_LINE
     228             :          sublim_data(nx_block,ny_block,2,max_blocks), &   ! LCOV_EXCL_LINE
     229             :           frain_data(nx_block,ny_block,2,max_blocks), &   ! LCOV_EXCL_LINE
     230             :         topmelt_data(nx_block,ny_block,2,max_blocks,ncat), &   ! LCOV_EXCL_LINE
     231             :         botmelt_data(nx_block,ny_block,2,max_blocks,ncat), &   ! LCOV_EXCL_LINE
     232             :            ocn_frc_m(nx_block,ny_block,  max_blocks,nfld,12), & ! ocn data for 12 months   ! LCOV_EXCL_LINE
     233             :         topmelt_file(ncat), &   ! LCOV_EXCL_LINE
     234             :         botmelt_file(ncat), &   ! LCOV_EXCL_LINE
     235             :         wave_spectrum_data(nx_block,ny_block,nfreq,2,max_blocks), &   ! LCOV_EXCL_LINE
     236          37 :          stat=ierr)
     237          37 :       if (ierr/=0) call abort_ice('(alloc_forcing): Out of Memory')
     238             : 
     239             : ! initialize this, not set in box2001 (and some other forcings?)
     240             : 
     241      111936 :       cldf = c0
     242             : 
     243          37 :       end subroutine alloc_forcing
     244             : 
     245             : !=======================================================================
     246             : 
     247          37 :       subroutine init_forcing_atmo
     248             : 
     249             : ! Determine the current and final year of the forcing cycle based on
     250             : ! namelist input; initialize the atmospheric forcing data filenames.
     251             : 
     252             :       use ice_calendar, only: use_leap_years
     253             : 
     254             :       integer (kind=int_kind) :: modadj   ! adjustment for mod function
     255             :       character(len=*), parameter :: subname = '(init_forcing_atmo)'
     256             : 
     257             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
     258             : 
     259          37 :       modadj      = abs((min(0,myear-fyear_init)/ycycle+1)*ycycle)
     260          37 :       fyear       = fyear_init + mod(myear-fyear_init+modadj,ycycle)
     261          37 :       fyear_final = fyear_init + ycycle - 1 ! last year in forcing cycle
     262             : 
     263             :       if (local_debug .and. my_task == master_task) then
     264             :          write(nu_diag,*) subname,'fdbg fyear = ',fyear,fyear_init,fyear_final
     265             :          write(nu_diag,*) subname,'fdbg atm_data_type = ',trim(atm_data_type)
     266             :       endif
     267             : 
     268          37 :       if (trim(atm_data_type) /= 'default' .and. &
     269             :                           my_task == master_task) then
     270           7 :          write (nu_diag,*) ' Initial forcing data year = ',fyear_init
     271           7 :          write (nu_diag,*) ' Final   forcing data year = ',fyear_final
     272             :       endif
     273             : 
     274          37 :       if (trim(atm_data_type) == 'hadgem' .and. &
     275             :           trim(precip_units) /= 'mks') then
     276           0 :          if (my_task == master_task) then
     277           0 :             write (nu_diag,*) 'WARNING: HadGEM atmospheric data chosen with wrong precip_units'
     278           0 :             write (nu_diag,*) 'WARNING:   Changing precip_units to mks (i.e. kg/m2 s).'
     279             :          endif
     280             :          call abort_ice(error_message=subname//' HadGEM precip_units error', &
     281           0 :             file=__FILE__, line=__LINE__)
     282             :       endif
     283             : 
     284          37 :       if (use_leap_years .and. (index(trim(atm_data_type),'JRA55') == 0 .and. &
     285             :                                 trim(atm_data_type) /= 'hycom'       .and. &   ! LCOV_EXCL_LINE
     286             :                                 trim(atm_data_type) /= 'box2001'))   then
     287           0 :          write(nu_diag,*) 'use_leap_years option is currently only supported for'
     288           0 :          write(nu_diag,*) 'JRA55, JRA55do, default , and box2001 atmospheric data'
     289           0 :          call abort_ice(error_message=subname, file=__FILE__, line=__LINE__)
     290             :       endif
     291             : 
     292             :     !-------------------------------------------------------------------
     293             :     ! Get filenames for input forcing data
     294             :     !-------------------------------------------------------------------
     295             : 
     296             :       ! default forcing values from init_flux_atm
     297          37 :       if (trim(atm_data_type) == 'ncar') then
     298           0 :          call NCAR_files(fyear)
     299          37 :       elseif (index(trim(atm_data_type),'JRA55') > 0) then
     300          21 :          call JRA55_files(fyear)
     301          16 :       elseif (trim(atm_data_type) == 'hadgem') then
     302           0 :          call hadgem_files(fyear)
     303          16 :       elseif (trim(atm_data_type) == 'monthly') then
     304           0 :          call monthly_files(fyear)
     305          16 :       elseif (trim(atm_data_type) == 'oned') then
     306           0 :          call oned_files
     307          16 :       elseif (trim(atm_data_type) == 'ISPOL') then
     308           0 :          call ISPOL_files
     309          16 :       elseif (trim(atm_data_type) == 'box2001') then
     310          16 :          call box2001_data_atm
     311           0 :       elseif (trim(atm_data_type) == 'uniform_northeast') then
     312           0 :          call uniform_data_atm('NE')
     313           0 :       elseif (trim(atm_data_type) == 'uniform_north') then
     314           0 :          call uniform_data_atm('N')
     315           0 :       elseif (trim(atm_data_type) == 'uniform_east') then
     316           0 :          call uniform_data_atm('E')
     317           0 :       elseif (trim(atm_data_type) == 'uniform_south') then
     318           0 :          call uniform_data_atm('S')
     319           0 :       elseif (trim(atm_data_type) == 'uniform_west') then
     320           0 :          call uniform_data_atm('W')
     321           0 :       elseif (trim(atm_data_type) == 'calm') then
     322           0 :          call uniform_data_atm('N',c0) ! direction does not matter when c0
     323           0 :       elseif (trim(atm_data_type) == 'hycom') then
     324           0 :          call hycom_atm_files
     325           0 :       elseif (trim(atm_data_type) == 'default') then
     326             :          ! don't need to do anything more
     327             :       else
     328             :         call abort_ice (error_message=subname//' ERROR atm_data_type unknown = '// &
     329           0 :                         trim(atm_data_type), file=__FILE__, line=__LINE__)
     330             :       endif
     331             : 
     332          37 :       end subroutine init_forcing_atmo
     333             : 
     334             : !=======================================================================
     335             : 
     336          37 :       subroutine init_forcing_ocn(dt)
     337             : 
     338             : ! Set sea surface salinity and freezing temperature to annual mean value
     339             : !  using a 12-month climatology.
     340             : ! Read sst data for current month, and adjust sst based on freezing
     341             : ! temperature.  No interpolation in time.
     342             : 
     343             : ! Note: SST is subsequently prognosed if CICE is run
     344             : ! with a mixed layer ocean (oceanmixed_ice = T), and can be
     345             : ! restored to data (restore_ocn = T).
     346             : 
     347             :       use ice_blocks, only: nx_block, ny_block
     348             :       use ice_domain, only: nblocks
     349             :       use ice_domain_size, only: max_blocks
     350             :       use ice_flux, only: sss, sst, Tf
     351             : 
     352             :       real (kind=dbl_kind), intent(in) :: &
     353             :          dt                   ! time step
     354             : 
     355             :       ! local variables
     356             : 
     357             :       integer (kind=int_kind) :: &
     358             :          i, j, iblk       , & ! horizontal indices   ! LCOV_EXCL_LINE
     359             :          k                , & ! month index   ! LCOV_EXCL_LINE
     360             :          fid              , & ! file id for netCDF file   ! LCOV_EXCL_LINE
     361             :          nbits
     362             : 
     363             :       logical (kind=log_kind) :: diag
     364             : 
     365           8 :       real (kind=dbl_kind) :: secday
     366             : 
     367             :       character (char_len) :: &
     368             :          fieldname            ! field name in netcdf file
     369             : 
     370             :       real (kind=dbl_kind), dimension (nx_block,ny_block,max_blocks) :: &
     371       27874 :          work1
     372             : 
     373             :       character(len=*), parameter :: subname = '(init_forcing_ocn)'
     374             : 
     375             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
     376             : 
     377          37 :       call icepack_query_parameters(secday_out=secday)
     378          37 :       call icepack_warnings_flush(nu_diag)
     379          37 :       if (icepack_warnings_aborted()) call abort_ice(error_message=subname, &
     380           0 :          file=__FILE__, line=__LINE__)
     381             : 
     382          37 :       call alloc_forcing()
     383             : 
     384      223996 :       sst_data(:,:,:,:) = c0
     385      223996 :       sss_data(:,:,:,:) = c0
     386      223996 :       uocn_data(:,:,:,:) = c0
     387      223996 :       vocn_data(:,:,:,:) = c0
     388             : 
     389          37 :       nbits = 64              ! double precision data
     390             : 
     391          37 :       if (restore_ocn .or. restore_bgc) then
     392           0 :          if (trestore == 0) then
     393           0 :             trest = dt        ! use data instantaneously
     394             :          else
     395           0 :             trest = real(trestore,kind=dbl_kind) * secday ! seconds
     396             :          endif
     397             :       endif
     398             : 
     399             :     !-------------------------------------------------------------------
     400             :     ! Sea surface salinity (SSS)
     401             :     ! initialize to annual climatology created from monthly data
     402             :     !-------------------------------------------------------------------
     403             : 
     404          37 :       if (trim(ocn_data_type) == 'clim') then
     405             : 
     406           0 :          sss_file = trim(ocn_data_dir)//'/sss.mm.100x116.da' ! gx3 only
     407             : 
     408           0 :          if (my_task == master_task) then
     409           0 :             write (nu_diag,*) ' '
     410           0 :             write (nu_diag,*) 'SSS climatology computed from:'
     411           0 :             write (nu_diag,*) trim(sss_file)
     412             :          endif
     413             : 
     414           0 :          if (my_task == master_task) &
     415           0 :               call ice_open (nu_forcing, sss_file, nbits)
     416             : 
     417           0 :          sss(:,:,:) = c0
     418             : 
     419           0 :          do k = 1,12            ! loop over 12 months
     420             :             call ice_read (nu_forcing, k, work1, 'rda8', debug_forcing, &
     421           0 :                            field_loc_center, field_type_scalar)
     422           0 :             !$OMP PARALLEL DO PRIVATE(iblk,i,j)
     423           0 :             do iblk = 1, nblocks
     424           0 :                do j = 1, ny_block
     425           0 :                do i = 1, nx_block
     426           0 :                   sss(i,j,iblk) = sss(i,j,iblk) + work1(i,j,iblk)
     427             :                enddo
     428             :                enddo
     429             :             enddo
     430             :             !$OMP END PARALLEL DO
     431             :          enddo                  ! k
     432             : 
     433           0 :          !$OMP PARALLEL DO PRIVATE(iblk,i,j)
     434           0 :          do iblk = 1, nblocks
     435           0 :             do j = 1, ny_block
     436           0 :             do i = 1, nx_block
     437           0 :                sss(i,j,iblk) = sss(i,j,iblk) / c12   ! annual average
     438           0 :                sss(i,j,iblk) = max(sss(i,j,iblk),c0)
     439             :             enddo
     440             :             enddo
     441             :          enddo
     442             :          !$OMP END PARALLEL DO
     443             : 
     444           0 :          call ocn_freezing_temperature
     445             : 
     446           0 :          if (my_task == master_task) close(nu_forcing)
     447             : 
     448             :     !-------------------------------------------------------------------
     449             :     ! Sea surface temperature (SST)
     450             :     ! initialize to data for current month
     451             :     !-------------------------------------------------------------------
     452             : 
     453           0 :          if (nx_global == 320) then ! gx1
     454           0 :             sst_file = trim(ocn_data_dir)//'/sst_clim_hurrell.dat'
     455             :          else                   ! gx3
     456           0 :             sst_file = trim(ocn_data_dir)//'/sst.mm.100x116.da'
     457             :          endif
     458             : 
     459           0 :          if (my_task == master_task) then
     460           0 :             write (nu_diag,*) ' '
     461           0 :             write (nu_diag,*) 'Initial SST file:', trim(sst_file)
     462             :          endif
     463             : 
     464           0 :          if (my_task == master_task) &
     465           0 :               call ice_open (nu_forcing, sst_file, nbits)
     466             : 
     467             :          call ice_read (nu_forcing, mmonth, sst, 'rda8', debug_forcing, &
     468           0 :                         field_loc_center, field_type_scalar)
     469             : 
     470           0 :          if (my_task == master_task) close(nu_forcing)
     471             : 
     472             :          ! Make sure sst is not less than freezing temperature Tf
     473           0 :          !$OMP PARALLEL DO PRIVATE(iblk,i,j)
     474           0 :          do iblk = 1, nblocks
     475           0 :             do j = 1, ny_block
     476           0 :             do i = 1, nx_block
     477           0 :                sst(i,j,iblk) = max(sst(i,j,iblk),Tf(i,j,iblk))
     478             :             enddo
     479             :             enddo
     480             :          enddo
     481             :          !$OMP END PARALLEL DO
     482             : 
     483          37 :       elseif (trim(ocn_data_type) == 'hadgem_sst' .or.  &
     484             :           trim(ocn_data_type) == 'hadgem_sst_uvocn') then
     485             : 
     486           0 :          diag = .true.   ! write diagnostic information
     487             : 
     488           0 :          sst_file = trim (ocn_data_dir)//'/MONTHLY/sst.1997.nc'
     489             : 
     490           0 :          if (my_task == master_task) then
     491             : 
     492           0 :              write (nu_diag,*) ' '
     493           0 :              write (nu_diag,*) 'Initial SST file:', trim(sst_file)
     494             : 
     495           0 :              call ice_open_nc(sst_file,fid)
     496             : 
     497             :          endif
     498             : 
     499           0 :          fieldname='sst'
     500           0 :          call ice_read_nc(fid,mmonth,fieldname,sst,diag)
     501             : 
     502           0 :          if (my_task == master_task) call ice_close_nc(fid)
     503             : 
     504             :          ! Make sure sst is not less than freezing temperature Tf
     505           0 :          !$OMP PARALLEL DO PRIVATE(iblk,i,j)
     506           0 :          do iblk = 1, nblocks
     507           0 :             do j = 1, ny_block
     508           0 :             do i = 1, nx_block
     509           0 :                sst(i,j,iblk) = max(sst(i,j,iblk),Tf(i,j,iblk))
     510             :             enddo
     511             :             enddo
     512             :          enddo
     513             :          !$OMP END PARALLEL DO
     514             : 
     515          37 :       elseif (trim(ocn_data_type) == 'ncar') then
     516           0 :          call ocn_data_ncar_init
     517             : !        call ocn_data_ncar_init_3D
     518             : 
     519          37 :       elseif (trim(ocn_data_type) == 'hycom') then
     520           0 :          call ocn_data_hycom_init
     521             : 
     522          37 :       elseif (trim(ocn_data_type) == 'box2001') then
     523          16 :          call box2001_data_ocn
     524             : 
     525             :       ! uniform forcing options
     526          21 :       elseif (trim(ocn_data_type) == 'uniform_northeast') then
     527           0 :          call uniform_data_ocn('NE',p1)
     528          21 :       elseif (trim(ocn_data_type) == 'uniform_east') then
     529           0 :          call uniform_data_ocn('E',p1)
     530          21 :       elseif (trim(ocn_data_type) == 'uniform_north') then
     531           0 :          call uniform_data_ocn('N',p1)
     532          21 :       elseif (trim(ocn_data_type) == 'calm') then
     533           0 :          call uniform_data_ocn('N',c0) ! directon does not matter for c0
     534          21 :       elseif (trim(ocn_data_type) == 'default') then
     535             :          ! don't need to do anything more
     536             :       else
     537             :          call abort_ice (error_message=subname//' ERROR ocn_data_type unknown = '// &
     538           0 :                          trim(ocn_data_type), file=__FILE__, line=__LINE__)
     539             :       endif
     540             : 
     541          37 :       end subroutine init_forcing_ocn
     542             : 
     543             : !=======================================================================
     544             : 
     545           0 :       subroutine ocn_freezing_temperature
     546             : 
     547             :  ! Compute ocean freezing temperature Tf based on tfrz_option
     548             :  ! 'minus1p8'         Tf = -1.8 C (default)
     549             :  ! 'linear_salt'      Tf = -depressT * sss
     550             :  ! 'mushy'            Tf conforms with mushy layer thermo (ktherm=2)
     551             : 
     552             :       use ice_blocks, only: nx_block, ny_block
     553             :       use ice_domain, only: nblocks
     554             :       use ice_flux, only: sss, Tf
     555             : 
     556             :       ! local variables
     557             : 
     558             :       integer (kind=int_kind) :: &
     559             :          i, j, iblk           ! horizontal indices
     560             : 
     561             :       character(len=*), parameter :: subname = '(ocn_freezing_temperature)'
     562             : 
     563             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
     564             : 
     565           0 :       !$OMP PARALLEL DO PRIVATE(iblk,i,j)
     566           0 :       do iblk = 1, nblocks
     567           0 :          do j = 1, ny_block
     568           0 :          do i = 1, nx_block
     569           0 :             Tf(i,j,iblk) = icepack_sea_freezing_temperature(sss(i,j,iblk))
     570             :          enddo
     571             :          enddo
     572             :       enddo
     573             :       !$OMP END PARALLEL DO
     574             : 
     575           0 :       call icepack_warnings_flush(nu_diag)
     576           0 :       if (icepack_warnings_aborted()) call abort_ice(error_message=subname, &
     577           0 :          file=__FILE__, line=__LINE__)
     578             : 
     579           0 :       end subroutine ocn_freezing_temperature
     580             : 
     581             : !=======================================================================
     582             : 
     583        5784 :       subroutine get_forcing_atmo
     584             : 
     585             : ! Get atmospheric forcing data and interpolate as necessary
     586             : 
     587             :       use ice_blocks, only: block, get_block
     588             :       use ice_domain, only: nblocks, blocks_ice
     589             :       use ice_flux, only: Tair, fsw, flw, frain, fsnow, Qa, rhoa, &
     590             :           uatm, vatm, strax, stray, zlvl, wind, swvdr, swvdf, swidr, swidf, &   ! LCOV_EXCL_LINE
     591             :           potT, sst
     592             :       use ice_state, only: aice, trcr
     593             :       use ice_grid, only: ANGLET, hm
     594             : 
     595             :       integer (kind=int_kind) :: &
     596             :          iblk, &              ! block index   ! LCOV_EXCL_LINE
     597             :          ilo,ihi,jlo,jhi, &   ! beginning and end of physical domain   ! LCOV_EXCL_LINE
     598             :          modadj, &            ! adjustment to make mod a postive number   ! LCOV_EXCL_LINE
     599             :          fyear_old, &         ! fyear setting on last timestep   ! LCOV_EXCL_LINE
     600             :          nt_Tsfc
     601             : 
     602             :       type (block) :: &
     603             :          this_block           ! block information for current block
     604             : 
     605             :       character(len=*), parameter :: subname = '(get_forcing_atmo)'
     606             : 
     607             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
     608             : 
     609        5784 :       call ice_timer_start(timer_forcing)
     610             : 
     611        5784 :       fyear_old = fyear
     612        5784 :       modadj    = abs((min(0,myear-fyear_init)/ycycle+1)*ycycle)
     613        5784 :       fyear     = fyear_init + mod(myear-fyear_init+modadj,ycycle)
     614        5784 :       if (trim(atm_data_type) /= 'default' .and. &
     615             :           (istep <= 1 .or. fyear /= fyear_old)) then
     616          37 :          if (my_task == master_task) then
     617           7 :             write (nu_diag,*) ' Set current forcing data year = ',fyear
     618             :          endif
     619             :       endif
     620             : 
     621        5784 :       call icepack_query_tracer_indices(nt_Tsfc_out=nt_Tsfc)
     622        5784 :       call icepack_warnings_flush(nu_diag)
     623        5784 :       if (icepack_warnings_aborted()) call abort_ice(error_message=subname, &
     624           0 :          file=__FILE__, line=__LINE__)
     625             : 
     626             :       !-------------------------------------------------------------------
     627             :       ! Read and interpolate atmospheric data
     628             :       !-------------------------------------------------------------------
     629             : 
     630             :       if (local_debug .and. my_task == master_task) then
     631             :          write(nu_diag,*) subname,'fdbg fyear = ',fyear
     632             :          write(nu_diag,*) subname,'fdbg atm_data_type = ',trim(atm_data_type)
     633             :       endif
     634             : 
     635        5784 :       if (trim(atm_data_type) == 'ncar') then
     636           0 :          call ncar_data
     637        5784 :       elseif (index(trim(atm_data_type),'JRA55') > 0) then
     638        2904 :          call JRA55_data
     639        2880 :       elseif (trim(atm_data_type) == 'hadgem') then
     640           0 :          call hadgem_data
     641        2880 :       elseif (trim(atm_data_type) == 'monthly') then
     642           0 :          call monthly_data
     643        2880 :       elseif (trim(atm_data_type) == 'oned') then
     644           0 :          call oned_data
     645        2880 :       elseif (trim(atm_data_type) == 'box2001') then
     646        2880 :          call box2001_data_atm
     647           0 :       elseif (trim(atm_data_type) == 'uniform_northeast') then
     648           0 :          call uniform_data_atm('NE')
     649           0 :       elseif (trim(atm_data_type) == 'uniform_north') then
     650           0 :          call uniform_data_atm('N')
     651           0 :       elseif (trim(atm_data_type) == 'uniform_east') then
     652           0 :          call uniform_data_atm('E')
     653           0 :       elseif (trim(atm_data_type) == 'uniform_south') then
     654           0 :          call uniform_data_atm('S')
     655           0 :       elseif (trim(atm_data_type) == 'uniform_west') then
     656           0 :          call uniform_data_atm('W')
     657           0 :       elseif (trim(atm_data_type) == 'calm') then
     658           0 :          call uniform_data_atm('N',c0) ! direction does not matter when c0
     659           0 :       elseif (trim(atm_data_type) == 'hycom') then
     660           0 :          call hycom_atm_data
     661             :       !elseif (trim(atm_data_type) == 'uniform_northeast') then
     662             :       !elseif (trim(atm_data_type) == 'uniform_east') then
     663             :       !elseif (trim(atm_data_type) == 'uniform_north') then
     664             :       else    ! default values set in init_flux
     665           0 :          return
     666             :       endif
     667             : 
     668             :       !-------------------------------------------------------------------
     669             :       ! Convert forcing data to fields needed by ice model
     670             :       !-------------------------------------------------------------------
     671             : 
     672        2880 :       !$OMP PARALLEL DO PRIVATE(iblk,ilo,ihi,jlo,jhi,this_block)
     673        8688 :       do iblk = 1, nblocks
     674             : 
     675        5784 :          this_block = get_block(blocks_ice(iblk),iblk)
     676        5784 :          ilo = this_block%ilo
     677        5784 :          ihi = this_block%ihi
     678        5784 :          jlo = this_block%jlo
     679        5784 :          jhi = this_block%jhi
     680             : 
     681             :          call prepare_forcing (nx_block, ny_block, &
     682             :                                ilo, ihi, jlo, jhi, &   ! LCOV_EXCL_LINE
     683             :                                hm    (:,:,iblk),   &   ! LCOV_EXCL_LINE
     684             :                                Tair  (:,:,iblk),   &   ! LCOV_EXCL_LINE
     685             :                                fsw   (:,:,iblk),   &   ! LCOV_EXCL_LINE
     686             :                                cldf  (:,:,iblk),   &   ! LCOV_EXCL_LINE
     687             :                                flw   (:,:,iblk),   &   ! LCOV_EXCL_LINE
     688             :                                frain (:,:,iblk),   &   ! LCOV_EXCL_LINE
     689             :                                fsnow (:,:,iblk),   &   ! LCOV_EXCL_LINE
     690             :                                Qa    (:,:,iblk),   &   ! LCOV_EXCL_LINE
     691             :                                rhoa  (:,:,iblk),   &   ! LCOV_EXCL_LINE
     692             :                                uatm  (:,:,iblk),   &   ! LCOV_EXCL_LINE
     693             :                                vatm  (:,:,iblk),   &   ! LCOV_EXCL_LINE
     694             :                                strax (:,:,iblk),   &   ! LCOV_EXCL_LINE
     695             :                                stray (:,:,iblk),   &   ! LCOV_EXCL_LINE
     696             :                                zlvl  (:,:,iblk),   &   ! LCOV_EXCL_LINE
     697             :                                wind  (:,:,iblk),   &   ! LCOV_EXCL_LINE
     698             :                                swvdr (:,:,iblk),   &   ! LCOV_EXCL_LINE
     699             :                                swvdf (:,:,iblk),   &   ! LCOV_EXCL_LINE
     700             :                                swidr (:,:,iblk),   &   ! LCOV_EXCL_LINE
     701             :                                swidf (:,:,iblk),   &   ! LCOV_EXCL_LINE
     702             :                                potT  (:,:,iblk),   &   ! LCOV_EXCL_LINE
     703             :                                ANGLET(:,:,iblk),   &   ! LCOV_EXCL_LINE
     704             :                                trcr  (:,:,nt_Tsfc,iblk), &   ! LCOV_EXCL_LINE
     705             :                                sst   (:,:,iblk),   &   ! LCOV_EXCL_LINE
     706       11568 :                                aice  (:,:,iblk) )
     707             : 
     708             :       enddo                     ! iblk
     709             :       !$OMP END PARALLEL DO
     710             : 
     711        5784 :       call ice_timer_start(timer_bound)
     712             :       call ice_HaloUpdate (swvdr,             halo_info, &
     713        5784 :                            field_loc_center,  field_type_scalar)
     714             :       call ice_HaloUpdate (swvdf,             halo_info, &
     715        5784 :                            field_loc_center,  field_type_scalar)
     716             :       call ice_HaloUpdate (swidr,             halo_info, &
     717        5784 :                            field_loc_center,  field_type_scalar)
     718             :       call ice_HaloUpdate (swidf,             halo_info, &
     719        5784 :                            field_loc_center,  field_type_scalar)
     720        5784 :       call ice_timer_stop(timer_bound)
     721             : 
     722        5784 :       call ice_timer_stop(timer_forcing)
     723             : 
     724        5784 :       end subroutine get_forcing_atmo
     725             : 
     726             : !=======================================================================
     727             : 
     728        5784 :       subroutine get_forcing_ocn (dt)
     729             : 
     730             : ! Read and interpolate annual climatologies of SSS and SST.
     731             : ! Restore model SST to data if desired.
     732             : ! Interpolate ocean fields to U grid if necessary.
     733             : 
     734             :       real (kind=dbl_kind), intent(in) :: &
     735             :          dt      ! time step
     736             : 
     737             :       character(len=*), parameter :: subname = '(get_forcing_ocn)'
     738             : 
     739             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
     740             : 
     741        5784 :       call ice_timer_start(timer_forcing)
     742             : 
     743             :       if (local_debug .and. my_task == master_task) then
     744             :          write(nu_diag,*) subname,'fdbg fyear = ',fyear
     745             :          write(nu_diag,*) subname,'fdbg ocn_data_type = ',trim(ocn_data_type)
     746             :       endif
     747             : 
     748        5784 :       if (trim(ocn_data_type) == 'clim') then
     749           0 :          call ocn_data_clim(dt)
     750        5784 :       elseif (trim(ocn_data_type) == 'ncar' .or.  &
     751             :               trim(ocn_data_type) == 'ISPOL') then
     752           0 :          call ocn_data_ncar(dt)
     753        5784 :       elseif (trim(ocn_data_type) == 'hadgem_sst' .or.  &
     754             :               trim(ocn_data_type) == 'hadgem_sst_uvocn') then
     755           0 :          call ocn_data_hadgem(dt)
     756        5784 :       elseif (trim(ocn_data_type) == 'oned') then
     757           0 :          call ocn_data_oned
     758        5784 :       elseif (trim(ocn_data_type) == 'hycom') then
     759             : !         call ocn_data_hycom(dt)
     760             : !MHRI: NOT IMPLEMENTED YET
     761        5784 :       elseif (trim(ocn_data_type) == 'box2001') then
     762        2880 :          call box2001_data_ocn
     763             :       ! uniform forcing options
     764        2904 :       elseif (trim(ocn_data_type) == 'uniform_northeast') then
     765             : ! tcraig, not time varying
     766           0 :          call uniform_data_ocn('NE',p1)
     767        2904 :       elseif (trim(ocn_data_type) == 'uniform_east') then
     768           0 :          call uniform_data_ocn('E',p1)
     769        2904 :       elseif (trim(ocn_data_type) == 'uniform_north') then
     770           0 :          call uniform_data_ocn('N',p1)
     771        2904 :       elseif (trim(ocn_data_type) == 'calm') then
     772           0 :          call uniform_data_ocn('N',c0) ! directon does not matter for c0
     773             :       endif
     774             : 
     775        5784 :       call ice_timer_stop(timer_forcing)
     776             : 
     777        5784 :       end subroutine get_forcing_ocn
     778             : 
     779             : !=======================================================================
     780             : 
     781           0 :       subroutine read_data (flag, recd, yr, ixm, ixx, ixp, &
     782             :                             maxrec, data_file, field_data, &   ! LCOV_EXCL_LINE
     783             :                             field_loc, field_type)
     784             : 
     785             : ! If data is at the beginning of a one-year record, get data from
     786             : !  the previous year.
     787             : ! If data is at the end of a one-year record, get data from the
     788             : !  following year.
     789             : ! If no earlier data exists (beginning of fyear_init), then
     790             : !  (1) For monthly data, get data from the end of fyear_final.
     791             : !  (2) For more frequent data, let the ixm value equal the
     792             : !      first value of the year.
     793             : ! If no later data exists (end of fyear_final), then
     794             : !  (1) For monthly data, get data from the beginning of fyear_init.
     795             : !  (2) For more frequent data, let the ixp value
     796             : !      equal the last value of the year.
     797             : ! In other words, we assume persistence when daily or 6-hourly
     798             : !   data is missing, and we assume periodicity when monthly data
     799             : !   is missing.
     800             : 
     801             :       use ice_diagnostics, only: debug_model_step
     802             : 
     803             :       logical (kind=log_kind), intent(in) :: flag
     804             : 
     805             :       integer (kind=int_kind), intent(in) :: &
     806             :          recd                , & ! baseline record number   ! LCOV_EXCL_LINE
     807             :          yr                  , & ! year of forcing data   ! LCOV_EXCL_LINE
     808             :          ixm, ixx, ixp       , & ! record numbers of 3 data values   ! LCOV_EXCL_LINE
     809             :                                  ! relative to recd
     810             :          maxrec                  ! maximum record value
     811             : 
     812             :       real (kind=dbl_kind), dimension(nx_block,ny_block,2,max_blocks), intent(inout) :: &
     813             :          field_data              ! 2 values needed for interpolation
     814             : 
     815             :       integer (kind=int_kind), intent(in) :: &
     816             :            field_loc, &      ! location of field on staggered grid   ! LCOV_EXCL_LINE
     817             :            field_type        ! type of field (scalar, vector, angle)
     818             : 
     819             :       ! local variables
     820             : 
     821             :       character (char_len_long) :: &
     822             :          data_file               ! data file to be read
     823             : 
     824             :       integer (kind=int_kind) :: &
     825             :          nbits            , & ! = 32 for single precision, 64 for double   ! LCOV_EXCL_LINE
     826             :          nrec             , & ! record number to read   ! LCOV_EXCL_LINE
     827             :          n2, n4           , & ! like ixm and ixp, but   ! LCOV_EXCL_LINE
     828             :                               ! adjusted at beginning and end of data
     829             :          arg                  ! value of time argument in field_data
     830             : 
     831             :       character(len=*), parameter :: subname = '(read_data)'
     832             : 
     833             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
     834             : 
     835           0 :       call ice_timer_start(timer_readwrite)  ! reading/writing
     836             : 
     837           0 :       nbits = 64              ! double precision data
     838             : 
     839           0 :       if (istep1 > debug_model_step) debug_forcing = .true.  !! debugging
     840             : 
     841           0 :       if (my_task==master_task .and. (debug_forcing)) then
     842           0 :          write(nu_diag,*) '  ', trim(data_file)
     843             :       endif
     844             : 
     845           0 :       if (flag) then
     846             : 
     847             :       !-----------------------------------------------------------------
     848             :       ! Initialize record counters
     849             :       ! (n2, n4 will change only at the very beginning or end of
     850             :       !  a forcing cycle.)
     851             :       !-----------------------------------------------------------------
     852           0 :          n2 = ixm
     853           0 :          n4 = ixp
     854           0 :          arg = 0
     855             : 
     856             :       !-----------------------------------------------------------------
     857             :       ! read data
     858             :       !-----------------------------------------------------------------
     859             : 
     860           0 :          if (ixm /= -99) then
     861             :          ! currently in first half of data interval
     862           0 :             if (ixx <= 1) then
     863           0 :                if (yr > fyear_init) then ! get data from previous year
     864           0 :                   call file_year (data_file, yr-1)
     865             :                else             ! yr = fyear_init, no prior data exists
     866           0 :                   if (maxrec > 12) then ! extrapolate from first record
     867           0 :                      if (ixx == 1) n2 = ixx
     868             :                   else          ! go to end of fyear_final
     869           0 :                      call file_year (data_file, fyear_final)
     870             :                   endif
     871             :                endif            ! yr > fyear_init
     872             :             endif               ! ixx <= 1
     873             : 
     874           0 :             call ice_open (nu_forcing, data_file, nbits)
     875             : 
     876           0 :             arg = 1
     877           0 :             nrec = recd + n2
     878           0 :             call ice_read (nu_forcing, nrec, field_data(:,:,arg,:), &
     879           0 :                            'rda8', debug_forcing, field_loc, field_type)
     880             : 
     881           0 :             if (ixx==1 .and. my_task == master_task) close(nu_forcing)
     882             :          endif                  ! ixm ne -99
     883             : 
     884             :          ! always read ixx data from data file for current year
     885           0 :          call file_year (data_file, yr)
     886           0 :          call ice_open (nu_forcing, data_file, nbits)
     887             : 
     888           0 :          arg = arg + 1
     889           0 :          nrec = recd + ixx
     890           0 :          call ice_read (nu_forcing, nrec, field_data(:,:,arg,:), &
     891           0 :                         'rda8', debug_forcing, field_loc, field_type)
     892             : 
     893           0 :          if (ixp /= -99) then
     894             :          ! currently in latter half of data interval
     895           0 :             if (ixx==maxrec) then
     896           0 :                if (yr < fyear_final) then ! get data from following year
     897           0 :                   if (my_task == master_task) close(nu_forcing)
     898           0 :                   call file_year (data_file, yr+1)
     899           0 :                   call ice_open (nu_forcing, data_file, nbits)
     900             :                else             ! yr = fyear_final, no more data exists
     901           0 :                   if (maxrec > 12) then ! extrapolate from ixx
     902           0 :                      n4 = ixx
     903             :                   else          ! go to beginning of fyear_init
     904           0 :                      if (my_task == master_task) close(nu_forcing)
     905           0 :                      call file_year (data_file, fyear_init)
     906             : 
     907           0 :                      call ice_open (nu_forcing, data_file, nbits)
     908             : 
     909             :                   endif
     910             :                endif            ! yr < fyear_final
     911             :             endif               ! ixx = maxrec
     912             : 
     913           0 :             arg = arg + 1
     914           0 :             nrec = recd + n4
     915           0 :             call ice_read (nu_forcing, nrec, field_data(:,:,arg,:), &
     916           0 :                            'rda8', debug_forcing, field_loc, field_type)
     917             :          endif                  ! ixp /= -99
     918             : 
     919           0 :          if (my_task == master_task) close(nu_forcing)
     920             : 
     921             :       endif                     ! flag
     922             : 
     923           0 :       call ice_timer_stop(timer_readwrite)  ! reading/writing
     924             : 
     925           0 :       end subroutine read_data
     926             : 
     927             : !=======================================================================
     928             : 
     929           0 :       subroutine read_data_nc (flag, recd, yr, ixm, ixx, ixp, &
     930             :                             maxrec, data_file, fieldname, field_data, &   ! LCOV_EXCL_LINE
     931             :                             field_loc, field_type)
     932             : 
     933             : ! If data is at the beginning of a one-year record, get data from
     934             : !  the previous year.
     935             : ! If data is at the end of a one-year record, get data from the
     936             : !  following year.
     937             : ! If no earlier data exists (beginning of fyear_init), then
     938             : !  (1) For monthly data, get data from the end of fyear_final.
     939             : !  (2) For more frequent data, let the ixm value equal the
     940             : !      first value of the year.
     941             : ! If no later data exists (end of fyear_final), then
     942             : !  (1) For monthly data, get data from the beginning of fyear_init.
     943             : !  (2) For more frequent data, let the ixp value
     944             : !      equal the last value of the year.
     945             : ! In other words, we assume persistence when daily or 6-hourly
     946             : !   data is missing, and we assume periodicity when monthly data
     947             : !   is missing.
     948             : !
     949             : ! Adapted by Alison McLaren, Met Office from read_data
     950             : 
     951             :       use ice_diagnostics, only: debug_model_step
     952             : 
     953             :       logical (kind=log_kind), intent(in) :: flag
     954             : 
     955             :       integer (kind=int_kind), intent(in) :: &
     956             :          recd                , & ! baseline record number   ! LCOV_EXCL_LINE
     957             :          yr                  , & ! year of forcing data   ! LCOV_EXCL_LINE
     958             :          ixm, ixx, ixp       , & ! record numbers of 3 data values   ! LCOV_EXCL_LINE
     959             :                                  ! relative to recd
     960             :          maxrec                  ! maximum record value
     961             : 
     962             :       character (char_len_long) :: &
     963             :          data_file               ! data file to be read
     964             : 
     965             :       character (char_len), intent(in) :: &
     966             :          fieldname               ! field name in netCDF file
     967             : 
     968             :       integer (kind=int_kind), intent(in) :: &
     969             :          field_loc, &            ! location of field on staggered grid   ! LCOV_EXCL_LINE
     970             :          field_type              ! type of field (scalar, vector, angle)
     971             : 
     972             :       real (kind=dbl_kind), dimension(nx_block,ny_block,2,max_blocks), intent(out) :: &
     973             :          field_data              ! 2 values needed for interpolation
     974             : 
     975             :       ! local variables
     976             : 
     977             :       integer (kind=int_kind) :: &
     978             :          nrec             , & ! record number to read   ! LCOV_EXCL_LINE
     979             :          n2, n4           , & ! like ixm and ixp, but   ! LCOV_EXCL_LINE
     980             :                               ! adjusted at beginning and end of data
     981             :          arg              , & ! value of time argument in field_data
     982             :          fid                  ! file id for netCDF routines
     983             : 
     984             :       character(len=*), parameter :: subname = '(read_data_nc)'
     985             : 
     986             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
     987             : 
     988           0 :       call ice_timer_start(timer_readwrite)  ! reading/writing
     989             : 
     990           0 :       if (istep1 > debug_model_step) debug_forcing = .true.  !! debugging
     991             : 
     992           0 :       if (my_task==master_task .and. (debug_forcing)) then
     993           0 :          write(nu_diag,*) '  ', trim(data_file)
     994             :       endif
     995             : 
     996           0 :       if (flag) then
     997             : 
     998             :       !-----------------------------------------------------------------
     999             :       ! Initialize record counters
    1000             :       ! (n2, n4 will change only at the very beginning or end of
    1001             :       !  a forcing cycle.)
    1002             :       !-----------------------------------------------------------------
    1003           0 :          n2 = ixm
    1004           0 :          n4 = ixp
    1005           0 :          arg = 0
    1006             : 
    1007             :       !-----------------------------------------------------------------
    1008             :       ! read data
    1009             :       !-----------------------------------------------------------------
    1010             : 
    1011           0 :          if (ixm /= -99) then
    1012             :          ! currently in first half of data interval
    1013           0 :             if (ixx <= 1) then
    1014           0 :                if (yr > fyear_init) then ! get data from previous year
    1015           0 :                   call file_year (data_file, yr-1)
    1016             :                else             ! yr = fyear_init, no prior data exists
    1017           0 :                   if (maxrec > 12) then ! extrapolate from first record
    1018           0 :                      if (ixx == 1) n2 = ixx
    1019             :                   else          ! go to end of fyear_final
    1020           0 :                      call file_year (data_file, fyear_final)
    1021             :                   endif
    1022             :                endif            ! yr > fyear_init
    1023             :             endif               ! ixx <= 1
    1024             : 
    1025           0 :             call ice_open_nc (data_file, fid)
    1026             : 
    1027           0 :             arg = 1
    1028           0 :             nrec = recd + n2
    1029             : 
    1030             :             call ice_read_nc &
    1031             :                  (fid, nrec, fieldname, field_data(:,:,arg,:), debug_forcing, &   ! LCOV_EXCL_LINE
    1032           0 :                   field_loc, field_type)
    1033             : 
    1034           0 :             if (ixx==1) call ice_close_nc(fid)
    1035             :          endif                  ! ixm ne -99
    1036             : 
    1037             :          ! always read ixx data from data file for current year
    1038           0 :          call file_year (data_file, yr)
    1039           0 :          call ice_open_nc (data_file, fid)
    1040             : 
    1041           0 :          arg = arg + 1
    1042           0 :          nrec = recd + ixx
    1043             : 
    1044             :          call ice_read_nc &
    1045             :               (fid, nrec, fieldname, field_data(:,:,arg,:), debug_forcing, &   ! LCOV_EXCL_LINE
    1046           0 :                field_loc, field_type)
    1047             : 
    1048           0 :          if (ixp /= -99) then
    1049             :          ! currently in latter half of data interval
    1050           0 :             if (ixx==maxrec) then
    1051           0 :                if (yr < fyear_final) then ! get data from following year
    1052           0 :                   call ice_close_nc(fid)
    1053           0 :                   call file_year (data_file, yr+1)
    1054           0 :                   call ice_open_nc (data_file, fid)
    1055             :                else             ! yr = fyear_final, no more data exists
    1056           0 :                   if (maxrec > 12) then ! extrapolate from ixx
    1057           0 :                      n4 = ixx
    1058             :                   else          ! go to beginning of fyear_init
    1059           0 :                      call ice_close_nc(fid)
    1060           0 :                      call file_year (data_file, fyear_init)
    1061           0 :                      call ice_open_nc (data_file, fid)
    1062             : 
    1063             :                   endif
    1064             :                endif            ! yr < fyear_final
    1065             :             endif               ! ixx = maxrec
    1066             : 
    1067           0 :             arg = arg + 1
    1068           0 :             nrec = recd + n4
    1069             : 
    1070             :             call ice_read_nc &
    1071             :                  (fid, nrec, fieldname, field_data(:,:,arg,:), debug_forcing, &   ! LCOV_EXCL_LINE
    1072           0 :                   field_loc, field_type)
    1073             :          endif                  ! ixp /= -99
    1074             : 
    1075           0 :          call ice_close_nc(fid)
    1076             : 
    1077             :       endif                     ! flag
    1078             : 
    1079           0 :       call ice_timer_stop(timer_readwrite)  ! reading/writing
    1080             : 
    1081           0 :       end subroutine read_data_nc
    1082             : 
    1083             : !=======================================================================
    1084             : 
    1085           0 :       subroutine read_data_nc_hycom (flag, recd,  &
    1086             :                             data_file, fieldname, field_data, &   ! LCOV_EXCL_LINE
    1087             :                             field_loc, field_type)
    1088             : 
    1089             : !  Data is assumed to cover the entire time period of simulation.
    1090             : !  It is not bounded by start of year nor end of year
    1091             : !  Data must be accesible both before and after (or on) the point in time
    1092             : !    Assume increasing timeaxis within the forcing files, but they do not
    1093             : !      have to be equal spaced. Read time vector from "MT" in "init_hycom"
    1094             : !
    1095             : ! Adapted by Mads Hvid Ribergaard, DMI from read_data_nc
    1096             : 
    1097             :       use ice_diagnostics, only: debug_model_step
    1098             :       use ice_timers, only: ice_timer_start, ice_timer_stop, timer_readwrite
    1099             : 
    1100             :       logical (kind=log_kind), intent(in) :: flag
    1101             : 
    1102             :       integer (kind=int_kind), intent(in) :: &
    1103             :          recd                    ! baseline record number
    1104             : 
    1105             :       character (char_len_long) :: &
    1106             :          data_file               ! data file to be read
    1107             :       character (char_len), intent(in) :: &
    1108             :          fieldname               ! field name in netCDF file
    1109             : 
    1110             :       integer (kind=int_kind), intent(in) :: &
    1111             :            field_loc, &      ! location of field on staggered grid   ! LCOV_EXCL_LINE
    1112             :            field_type        ! type of field (scalar, vector, angle)
    1113             : 
    1114             :       real (kind=dbl_kind), dimension(nx_block,ny_block,2,max_blocks), &
    1115             :          intent(out) :: &   ! LCOV_EXCL_LINE
    1116             :          field_data              ! 2 values needed for interpolation
    1117             : 
    1118             :       ! local variables
    1119             :       integer (kind=int_kind) :: &
    1120             :          fid                  ! file id for netCDF routines
    1121             : 
    1122             :       character(len=*), parameter :: subname = '(read_data_nc_hycom)'
    1123             : 
    1124             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    1125             : 
    1126           0 :       call ice_timer_start(timer_readwrite)  ! reading/writing
    1127             : 
    1128           0 :       if (istep1 > debug_model_step) debug_forcing = .true.  !! debugging
    1129             : 
    1130           0 :       if (my_task==master_task .and. (debug_forcing)) then
    1131           0 :          write(nu_diag,*) '  ', trim(data_file)
    1132             :       endif
    1133             : 
    1134           0 :       if (flag) then
    1135             : 
    1136           0 :          call ice_open_nc (data_file, fid)
    1137             :       !-----------------------------------------------------------------
    1138             :       ! read data
    1139             :       !-----------------------------------------------------------------
    1140             :          call ice_read_nc &
    1141             :                (fid, recd , fieldname, field_data(:,:,1,:), debug_forcing, &   ! LCOV_EXCL_LINE
    1142           0 :                 field_loc, field_type)
    1143             : 
    1144             :          call ice_read_nc &
    1145             :               (fid, recd+1, fieldname, field_data(:,:,2,:), debug_forcing, &   ! LCOV_EXCL_LINE
    1146           0 :                field_loc, field_type)
    1147             : 
    1148           0 :          call ice_close_nc(fid)
    1149             : 
    1150             :       endif                     ! flag
    1151             : 
    1152           0 :       call ice_timer_stop(timer_readwrite)  ! reading/writing
    1153             : 
    1154           0 :       end subroutine read_data_nc_hycom
    1155             : 
    1156             : !=======================================================================
    1157             : 
    1158           0 :       subroutine read_clim_data (readflag, recd, ixm, ixx, ixp, &
    1159             :                                  data_file, field_data, &   ! LCOV_EXCL_LINE
    1160             :                                  field_loc, field_type)
    1161             : 
    1162             : ! Read data needed for interpolation, as in read_data.
    1163             : ! Assume a one-year cycle of climatological data, so that there is
    1164             : !  no need to get data from other years or to extrapolate data beyond
    1165             : !  the forcing time period.
    1166             : 
    1167             :       use ice_diagnostics, only: debug_model_step
    1168             : 
    1169             :       logical (kind=log_kind),intent(in) :: readflag
    1170             : 
    1171             :       integer (kind=int_kind), intent(in) :: &
    1172             :         recd            , & ! baseline record number   ! LCOV_EXCL_LINE
    1173             :         ixm,ixx,ixp         ! record numbers of 3 data values
    1174             :                             ! relative to recd
    1175             : 
    1176             :       character (char_len_long), intent(in) ::  data_file
    1177             : 
    1178             :       integer (kind=int_kind), intent(in) :: &
    1179             :            field_loc, &      ! location of field on staggered grid   ! LCOV_EXCL_LINE
    1180             :            field_type        ! type of field (scalar, vector, angle)
    1181             : 
    1182             :       real (kind=dbl_kind), dimension(nx_block,ny_block,2,max_blocks), intent(inout) :: &
    1183             :         field_data         ! 2 values needed for interpolation
    1184             : 
    1185             :       ! local variables
    1186             : 
    1187             :       integer (kind=int_kind) :: &
    1188             :         nbits          , & ! = 32 for single precision, 64 for double   ! LCOV_EXCL_LINE
    1189             :         nrec           , & ! record number to read   ! LCOV_EXCL_LINE
    1190             :         arg                ! value of time argument in field_data
    1191             : 
    1192             :       character(len=*), parameter :: subname = '(read_clim_data)'
    1193             : 
    1194             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    1195             : 
    1196           0 :       call ice_timer_start(timer_readwrite)  ! reading/writing
    1197             : 
    1198           0 :       nbits = 64                ! double precision data
    1199             : 
    1200           0 :       if (istep1 > debug_model_step) debug_forcing = .true.  !! debugging
    1201             : 
    1202           0 :       if (my_task==master_task .and. (debug_forcing)) &
    1203           0 :         write(nu_diag,*) '  ', trim(data_file)
    1204             : 
    1205           0 :       if (readflag) then
    1206             : 
    1207             :       !-----------------------------------------------------------------
    1208             :       ! read data
    1209             :       !-----------------------------------------------------------------
    1210             : 
    1211           0 :          call ice_open (nu_forcing, data_file, nbits)
    1212             : 
    1213           0 :          arg = 0
    1214           0 :          if (ixm /= -99) then
    1215           0 :             arg = 1
    1216           0 :             nrec = recd + ixm
    1217           0 :             call ice_read (nu_forcing, nrec, field_data(:,:,arg,:), &
    1218           0 :                            'rda8', debug_forcing, field_loc, field_type)
    1219             :          endif
    1220             : 
    1221           0 :          arg = arg + 1
    1222           0 :          nrec = recd + ixx
    1223           0 :          call ice_read (nu_forcing, nrec, field_data(:,:,arg,:), &
    1224           0 :                         'rda8', debug_forcing, field_loc, field_type)
    1225             : 
    1226           0 :          if (ixp /= -99) then
    1227           0 :             arg = arg + 1
    1228           0 :             nrec = recd + ixp
    1229           0 :             call ice_read (nu_forcing, nrec, field_data(:,:,arg,:), &
    1230           0 :                            'rda8', debug_forcing, field_loc, field_type)
    1231             :          endif
    1232             : 
    1233           0 :          if (my_task == master_task) close (nu_forcing)
    1234             :       endif                     ! readflag
    1235             : 
    1236           0 :       call ice_timer_stop(timer_readwrite)  ! reading/writing
    1237             : 
    1238           0 :       end subroutine read_clim_data
    1239             : 
    1240             : !=======================================================================
    1241             : 
    1242           0 :       subroutine read_clim_data_nc (readflag, recd, ixm, ixx, ixp, &
    1243             :                                  data_file, fieldname, field_data, &   ! LCOV_EXCL_LINE
    1244             :                                  field_loc, field_type)
    1245             : 
    1246             : ! Read data needed for interpolation, as in read_data.
    1247             : ! Assume a one-year cycle of climatological data, so that there is
    1248             : !  no need to get data from other years or to extrapolate data beyond
    1249             : !  the forcing time period.
    1250             : 
    1251             :       use ice_diagnostics, only: debug_model_step
    1252             : 
    1253             :       logical (kind=log_kind),intent(in) :: readflag
    1254             : 
    1255             :       integer (kind=int_kind), intent(in) :: &
    1256             :         recd            , & ! baseline record number   ! LCOV_EXCL_LINE
    1257             :         ixm,ixx,ixp         ! record numbers of 3 data values
    1258             :                             ! relative to recd
    1259             : 
    1260             :       character (char_len_long), intent(in) ::  data_file
    1261             : 
    1262             :       character (char_len), intent(in) :: &
    1263             :          fieldname               ! field name in netCDF file
    1264             : 
    1265             :       integer (kind=int_kind), intent(in) :: &
    1266             :            field_loc, &      ! location of field on staggered grid   ! LCOV_EXCL_LINE
    1267             :            field_type        ! type of field (scalar, vector, angle)
    1268             : 
    1269             :       real (kind=dbl_kind), dimension(nx_block,ny_block,2,max_blocks), intent(out) :: &
    1270             :         field_data         ! 2 values needed for interpolation
    1271             : 
    1272             :       ! local variables
    1273             : 
    1274             :       integer (kind=int_kind) :: &
    1275             :         nrec           , & ! record number to read   ! LCOV_EXCL_LINE
    1276             :         arg            , & ! value of time argument in field_data   ! LCOV_EXCL_LINE
    1277             :         fid                ! file id for netCDF routines
    1278             : 
    1279             :       character(len=*), parameter :: subname = '(read_clim_data_nc)'
    1280             : 
    1281             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    1282             : 
    1283           0 :       call ice_timer_start(timer_readwrite)  ! reading/writing
    1284             : 
    1285           0 :       if (istep1 > debug_model_step) debug_forcing = .true.  !! debugging
    1286             : 
    1287           0 :       if (my_task==master_task .and. (debug_forcing)) &
    1288           0 :         write(nu_diag,*) '  ', trim(data_file)
    1289             : 
    1290           0 :       if (readflag) then
    1291             : 
    1292             :       !-----------------------------------------------------------------
    1293             :       ! read data
    1294             :       !-----------------------------------------------------------------
    1295             : 
    1296           0 :          call ice_open_nc (data_file, fid)
    1297             : 
    1298           0 :          arg = 0
    1299           0 :          if (ixm /= -99) then
    1300           0 :             arg = 1
    1301           0 :             nrec = recd + ixm
    1302             :             call ice_read_nc &
    1303             :                  (fid, nrec, fieldname, field_data(:,:,arg,:), &   ! LCOV_EXCL_LINE
    1304           0 :                   debug_forcing, field_loc, field_type)
    1305             :          endif
    1306             : 
    1307           0 :          arg = arg + 1
    1308           0 :          nrec = recd + ixx
    1309             :          call ice_read_nc &
    1310             :                  (fid, nrec, fieldname, field_data(:,:,arg,:), &   ! LCOV_EXCL_LINE
    1311           0 :                   debug_forcing, field_loc, field_type)
    1312             : 
    1313           0 :          if (ixp /= -99) then
    1314           0 :             arg = arg + 1
    1315           0 :             nrec = recd + ixp
    1316             :             call ice_read_nc &
    1317             :                  (fid, nrec, fieldname, field_data(:,:,arg,:), &   ! LCOV_EXCL_LINE
    1318           0 :                   debug_forcing, field_loc, field_type)
    1319             :          endif
    1320             : 
    1321           0 :          if (my_task == master_task) call ice_close_nc (fid)
    1322             :       endif                     ! readflag
    1323             : 
    1324           0 :       call ice_timer_stop(timer_readwrite)  ! reading/writing
    1325             : 
    1326           0 :       end subroutine read_clim_data_nc
    1327             : 
    1328             : !=======================================================================
    1329             : 
    1330           0 :       subroutine interp_coeff_monthly (recslot)
    1331             : 
    1332             : ! Compute coefficients for interpolating monthly data to current time step.
    1333             : 
    1334             :       integer (kind=int_kind), intent(in) :: &
    1335             :           recslot         ! slot (1 or 2) for current record
    1336             : 
    1337             :       ! local variables
    1338             : 
    1339             :       real (kind=dbl_kind) :: &
    1340             :           secday       , & ! seconds in day   ! LCOV_EXCL_LINE
    1341             :           tt           , & ! days elapsed in current year   ! LCOV_EXCL_LINE
    1342           0 :           t1, t2           ! days elapsed at month midpoint
    1343             : 
    1344             :       real (kind=dbl_kind) :: &
    1345           0 :           daymid(0:13)     ! month mid-points
    1346             : 
    1347             :       character(len=*), parameter :: subname = '(interp_coeff_monthly)'
    1348             : 
    1349             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    1350             : 
    1351           0 :       call icepack_query_parameters(secday_out=secday)
    1352           0 :       call icepack_warnings_flush(nu_diag)
    1353           0 :       if (icepack_warnings_aborted()) call abort_ice(error_message=subname, &
    1354           0 :          file=__FILE__, line=__LINE__)
    1355             : 
    1356           0 :       daymid(1:13) = 14._dbl_kind   ! time frame ends 0 sec into day 15
    1357           0 :       daymid(0)    = 14._dbl_kind - daymo(12)  ! Dec 15, 0 sec
    1358             : 
    1359             :       ! compute days since Jan 1, 00h, yday is the day counter for the year
    1360           0 :       tt = real(yday-1,kind=dbl_kind) + real(msec,kind=dbl_kind)/secday
    1361             : 
    1362             :       ! Find neighboring times
    1363             : 
    1364           0 :       if (recslot==2) then      ! first half of month
    1365           0 :         t2 = daycal(mmonth) + daymid(mmonth)   ! midpoint, current month
    1366           0 :         if (mmonth == 1) then
    1367           0 :           t1 = daymid(0)                 ! Dec 15 (0 sec)
    1368             :         else
    1369           0 :           t1 = daycal(mmonth-1) + daymid(mmonth-1) ! midpoint, previous month
    1370             :         endif
    1371             :       else                      ! second half of month
    1372           0 :         t1 = daycal(mmonth) + daymid(mmonth)    ! midpoint, current month
    1373           0 :         t2 = daycal(mmonth+1) + daymid(mmonth+1)! day 15 of next month (0 sec)
    1374             :       endif
    1375             : 
    1376           0 :       if (tt < t1 .or. tt > t2) then
    1377           0 :         write(nu_diag,*) subname,' ERROR in tt',tt,t1,t2
    1378             :         call abort_ice (error_message=subname//' ERROR in tt', &
    1379           0 :            file=__FILE__, line=__LINE__)
    1380             :       endif
    1381             : 
    1382             :       ! Compute coefficients
    1383           0 :       c1intp = (t2 - tt) / (t2 - t1)
    1384           0 :       c2intp =  c1 - c1intp
    1385             : 
    1386           0 :       end subroutine interp_coeff_monthly
    1387             : 
    1388             : !=======================================================================
    1389             : 
    1390           0 :       subroutine interp_coeff (recnum, recslot, secint, dataloc)
    1391             : 
    1392             : ! Compute coefficients for interpolating data to current time step.
    1393             : ! Works for any data interval that divides evenly into a
    1394             : !  year (daily, 6-hourly, etc.)
    1395             : ! Use interp_coef_monthly for monthly data.
    1396             : 
    1397             :       integer (kind=int_kind), intent(in) :: &
    1398             :           recnum      , & ! record number for current data value   ! LCOV_EXCL_LINE
    1399             :           recslot     , & ! spline slot for current record   ! LCOV_EXCL_LINE
    1400             :           dataloc         ! = 1 for data located in middle of time interval
    1401             :                           ! = 2 for date located at end of time interval
    1402             : 
    1403             :       real (kind=dbl_kind), intent(in) :: &
    1404             :           secint                    ! seconds in data interval
    1405             : 
    1406             :       ! local variables
    1407             : 
    1408             :       real (kind=dbl_kind) :: &
    1409           0 :           secday           ! seconds in a day
    1410             : 
    1411             :       real (kind=dbl_kind) :: &
    1412             :           tt           , & ! seconds elapsed in current year   ! LCOV_EXCL_LINE
    1413             :           t1, t2       , & ! seconds elapsed at data points   ! LCOV_EXCL_LINE
    1414           0 :           rcnum            ! recnum => dbl_kind
    1415             : 
    1416             :       character(len=*), parameter :: subname = '(interp_coeff)'
    1417             : 
    1418             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    1419             : 
    1420           0 :       call icepack_query_parameters(secday_out=secday)
    1421           0 :       call icepack_warnings_flush(nu_diag)
    1422           0 :       if (icepack_warnings_aborted()) call abort_ice(error_message=subname, &
    1423           0 :          file=__FILE__, line=__LINE__)
    1424             : 
    1425             :       ! compute seconds since Jan 1, 00h, yday is the day counter for the year
    1426           0 :       tt = real(yday-1,kind=dbl_kind)*secday + real(msec,kind=dbl_kind)
    1427             : 
    1428             :       ! Find neighboring times
    1429           0 :       rcnum = real(recnum,kind=dbl_kind)
    1430           0 :       if (recslot==2) then           ! current record goes in slot 2
    1431           0 :          if (dataloc==1) then        ! data located at middle of interval
    1432           0 :             t2 = (rcnum-p5)*secint
    1433             :          else                        !  data located at end of interval
    1434           0 :             t2 = rcnum*secint
    1435             :          endif
    1436           0 :          t1 = t2 - secint            !  - 1 interval
    1437             :       else                           ! recslot = 1
    1438           0 :          if (dataloc==1) then        ! data located at middle of interval
    1439           0 :             t1 = (rcnum-p5)*secint
    1440             :          else
    1441           0 :             t1 = rcnum*secint        ! data located at end of interval
    1442             :          endif
    1443           0 :          t2 = t1 + secint            !  + 1 interval
    1444             :       endif
    1445             : 
    1446             :       ! Compute coefficients
    1447           0 :       c1intp =  abs((t2 - tt) / (t2 - t1))
    1448           0 :       c2intp =  c1 - c1intp
    1449             : 
    1450             :       if (local_debug .and. my_task == master_task) then
    1451             :          write(nu_diag,*) subname,'fdbg yday,sec = ',yday,msec
    1452             :          write(nu_diag,*) subname,'fdbg tt = ',tt
    1453             :          write(nu_diag,*) subname,'fdbg c12intp = ',c1intp,c2intp
    1454             :       endif
    1455             : 
    1456           0 :       end subroutine interp_coeff
    1457             : 
    1458             : !=======================================================================
    1459             : 
    1460           0 :       subroutine interp_coeff2 (tt, t1, t2)
    1461             : 
    1462             : ! Compute coefficients for interpolating data to current time step.
    1463             : ! Works for any data interval using decimal daynumbers
    1464             : 
    1465             :       ! local variables
    1466             :       real (kind=dbl_kind), intent(in) :: &
    1467             :           tt      , &  ! current decimal daynumber   ! LCOV_EXCL_LINE
    1468             :           t1, t2       ! first+last decimal daynumber
    1469             :       character(len=*), parameter :: subname = '(interp_coeff2)'
    1470             : 
    1471             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    1472             : 
    1473             :       ! Compute coefficients
    1474           0 :       c1intp =  abs((t2 - tt) / (t2 - t1))
    1475           0 :       c2intp =  c1 - c1intp
    1476             : 
    1477           0 :       end subroutine interp_coeff2
    1478             : 
    1479             : !=======================================================================
    1480             : 
    1481       11616 :       subroutine interpolate_data (field_data, field)
    1482             : 
    1483             : ! Linear interpolation
    1484             : 
    1485             : ! author: Elizabeth C. Hunke, LANL
    1486             : 
    1487             :       use ice_domain, only: nblocks
    1488             : 
    1489             :       real (kind=dbl_kind), dimension(nx_block,ny_block,2,max_blocks), intent(in) :: &
    1490             :         field_data    ! 2 values used for interpolation
    1491             : 
    1492             :       real (kind=dbl_kind), dimension(nx_block,ny_block,max_blocks), intent(out) :: &
    1493             :         field         ! interpolated field
    1494             : 
    1495             :       ! local variables
    1496             : 
    1497             :       integer (kind=int_kind) :: i,j, iblk
    1498             : 
    1499             :       character(len=*), parameter :: subname = '(interpolate data)'
    1500             : 
    1501             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    1502             : 
    1503       11520 :       !$OMP PARALLEL DO PRIVATE(iblk,i,j)
    1504         192 :       do iblk = 1, nblocks
    1505       23040 :          do j = 1, ny_block
    1506     1166880 :          do i = 1, nx_block
    1507             :             field(i,j,iblk) = c1intp * field_data(i,j,1,iblk) &
    1508     1166784 :                             + c2intp * field_data(i,j,2,iblk)
    1509             :          enddo
    1510             :          enddo
    1511             :       enddo
    1512             :       !$OMP END PARALLEL DO
    1513             : 
    1514       11616 :       end subroutine interpolate_data
    1515             : 
    1516             : !=======================================================================
    1517             : 
    1518           0 :       subroutine interpolate_wavespec_data (field_data, field)
    1519             : 
    1520             : ! Linear interpolation
    1521             : 
    1522             : ! author: Elizabeth C. Hunke, LANL
    1523             : 
    1524             :       use ice_domain, only: nblocks
    1525             : 
    1526             :       real (kind=dbl_kind), dimension(nx_block,ny_block,nfreq,2,max_blocks), intent(in) :: &
    1527             :         field_data    ! 2 values used for interpolation
    1528             : 
    1529             :       real (kind=dbl_kind), dimension(nx_block,ny_block,nfreq,max_blocks), intent(out) :: &
    1530             :         field         ! interpolated field
    1531             : 
    1532             :       ! local variables
    1533             : 
    1534             :       integer (kind=int_kind) :: i,j, iblk, freq
    1535             : 
    1536             :       character(len=*), parameter :: subname = '(interpolate data)'
    1537             : 
    1538           0 :       !$OMP PARALLEL DO PRIVATE(iblk,i,j)
    1539           0 :       do iblk = 1, nblocks
    1540           0 :          do j = 1, ny_block
    1541           0 :          do i = 1, nx_block
    1542           0 :          do freq = 1, nfreq
    1543             :             field(i,j,freq,iblk) = c1intp * field_data(i,j,freq,1,iblk) &
    1544           0 :                             + c2intp * field_data(i,j,freq,2,iblk)
    1545             :          enddo
    1546             :          enddo
    1547             :          enddo
    1548             :       enddo
    1549             :       !$OMP END PARALLEL DO
    1550             : 
    1551           0 :       end subroutine interpolate_wavespec_data
    1552             : 
    1553             : 
    1554             : !=======================================================================
    1555             : 
    1556        8733 :       subroutine file_year (data_file, yr)
    1557             : 
    1558             : ! Construct the correct name of the atmospheric data file
    1559             : ! to be read, given the year and assuming the naming convention
    1560             : ! that filenames end with 'yyyy.dat' or 'yyyy.r' or 'yyyy.nc'.
    1561             : 
    1562             :       character (char_len_long), intent(inout) ::  data_file
    1563             : 
    1564             :       integer (kind=int_kind), intent(in) :: yr
    1565             : 
    1566             :       character (char_len_long) :: tmpname
    1567             : 
    1568             :       integer (kind=int_kind) :: i
    1569             : 
    1570             :       character(len=*), parameter :: subname = '(file_year)'
    1571             : 
    1572             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    1573             : 
    1574        8733 :       if (trim(atm_data_type) == 'hadgem') then ! netcdf
    1575           0 :          i = index(data_file,'.nc') - 5
    1576           0 :          tmpname = data_file
    1577           0 :          write(data_file,'(a,i4.4,a)') tmpname(1:i), yr, '.nc'
    1578        8733 :       elseif (index(trim(atm_data_type),'JRA55') > 0) then ! netcdf
    1579        8733 :          i = index(data_file,'.nc') - 5
    1580        8733 :          tmpname = data_file
    1581        8733 :          write(data_file,'(a,i4.4,a)') tmpname(1:i), yr, '.nc'
    1582             :       else                                     ! LANL/NCAR naming convention
    1583           0 :          i = index(data_file,'.dat') - 5
    1584           0 :          tmpname = data_file
    1585           0 :          write(data_file,'(a,i4.4,a)') tmpname(1:i), yr, '.dat'
    1586             :       endif
    1587             : 
    1588        8733 :       end subroutine file_year
    1589             : 
    1590             : !=======================================================================
    1591             : 
    1592       22944 :       subroutine prepare_forcing (nx_block, ny_block, &
    1593             :                                   ilo, ihi, jlo, jhi, &   ! LCOV_EXCL_LINE
    1594             :                                   hm,                 &   ! LCOV_EXCL_LINE
    1595             :                                   Tair,     fsw,      &   ! LCOV_EXCL_LINE
    1596             :                                   cldf,     flw,      &   ! LCOV_EXCL_LINE
    1597             :                                   frain,    fsnow,    &   ! LCOV_EXCL_LINE
    1598             :                                   Qa,       rhoa,     &   ! LCOV_EXCL_LINE
    1599             :                                   uatm,     vatm,     &   ! LCOV_EXCL_LINE
    1600             :                                   strax,    stray,    &   ! LCOV_EXCL_LINE
    1601             :                                   zlvl,     wind,     &   ! LCOV_EXCL_LINE
    1602             :                                   swvdr,    swvdf,    &   ! LCOV_EXCL_LINE
    1603             :                                   swidr,    swidf,    &   ! LCOV_EXCL_LINE
    1604             :                                   potT,     ANGLET,   &   ! LCOV_EXCL_LINE
    1605             :                                   Tsfc,     sst,      &   ! LCOV_EXCL_LINE
    1606             :                                   aice)
    1607             : 
    1608             :       integer (kind=int_kind), intent(in) :: &
    1609             :          nx_block, ny_block, & ! block dimensions   ! LCOV_EXCL_LINE
    1610             :          ilo,ihi,jlo,jhi       ! beginning and end of physical domain
    1611             : 
    1612             :       real (kind=dbl_kind), dimension(nx_block,ny_block), intent(in) :: &
    1613             :          ANGLET  , & ! ANGLE converted to T-cells   ! LCOV_EXCL_LINE
    1614             :          Tsfc    , & ! ice skin temperature   ! LCOV_EXCL_LINE
    1615             :          sst     , & ! sea surface temperature   ! LCOV_EXCL_LINE
    1616             :          aice    , & ! ice area fraction   ! LCOV_EXCL_LINE
    1617             :          hm          ! land mask
    1618             : 
    1619             :       real (kind=dbl_kind), dimension(nx_block,ny_block), intent(inout) :: &
    1620             :          fsw     , & ! incoming shortwave radiation (W/m^2)   ! LCOV_EXCL_LINE
    1621             :          cldf    , & ! cloud fraction   ! LCOV_EXCL_LINE
    1622             :          frain   , & ! rainfall rate (kg/m^2 s)   ! LCOV_EXCL_LINE
    1623             :          fsnow   , & ! snowfall rate (kg/m^2 s)   ! LCOV_EXCL_LINE
    1624             :          Tair    , & ! air temperature  (K)   ! LCOV_EXCL_LINE
    1625             :          Qa      , & ! specific humidity (kg/kg)   ! LCOV_EXCL_LINE
    1626             :          rhoa    , & ! air density (kg/m^3)   ! LCOV_EXCL_LINE
    1627             :          uatm    , & ! wind velocity components (m/s)   ! LCOV_EXCL_LINE
    1628             :          vatm    , &   ! LCOV_EXCL_LINE
    1629             :          strax   , & ! wind stress components (N/m^2)   ! LCOV_EXCL_LINE
    1630             :          stray   , &   ! LCOV_EXCL_LINE
    1631             :          zlvl    , & ! atm level height (m)   ! LCOV_EXCL_LINE
    1632             :          wind    , & ! wind speed (m/s)   ! LCOV_EXCL_LINE
    1633             :          flw     , & ! incoming longwave radiation (W/m^2)   ! LCOV_EXCL_LINE
    1634             :          swvdr   , & ! sw down, visible, direct  (W/m^2)   ! LCOV_EXCL_LINE
    1635             :          swvdf   , & ! sw down, visible, diffuse (W/m^2)   ! LCOV_EXCL_LINE
    1636             :          swidr   , & ! sw down, near IR, direct  (W/m^2)   ! LCOV_EXCL_LINE
    1637             :          swidf   , & ! sw down, near IR, diffuse (W/m^2)   ! LCOV_EXCL_LINE
    1638             :          potT        ! air potential temperature  (K)
    1639             : 
    1640             :       ! local variables
    1641             : 
    1642             :       integer (kind=int_kind) :: &
    1643             :          i, j
    1644             : 
    1645        5760 :       real (kind=dbl_kind) :: workx, worky, &
    1646        5760 :          precip_factor, zlvl0, secday, Tffresh, puny
    1647             : 
    1648             :       logical (kind=log_kind) :: calc_strair
    1649             : 
    1650             :       character(len=*), parameter :: subname = '(prepare_forcing)'
    1651             : 
    1652             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    1653             : 
    1654       22944 :       call icepack_query_parameters(Tffresh_out=Tffresh, puny_out=puny)
    1655       22944 :       call icepack_query_parameters(secday_out=secday)
    1656       22944 :       call icepack_query_parameters(calc_strair_out=calc_strair)
    1657       22944 :       call icepack_warnings_flush(nu_diag)
    1658       22944 :       if (icepack_warnings_aborted()) call abort_ice(error_message=subname, &
    1659           0 :          file=__FILE__, line=__LINE__)
    1660             : 
    1661      707688 :       do j = jlo, jhi
    1662    13826928 :       do i = ilo, ihi
    1663             : 
    1664    13119240 :          zlvl0 = c10 ! default
    1665             : 
    1666             :       !-----------------------------------------------------------------
    1667             :       ! make sure interpolated values are physically realistic
    1668             :       !-----------------------------------------------------------------
    1669    13119240 :          cldf (i,j) = max(min(cldf(i,j),c1),c0)
    1670    13119240 :          fsw  (i,j) = max(fsw(i,j),c0)
    1671    13119240 :          fsnow(i,j) = max(fsnow(i,j),c0)
    1672    13119240 :          rhoa (i,j) = max(rhoa(i,j),c0)
    1673    13803984 :          Qa   (i,j) = max(Qa(i,j),c0)
    1674             : 
    1675             : !        if (rhoa(i,j) .lt. puny) rhoa(i,j) = 1.3_dbl_kind
    1676             : !        if (Tair(i,j) .lt. puny) Tair(i,j) = Tffresh
    1677             : !        if (Qa(i,j) .lt. puny) Qa(i,j) = 0.0035_dbl_kind
    1678             :       enddo                     ! i
    1679             :       enddo                     ! j
    1680             : 
    1681             :       !-----------------------------------------------------------------
    1682             :       ! calculations specific to datasets
    1683             :       !-----------------------------------------------------------------
    1684             : 
    1685       22944 :       if (trim(atm_data_type) == 'ncar') then
    1686             : 
    1687             :          ! precip is in mm/month
    1688             : 
    1689           0 :          zlvl0 = c10
    1690             : 
    1691           0 :          do j = jlo, jhi
    1692           0 :          do i = ilo, ihi
    1693             :             ! correct known biases in NCAR data (as in CESM latm)
    1694           0 :             Qa (i,j) = Qa (i,j) * 0.94_dbl_kind
    1695           0 :             fsw(i,j) = fsw(i,j) * 0.92_dbl_kind
    1696             : 
    1697             :             ! downward longwave as in Parkinson and Washington (1979)
    1698           0 :             call longwave_parkinson_washington(Tair(i,j), cldf(i,j), &
    1699           0 :                                               flw(i,j))
    1700             :          enddo
    1701             :          enddo
    1702             : 
    1703       22944 :       elseif (trim(atm_data_type) == 'oned') then  ! rectangular grid
    1704             : 
    1705             :          ! precip is in kg/m^2/s
    1706             : 
    1707           0 :          zlvl0 = c10
    1708             : 
    1709           0 :          do j = jlo, jhi
    1710           0 :          do i = ilo, ihi
    1711             : 
    1712             :       !-----------------------------------------------------------------
    1713             :       ! compute downward longwave as in Parkinson and Washington (1979)
    1714             :       !-----------------------------------------------------------------
    1715             : 
    1716             :             ! downward longwave as in Parkinson and Washington (1979)
    1717           0 :             call longwave_parkinson_washington(Tair(i,j), cldf(i,j), &
    1718           0 :                                                flw(i,j))
    1719             : 
    1720             :             ! longwave based on Rosati and Miyakoda, JPO 18, p. 1607 (1988)
    1721             : !            call longwave_rosati_miyakoda(cldf(i,j), Tsfc(i,j), &
    1722             : !                                          aice(i,j), sst(i,j),  &   ! LCOV_EXCL_LINE
    1723             : !                                          Qa(i,j),   Tair(i,j), &   ! LCOV_EXCL_LINE
    1724             : !                                          hm(i,j),   flw(i,j))
    1725             :          enddo
    1726             :          enddo
    1727             : 
    1728             :       endif                     ! atm_data_type
    1729             : 
    1730             :       !-----------------------------------------------------------------
    1731             :       ! Compute other fields needed by model
    1732             :       !-----------------------------------------------------------------
    1733             : 
    1734             :       ! convert precipitation units to kg/m^2 s
    1735       22944 :       if (trim(precip_units) == 'mm_per_month') then
    1736        5760 :          precip_factor = c12/(secday*real(days_per_year,kind=dbl_kind))
    1737       17184 :       elseif (trim(precip_units) == 'mm_per_day') then
    1738           0 :          precip_factor = c1/secday
    1739       17184 :       elseif (trim(precip_units) == 'mm_per_sec' .or. &
    1740             :               trim(precip_units) == 'mks') then
    1741       17184 :          precip_factor = c1    ! mm/sec = kg/m^2 s
    1742           0 :       elseif (trim(precip_units) == 'm_per_sec') then
    1743           0 :          precip_factor = c1000
    1744             :       endif
    1745             : 
    1746      707688 :       do j = jlo, jhi
    1747    13826928 :       do i = ilo, ihi
    1748             : 
    1749    13119240 :          zlvl(i,j) = zlvl0
    1750    13119240 :          potT(i,j) = Tair(i,j)
    1751             : 
    1752             :         ! divide shortwave into spectral bands
    1753    13119240 :          swvdr(i,j) = fsw(i,j)*frcvdr        ! visible direct
    1754    13119240 :          swvdf(i,j) = fsw(i,j)*frcvdf        ! visible diffuse
    1755    13119240 :          swidr(i,j) = fsw(i,j)*frcidr        ! near IR direct
    1756    13119240 :          swidf(i,j) = fsw(i,j)*frcidf        ! near IR diffuse
    1757             : 
    1758             :         ! convert precipitation units to kg/m^2 s
    1759    13803984 :          fsnow(i,j) = fsnow(i,j) * precip_factor
    1760             :       enddo                     ! i
    1761             :       enddo                     ! j
    1762             : 
    1763             :       ! determine whether precip is rain or snow
    1764             :       ! HadGEM forcing provides separate snowfall and rainfall rather
    1765             :       ! than total precipitation
    1766       22944 :       if (trim(atm_data_type) /= 'hadgem') then
    1767             : 
    1768      707688 :         do j = jlo, jhi
    1769    13826928 :         do i = ilo, ihi
    1770    13119240 :            frain(i,j) = c0
    1771    13803984 :            if (Tair(i,j) >= Tffresh) then
    1772     4301404 :                frain(i,j) = fsnow(i,j)
    1773     4301404 :                fsnow(i,j) = c0
    1774             :            endif
    1775             :         enddo                     ! i
    1776             :         enddo                     ! j
    1777             : 
    1778             :       endif
    1779             : 
    1780       22944 :       if (calc_strair) then
    1781             : 
    1782       22944 :         if (rotate_wind) then
    1783      707688 :           do j = jlo, jhi
    1784    13826928 :           do i = ilo, ihi
    1785    13119240 :              wind(i,j) = sqrt(uatm(i,j)**2 + vatm(i,j)**2)
    1786             :       !-----------------------------------------------------------------
    1787             :       ! Rotate zonal/meridional vectors to local coordinates.
    1788             :       ! Velocity comes in on T grid, but is oriented geographically ---
    1789             :       ! need to rotate to pop-grid FIRST using ANGLET
    1790             :       ! then interpolate to the U-cell centers  (otherwise we
    1791             :       ! interpolate across the pole).
    1792             :       ! Use ANGLET which is on the T grid !
    1793             :       ! Atmo variables are needed in T cell centers in subroutine
    1794             :       ! atmo_boundary_layer, and are interpolated to the U grid later as
    1795             :       ! necessary.
    1796             :       !-----------------------------------------------------------------
    1797    13119240 :              workx      = uatm(i,j) ! wind velocity, m/s
    1798    13119240 :              worky      = vatm(i,j)
    1799     4176000 :              uatm (i,j) = workx*cos(ANGLET(i,j)) & ! convert to POP grid
    1800    13119240 :                         + worky*sin(ANGLET(i,j))   ! note uatm, vatm, wind
    1801     4176000 :              vatm (i,j) = worky*cos(ANGLET(i,j)) & !  are on the T-grid here
    1802    13803984 :                         - workx*sin(ANGLET(i,j))
    1803             :           enddo                     ! i
    1804             :           enddo                     ! j
    1805             :         else ! not rotated
    1806           0 :           do j = jlo, jhi
    1807           0 :           do i = ilo, ihi
    1808           0 :              wind(i,j) = sqrt(uatm(i,j)**2 + vatm(i,j)**2)
    1809             :           enddo                     ! i
    1810             :           enddo                     ! j
    1811             :         endif ! rotated
    1812             : 
    1813             :       else ! strax, stray, wind are read from files
    1814             : 
    1815           0 :         if (rotate_wind) then
    1816           0 :           do j = jlo, jhi
    1817           0 :           do i = ilo, ihi
    1818           0 :              workx      = strax(i,j) ! wind stress
    1819           0 :              worky      = stray(i,j)
    1820           0 :              strax(i,j) = workx*cos(ANGLET(i,j)) & ! convert to POP grid
    1821           0 :                         + worky*sin(ANGLET(i,j))   ! note strax, stray, wind
    1822           0 :              stray(i,j) = worky*cos(ANGLET(i,j)) & !  are on the T-grid here
    1823           0 :                         - workx*sin(ANGLET(i,j))
    1824             :           enddo                     ! i
    1825             :           enddo                     ! j
    1826             :         else ! not rotated
    1827             :           ! wind (speed) is already read from file, so all is in place
    1828             :         endif ! rotated
    1829             : 
    1830             :       endif                   ! calc_strair
    1831             : 
    1832       22944 :       end subroutine prepare_forcing
    1833             : 
    1834             : !=======================================================================
    1835             : 
    1836           0 :       subroutine longwave_parkinson_washington(Tair, cldf, flw)
    1837             : 
    1838             :       ! compute downward longwave as in Parkinson and Washington (1979)
    1839             :       ! (for now)
    1840             :       ! Parkinson, C. L. and W. M. Washington (1979),
    1841             :       ! Large-scale numerical-model of sea ice,
    1842             :       ! JGR, 84, 311-337, doi:10.1029/JC084iC01p00311
    1843             : 
    1844             :       real(kind=dbl_kind), intent(in) :: &
    1845             :            Tair , & ! air temperature  (K)   ! LCOV_EXCL_LINE
    1846             :            cldf     ! cloud fraction
    1847             : 
    1848             :       real(kind=dbl_kind), intent(out) :: &
    1849             :            flw      ! incoming longwave radiation (W/m^2)
    1850             : 
    1851             :       real(kind=dbl_kind) :: &
    1852           0 :            Tffresh, stefan_boltzmann
    1853             : 
    1854             :       character(len=*), parameter :: subname = '(longwave_parkinson_washington)'
    1855             : 
    1856             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    1857             : 
    1858             :       call icepack_query_parameters(Tffresh_out=Tffresh, &
    1859           0 :            stefan_boltzmann_out=stefan_boltzmann)
    1860           0 :       call icepack_warnings_flush(nu_diag)
    1861           0 :       if (icepack_warnings_aborted()) call abort_ice(error_message=subname, &
    1862           0 :          file=__FILE__, line=__LINE__)
    1863             : 
    1864             :       flw = stefan_boltzmann*Tair**4 &
    1865             :              * (c1 - 0.261_dbl_kind &   ! LCOV_EXCL_LINE
    1866             :              * exp(-7.77e-4_dbl_kind*(Tffresh - Tair)**2)) &   ! LCOV_EXCL_LINE
    1867           0 :              * (c1 + 0.275_dbl_kind*cldf)
    1868             : 
    1869           0 :       end subroutine longwave_parkinson_washington
    1870             : 
    1871             : !=======================================================================
    1872             : 
    1873           0 :       subroutine longwave_rosati_miyakoda(cldf, Tsfc, &
    1874             :                                           aice, sst,  &   ! LCOV_EXCL_LINE
    1875             :                                           Qa,   Tair, &   ! LCOV_EXCL_LINE
    1876             :                                           hm,   flw)
    1877             : 
    1878             :       ! based on
    1879             :       ! Rosati, A. and K. Miyakoda (1988),
    1880             :       ! A general-circulation model for upper ocean simulation,
    1881             :       ! J. Physical Oceanography, 18, 1601-1626,
    1882             :       ! doi:10.1175/1520-0485(1988)018<1601:AGCMFU>2.0.CO;2
    1883             : 
    1884             :       real(kind=dbl_kind), intent(in) :: &
    1885             :            cldf , & ! cloud fraction   ! LCOV_EXCL_LINE
    1886             :            Tsfc , & ! ice skin temperature   ! LCOV_EXCL_LINE
    1887             :            aice , & ! ice area fraction   ! LCOV_EXCL_LINE
    1888             :            sst  , & ! sea surface temperature   ! LCOV_EXCL_LINE
    1889             :            Qa   , & ! specific humidity (kg/kg)   ! LCOV_EXCL_LINE
    1890             :            Tair , & ! air temperature  (K)   ! LCOV_EXCL_LINE
    1891             :            hm       ! land mask
    1892             : 
    1893             :       real(kind=dbl_kind), intent(out) :: &
    1894             :            flw      ! incoming longwave radiation (W/m^2)
    1895             : 
    1896             :       real(kind=dbl_kind) :: &
    1897             :            fcc  , & ! cloudiness modification   ! LCOV_EXCL_LINE
    1898             :            sstk , & ! ice/ocean surface temperature (K)   ! LCOV_EXCL_LINE
    1899             :            rtea , & ! square root of the vapour pressure   ! LCOV_EXCL_LINE
    1900             :            ptem , & ! potential air temperature (K)   ! LCOV_EXCL_LINE
    1901           0 :            qlwm
    1902             : 
    1903             :       real(kind=dbl_kind) :: &
    1904           0 :            Tffresh, stefan_boltzmann, emissivity
    1905             : 
    1906             :       character(len=*), parameter :: subname = '(longwave_rosati_miyakoda)'
    1907             : 
    1908             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    1909             : 
    1910             :       call icepack_query_parameters(Tffresh_out=Tffresh, &
    1911             :            stefan_boltzmann_out=stefan_boltzmann, &   ! LCOV_EXCL_LINE
    1912           0 :            emissivity_out=emissivity)
    1913           0 :       call icepack_warnings_flush(nu_diag)
    1914           0 :       if (icepack_warnings_aborted()) call abort_ice(error_message=subname, &
    1915           0 :          file=__FILE__, line=__LINE__)
    1916             : 
    1917           0 :       fcc = c1 - 0.8_dbl_kind * cldf
    1918             :       sstk = (Tsfc * aice &
    1919           0 :            + sst * (c1 - aice)) + Tffresh
    1920             :       rtea = sqrt(c1000*Qa /  &
    1921           0 :            (0.622_dbl_kind+0.378_dbl_kind*Qa))
    1922           0 :       ptem = Tair    ! get this from stability?
    1923             :       qlwm = ptem * ptem * ptem  &
    1924             :                  * ( ptem*(0.39_dbl_kind-0.05_dbl_kind*rtea)*fcc  &   ! LCOV_EXCL_LINE
    1925           0 :                  + c4*(sstk-ptem) )
    1926           0 :       flw = emissivity*stefan_boltzmann * ( sstk**4 - qlwm )
    1927           0 :       flw = flw * hm ! land mask
    1928             : 
    1929           0 :       end subroutine longwave_rosati_miyakoda
    1930             : 
    1931             : !=======================================================================
    1932             : ! NCAR atmospheric forcing
    1933             : !=======================================================================
    1934             : 
    1935           0 :       subroutine ncar_files (yr)
    1936             : 
    1937             :       ! Construct filenames based on the LANL naming conventions for NCAR data.
    1938             :       ! Edit for other directory structures or filenames.
    1939             :       ! Note: The year number in these filenames does not matter, because
    1940             :       !       subroutine file_year will insert the correct year.
    1941             :       ! Note: atm_data_dir may have NCAR_bulk or not
    1942             :       !
    1943             :       ! atm_data_type should be 'ncar'
    1944             :       ! atm_dat_dir should be ${CICE_DATA_root}/forcing/$grid/[NCAR_bulk,'']
    1945             :       !    atm_data_dir should be set to ${CICE_DATA_root}/forcing/$grid/[JRA55,JRA55do,'']
    1946             :       !       NCAR_bulk at the end of the atm_data_dir is optional to provide backwards
    1947             :       !       compatibility and if not included, will be appended automaticaly.
    1948             :       !       The grid is typically gx1, gx3, tx1, or similar.
    1949             : 
    1950             :       integer (kind=int_kind), intent(in) :: &
    1951             :            yr                   ! current forcing year
    1952             : 
    1953             :       character (char_len_long) :: &
    1954             :            atm_data_dir_extra   ! atm_dat_dir extra if needed
    1955             : 
    1956             :       integer (kind=int_kind) :: &
    1957             :            strind   ! string index
    1958             : 
    1959             :       character(len=*), parameter :: subname = '(ncar_files)'
    1960             : 
    1961             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    1962             : 
    1963             :       ! decide whether NCAR_bulk is part of atm_data_dir and set atm_data_dir_extra
    1964           0 :       atm_data_dir_extra = '/NCAR_bulk'
    1965           0 :       strind = index(trim(atm_data_dir),'NCAR_bulk')
    1966           0 :       if (strind > 0) then
    1967           0 :          atm_data_dir_extra = ''
    1968             :       endif
    1969             : 
    1970           0 :       fsw_file   = trim(atm_data_dir)//trim(atm_data_dir_extra)//'/MONTHLY/swdn.1996.dat'
    1971           0 :       call file_year(fsw_file,yr)
    1972             : 
    1973           0 :       flw_file   = trim(atm_data_dir)//trim(atm_data_dir_extra)//'/MONTHLY/cldf.1996.dat'
    1974           0 :       call file_year(flw_file,yr)
    1975             : 
    1976           0 :       rain_file  = trim(atm_data_dir)//trim(atm_data_dir_extra)//'/MONTHLY/prec.1996.dat'
    1977           0 :       call file_year(rain_file,yr)
    1978             : 
    1979           0 :       uwind_file = trim(atm_data_dir)//trim(atm_data_dir_extra)//'/4XDAILY/u_10.1996.dat'
    1980           0 :       call file_year(uwind_file,yr)
    1981             : 
    1982           0 :       vwind_file = trim(atm_data_dir)//trim(atm_data_dir_extra)//'/4XDAILY/v_10.1996.dat'
    1983           0 :       call file_year(vwind_file,yr)
    1984             : 
    1985           0 :       tair_file  = trim(atm_data_dir)//trim(atm_data_dir_extra)//'/4XDAILY/t_10.1996.dat'
    1986           0 :       call file_year(tair_file,yr)
    1987             : 
    1988           0 :       humid_file = trim(atm_data_dir)//trim(atm_data_dir_extra)//'/4XDAILY/q_10.1996.dat'
    1989           0 :       call file_year(humid_file,yr)
    1990             : 
    1991           0 :       rhoa_file  = trim(atm_data_dir)//trim(atm_data_dir_extra)//'/4XDAILY/dn10.1996.dat'
    1992           0 :       call file_year(rhoa_file,yr)
    1993             : 
    1994           0 :       if (my_task == master_task) then
    1995           0 :          write (nu_diag,*) ' '
    1996           0 :          write (nu_diag,*) 'Forcing data year =', fyear
    1997           0 :          write (nu_diag,*) 'Atmospheric data files:'
    1998           0 :          write (nu_diag,'(3a)') trim(fsw_file)
    1999           0 :          write (nu_diag,'(3a)') trim(flw_file)
    2000           0 :          write (nu_diag,'(3a)') trim(rain_file)
    2001           0 :          write (nu_diag,'(3a)') trim(uwind_file)
    2002           0 :          write (nu_diag,'(3a)') trim(vwind_file)
    2003           0 :          write (nu_diag,'(3a)') trim(tair_file)
    2004           0 :          write (nu_diag,'(3a)') trim(humid_file)
    2005           0 :          write (nu_diag,'(3a)') trim(rhoa_file)
    2006             :       endif                     ! master_task
    2007             : 
    2008           0 :       end subroutine ncar_files
    2009             : 
    2010             : !=======================================================================
    2011             : 
    2012           0 :       subroutine ncar_data
    2013             : 
    2014             :       use ice_flux, only: fsw, fsnow, Tair, uatm, vatm, rhoa, Qa
    2015             : 
    2016             :       integer (kind=int_kind) :: &
    2017             :           ixm,ixx,ixp , & ! record numbers for neighboring months   ! LCOV_EXCL_LINE
    2018             :           recnum      , & ! record number   ! LCOV_EXCL_LINE
    2019             :           maxrec      , & ! maximum record number   ! LCOV_EXCL_LINE
    2020             :           recslot     , & ! spline slot for current record   ! LCOV_EXCL_LINE
    2021             :           dataloc     , & ! = 1 for data located in middle of time interval   ! LCOV_EXCL_LINE
    2022             :                           ! = 2 for date located at end of time interval
    2023             :           midmonth        ! middle day of month
    2024             : 
    2025             :       real (kind=dbl_kind) :: &
    2026             :           secday, &           ! number of seconds in day   ! LCOV_EXCL_LINE
    2027           0 :           sec6hr              ! number of seconds in 6 hours
    2028             : 
    2029             :       logical (kind=log_kind) :: readm, read6
    2030             : 
    2031             :       character(len=*), parameter :: subname = '(ncar_data)'
    2032             : 
    2033             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    2034             : 
    2035           0 :       call icepack_query_parameters(secday_out=secday)
    2036           0 :       call icepack_warnings_flush(nu_diag)
    2037           0 :       if (icepack_warnings_aborted()) call abort_ice(error_message=subname, &
    2038           0 :          file=__FILE__, line=__LINE__)
    2039             : 
    2040             :     !-------------------------------------------------------------------
    2041             :     ! monthly data
    2042             :     !
    2043             :     ! Assume that monthly data values are located in the middle of the
    2044             :     ! month.
    2045             :     !-------------------------------------------------------------------
    2046             : 
    2047           0 :       midmonth = 15  ! data is given on 15th of every month
    2048             : !      midmonth = fix(p5 * real(daymo(mmonth)))  ! exact middle
    2049             : 
    2050             :       ! Compute record numbers for surrounding months
    2051           0 :       maxrec = 12
    2052           0 :       ixm  = mod(mmonth+maxrec-2,maxrec) + 1
    2053           0 :       ixp  = mod(mmonth,         maxrec) + 1
    2054           0 :       if (mday >= midmonth) ixm = -99  ! other two points will be used
    2055           0 :       if (mday <  midmonth) ixp = -99
    2056             : 
    2057             :       ! Determine whether interpolation will use values 1:2 or 2:3
    2058             :       ! recslot = 2 means we use values 1:2, with the current value (2)
    2059             :       !  in the second slot
    2060             :       ! recslot = 1 means we use values 2:3, with the current value (2)
    2061             :       !  in the first slot
    2062           0 :       recslot = 1                             ! latter half of month
    2063           0 :       if (mday < midmonth) recslot = 2        ! first half of month
    2064             : 
    2065             :       ! Find interpolation coefficients
    2066           0 :       call interp_coeff_monthly (recslot)
    2067             : 
    2068             :       ! Read 2 monthly values
    2069           0 :       readm = .false.
    2070           0 :       if (istep==1 .or. (mday==midmonth .and. msec==0)) readm = .true.
    2071             : 
    2072           0 :       if (trim(atm_data_format) == 'bin') then
    2073             :          call read_data (readm, 0, fyear, ixm, mmonth, ixp, &
    2074             :                          maxrec, fsw_file, fsw_data, &   ! LCOV_EXCL_LINE
    2075           0 :                          field_loc_center, field_type_scalar)
    2076             :          call read_data (readm, 0, fyear, ixm, mmonth, ixp, &
    2077             :                          maxrec, flw_file, cldf_data, &   ! LCOV_EXCL_LINE
    2078           0 :                          field_loc_center, field_type_scalar)
    2079             :          call read_data (readm, 0, fyear, ixm, mmonth, ixp, &
    2080             :                          maxrec, rain_file, fsnow_data, &   ! LCOV_EXCL_LINE
    2081           0 :                          field_loc_center, field_type_scalar)
    2082             :       else
    2083             :          call abort_ice (error_message=subname//'nonbinary atm_data_format unavailable', &
    2084           0 :             file=__FILE__, line=__LINE__)
    2085             : !        The routine exists, for example:
    2086             : !         call read_data_nc (readm, 0, fyear, ixm, mmonth, ixp, &
    2087             : !                            maxrec, fsw_file, 'fsw', fsw_data, &   ! LCOV_EXCL_LINE
    2088             : !                            field_loc_center, field_type_scalar)
    2089             : !         call read_data_nc (readm, 0, fyear, ixm, mmonth, ixp, &
    2090             : !                            maxrec, flw_file, 'cldf',cldf_data, &   ! LCOV_EXCL_LINE
    2091             : !                            field_loc_center, field_type_scalar)
    2092             : !         call read_data_nc (readm, 0, fyear, ixm, mmonth, ixp, &
    2093             : !                            maxrec, rain_file,'prec',fsnow_data, &   ! LCOV_EXCL_LINE
    2094             : !                            field_loc_center, field_type_scalar)
    2095             :       endif
    2096             : 
    2097             :       ! Interpolate to current time step
    2098           0 :       call interpolate_data (fsw_data,   fsw)
    2099           0 :       call interpolate_data (cldf_data,  cldf)
    2100           0 :       call interpolate_data (fsnow_data, fsnow)
    2101             : 
    2102             :     !-------------------------------------------------------------------
    2103             :     ! 6-hourly data
    2104             :     !
    2105             :     ! Assume that the 6-hourly value is located at the end of the
    2106             :     !  6-hour period.  This is the convention for NCEP reanalysis data.
    2107             :     !  E.g. record 1 gives conditions at 6 am GMT on 1 January.
    2108             :     !-------------------------------------------------------------------
    2109             : 
    2110           0 :       dataloc = 2               ! data located at end of interval
    2111           0 :       sec6hr = secday/c4        ! seconds in 6 hours
    2112           0 :       maxrec = 1460             ! 365*4
    2113             : 
    2114             :       ! current record number
    2115           0 :       recnum = 4*int(yday) - 3 + int(real(msec,kind=dbl_kind)/sec6hr)
    2116             : 
    2117             :       ! Compute record numbers for surrounding data
    2118             : 
    2119           0 :       ixm = mod(recnum+maxrec-2,maxrec) + 1
    2120           0 :       ixx = mod(recnum-1,       maxrec) + 1
    2121             : !      ixp = mod(recnum,         maxrec) + 1
    2122             : 
    2123             :       ! Compute interpolation coefficients
    2124             :       ! If data is located at the end of the time interval, then the
    2125             :       !  data value for the current record always goes in slot 2.
    2126             : 
    2127           0 :       recslot = 2
    2128           0 :       ixp = -99
    2129           0 :       call interp_coeff (recnum, recslot, sec6hr, dataloc)
    2130             : 
    2131             :       ! Read
    2132           0 :       read6 = .false.
    2133           0 :       if (istep==1 .or. oldrecnum /= recnum) read6 = .true.
    2134             : 
    2135           0 :       if (trim(atm_data_format) == 'bin') then
    2136             :          call read_data (read6, 0, fyear, ixm, ixx, ixp, &
    2137             :                          maxrec, tair_file, Tair_data, &   ! LCOV_EXCL_LINE
    2138           0 :                          field_loc_center, field_type_scalar)
    2139             :          call read_data (read6, 0, fyear, ixm, ixx, ixp, &
    2140             :                          maxrec, uwind_file, uatm_data, &   ! LCOV_EXCL_LINE
    2141           0 :                          field_loc_center, field_type_vector)
    2142             :          call read_data (read6, 0, fyear, ixm, ixx, ixp, &
    2143             :                          maxrec, vwind_file, vatm_data, &   ! LCOV_EXCL_LINE
    2144           0 :                          field_loc_center, field_type_vector)
    2145             :          call read_data (read6, 0, fyear, ixm, ixx, ixp, &
    2146             :                          maxrec, rhoa_file, rhoa_data, &   ! LCOV_EXCL_LINE
    2147           0 :                          field_loc_center, field_type_scalar)
    2148             :          call read_data (read6, 0, fyear, ixm, ixx, ixp, &
    2149             :                          maxrec, humid_file, Qa_data, &   ! LCOV_EXCL_LINE
    2150           0 :                          field_loc_center, field_type_scalar)
    2151             :       else
    2152             :          call abort_ice (error_message=subname//'nonbinary atm_data_format unavailable', &
    2153           0 :             file=__FILE__, line=__LINE__)
    2154             :       endif
    2155             : 
    2156             :       ! Interpolate
    2157           0 :       call interpolate_data (Tair_data, Tair)
    2158           0 :       call interpolate_data (uatm_data, uatm)
    2159           0 :       call interpolate_data (vatm_data, vatm)
    2160           0 :       call interpolate_data (rhoa_data, rhoa)
    2161           0 :       call interpolate_data (Qa_data,   Qa)
    2162             : 
    2163             :       ! Save record number for next time step
    2164           0 :       oldrecnum = recnum
    2165             : 
    2166           0 :       end subroutine ncar_data
    2167             : 
    2168             : !=======================================================================
    2169             : 
    2170          21 :       subroutine JRA55_files(yr)
    2171             : 
    2172             :       ! find the JRA55 files:
    2173             :       ! This subroutine finds the JRA55 atm forcing files based on settings
    2174             :       ! in atm_data_type and atm_data_dir.  Because the filenames are not
    2175             :       ! entirely consistent, we need a flexible method.
    2176             :       !
    2177             :       ! atm_data_type could be JRA55 or JRA55do with/without _grid appended
    2178             :       ! atm_data_dir could contain JRA55 or JRA55do or not
    2179             :       ! actual files could have grid in name in two location or not at all
    2180             :       !
    2181             :       ! The files will generally be of the format
    2182             :       !    $atm_data_type/[JRA55,JRA55do,'']/8XDAILY/[JRA55,JRA55do][_$grid,'']_03hr_forcing[_$grid,'']_$year.nc
    2183             :       ! The options defined by cnt try several versions of paths/filenames
    2184             :       ! As a user,
    2185             :       !    atm_data_type should be set to JRA55, JRA55do, JRA55_xxx, or JRA55do_xxx
    2186             :       !       where xxx can be any set of characters.  The _xxx if included will be ignored.
    2187             :       !       Historically, these were set to JRA55_gx1 and so forth but the _gx1 is no longer needed
    2188             :       !       but this is still allowed for backwards compatibility.  atm_data_type_prefix
    2189             :       !       is atm_data_type with _ and everything after _ removed.
    2190             :       !    atm_data_dir should be set to ${CICE_DATA_root}/forcing/$grid/[JRA55,JRA55do,'']
    2191             :       !       The [JRA55,JRA55do] at the end of the atm_data_dir is optional to provide backwards
    2192             :       !       compatibility and if not included, will be appended automaticaly using
    2193             :       !       the atm_data_type_prefix value.  The grid is typically gx1, gx3, tx1, or similar.
    2194             :       ! In general, we recommend using the following format
    2195             :       !    atm_data_type = [JRA55,JRA55do]
    2196             :       !    atm_data_dir = ${CICE_DATA_root}/forcing/$grid
    2197             : 
    2198             :       integer (kind=int_kind), intent(in) :: &
    2199             :            yr         ! current forcing year
    2200             : 
    2201             :       ! local variables
    2202             :       character(len=16) :: &
    2203             :            grd        ! gx3, gx1, tx1
    2204             : 
    2205             :       character(len=64) :: &
    2206             :            atm_data_type_prefix  ! atm_data_type prefix
    2207             : 
    2208             :       integer (kind=int_kind) :: &
    2209             :            cnt    , & ! search for files   ! LCOV_EXCL_LINE
    2210             :            strind     ! string index
    2211             : 
    2212             :       logical :: &
    2213             :            exists     ! file existance
    2214             : 
    2215             :       character(len=*), parameter :: subname = '(JRA55_files)'
    2216             : 
    2217             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    2218             : 
    2219             :       ! this could be JRA55[do] or JRA55[do]_grid, drop the _grid if set
    2220          21 :       atm_data_type_prefix = trim(atm_data_type)
    2221          21 :       strind = index(trim(atm_data_type),'_')
    2222          21 :       if (strind > 0) then
    2223           0 :          atm_data_type_prefix = atm_data_type(1:strind-1)
    2224             :       endif
    2225             : 
    2226             :       ! check for grid version using fortran INDEX intrinsic
    2227          21 :       if (index(trim(atm_data_dir),'gx1') > 0) then
    2228           0 :          grd = 'gx1'
    2229          21 :       else if (index(trim(atm_data_dir),'gx3') > 0) then
    2230          21 :          grd = 'gx3'
    2231           0 :       else if (index(trim(atm_data_dir),'tx1') > 0) then
    2232           0 :          grd = 'tx1'
    2233             :       else
    2234           0 :          call abort_ice(error_message=subname//' unknown grid type')
    2235             :       endif
    2236             : 
    2237             :       ! cnt represents the possible file format options and steps thru them until one is found
    2238          21 :       exists = .false.
    2239          21 :       cnt = 1
    2240          42 :       do while (.not.exists .and. cnt <= 6)
    2241          21 :          if (cnt == 1) uwind_file = trim(atm_data_dir)//'/'//trim(atm_data_type_prefix)// &
    2242          21 :                                     '/8XDAILY/'//trim(atm_data_type_prefix)//'_'//trim(grd)//'_03hr_forcing_2005.nc'
    2243             : 
    2244          21 :          if (cnt == 2) uwind_file = trim(atm_data_dir)//'/'//trim(atm_data_type_prefix)// &
    2245           0 :                                     '/8XDAILY/'//trim(atm_data_type_prefix)//'_03hr_forcing_'//trim(grd)//'_2005.nc'
    2246             : 
    2247          21 :          if (cnt == 3) uwind_file = trim(atm_data_dir)//'/'//trim(atm_data_type_prefix)// &
    2248           0 :                                     '/8XDAILY/'//trim(atm_data_type_prefix)//                '_03hr_forcing_2005.nc'
    2249             : 
    2250          21 :          if (cnt == 4) uwind_file = trim(atm_data_dir)//                                  &
    2251           0 :                                     '/8XDAILY/'//trim(atm_data_type_prefix)//'_'//trim(grd)//'_03hr_forcing_2005.nc'
    2252             : 
    2253          21 :          if (cnt == 5) uwind_file = trim(atm_data_dir)//                                  &
    2254           0 :                                     '/8XDAILY/'//trim(atm_data_type_prefix)//'_03hr_forcing_'//trim(grd)//'_2005.nc'
    2255             : 
    2256          21 :          if (cnt == 6) uwind_file = trim(atm_data_dir)//                                  &
    2257           0 :                                     '/8XDAILY/'//trim(atm_data_type_prefix)//                '_03hr_forcing_2005.nc'
    2258             : 
    2259          21 :          call file_year(uwind_file,yr)
    2260          21 :          INQUIRE(FILE=uwind_file,EXIST=exists)
    2261             : !         if (my_task == master_task) then
    2262             : !            write(nu_diag,*) subname,cnt,exists,trim(uwind_file)
    2263             : !         endif
    2264          21 :          cnt = cnt + 1
    2265             :       enddo
    2266             : 
    2267          21 :       if (.not.exists) then
    2268           0 :          call abort_ice(error_message=subname//' could not find forcing file')
    2269             :       endif
    2270             : 
    2271          21 :       if (my_task == master_task) then
    2272           5 :          write (nu_diag,'(2a)') ' '
    2273           5 :          write (nu_diag,'(2a)') subname,'Atmospheric data files:'
    2274           5 :          write (nu_diag,'(2a)') subname,trim(uwind_file)
    2275             :       endif
    2276             : 
    2277          21 :     end subroutine JRA55_files
    2278             : 
    2279             : !=======================================================================
    2280             : 
    2281        2904 :       subroutine JRA55_data
    2282             : 
    2283             :       use ice_blocks, only: block, get_block
    2284             :       use ice_global_reductions, only: global_minval, global_maxval
    2285             :       use ice_domain, only: nblocks, distrb_info
    2286             :       use ice_flux, only: fsnow, Tair, uatm, vatm, Qa, fsw, flw
    2287             :       use ice_grid, only: hm, tmask, umask
    2288             :       use ice_state, only: aice
    2289             :       use ice_calendar, only: days_per_year
    2290             : 
    2291             :       integer (kind=int_kind) :: &
    2292             :           ncid        , & ! netcdf file id   ! LCOV_EXCL_LINE
    2293             :           i, j, n1    , &   ! LCOV_EXCL_LINE
    2294             :           lfyear      , & ! local year value   ! LCOV_EXCL_LINE
    2295             :           recnum      , & ! record number   ! LCOV_EXCL_LINE
    2296             :           maxrec      , & ! maximum record number   ! LCOV_EXCL_LINE
    2297             :           iblk            ! block index
    2298             : 
    2299             :       integer (kind=int_kind), save :: &
    2300             :           frec_info(2,2) = -99    ! remember prior values to reduce reading
    2301             :                                   ! first dim is yr, recnum
    2302             :                                   ! second dim is data1 data2
    2303             : 
    2304             :       real (kind=dbl_kind) :: &
    2305             :           sec3hr          , & ! number of seconds in 3 hours   ! LCOV_EXCL_LINE
    2306             :           secday          , & ! number of seconds in day   ! LCOV_EXCL_LINE
    2307             :           eps, tt         , & ! for interpolation coefficients   ! LCOV_EXCL_LINE
    2308             :           Tffresh         , &   ! LCOV_EXCL_LINE
    2309        1440 :           vmin, vmax
    2310             : 
    2311             :       character(len=64) :: fieldname !netcdf field name
    2312             :       character (char_len_long) :: uwind_file_old
    2313             :       character(len=*), parameter :: subname = '(JRA55_data)'
    2314             : 
    2315             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    2316             : 
    2317        2904 :       call icepack_query_parameters(Tffresh_out=Tffresh)
    2318        2904 :       call icepack_query_parameters(secday_out=secday)
    2319        2904 :       call icepack_warnings_flush(nu_diag)
    2320        2904 :       if (icepack_warnings_aborted()) call abort_ice(error_message=subname, &
    2321           0 :          file=__FILE__, line=__LINE__)
    2322             : 
    2323        2904 :       sec3hr = secday/c8        ! seconds in 3 hours
    2324        2904 :       maxrec = days_per_year * 8
    2325             : 
    2326             :       if (local_debug .and. my_task == master_task) then
    2327             :          write(nu_diag,*) subname,'fdbg dpy, maxrec = ',days_per_year,maxrec
    2328             :       endif
    2329             : 
    2330             :       !-------------------------------------------------------------------
    2331             :       ! 3-hourly data
    2332             :       ! states are instantaneous, 1st record is 00z Jan 1
    2333             :       ! fluxes are 3 hour averages, 1st record is 00z-03z Jan 1
    2334             :       ! interpolate states, do not interpolate fluxes
    2335             :       !-------------------------------------------------------------------
    2336             :       ! File is NETCDF with winds in NORTH and EAST direction
    2337             :       ! file variable names are:
    2338             :       ! glbrad   (shortwave W/m^2), 3 hr average
    2339             :       ! dlwsfc   (longwave W/m^2), 3 hr average
    2340             :       ! wndewd   (eastward wind m/s), instantaneous
    2341             :       ! wndnwd   (northward wind m/s), instantaneous
    2342             :       ! airtmp   (air temperature K), instantaneous
    2343             :       ! spchmd   (specific humidity kg/kg), instantaneous
    2344             :       ! ttlpcp   (precipitation kg/m s-1), 3 hr average
    2345             :       !-------------------------------------------------------------------
    2346             : 
    2347        2904 :       uwind_file_old = uwind_file
    2348        2904 :       if (uwind_file /= uwind_file_old .and. my_task == master_task) then
    2349           0 :          write(nu_diag,'(2a)') subname,' reading forcing file = ',trim(uwind_file)
    2350             :       endif
    2351             : 
    2352        2904 :       call ice_open_nc(uwind_file,ncid)
    2353             : 
    2354        8712 :       do n1 = 1, 2
    2355             : 
    2356        5808 :          lfyear = fyear
    2357        5808 :          call file_year(uwind_file,lfyear)
    2358        5808 :          if (n1 == 1) then
    2359        2904 :             recnum = 8*int(yday) - 7 + int(real(msec,kind=dbl_kind)/sec3hr)
    2360        2904 :             if (my_task == master_task .and. (recnum <= 2 .or. recnum >= maxrec-1)) then
    2361          20 :                write(nu_diag,'(3a)') subname,' reading forcing file 1st ts = ',trim(uwind_file)
    2362             :             endif
    2363        2904 :          elseif (n1 == 2) then
    2364        2904 :             recnum = 8*int(yday) - 7 + int(real(msec,kind=dbl_kind)/sec3hr) + 1
    2365        2904 :             if (recnum > maxrec) then
    2366           0 :                lfyear = fyear + 1  ! next year
    2367           0 :                if (lfyear > fyear_final) lfyear = fyear_init
    2368           0 :                recnum = 1
    2369           0 :                call file_year(uwind_file,lfyear)
    2370           0 :                if (my_task == master_task) then
    2371           0 :                   write(nu_diag,'(3a)') subname,' reading forcing file 2nd ts = ',trim(uwind_file)
    2372             :                endif
    2373           0 :                call ice_close_nc(ncid)
    2374           0 :                call ice_open_nc(uwind_file,ncid)
    2375             :             endif
    2376             :          endif
    2377             : 
    2378             :          if (local_debug .and. my_task == master_task) then
    2379             :             write(nu_diag,*) subname,'fdbg read recnum = ',recnum,n1
    2380             :          endif
    2381             : 
    2382             :          ! to reduce reading, check whether it's the same data as last read
    2383             : 
    2384        5808 :          if (lfyear /= frec_info(1,n1) .or. recnum /= frec_info(2,n1)) then
    2385             : 
    2386             :             ! check whether we can copy values from 2 to 1, should be faster than reading
    2387             :             ! can only do this from 2 to 1 or 1 to 2 without setting up a temporary
    2388             :             ! it's more likely that the values from data2 when time advances are needed in data1
    2389             :             ! compare n1=1 year/record with data from last timestep at n1=2
    2390             : 
    2391        1978 :             if (n1 == 1 .and. lfyear == frec_info(1,2) .and. recnum == frec_info(2,2)) then
    2392     3119648 :                 Tair_data(:,:,1,:) =  Tair_data(:,:,2,:)
    2393     3119648 :                 uatm_data(:,:,1,:) =  uatm_data(:,:,2,:)
    2394     3119648 :                 vatm_data(:,:,1,:) =  vatm_data(:,:,2,:)
    2395     3119648 :                   Qa_data(:,:,1,:) =    Qa_data(:,:,2,:)
    2396     3119648 :                  fsw_data(:,:,1,:) =   fsw_data(:,:,2,:)
    2397     3119648 :                  flw_data(:,:,1,:) =   flw_data(:,:,2,:)
    2398     3119648 :                fsnow_data(:,:,1,:) = fsnow_data(:,:,2,:)
    2399             :             else
    2400             : 
    2401        1010 :                fieldname = 'airtmp'
    2402           0 :                call ice_read_nc(ncid,recnum,fieldname,Tair_data(:,:,n1,:),local_debug, &
    2403             :                     field_loc=field_loc_center, &   ! LCOV_EXCL_LINE
    2404        1010 :                     field_type=field_type_scalar)
    2405             : 
    2406        1010 :                fieldname = 'wndewd'
    2407           0 :                call ice_read_nc(ncid,recnum,fieldname,uatm_data(:,:,n1,:),local_debug, &
    2408             :                     field_loc=field_loc_center, &   ! LCOV_EXCL_LINE
    2409        1010 :                     field_type=field_type_scalar)
    2410             : 
    2411        1010 :                fieldname = 'wndnwd'
    2412           0 :                call ice_read_nc(ncid,recnum,fieldname,vatm_data(:,:,n1,:),local_debug, &
    2413             :                     field_loc=field_loc_center, &   ! LCOV_EXCL_LINE
    2414        1010 :                     field_type=field_type_scalar)
    2415             : 
    2416        1010 :                fieldname = 'spchmd'
    2417           0 :                call ice_read_nc(ncid,recnum,fieldname,Qa_data(:,:,n1,:),local_debug, &
    2418             :                     field_loc=field_loc_center, &   ! LCOV_EXCL_LINE
    2419        1010 :                     field_type=field_type_scalar)
    2420             : 
    2421        1010 :                fieldname = 'glbrad'
    2422           0 :                call ice_read_nc(ncid,recnum,fieldname,fsw_data(:,:,n1,:),local_debug, &
    2423             :                     field_loc=field_loc_center, &   ! LCOV_EXCL_LINE
    2424        1010 :                     field_type=field_type_scalar)
    2425             : 
    2426        1010 :                fieldname = 'dlwsfc'
    2427           0 :                call ice_read_nc(ncid,recnum,fieldname,flw_data(:,:,n1,:),local_debug, &
    2428             :                     field_loc=field_loc_center, &   ! LCOV_EXCL_LINE
    2429        1010 :                     field_type=field_type_scalar)
    2430             : 
    2431        1010 :                fieldname = 'ttlpcp'
    2432           0 :                call ice_read_nc(ncid,recnum,fieldname,fsnow_data(:,:,n1,:),local_debug, &
    2433             :                     field_loc=field_loc_center, &   ! LCOV_EXCL_LINE
    2434        1010 :                     field_type=field_type_scalar)
    2435             :             endif  ! copy data from n1=2 from last timestep to n1=1
    2436             :          endif  ! input data is same as last timestep
    2437             : 
    2438        5808 :          frec_info(1,n1) = lfyear
    2439        8712 :          frec_info(2,n1) = recnum
    2440             : 
    2441             :       enddo  ! n1
    2442             : 
    2443        2904 :       call ice_close_nc(ncid)
    2444             : 
    2445             :       ! reset uwind_file to original year
    2446        2904 :       call file_year(uwind_file,fyear)
    2447             : 
    2448             :       ! Compute interpolation coefficients
    2449        2904 :       eps = 1.0e-6
    2450        2904 :       tt = real(mod(msec,nint(sec3hr)),kind=dbl_kind)
    2451        2904 :       c2intp = tt / sec3hr
    2452        2904 :       if (c2intp < c0 .and. c2intp > c0-eps) c2intp = c0
    2453        2904 :       if (c2intp > c1 .and. c2intp < c1+eps) c2intp = c1
    2454        2904 :       c1intp = 1.0_dbl_kind - c2intp
    2455        2904 :       if (c2intp < c0 .or. c2intp > c1) then
    2456           0 :          write(nu_diag,*) subname,' ERROR: c2intp = ',c2intp
    2457             :          call abort_ice (error_message=subname//' ERROR: c2intp out of range', &
    2458           0 :             file=__FILE__, line=__LINE__)
    2459             :       endif
    2460             :       if (local_debug .and. my_task == master_task) then
    2461             :          write(nu_diag,*) subname,'fdbg c12intp = ',c1intp,c2intp
    2462             :       endif
    2463             : 
    2464             :       ! Interpolate
    2465        2904 :       call interpolate_data (Tair_data, Tair)
    2466        2904 :       call interpolate_data (uatm_data, uatm)
    2467        2904 :       call interpolate_data (vatm_data, vatm)
    2468        2904 :       call interpolate_data (Qa_data, Qa)
    2469             :       ! use 3 hr average for heat flux and precip fields, no interpolation
    2470             : !      call interpolate_data (fsw_data, fsw)
    2471             : !      call interpolate_data (flw_data, flw)
    2472             : !      call interpolate_data (fsnow_data, fsnow)
    2473     9358944 :       fsw(:,:,:) = fsw_data(:,:,1,:)
    2474     9358944 :       flw(:,:,:) = flw_data(:,:,1,:)
    2475     9358944 :       fsnow(:,:,:) = fsnow_data(:,:,1,:)
    2476             : 
    2477        2880 :       !$OMP PARALLEL DO PRIVATE(iblk,i,j)
    2478          48 :       do iblk = 1, nblocks
    2479             :         ! limit summer Tair values where ice is present
    2480        2856 :         do j = 1, ny_block
    2481      291720 :           do i = 1, nx_block
    2482      291696 :             if (aice(i,j,iblk) > p1) Tair(i,j,iblk) = min(Tair(i,j,iblk), Tffresh+p1)
    2483             :           enddo
    2484             :         enddo
    2485             : 
    2486        5760 :         do j = 1, ny_block
    2487      291720 :           do i = 1, nx_block
    2488      288864 :             Qa  (i,j,iblk) = Qa  (i,j,iblk) * hm(i,j,iblk)
    2489      288864 :             Tair(i,j,iblk) = Tair(i,j,iblk) * hm(i,j,iblk)
    2490      288864 :             uatm(i,j,iblk) = uatm(i,j,iblk) * hm(i,j,iblk)
    2491      288864 :             vatm(i,j,iblk) = vatm(i,j,iblk) * hm(i,j,iblk)
    2492      288864 :             fsw (i,j,iblk) = fsw (i,j,iblk) * hm(i,j,iblk)
    2493      288864 :             flw (i,j,iblk) = flw (i,j,iblk) * hm(i,j,iblk)
    2494      291696 :             fsnow(i,j,iblk) = fsnow (i,j,iblk) * hm(i,j,iblk)
    2495             :           enddo
    2496             :         enddo
    2497             : 
    2498             :       enddo  ! iblk
    2499             :       !$OMP END PARALLEL DO
    2500             : 
    2501        2904 :       if (debug_forcing .or. local_debug) then
    2502           0 :          if (my_task.eq.master_task) write (nu_diag,*) subname,'fdbg JRA55_bulk_data'
    2503           0 :          vmin = global_minval(fsw,distrb_info,tmask)
    2504           0 :          vmax = global_maxval(fsw,distrb_info,tmask)
    2505           0 :          if (my_task.eq.master_task) write (nu_diag,*) subname,'fdbg fsw',vmin,vmax
    2506           0 :          vmin = global_minval(flw,distrb_info,tmask)
    2507           0 :          vmax = global_maxval(flw,distrb_info,tmask)
    2508           0 :          if (my_task.eq.master_task) write (nu_diag,*) subname,'fdbg flw',vmin,vmax
    2509           0 :          vmin =global_minval(fsnow,distrb_info,tmask)
    2510           0 :          vmax =global_maxval(fsnow,distrb_info,tmask)
    2511           0 :          if (my_task.eq.master_task) write (nu_diag,*) subname,'fdbg fsnow',vmin,vmax
    2512           0 :          vmin = global_minval(Tair,distrb_info,tmask)
    2513           0 :          vmax = global_maxval(Tair,distrb_info,tmask)
    2514           0 :          if (my_task.eq.master_task) write (nu_diag,*) subname,'fdbg Tair',vmin,vmax
    2515           0 :          vmin = global_minval(uatm,distrb_info,umask)
    2516           0 :          vmax = global_maxval(uatm,distrb_info,umask)
    2517           0 :          if (my_task.eq.master_task) write (nu_diag,*) subname,'fdbg uatm',vmin,vmax
    2518           0 :          vmin = global_minval(vatm,distrb_info,umask)
    2519           0 :          vmax = global_maxval(vatm,distrb_info,umask)
    2520           0 :          if (my_task.eq.master_task) write (nu_diag,*) subname,'fdbg vatm',vmin,vmax
    2521           0 :          vmin = global_minval(Qa,distrb_info,tmask)
    2522           0 :          vmax = global_maxval(Qa,distrb_info,tmask)
    2523           0 :          if (my_task.eq.master_task) write (nu_diag,*) subname,'fdbg Qa',vmin,vmax
    2524             :       endif                   ! debug_forcing
    2525             : 
    2526        5808 :       end subroutine JRA55_data
    2527             : 
    2528             : !=======================================================================
    2529             : !
    2530             : ! AOMIP shortwave forcing
    2531             : ! standard calculation using solar declination angle
    2532             : ! then shortwave is reduced using a function of cloud fraction
    2533             : 
    2534           0 :       subroutine compute_shortwave(nx_block,  ny_block, &
    2535             :                                    ilo, ihi, jlo, jhi, &   ! LCOV_EXCL_LINE
    2536           0 :                                    TLON, TLAT, hm, Qa, cldf, fsw)
    2537             : 
    2538             : !---!-------------------------------------------------------------------
    2539             : !---!-------------------------------------------------------------------
    2540             : 
    2541             :       integer (kind=int_kind), intent(in) :: &
    2542             :          nx_block, ny_block, & ! block dimensions   ! LCOV_EXCL_LINE
    2543             :          ilo,ihi,jlo,jhi       ! beginning and end of physical domain
    2544             : 
    2545             :       real (kind=dbl_kind), dimension(nx_block,ny_block), intent(in) :: &
    2546             :          TLON, TLAT     , & ! longitude, latitude   ! LCOV_EXCL_LINE
    2547             :          Qa             , & ! specific humidity   ! LCOV_EXCL_LINE
    2548             :          cldf           , & ! cloud fraction   ! LCOV_EXCL_LINE
    2549             :          hm                 ! land mask
    2550             : 
    2551             :       real (kind=dbl_kind), dimension(nx_block,ny_block), intent(inout) :: &
    2552             :          fsw                ! shortwave
    2553             : 
    2554             :       real (kind=dbl_kind) :: &
    2555             :          hour_angle, &   ! LCOV_EXCL_LINE
    2556             :          solar_time, &   ! LCOV_EXCL_LINE
    2557             :          declin    , &   ! LCOV_EXCL_LINE
    2558             :          cosZ      , &   ! LCOV_EXCL_LINE
    2559             :          e, d      , &   ! LCOV_EXCL_LINE
    2560             :          sw0       , &   ! LCOV_EXCL_LINE
    2561             :          secday    , &   ! LCOV_EXCL_LINE
    2562             :          pi        , &   ! LCOV_EXCL_LINE
    2563             :          lontmp    , &   ! LCOV_EXCL_LINE
    2564           0 :          deg2rad
    2565             : 
    2566             :       integer (kind=int_kind) :: &
    2567             :          i, j
    2568             : 
    2569             :       character(len=*), parameter :: subname = '(compute_shortwave)'
    2570             : 
    2571             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    2572             : 
    2573           0 :       call icepack_query_parameters(secday_out=secday, pi_out=pi)
    2574           0 :       call icepack_warnings_flush(nu_diag)
    2575           0 :       if (icepack_warnings_aborted()) call abort_ice(error_message=subname, &
    2576           0 :          file=__FILE__, line=__LINE__)
    2577             : 
    2578           0 :       do j=jlo,jhi
    2579           0 :        do i=ilo,ihi
    2580           0 :         deg2rad = pi/c180
    2581             : !       solar_time = mod(real(msec,kind=dbl_kind),secday)/c3600 &
    2582             : !                  + c12*sin(p5*TLON(i,j))
    2583             : 
    2584             : !       Convert longitude to range of -180 to 180 for LST calculation
    2585             : 
    2586           0 :         lontmp = mod(TLON(i,j)/deg2rad,c360)
    2587           0 :         if (lontmp .gt. c180) lontmp = lontmp - c360
    2588           0 :         if (lontmp .lt. -c180) lontmp = lontmp + c360
    2589             : 
    2590             :         solar_time = mod(real(msec,kind=dbl_kind),secday)/c3600 &
    2591           0 :                    + lontmp/c15
    2592           0 :         if (solar_time .ge. 24._dbl_kind) solar_time = solar_time - 24._dbl_kind
    2593           0 :         hour_angle = (c12 - solar_time)*pi/c12
    2594             :         declin = 23.44_dbl_kind*cos((172._dbl_kind-yday) &
    2595           0 :                  * c2*pi/c365)*deg2rad     ! use dayyr instead of c365???
    2596           0 :         cosZ = sin(TLAT(i,j))*sin(declin) &
    2597           0 :              + cos(TLAT(i,j))*cos(declin)*cos(hour_angle)
    2598           0 :         cosZ = max(cosZ,c0)
    2599           0 :         e = 1.e5*Qa(i,j)/(0.622_dbl_kind + 0.378_dbl_kind*Qa(i,j))
    2600           0 :         d = (cosZ+2.7_dbl_kind)*e*1.e-5_dbl_kind+1.085_dbl_kind*cosZ+p1
    2601           0 :         sw0 = 1353._dbl_kind*cosZ**2/d
    2602           0 :         sw0 = max(sw0,c0)
    2603             : 
    2604             :         ! total downward shortwave for cice
    2605           0 :         Fsw(i,j) = sw0*(c1-p6*cldf(i,j)**3)
    2606           0 :         Fsw(i,j) = Fsw(i,j)*hm(i,j)
    2607             :        enddo
    2608             :       enddo
    2609             : 
    2610           0 :       end subroutine compute_shortwave
    2611             : 
    2612             : !=======================================================================
    2613             : !
    2614             : ! prevents humidity from being super-saturated
    2615             : 
    2616           0 :       subroutine Qa_fixLY(nx_block, ny_block, Tair, Qa)
    2617             : 
    2618             :       integer (kind=int_kind), intent(in) :: &
    2619             :          nx_block, ny_block ! block dimensions
    2620             : 
    2621             :       real (kind=dbl_kind), dimension(nx_block,ny_block), intent(in) :: &
    2622             :          Tair               ! air temperature
    2623             : 
    2624             :       real (kind=dbl_kind), dimension(nx_block,ny_block), intent(inout) :: &
    2625             :          Qa                 ! specific humidity
    2626             : 
    2627             :       real (kind=dbl_kind), dimension (nx_block,ny_block) :: &
    2628           0 :          worka
    2629             : 
    2630             :       real (kind=dbl_kind) :: &
    2631           0 :          Tffresh, puny
    2632             : 
    2633             :       character(len=*), parameter :: subname = '(Qa_fixLY)'
    2634             : 
    2635             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    2636             : 
    2637           0 :       call icepack_query_parameters(Tffresh_out=Tffresh, puny_out=puny)
    2638           0 :       call icepack_warnings_flush(nu_diag)
    2639           0 :       if (icepack_warnings_aborted()) call abort_ice(error_message=subname, &
    2640           0 :          file=__FILE__, line=__LINE__)
    2641             : 
    2642           0 :       worka = Tair - Tffresh
    2643           0 :       worka = c2 + (0.7859_dbl_kind + 0.03477_dbl_kind*worka) &
    2644             :                      /(c1 + 0.00412_dbl_kind*worka) & ! 2+ converts ea mb -> Pa   ! LCOV_EXCL_LINE
    2645           0 :                 + 0.00422_dbl_kind*worka              ! for ice
    2646             :       ! vapor pressure
    2647           0 :       worka = (c10**worka)      ! saturated
    2648           0 :       worka = max(worka,puny)   ! puny over land to prevent division by zero
    2649             :       ! specific humidity
    2650           0 :       worka = 0.622_dbl_kind*worka/(1.e5_dbl_kind-0.378_dbl_kind*worka)
    2651             : 
    2652           0 :       Qa = min(Qa, worka)
    2653             : 
    2654           0 :       end subroutine Qa_fixLY
    2655             : 
    2656             : !=======================================================================
    2657             : ! HadGEM or HadGAM atmospheric forcing
    2658             : !=======================================================================
    2659             : 
    2660           0 :       subroutine hadgem_files (yr)
    2661             : 
    2662             : ! Construct filenames based on selected model options
    2663             : !
    2664             : ! Note: The year number in these filenames does not matter, because
    2665             : !       subroutine file_year will insert the correct year.
    2666             : !
    2667             : ! author: Alison McLaren, Met Office
    2668             : 
    2669             :       integer (kind=int_kind), intent(in) :: &
    2670             :            yr                   ! current forcing year
    2671             : 
    2672             :       integer (kind=int_kind) :: &
    2673             :            n           ! thickness category index
    2674             : 
    2675             :       logical (kind=log_kind) :: calc_strair, calc_Tsfc
    2676             : 
    2677             :       character(len=*), parameter :: subname = '(hadgem_files)'
    2678             : 
    2679             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    2680             : 
    2681             :       call icepack_query_parameters(calc_strair_out=calc_strair, &
    2682           0 :            calc_Tsfc_out=calc_Tsfc)
    2683           0 :       call icepack_warnings_flush(nu_diag)
    2684           0 :       if (icepack_warnings_aborted()) call abort_ice(error_message=subname, &
    2685           0 :          file=__FILE__, line=__LINE__)
    2686             : 
    2687             :       ! -----------------------------------------------------------
    2688             :       ! Rainfall and snowfall
    2689             :       ! -----------------------------------------------------------
    2690             : 
    2691             :       snow_file = &
    2692           0 :            trim(atm_data_dir)//'/MONTHLY/snowfall.1996.nc'
    2693           0 :            call file_year(snow_file,yr)
    2694             : 
    2695             :       rain_file = &
    2696           0 :            trim(atm_data_dir)//'/MONTHLY/rainfall.1996.nc'
    2697           0 :            call file_year(rain_file,yr)
    2698             : 
    2699           0 :       if (my_task == master_task) then
    2700           0 :          write (nu_diag,*) ' '
    2701           0 :          write (nu_diag,*) 'Atmospheric data files:'
    2702           0 :          write (nu_diag,*) trim(rain_file)
    2703           0 :          write (nu_diag,*) trim(snow_file)
    2704             :       endif
    2705             : 
    2706           0 :       if (calc_strair) then
    2707             : 
    2708             :          ! --------------------------------------------------------
    2709             :          ! Wind velocity
    2710             :          ! --------------------------------------------------------
    2711             : 
    2712             :          uwind_file = &
    2713           0 :            trim(atm_data_dir)//'/MONTHLY/u_10.1996.nc'
    2714           0 :            call file_year(uwind_file,yr)
    2715             : 
    2716             :          vwind_file = &
    2717           0 :            trim(atm_data_dir)//'/MONTHLY/v_10.1996.nc'
    2718           0 :            call file_year(vwind_file,yr)
    2719             : 
    2720           0 :          if (my_task == master_task) then
    2721           0 :             write (nu_diag,*) trim(uwind_file)
    2722           0 :             write (nu_diag,*) trim(vwind_file)
    2723             :          endif
    2724             : 
    2725             :       else
    2726             : 
    2727             :          ! --------------------------------------------------------
    2728             :          ! Wind stress
    2729             :          ! --------------------------------------------------------
    2730             : 
    2731             :          strax_file = &
    2732           0 :               trim(atm_data_dir)//'/MONTHLY/taux.1996.nc'
    2733           0 :          call file_year(strax_file,yr)
    2734             : 
    2735             :          stray_file = &
    2736           0 :               trim(atm_data_dir)//'/MONTHLY/tauy.1996.nc'
    2737           0 :          call file_year(stray_file,yr)
    2738             : 
    2739           0 :          if (my_task == master_task) then
    2740           0 :             write (nu_diag,*) trim(strax_file)
    2741           0 :             write (nu_diag,*) trim(stray_file)
    2742             :          endif
    2743             : 
    2744           0 :          if (calc_Tsfc .or. oceanmixed_ice) then
    2745             : 
    2746             :             ! --------------------------------------------------
    2747             :             ! Wind speed
    2748             :             ! --------------------------------------------------
    2749             : 
    2750             :             wind_file = &
    2751           0 :                trim(atm_data_dir)//'/MONTHLY/wind_10.1996.nc'
    2752           0 :             call file_year(wind_file,yr)
    2753             : 
    2754           0 :             if (my_task == master_task) then
    2755           0 :                write (nu_diag,*) trim(wind_file)
    2756             :             endif
    2757             : 
    2758             :          endif   ! calc_Tsfc or oceanmixed_ice
    2759             : 
    2760             :       endif  ! calc_strair
    2761             : 
    2762             :       ! --------------------------------------------------------------
    2763             :       ! Atmosphere properties.  Even if these fields are not
    2764             :       ! being used to force the ice (i.e. calc_Tsfc=.false.), they
    2765             :       ! are still needed to generate forcing for mixed layer model or
    2766             :       ! to calculate wind stress
    2767             :       ! --------------------------------------------------------------
    2768             : 
    2769           0 :        if (calc_Tsfc .or. oceanmixed_ice .or. calc_strair) then
    2770             : 
    2771             :          fsw_file = &
    2772           0 :            trim(atm_data_dir)//'/MONTHLY/SW_incoming.1996.nc'
    2773           0 :            call file_year(fsw_file,yr)
    2774             : 
    2775             :          flw_file = &
    2776           0 :            trim(atm_data_dir)//'/MONTHLY/LW_incoming.1996.nc'
    2777           0 :            call file_year(flw_file,yr)
    2778             : 
    2779             :          tair_file = &
    2780           0 :            trim(atm_data_dir)//'/MONTHLY/t_10.1996.nc'
    2781           0 :            call file_year(tair_file,yr)
    2782             : 
    2783             :          humid_file = &
    2784           0 :            trim(atm_data_dir)//'/MONTHLY/q_10.1996.nc'
    2785           0 :            call file_year(humid_file,yr)
    2786             : 
    2787             :          rhoa_file = &
    2788           0 :            trim(atm_data_dir)//'/MONTHLY/rho_10.1996.nc'
    2789           0 :            call file_year(rhoa_file,yr)
    2790             : 
    2791           0 :          if (my_task == master_task) then
    2792           0 :             write (nu_diag,*) trim(fsw_file)
    2793           0 :             write (nu_diag,*) trim(flw_file)
    2794           0 :             write (nu_diag,*) trim(tair_file)
    2795           0 :             write (nu_diag,*) trim(humid_file)
    2796           0 :             write (nu_diag,*) trim(rhoa_file)
    2797             :          endif                     ! master_task
    2798             : 
    2799             :       endif ! calc_Tsfc or oceanmixed_ice  or calc_strair
    2800             : 
    2801           0 :       if (.not. calc_Tsfc) then
    2802             : 
    2803             :          ! ------------------------------------------------------
    2804             :          ! Sublimation, topmelt and botmelt
    2805             :          ! ------------------------------------------------------
    2806             : 
    2807           0 :          do n = 1, ncat
    2808             : 
    2809             :             ! 'topmelt' = fsurf - fcondtop.
    2810           0 :             write(topmelt_file(n), '(a,i1,a)')  &
    2811           0 :               trim(atm_data_dir)//'/MONTHLY/topmeltn',n,'.1996.nc'
    2812           0 :               call file_year(topmelt_file(n),yr)
    2813             : 
    2814             :             ! 'botmelt' = fcondtop.
    2815           0 :             write(botmelt_file(n), '(a,i1,a)')  &
    2816           0 :               trim(atm_data_dir)//'/MONTHLY/botmeltn',n,'.1996.nc'
    2817           0 :               call file_year(botmelt_file(n),yr)
    2818             : 
    2819             :          enddo
    2820             : 
    2821             :          ! 'sublim' = - flat / Lsub.
    2822             :          sublim_file = &
    2823           0 :            trim(atm_data_dir)//'/MONTHLY/sublim.1996.nc'
    2824           0 :            call file_year(sublim_file,yr)
    2825             : 
    2826           0 :          if (my_task == master_task) then
    2827           0 :             do n = 1, ncat
    2828           0 :                write (nu_diag,*) trim(topmelt_file(n))
    2829           0 :                write (nu_diag,*) trim(botmelt_file(n))
    2830             :             enddo
    2831           0 :             write (nu_diag,*) trim(sublim_file)
    2832             : 
    2833             :          endif
    2834             : 
    2835             :       endif  ! .not. calc_Tsfc
    2836             : 
    2837           0 :       end subroutine hadgem_files
    2838             : 
    2839             : !=======================================================================
    2840             : 
    2841             : ! read HadGEM or HadGAM atmospheric data
    2842             : 
    2843           0 :       subroutine hadgem_data
    2844             : 
    2845             : ! authors: Alison McLaren, Met Office
    2846             : 
    2847             :       use ice_domain, only: nblocks
    2848             :       use ice_flux, only: fsnow, frain, uatm, vatm, strax, stray, wind, &
    2849             :           fsw, flw, Tair, rhoa, Qa, fcondtopn_f, fsurfn_f, flatn_f
    2850             : 
    2851             :       integer (kind=int_kind) :: &
    2852             :           i, j        , & ! horizontal indices   ! LCOV_EXCL_LINE
    2853             :           n           , & ! thickness category index   ! LCOV_EXCL_LINE
    2854             :           iblk        , & ! block index   ! LCOV_EXCL_LINE
    2855             :           ixm,ixp     , & ! record numbers for neighboring months   ! LCOV_EXCL_LINE
    2856             :           maxrec      , & ! maximum record number   ! LCOV_EXCL_LINE
    2857             :           recslot     , & ! spline slot for current record   ! LCOV_EXCL_LINE
    2858             :           midmonth        ! middle day of month
    2859             : 
    2860             :       logical (kind=log_kind) :: readm
    2861             : 
    2862             :       real (kind=dbl_kind), dimension(nx_block,ny_block,max_blocks) :: &
    2863             :             topmelt, & ! temporary fields   ! LCOV_EXCL_LINE
    2864             :             botmelt, &   ! LCOV_EXCL_LINE
    2865           0 :             sublim
    2866             : 
    2867             :       character (char_len) :: &
    2868             :             fieldname    ! field name in netcdf file
    2869             : 
    2870             :       real (kind=dbl_kind) :: &
    2871           0 :             Lsub
    2872             : 
    2873             :       logical (kind=log_kind) :: &
    2874             :             calc_strair, &   ! LCOV_EXCL_LINE
    2875             :             calc_Tsfc
    2876             : 
    2877             :       character(len=*), parameter :: subname = '(hadgem_data)'
    2878             : 
    2879             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    2880             : 
    2881           0 :       call icepack_query_parameters(Lsub_out=Lsub)
    2882             :       call icepack_query_parameters(calc_strair_out=calc_strair, &
    2883           0 :            calc_Tsfc_out=calc_Tsfc)
    2884           0 :       call icepack_warnings_flush(nu_diag)
    2885           0 :       if (icepack_warnings_aborted()) call abort_ice(error_message=subname, &
    2886           0 :          file=__FILE__, line=__LINE__)
    2887             : 
    2888             :     !-------------------------------------------------------------------
    2889             :     ! monthly data
    2890             :     !
    2891             :     ! Assume that monthly data values are located in the middle of the
    2892             :     ! month.
    2893             :     !-------------------------------------------------------------------
    2894             : 
    2895           0 :       midmonth = 15  ! data is given on 15th of every month
    2896             : !      midmonth = fix(p5 * real(daymo(mmonth)))  ! exact middle
    2897             : 
    2898             :       ! Compute record numbers for surrounding months
    2899           0 :       maxrec = 12
    2900           0 :       ixm  = mod(mmonth+maxrec-2,maxrec) + 1
    2901           0 :       ixp  = mod(mmonth,         maxrec) + 1
    2902           0 :       if (mday >= midmonth) ixm = -99  ! other two points will be used
    2903           0 :       if (mday <  midmonth) ixp = -99
    2904             : 
    2905             :       ! Determine whether interpolation will use values 1:2 or 2:3
    2906             :       ! recslot = 2 means we use values 1:2, with the current value (2)
    2907             :       !  in the second slot
    2908             :       ! recslot = 1 means we use values 2:3, with the current value (2)
    2909             :       !  in the first slot
    2910           0 :       recslot = 1                             ! latter half of month
    2911           0 :       if (mday < midmonth) recslot = 2        ! first half of month
    2912             : 
    2913             :       ! Find interpolation coefficients
    2914           0 :       call interp_coeff_monthly (recslot)
    2915             : 
    2916             :       ! Read 2 monthly values
    2917           0 :       readm = .false.
    2918           0 :       if (istep==1 .or. (mday==midmonth .and. msec==0)) readm = .true.
    2919             : 
    2920             :       ! -----------------------------------------------------------
    2921             :       ! Rainfall and snowfall
    2922             :       ! -----------------------------------------------------------
    2923             : 
    2924           0 :       fieldname='rainfall'
    2925             :       call read_data_nc (readm, 0, fyear, ixm, mmonth, ixp, &
    2926             :                       maxrec, rain_file, fieldname, frain_data, &   ! LCOV_EXCL_LINE
    2927           0 :                       field_loc_center, field_type_scalar)
    2928           0 :       fieldname='snowfall'
    2929             :       call read_data_nc (readm, 0, fyear, ixm, mmonth, ixp, &
    2930             :                       maxrec, snow_file, fieldname, fsnow_data, &   ! LCOV_EXCL_LINE
    2931           0 :                       field_loc_center, field_type_scalar)
    2932             : 
    2933             :       ! Interpolate to current time step
    2934           0 :       call interpolate_data (fsnow_data, fsnow)
    2935           0 :       call interpolate_data (frain_data, frain)
    2936             : 
    2937           0 :       if (calc_strair) then
    2938             : 
    2939             :          ! --------------------------------------------------------
    2940             :          ! Wind velocity
    2941             :          ! --------------------------------------------------------
    2942             : 
    2943           0 :          fieldname='u_10'
    2944             :          call read_data_nc (readm, 0, fyear, ixm, mmonth, ixp, &
    2945             :                       maxrec, uwind_file, fieldname, uatm_data, &   ! LCOV_EXCL_LINE
    2946           0 :                       field_loc_center, field_type_vector)
    2947           0 :          fieldname='v_10'
    2948             :          call read_data_nc (readm, 0, fyear, ixm, mmonth, ixp, &
    2949             :                       maxrec, vwind_file, fieldname, vatm_data, &   ! LCOV_EXCL_LINE
    2950           0 :                       field_loc_center, field_type_vector)
    2951             : 
    2952             :          ! Interpolate to current time step
    2953           0 :          call interpolate_data (uatm_data, uatm)
    2954           0 :          call interpolate_data (vatm_data, vatm)
    2955             : 
    2956             :       else
    2957             : 
    2958             :          ! --------------------------------------------------------
    2959             :          ! Wind stress
    2960             :          ! --------------------------------------------------------
    2961             : 
    2962           0 :          fieldname='taux'
    2963             :          call read_data_nc (readm, 0, fyear, ixm, mmonth, ixp, &
    2964             :                       maxrec, strax_file, fieldname, strax_data, &   ! LCOV_EXCL_LINE
    2965           0 :                       field_loc_center, field_type_vector)
    2966           0 :          fieldname='tauy'
    2967             :          call read_data_nc (readm, 0, fyear, ixm, mmonth, ixp, &
    2968             :                       maxrec, stray_file, fieldname, stray_data, &   ! LCOV_EXCL_LINE
    2969           0 :                       field_loc_center, field_type_vector)
    2970             : 
    2971             :          ! Interpolate to current time step
    2972           0 :          call interpolate_data (strax_data, strax)
    2973           0 :          call interpolate_data (stray_data, stray)
    2974             : 
    2975           0 :          if (calc_Tsfc .or. oceanmixed_ice) then
    2976             : 
    2977             :             ! --------------------------------------------------
    2978             :             ! Wind speed
    2979             :             ! --------------------------------------------------
    2980             : 
    2981           0 :             fieldname='wind_10'
    2982             :             call read_data_nc (readm, 0, fyear, ixm, mmonth, ixp, &
    2983             :                       maxrec, wind_file, fieldname, wind_data, &   ! LCOV_EXCL_LINE
    2984           0 :                       field_loc_center, field_type_scalar)
    2985             : 
    2986             :             ! Interpolate to current time step
    2987           0 :             call interpolate_data (wind_data, wind)
    2988             : 
    2989             :          endif   ! calc_Tsfc or oceanmixed_ice
    2990             : 
    2991             :       endif      ! calc_strair
    2992             : 
    2993             :       ! -----------------------------------------------------------
    2994             :       ! SW incoming, LW incoming, air temperature, density and
    2995             :       ! humidity at 10m.
    2996             :       !
    2997             :       ! Even if these fields are not being used to force the ice
    2998             :       ! (i.e. calc_Tsfc=.false.), they are still needed to generate
    2999             :       ! forcing for mixed layer model or to calculate wind stress
    3000             :       ! -----------------------------------------------------------
    3001             : 
    3002           0 :       if (calc_Tsfc .or. oceanmixed_ice .or. calc_strair) then
    3003             : 
    3004           0 :          fieldname='SW_incoming'
    3005             :          call read_data_nc (readm, 0, fyear, ixm, mmonth, ixp, &
    3006             :                       maxrec, fsw_file, fieldname, fsw_data, &   ! LCOV_EXCL_LINE
    3007           0 :                       field_loc_center, field_type_scalar)
    3008           0 :          fieldname='LW_incoming'
    3009             :          call read_data_nc (readm, 0, fyear, ixm, mmonth, ixp, &
    3010             :                       maxrec, flw_file, fieldname, flw_data, &   ! LCOV_EXCL_LINE
    3011           0 :                       field_loc_center, field_type_scalar)
    3012           0 :          fieldname='t_10'
    3013             :          call read_data_nc (readm, 0, fyear, ixm, mmonth, ixp, &
    3014             :                       maxrec, tair_file, fieldname, Tair_data, &   ! LCOV_EXCL_LINE
    3015           0 :                       field_loc_center, field_type_scalar)
    3016           0 :          fieldname='rho_10'
    3017             :          call read_data_nc (readm, 0, fyear, ixm, mmonth, ixp, &
    3018             :                       maxrec, rhoa_file, fieldname, rhoa_data, &   ! LCOV_EXCL_LINE
    3019           0 :                       field_loc_center, field_type_scalar)
    3020           0 :          fieldname='q_10'
    3021             :          call read_data_nc (readm, 0, fyear, ixm, mmonth, ixp, &
    3022             :                       maxrec, humid_file, fieldname, Qa_data, &   ! LCOV_EXCL_LINE
    3023           0 :                       field_loc_center, field_type_scalar)
    3024             : 
    3025             :          ! Interpolate onto current timestep
    3026             : 
    3027           0 :          call interpolate_data (fsw_data,   fsw)
    3028           0 :          call interpolate_data (flw_data,  flw)
    3029           0 :          call interpolate_data (Tair_data, Tair)
    3030           0 :          call interpolate_data (rhoa_data, rhoa)
    3031           0 :          call interpolate_data (Qa_data,   Qa)
    3032             : 
    3033             :       endif       ! calc_Tsfc or oceanmixed_ice or calc_strair
    3034             : 
    3035           0 :       if (.not. calc_Tsfc) then
    3036             : 
    3037             :          ! ------------------------------------------------------
    3038             :          ! Sublimation, topmelt and botmelt
    3039             :          ! ------------------------------------------------------
    3040             : 
    3041           0 :          fieldname='sublim'
    3042             :          call read_data_nc (readm, 0, fyear, ixm, mmonth, ixp, &
    3043             :                       maxrec, sublim_file, fieldname, sublim_data, &   ! LCOV_EXCL_LINE
    3044           0 :                       field_loc_center, field_type_scalar)
    3045             : 
    3046             :          ! Interpolate to current time step
    3047           0 :          call interpolate_data (sublim_data, sublim)
    3048             : 
    3049           0 :          do n = 1, ncat
    3050           0 :             write(fieldname, '(a,i1)') 'topmeltn',n
    3051             :             call read_data_nc (readm, 0, fyear, ixm, mmonth, ixp, &
    3052             :               maxrec, topmelt_file(n), fieldname, topmelt_data(:,:,:,:,n), &   ! LCOV_EXCL_LINE
    3053           0 :               field_loc_center, field_type_scalar)
    3054             : 
    3055           0 :             write(fieldname, '(a,i1)') 'botmeltn',n
    3056             :             call read_data_nc (readm, 0, fyear, ixm, mmonth, ixp, &
    3057             :               maxrec, botmelt_file(n), fieldname, botmelt_data(:,:,:,:,n), &   ! LCOV_EXCL_LINE
    3058           0 :               field_loc_center, field_type_scalar)
    3059             : 
    3060           0 :             call interpolate_data (topmelt_data(:,:,:,:,n), topmelt)
    3061           0 :             call interpolate_data (botmelt_data(:,:,:,:,n), botmelt)
    3062             : 
    3063             :             !--------------------------------------------------------
    3064             :             ! Convert from UM variables to CICE variables
    3065             :             !  topmelt = fsurf - fcondtop
    3066             :             !  botmelt = fcondtop  (as zero layer)
    3067             :             !
    3068             :             ! Convert UM sublimation data into CICE LH flux
    3069             :             ! (sublim = - flatn / Lsub) and have same value for all
    3070             :             ! categories
    3071             :             !--------------------------------------------------------
    3072             : 
    3073           0 :             !$OMP PARALLEL DO PRIVATE(iblk,i,j)
    3074           0 :             do iblk = 1, nblocks
    3075           0 :                do j = 1, ny_block
    3076           0 :                do i = 1, nx_block
    3077           0 :                   fcondtopn_f(i,j,n,iblk) = botmelt(i,j,iblk)
    3078             :                   fsurfn_f(i,j,n,iblk)    = topmelt(i,j,iblk) &
    3079           0 :                                             + botmelt(i,j,iblk)
    3080           0 :                   flatn_f(i,j,n,iblk)    = - sublim(i,j,iblk)*Lsub
    3081             :                enddo
    3082             :                enddo
    3083             :             enddo
    3084             :             !$OMP END PARALLEL DO
    3085             : 
    3086             :          enddo  ! ncat
    3087             : 
    3088             :       endif   ! .not. calc_Tsfc
    3089             : 
    3090           0 :       end subroutine hadgem_data
    3091             : 
    3092             : !=======================================================================
    3093             : ! monthly forcing
    3094             : !=======================================================================
    3095             : 
    3096           0 :       subroutine monthly_files (yr)
    3097             : 
    3098             : ! Construct filenames based on the LANL naming conventions for NCAR data.
    3099             : ! Edit for other directory structures or filenames.
    3100             : ! Note: The year number in these filenames does not matter, because
    3101             : !       subroutine file_year will insert the correct year.
    3102             : 
    3103             : ! author: Elizabeth C. Hunke, LANL
    3104             : 
    3105             :       integer (kind=int_kind), intent(in) :: &
    3106             :            yr                   ! current forcing year
    3107             : 
    3108             :       character(len=*), parameter :: subname = '(monthly_files)'
    3109             : 
    3110             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    3111             : 
    3112             :       flw_file = &
    3113           0 :            trim(atm_data_dir)//'/MONTHLY/cldf.omip.dat'
    3114             : 
    3115             :       rain_file = &
    3116           0 :            trim(atm_data_dir)//'/MONTHLY/prec.nmyr.dat'
    3117             : 
    3118             :       tair_file = &
    3119           0 :            trim(atm_data_dir)//'/MONTHLY/t_10.1996.dat'
    3120           0 :       call file_year(tair_file,yr)
    3121             : 
    3122             :       humid_file = &
    3123           0 :            trim(atm_data_dir)//'/MONTHLY/q_10.1996.dat'
    3124           0 :       call file_year(humid_file,yr)
    3125             : 
    3126             :       ! stress/speed is used instead of wind components
    3127             :       strax_file = &
    3128           0 :            trim(atm_data_dir)//'/MONTHLY/strx.1996.dat'
    3129           0 :       call file_year(strax_file,yr)
    3130             : 
    3131             :       stray_file = &
    3132           0 :            trim(atm_data_dir)//'/MONTHLY/stry.1996.dat'
    3133           0 :       call file_year(stray_file,yr)
    3134             : 
    3135             :       wind_file = &
    3136           0 :            trim(atm_data_dir)//'/MONTHLY/wind.1996.dat'
    3137           0 :       call file_year(wind_file,yr)
    3138             : 
    3139           0 :       if (my_task == master_task) then
    3140           0 :          write (nu_diag,*) ' '
    3141           0 :          write (nu_diag,*) 'Forcing data year = ', fyear
    3142           0 :          write (nu_diag,*) 'Atmospheric data files:'
    3143           0 :          write (nu_diag,*) trim(flw_file)
    3144           0 :          write (nu_diag,*) trim(rain_file)
    3145           0 :          write (nu_diag,*) trim(tair_file)
    3146           0 :          write (nu_diag,*) trim(humid_file)
    3147           0 :          write (nu_diag,*) trim(uwind_file)
    3148           0 :          write (nu_diag,*) trim(vwind_file)
    3149             :       endif                     ! master_task
    3150             : 
    3151           0 :       end subroutine monthly_files
    3152             : 
    3153             : !=======================================================================
    3154             : ! read monthly atmospheric data
    3155             : 
    3156           0 :       subroutine monthly_data
    3157             : 
    3158             :       use ice_blocks, only: block, get_block
    3159             :       use ice_global_reductions, only: global_minval, global_maxval
    3160             :       use ice_domain, only: nblocks, distrb_info, blocks_ice
    3161             :       use ice_flux, only: fsnow, Tair, Qa, wind, strax, stray, fsw
    3162             :       use ice_grid, only: hm, tlon, tlat, tmask, umask
    3163             : 
    3164             :       integer (kind=int_kind) :: &
    3165             :           i, j        , &   ! LCOV_EXCL_LINE
    3166             :           ixm,ixp     , & ! record numbers for neighboring months   ! LCOV_EXCL_LINE
    3167             :           maxrec      , & ! maximum record number   ! LCOV_EXCL_LINE
    3168             :           recslot     , & ! spline slot for current record   ! LCOV_EXCL_LINE
    3169             :           midmonth    , & ! middle day of month   ! LCOV_EXCL_LINE
    3170             :           iblk        , & ! block index   ! LCOV_EXCL_LINE
    3171             :           ilo,ihi,jlo,jhi ! beginning and end of physical domain
    3172             : 
    3173             :       real (kind=dbl_kind) :: &
    3174           0 :           vmin, vmax
    3175             : 
    3176             :       logical (kind=log_kind) :: readm
    3177             : 
    3178             :       type (block) :: &
    3179             :          this_block           ! block information for current block
    3180             : 
    3181             :       character(len=*), parameter :: subname = '(monthly_data)'
    3182             : 
    3183             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    3184             : 
    3185             :     !-------------------------------------------------------------------
    3186             :     ! monthly data
    3187             :     !
    3188             :     ! Assume that monthly data values are located in the middle of the
    3189             :     ! month.
    3190             :     !-------------------------------------------------------------------
    3191             : 
    3192           0 :       midmonth = 15  ! data is given on 15th of every month
    3193             : !      midmonth = fix(p5 * real(daymo(mmonth)))  ! exact middle
    3194             : 
    3195             :       ! Compute record numbers for surrounding months
    3196           0 :       maxrec = 12
    3197           0 :       ixm  = mod(mmonth+maxrec-2,maxrec) + 1
    3198           0 :       ixp  = mod(mmonth,         maxrec) + 1
    3199           0 :       if (mday >= midmonth) ixm = -99  ! other two points will be used
    3200           0 :       if (mday <  midmonth) ixp = -99
    3201             : 
    3202             :       ! Determine whether interpolation will use values 1:2 or 2:3
    3203             :       ! recslot = 2 means we use values 1:2, with the current value (2)
    3204             :       !  in the second slot
    3205             :       ! recslot = 1 means we use values 2:3, with the current value (2)
    3206             :       !  in the first slot
    3207           0 :       recslot = 1                             ! latter half of month
    3208           0 :       if (mday < midmonth) recslot = 2        ! first half of month
    3209             : 
    3210             :       ! Find interpolation coefficients
    3211           0 :       call interp_coeff_monthly (recslot)
    3212             : 
    3213             :       ! Read 2 monthly values
    3214           0 :       readm = .false.
    3215           0 :       if (istep==1 .or. (mday==midmonth .and. msec==0)) readm = .true.
    3216             : 
    3217             :       call read_clim_data (readm, 0, ixm, mmonth, ixp,  &
    3218             :              flw_file, cldf_data, &   ! LCOV_EXCL_LINE
    3219           0 :              field_loc_center, field_type_scalar)
    3220             :       call read_clim_data (readm, 0, ixm, mmonth, ixp,  &
    3221             :              rain_file, fsnow_data, &   ! LCOV_EXCL_LINE
    3222           0 :              field_loc_center, field_type_scalar)
    3223             :       call read_clim_data (readm, 0, ixm, mmonth, ixp,  &
    3224             :              tair_file, Tair_data, &   ! LCOV_EXCL_LINE
    3225           0 :              field_loc_center, field_type_scalar)
    3226             :       call read_clim_data (readm, 0, ixm, mmonth, ixp,  &
    3227             :              humid_file, Qa_data, &   ! LCOV_EXCL_LINE
    3228           0 :              field_loc_center, field_type_scalar)
    3229             :       call read_clim_data (readm, 0, ixm, mmonth, ixp,  &
    3230             :              wind_file, wind_data, &   ! LCOV_EXCL_LINE
    3231           0 :              field_loc_center, field_type_scalar)
    3232             :       call read_clim_data (readm, 0, ixm, mmonth, ixp,  &
    3233             :              strax_file, strax_data, &   ! LCOV_EXCL_LINE
    3234           0 :              field_loc_center, field_type_vector)
    3235             :       call read_clim_data (readm, 0, ixm, mmonth, ixp,  &
    3236             :              stray_file, stray_data, &   ! LCOV_EXCL_LINE
    3237           0 :              field_loc_center, field_type_vector)
    3238             : 
    3239           0 :       call interpolate_data (cldf_data, cldf)
    3240           0 :       call interpolate_data (fsnow_data, fsnow)  ! units mm/s = kg/m^2/s
    3241           0 :       call interpolate_data (Tair_data, Tair)
    3242           0 :       call interpolate_data (Qa_data, Qa)
    3243           0 :       call interpolate_data (wind_data, wind)
    3244           0 :       call interpolate_data (strax_data, strax)
    3245           0 :       call interpolate_data (stray_data, stray)
    3246             : 
    3247           0 :       !$OMP PARALLEL DO PRIVATE(iblk,i,j,ilo,ihi,jlo,jhi,this_block)
    3248           0 :       do iblk = 1, nblocks
    3249             :         call Qa_fixLY(nx_block,  ny_block, &
    3250             :                                  Tair (:,:,iblk), &   ! LCOV_EXCL_LINE
    3251           0 :                                  Qa   (:,:,iblk))
    3252             : 
    3253           0 :         do j = 1, ny_block
    3254           0 :           do i = 1, nx_block
    3255           0 :             Qa   (i,j,iblk) = Qa   (i,j,iblk) * hm(i,j,iblk)
    3256           0 :             Tair (i,j,iblk) = Tair (i,j,iblk) * hm(i,j,iblk)
    3257           0 :             wind (i,j,iblk) = wind (i,j,iblk) * hm(i,j,iblk)
    3258           0 :             strax(i,j,iblk) = strax(i,j,iblk) * hm(i,j,iblk)
    3259           0 :             stray(i,j,iblk) = stray(i,j,iblk) * hm(i,j,iblk)
    3260             :           enddo
    3261             :         enddo
    3262             : 
    3263             :       ! AOMIP
    3264           0 :       this_block = get_block(blocks_ice(iblk),iblk)
    3265           0 :       ilo = this_block%ilo
    3266           0 :       ihi = this_block%ihi
    3267           0 :       jlo = this_block%jlo
    3268           0 :       jhi = this_block%jhi
    3269             : 
    3270             :       call compute_shortwave(nx_block, ny_block, &
    3271             :                              ilo, ihi, jlo, jhi, &   ! LCOV_EXCL_LINE
    3272             :                              TLON (:,:,iblk), &   ! LCOV_EXCL_LINE
    3273             :                              TLAT (:,:,iblk), &   ! LCOV_EXCL_LINE
    3274             :                              hm   (:,:,iblk), &   ! LCOV_EXCL_LINE
    3275             :                              Qa   (:,:,iblk), &   ! LCOV_EXCL_LINE
    3276             :                              cldf (:,:,iblk), &   ! LCOV_EXCL_LINE
    3277           0 :                              fsw  (:,:,iblk))
    3278             : 
    3279             :       enddo  ! iblk
    3280             :       !$OMP END PARALLEL DO
    3281             : 
    3282           0 :          if (debug_forcing) then
    3283           0 :            if (my_task == master_task) write (nu_diag,*) 'LY_bulk_data'
    3284           0 :            vmin = global_minval(fsw,distrb_info,tmask)
    3285           0 :            vmax = global_maxval(fsw,distrb_info,tmask)
    3286           0 :            if (my_task.eq.master_task)  &
    3287           0 :                write (nu_diag,*) 'fsw',vmin,vmax
    3288           0 :            vmin = global_minval(cldf,distrb_info,tmask)
    3289           0 :            vmax = global_maxval(cldf,distrb_info,tmask)
    3290           0 :            if (my_task.eq.master_task) &
    3291           0 :                write (nu_diag,*) 'cldf',vmin,vmax
    3292           0 :            vmin =global_minval(fsnow,distrb_info,tmask)
    3293           0 :            vmax =global_maxval(fsnow,distrb_info,tmask)
    3294           0 :            if (my_task.eq.master_task) &
    3295           0 :                write (nu_diag,*) 'fsnow',vmin,vmax
    3296           0 :            vmin = global_minval(Tair,distrb_info,tmask)
    3297           0 :            vmax = global_maxval(Tair,distrb_info,tmask)
    3298           0 :            if (my_task.eq.master_task) &
    3299           0 :                write (nu_diag,*) 'Tair',vmin,vmax
    3300           0 :            vmin = global_minval(wind,distrb_info,umask)
    3301           0 :            vmax = global_maxval(wind,distrb_info,umask)
    3302           0 :            if (my_task.eq.master_task) &
    3303           0 :                write (nu_diag,*) 'wind',vmin,vmax
    3304           0 :            vmin = global_minval(strax,distrb_info,umask)
    3305           0 :            vmax = global_maxval(strax,distrb_info,umask)
    3306           0 :            if (my_task.eq.master_task) &
    3307           0 :                write (nu_diag,*) 'strax',vmin,vmax
    3308           0 :            vmin = global_minval(stray,distrb_info,umask)
    3309           0 :            vmax = global_maxval(stray,distrb_info,umask)
    3310           0 :            if (my_task.eq.master_task) &
    3311           0 :                write (nu_diag,*) 'stray',vmin,vmax
    3312           0 :            vmin = global_minval(Qa,distrb_info,tmask)
    3313           0 :            vmax = global_maxval(Qa,distrb_info,tmask)
    3314           0 :            if (my_task.eq.master_task)  &
    3315           0 :                write (nu_diag,*) 'Qa',vmin,vmax
    3316             : 
    3317             :         endif                   ! debug_forcing
    3318             : 
    3319           0 :       end subroutine monthly_data
    3320             : 
    3321             : !=======================================================================
    3322             : ! Oned atmospheric data
    3323             : !=======================================================================
    3324             : 
    3325           0 :       subroutine oned_data
    3326             : 
    3327             :       use ice_flux, only: uatm, vatm, Tair, fsw, fsnow, Qa, rhoa, frain
    3328             : 
    3329             :       ! local parameters
    3330             : 
    3331             :       character (char_len_long) :: &
    3332             :          met_file,   &    ! netcdf filename   ! LCOV_EXCL_LINE
    3333             :          fieldname        ! field name in netcdf file
    3334             : 
    3335             :       integer (kind=int_kind) :: &
    3336             :          fid              ! file id for netCDF file
    3337             : 
    3338             :       real (kind=dbl_kind):: &
    3339           0 :          work             ! temporary variable
    3340             : 
    3341             :       logical (kind=log_kind) :: diag
    3342             : 
    3343             :       integer (kind=int_kind) :: &
    3344             :          status           ! status flag
    3345             : 
    3346             :       real (kind=dbl_kind) :: & ! used to determine specific humidity
    3347             :          Temp               , & ! air temperature (K)   ! LCOV_EXCL_LINE
    3348             :          rh                 , & ! relative humidity (%)   ! LCOV_EXCL_LINE
    3349             :          Psat               , & ! saturation vapour pressure (hPa)   ! LCOV_EXCL_LINE
    3350           0 :          ws                     ! saturation mixing ratio
    3351             : 
    3352             :       real (kind=dbl_kind), parameter :: & ! coefficients for Hyland-Wexler Qa
    3353             :          ps1 = 0.58002206e4_dbl_kind,    & ! (K)   ! LCOV_EXCL_LINE
    3354             :          ps2 = 1.3914993_dbl_kind,       & !   ! LCOV_EXCL_LINE
    3355             :          ps3 = 0.48640239e-1_dbl_kind,   & ! (K^-1)   ! LCOV_EXCL_LINE
    3356             :          ps4 = 0.41764768e-4_dbl_kind,   & ! (K^-2)   ! LCOV_EXCL_LINE
    3357             :          ps5 = 0.14452093e-7_dbl_kind,   & ! (K^-3)   ! LCOV_EXCL_LINE
    3358             :          ps6 = 6.5459673_dbl_kind,       & !   ! LCOV_EXCL_LINE
    3359             :          ws1 = 621.97_dbl_kind,          & ! for saturation mixing ratio   ! LCOV_EXCL_LINE
    3360             :          Pair = 1020._dbl_kind             ! Sea level pressure (hPa)
    3361             : 
    3362             :       character(len=*), parameter :: subname = '(oned_data)'
    3363             : 
    3364             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    3365             : 
    3366           0 :       diag = .false.   ! write diagnostic information
    3367             : 
    3368           0 :       if (trim(atm_data_format) == 'nc') then     ! read nc file
    3369             : 
    3370             :         ! hourly data beginning Jan 1, 1989, 01:00
    3371             :         ! HARDWIRED for dt = 1 hour!
    3372           0 :         met_file = uwind_file
    3373           0 :         call ice_open_nc(met_file,fid)
    3374             : 
    3375           0 :         fieldname='Uatm'
    3376           0 :         call ice_read_nc(fid,istep1,fieldname,work,diag)
    3377           0 :         uatm(:,:,:) = work
    3378             : 
    3379           0 :         fieldname='Vatm'
    3380           0 :         call ice_read_nc(fid,istep1,fieldname,work,diag)
    3381           0 :         vatm(:,:,:) = work
    3382             : 
    3383           0 :         fieldname='Tair'
    3384           0 :         call ice_read_nc(fid,istep1,fieldname,work,diag)
    3385           0 :         Temp = work
    3386           0 :         Tair(:,:,:) = Temp
    3387             : 
    3388           0 :         call ice_close_nc(fid)
    3389             : 
    3390             :         ! hourly solar data beginning Jan 1, 1989, 01:00
    3391           0 :         met_file = fsw_file
    3392           0 :         call ice_open_nc(met_file,fid)
    3393             : 
    3394           0 :         fieldname='fsw'
    3395           0 :         call ice_read_nc(fid,istep1,fieldname,work,diag)
    3396           0 :         fsw(:,:,:) = work
    3397             : 
    3398           0 :         call ice_close_nc(fid)
    3399             : 
    3400             :         ! hourly interpolated monthly  data beginning Jan 1, 1989, 01:00
    3401           0 :         met_file = humid_file
    3402           0 :         call ice_open_nc(met_file,fid)
    3403             : 
    3404           0 :         fieldname='rh'
    3405           0 :         call ice_read_nc(fid,istep1,fieldname,work,diag)
    3406           0 :         rh = work
    3407             : 
    3408           0 :         fieldname='fsnow'
    3409           0 :         call ice_read_nc(fid,istep1,fieldname,work,diag)
    3410           0 :         fsnow(:,:,:) = work
    3411             : 
    3412           0 :         call ice_close_nc(fid)
    3413             : 
    3414             :       !-------------------------------------------------------------------
    3415             :       ! Find specific humidity using Hyland-Wexler formulation
    3416             :       ! Hyland, R.W. and A. Wexler, Formulations for the Thermodynamic
    3417             :       ! Properties of the saturated phases of H20 from 173.15K to 473.15K,
    3418             :       ! ASHRAE Trans, 89(2A), 500-519, 1983
    3419             :       !-------------------------------------------------------------------
    3420             : 
    3421             :         Psat = exp(-ps1/Temp + ps2 - ps3*Temp + ps4*Temp**2 - ps5 * Temp**3  &
    3422           0 :               + ps6 * log(Temp))*p01          ! saturation vapour pressure
    3423           0 :         ws = ws1 * Psat/(Pair - Psat)         ! saturation mixing ratio
    3424           0 :         Qa(:,:,:) = rh * ws * p01/(c1 + rh * ws * p01) * p001
    3425             :                                               ! specific humidity (kg/kg)
    3426             :       endif ! atm_data_format
    3427             : 
    3428             :       ! flw calculated in prepare_forcing
    3429           0 :         rhoa (:,:,:) = 1.3_dbl_kind ! air density (kg/m^3)
    3430           0 :         cldf (:,:,:) = p25          ! cloud fraction
    3431           0 :         frain(:,:,:) = c0           ! this is available in hourlymet_rh file
    3432             : 
    3433           0 :       end subroutine oned_data
    3434             : 
    3435             : !=======================================================================
    3436             : 
    3437           0 :       subroutine oned_files
    3438             : 
    3439             :       character(len=*), parameter :: subname = '(oned_files)'
    3440             : 
    3441             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    3442             : 
    3443             :       fsw_file = &
    3444           0 :            trim(atm_data_dir)//'/hourlysolar_brw1989_5yr.nc'
    3445             : 
    3446             :       rain_file = &
    3447           0 :            trim(atm_data_dir)//'/hourlymet_rh_5yr.nc'
    3448             : 
    3449             :       uwind_file = &
    3450           0 :            trim(atm_data_dir)//'/hourlymet_brw1989_5yr.nc'
    3451             : 
    3452             :       vwind_file = &
    3453           0 :            trim(atm_data_dir)//'/hourlymet_brw1989_5yr.nc'
    3454             : 
    3455             :       tair_file = &
    3456           0 :            trim(atm_data_dir)//'/hourlymet_brw1989_5yr.nc'
    3457             : 
    3458             :       humid_file = &
    3459           0 :            trim(atm_data_dir)//'/hourlymet_rh_5yr.nc'
    3460             : 
    3461           0 :       if (my_task == master_task) then
    3462           0 :          write (nu_diag,*) ' '
    3463           0 :          write (nu_diag,*) 'Atmospheric data files:'
    3464           0 :          write (nu_diag,*) trim(fsw_file)
    3465           0 :          write (nu_diag,*) trim(rain_file)
    3466           0 :          write (nu_diag,*) trim(uwind_file)
    3467           0 :          write (nu_diag,*) trim(vwind_file)
    3468           0 :          write (nu_diag,*) trim(tair_file)
    3469           0 :          write (nu_diag,*) trim(humid_file)
    3470             :       endif                     ! master_task
    3471             : 
    3472           0 :       end subroutine oned_files
    3473             : 
    3474             : !=======================================================================
    3475             : ! Climatological ocean forcing
    3476             : !=======================================================================
    3477             : 
    3478           0 :       subroutine ocn_data_clim (dt)
    3479             : 
    3480             : ! Interpolate monthly sss, sst data to timestep.
    3481             : ! Restore prognostic sst to data.
    3482             : ! Interpolate fields from U grid to T grid if necessary.
    3483             : 
    3484             : ! author: Elizabeth C. Hunke and William H. Lipscomb, LANL
    3485             : 
    3486             :       use ice_domain, only: nblocks
    3487             :       use ice_flux, only: sss, sst
    3488             : 
    3489             :       real (kind=dbl_kind), intent(in) :: &
    3490             :          dt      ! time step
    3491             : 
    3492             :       ! local variables
    3493             : 
    3494             :       integer (kind=int_kind) :: &
    3495             :           i, j, iblk  , & ! horizontal indices   ! LCOV_EXCL_LINE
    3496             :           ixm,ixp     , & ! record numbers for neighboring months   ! LCOV_EXCL_LINE
    3497             :           maxrec      , & ! maximum record number   ! LCOV_EXCL_LINE
    3498             :           recslot     , & ! spline slot for current record   ! LCOV_EXCL_LINE
    3499             :           midmonth        ! middle day of month
    3500             : 
    3501             :       real (kind=dbl_kind), dimension(nx_block,ny_block,max_blocks) :: &
    3502           0 :           sstdat              ! data value toward which SST is restored
    3503             : 
    3504             :       logical (kind=log_kind) :: readm
    3505             : 
    3506             :       character(len=*), parameter :: subname = '(ocn_data_clim)'
    3507             : 
    3508             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    3509             : 
    3510           0 :       if (my_task == master_task .and. istep == 1) then
    3511           0 :          if (trim(ocn_data_type)=='clim') then
    3512           0 :             write (nu_diag,*) ' '
    3513           0 :             write (nu_diag,*) 'SSS data interpolated to timestep:'
    3514           0 :             write (nu_diag,*) trim(sss_file)
    3515           0 :             write (nu_diag,*) ' '
    3516           0 :             write (nu_diag,*) 'SST data interpolated to timestep:'
    3517           0 :             write (nu_diag,*) trim(sst_file)
    3518           0 :             if (restore_ocn) write (nu_diag,*) &
    3519           0 :               'SST restoring timescale (days) =', trestore
    3520             :          endif
    3521             :       endif                     ! my_task, istep
    3522             : 
    3523             :     !-------------------------------------------------------------------
    3524             :     ! monthly data
    3525             :     !
    3526             :     ! Assume that monthly data values are located in the middle of the
    3527             :     ! month.
    3528             :     !-------------------------------------------------------------------
    3529             : 
    3530           0 :       if (trim(ocn_data_type)=='clim') then
    3531             : 
    3532           0 :          midmonth = 15          ! data is given on 15th of every month
    3533             : !!!      midmonth = fix(p5 * real(daymo(mmonth)))  ! exact middle
    3534             : 
    3535             :          ! Compute record numbers for surrounding months
    3536           0 :          maxrec = 12
    3537           0 :          ixm  = mod(mmonth+maxrec-2,maxrec) + 1
    3538           0 :          ixp  = mod(mmonth,         maxrec) + 1
    3539           0 :          if (mday >= midmonth) ixm = -99 ! other two points will be used
    3540           0 :          if (mday <  midmonth) ixp = -99
    3541             : 
    3542             :          ! Determine whether interpolation will use values 1:2 or 2:3
    3543             :          ! recslot = 2 means we use values 1:2, with the current value (2)
    3544             :          !  in the second slot
    3545             :          ! recslot = 1 means we use values 2:3, with the current value (2)
    3546             :          !  in the first slot
    3547           0 :          recslot = 1            ! latter half of month
    3548           0 :          if (mday < midmonth) recslot = 2 ! first half of month
    3549             : 
    3550             :          ! Find interpolation coefficients
    3551           0 :          call interp_coeff_monthly (recslot)
    3552             : 
    3553           0 :          readm = .false.
    3554           0 :          if (istep==1 .or. (mday==midmonth .and. msec==0)) readm = .true.
    3555             : 
    3556             :     !-------------------------------------------------------------------
    3557             :     ! Read two monthly SSS values and interpolate.
    3558             :     ! Note: SSS is restored instantaneously to data.
    3559             :     !-------------------------------------------------------------------
    3560             : 
    3561             :          call read_clim_data (readm, 0, ixm, mmonth, ixp, &
    3562             :                               sss_file, sss_data, &   ! LCOV_EXCL_LINE
    3563           0 :                               field_loc_center, field_type_scalar)
    3564           0 :          call interpolate_data (sss_data, sss)
    3565             : 
    3566           0 :          !$OMP PARALLEL DO PRIVATE(iblk,i,j)
    3567           0 :          do iblk = 1, nblocks
    3568           0 :             do j = 1, ny_block
    3569           0 :             do i = 1, nx_block
    3570           0 :                sss(i,j,iblk) = max(sss(i,j,iblk), c0)
    3571             :             enddo
    3572             :             enddo
    3573             :          enddo
    3574             :          !$OMP END PARALLEL DO
    3575             : 
    3576           0 :          call ocn_freezing_temperature
    3577             :       endif
    3578             : 
    3579             :     !-------------------------------------------------------------------
    3580             :     ! Read two monthly SST values and interpolate.
    3581             :     ! Restore toward interpolated value.
    3582             :     !-------------------------------------------------------------------
    3583             : 
    3584           0 :       if (trim(ocn_data_type)=='clim') then
    3585             :          call read_clim_data (readm, 0, ixm, mmonth, ixp, &
    3586             :                               sst_file, sst_data, &   ! LCOV_EXCL_LINE
    3587           0 :                               field_loc_center, field_type_scalar)
    3588           0 :          call interpolate_data (sst_data, sstdat)
    3589             : 
    3590           0 :          if (restore_ocn) then
    3591           0 :          !$OMP PARALLEL DO PRIVATE(iblk,i,j)
    3592           0 :          do iblk = 1, nblocks
    3593           0 :             do j = 1, ny_block
    3594           0 :             do i = 1, nx_block
    3595             :                sst(i,j,iblk) = sst(i,j,iblk)  &
    3596           0 :                          + (sstdat(i,j,iblk)-sst(i,j,iblk))*dt/trest
    3597             :             enddo
    3598             :             enddo
    3599             :          enddo
    3600             :          !$OMP END PARALLEL DO
    3601             :          endif
    3602             :       endif
    3603             : 
    3604           0 :       end subroutine ocn_data_clim
    3605             : 
    3606             : !=======================================================================
    3607             : ! NCAR CESM M-configuration (AIO) ocean forcing
    3608             : !=======================================================================
    3609             : 
    3610           0 :       subroutine ocn_data_ncar_init
    3611             : 
    3612             : ! Reads NCAR pop ocean forcing data set 'pop_frc_gx1v3_010815.nc'
    3613             : !
    3614             : ! List of ocean forcing fields: Note that order is important!
    3615             : ! (order is determined by field list in vname).
    3616             : !
    3617             : ! For ocean mixed layer-----------------------------units
    3618             : !
    3619             : ! 1  sst------temperature---------------------------(C)
    3620             : ! 2  sss------salinity------------------------------(ppt)
    3621             : ! 3  hbl------depth---------------------------------(m)
    3622             : ! 4  u--------surface u current---------------------(m/s)
    3623             : ! 5  v--------surface v current---------------------(m/s)
    3624             : ! 6  dhdx-----surface tilt x direction--------------(m/m)
    3625             : ! 7  dhdy-----surface tilt y direction--------------(m/m)
    3626             : ! 8  qdp------ocean sub-mixed layer heat flux-------(W/m2)
    3627             : !
    3628             : ! Fields 4, 5, 6, 7 are on the U-grid; 1, 2, 3, and 8 are
    3629             : ! on the T-grid.
    3630             : 
    3631             : ! authors: Bruce Briegleb, NCAR
    3632             : !          Elizabeth Hunke, LANL
    3633             : 
    3634             :       use ice_blocks, only: nx_block, ny_block
    3635             :       use ice_domain_size, only: max_blocks
    3636             : #ifdef USE_NETCDF
    3637             :       use netcdf
    3638             : #endif
    3639             : 
    3640             :       integer (kind=int_kind) :: &
    3641             :         n   , & ! field index   ! LCOV_EXCL_LINE
    3642             :         m   , & ! month index   ! LCOV_EXCL_LINE
    3643             :         nrec, & ! record number for direct access   ! LCOV_EXCL_LINE
    3644             :         nbits
    3645             : 
    3646             :       character(char_len) :: &
    3647             :         vname(nfld) ! variable names to search for in file
    3648             :       data vname /  &
    3649             :            'T',      'S',      'hblt',  'U',     'V', &   ! LCOV_EXCL_LINE
    3650             :            'dhdx',   'dhdy',   'qdp' /
    3651             : 
    3652             :       integer (kind=int_kind) :: &
    3653             :         status  , & ! status flag   ! LCOV_EXCL_LINE
    3654             :         fid     , & ! file id   ! LCOV_EXCL_LINE
    3655             :         dimid   , & ! dimension id   ! LCOV_EXCL_LINE
    3656             :         nlat    , & ! number of longitudes of data   ! LCOV_EXCL_LINE
    3657             :         nlon        ! number of latitudes  of data
    3658             : 
    3659             :       real (kind=dbl_kind), dimension (nx_block,ny_block,max_blocks) :: &
    3660           0 :          work1
    3661             : 
    3662             :       character(len=*), parameter :: subname = '(ocn_data_ncar_init)'
    3663             : 
    3664             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    3665             : 
    3666           0 :       if (my_task == master_task) then
    3667             : 
    3668           0 :          write (nu_diag,*) 'WARNING: evp_prep calculates surface tilt'
    3669           0 :          write (nu_diag,*) 'WARNING: stress from geostrophic currents,'
    3670           0 :          write (nu_diag,*) 'WARNING: not data from ocean forcing file.'
    3671           0 :          write (nu_diag,*) 'WARNING: Alter ice_dyn_evp.F90 if desired.'
    3672             : 
    3673           0 :          if (restore_ocn) write (nu_diag,*)  &
    3674           0 :              'SST restoring timescale = ',trestore,' days'
    3675             : 
    3676           0 :          sst_file = trim(ocn_data_dir)//'/'//trim(oceanmixed_file) ! not just sst
    3677             : 
    3678             :         !---------------------------------------------------------------
    3679             :         ! Read in ocean forcing data from an existing file
    3680             :         !---------------------------------------------------------------
    3681           0 :         write (nu_diag,*) 'ocean mixed layer forcing data file = ', &
    3682           0 :                            trim(sst_file)
    3683             : 
    3684             :       endif ! master_task
    3685             : 
    3686           0 :       if (trim(ocn_data_format) == 'nc') then
    3687             : #ifdef USE_NETCDF
    3688           0 :         if (my_task == master_task) then
    3689           0 :           call ice_open_nc(sst_file, fid)
    3690             : 
    3691             : !          status = nf90_inq_dimid(fid,'nlon',dimid)
    3692           0 :           status = nf90_inq_dimid(fid,'ni',dimid)
    3693           0 :           status = nf90_inquire_dimension(fid,dimid,len=nlon)
    3694             : 
    3695             : !          status = nf90_inq_dimid(fid,'nlat',dimid)
    3696           0 :           status = nf90_inq_dimid(fid,'nj',dimid)
    3697           0 :           status = nf90_inquire_dimension(fid,dimid,len=nlat)
    3698             : 
    3699           0 :           if( nlon .ne. nx_global ) then
    3700             :             call abort_ice (error_message=subname//'ice: ocn frc file nlon ne nx_global', &
    3701           0 :                file=__FILE__, line=__LINE__)
    3702             :           endif
    3703           0 :           if( nlat .ne. ny_global ) then
    3704             :             call abort_ice (error_message=subname//'ice: ocn frc file nlat ne ny_global', &
    3705           0 :                file=__FILE__, line=__LINE__)
    3706             :           endif
    3707             : 
    3708             :         endif ! master_task
    3709             : 
    3710             :         ! Read in ocean forcing data for all 12 months
    3711           0 :         do n=1,nfld
    3712           0 :           do m=1,12
    3713             : 
    3714             :             ! Note: netCDF does single to double conversion if necessary
    3715             : !           if (n >= 4 .and. n <= 7) then
    3716             : !              call ice_read_nc(fid, m, vname(n), work1, debug_forcing, &
    3717             : !                               field_loc_NEcorner, field_type_vector)
    3718             : !           else
    3719           0 :                call ice_read_nc(fid, m, vname(n), work1, debug_forcing, &
    3720           0 :                                 field_loc_center, field_type_scalar)
    3721             : !           endif
    3722             : 
    3723           0 :             ocn_frc_m(:,:,:,n,m) = work1(:,:,:)
    3724             : 
    3725             :           enddo               ! month loop
    3726             :         enddo               ! field loop
    3727             : 
    3728           0 :         if (my_task == master_task) call ice_close_nc(fid)
    3729             : #else
    3730             :       call abort_ice(subname//'ERROR: USE_NETCDF cpp not defined for '//trim(sst_file), &
    3731             :           file=__FILE__, line=__LINE__)
    3732             : #endif
    3733             : 
    3734             :       else  ! binary format
    3735             : 
    3736           0 :         nbits = 64
    3737           0 :         call ice_open (nu_forcing, sst_file, nbits)
    3738             : 
    3739           0 :         nrec = 0
    3740           0 :         do n=1,nfld
    3741           0 :            do m=1,12
    3742           0 :               nrec = nrec + 1
    3743           0 :               if (n >= 4 .and. n <= 7) then
    3744             :                 call ice_read (nu_forcing, nrec, work1, 'rda8', debug_forcing, &
    3745           0 :                                field_loc_NEcorner, field_type_vector)
    3746             :               else
    3747             :                 call ice_read (nu_forcing, nrec, work1, 'rda8', debug_forcing, &
    3748           0 :                                field_loc_center, field_type_scalar)
    3749             :               endif
    3750           0 :               ocn_frc_m(:,:,:,n,m) = work1(:,:,:)
    3751             :            enddo               ! month loop
    3752             :         enddo               ! field loop
    3753           0 :         close (nu_forcing)
    3754             : 
    3755             :       endif
    3756             : 
    3757             : !echmod - currents cause Fram outflow to be too large
    3758             : !             ocn_frc_m(:,:,:,4,:) = c0
    3759             : !             ocn_frc_m(:,:,:,5,:) = c0
    3760             : !echmod
    3761             : 
    3762           0 :       end subroutine ocn_data_ncar_init
    3763             : 
    3764             : !=======================================================================
    3765             : 
    3766           0 :       subroutine ocn_data_ncar_init_3D
    3767             : 
    3768             : ! Reads NCAR pop ocean forcing data set 'oceanmixed_ice_depth.nc'
    3769             : !
    3770             : ! List of ocean forcing fields: Note that order is important!
    3771             : ! (order is determined by field list in vname).
    3772             : !
    3773             : ! For ocean mixed layer-----------------------------units
    3774             : !
    3775             : ! 1  sst------temperature---------------------------(C)
    3776             : ! 2  sss------salinity------------------------------(ppt)
    3777             : ! 3  hbl------depth---------------------------------(m)
    3778             : ! 4  u--------surface u current---------------------(m/s)
    3779             : ! 5  v--------surface v current---------------------(m/s)
    3780             : ! 6  dhdx-----surface tilt x direction--------------(m/m)
    3781             : ! 7  dhdy-----surface tilt y direction--------------(m/m)
    3782             : ! 8  qdp------ocean sub-mixed layer heat flux-------(W/m2)
    3783             : !
    3784             : ! All fields are on the T-grid.
    3785             : !
    3786             : ! authors: Bruce Briegleb, NCAR
    3787             : !          Elizabeth Hunke, LANL
    3788             : 
    3789             :       use ice_blocks, only: nx_block, ny_block
    3790             :       use ice_domain_size, only: max_blocks
    3791             :       use ice_grid, only: grid_average_X2Y, ANGLET
    3792             :       use ice_read_write, only: ice_read_nc_uv
    3793             : #ifdef USE_NETCDF
    3794             :       use netcdf
    3795             : #endif
    3796             : 
    3797             : #ifdef USE_NETCDF
    3798             :       integer (kind=int_kind) :: &
    3799             :         n   , & ! field index   ! LCOV_EXCL_LINE
    3800             :         m   , & ! month index   ! LCOV_EXCL_LINE
    3801             :         nzlev   ! z level of currents
    3802             : 
    3803             :       character(char_len) :: &
    3804             :         vname(nfld) ! variable names to search for in file
    3805             :       data vname /  &
    3806             :            'T',      'S',      'hblt',  'U',     'V', &   ! LCOV_EXCL_LINE
    3807             :            'dhdx',   'dhdy',   'qdp' /
    3808             : 
    3809             :       integer (kind=int_kind) :: &
    3810             :         fid        , & ! file id   ! LCOV_EXCL_LINE
    3811             :         dimid          ! dimension id
    3812             : 
    3813             :       integer (kind=int_kind) :: &
    3814             :         status  , & ! status flag   ! LCOV_EXCL_LINE
    3815             :         nlat    , & ! number of longitudes of data   ! LCOV_EXCL_LINE
    3816             :         nlon        ! number of latitudes  of data
    3817             : 
    3818             :       real (kind=dbl_kind), dimension (nx_block,ny_block,max_blocks) :: &
    3819           0 :          work1, work2
    3820             : #endif
    3821             : 
    3822             :       character(len=*), parameter :: subname = '(ocn_data_ncar_init_3D)'
    3823             : 
    3824             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    3825             : 
    3826           0 :       if (my_task == master_task) then
    3827             : 
    3828           0 :          write (nu_diag,*) 'WARNING: evp_prep calculates surface tilt'
    3829           0 :          write (nu_diag,*) 'WARNING: stress from geostrophic currents,'
    3830           0 :          write (nu_diag,*) 'WARNING: not data from ocean forcing file.'
    3831           0 :          write (nu_diag,*) 'WARNING: Alter ice_dyn_evp.F if desired.'
    3832             : 
    3833           0 :          if (restore_ocn) write (nu_diag,*)  &
    3834           0 :              'SST restoring timescale = ',trestore,' days'
    3835             : 
    3836           0 :          sst_file = trim(ocn_data_dir)//'/'//trim(oceanmixed_file) ! not just sst
    3837             : 
    3838             :         !---------------------------------------------------------------
    3839             :         ! Read in ocean forcing data from an existing file
    3840             :         !---------------------------------------------------------------
    3841           0 :         write (nu_diag,*) 'ocean mixed layer forcing data file = ', &
    3842           0 :                            trim(sst_file)
    3843           0 :         write (nu_diag,*)
    3844             : 
    3845             :       endif ! master_task
    3846             : 
    3847           0 :       if (trim(ocn_data_format) == 'nc') then
    3848             : #ifdef USE_NETCDF
    3849           0 :         if (my_task == master_task) then
    3850           0 :           call ice_open_nc(sst_file, fid)
    3851             : 
    3852             : !          status = nf90_inq_dimid(fid,'nlon',dimid)
    3853           0 :           status = nf90_inq_dimid(fid,'ni',dimid)
    3854           0 :           status = nf90_inquire_dimension(fid,dimid,len=nlon)
    3855             : 
    3856             : !          status = nf90_inq_dimid(fid,'nlat',dimid)
    3857           0 :           status = nf90_inq_dimid(fid,'nj',dimid)
    3858           0 :           status = nf90_inquire_dimension(fid,dimid,len=nlat)
    3859             : 
    3860           0 :           if( nlon .ne. nx_global ) then
    3861             :             call abort_ice (error_message=subname//'ice: ocn frc file nlon ne nx_global', &
    3862           0 :                file=__FILE__, line=__LINE__)
    3863             :           endif
    3864           0 :           if( nlat .ne. ny_global ) then
    3865             :             call abort_ice (error_message=subname//'ice: ocn frc file nlat ne ny_global', &
    3866           0 :                file=__FILE__, line=__LINE__)
    3867             :           endif
    3868             : 
    3869             :         endif ! master_task
    3870             : 
    3871             :         ! Read in ocean forcing data for all 12 months
    3872           0 :         do n=1,nfld
    3873           0 :           do m=1,12
    3874             : 
    3875             :             ! Note: netCDF does single to double conversion if necessary
    3876           0 :             if (n == 4 .or. n == 5) then ! 3D currents
    3877           0 :                nzlev = 1                 ! surface currents
    3878           0 :                call ice_read_nc_uv(fid, m, nzlev, vname(n), work1, debug_forcing, &
    3879           0 :                                 field_loc_center, field_type_scalar)
    3880             :             else
    3881           0 :                call ice_read_nc(fid, m, vname(n), work1, debug_forcing, &
    3882           0 :                                 field_loc_center, field_type_scalar)
    3883             :             endif
    3884             : 
    3885             :             ! the land mask used in ocean_mixed_depth.nc does not
    3886             :             ! match our gx1v3 mask (hm)
    3887           0 :             where (work1(:,:,:) < -900.) work1(:,:,:) = c0
    3888             : 
    3889           0 :             ocn_frc_m(:,:,:,n,m) = work1(:,:,:)
    3890             : 
    3891             :           enddo               ! month loop
    3892             :         enddo               ! field loop
    3893             : 
    3894           0 :         if (my_task == master_task) call ice_close_nc(fid)
    3895             : 
    3896             :         ! Rotate vector quantities and shift to U-grid
    3897           0 :         do n=4,6,2
    3898           0 :           do m=1,12
    3899             : 
    3900           0 :              work1(:,:,:) = ocn_frc_m(:,:,:,n  ,m)
    3901           0 :              work2(:,:,:) = ocn_frc_m(:,:,:,n+1,m)
    3902           0 :              ocn_frc_m(:,:,:,n  ,m) = work1(:,:,:)*cos(ANGLET(:,:,:)) &
    3903           0 :                                     + work2(:,:,:)*sin(ANGLET(:,:,:))
    3904           0 :              ocn_frc_m(:,:,:,n+1,m) = work2(:,:,:)*cos(ANGLET(:,:,:)) &
    3905           0 :                                     - work1(:,:,:)*sin(ANGLET(:,:,:))
    3906             : 
    3907           0 :              work1(:,:,:) = ocn_frc_m(:,:,:,n  ,m)
    3908           0 :              work2(:,:,:) = ocn_frc_m(:,:,:,n+1,m)
    3909           0 :              call grid_average_X2Y('A',work1,'T',ocn_frc_m(:,:,:,n  ,m),'U')
    3910           0 :              call grid_average_X2Y('A',work2,'T',ocn_frc_m(:,:,:,n+1,m),'U')
    3911             : 
    3912             :           enddo               ! month loop
    3913             :         enddo               ! field loop
    3914             : 
    3915             : #else
    3916             :         call abort_ice(subname//'ERROR: USE_NETCDF cpp not defined', &
    3917             :             file=__FILE__, line=__LINE__)
    3918             : #endif
    3919             : 
    3920             :       else  ! binary format
    3921             : 
    3922             :         call abort_ice (error_message=subname//'new ocean forcing is netcdf only', &
    3923           0 :            file=__FILE__, line=__LINE__)
    3924             : 
    3925             :       endif
    3926             : 
    3927           0 :       end subroutine ocn_data_ncar_init_3D
    3928             : 
    3929             : !=======================================================================
    3930             : 
    3931           0 :       subroutine ocn_data_ncar(dt)
    3932             : 
    3933             : ! Interpolate monthly ocean data to timestep.
    3934             : ! Restore sst if desired. sst is updated with surface fluxes in ice_ocean.F.
    3935             : 
    3936             :       use ice_blocks, only: nx_block, ny_block
    3937             :       use ice_global_reductions, only: global_minval, global_maxval
    3938             :       use ice_domain, only: nblocks, distrb_info
    3939             :       use ice_domain_size, only: max_blocks
    3940             :       use ice_flux, only: sss, sst, Tf, uocn, vocn, ss_tltx, ss_tlty, &
    3941             :             qdp, hmix
    3942             :       use ice_restart_shared, only: restart
    3943             :       use ice_grid, only: hm, tmask, umask
    3944             : 
    3945             :       real (kind=dbl_kind), intent(in) :: &
    3946             :          dt      ! time step
    3947             : 
    3948             :       integer (kind=int_kind) :: &
    3949             :           i, j, n, iblk   , &   ! LCOV_EXCL_LINE
    3950             :           ixm,ixp         , & ! record numbers for neighboring months   ! LCOV_EXCL_LINE
    3951             :           maxrec          , & ! maximum record number   ! LCOV_EXCL_LINE
    3952             :           recslot         , & ! spline slot for current record   ! LCOV_EXCL_LINE
    3953             :           midmonth            ! middle day of month
    3954             : 
    3955             :       real (kind=dbl_kind) :: &
    3956           0 :           vmin, vmax
    3957             : 
    3958             :       real (kind=dbl_kind), dimension (nx_block,ny_block,max_blocks) :: &
    3959           0 :          work1
    3960             : 
    3961             :       character(len=*), parameter :: subname = '(ocn_data_ncar)'
    3962             : 
    3963             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    3964             : 
    3965             :     !-------------------------------------------------------------------
    3966             :     ! monthly data
    3967             :     !
    3968             :     ! Assume that monthly data values are located in the middle of the
    3969             :     ! month.
    3970             :     !-------------------------------------------------------------------
    3971             : 
    3972           0 :       midmonth = 15  ! data is given on 15th of every month
    3973             : !      midmonth = fix(p5 * real(daymo(mmonth),kind=dbl_kind))  ! exact middle
    3974             : 
    3975             :       ! Compute record numbers for surrounding months
    3976           0 :       maxrec = 12
    3977           0 :       ixm  = mod(mmonth+maxrec-2,maxrec) + 1
    3978           0 :       ixp  = mod(mmonth,         maxrec) + 1
    3979           0 :       if (mday >= midmonth) ixm = -99  ! other two points will be used
    3980           0 :       if (mday <  midmonth) ixp = -99
    3981             : 
    3982             :       ! Determine whether interpolation will use values 1:2 or 2:3
    3983             :       ! recslot = 2 means we use values 1:2, with the current value (2)
    3984             :       !  in the second slot
    3985             :       ! recslot = 1 means we use values 2:3, with the current value (2)
    3986             :       !  in the first slot
    3987           0 :       recslot = 1                             ! latter half of month
    3988           0 :       if (mday < midmonth) recslot = 2        ! first half of month
    3989             : 
    3990             :       ! Find interpolation coefficients
    3991           0 :       call interp_coeff_monthly (recslot)
    3992             : 
    3993           0 :       sst_data(:,:,:,:) = c0
    3994           0 :       do n = nfld, 1, -1
    3995           0 :         do iblk = 1, nblocks
    3996             :         ! use sst_data arrays as temporary work space until n=1
    3997           0 :         if (ixm /= -99) then  ! first half of month
    3998           0 :           sst_data(:,:,1,iblk) = ocn_frc_m(:,:,iblk,n,ixm)
    3999           0 :           sst_data(:,:,2,iblk) = ocn_frc_m(:,:,iblk,n,mmonth)
    4000             :         else                 ! second half of month
    4001           0 :           sst_data(:,:,1,iblk) = ocn_frc_m(:,:,iblk,n,mmonth)
    4002           0 :           sst_data(:,:,2,iblk) = ocn_frc_m(:,:,iblk,n,ixp)
    4003             :         endif
    4004             :         enddo
    4005             : 
    4006           0 :         call interpolate_data (sst_data,work1)
    4007             :         ! masking by hm is necessary due to NaNs in the data file
    4008           0 :         do j = 1, ny_block
    4009           0 :           do i = 1, nx_block
    4010           0 :             if (n == 2) sss    (i,j,:) = c0
    4011           0 :             if (n == 3) hmix   (i,j,:) = c0
    4012           0 :             if (n == 4) uocn   (i,j,:) = c0
    4013           0 :             if (n == 5) vocn   (i,j,:) = c0
    4014           0 :             if (n == 6) ss_tltx(i,j,:) = c0
    4015           0 :             if (n == 7) ss_tlty(i,j,:) = c0
    4016           0 :             if (n == 8) qdp    (i,j,:) = c0
    4017           0 :             do iblk = 1, nblocks
    4018           0 :               if (hm(i,j,iblk) == c1) then
    4019           0 :                 if (n == 2) sss    (i,j,iblk) = work1(i,j,iblk)
    4020           0 :                 if (n == 3) hmix   (i,j,iblk) = max(mixed_layer_depth_default,work1(i,j,iblk))
    4021           0 :                 if (n == 4) uocn   (i,j,iblk) = work1(i,j,iblk)
    4022           0 :                 if (n == 5) vocn   (i,j,iblk) = work1(i,j,iblk)
    4023           0 :                 if (n == 6) ss_tltx(i,j,iblk) = work1(i,j,iblk)
    4024           0 :                 if (n == 7) ss_tlty(i,j,iblk) = work1(i,j,iblk)
    4025           0 :                 if (n == 8) qdp    (i,j,iblk) = work1(i,j,iblk)
    4026             :               endif
    4027             :             enddo
    4028             :           enddo
    4029             :         enddo
    4030             :       enddo
    4031             : 
    4032           0 :       do j = 1, ny_block
    4033           0 :          do i = 1, nx_block
    4034           0 :             sss (i,j,:) = max (sss(i,j,:), c0)
    4035           0 :             hmix(i,j,:) = max(hmix(i,j,:), c0)
    4036             :          enddo
    4037             :       enddo
    4038             : 
    4039           0 :       call ocn_freezing_temperature
    4040             : 
    4041           0 :       if (restore_ocn) then
    4042           0 :         do j = 1, ny_block
    4043           0 :          do i = 1, nx_block
    4044           0 :            sst(i,j,:) = sst(i,j,:) + (work1(i,j,:)-sst(i,j,:))*dt/trest
    4045             :          enddo
    4046             :         enddo
    4047             : !     else sst is only updated in ice_ocean.F
    4048             :       endif
    4049             : 
    4050             :       ! initialize sst properly on first step
    4051           0 :       if (istep1 <= 1 .and. .not. (restart)) then
    4052           0 :         call interpolate_data (sst_data,sst)
    4053           0 :         !$OMP PARALLEL DO PRIVATE(iblk,i,j)
    4054           0 :         do iblk = 1, nblocks
    4055           0 :          do j = 1, ny_block
    4056           0 :           do i = 1, nx_block
    4057           0 :             if (hm(i,j,iblk) == c1) then
    4058           0 :               sst(i,j,iblk) =  max (sst(i,j,iblk), Tf(i,j,iblk))
    4059             :             else
    4060           0 :               sst(i,j,iblk) = c0
    4061             :             endif
    4062             :           enddo
    4063             :          enddo
    4064             :         enddo
    4065             :         !$OMP END PARALLEL DO
    4066             :       endif
    4067             : 
    4068           0 :       if (debug_forcing) then
    4069           0 :          if (my_task == master_task)  &
    4070           0 :                write (nu_diag,*) 'ocn_data_ncar'
    4071           0 :            vmin = global_minval(Tf,distrb_info,tmask)
    4072           0 :            vmax = global_maxval(Tf,distrb_info,tmask)
    4073           0 :            if (my_task.eq.master_task)  &
    4074           0 :                write (nu_diag,*) 'Tf',vmin,vmax
    4075           0 :            vmin = global_minval(sst,distrb_info,tmask)
    4076           0 :            vmax = global_maxval(sst,distrb_info,tmask)
    4077           0 :            if (my_task.eq.master_task)  &
    4078           0 :                write (nu_diag,*) 'sst',vmin,vmax
    4079           0 :            vmin = global_minval(sss,distrb_info,tmask)
    4080           0 :            vmax = global_maxval(sss,distrb_info,tmask)
    4081           0 :            if (my_task.eq.master_task)  &
    4082           0 :                write (nu_diag,*) 'sss',vmin,vmax
    4083           0 :            vmin = global_minval(hmix,distrb_info,tmask)
    4084           0 :            vmax = global_maxval(hmix,distrb_info,tmask)
    4085           0 :            if (my_task.eq.master_task)  &
    4086           0 :                write (nu_diag,*) 'hmix',vmin,vmax
    4087           0 :            vmin = global_minval(uocn,distrb_info,umask)
    4088           0 :            vmax = global_maxval(uocn,distrb_info,umask)
    4089           0 :            if (my_task.eq.master_task)  &
    4090           0 :                write (nu_diag,*) 'uocn',vmin,vmax
    4091           0 :            vmin = global_minval(vocn,distrb_info,umask)
    4092           0 :            vmax = global_maxval(vocn,distrb_info,umask)
    4093           0 :            if (my_task.eq.master_task)  &
    4094           0 :                write (nu_diag,*) 'vocn',vmin,vmax
    4095           0 :            vmin = global_minval(ss_tltx,distrb_info,umask)
    4096           0 :            vmax = global_maxval(ss_tltx,distrb_info,umask)
    4097           0 :            if (my_task.eq.master_task)  &
    4098           0 :                write (nu_diag,*) 'ss_tltx',vmin,vmax
    4099           0 :            vmin = global_minval(ss_tlty,distrb_info,umask)
    4100           0 :            vmax = global_maxval(ss_tlty,distrb_info,umask)
    4101           0 :            if (my_task.eq.master_task)  &
    4102           0 :                write (nu_diag,*) 'ss_tlty',vmin,vmax
    4103           0 :            vmin = global_minval(qdp,distrb_info,tmask)
    4104           0 :            vmax = global_maxval(qdp,distrb_info,tmask)
    4105           0 :            if (my_task.eq.master_task)  &
    4106           0 :                write (nu_diag,*) 'qdp',vmin,vmax
    4107             :       endif
    4108             : 
    4109           0 :       end subroutine ocn_data_ncar
    4110             : 
    4111             : !=======================================================================
    4112             : ! ocean data for oned configuration
    4113             : ! Current (released) values are the same as the defaults (ice_flux.F90)
    4114             : 
    4115           0 :       subroutine ocn_data_oned
    4116             : 
    4117             :       use ice_flux, only: sss, sst, Tf, uocn, vocn, ss_tltx, ss_tlty, &
    4118             :             qdp, hmix, frzmlt
    4119             : 
    4120             :       character(len=*), parameter :: subname = '(ocn_data_oned)'
    4121             : 
    4122             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    4123             : 
    4124           0 :       sss    (:,:,:) = 34.0_dbl_kind   ! sea surface salinity (ppt)
    4125             : 
    4126           0 :       call ocn_freezing_temperature
    4127             : 
    4128           0 :       sst    (:,:,:) = Tf(:,:,:)       ! sea surface temp (C)
    4129           0 :       uocn   (:,:,:) = c0              ! surface ocean currents (m/s)
    4130           0 :       vocn   (:,:,:) = c0
    4131           0 :       ss_tltx(:,:,:) = c0              ! sea surface tilt (m/m)
    4132           0 :       ss_tlty(:,:,:) = c0
    4133           0 :       frzmlt (:,:,:) = c0              ! freezing/melting potential (W/m^2)
    4134           0 :       qdp    (:,:,:) = c0              ! deep ocean heat flux (W/m^2)
    4135           0 :       hmix   (:,:,:) = mixed_layer_depth_default   ! ocean mixed layer depth
    4136             : 
    4137           0 :       end subroutine ocn_data_oned
    4138             : 
    4139             : !=======================================================================
    4140             : 
    4141           0 :       subroutine ocn_data_hadgem(dt)
    4142             : 
    4143             : !  Reads in HadGEM ocean forcing data as required from netCDF files
    4144             : !  Current options (selected by ocn_data_type)
    4145             : !  hadgem_sst: read in sst only
    4146             : !  hadgem_sst_uvocn: read in sst plus uocn and vocn
    4147             : 
    4148             : ! authors: Ann Keen, Met Office
    4149             : 
    4150             :       use ice_domain, only: nblocks
    4151             :       use ice_domain_size, only: max_blocks
    4152             :       use ice_flux, only: sst, uocn, vocn
    4153             :       use ice_grid, only: ANGLET
    4154             : 
    4155             :       real (kind=dbl_kind), intent(in) :: &
    4156             :          dt      ! time step
    4157             : 
    4158             :       integer (kind=int_kind) :: &
    4159             :           i, j, iblk  , &   ! LCOV_EXCL_LINE
    4160             :           ixm,ixp     , & ! record numbers for neighboring months   ! LCOV_EXCL_LINE
    4161             :           maxrec      , & ! maximum record number   ! LCOV_EXCL_LINE
    4162             :           recslot     , & ! spline slot for current record   ! LCOV_EXCL_LINE
    4163             :           midmonth        ! middle day of month
    4164             : 
    4165             :       real (kind=dbl_kind), dimension(nx_block,ny_block,max_blocks) :: &
    4166           0 :           sstdat              ! data value toward which SST is restored
    4167             : 
    4168           0 :       real (kind=dbl_kind) :: workx, worky
    4169             : 
    4170             :       logical (kind=log_kind) :: readm
    4171             : 
    4172             :       character (char_len) :: &
    4173             :             fieldname     ! field name in netcdf file
    4174             : 
    4175             :       character (char_len_long) :: &
    4176             :             filename      ! name of netCDF file
    4177             : 
    4178             :       character(len=*), parameter :: subname = '(ocn_data_hadgem)'
    4179             : 
    4180             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    4181             : 
    4182             :     !-------------------------------------------------------------------
    4183             :     ! monthly data
    4184             :     !
    4185             :     ! Assume that monthly data values are located in the middle of the
    4186             :     ! month.
    4187             :     !-------------------------------------------------------------------
    4188             : 
    4189           0 :       midmonth = 15  ! data is given on 15th of every month
    4190             : !      midmonth = fix(p5 * real(daymo(mmonth)))  ! exact middle
    4191             : 
    4192             :       ! Compute record numbers for surrounding months
    4193           0 :       maxrec = 12
    4194           0 :       ixm  = mod(mmonth+maxrec-2,maxrec) + 1
    4195           0 :       ixp  = mod(mmonth,         maxrec) + 1
    4196           0 :       if (mday >= midmonth) ixm = -99  ! other two points will be used
    4197           0 :       if (mday <  midmonth) ixp = -99
    4198             : 
    4199             :       ! Determine whether interpolation will use values 1:2 or 2:3
    4200             :       ! recslot = 2 means we use values 1:2, with the current value (2)
    4201             :       !  in the second slot
    4202             :       ! recslot = 1 means we use values 2:3, with the current value (2)
    4203             :       !  in the first slot
    4204           0 :       recslot = 1                             ! latter half of month
    4205           0 :       if (mday < midmonth) recslot = 2        ! first half of month
    4206             : 
    4207             :       ! Find interpolation coefficients
    4208           0 :       call interp_coeff_monthly (recslot)
    4209             : 
    4210             :       ! Read 2 monthly values
    4211           0 :       readm = .false.
    4212           0 :       if (istep==1 .or. (mday==midmonth .and. msec==0)) readm = .true.
    4213             : 
    4214           0 :       if (my_task == master_task .and. istep == 1) then
    4215           0 :          write (nu_diag,*) ' '
    4216           0 :          write (nu_diag,*) 'SST data interpolated to timestep:'
    4217           0 :          write (nu_diag,*) trim(ocn_data_dir)//'/MONTHLY/sst.1997.nc'
    4218           0 :          if (restore_ocn) write (nu_diag,*) &
    4219           0 :               'SST restoring timescale (days) =', trestore
    4220           0 :          if (trim(ocn_data_type)=='hadgem_sst_uvocn') then
    4221           0 :             write (nu_diag,*) ' '
    4222           0 :             write (nu_diag,*) 'uocn and vocn interpolated to timestep:'
    4223           0 :             write (nu_diag,*) trim(ocn_data_dir)//'/MONTHLY/uocn.1997.nc'
    4224           0 :             write (nu_diag,*) trim(ocn_data_dir)//'/MONTHLY/vocn.1997.nc'
    4225             :          endif
    4226             :       endif                     ! my_task, istep
    4227             : 
    4228             :       ! -----------------------------------------------------------
    4229             :       ! SST
    4230             :       ! -----------------------------------------------------------
    4231           0 :       sst_file = trim(ocn_data_dir)//'/MONTHLY/sst.1997.nc'
    4232           0 :       fieldname='sst'
    4233             :       call read_data_nc (readm, 0, fyear, ixm, mmonth, ixp, &
    4234             :                       maxrec, sst_file, fieldname, sst_data, &   ! LCOV_EXCL_LINE
    4235           0 :                       field_loc_center, field_type_scalar)
    4236             : 
    4237             :       ! Interpolate to current time step
    4238           0 :       call interpolate_data (sst_data, sstdat)
    4239             : 
    4240             :       ! Restore SSTs if required
    4241           0 :         if (restore_ocn) then
    4242           0 :          !$OMP PARALLEL DO PRIVATE(iblk,i,j)
    4243           0 :          do iblk = 1, nblocks
    4244           0 :             do j = 1, ny_block
    4245           0 :             do i = 1, nx_block
    4246             :                sst(i,j,iblk) = sst(i,j,iblk)  &
    4247           0 :                          + (sstdat(i,j,iblk)-sst(i,j,iblk))*dt/trest
    4248             :             enddo
    4249             :             enddo
    4250             :          enddo
    4251             :          !$OMP END PARALLEL DO
    4252             :          endif
    4253             : 
    4254             :       ! -----------------------------------------------------------
    4255             :       ! Ocean currents
    4256             :       ! --------------
    4257             :       ! Values read in are on T grid and oriented geographically, hence
    4258             :       ! vectors need to be rotated to model grid and then interpolated
    4259             :       ! to U grid.
    4260             :       ! Also need to be converted from cm s-1 (UM) to m s-1 (CICE)
    4261             :       ! -----------------------------------------------------------
    4262             : 
    4263           0 :       if (trim(ocn_data_type)=='hadgem_sst_uvocn') then
    4264             : 
    4265           0 :         filename = trim(ocn_data_dir)//'/MONTHLY/uocn.1997.nc'
    4266           0 :         fieldname='uocn'
    4267             :         call read_data_nc (readm, 0, fyear, ixm, mmonth, ixp, &
    4268             :                       maxrec, filename, fieldname, uocn_data, &   ! LCOV_EXCL_LINE
    4269           0 :                       field_loc_center, field_type_vector)
    4270             : 
    4271             :         ! Interpolate to current time step
    4272           0 :         call interpolate_data (uocn_data, uocn)
    4273             : 
    4274           0 :         filename = trim(ocn_data_dir)//'/MONTHLY/vocn.1997.nc'
    4275           0 :         fieldname='vocn'
    4276             :         call read_data_nc (readm, 0, fyear, ixm, mmonth, ixp, &
    4277             :                       maxrec, filename, fieldname, vocn_data, &   ! LCOV_EXCL_LINE
    4278           0 :                       field_loc_center, field_type_vector)
    4279             : 
    4280             :         ! Interpolate to current time step
    4281           0 :         call interpolate_data (vocn_data, vocn)
    4282             : 
    4283             :      !-----------------------------------------------------------------
    4284             :      ! Rotate zonal/meridional vectors to local coordinates,
    4285             :      ! and change  units
    4286             :      !-----------------------------------------------------------------
    4287             : 
    4288           0 :          !$OMP PARALLEL DO PRIVATE(iblk,i,j,workx,worky)
    4289           0 :          do iblk = 1, nblocks
    4290           0 :             do j = 1, ny_block
    4291           0 :             do i = 1, nx_block
    4292             : 
    4293           0 :                workx      = uocn(i,j,iblk)
    4294           0 :                worky      = vocn(i,j,iblk)
    4295             :                uocn(i,j,iblk) = workx*cos(ANGLET(i,j,iblk)) &
    4296           0 :                                   + worky*sin(ANGLET(i,j,iblk))
    4297             :                vocn(i,j,iblk) = worky*cos(ANGLET(i,j,iblk)) &
    4298           0 :                                   - workx*sin(ANGLET(i,j,iblk))
    4299             : 
    4300           0 :                uocn(i,j,iblk) = uocn(i,j,iblk) * cm_to_m
    4301           0 :                vocn(i,j,iblk) = vocn(i,j,iblk) * cm_to_m
    4302             : 
    4303             :             enddo   ! i
    4304             :             enddo   ! j
    4305             :          enddo      ! nblocks
    4306             :          !$OMP END PARALLEL DO
    4307             : 
    4308             :      !-----------------------------------------------------------------
    4309             :      ! Interpolate to U grid
    4310             :      !-----------------------------------------------------------------
    4311             : 
    4312             :          ! tcraig, this is now computed in dynamics for consistency
    4313             : 
    4314             :      endif    !   ocn_data_type = hadgem_sst_uvocn
    4315             : 
    4316           0 :      end subroutine ocn_data_hadgem
    4317             : 
    4318             : !=======================================================================
    4319             : 
    4320           0 :       subroutine ocn_data_hycom_init
    4321             :         ! Read SSS+SST from a HYCOM file converted to NetCDF format.
    4322             :         ! HYCOM binary2NetCDF: hcdata2ncdf2d (or hcdata2ncdf3z)
    4323             :         !   + rename/link file
    4324             :         use ice_blocks, only: nx_block, ny_block
    4325             :         use ice_domain, only: nblocks
    4326             :         use ice_flux, only: sss, sst, Tf
    4327             : 
    4328             :         integer (kind=int_kind) :: &
    4329             :            i, j, iblk       , & ! horizontal indices   ! LCOV_EXCL_LINE
    4330             :            fid                  ! file id for netCDF file
    4331             : 
    4332             :         character (char_len) :: &
    4333             :            fieldname            ! field name in netcdf file
    4334             : 
    4335             :         character(len=*), parameter :: subname = '(ocn_data_hycom_init)'
    4336             : 
    4337             :         if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    4338             : 
    4339           0 :         if (trim(ocn_data_type) == 'hycom') then
    4340           0 :            sss_file = trim(ocn_data_dir)//'ice.restart.surf.nc'
    4341             : 
    4342           0 :            if (my_task == master_task) then
    4343           0 :              write (nu_diag,*)' '
    4344           0 :              write (nu_diag,*)'Initial SSS file: ',trim(sss_file)
    4345             :            endif
    4346             : 
    4347           0 :            fieldname = 'sss'
    4348           0 :            call ice_open_nc (sss_file, fid)
    4349             :            call ice_read_nc (fid, 1 , fieldname, sss, debug_forcing, &
    4350           0 :                              field_loc_center, field_type_scalar)
    4351           0 :            call ice_close_nc(fid)
    4352             : 
    4353           0 :            call ocn_freezing_temperature
    4354             : 
    4355           0 :            sst_file = trim(ocn_data_dir)//'ice.restart.surf.nc'
    4356             : 
    4357           0 :            if (my_task == master_task) then
    4358           0 :              write (nu_diag,*)' '
    4359           0 :              write (nu_diag,*)'Initial SST file: ',trim(sst_file)
    4360             :            endif
    4361             : 
    4362           0 :            fieldname = 'sst'
    4363           0 :            call ice_open_nc (sst_file, fid)
    4364             :            call ice_read_nc (fid, 1 , fieldname, sst, debug_forcing, &
    4365           0 :                                 field_loc_center, field_type_scalar)
    4366           0 :            call ice_close_nc(fid)
    4367             : 
    4368             :            ! Make sure sst is not less than freezing temperature Tf
    4369           0 :            !$OMP PARALLEL DO PRIVATE(iblk,i,j)
    4370           0 :            do iblk = 1, nblocks
    4371           0 :               do j = 1, ny_block
    4372           0 :               do i = 1, nx_block
    4373           0 :                  sst(i,j,iblk) = max(sst(i,j,iblk),Tf(i,j,iblk))
    4374             :               enddo
    4375             :               enddo
    4376             :            enddo
    4377             :            !$OMP END PARALLEL DO
    4378             :         endif
    4379             : 
    4380           0 :       end subroutine ocn_data_hycom_init
    4381             : 
    4382             : !=======================================================================
    4383             : 
    4384           0 :       subroutine hycom_atm_files
    4385             : 
    4386             :       use ice_broadcast, only: broadcast_array, broadcast_scalar
    4387             : 
    4388             :       integer (kind = int_kind) :: &
    4389             :             fid          ! File id
    4390             :       character (char_len) :: &
    4391             :             varname      ! variable name in netcdf file
    4392             :       character(len=*), parameter :: subname = '(hycom_atm_files)'
    4393             : 
    4394             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    4395             : 
    4396           0 :       fsw_file   = trim(atm_data_dir)//'/forcing.shwflx.nc'
    4397           0 :       flw_file   = trim(atm_data_dir)//'/forcing.radflx.nc'
    4398           0 :       rain_file  = trim(atm_data_dir)//'/forcing.precip.nc'
    4399           0 :       uwind_file = trim(atm_data_dir)//'/forcing.wndewd.nc'
    4400           0 :       vwind_file = trim(atm_data_dir)//'/forcing.wndnwd.nc'
    4401           0 :       tair_file  = trim(atm_data_dir)//'/forcing.airtmp.nc'
    4402           0 :       humid_file = trim(atm_data_dir)//'/forcing.vapmix.nc'
    4403             : 
    4404             :       ! Read time vector from "tair_file"
    4405           0 :       call ice_open_nc(tair_file, fid)
    4406           0 :       varname='MT'
    4407           0 :       call ice_get_ncvarsize(fid,varname,Njday_atm)
    4408           0 :       call broadcast_scalar(Njday_atm,master_task)
    4409           0 :       allocate(jday_atm(Njday_atm))
    4410           0 :       call ice_read_vec_nc(fid,Njday_atm, varname,jday_atm, .true.)
    4411           0 :       call ice_close_nc(fid)
    4412           0 :       call broadcast_array(jday_atm ,master_task)
    4413             : 
    4414             :       ! Write diag info
    4415           0 :       if (my_task == master_task) then
    4416           0 :          write (nu_diag,*) ' '
    4417           0 :          write (nu_diag,*) 'CICE: Atm. (hycomdate) Start = ',jday_atm(1)
    4418           0 :          write (nu_diag,*) 'CICE: Atm. (hycomdate) End   = ',jday_atm(Njday_atm)
    4419           0 :          write (nu_diag,*) 'CICE: Total Atm timesteps    = ',Njday_atm
    4420           0 :          write (nu_diag,*) 'CICE: Atmospheric forcing files:'
    4421           0 :          write (nu_diag,*) trim(fsw_file)
    4422           0 :          write (nu_diag,*) trim(flw_file)
    4423           0 :          write (nu_diag,*) trim(rain_file)
    4424           0 :          write (nu_diag,*) trim(uwind_file)
    4425           0 :          write (nu_diag,*) trim(vwind_file)
    4426           0 :          write (nu_diag,*) trim(tair_file)
    4427           0 :          write (nu_diag,*) trim(humid_file)
    4428             :       endif                     ! master_task
    4429             : 
    4430           0 :       end subroutine hycom_atm_files
    4431             : 
    4432             : !=======================================================================
    4433             : 
    4434           0 :       subroutine hycom_atm_data
    4435             : 
    4436             :       use ice_flux, only: fsw, fsnow, Tair, uatm, vatm, Qa, flw
    4437             :       use ice_domain, only: nblocks
    4438             : 
    4439             :       integer (kind=int_kind) :: &
    4440             :           recnum       ! record number
    4441             : 
    4442             :       real (kind=dbl_kind) :: &
    4443           0 :           hcdate         ! current time in HYCOM jday units
    4444             : 
    4445             :       logical (kind=log_kind) :: read6
    4446             : 
    4447             :       character (char_len) :: &
    4448             :             fieldname    ! field name in netcdf file
    4449             : 
    4450             :       integer (kind=int_kind) :: &
    4451             :          i, j, iblk      ! horizontal indices
    4452             : 
    4453           0 :       real (kind=dbl_kind) :: Tffresh, secday
    4454             : 
    4455             :       character(len=*), parameter :: subname = '(hycom_atm_data)'
    4456             : 
    4457             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    4458             : 
    4459           0 :       call icepack_query_parameters(Tffresh_out=Tffresh)
    4460           0 :       call icepack_query_parameters(secday_out=secday)
    4461             : 
    4462             :       ! current time in HYCOM jday units (HYCOM ref year: 1900,12,31,000000)
    4463           0 :       hcdate = real(compute_days_between(1900,12,31,myear,mmonth,mday)) + msec/secday
    4464             : 
    4465             :       ! Init recnum try
    4466           0 :       recnum=min(max(oldrecnum,1),Njday_atm-1)
    4467             : 
    4468             :       ! Find correct time in ATM data ... assume cont. incr. time-axis
    4469           0 :       do while ( recnum<Njday_atm )
    4470           0 :         if ( hcdate>=jday_atm(recnum) .and. &
    4471           0 :              hcdate<=jday_atm(recnum+1) ) exit
    4472           0 :         if ( abs(hcdate-jday_atm(recnum))<p001 ) exit  ! Accept within tolerance = 0.001 days
    4473           0 :         if ( abs(hcdate-jday_atm(recnum+1))<p001 ) exit  ! Accept within tolerance = 0.001 days
    4474           0 :         recnum=recnum+1
    4475             :       enddo
    4476             : 
    4477             :       ! Last Atm date might be the same as last CICE date.
    4478           0 :       recnum=min(recnum,Njday_atm-1)
    4479             : 
    4480             :       ! Check if current time do not exceed last forcing time
    4481             :       ! + check forcing is available before (or at) current forcing time
    4482           0 :       if ( hcdate>jday_atm(recnum+1)+p001 .or. hcdate<jday_atm(recnum)-p001) then
    4483             :          write (nu_diag,*) &
    4484           0 :          'ERROR: CICE: Atm forcing not available at hcdate =',hcdate
    4485             :          write (nu_diag,*) &
    4486           0 :          'ERROR: CICE: myear, yday ,msec = ',myear, yday, msec
    4487           0 :          call abort_ice ('ERROR: CICE stopped')
    4488             :       endif
    4489             : 
    4490             :       ! Compute interpolation coefficients
    4491           0 :       call interp_coeff2 (hcdate, jday_atm(recnum), jday_atm(recnum+1) )
    4492             : 
    4493             : 
    4494             :       ! Read
    4495           0 :       read6 = .false.
    4496           0 :       if (istep==1 .or. oldrecnum /= recnum) read6 = .true.
    4497             : 
    4498           0 :       if (trim(atm_data_format) == 'nc') then
    4499             : 
    4500           0 :          if (read6 .and. my_task == master_task) write(nu_diag,*) &
    4501           0 :            'CICE: Atm. read: = ',jday_atm(recnum), jday_atm(recnum+1)
    4502             : 
    4503           0 :          fieldname = 'airtmp'
    4504             :          call read_data_nc_hycom (read6, recnum, &
    4505             :                           tair_file, fieldname, Tair_data, &   ! LCOV_EXCL_LINE
    4506           0 :                           field_loc_center, field_type_scalar)
    4507           0 :          fieldname = 'wndewd'
    4508             :          call read_data_nc_hycom (read6, recnum, &
    4509             :                           uwind_file, fieldname, uatm_data, &   ! LCOV_EXCL_LINE
    4510           0 :                           field_loc_center, field_type_vector)
    4511           0 :          fieldname = 'wndnwd'
    4512             :          call read_data_nc_hycom (read6, recnum, &
    4513             :                           vwind_file, fieldname, vatm_data, &   ! LCOV_EXCL_LINE
    4514           0 :                           field_loc_center, field_type_vector)
    4515           0 :          fieldname = 'vapmix'
    4516             :          call read_data_nc_hycom (read6, recnum, &
    4517             :                           humid_file, fieldname, Qa_data,  &   ! LCOV_EXCL_LINE
    4518           0 :                           field_loc_center, field_type_scalar)
    4519           0 :          fieldname = 'shwflx'
    4520             :          call read_data_nc_hycom (read6, recnum, &
    4521             :                           fsw_file, fieldname, fsw_data,   &   ! LCOV_EXCL_LINE
    4522           0 :                           field_loc_center, field_type_scalar)
    4523           0 :          fieldname = 'radflx'
    4524             :          call read_data_nc_hycom (read6, recnum, &
    4525             :                           flw_file, fieldname, flw_data,   &   ! LCOV_EXCL_LINE
    4526           0 :                           field_loc_center, field_type_scalar)
    4527           0 :          fieldname = 'precip'
    4528             :          call read_data_nc_hycom (read6, recnum, &
    4529             :                           rain_file, fieldname, fsnow_data,&   ! LCOV_EXCL_LINE
    4530           0 :                           field_loc_center, field_type_scalar)
    4531             : 
    4532             :       else
    4533           0 :          call abort_ice(subname//'ERROR: atm_data_format unavailable for hycom')
    4534             :       endif
    4535             : 
    4536             :       ! Interpolate
    4537           0 :       if (debug_forcing) then
    4538           0 :         if (my_task == master_task) then
    4539           0 :            write(nu_diag,*)'CICE: Atm. interpolate: = ',&
    4540           0 :                                   hcdate,c1intp,c2intp
    4541             :         endif
    4542             :       endif
    4543           0 :       call interpolate_data (Tair_data, Tair)
    4544           0 :       call interpolate_data (uatm_data, uatm)
    4545           0 :       call interpolate_data (vatm_data, vatm)
    4546           0 :       call interpolate_data ( fsw_data, fsw)
    4547           0 :       call interpolate_data ( flw_data, flw)
    4548           0 :       call interpolate_data (  Qa_data, Qa)
    4549           0 :       call interpolate_data (fsnow_data, fsnow)
    4550             : 
    4551             :       ! Adjust data forcing to CICE units
    4552           0 :       !$OMP PARALLEL DO PRIVATE(iblk,i,j)
    4553           0 :       do iblk = 1, nblocks
    4554           0 :          do j = 1, ny_block
    4555           0 :          do i = 1, nx_block
    4556             :             ! Air temperature: Degrees --> Kelvin
    4557           0 :             Tair(i,j,iblk) = Tair(i,j,iblk) + Tffresh
    4558             :          enddo  ! i
    4559             :          enddo  ! j
    4560             :       enddo     ! nblocks
    4561             :       !$OMP END PARALLEL DO
    4562             : 
    4563             :       ! Save record number for next time step
    4564           0 :       oldrecnum = recnum
    4565             : 
    4566           0 :       end subroutine hycom_atm_data
    4567             : 
    4568             : !=======================================================================
    4569             : !
    4570           0 :       subroutine read_data_nc_point (flag, recd, yr, ixm, ixx, ixp, &
    4571             :                             maxrec, data_file, fieldname, field_data, &   ! LCOV_EXCL_LINE
    4572             :                             field_loc, field_type)
    4573             : !
    4574             : ! If data is at the beginning of a one-year record, get data from
    4575             : !  the previous year.
    4576             : ! If data is at the end of a one-year record, get data from the
    4577             : !  following year.
    4578             : ! If no earlier data exists (beginning of fyear_init), then
    4579             : !  (1) For monthly data, get data from the end of fyear_final.
    4580             : !  (2) For more frequent data, let the ixm value equal the
    4581             : !      first value of the year.
    4582             : ! If no later data exists (end of fyear_final), then
    4583             : !  (1) For monthly data, get data from the beginning of fyear_init.
    4584             : !  (2) For more frequent data, let the ixp value
    4585             : !      equal the last value of the year.
    4586             : ! In other words, we assume persistence when daily or 6-hourly
    4587             : !   data is missing, and we assume periodicity when monthly data
    4588             : !   is missing.
    4589             : !
    4590             :       use ice_diagnostics, only: debug_model_step
    4591             : 
    4592             :       logical (kind=log_kind), intent(in) :: flag
    4593             : 
    4594             :       integer (kind=int_kind), intent(in) :: &
    4595             :          recd                , & ! baseline record number   ! LCOV_EXCL_LINE
    4596             :          yr                  , & ! year of forcing data   ! LCOV_EXCL_LINE
    4597             :          ixm, ixx, ixp       , & ! record numbers of 3 data values   ! LCOV_EXCL_LINE
    4598             :                                  ! relative to recd
    4599             :          maxrec                  ! maximum record value
    4600             : 
    4601             :       character (char_len_long), intent(in) :: &
    4602             :          data_file               ! data file to be read
    4603             : 
    4604             :       character (char_len), intent(in) :: &
    4605             :          fieldname               ! field name in netCDF file
    4606             : 
    4607             :       integer (kind=int_kind), intent(in) :: &
    4608             :            field_loc, &      ! location of field on staggered grid   ! LCOV_EXCL_LINE
    4609             :            field_type        ! type of field (scalar, vector, angle)
    4610             : 
    4611             :       real (kind=dbl_kind), dimension(2), intent(inout) :: &
    4612             :          field_data              ! 2 values needed for interpolation
    4613             : 
    4614             :       integer (kind=int_kind) :: &
    4615             :          nrec             , & ! record number to read   ! LCOV_EXCL_LINE
    4616             :          n2, n4           , & ! like ixm and ixp, but   ! LCOV_EXCL_LINE
    4617             :                               ! adjusted at beginning and end of data
    4618             :          arg              , & ! value of time argument in field_data
    4619             :          fid                  ! file id for netCDF routines
    4620             : 
    4621             :       character(len=*), parameter :: subname = '(read_data_nc_point)'
    4622             : 
    4623             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    4624             : 
    4625           0 :       call ice_timer_start(timer_readwrite)  ! reading/writing
    4626             : 
    4627           0 :       field_data = c0 ! to satisfy intent(out) attribute
    4628             : 
    4629           0 :       if (istep1 > debug_model_step) debug_forcing = .true.  !! debugging
    4630             : 
    4631           0 :       if (my_task==master_task .and. (debug_forcing)) then
    4632           0 :          write(nu_diag,*) '  ', trim(data_file)
    4633             :       endif
    4634             : 
    4635           0 :       if (flag) then
    4636             : 
    4637             :       !-----------------------------------------------------------------
    4638             :       ! Initialize record counters
    4639             :       ! (n2, n4 will change only at the very beginning or end of
    4640             :       !  a forcing cycle.)
    4641             :       !-----------------------------------------------------------------
    4642           0 :          n2 = ixm
    4643           0 :          n4 = ixp
    4644           0 :          arg = 0
    4645             : 
    4646             :       !-----------------------------------------------------------------
    4647             :       ! read data
    4648             :       !-----------------------------------------------------------------
    4649             : 
    4650           0 :          if (ixm /= -99) then
    4651             :          ! currently in first half of data interval
    4652           0 :             if (ixx <= 1) then
    4653           0 :                if (yr > fyear_init) then ! get data from previous year
    4654             :                   !call file_year (data_file, yr-1)
    4655             :                else             ! yr = fyear_init, no prior data exists
    4656           0 :                   if (maxrec > 12) then ! extrapolate from first record
    4657           0 :                      if (ixx == 1) n2 = ixx
    4658             :                   else          ! go to end of fyear_final
    4659             :                     ! call file_year (data_file, fyear_final)
    4660             :                   endif
    4661             :                endif            ! yr > fyear_init
    4662             :             endif               ! ixx <= 1
    4663             : 
    4664             :       ! write(nu_diag,*) '!! read_data_nc !!!', trim(data_file)
    4665             :       ! write(nu_diag,*) 'istep  ', istep
    4666             :       ! write(nu_diag,*) 'fyear_final  ', fyear_final
    4667             :       ! write(nu_diag,*) 'fyear_init  ', fyear_init
    4668             :       ! write(nu_diag,*) 'ixm, ixx, ixp  ', ixm, ixx, ixp
    4669             :       ! write(nu_diag,*) 'maxrec ', maxrec
    4670             :       ! write(nu_diag,*) 'fieldname  ', fieldname
    4671             : 
    4672           0 :             call ice_open_nc (data_file, fid)
    4673             : 
    4674           0 :             arg = 1
    4675           0 :             nrec = recd + n2
    4676             : 
    4677             :             call ice_read_nc &
    4678             :                  (fid, nrec, fieldname, field_data(arg), debug_forcing, &   ! LCOV_EXCL_LINE
    4679           0 :                   field_loc, field_type)
    4680             : 
    4681             :             !if (ixx==1) call ice_close_nc(fid)
    4682           0 :             call ice_close_nc(fid)
    4683             :          endif                  ! ixm ne -99
    4684             : 
    4685             :         ! always read ixx data from data file for current year
    4686             :         ! call file_year (data_file, yr)
    4687           0 :          call ice_open_nc (data_file, fid)
    4688             : 
    4689           0 :          arg = arg + 1
    4690           0 :          nrec = recd + ixx
    4691             : 
    4692             :          call ice_read_nc &
    4693             :               (fid, nrec, fieldname, field_data(arg), debug_forcing, &   ! LCOV_EXCL_LINE
    4694           0 :                field_loc, field_type)
    4695             : 
    4696           0 :          if (ixp /= -99) then
    4697             :          ! currently in latter half of data interval
    4698           0 :             if (ixx==maxrec) then
    4699           0 :                if (yr < fyear_final) then ! get data from following year
    4700           0 :                   call ice_close_nc(fid)
    4701             :                   !call file_year (data_file, yr+1)
    4702           0 :                   call ice_open_nc (data_file, fid)
    4703             :                else             ! yr = fyear_final, no more data exists
    4704           0 :                   if (maxrec > 12) then ! extrapolate from ixx
    4705           0 :                      n4 = ixx
    4706             :                   else          ! go to beginning of fyear_init
    4707           0 :                      call ice_close_nc(fid)
    4708             :                     ! call file_year (data_file, fyear_init)
    4709           0 :                      call ice_open_nc (data_file, fid)
    4710             : 
    4711             :                   endif
    4712             :                endif            ! yr < fyear_final
    4713             :             endif               ! ixx = maxrec
    4714             : 
    4715           0 :             arg = arg + 1
    4716           0 :             nrec = recd + n4
    4717             : 
    4718             :             call ice_read_nc &
    4719             :                  (fid, nrec, fieldname, field_data(arg), debug_forcing, &   ! LCOV_EXCL_LINE
    4720           0 :                   field_loc, field_type)
    4721             :          endif                  ! ixp /= -99
    4722             : 
    4723           0 :          call ice_close_nc(fid)
    4724             : 
    4725             :       endif                     ! flag
    4726             : 
    4727           0 :       call ice_timer_stop(timer_readwrite)  ! reading/writing
    4728             : 
    4729           0 :       end subroutine read_data_nc_point
    4730             : 
    4731             : !=======================================================================
    4732             : 
    4733           0 :       subroutine ISPOL_files
    4734             : 
    4735             :       character(len=*), parameter :: subname = '(ISPOL_files)'
    4736             : 
    4737             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    4738             : 
    4739             :       fsw_file = &
    4740           0 :            trim(atm_data_dir)//'/fsw_sfc_4Xdaily.nc'
    4741             : 
    4742             :       flw_file = &
    4743           0 :            trim(atm_data_dir)//'/flw_sfc_4Xdaily.nc'
    4744             : 
    4745             :       rain_file = &
    4746           0 :            trim(atm_data_dir)//'/fsnow_sfc_daily_mod3.nc'
    4747             : 
    4748             :       uwind_file = &
    4749           0 :            trim(atm_data_dir)//'/uatm_10m_daily.nc'
    4750             : 
    4751             :       vwind_file = &
    4752           0 :            trim(atm_data_dir)//'/vatm_10m_daily.nc'
    4753             : 
    4754             :       tair_file = &
    4755           0 :            trim(atm_data_dir)//'/Tair_2m_daily.nc'
    4756             : 
    4757             :       humid_file = &
    4758           0 :            trim(atm_data_dir)//'/Qa_2m_daily.nc'
    4759             : 
    4760           0 :       if (my_task == master_task) then
    4761           0 :          write (nu_diag,*) ' '
    4762           0 :          write (nu_diag,*) 'Atmospheric data files:'
    4763           0 :          write (nu_diag,*) trim(fsw_file)
    4764           0 :          write (nu_diag,*) trim(flw_file)
    4765           0 :          write (nu_diag,*) trim(rain_file)
    4766           0 :          write (nu_diag,*) trim(uwind_file)
    4767           0 :          write (nu_diag,*) trim(vwind_file)
    4768           0 :          write (nu_diag,*) trim(tair_file)
    4769           0 :          write (nu_diag,*) trim(humid_file)
    4770             :       endif                     ! master_task
    4771             : 
    4772           0 :       end subroutine ISPOL_files
    4773             : 
    4774             : !=======================================================================
    4775             : 
    4776           0 :       subroutine ISPOL_data
    4777             : 
    4778             : ! Defines atmospheric data fields for Antarctic Weddell sea location
    4779             : 
    4780             : ! authors: Nicole Jeffery, LANL
    4781             : !
    4782             :       use ice_flux, only: uatm, vatm, Tair, fsw,  Qa, rhoa, &
    4783             :           frain, fsnow, flw
    4784             : 
    4785             : !local parameters
    4786             : 
    4787             :       character (char_len_long) :: &
    4788             :          met_file,   &    ! netcdf filename   ! LCOV_EXCL_LINE
    4789             :          fieldname        ! field name in netcdf file
    4790             : 
    4791             :       real (kind=dbl_kind), dimension(2), save :: &
    4792             :          Tair_data_p      , &      ! air temperature (K) for interpolation   ! LCOV_EXCL_LINE
    4793             :          Qa_data_p,  fsnow_data_p, &   ! LCOV_EXCL_LINE
    4794             :          fsw_data_p, flw_data_p, &   ! LCOV_EXCL_LINE
    4795             :          uatm_data_p, vatm_data_p
    4796             : 
    4797             :       real (kind=dbl_kind), parameter :: & ! coefficients for Hyland-Wexler Qa
    4798             :          ps1 = 0.58002206e4_dbl_kind,    & ! (K)   ! LCOV_EXCL_LINE
    4799             :          ps2 = 1.3914993_dbl_kind,       & !   ! LCOV_EXCL_LINE
    4800             :          ps3 = 0.48640239e-1_dbl_kind,   & ! (K^-1)   ! LCOV_EXCL_LINE
    4801             :          ps4 = 0.41764768e-4_dbl_kind,   & ! (K^-2)   ! LCOV_EXCL_LINE
    4802             :          ps5 = 0.14452093e-7_dbl_kind,   & ! (K^-3)   ! LCOV_EXCL_LINE
    4803             :          ps6 = 6.5459673_dbl_kind,       & !   ! LCOV_EXCL_LINE
    4804             :          ws1 = 621.97_dbl_kind,          & ! for saturation mixing ratio   ! LCOV_EXCL_LINE
    4805             :          Pair = 1020._dbl_kind,          & ! Sea level pressure (hPa)   ! LCOV_EXCL_LINE
    4806             :          lapse_rate = 0.0065_dbl_kind      ! (K/m) lapse rate over sea level
    4807             : 
    4808             :       ! for interpolation of hourly data
    4809             :       integer (kind=int_kind) :: &
    4810             :          ixm,ixx,ixp , &  ! record numbers for neighboring months   ! LCOV_EXCL_LINE
    4811             :          maxrec      , &  ! maximum record number   ! LCOV_EXCL_LINE
    4812             :          recslot     , &  ! spline slot for current record   ! LCOV_EXCL_LINE
    4813             :          dataloc          ! = 1 for data located in middle of time interval
    4814             :                           ! = 2 for date located at end of time interval
    4815             :       real (kind=dbl_kind) :: &
    4816             :          secday    , &   ! LCOV_EXCL_LINE
    4817           0 :          Qa_pnt
    4818             : 
    4819             :       real (kind=dbl_kind) :: &
    4820           0 :          sec1hr           ! number of seconds in 1 hour
    4821             : 
    4822             :       logical (kind=log_kind) :: read1
    4823             : 
    4824             :       integer (kind=int_kind) :: &
    4825             :           recnum      , & ! record number   ! LCOV_EXCL_LINE
    4826             :           recnum4X        ! record number
    4827             : 
    4828             :       character(len=*), parameter :: subname = '(ISPOL_data)'
    4829             : 
    4830             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    4831             : 
    4832           0 :       call icepack_query_parameters(secday_out=secday)
    4833           0 :       call icepack_warnings_flush(nu_diag)
    4834           0 :       if (icepack_warnings_aborted()) call abort_ice(error_message=subname, &
    4835           0 :          file=__FILE__, line=__LINE__)
    4836             : 
    4837           0 :       if (trim(atm_data_format) == 'nc') then     ! read nc file
    4838             : 
    4839             :      !-------------------------------------------------------------------
    4840             :      ! data from NCEP_DOE Reanalysis 2 and Bareiss et al 2008
    4841             :      ! daily data located at the end of the 24-hour period.
    4842             :      !-------------------------------------------------------------------
    4843             : 
    4844           0 :       dataloc = 2                          ! data located at end of interval
    4845           0 :       sec1hr = secday                      ! seconds in day
    4846           0 :       maxrec = 366                         !
    4847             : 
    4848             :       ! current record number
    4849           0 :       recnum = int(yday)
    4850             : 
    4851             :       ! Compute record numbers for surrounding data (2 on each side)
    4852           0 :       ixm = mod(recnum+maxrec-2,maxrec) + 1
    4853           0 :       ixx = mod(recnum-1,       maxrec) + 1
    4854             : !     ixp = mod(recnum,         maxrec) + 1
    4855             : 
    4856             :       ! Compute interpolation coefficients
    4857             :       ! If data is located at the end of the time interval, then the
    4858             :       !  data value for the current record goes in slot 2
    4859             : 
    4860           0 :       recslot = 2
    4861           0 :       ixp = -99
    4862           0 :       call interp_coeff (recnum, recslot, sec1hr, dataloc)
    4863             : 
    4864           0 :       read1 = .false.
    4865           0 :       if (istep==1 .or. oldrecnum .ne. recnum) read1 = .true.
    4866             : 
    4867             :       ! Daily 2m Air temperature 1991
    4868             : 
    4869           0 :         met_file = tair_file
    4870           0 :         fieldname='Tair'
    4871             : 
    4872             :         call read_data_nc_point(read1, 0, fyear, ixm, ixx, ixp, &
    4873             :                     maxrec, met_file, fieldname, Tair_data_p, &   ! LCOV_EXCL_LINE
    4874           0 :                     field_loc_center, field_type_scalar)
    4875             : 
    4876           0 :         Tair(:,:,:) =  c1intp * Tair_data_p(1) &
    4877             :                        + c2intp * Tair_data_p(2) &   ! LCOV_EXCL_LINE
    4878           0 :                      - lapse_rate*8.0_dbl_kind
    4879             : 
    4880           0 :         met_file = humid_file
    4881           0 :         fieldname='Qa'
    4882             : 
    4883             :         call read_data_nc_point(read1, 0, fyear, ixm, ixx, ixp, &
    4884             :                     maxrec, met_file, fieldname, Qa_data_p, &   ! LCOV_EXCL_LINE
    4885           0 :                     field_loc_center, field_type_scalar)
    4886             : 
    4887             :         Qa_pnt= c1intp * Qa_data_p(1) &
    4888           0 :                           + c2intp * Qa_data_p(2)
    4889           0 :         Qa(:,:,:) = Qa_pnt
    4890             : 
    4891           0 :         met_file = uwind_file
    4892           0 :         fieldname='uatm'
    4893             : 
    4894             :         call read_data_nc_point(read1, 0, fyear, ixm, ixx, ixp, &
    4895             :                     maxrec, met_file, fieldname, uatm_data_p, &   ! LCOV_EXCL_LINE
    4896           0 :                     field_loc_center, field_type_scalar)
    4897             : 
    4898           0 :         uatm(:,:,:) =  c1intp * uatm_data_p(1) &
    4899           0 :                           + c2intp * uatm_data_p(2)
    4900             : 
    4901           0 :         met_file = vwind_file
    4902           0 :         fieldname='vatm'
    4903             : 
    4904             :         call read_data_nc_point(read1, 0, fyear, ixm, ixx, ixp, &
    4905             :                     maxrec, met_file, fieldname, vatm_data_p, &   ! LCOV_EXCL_LINE
    4906           0 :                     field_loc_center, field_type_scalar)
    4907             : 
    4908           0 :         vatm(:,:,:) =  c1intp * vatm_data_p(1) &
    4909           0 :                           + c2intp * vatm_data_p(2)
    4910             : 
    4911           0 :         met_file = rain_file
    4912           0 :         fieldname='fsnow'
    4913             : 
    4914             :         call read_data_nc_point(read1, 0, fyear, ixm, ixx, ixp, &
    4915             :                     maxrec, met_file, fieldname, fsnow_data_p, &   ! LCOV_EXCL_LINE
    4916           0 :                     field_loc_center, field_type_scalar)
    4917             : 
    4918           0 :         fsnow(:,:,:) =  (c1intp * fsnow_data_p(1) + &
    4919           0 :                          c2intp * fsnow_data_p(2))
    4920             : 
    4921             :         !-----------------------------
    4922             :         !fsw and flw are every 6 hours
    4923             :         !------------------------------
    4924           0 :         dataloc = 2                          ! data located at end of interval
    4925           0 :         sec1hr = secday/c4                   ! seconds in 6 hours
    4926           0 :         maxrec = 1460                        ! 366*4
    4927             : 
    4928             :       ! current record number
    4929           0 :         recnum4X = 4*int(yday) - 3 + int(real(msec,kind=dbl_kind)/sec1hr)
    4930             : 
    4931             :       ! Compute record numbers for surrounding data (2 on each side)
    4932           0 :       ixm = mod(recnum4X+maxrec-2,maxrec) + 1
    4933           0 :       ixx = mod(recnum4X-1,       maxrec) + 1
    4934             : 
    4935             :       ! Compute interpolation coefficients
    4936             :       ! If data is located at the end of the time interval, then the
    4937             :       !  data value for the current record goes in slot 2
    4938             : 
    4939           0 :       recslot = 2
    4940           0 :       ixp = -99
    4941           0 :       call interp_coeff (recnum4X, recslot, sec1hr, dataloc)
    4942             : 
    4943           0 :       read1 = .false.
    4944           0 :       if (istep==1 .or. oldrecnum4X .ne. recnum4X) read1 = .true.
    4945             : 
    4946           0 :         met_file = fsw_file
    4947           0 :         fieldname='fsw'
    4948             : 
    4949             :         call read_data_nc_point(read1, 0, fyear, ixm, ixx, ixp, &
    4950             :                     maxrec, met_file, fieldname, fsw_data_p, &   ! LCOV_EXCL_LINE
    4951           0 :                     field_loc_center, field_type_scalar)
    4952             : 
    4953           0 :         fsw(:,:,:) =  c1intp * fsw_data_p(1) &
    4954           0 :                           + c2intp * fsw_data_p(2)
    4955             : 
    4956           0 :         met_file = flw_file
    4957           0 :         fieldname='flw'
    4958             : 
    4959             :         call read_data_nc_point(read1, 0, fyear, ixm, ixx, ixp, &
    4960             :                     maxrec, met_file, fieldname, flw_data_p, &   ! LCOV_EXCL_LINE
    4961           0 :                     field_loc_center, field_type_scalar)
    4962             : 
    4963           0 :         flw(:,:,:) =  c1intp * flw_data_p(1) &
    4964           0 :                           + c2intp * flw_data_p(2)
    4965             :      endif  !nc
    4966             : 
    4967             :       !flw   given cldf and Tair  calculated in prepare_forcing
    4968             : 
    4969             :       !-----------------------------
    4970             :       ! fixed data
    4971             :       ! May not be needed
    4972             :       !-----------------------------
    4973           0 :       rhoa (:,:,:) = 1.3_dbl_kind ! air density (kg/m^3)
    4974           0 :       cldf(:,:,:) =  c1  !0.25_dbl_kind ! cloud fraction
    4975           0 :       frain(:,:,:) = c0            ! this is available in hourlymet_rh file
    4976             : 
    4977             :       ! Save record number for next time step
    4978           0 :       oldrecnum = recnum
    4979           0 :       oldrecnum4X = recnum4X
    4980             : 
    4981           0 :       end subroutine ISPOL_data
    4982             : 
    4983             : !=======================================================================
    4984             : 
    4985           0 :       subroutine ocn_data_ispol_init
    4986             : 
    4987             : ! Reads NCAR pop ocean forcing data set 'pop_frc_gx1v3_010815.nc'
    4988             : ! at the ISPOL location -67.4677N, 310.4375E
    4989             : !
    4990             : ! For ocean mixed layer-----------------------------units
    4991             : !
    4992             : ! 1  sst------temperature---------------------------(C)
    4993             : ! 2  sss------salinity------------------------------(ppt)
    4994             : ! 3  hbl------depth---------------------------------(m)
    4995             : ! 4  u--------surface u current---------------------(m/s)
    4996             : ! 5  v--------surface v current---------------------(m/s)
    4997             : ! 6  dhdx-----surface tilt x direction--------------(m/m)
    4998             : ! 7  dhdy-----surface tilt y direction--------------(m/m)
    4999             : ! 8  qdp------ocean sub-mixed layer heat flux-------(W/m2)
    5000             : !
    5001             : ! Fields 4, 5, 6, 7 are on the U-grid; 1, 2, 3, and 8 are
    5002             : ! on the T-grid.
    5003             : !
    5004             : ! authors: Nicole Jeffery, LANL
    5005             : !
    5006             :       use ice_gather_scatter
    5007             :       use ice_read_write
    5008             : 
    5009             :       integer (kind=int_kind) :: &
    5010             :         n   , & ! field index   ! LCOV_EXCL_LINE
    5011             :         m       ! month index
    5012             : 
    5013             :       character(char_len) :: &
    5014             :         vname(nfld) ! variable names to search for in file
    5015             :       data vname /  &
    5016             :            'T',      'S',      'hblt',  'U',     'V', &   ! LCOV_EXCL_LINE
    5017             :            'dhdx',   'dhdy',   'qdp' /
    5018             : 
    5019             :       real (kind=dbl_kind) :: &
    5020           0 :         work
    5021             : 
    5022             :       integer (kind=int_kind) :: &
    5023             :         fid         ! file id
    5024             : 
    5025             :       character(len=*), parameter :: subname = '(ocn_data_ispol_init)'
    5026             : 
    5027             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    5028             : 
    5029           0 :       if (my_task == master_task) then
    5030             : 
    5031           0 :          if (restore_ocn) write (nu_diag,*)  &
    5032           0 :              'SST restoring timescale = ',trestore,' days'
    5033             : 
    5034           0 :          sst_file = trim(ocn_data_dir)//'/'//trim(oceanmixed_file) ! not just sst
    5035             : 
    5036             :         !---------------------------------------------------------------
    5037             :         ! Read in ocean forcing data from an existing file
    5038             :         !---------------------------------------------------------------
    5039           0 :         write (nu_diag,*) 'ocean mixed layer forcing data file = ', &
    5040           0 :                            sst_file
    5041             : 
    5042             :       endif ! master_task
    5043             : 
    5044           0 :       if (trim(ocn_data_format) == 'nc') then
    5045           0 :         if (my_task == master_task) then
    5046           0 :           call ice_open_nc(sst_file, fid)
    5047             :         endif ! master_task
    5048             : 
    5049             :         ! Read in ocean forcing data for all 12 months
    5050           0 :         do n=1,nfld
    5051           0 :           do m=1,12
    5052             :             ! Note: netCDF does single to double conversion if necessary
    5053           0 :             if (n >= 4 .and. n <= 7) then
    5054           0 :                call ice_read_nc(fid, m, vname(n), work, debug_forcing, &
    5055           0 :                                 field_loc_NEcorner, field_type_vector)
    5056             :             else
    5057           0 :                call ice_read_nc(fid, m, vname(n), work, debug_forcing, &
    5058           0 :                                 field_loc_center, field_type_scalar)
    5059             :             endif
    5060           0 :             ocn_frc_m(:,:,:,n,m) = work
    5061             :           enddo               ! month loop
    5062             :         enddo               ! field loop
    5063             : 
    5064           0 :         if (my_task == master_task) call ice_close_nc(fid)
    5065             : 
    5066             :       else  ! binary format
    5067             :          call abort_ice (error_message=subname//'new ocean forcing is netcdf only', &
    5068           0 :             file=__FILE__, line=__LINE__)
    5069             :       endif
    5070             : 
    5071             : !echmod - currents cause Fram outflow to be too large
    5072           0 :               ocn_frc_m(:,:,:,4,:) = c0
    5073           0 :               ocn_frc_m(:,:,:,5,:) = c0
    5074             : !echmod
    5075             : 
    5076           0 :       end subroutine ocn_data_ispol_init
    5077             : 
    5078             : !=======================================================================
    5079             : !
    5080        2896 :       subroutine box2001_data_atm
    5081             : 
    5082             : ! wind fields as in Hunke, JCP 2001
    5083             : ! these are defined at the u point
    5084             : ! authors: Elizabeth Hunke, LANL
    5085             : 
    5086             :       use ice_domain, only: nblocks, blocks_ice
    5087             :       use ice_calendar, only: timesecs
    5088             :       use ice_blocks, only: block, get_block, nx_block, ny_block, nghost
    5089             :       use ice_flux, only: uatm, vatm, wind, rhoa, strax, stray
    5090             :       use ice_state, only: aice
    5091             : 
    5092             :       ! local parameters
    5093             : 
    5094             :       integer (kind=int_kind) :: &
    5095             :          iblk, i,j           ! loop indices
    5096             : 
    5097             :       integer (kind=int_kind) :: &
    5098             :          iglob(nx_block), & ! global indices   ! LCOV_EXCL_LINE
    5099        5792 :          jglob(ny_block)    ! global indices
    5100             : 
    5101             :       type (block) :: &
    5102             :          this_block           ! block information for current block
    5103             : 
    5104             :       real (kind=dbl_kind) :: &
    5105           0 :          secday, pi , puny, period, pi2, tau
    5106             : 
    5107             :       character(len=*), parameter :: subname = '(box2001_data_atm)'
    5108             : 
    5109             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    5110             : 
    5111        2896 :       call icepack_query_parameters(pi_out=pi, pi2_out=pi2, puny_out=puny)
    5112        2896 :       call icepack_query_parameters(secday_out=secday)
    5113             : 
    5114        2896 :       period = c4*secday
    5115             : 
    5116        8688 :       do iblk = 1, nblocks
    5117      205616 :          do j = 1, ny_block
    5118     6898272 :          do i = 1, nx_block
    5119             : 
    5120     6695552 :          this_block = get_block(blocks_ice(iblk),iblk)
    5121   234344320 :          iglob = this_block%i_glob
    5122   234344320 :          jglob = this_block%j_glob
    5123             : 
    5124             :          ! wind components
    5125           0 :          uatm(i,j,iblk) = c5 + (sin(pi2*timesecs/period)-c3) &
    5126             :                               * sin(pi2*real(iglob(i), kind=dbl_kind)  &   ! LCOV_EXCL_LINE
    5127             :                                        /real(nx_global,kind=dbl_kind)) &   ! LCOV_EXCL_LINE
    5128             :                               * sin(pi *real(jglob(j), kind=dbl_kind)  &   ! LCOV_EXCL_LINE
    5129     6695552 :                                        /real(ny_global,kind=dbl_kind))
    5130           0 :          vatm(i,j,iblk) = c5 + (sin(pi2*timesecs/period)-c3) &
    5131             :                               * sin(pi *real(iglob(i), kind=dbl_kind)  &   ! LCOV_EXCL_LINE
    5132             :                                        /real(nx_global,kind=dbl_kind)) &   ! LCOV_EXCL_LINE
    5133             :                               * sin(pi2*real(jglob(j), kind=dbl_kind)  &   ! LCOV_EXCL_LINE
    5134     6695552 :                                        /real(ny_global,kind=dbl_kind))
    5135             :          ! wind stress
    5136     6695552 :          wind(i,j,iblk) = sqrt(uatm(i,j,iblk)**2 + vatm(i,j,iblk)**2)
    5137     6695552 :          tau = rhoa(i,j,iblk) * 0.0012_dbl_kind * wind(i,j,iblk)
    5138             : 
    5139     6695552 :          strax(i,j,iblk) = aice(i,j,iblk) * tau * uatm(i,j,iblk)
    5140     6892480 :          stray(i,j,iblk) = aice(i,j,iblk) * tau * vatm(i,j,iblk)
    5141             : 
    5142             : ! initialization test
    5143             :        ! Diagonal wind vectors 1
    5144             :          !uatm(i,j,iblk) = c1 *real(j-nghost, kind=dbl_kind) &
    5145             :          !                   / real(ny_global,kind=dbl_kind)
    5146             :          !vatm(i,j,iblk) = c1 *real(j-nghost, kind=dbl_kind) &
    5147             :          !                   / real(ny_global,kind=dbl_kind)
    5148             : 
    5149             :        ! Diagonal wind vectors 2
    5150             :          !uatm(i,j,iblk) = c1 *real(i-nghost, kind=dbl_kind) &
    5151             :          !                   / real(nx_global,kind=dbl_kind)
    5152             :          !vatm(i,j,iblk) = -c1 *real(i-nghost, kind=dbl_kind) &
    5153             :          !                   / real(nx_global,kind=dbl_kind)
    5154             : 
    5155             :        ! Wind in x direction
    5156             :         ! uatm(i,j,iblk) = c1 *real(i-nghost, kind=dbl_kind) &
    5157             :         !                    / real(nx_global,kind=dbl_kind)
    5158             :         ! vatm(i,j,iblk) = c0
    5159             : 
    5160             :        ! Wind in y direction
    5161             :         ! uatm(i,j,iblk) = c0
    5162             :         ! vatm(i,j,iblk) = c1 *real(j-nghost, kind=dbl_kind) &
    5163             :         !                    / real(ny_global,kind=dbl_kind)
    5164             : ! initialization test
    5165             : 
    5166             :          enddo
    5167             :          enddo
    5168             :       enddo ! nblocks
    5169             : 
    5170        2896 :       end subroutine box2001_data_atm
    5171             : 
    5172             : !=======================================================================
    5173             : !
    5174        2896 :       subroutine box2001_data_ocn
    5175             : 
    5176             : ! current fields as in Hunke, JCP 2001
    5177             : ! these are defined at the u point
    5178             : ! authors: Elizabeth Hunke, LANL
    5179             : 
    5180             :       use ice_domain, only: nblocks, blocks_ice
    5181             :       use ice_blocks, only: block, get_block, nx_block, ny_block, nghost
    5182             :       use ice_flux, only: uocn, vocn
    5183             :       use ice_grid, only: uvm
    5184             : 
    5185             :       ! local parameters
    5186             : 
    5187             :       integer (kind=int_kind) :: &
    5188             :          iblk, i,j           ! loop indices
    5189             : 
    5190             :       integer (kind=int_kind) :: &
    5191             :          iglob(nx_block), & ! global indices   ! LCOV_EXCL_LINE
    5192        5792 :          jglob(ny_block)    ! global indices
    5193             : 
    5194             :       type (block) :: &
    5195             :          this_block           ! block information for current block
    5196             : 
    5197             :       character(len=*), parameter :: subname = '(box2001_data_ocn)'
    5198             : 
    5199             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    5200             : 
    5201        8688 :       do iblk = 1, nblocks
    5202      205616 :          do j = 1, ny_block
    5203     6898272 :          do i = 1, nx_block
    5204             : 
    5205     6695552 :          this_block = get_block(blocks_ice(iblk),iblk)
    5206   234344320 :          iglob = this_block%i_glob
    5207   234344320 :          jglob = this_block%j_glob
    5208             : 
    5209             :          ! ocean current
    5210             :          ! constant in time, could be initialized in ice_flux.F90
    5211           0 :          uocn(i,j,iblk) =  p2*real(jglob(j), kind=dbl_kind) &
    5212     6695552 :                             / real(ny_global,kind=dbl_kind) - p1
    5213           0 :          vocn(i,j,iblk) = -p2*real(iglob(i), kind=dbl_kind) &
    5214     6695552 :                             / real(nx_global,kind=dbl_kind) + p1
    5215             : 
    5216     6695552 :          uocn(i,j,iblk) = uocn(i,j,iblk) * uvm(i,j,iblk)
    5217     6892480 :          vocn(i,j,iblk) = vocn(i,j,iblk) * uvm(i,j,iblk)
    5218             : 
    5219             :          enddo
    5220             :          enddo
    5221             :       enddo ! nblocks
    5222             : 
    5223        2896 :       end subroutine box2001_data_ocn
    5224             : 
    5225             : !=======================================================================
    5226             : !
    5227           0 :       subroutine uniform_data_atm(dir,spd)
    5228             : !     uniform wind fields in some direction
    5229             : 
    5230             :       use ice_domain, only: nblocks
    5231             :       use ice_blocks, only: nx_block, ny_block, nghost
    5232             :       use ice_flux, only: uatm, vatm, wind, rhoa, strax, stray
    5233             :       use ice_state, only: aice
    5234             : 
    5235             :       character(len=*), intent(in) :: dir
    5236             :       real(kind=dbl_kind), intent(in), optional :: spd ! velocity
    5237             : 
    5238             :       ! local parameters
    5239             : 
    5240             :       integer (kind=int_kind) :: &
    5241             :          iblk, i,j           ! loop indices
    5242             : 
    5243             :       real (kind=dbl_kind) :: &
    5244             :          tau, &   ! LCOV_EXCL_LINE
    5245           0 :          atm_val ! value to use for atm speed
    5246             : 
    5247             :       character(len=*), parameter :: subname = '(uniform_data_atm)'
    5248             : 
    5249             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    5250             : 
    5251             :       ! check for optional spd
    5252           0 :       if (present(spd)) then
    5253           0 :          atm_val = spd
    5254             :       else
    5255           0 :          atm_val = c5 ! default
    5256             :       endif
    5257             : 
    5258             :       ! wind components
    5259           0 :       if (dir == 'NE') then
    5260           0 :          uatm = atm_val
    5261           0 :          vatm = atm_val
    5262           0 :       elseif (dir == 'N') then
    5263           0 :          uatm = c0
    5264           0 :          vatm = atm_val
    5265           0 :       elseif (dir == 'E') then
    5266           0 :          uatm = atm_val
    5267           0 :          vatm = c0
    5268           0 :       elseif (dir == 'S') then
    5269           0 :          uatm = c0
    5270           0 :          vatm = -atm_val
    5271           0 :       elseif (dir == 'W') then
    5272           0 :          uatm = -atm_val
    5273           0 :          vatm = c0
    5274             :       else
    5275             :          call abort_ice (subname//'ERROR: dir unknown, dir = '//trim(dir), &
    5276           0 :               file=__FILE__, line=__LINE__)
    5277             :       endif
    5278             : 
    5279           0 :       do iblk = 1, nblocks
    5280           0 :          do j = 1, ny_block
    5281           0 :          do i = 1, nx_block
    5282             : 
    5283             :             ! wind stress
    5284           0 :             wind(i,j,iblk) = sqrt(uatm(i,j,iblk)**2 + vatm(i,j,iblk)**2)
    5285           0 :             tau = rhoa(i,j,iblk) * 0.0012_dbl_kind * wind(i,j,iblk)
    5286           0 :             strax(i,j,iblk) = aice(i,j,iblk) * tau * uatm(i,j,iblk)
    5287           0 :             stray(i,j,iblk) = aice(i,j,iblk) * tau * vatm(i,j,iblk)
    5288             : 
    5289             :          enddo
    5290             :          enddo
    5291             :       enddo ! nblocks
    5292             : 
    5293           0 :       end subroutine uniform_data_atm
    5294             : !=======================================================================
    5295             : 
    5296             : !
    5297           0 :       subroutine uniform_data_ocn(dir,spd)
    5298             : 
    5299             : !     uniform current fields in some direction
    5300             : 
    5301             :       use ice_flux, only: uocn, vocn
    5302             : 
    5303             :       character(len=*), intent(in) :: dir
    5304             : 
    5305             :       real(kind=dbl_kind), intent(in), optional :: spd ! velocity
    5306             : 
    5307             :       ! local parameters
    5308             : 
    5309             :       real(kind=dbl_kind) :: &
    5310           0 :            ocn_val ! value to use for ocean currents
    5311             : 
    5312             :       character(len=*), parameter :: subname = '(uniform_data_ocn)'
    5313             : 
    5314             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    5315             : 
    5316           0 :       if (present(spd)) then
    5317           0 :          ocn_val = spd
    5318             :       else
    5319           0 :          ocn_val = p1 ! default
    5320             :       endif
    5321             : 
    5322             :       ! ocn components
    5323           0 :       if (dir == 'NE') then
    5324           0 :          uocn = ocn_val
    5325           0 :          vocn = ocn_val
    5326           0 :       elseif (dir == 'N') then
    5327           0 :          uocn = c0
    5328           0 :          vocn = ocn_val
    5329           0 :       elseif (dir == 'E') then
    5330           0 :          uocn = ocn_val
    5331           0 :          vocn = c0
    5332             :       else
    5333             :          call abort_ice (subname//'ERROR: dir unknown, dir = '//trim(dir), &
    5334           0 :               file=__FILE__, line=__LINE__)
    5335             :       endif
    5336             : 
    5337           0 :       end subroutine uniform_data_ocn
    5338             : !=======================================================================
    5339             : 
    5340           0 :       subroutine get_wave_spec
    5341             : 
    5342             :       use ice_read_write, only: ice_read_nc_xyf
    5343             :       use ice_arrays_column, only: wave_spectrum, &
    5344             :                                    dwavefreq, wavefreq
    5345             :       use ice_constants, only: c0
    5346             :       use ice_timers, only: ice_timer_start, ice_timer_stop, timer_fsd
    5347             : 
    5348             :       ! local variables
    5349             :       integer (kind=int_kind) :: &
    5350             :          fid                    ! file id for netCDF routines
    5351             : 
    5352             :       real(kind=dbl_kind), dimension(nfreq) :: &
    5353           0 :          wave_spectrum_profile  ! wave spectrum
    5354             : 
    5355             :       character(char_len) :: wave_spec_type
    5356             :       logical (kind=log_kind) :: wave_spec
    5357             :       character(len=*), parameter :: subname = '(get_wave_spec)'
    5358             : 
    5359             :       if (local_debug .and. my_task == master_task) write(nu_diag,*) subname,'fdbg start'
    5360             : 
    5361           0 :       call ice_timer_start(timer_fsd)
    5362             : 
    5363             :       call icepack_query_parameters(wave_spec_out=wave_spec, &
    5364           0 :                                     wave_spec_type_out=wave_spec_type)
    5365           0 :       call icepack_warnings_flush(nu_diag)
    5366           0 :       if (icepack_warnings_aborted()) call abort_ice(error_message=subname, &
    5367           0 :          file=__FILE__, line=__LINE__)
    5368             : 
    5369             :       ! if no wave data is provided, wave_spectrum is zero everywhere
    5370           0 :       wave_spectrum(:,:,:,:) = c0
    5371           0 :       debug_forcing = .false.
    5372             : 
    5373             :       ! wave spectrum and frequencies
    5374           0 :       if (wave_spec) then
    5375             :       ! get hardwired frequency bin info and a dummy wave spectrum profile
    5376             :       ! the latter is used if wave_spec_type == profile
    5377             :          call icepack_init_wave(nfreq,                 &
    5378             :                                 wave_spectrum_profile, &   ! LCOV_EXCL_LINE
    5379           0 :                                 wavefreq, dwavefreq)
    5380             : 
    5381             :          ! read more realistic data from a file
    5382           0 :          if ((trim(wave_spec_type) == 'constant').OR.(trim(wave_spec_type) == 'random')) then
    5383           0 :             if (trim(wave_spec_file(1:4)) == 'unkn') then
    5384             :                call abort_ice (subname//'ERROR: wave_spec_file '//trim(wave_spec_file), &
    5385           0 :                   file=__FILE__, line=__LINE__)
    5386             :             else
    5387             : #ifdef USE_NETCDF
    5388           0 :                call wave_spec_data
    5389             : #else
    5390             :                write (nu_diag,*) "wave spectrum file not available, requires cpp USE_NETCDF"
    5391             :                write (nu_diag,*) "wave spectrum file not available, using default profile"
    5392             :                call abort_ice (subname//'ERROR: wave_spec_file '//trim(wave_spec_file), &
    5393             :                   file=__FILE__, line=__LINE__)
    5394             : #endif
    5395             :             endif
    5396             :          endif
    5397             :       endif
    5398             : 
    5399           0 :       call ice_timer_stop(timer_fsd)
    5400             : 
    5401           0 :       end subroutine get_wave_spec
    5402             : 
    5403             : !=======================================================================
    5404             : !
    5405             : !   Read in wave spectrum forcing as a function of time. 6 hourly
    5406             : !   LR started working from JRA55_data routine
    5407             : !   Changed fields, and changed 3 hourly to 6 hourly
    5408             : !
    5409           0 :       subroutine wave_spec_data
    5410             : 
    5411             :       use ice_blocks, only: block, get_block
    5412             :       use ice_global_reductions, only: global_minval, global_maxval
    5413             :       use ice_domain, only: nblocks, distrb_info, blocks_ice
    5414             :       use ice_arrays_column, only: wave_spectrum, &
    5415             :                                    dwavefreq, wavefreq
    5416             :       use ice_read_write, only: ice_read_nc_xyf
    5417             :       use ice_grid, only: hm, tlon, tlat, tmask, umask
    5418             :       use ice_calendar, only: days_per_year, use_leap_years
    5419             : 
    5420             :       integer (kind=int_kind) :: &
    5421             :           ncid        , & ! netcdf file id   ! LCOV_EXCL_LINE
    5422             :           i, j, freq  , &   ! LCOV_EXCL_LINE
    5423             :           ixm,ixx,ixp , & ! record numbers for neighboring months   ! LCOV_EXCL_LINE
    5424             :           recnum      , & ! record number   ! LCOV_EXCL_LINE
    5425             :           maxrec      , & ! maximum record number   ! LCOV_EXCL_LINE
    5426             :           recslot     , & ! spline slot for current record   ! LCOV_EXCL_LINE
    5427             :           midmonth    , & ! middle day of month   ! LCOV_EXCL_LINE
    5428             :           dataloc     , & ! = 1 for data located in middle of time interval   ! LCOV_EXCL_LINE
    5429             :                           ! = 2 for date located at end of time interval
    5430             :           iblk        , & ! block index
    5431             :           ilo,ihi,jlo,jhi, & ! beginning and end of physical domain   ! LCOV_EXCL_LINE
    5432             :           yr              ! current forcing year
    5433             : 
    5434             :       real (kind=dbl_kind) :: &
    5435             :           sec6hr          , & ! number of seconds in 3 hours   ! LCOV_EXCL_LINE
    5436             :           secday          , & ! number of seconds in day   ! LCOV_EXCL_LINE
    5437             :           vmin, vmax
    5438             : 
    5439             :       logical (kind=log_kind) :: readm, read6,debug_n_d
    5440             : 
    5441             :       type (block) :: &
    5442             :          this_block           ! block information for current block
    5443             : 
    5444             :       real(kind=dbl_kind), dimension(nfreq) :: &
    5445           0 :          wave_spectrum_profile  ! wave spectrum
    5446             : 
    5447             :       character(len=64) :: fieldname !netcdf field name
    5448             :       character(char_len_long) :: spec_file
    5449             :       character(char_len) :: wave_spec_type
    5450             :       logical (kind=log_kind) :: wave_spec
    5451             :       character(len=*), parameter :: subname = '(wave_spec_data)'
    5452             : 
    5453             : 
    5454             : 
    5455           0 :       debug_n_d = .false.  !usually false
    5456             : 
    5457           0 :       call icepack_query_parameters(secday_out=secday)
    5458           0 :       call icepack_warnings_flush(nu_diag)
    5459           0 :       if (icepack_warnings_aborted()) call abort_ice(error_message=subname, &
    5460           0 :          file=__FILE__, line=__LINE__)
    5461             : 
    5462             :          call icepack_init_wave(nfreq,                 &
    5463             :                                 wave_spectrum_profile, &   ! LCOV_EXCL_LINE
    5464           0 :                                 wavefreq, dwavefreq)
    5465             : 
    5466             : 
    5467             :       !spec_file = trim(ocn_data_dir)//'/'//trim(wave_spec_file)
    5468           0 :       spec_file = trim(wave_spec_file)
    5469           0 :       wave_spectrum_data = c0
    5470           0 :       wave_spectrum = c0
    5471           0 :       yr = fyear  ! current year
    5472             :     !-------------------------------------------------------------------
    5473             :     ! 6-hourly data
    5474             :     !
    5475             :     ! Assume that the 6-hourly value is located at the end of the
    5476             :     !  6-hour period.  This is the convention for NCEP reanalysis data.
    5477             :     !  E.g. record 1 gives conditions at 6 am GMT on 1 January.
    5478             :     !-------------------------------------------------------------------
    5479             : 
    5480           0 :       dataloc = 2               ! data located at end of interval
    5481           0 :       sec6hr = secday/c4        ! seconds in 6 hours
    5482             :       !maxrec = 2920            ! 365*8; for leap years = 366*8
    5483             : 
    5484           0 :       if (use_leap_years) days_per_year = 366 !overrides setting of 365 in ice_calendar
    5485           0 :       maxrec = days_per_year*4
    5486             : 
    5487           0 :       if(days_per_year == 365 .and. (mod(yr,  4) == 0)) then
    5488           0 :       call abort_ice('days_per_year should be set to 366 for leap years')
    5489             :       end if
    5490             : 
    5491             :       ! current record number
    5492           0 :       recnum = 4*int(yday) - 3 + int(real(msec,kind=dbl_kind)/sec6hr)
    5493             : 
    5494             :       ! Compute record numbers for surrounding data (2 on each side)
    5495             : 
    5496           0 :       ixm = mod(recnum+maxrec-2,maxrec) + 1
    5497           0 :       ixx = mod(recnum-1,       maxrec) + 1
    5498             : 
    5499             :       ! Compute interpolation coefficients
    5500             :       ! If data is located at the end of the time interval, then the
    5501             :       !  data value for the current record goes in slot 2
    5502             : 
    5503           0 :       recslot = 2
    5504           0 :       ixp = -99
    5505           0 :       call interp_coeff (recnum, recslot, sec6hr, dataloc)
    5506             : 
    5507             :       ! Read
    5508           0 :       read6 = .false.
    5509           0 :       if (istep==1 .or. oldrecnum .ne. recnum) read6 = .true.
    5510             :          !-------------------------------------------------------------------
    5511             :          ! File is NETCDF
    5512             :          ! file variable names are:
    5513             :          ! efreq   (wave spectrum, energy as a function of wave frequency UNITS)
    5514             :          !-------------------------------------------------------------------
    5515           0 :          call ice_open_nc(spec_file,ncid)
    5516             : 
    5517           0 :          call ice_read_nc_xyf(ncid,recnum,'efreq',wave_spectrum_data(:,:,:,1,:),debug_n_d, &
    5518             :               field_loc=field_loc_center, &   ! LCOV_EXCL_LINE
    5519           0 :               field_type=field_type_scalar)
    5520           0 :          call ice_read_nc_xyf(ncid,recnum,'efreq',wave_spectrum_data(:,:,:,2,:),debug_n_d, &
    5521             :               field_loc=field_loc_center, &   ! LCOV_EXCL_LINE
    5522           0 :               field_type=field_type_scalar)
    5523           0 :          call ice_close_nc(ncid)
    5524             : 
    5525             : 
    5526             :       ! Interpolate
    5527           0 :       call interpolate_wavespec_data (wave_spectrum_data, wave_spectrum)
    5528             : 
    5529             :       ! Save record number
    5530           0 :       oldrecnum = recnum
    5531             : 
    5532             :          if (local_debug) then
    5533             :            if (my_task == master_task) write (nu_diag,*) &
    5534             :               'wave_spec_data ',spec_file
    5535             :            if (my_task.eq.master_task)  &
    5536             :                write (nu_diag,*) 'maxrec',maxrec
    5537             :                write (nu_diag,*) 'days_per_year', days_per_year
    5538             : 
    5539             :         endif                   ! local debug
    5540             : 
    5541           0 :       end subroutine wave_spec_data
    5542             : 
    5543             : !=======================================================================
    5544             : 
    5545             : ! initial snow aging lookup table
    5546             : !
    5547             : ! Dry snow metamorphism table
    5548             : ! snicar_drdt_bst_fit_60_c070416.nc
    5549             : ! Flanner (file metadata units mislabelled)
    5550             : ! drdsdt0 (10^-6 m/hr) tau (10^-6 m)
    5551             : !
    5552           0 :      subroutine init_snowtable
    5553             : 
    5554             :       use ice_broadcast, only: broadcast_array, broadcast_scalar
    5555             :       integer (kind=int_kind) :: &
    5556             :           idx_T_max   , &  ! Table dimensions   ! LCOV_EXCL_LINE
    5557             :           idx_rhos_max, &   ! LCOV_EXCL_LINE
    5558             :           idx_Tgrd_max
    5559             :       real (kind=dbl_kind), allocatable :: &
    5560             :           snowage_rhos (:), &   ! LCOV_EXCL_LINE
    5561             :           snowage_Tgrd (:), &   ! LCOV_EXCL_LINE
    5562             :           snowage_T    (:), &   ! LCOV_EXCL_LINE
    5563             :           snowage_tau  (:,:,:), &   ! LCOV_EXCL_LINE
    5564             :           snowage_kappa(:,:,:), &   ! LCOV_EXCL_LINE
    5565           0 :           snowage_drdt0(:,:,:)
    5566             : 
    5567             :       ! local variables
    5568             : 
    5569             :       logical (kind=log_kind) :: diag = .false.
    5570             : 
    5571             :       integer (kind=int_kind) :: &
    5572             :          fid                  ! file id for netCDF file
    5573             : 
    5574             :       character (char_len) :: &
    5575             :          snw_aging_table, &   ! aging table setting   ! LCOV_EXCL_LINE
    5576             :          fieldname            ! field name in netcdf file
    5577             : 
    5578             :       character(len=*), parameter :: subname = '(init_snowtable)'
    5579             : 
    5580             :       !-----------------------------------------------------------------
    5581             :       ! read table of snow aging parameters
    5582             :       !-----------------------------------------------------------------
    5583             : 
    5584             :       call icepack_query_parameters(snw_aging_table_out=snw_aging_table, &
    5585           0 :          isnw_rhos_out=idx_rhos_max, isnw_Tgrd_out=idx_Tgrd_max, isnw_T_out=idx_T_max)
    5586             : 
    5587           0 :       if (my_task == master_task) then
    5588           0 :          write (nu_diag,*) ' '
    5589           0 :          write (nu_diag,*) 'Snow aging file:', trim(snw_filename)
    5590             :       endif
    5591             : 
    5592           0 :       if (snw_aging_table == 'snicar') then
    5593             :          ! just read the 3d data and pass it in
    5594             : 
    5595           0 :          call ice_open_nc(snw_filename,fid)
    5596             : 
    5597           0 :          allocate(snowage_tau  (idx_rhos_max, idx_Tgrd_max, idx_T_max))
    5598           0 :          allocate(snowage_kappa(idx_rhos_max, idx_Tgrd_max, idx_T_max))
    5599           0 :          allocate(snowage_drdt0(idx_rhos_max, idx_Tgrd_max, idx_T_max))
    5600             : 
    5601           0 :          fieldname = trim(snw_tau_fname)
    5602             :          call ice_read_nc(fid,fieldname,snowage_tau,  diag, &
    5603           0 :                           idx_rhos_max,idx_Tgrd_max,idx_T_max)
    5604           0 :          fieldname = trim(snw_kappa_fname)
    5605             :          call ice_read_nc(fid,fieldname,snowage_kappa,diag, &
    5606           0 :                           idx_rhos_max,idx_Tgrd_max,idx_T_max)
    5607           0 :          fieldname = trim(snw_drdt0_fname)
    5608             :          call ice_read_nc(fid,fieldname,snowage_drdt0,diag, &
    5609           0 :                           idx_rhos_max,idx_Tgrd_max,idx_T_max)
    5610             : 
    5611           0 :          call ice_close_nc(fid)
    5612             : 
    5613           0 :          call broadcast_array(snowage_tau  , master_task)
    5614           0 :          call broadcast_array(snowage_kappa, master_task)
    5615           0 :          call broadcast_array(snowage_drdt0, master_task)
    5616             : 
    5617           0 :          if (my_task == master_task) then
    5618           0 :             write(nu_diag,*) subname,'  '
    5619           0 :             write(nu_diag,*) subname,' Successfully read snow aging properties:'
    5620           0 :             write(nu_diag,*) subname,' snw_aging_table = ',trim(snw_aging_table)
    5621           0 :             write(nu_diag,*) subname,' idx_rhos_max = ',idx_rhos_max
    5622           0 :             write(nu_diag,*) subname,' idx_Tgrd_max = ',idx_Tgrd_max
    5623           0 :             write(nu_diag,*) subname,' idx_T_max    = ',idx_T_max
    5624           0 :             write(nu_diag,*) subname,' Data at rhos, Tgrd, T at first index '
    5625           0 :             write(nu_diag,*) subname,' snoage_tau (1,1,1)         = ',snowage_tau  (1,1,1)
    5626           0 :             write(nu_diag,*) subname,' snoage_kappa (1,1,1)       = ',snowage_kappa(1,1,1)
    5627           0 :             write(nu_diag,*) subname,' snoage_drdt0 (1,1,1)       = ',snowage_drdt0(1,1,1)
    5628           0 :             write(nu_diag,*) subname,' Data at rhos, Tgrd, T at max index'
    5629           0 :             write(nu_diag,*) subname,' snoage_tau (max,max,max)   = ',snowage_tau  (idx_rhos_max, idx_Tgrd_max, idx_T_max)
    5630           0 :             write(nu_diag,*) subname,' snoage_kappa (max,max,max) = ',snowage_kappa(idx_rhos_max, idx_Tgrd_max, idx_T_max)
    5631           0 :             write(nu_diag,*) subname,' snoage_drdt0 (max,max,max) = ',snowage_drdt0(idx_rhos_max, idx_Tgrd_max, idx_T_max)
    5632             :          endif
    5633             : 
    5634             :          call icepack_init_parameters(        &
    5635             :             snowage_tau_in   = snowage_tau,   &   ! LCOV_EXCL_LINE
    5636             :             snowage_kappa_in = snowage_kappa, &   ! LCOV_EXCL_LINE
    5637           0 :             snowage_drdt0_in = snowage_drdt0 )
    5638             : 
    5639           0 :          deallocate(snowage_tau)
    5640           0 :          deallocate(snowage_kappa)
    5641           0 :          deallocate(snowage_drdt0)
    5642             : 
    5643             :       else
    5644             :          ! read everything and pass it in
    5645             : 
    5646           0 :          call ice_open_nc(snw_filename,fid)
    5647             : 
    5648           0 :          fieldname = trim(snw_rhos_fname)
    5649           0 :          call ice_get_ncvarsize(fid,fieldname,idx_rhos_max)
    5650           0 :          fieldname = trim(snw_Tgrd_fname)
    5651           0 :          call ice_get_ncvarsize(fid,fieldname,idx_Tgrd_max)
    5652           0 :          fieldname = trim(snw_T_fname)
    5653           0 :          call ice_get_ncvarsize(fid,fieldname,idx_T_max)
    5654             : 
    5655           0 :          call broadcast_scalar(idx_rhos_max, master_task)
    5656           0 :          call broadcast_scalar(idx_Tgrd_max, master_task)
    5657           0 :          call broadcast_scalar(idx_T_max   , master_task)
    5658             : 
    5659           0 :          allocate(snowage_rhos (idx_rhos_max))
    5660           0 :          allocate(snowage_Tgrd (idx_Tgrd_max))
    5661           0 :          allocate(snowage_T    (idx_T_max))
    5662           0 :          allocate(snowage_tau  (idx_rhos_max, idx_Tgrd_max, idx_T_max))
    5663           0 :          allocate(snowage_kappa(idx_rhos_max, idx_Tgrd_max, idx_T_max))
    5664           0 :          allocate(snowage_drdt0(idx_rhos_max, idx_Tgrd_max, idx_T_max))
    5665             : 
    5666           0 :          fieldname = trim(snw_rhos_fname)
    5667             :          call ice_read_nc(fid,fieldname,snowage_rhos,  diag, &
    5668           0 :                           idx_rhos_max)
    5669           0 :          fieldname = trim(snw_Tgrd_fname)
    5670             :          call ice_read_nc(fid,fieldname,snowage_Tgrd,  diag, &
    5671           0 :                           idx_Tgrd_max)
    5672           0 :          fieldname = trim(snw_T_fname)
    5673             :          call ice_read_nc(fid,fieldname,snowage_T,  diag, &
    5674           0 :                           idx_T_max)
    5675             : 
    5676           0 :          fieldname = trim(snw_tau_fname)
    5677             :          call ice_read_nc(fid,fieldname,snowage_tau,  diag, &
    5678           0 :                           idx_rhos_max,idx_Tgrd_max,idx_T_max)
    5679           0 :          fieldname = trim(snw_kappa_fname)
    5680             :          call ice_read_nc(fid,fieldname,snowage_kappa,diag, &
    5681           0 :                           idx_rhos_max,idx_Tgrd_max,idx_T_max)
    5682           0 :          fieldname = trim(snw_drdt0_fname)
    5683             :          call ice_read_nc(fid,fieldname,snowage_drdt0,diag, &
    5684           0 :                           idx_rhos_max,idx_Tgrd_max,idx_T_max)
    5685             : 
    5686           0 :          call ice_close_nc(fid)
    5687             : 
    5688           0 :          call broadcast_array(snowage_rhos , master_task)
    5689           0 :          call broadcast_array(snowage_Tgrd , master_task)
    5690           0 :          call broadcast_array(snowage_T    , master_task)
    5691           0 :          call broadcast_array(snowage_tau  , master_task)
    5692           0 :          call broadcast_array(snowage_kappa, master_task)
    5693           0 :          call broadcast_array(snowage_drdt0, master_task)
    5694             : 
    5695           0 :          if (my_task == master_task) then
    5696           0 :             write(nu_diag,*) subname,'  '
    5697           0 :             write(nu_diag,*) subname,' Successfully read snow aging properties:'
    5698           0 :             write(nu_diag,*) subname,' idx_rhos_max = ',idx_rhos_max
    5699           0 :             write(nu_diag,*) subname,' idx_Tgrd_max = ',idx_Tgrd_max
    5700           0 :             write(nu_diag,*) subname,' idx_T_max    = ',idx_T_max
    5701           0 :             write(nu_diag,*) subname,' Data at rhos, Tgrd, T = ',snowage_rhos(1),snowage_Tgrd(1),snowage_T(1)
    5702           0 :             write(nu_diag,*) subname,' snoage_tau (1,1,1)         = ',snowage_tau  (1,1,1)
    5703           0 :             write(nu_diag,*) subname,' snoage_kappa (1,1,1)       = ',snowage_kappa(1,1,1)
    5704           0 :             write(nu_diag,*) subname,' snoage_drdt0 (1,1,1)       = ',snowage_drdt0(1,1,1)
    5705           0 :             write(nu_diag,*) subname,' Data at rhos, Tgrd, T = ', &
    5706           0 :                                        snowage_rhos(idx_rhos_max),snowage_Tgrd(idx_Tgrd_max),snowage_T(idx_T_max)
    5707           0 :             write(nu_diag,*) subname,' snoage_tau (max,max,max)   = ',snowage_tau  (idx_rhos_max, idx_Tgrd_max, idx_T_max)
    5708           0 :             write(nu_diag,*) subname,' snoage_kappa (max,max,max) = ',snowage_kappa(idx_rhos_max, idx_Tgrd_max, idx_T_max)
    5709           0 :             write(nu_diag,*) subname,' snoage_drdt0 (max,max,max) = ',snowage_drdt0(idx_rhos_max, idx_Tgrd_max, idx_T_max)
    5710             :          endif
    5711             : 
    5712             :          call icepack_init_parameters(        &
    5713             :             isnw_t_in        = idx_T_max,     &   ! LCOV_EXCL_LINE
    5714             :             isnw_Tgrd_in     = idx_Tgrd_max,  &   ! LCOV_EXCL_LINE
    5715             :             isnw_rhos_in     = idx_rhos_max,  &   ! LCOV_EXCL_LINE
    5716             :             snowage_rhos_in  = snowage_rhos,  &   ! LCOV_EXCL_LINE
    5717             :             snowage_Tgrd_in  = snowage_Tgrd,  &   ! LCOV_EXCL_LINE
    5718             :             snowage_T_in     = snowage_T,     &   ! LCOV_EXCL_LINE
    5719             :             snowage_tau_in   = snowage_tau,   &   ! LCOV_EXCL_LINE
    5720             :             snowage_kappa_in = snowage_kappa, &   ! LCOV_EXCL_LINE
    5721           0 :             snowage_drdt0_in = snowage_drdt0 )
    5722             : 
    5723           0 :          deallocate(snowage_rhos)
    5724           0 :          deallocate(snowage_Tgrd)
    5725           0 :          deallocate(snowage_T)
    5726           0 :          deallocate(snowage_tau)
    5727           0 :          deallocate(snowage_kappa)
    5728           0 :          deallocate(snowage_drdt0)
    5729             : 
    5730             :       endif
    5731             : 
    5732           0 :       end subroutine init_snowtable
    5733             : 
    5734             : !=======================================================================
    5735             : 
    5736             :       end module ice_forcing
    5737             : 
    5738             : !=======================================================================

Generated by: LCOV version 1.14-6-g40580cd