FMS  2025.04
Flexible Modeling System
amip_interp.F90
1 !***********************************************************************
2 !* Apache License 2.0
3 !*
4 !* This file is part of the GFDL Flexible Modeling System (FMS).
5 !*
6 !* Licensed under the Apache License, Version 2.0 (the "License");
7 !* you may not use this file except in compliance with the License.
8 !* You may obtain a copy of the License at
9 !*
10 !* http://www.apache.org/licenses/LICENSE-2.0
11 !*
12 !* FMS is distributed in the hope that it will be useful, but WITHOUT
13 !* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied;
14 !* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
15 !* PARTICULAR PURPOSE. See the License for the specific language
16 !* governing permissions and limitations under the License.
17 !***********************************************************************
18 !
19 !> @defgroup amip_interp_mod amip_interp_mod
20 !> @ingroup amip_interp
21 !> @brief Provides observed sea surface temperature and ice mask data sets that have been
22 !! interpolated onto your model's grid.
23 !!
24 !> @author Bruce Wyman
25 !!
26 !> When using these routines three possible data sets are available:
27 !!
28 !! 1. AMIP http://www.pcmdi.github.io/mips/amip from Jan 1979 to Jan 1989 (2 deg x 2 deg)
29 !! 2. Reynolds OI @ref amip_interp.rey_oi.txt from Nov 1981 to Jan 1999 (1 deg x 1 deg)
30 !! 3. Reynolds EOF podaac.jpl.nasa.gov/ from Jan 1950 to Dec 1998 (2 deg x 2 deg)
31 !!
32 !! All original data are observed monthly means. This module
33 !! interpolates linearly in time between pairs of monthly means.
34 !! Horizontal interpolation is done using the horiz_interp module.
35 !!
36 !! When a requested date falls outside the range of dates available
37 !! a namelist option allows for use of the climatological monthly
38 !! mean values which are computed from all of the data in a particular
39 !! data set. \n
40 !! \n AMIP 1:\n
41 !! from Jan 1979 to Jan 1989 (2 deg x 2 deg).\n\n
42 !! Reynolds OI:\n
43 !! from Nov 1981 to Jan 1999 (1 deg x 1 deg)\n
44 !! The analysis uses in situ and satellite SST's plus
45 !! SST's simulated by sea-ice cover.\n\n
46 !! Reynold's EOF:\n
47 !! from Jan 1950 to Dec 1998 (2 deg x 2 deg)\n
48 !! NCEP Reynolds Historical Reconstructed Sea Surface Temperature
49 !! The analysis uses both in-situ SSTs and satellite derived SSTs
50 !! from the NOAA Advanced Very High Resolution Radiometer.
51 !! In-situ data is used from 1950 to 1981, while both AVHRR derived
52 !! satellite SSTs and in-situ data are used from 1981 to the
53 !! end of 1998.
54 !!
55 !> @note The data set used by this module have been reformatted as 32-bit IEEE.
56 !! The data values are packed into 16-bit integers.
57 !!
58 !! The data sets are read from the following files:
59 !!
60 !! amip1 INPUT/amip1_sst.data
61 !! reynolds_io INPUT/reyoi_sst.data
62 !! reynolds_eof INPUT/reynolds_sst.data
63 !!
64 !> @var character(len=24) data_set
65 !! Name/type of SST data that will be used.
66 !! Possible values (case-insensitive) are:
67 !! 1) amip1
68 !! 2) reynolds_eof
69 !! 3) reynolds_oi
70 !! See the @ref amip_interp_oi page for more information
71 !! @var character(len=16) date_out_of_range
72 !! Controls the use of climatological monthly mean data when
73 !! the requested date falls outside the range of the data set.<BR/>
74 !! Possible values are:
75 !! <PRE>
76 !! fail - program will fail if requested date is prior
77 !! to or after the data set period.
78 !! initclimo - program uses climatological requested data is
79 !! prior to data set period and will fail if
80 !! requested date is after data set period.
81 !! climo - program uses climatological data anytime.
82 !! </PRE>
83 !! @var real tice_crit
84 !! Freezing point of sea water in degC or degK. Defaults to -1.80
85 !! @var integer verbose
86 !! Controls printed output, 0 <= verbose <= 3, default=0
87 !! additional parameters for controlling zonal prescribed sst ----
88 !! these parameters only have an effect when use_zonal=.true. ----
89 !! @var logical use_zonal
90 !! Flag to selected zonal sst or data set. Default=.false.
91 !! @var real teq
92 !! sst at the equator. Default=305
93 !! @var real tdif
94 !! Equator to pole sst difference. Default=50
95 !! @var real tann
96 !! Amplitude of annual cycle. Default=20
97 !! @var real tlag
98 !! Offset for time of year (for annual cycle). Default=0.875
99 !! @var integer amip_date
100 !! Single calendar date in integer "(year,month,day)" format
101 !! that is used only if set with year>0, month>0, day>0.
102 !! If used, model calendar date is replaced by this date,
103 !! but model time of day is still used to determine ice/sst.
104 !! Used for repeating-single-day (rsd) experiments.
105 !! Default=/-1,-1,-1/
106 !! @var real sst_pert
107 !! Temperature perturbation in degrees Kelvin added onto the SST.
108 !! The perturbation is globally-uniform (even near sea-ice).
109 !! It is only used when abs(sst_pert) > 1.e-4. SST perturbation runs
110 !! may be useful in accessing model sensitivities.
111 !! Default=0.
112 
113 !> @addtogroup amip_interp_mod
114 !> @{
115 module amip_interp_mod
116 
117 use time_interp_mod, only: time_interp, fraction_of_year
118 
119 use time_manager_mod, only: time_type, operator(+), operator(>), &
121 
122 ! add by JHC
123 use get_cal_time_mod, only: get_cal_time
124 
125 ! end add by JHC
126 
127 use horiz_interp_mod, only: horiz_interp_init, horiz_interp, &
129  horiz_interp_type, assignment(=)
130 
131 use fms_mod, only: error_mesg, write_version_number, &
132  note, warning, fatal, stdlog, check_nml_error, &
133  mpp_pe, lowercase, mpp_root_pe, &
134  note, mpp_error, fms_error_handler
135 
136 use constants_mod, only: tfreeze, pi
137 use platform_mod, only: r4_kind, r8_kind, i2_kind, fms_file_len
138 use mpp_mod, only: input_nml_file
139 use fms2_io_mod, only: fmsnetcdffile_t, fms2_io_file_exists=>file_exists, open_file, close_file, &
140  get_dimension_size, fms2_io_read_data=>read_data
141 use netcdf, only: nf90_max_name
142 
143 implicit none
144 private
145 
146 !-----------------------------------------------------------------------
147 !----------------- Public interfaces -----------------------------------
148 
150  & amip_interp_del, amip_interp_type, assignment(=)
151 
152 !-----------------------------------------------------------------------
153 !----------------- Public Data -----------------------------------
154 integer :: i_sst = 1200
155 integer :: j_sst = 600
156 real(r8_kind), parameter:: big_number = 1.e30_r8_kind
157 logical :: forecast_mode = .false.
158 
159 public i_sst, j_sst, forecast_mode, use_ncep_sst
160 
161 !-----------------------------------------------------------------------
162 !--------------------- private below here ------------------------------
163 
164 ! ---- version number -----
165 
166 ! Include variable "version" to be written to log file.
167 #include<file_version.h>
168 
169 ! add by JHC
170  real(r8_kind), allocatable, dimension(:,:) :: tempamip
171 ! end add by JHC
172 !-----------------------------------------------------------------------
173 !------ private defined data type --------
174 
175 !> @}
176 
177 !> @brief Private data type for representing a calendar date
178 !> @ingroup amip_interp_mod
180  sequence
181  integer :: year, month, day
182 end type
183 
184 !> Assignment overload to allow native assignment between amip_interp_type variables.
185 !> @ingroup amip_interp_mod
186 interface assignment(=)
187  module procedure amip_interp_type_eq
188 end interface
189 
190 !> Private logical equality overload for amip_interp_type
191 !> @ingroup amip_interp_mod
192 interface operator (==)
193  module procedure date_equals
194 end interface
195 
196 !> Private logical inequality overload for amip_interp_type
197 !> @ingroup amip_interp_mod
198 interface operator (/=)
199  module procedure date_not_equals
200 end interface
201 
202 !> Private logical greater than overload for amip_interp_type
203 !> @ingroup amip_interp_mod
204 interface operator (>)
205  module procedure date_gt
206 end interface
207 
208 !> Retrieve sea surface temperature data and interpolated grid
209 interface get_amip_sst
210  module procedure get_amip_sst_r4, get_amip_sst_r8
211 end interface
212 
213 !> AMIP interpolation for ice
214 interface get_amip_ice
215  module procedure get_amip_ice_r4, get_amip_ice_r8
216 end interface
217 
218 !> Initializes data needed for the horizontal
219 !! interpolation between the sst data and model grid.
220 !!
221 !> The returned variable of type amip_interp_type is needed when
222 !! calling get_amip_sst and get_amip_ice.
223 !!
224 !> @param lon
225 !! Longitude in radians of the model's grid box edges (1d lat/lon grid case)
226 !! or at grid box mid-point (2d case for arbitrary grids).
227 !> @param lat
228 !! Latitude in radians of the model's grid box edges (1d lat/lon grid case)
229 !! or at grid box mid-point (2d case for arbitrary grids).
230 !> @param mask
231 !! A mask for the model grid.
232 !> @param use_climo
233 !! Flag the specifies that monthly mean climatological values will be used.
234 !> @param use_annual
235 !! Flag the specifies that the annual mean climatological
236 !! will be used. If both use_annual = use_climo = true,
237 !! then use_annual = true will be used.
238 !> @param interp_method
239 !! specify the horiz_interp scheme. = "conservative" means conservative scheme,
240 !! = "bilinear" means bilinear interpolation.
241 !!
242 !> @return interp, a defined data type variable needed when calling get_amip_sst and get_amip_ice.
243 !!
244 !! \n Example usage:
245 !!
246 !! Interp = amip_interp_new ( lon, lat, mask, use_climo, use_annual, interp_method )
247 !!
248 !! This function may be called to initialize multiple variables
249 !! of type amip_interp_type. However, there currently is no
250 !! call to release the storage used by this variable.
251 !!
252 !! The size of input augment mask must be a function of the size
253 !! of input augments lon and lat. The first and second dimensions
254 !! of mask must equal (size(lon,1)-1, size(lat,2)-1).
255 !!
256 !> @throws "FATAL: the value of the namelist parameter DATA_SET being used is not allowed"
257 !! Check the value of namelist variable DATA_SET.
258 !!
259 !> @throws "FATAL: requested input data set does not exist"
260 !! The data set requested is valid but the data does not exist in
261 !! the INPUT subdirectory. You may have requested amip2 data which
262 !! has not been officially set up.
263 !! See the section on DATA SETS to properly set the data up.
264 !!
265 !> @throws "FATAL: use_climo mismatch"
266 !! The namelist variable date_out_of_range = 'fail' and the amip_interp_new
267 !! argument use_climo = true. This combination is not allowed.
268 !!
269 !> @throws "FATAL: use_annual(climo) mismatch"
270 !! The namelist variable date_out_of_range = 'fail' and the amip_interp_new
271 !! argument use_annual = true. This combination is not allowed.
272 !!
273 !> @ingroup amip_interp_mod
275  module procedure amip_interp_new_1d_r4, amip_interp_new_1d_r8
276  module procedure amip_interp_new_2d_r4, amip_interp_new_2d_r8
277 end interface
278 
279 !----- public data type ------
280 
281 !> @brief Contains information needed by the interpolation module (exchange_mod) and buffers
282 !! data (r4_kind flavor).
283 !> @ingroup amip_interp_mod
285  private
286  type (horiz_interp_type) :: Hintrp, Hintrp2 ! add by JHC
287  real(r4_kind), dimension(:,:), allocatable :: data1_r4, data2_r4
288  real(r8_kind), dimension(:,:), allocatable :: data1_r8, data2_r8
289  type (date_type) :: Date1, Date2
290  logical :: use_climo, use_annual
291  logical :: I_am_initialized=.false.
292 end type amip_interp_type
293 
294 !> @addtogroup amip_interp_mod
295 !> @{
296 !-----------------------------------------------------------------------
297 ! ---- resolution/grid variables ----
298 
299  integer :: mobs, nobs
300  real(r8_kind), allocatable, dimension(:) :: lon_bnd, lat_bnd
301 
302 ! ---- global unit & date ----
303 
304  integer :: iunit
305  character(len=FMS_FILE_LEN) :: file_name_sst, file_name_ice
306  type(FmsNetcdfFile_t), target :: fileobj_sst, fileobj_ice
307 
308  type (date_type) :: Curr_date = date_type( -99, -99, -99 )
309  type (date_type) :: Date_end = date_type( -99, -99, -99 )
310 
311  real(r8_kind) :: tice_crit_k
312  integer(i2_kind) :: ice_crit
313 
314  logical :: module_is_initialized = .false.
315 
316 !-----------------------------------------------------------------------
317 !---- namelist ----
318 
319  character(len=24) :: data_set = 'amip1' !< use 'amip1', 'amip2', 'reynolds_eof'
320  !! 'reynolds_oi', 'hurrell', or 'daily',
321  !! when "use_daily=.T."
322  ! add by JHC
323 
324  character(len=16) :: date_out_of_range = 'fail' !< use 'fail', 'initclimo', or 'climo'
325 
326  real(r8_kind) :: tice_crit = -1.80_r8_kind !< in degC or degK
327  integer :: verbose = 0 !< 0 <= verbose <= 3
328 
329  logical :: use_zonal = .false. !< parameters for prescribed zonal sst option
330  real(r8_kind) :: teq = 305._r8_kind !< parameters for prescribed zonal sst option
331  real(r8_kind) :: tdif = 50._r8_kind !< parameters for prescribed zonal sst option
332  real(r8_kind) :: tann = 20._r8_kind !< parameters for prescribed zonal sst option
333  real(r8_kind) :: tlag = 0.875_r8_kind !< parameters for prescribed zonal sst option
334 
335 
336  integer :: amip_date(3)=(/-1,-1,-1/) !< amip date for repeating single day (rsd) option
337 
338  real(r8_kind) :: sst_pert = 0._r8_kind !< global temperature perturbation used for sensitivity experiments
339 
340  character(len=6) :: sst_pert_type = 'fixed' !< use 'random' or 'fixed'
341  logical :: do_sst_pert = .false.
342  logical :: use_daily = .false. !< if '.true.', give 'data_set = 'daily''
343 
344  logical :: use_ncep_sst = .false. !< SJL: During nudging: use_ncep_sst = .T.; no_anom_sst = .T.
345  !! during forecast: use_ncep_sst = .T.; no_anom_sst = .F.
346  logical :: no_anom_sst = .true. !< SJL: During nudging: use_ncep_sst = .T.; no_anom_sst = .T.
347  !! during forecast: use_ncep_sst = .T.; no_anom_sst = .F.
348  logical :: use_ncep_ice = .false. !< For seasonal forecast: use_ncep_ice = .F.
349  logical :: interp_oi_sst = .false. !< changed to false for regular runs
350  logical :: use_mpp_io = .false. !< Set to .true. to use mpp_io, otherwise fms2io is used
351 
352  namelist /amip_interp_nml/ use_ncep_sst, no_anom_sst, use_ncep_ice, tice_crit, &
355  ! add by JHC
356  sst_pert, sst_pert_type, do_sst_pert, &
357  use_daily, &
358  ! end add by JHC
359  verbose, i_sst, j_sst, forecast_mode, &
360  use_mpp_io
361 
362 !-----------------------------------------------------------------------
363 
364 contains
365 
366  !> initialize @ref amip_interp_mod for use
367  subroutine amip_interp_init
368  integer :: iunit,io,ierr
369 
370 !-----------------------------------------------------------------------
371 
372  call horiz_interp_init
373 
374 ! ---- read namelist ----
375 
376  read (input_nml_file, amip_interp_nml, iostat=io)
377  ierr = check_nml_error(io,'amip_interp_nml')
378 
379 ! ----- write namelist/version info -----
380  call write_version_number("AMIP_INTERP_MOD", version)
381 
382  iunit = stdlog( )
383  if (mpp_pe() == 0) then
384  write (iunit,nml=amip_interp_nml)
385  endif
386 
387  if (use_mpp_io) then
388  !! USE_MPP_IO_WARNING
389  call mpp_error ('amip_interp_mod', &
390  'MPP_IO is no longer supported. Please remove use_mpp_io from amip_interp_nml',&
391  fatal)
392  endif
393  if ( .not. use_ncep_sst ) interp_oi_sst = .false.
394 
395 ! ---- freezing point of sea water in deg K ---
396 
397  tice_crit_k = tice_crit
398  if ( tice_crit_k < 200._r8_kind ) then
399  tice_crit_k = tice_crit_k + tfreeze
400  endif
401  ice_crit = nint((tice_crit_k-tfreeze)*100._r8_kind, i2_kind)
402 
403 ! ---- set up file dependent variable ----
404 ! ---- global file name ----
405 ! ---- grid box edges ----
406 ! ---- initialize zero size grid if not pe 0 ------
407 
408  if (lowercase(trim(data_set)) == 'amip1') then
409  file_name_sst = 'INPUT/' // 'amip1_sst.data'
410  file_name_ice = 'INPUT/' // 'amip1_sst.data'
411  mobs = 180; nobs = 91
412  call set_sst_grid_edges_amip1
413  if (mpp_pe() == 0) &
414  call error_mesg ('amip_interp_init', 'using AMIP 1 sst', note)
415  date_end = date_type( 1989, 1, 0 )
416  else if (lowercase(trim(data_set)) == 'amip2') then
417  file_name_sst = 'INPUT/' // 'amip2_sst.data'
418  file_name_ice = 'INPUT/' // 'amip2_ice.data'
419  mobs = 360; nobs = 180
420  call set_sst_grid_edges_oi
421 ! --- specfied min for amip2 ---
422  tice_crit_k = 271.38_r8_kind
423  if (mpp_pe() == 0) &
424  call error_mesg ('amip_interp_init', 'using AMIP 2 sst', note)
425  date_end = date_type( 1996, 3, 0 )
426  else if (lowercase(trim(data_set)) == 'hurrell') then
427  file_name_sst = 'INPUT/' // 'hurrell_sst.data'
428  file_name_ice = 'INPUT/' // 'hurrell_ice.data'
429  mobs = 360; nobs = 180
430  call set_sst_grid_edges_oi
431 ! --- specfied min for hurrell ---
432  tice_crit_k = 271.38_r8_kind
433  if (mpp_pe() == 0) &
434  call error_mesg ('amip_interp_init', 'using HURRELL sst', note)
435  date_end = date_type( 2011, 8, 16 ) ! updated by JHC
436 ! add by JHC
437  else if (lowercase(trim(data_set)) == 'daily') then
438  file_name_sst = 'INPUT/' // 'hurrell_sst.data'
439  file_name_ice = 'INPUT/' // 'hurrell_ice.data'
440  mobs = 360; nobs = 180
441  call set_sst_grid_edges_oi
442  if (mpp_pe() == 0) &
443  call error_mesg ('amip_interp_init', 'using AVHRR daily sst', note)
444  date_end = date_type( 2011, 8, 16 )
445 ! end add by JHC
446  else if (lowercase(trim(data_set)) == 'reynolds_eof') then
447  file_name_sst = 'INPUT/' // 'reynolds_sst.data'
448  file_name_ice = 'INPUT/' // 'reynolds_sst.data'
449  mobs = 180; nobs = 90
450  call set_sst_grid_edges_oi
451  if (mpp_pe() == 0) &
452  call error_mesg ('amip_interp_init', &
453  'using NCEP Reynolds Historical Reconstructed SST', note)
454  date_end = date_type( 1998, 12, 0 )
455  else if (lowercase(trim(data_set)) == 'reynolds_oi') then
456  file_name_sst = 'INPUT/' // 'reyoi_sst.data'
457  file_name_ice = 'INPUT/' // 'reyoi_sst.data'
458 !--- Added by SJL ----------------------------------------------
459  if ( use_ncep_sst ) then
460  mobs = i_sst; nobs = j_sst
461  else
462  mobs = 360; nobs = 180
463  endif
464 !--- Added by SJL ----------------------------------------------
465  call set_sst_grid_edges_oi
466  if (mpp_pe() == 0) &
467  call error_mesg ('amip_interp_init', 'using Reynolds OI SST', &
468  note)
469  date_end = date_type( 1999, 1, 0 )
470  else
471  call error_mesg ('amip_interp_init', 'the value of the &
472  &namelist parameter DATA_SET being used is not allowed', fatal)
473  endif
474 
475  if (verbose > 1 .and. mpp_pe() == 0) &
476  print *, 'ice_crit,tice_crit_k=',ice_crit,tice_crit_k
477 
478 ! --- check existence of sst data file ??? ---
479  file_name_sst = trim(file_name_sst)//'.nc'
480  file_name_ice = trim(file_name_ice)//'.nc'
481 
482  if (.not. fms2_io_file_exists(trim(file_name_sst)) ) then
483  call error_mesg ('amip_interp_init', &
484  'file '//trim(file_name_sst)//' does not exist', fatal)
485  endif
486  if (.not. fms2_io_file_exists(trim(file_name_ice)) ) then
487  call error_mesg ('amip_interp_init', &
488  'file '//trim(file_name_ice)//' does not exist', fatal)
489  endif
490 
491  if (.not. open_file(fileobj_sst, trim(file_name_sst), 'read')) &
492  call error_mesg ('amip_interp_init', 'Error in opening file '//trim(file_name_sst), fatal)
493  if (.not. open_file(fileobj_ice, trim(file_name_ice), 'read')) &
494  call error_mesg ('amip_interp_init', 'Error in opening file '//trim(file_name_ice), fatal)
495  module_is_initialized = .true.
496  end subroutine amip_interp_init
497 
498  subroutine set_sst_grid_edges_amip1
499  integer :: i, j
500  real(r8_kind) :: hpie, dlon, dlat, wb, sb
501 
502  allocate(lon_bnd(mobs+1))
503  allocate(lat_bnd(nobs+1))
504 
505 ! ---- compute grid edges (do only once) -----
506 
507  hpie = pi / 2._r8_kind
508 
509  dlon = 4._r8_kind*hpie/real(mobs, r8_kind)
510  wb = -0.5_r8_kind*dlon
511 
512  do i = 1, mobs+1
513  lon_bnd(i) = wb + dlon*real(i-1, r8_kind)
514  enddo
515  lon_bnd(mobs+1) = lon_bnd(1) + 4._r8_kind*hpie
516 
517  dlat = 2._r8_kind*hpie/real(nobs-1, r8_kind)
518  sb = -hpie + 0.5_r8_kind*dlat
519 
520  lat_bnd(1) = -hpie
521  lat_bnd(nobs+1) = hpie
522  do j = 2, nobs
523  lat_bnd(j) = sb + dlat * real(j-2, r8_kind)
524  enddo
525  end subroutine set_sst_grid_edges_amip1
526 
527  subroutine set_sst_grid_edges_oi
528  integer :: i, j
529  real(r8_kind) :: hpie, dlon, dlat, wb, sb
530 
531 ! add by JHC
532  if(allocated(lon_bnd)) deallocate(lon_bnd)
533  if(allocated(lat_bnd)) deallocate(lat_bnd)
534 ! end add by JHC
535 
536  allocate(lon_bnd(mobs+1))
537  allocate(lat_bnd(nobs+1))
538 
539 ! ---- compute grid edges (do only once) -----
540 
541  hpie = pi / 2._r8_kind
542  dlon = 4._r8_kind*hpie/real(mobs, r8_kind)
543  wb = 0.0_r8_kind
544 
545  lon_bnd(1) = wb
546  do i = 2, mobs+1
547  lon_bnd(i) = wb + dlon * real(i-1, r8_kind)
548  enddo
549  lon_bnd(mobs+1) = lon_bnd(1) + 4._r8_kind*hpie
550 
551  dlat = 2._r8_kind*hpie/real(nobs, r8_kind)
552  sb = -hpie
553 
554  lat_bnd(1) = sb
555  lat_bnd(nobs+1) = hpie
556  do j = 2, nobs
557  lat_bnd(j) = sb + dlat * real(j-1, r8_kind)
558  enddo
559  end subroutine set_sst_grid_edges_oi
560 
561 !> Frees data associated with a amip_interp_type variable. Should be used for any
562 !! variables initialized via @ref amip_interp_new.
563 !> @param[inout] Interp A defined data type variable initialized by amip_interp_new and used
564 !! when calling get_amip_sst and get_amip_ice.
565  subroutine amip_interp_del (Interp)
566  type (amip_interp_type), intent(inout) :: interp
567 
568  if(allocated(interp%data1_r4)) deallocate(interp%data1_r4)
569  if(allocated(interp%data1_r8)) deallocate(interp%data1_r8)
570  if(allocated(interp%data2_r4)) deallocate(interp%data2_r4)
571  if(allocated(interp%data2_r8)) deallocate(interp%data2_r8)
572 
573  if(allocated(lon_bnd)) deallocate(lon_bnd)
574  if(allocated(lat_bnd)) deallocate(lat_bnd)
575 
576  call horiz_interp_del ( interp%Hintrp )
577 
578  interp%I_am_initialized = .false.
579  end subroutine amip_interp_del
580 
581 !> @brief Returns the size (i.e., number of longitude and latitude
582 !! points) of the observed data grid.
583 !! @throws FATAL have not called amip_interp_new
584 !! Must call amip_interp_new before get_sst_grid_size.
585  subroutine get_sst_grid_size (nlon, nlat)
586  integer, intent(out) :: nlon !> The number of longitude points (first dimension) in the
587  !! observed data grid. For AMIP 1 nlon = 180, and the Reynolds nlon = 360.
588  integer, intent(out) :: nlat !> The number of latitude points (second dimension) in the
589  !! observed data grid. For AMIP 1 nlon = 91, and the Reynolds nlon = 180.
590 
591  if ( .not.module_is_initialized ) call amip_interp_init
592 
593  nlon = mobs; nlat = nobs
594  end subroutine get_sst_grid_size
595 
596 !> @return logical answer
597 function date_equals (Left, Right) result (answer)
598 type (date_type), intent(in) :: left, right
599 logical :: answer
600 
601  if (left % year == right % year .and. &
602  left % month == right % month .and. &
603  left % day == right % day ) then
604  answer = .true.
605  else
606  answer = .false.
607  endif
608 end function date_equals
609 
610 !> @return logical answer
611 function date_not_equals (Left, Right) result (answer)
612 type (date_type), intent(in) :: left, right
613 logical :: answer
614 
615  if (left % year == right % year .and. &
616  left % month == right % month .and. &
617  left % day == right % day ) then
618  answer = .false.
619  else
620  answer = .true.
621  endif
622 end function date_not_equals
623 
624 !> @return logical answer
625 function date_gt (Left, Right) result (answer)
626 type (date_type), intent(in) :: left, right
627 logical :: answer
628 integer :: i, dif(3)
629 
630  dif(1) = left%year - right%year
631  dif(2) = left%month - right%month
632  dif(3) = left%day - right%day
633  answer = .false.
634  do i = 1, 3
635  if (dif(i) == 0) cycle
636  if (dif(i) < 0) exit
637  if (dif(i) > 0) then
638  answer = .true.
639  exit
640  endif
641  enddo
642 end function date_gt
643 
644 subroutine amip_interp_type_eq (amip_interp_out, amip_interp_in)
645  type(amip_interp_type), intent(inout) :: amip_interp_out
646  type(amip_interp_type), intent(in) :: amip_interp_in
647 
648  if(.not.amip_interp_in%I_am_initialized) then
649  call mpp_error(fatal,'amip_interp_type_eq: amip_interp_type variable on right hand side is unassigned')
650  endif
651 
652  amip_interp_out%Hintrp = amip_interp_in%Hintrp
653  amip_interp_out%Hintrp2 = amip_interp_in%Hintrp2 !< missing assignment statement; added by GPP
654  amip_interp_out%data1_r4 = amip_interp_in%data1_r4
655  amip_interp_out%data1_r8 = amip_interp_in%data1_r8
656  amip_interp_out%data2_r4 = amip_interp_in%data2_r4
657  amip_interp_out%data2_r8 = amip_interp_in%data2_r8
658  amip_interp_out%Date1 = amip_interp_in%Date1
659  amip_interp_out%Date2 = amip_interp_in%Date2
660  amip_interp_out%Date1 = amip_interp_in%Date1
661  amip_interp_out%Date2 = amip_interp_in%Date2
662  amip_interp_out%use_climo = amip_interp_in%use_climo
663  amip_interp_out%use_annual = amip_interp_in%use_annual
664  amip_interp_out%I_am_initialized = .true.
665 end subroutine amip_interp_type_eq
666 
667 #include "amip_interp_r4.fh"
668 #include "amip_interp_r8.fh"
669 
670 end module amip_interp_mod
671 !> @}
672 ! <INFO>
673 
674 ! <FUTURE>
675 ! Add AMIP 2 data set.
676 !
677 ! Other data sets (or extend current data sets).
678 ! </FUTURE>
679 
680 ! </INFO>
real(r8_kind) tice_crit
in degC or degK
character(len=24) data_set
use 'amip1', 'amip2', 'reynolds_eof' 'reynolds_oi', 'hurrell', or 'daily', when "use_daily=....
real(r8_kind) teq
parameters for prescribed zonal sst option
logical function date_not_equals(Left, Right)
logical interp_oi_sst
changed to false for regular runs
subroutine, public amip_interp_init
initialize amip_interp_mod for use
logical use_mpp_io
Set to .true. to use mpp_io, otherwise fms2io is used.
real(r8_kind) tann
parameters for prescribed zonal sst option
logical no_anom_sst
SJL: During nudging: use_ncep_sst = .T.; no_anom_sst = .T. during forecast: use_ncep_sst = ....
logical use_ncep_ice
For seasonal forecast: use_ncep_ice = .F.
logical function date_equals(Left, Right)
real(r8_kind) sst_pert
global temperature perturbation used for sensitivity experiments
integer verbose
0 <= verbose <= 3
character(len=16) date_out_of_range
use 'fail', 'initclimo', or 'climo'
subroutine, public amip_interp_del(Interp)
Frees data associated with a amip_interp_type variable. Should be used for any variables initialized ...
logical, public use_ncep_sst
SJL: During nudging: use_ncep_sst = .T.; no_anom_sst = .T. during forecast: use_ncep_sst = ....
real(r8_kind) tlag
parameters for prescribed zonal sst option
integer, dimension(3) amip_date
amip date for repeating single day (rsd) option
logical use_zonal
parameters for prescribed zonal sst option
logical use_daily
if '.true.', give 'data_set = 'daily''
logical function date_gt(Left, Right)
subroutine get_sst_grid_size(nlon, nlat)
Returns the size (i.e., number of longitude and latitude points) of the observed data grid.
subroutine amip_interp_type_eq(amip_interp_out, amip_interp_in)
character(len=6) sst_pert_type
use 'random' or 'fixed'
real(r8_kind) tdif
parameters for prescribed zonal sst option
Initializes data needed for the horizontal interpolation between the sst data and model grid.
Contains information needed by the interpolation module (exchange_mod) and buffers data (r4_kind flav...
Private data type for representing a calendar date.
Close a netcdf or domain file opened with open_file or open_virtual_file.
Definition: fms2_io.F90:165
Opens a given netcdf or domain file.
Definition: fms2_io.F90:121
Read data from a defined field in a file.
Definition: fms2_io.F90:291
integer function, public check_nml_error(IOSTAT, NML_NAME)
Checks the iostat argument that is returned after reading a namelist and determines if the error code...
Definition: fms.F90:523
subroutine, public write_version_number(version, tag, unit)
Prints to the log file (or a specified unit) the version id string and tag name.
Definition: fms.F90:701
logical function, public fms_error_handler(routine, message, err_msg)
Facilitates the control of fatal error conditions.
Definition: fms.F90:468
subroutine, public error_mesg(routine, message, level)
Print notes, warnings and error messages; terminates program for warning and error messages....
Definition: fms.F90:441
Added for mixed precision support. Updates force time_manager math to be done with kind=8 reals _wrap...
subroutine, public horiz_interp_del(Interp)
Deallocates memory used by "horiz_interp_type" variables. Must be called before reinitializing with h...
subroutine, public horiz_interp_init
Initialize module and writes version number to logfile.out.
Subroutine for performing the horizontal interpolation between two grids.
integer function stdlog()
This function returns the current standard fortran unit numbers for log messages. Log messages,...
Definition: mpp_util.inc:58
integer function mpp_pe()
Returns processor ID.
Definition: mpp_util.inc:406
Error handler.
Definition: mpp.F90:381
real(r8_kind) function, public fraction_of_year(Time)
Wrapper function to return the fractional time into the current year Always returns an r8_kind,...
Returns a weight and dates or indices for interpolating between two dates. The interface fraction_of_...
subroutine, public get_date(time, year, month, day, hour, minute, second, tick, err_msg)
Gets the date for different calendar types. Given a time_interval, returns the corresponding date und...
Given an input date in year, month, days, etc., creates a time_type that represents this time interva...
Given some number of seconds and days, returns the corresponding time_type.
Type to represent amounts of time. Implemented as seconds and days to allow for larger intervals.
AMIP interpolation for ice.
Retrieve sea surface temperature data and interpolated grid.
Allocates space and initializes a derived-type variable that contains pre-computed interpolation indi...