FV3 Bundle
amip_interp.F90
Go to the documentation of this file.
1 !***********************************************************************
2 !* GNU Lesser General Public License
3 !*
4 !* This file is part of the GFDL Flexible Modeling System (FMS).
5 !*
6 !* FMS is free software: you can redistribute it and/or modify it under
7 !* the terms of the GNU Lesser General Public License as published by
8 !* the Free Software Foundation, either version 3 of the License, or (at
9 !* your option) any later version.
10 !*
11 !* FMS is distributed in the hope that it will be useful, but WITHOUT
12 !* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 !* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 !* for more details.
15 !*
16 !* You should have received a copy of the GNU Lesser General Public
17 !* License along with FMS. If not, see <http://www.gnu.org/licenses/>.
18 !***********************************************************************
19 
20 
22 
23 
24 ! <CONTACT EMAIL="Bruce.Wyman@noaa.gov">
25 ! Bruce Wyman
26 ! </CONTACT>
27 
28 ! <HISTORY SRC="http://www.gfdl.noaa.gov/fms-cgi-bin/cvsweb.cgi/FMS/"/>
29 
30 ! <OVERVIEW>
31 ! Provides observed SST and ice mask data sets that have been
32 ! interpolated onto your model's grid.
33 ! </OVERVIEW>
34 
35 ! <DESCRIPTION>
36 ! Three possible data sets are available:
37 !
38 ! 1) <LINK SRC="http://www-pcmdi.llnl.gov/amip">AMIP 1</LINK> from Jan 1979 to Jan 1989 (2 deg x 2 deg)<BR/>
39 ! 2) <LINK SRC="amip_interp.rey_oi.txt">Reynolds OI</LINK> from Nov 1981 to Jan 1999 (1 deg x 1 deg)<BR/>
40 ! 3) <LINK SRC="ftp://podaac.jpl.nasa.gov/pub/sea_surface_temperature/reynolds/rsst/doc/rsst.html">Reynolds EOF</LINK> from Jan 1950 to Dec 1998 (2 deg x 2 deg)<BR/><BR/>
41 !
42 ! All original data are observed monthly means. This module
43 ! interpolates linearly in time between pairs of monthly means.
44 ! Horizontal interpolation is done using the horiz_interp module.
45 !
46 ! When a requested date falls outside the range of dates available
47 ! a namelist option allows for use of the climatological monthly
48 ! mean values which are computed from all of the data in a particular
49 ! data set.
50 ! </DESCRIPTION>
51 
52 ! <DATASET NAME="AMIP 1">
53 ! from Jan 1979 to Jan 1989 (2 deg x 2 deg).
54 ! </DATASET>
55 ! <DATASET NAME="Reynolds OI">
56 ! from Nov 1981 to Jan 1999 (1 deg x 1 deg)
57 ! The analysis uses in situ and satellite SST's plus
58 ! SST's simulated by sea-ice cover.
59 ! </DATASET>
60 ! <DATASET NAME="Reynolds EOF">
61 ! from Jan 1950 to Dec 1998 (2 deg x 2 deg)
62 ! NCEP Reynolds Historical Reconstructed Sea Surface Temperature
63 ! The analysis uses both in-situ SSTs and satellite derived SSTs
64 ! from the NOAA Advanced Very High Resolution Radiometer.
65 ! In-situ data is used from 1950 to 1981, while both AVHRR derived
66 ! satellite SSTs and in-situ data are used from 1981 to the
67 ! end of 1998.
68 !
69 ! Note: The data set used by this module have been reformatted as 32-bit IEEE.
70 ! The data values are packed into 16-bit integers.
71 !
72 ! The data sets are read from the following files:
73 !
74 ! amip1 INPUT/amip1_sst.data
75 ! reynolds_io INPUT/reyoi_sst.data
76 ! reynolds_eof INPUT/reynolds_sst.data
77 ! </DATASET>
78 !-----------------------------------------------------------------------
79 
81 
82 use time_manager_mod, only: time_type, operator(+), operator(>), &
84 
85 ! add by JHC
87 use mpp_io_mod, only : mpp_open, mpp_read, mpp_rdonly, mpp_netcdf, &
88  mpp_multi, mpp_single, mpp_close, mpp_get_times
89 ! end add by JHC
90 
93  horiz_interp_type, assignment(=)
94 
95 use fms_mod, only: file_exist, error_mesg, write_version_number, &
96  note, warning, fatal, stdlog, check_nml_error, &
97  open_namelist_file, open_ieee32_file, &
98  mpp_pe, close_file, lowercase, mpp_root_pe, &
100 use fms_io_mod, only: read_data, field_size ! add by JHC
101 use constants_mod, only: tfreeze, pi
102 use platform_mod, only: r4_kind, i2_kind
103 use mpp_mod, only: input_nml_file
104 
105 implicit none
106 private
107 
108 !-----------------------------------------------------------------------
109 !----------------- Public interfaces -----------------------------------
110 
112  amip_interp_del, amip_interp_type, assignment(=)
113 
114 !-----------------------------------------------------------------------
115 !----------------- Public Data -----------------------------------
116 integer :: i_sst = 1200
117 integer :: j_sst = 600
118 real, parameter:: big_number = 1.e30
119 logical :: forecast_mode = .false.
120 real, allocatable, dimension(:,:) :: sst_ncep, sst_anom
121 
123 
124 !-----------------------------------------------------------------------
125 !--------------------- private below here ------------------------------
126 
127 ! ---- version number -----
128 
129 ! Include variable "version" to be written to log file.
130 #include<file_version.h>
131 
132  real, allocatable:: temp1(:,:), temp2(:,:)
133 ! add by JHC
134  real, allocatable, dimension(:,:) :: tempamip
135 ! end add by JHC
136 !-----------------------------------------------------------------------
137 !------ private defined data type --------
138 
140  sequence
141  integer :: year, month, day
142 end type
143 
144 interface assignment(=)
145  module procedure amip_interp_type_eq
146 end interface
147 
148 interface operator (==)
149  module procedure date_equals
150 end interface
151 
152 interface operator (/=)
153  module procedure date_not_equals
154 end interface
155 
156 interface operator (>)
157  module procedure date_gt
158 end interface
159 
160 ! <INTERFACE NAME="amip_interp_new">
161 ! <OVERVIEW>
162 ! Function that initializes data needed for the horizontal
163 ! interpolation between the sst grid and model grid. The
164 ! returned variable of type amip_interp_type is needed when
165 ! calling get_amip_sst and get_amip_ice.
166 ! </OVERVIEW>
167 ! <DESCRIPTION>
168 ! Function that initializes data needed for the horizontal
169 ! interpolation between the sst grid and model grid. The
170 ! returned variable of type amip_interp_type is needed when
171 ! calling get_amip_sst and get_amip_ice.
172 ! </DESCRIPTION>
173 ! <IN NAME="lon">
174 ! Longitude in radians of the model's grid box edges (1d lat/lon grid case)
175 ! or at grid box mid-point (2d case for arbitrary grids).
176 ! </IN>
177 ! <IN NAME="lat">
178 ! Latitude in radians of the model's grid box edges (1d lat/lon grid case)
179 ! or at grid box mid-point (2d case for arbitrary grids).
180 ! </IN>
181 ! <IN NAME="mask">
182 ! A mask for the model grid.
183 ! </IN>
184 ! <IN NAME="use_climo">
185 ! Flag the specifies that monthly mean climatological values will be used.
186 ! </IN>
187 ! <IN NAME="use_annual">
188 ! Flag the specifies that the annual mean climatological
189 ! will be used. If both use_annual = use_climo = true,
190 ! then use_annual = true will be used.
191 ! </IN>
192 ! <IN NAME="interp_method">
193 ! specify the horiz_interp scheme. = "conservative" means conservative scheme,
194 ! = "bilinear" means bilinear interpolation.
195 ! </IN>
196 ! <OUT NAME="Interp">
197 ! A defined data type variable needed when calling get_amip_sst and get_amip_ice.
198 ! </OUT>
199 ! <TEMPLATE>
200 ! Interp = amip_interp_new ( lon, lat, mask, use_climo, use_annual, interp_method )
201 ! </TEMPLATE>
202 
203 ! <NOTE>
204 ! This function may be called to initialize multiple variables
205 ! of type amip_interp_type. However, there currently is no
206 ! call to release the storage used by this variable.
207 ! </NOTE>
208 ! <NOTE>
209 ! The size of input augment mask must be a function of the size
210 ! of input augments lon and lat. The first and second dimensions
211 ! of mask must equal (size(lon,1)-1, size(lat,2)-1).
212 ! </NOTE>
213 
214 ! <ERROR MSG="the value of the namelist parameter DATA_SET being used is not allowed" STATUS="FATAL">
215 ! Check the value of namelist variable DATA_SET.
216 ! </ERROR>
217 ! <ERROR MSG="requested input data set does not exist" STATUS="FATAL">
218 ! The data set requested is valid but the data does not exist in
219 ! the INPUT subdirectory. You may have requested amip2 data which
220 ! has not been officially set up.
221 ! See the section on DATA SETS to properly set the data up.
222 ! </ERROR>
223 ! <ERROR MSG="use_climo mismatch" STATUS="FATAL">
224 ! The namelist variable date_out_of_range = 'fail' and the amip_interp_new
225 ! argument use_climo = true. This combination is not allowed.
226 ! </ERROR>
227 ! <ERROR MSG="use_annual(climo) mismatch" STATUS="FATAL">
228 ! The namelist variable date_out_of_range = 'fail' and the amip_interp_new
229 ! argument use_annual = true. This combination is not allowed.
230 ! </ERROR>
232  module procedure amip_interp_new_1d
233  module procedure amip_interp_new_2d
234 end interface
235 ! </INTERFACE>
236 
237 
238 !-----------------------------------------------------------------------
239 !----- public data type ------
240 ! <DATA NAME="amip_interp_type" TYPE="type (horiz_interp_type)" >
241 ! All variables in this data type are PRIVATE. It contains information
242 ! needed by the interpolation module (exchange_mod) and buffers data.
243 ! </DATA>
245  private
246  type(horiz_interp_type) :: hintrp, hintrp2 ! add by JHC
247  real, pointer :: data1(:,:) =>null(), &
248  data2(:,:) =>null()
249  type(date_type) :: date1, date2
250  logical :: use_climo, use_annual
251  logical :: i_am_initialized=.false.
252 end type
253 
254 !-----------------------------------------------------------------------
255 ! ---- resolution/grid variables ----
256 
257  integer :: mobs, nobs
258  real, allocatable :: lon_bnd(:), lat_bnd(:)
259 
260 ! ---- global unit & date ----
261 
262  integer, parameter :: maxc = 128
263  integer :: unit
264  character(len=maxc) :: file_name_sst, file_name_ice
265 
266  type(date_type) :: curr_date = date_type( -99, -99, -99 )
267  type(date_type) :: date_end = date_type( -99, -99, -99 )
268 
269  real :: tice_crit_k
270  integer(I2_KIND) :: ice_crit
271 
272  logical :: module_is_initialized = .false.
273 
274 !-----------------------------------------------------------------------
275 !---- namelist ----
276 
277 ! <NAMELIST NAME="amip_interp_nml">
278 ! <DATA NAME="data_set" TYPE="character(len=24)" DEFAULT="data_set = 'amip1'">
279 ! Name/type of SST data that will be used.
280 ! <BR/>
281 ! Possible values (case-insensitive) are: <BR/>
282 ! 1) amip1<BR/>
283 ! 2) reynolds_eof<BR/>
284 ! 3) reynolds_oi<BR/>
285 ! See the <LINK SRC="amip_interp.html#DATA SETS">data set </LINK>section for more on these data.
286 ! </DATA>
287 
288 ! <DATA NAME="date_out_of_range" TYPE="character(len=16)" DEFAULT="date_out_of_range = 'fail'">
289 ! Controls the use of climatological monthly mean data when
290 ! the requested date falls outside the range of the data set.<BR/>
291 ! Possible values are:
292 ! <PRE>
293 ! fail - program will fail if requested date is prior
294 ! to or after the data set period.
295 ! initclimo - program uses climatological requested data is
296 ! prior to data set period and will fail if
297 ! requested date is after data set period.
298 ! climo - program uses climatological data anytime.
299 ! </PRE>
300 ! </DATA>
301 
302 ! <DATA NAME="tice_crit" TYPE="real" DEFAULT="tice_crit = -1.80">
303 ! Freezing point of sea water in degC or degK.
304 ! </DATA>
305 ! <DATA NAME="verbose" TYPE="integer" DEFAULT="verbose = 0">
306 ! Controls printed output, 0 <= verbose <= 3
307 ! </DATA>
308 
309 !---- additional parameters for controlling zonal prescribed sst ----
310 !---- these parameters only have an effect when use_zonal=.true. ----
311 ! <DATA NAME="use_zonal" TYPE="logical" DEFAULT=".false.">
312 ! Flag to selected zonal sst or data set.
313 ! </DATA>
314 ! <DATA NAME="teq" TYPE="real" DEFAULT="teq=305.">
315 ! sst at the equator.
316 ! </DATA>
317 ! <DATA NAME="tdif" TYPE="real" DEFAULT="tdif=50.">
318 ! Equator to pole sst difference.
319 ! </DATA>
320 ! <DATA NAME="tann" TYPE="real" DEFAULT="tann=20.">
321 ! Amplitude of annual cycle.
322 ! </DATA>
323 ! <DATA NAME="tlag" TYPE="real" DEFAULT="tlag=0.875">
324 ! Offset for time of year (for annual cycle).
325 ! </DATA>
326 
327 ! <DATA NAME="amip_date" TYPE="integer(3)" DEFAULT="/-1,-1,-1/">
328 ! Single calendar date in integer "(year,month,day)" format
329 ! that is used only if set with year>0, month>0, day>0.
330 ! If used, model calendar date is replaced by this date,
331 ! but model time of day is still used to determine ice/sst.
332 ! Used for repeating-single-day (rsd) experiments.
333 ! </DATA>
334 
335 ! <DATA NAME="sst_pert" TYPE="real" DEFAULT="sst_pert=0.">
336 ! Temperature perturbation in degrees Kelvin added onto the SST.
337 ! The perturbation is globally-uniform (even near sea-ice).
338 ! It is only used when abs(sst_pert) > 1.e-4. SST perturbation runs
339 ! may be useful in accessing model sensitivities.
340 ! </DATA>
341  character(len=24) :: data_set = 'amip1' ! use 'amip1'
342  ! 'amip2'
343  ! 'reynolds_eof'
344  ! 'reynolds_oi'
345  ! 'hurrell'
346  ! add by JHC:
347  ! 'daily', when "use_daily=.T."
348 
349  character(len=16) :: date_out_of_range = 'fail' ! use 'fail'
350  ! 'initclimo'
351  ! 'climo'
352 
353  real :: tice_crit = -1.80 ! in degC or degK
354  integer :: verbose = 0 ! 0 <= verbose <= 3
355 
356 !parameters for prescribed zonal sst option
357  logical :: use_zonal = .false.
358  real :: teq = 305.
359  real :: tdif = 50.
360  real :: tann = 20.
361  real :: tlag = 0.875
362 
363 
364 !amip date for repeating single day (rsd) option
365  integer :: amip_date(3)=(/-1,-1,-1/)
366 
367 !global temperature perturbation used for sensitivity experiments
368  real :: sst_pert = 0.
369 
370 ! add by JHC
371  character(len=6) :: sst_pert_type = 'fixed' ! use 'random' or 'fixed'
372  logical :: do_sst_pert = .false.
373  logical :: use_daily = .false. ! if '.true.', give 'data_set = 'daily''
374 ! end add by JHC
375 
376 ! SJL: During nudging: use_ncep_sst = .T.; no_anom_sst = .T.
377 ! during forecast: use_ncep_sst = .T.; no_anom_sst = .F.
378 ! For seasonal forecast: use_ncep_ice = .F.
379 
380  logical :: use_ncep_sst = .false.
381  logical :: no_anom_sst = .true.
382  logical :: use_ncep_ice = .false.
383  logical :: interp_oi_sst = .false. ! changed to false for regular runs
384 
385  namelist /amip_interp_nml/ use_ncep_sst, no_anom_sst, use_ncep_ice, tice_crit, &
388  ! add by JHC
390  use_daily, &
391  ! end add by JHC
393 ! </NAMELIST>
394 
395 
396 !-----------------------------------------------------------------------
397 
398 contains
399 
400 !#######################################################################
401 ! <SUBROUTINE NAME="get_amip_sst" INTERFACE="get_amip_sst">
402 ! <IN NAME="Time" TYPE="time_type" ></IN>
403 ! <OUT NAME="sst" TYPE="real" DIM="(:,:)"> </OUT>
404 ! <INOUT NAME="Interp" TYPE="amip_interp_type"> </INOUT>
405 ! </SUBROUTINE>
406 
407 ! modified by JHC
408 subroutine get_amip_sst (Time, Interp, sst, err_msg, lon_model, lat_model)
409 !subroutine get_amip_sst (Time, Interp, sst, err_msg)
410 
411  type(time_type), intent(in) :: time
412  type(amip_interp_type), intent(inout) :: interp
413  real, intent(out) :: sst(:,:)
414  character(len=*), optional, intent(out) :: err_msg
415 
416  real, dimension(mobs,nobs) :: sice
417 
418  integer :: year1, year2, month1, month2
419  real :: fmonth
420  type(date_type) :: date1, date2, udate1, udate2
421 
422  type(time_type) :: amip_time
423  integer :: tod(3),dum(3)
424 
425 ! add by JHC
426  real, intent(in), dimension(:,:), optional :: lon_model, lat_model
427  real :: pert
428  integer :: i, j, mobs_sst, nobs_sst
429  integer :: jhctod(6)
430  type(time_type) :: udate
431  character(len=4) :: yyyy
432  integer :: nrecords, ierr, k, yr, mo, dy
433  integer :: siz(4)
434  integer, dimension(:), allocatable :: ryr, rmo, rdy
435  character(len=30) :: time_unit
436  real, dimension(:), allocatable :: timeval
437  character(len=maxc) :: ncfilename
438 ! end add by JHC
439 
440 
441  if(present(err_msg)) err_msg = ''
442  if(.not.interp%I_am_initialized) then
443  if(fms_error_handler('get_amip_sst','The amip_interp_type variable is not initialized',err_msg)) return
444  endif
445 
446 !-----------------------------------------------------------------------
447 !----- compute zonally symetric sst ---------------
448 
449  if ( use_ncep_sst .and. forecast_mode ) no_anom_sst = .false.
450 
451  if (all(amip_date>0)) then
452  call get_date(time,dum(1),dum(2),dum(3),tod(1),tod(2),tod(3))
453  amip_time = set_date(amip_date(1),amip_date(2),amip_date(3),tod(1),tod(2),tod(3))
454  else
455  amip_time = time
456  endif
457 
458 ! add by JHC
459 if ( .not.use_daily ) then
460 ! end add by JHC
461 
462  if ( .not. allocated(temp1) ) allocate (temp1(mobs,nobs))
463  if ( .not. allocated(temp2) ) allocate (temp2(mobs,nobs))
464 
465  if (use_zonal) then
466  call zonal_sst (amip_time, sice, temp1)
467  call horiz_interp ( interp%Hintrp, temp1, sst )
468  else
469 
470 !-----------------------------------------------------------------------
471 !---------- get new observed sea surface temperature -------------------
472 
473 ! ---- time interpolation for months -----
474  call time_interp (amip_time, fmonth, year1, year2, month1, month2)
475 ! ---- force climatology ----
476  if (interp % use_climo) then
477  year1=0; year2=0
478  endif
479  if (interp % use_annual) then
480  year1=0; year2=0
481  month1=0; month2=0
482  endif
483 ! ---------------------------
484 
485  date1 = date_type( year1, month1, 0 )
486  date2 = date_type( year2, month2, 0 )
487 
488 ! -- open/rewind file --
489  unit = -1
490 !-----------------------------------------------------------------------
491 
492 
493  if (date1 /= interp % Date1) then
494 ! ---- use Date2 for Date1 ----
495  if (date1 == interp % Date2) then
496  interp % Date1 = interp % Date2
497  interp % data1 = interp % data2
498  temp1(:,:) = temp2(:,:) ! SJL BUG fix: June 24, 2011
499  else
500  call read_record ('sst', date1, udate1, temp1)
501  if ( use_ncep_sst .and. (.not. no_anom_sst) ) then
502  temp1(:,:) = temp1(:,:) + sst_anom(:,:)
503  endif
504  call horiz_interp ( interp%Hintrp, temp1, interp%data1 )
505  call clip_data ('sst', interp%data1)
506  interp % Date1 = date1
507  endif
508  endif
509 
510 !-----------------------------------------------------------------------
511 
512  if (date2 /= interp % Date2) then
513  call read_record ('sst', date2, udate2, temp2)
514  if ( use_ncep_sst .and. (.not. no_anom_sst) ) then
515  temp2(:,:) = temp2(:,:) + sst_anom(:,:)
516  endif
517  call horiz_interp ( interp%Hintrp, temp2, interp%data2 )
518  call clip_data ('sst', interp%data2)
519  interp % Date2 = date2
520  endif
521 
522 ! ---- if the unit was opened, close it and print dates ----
523 
524  if (unit /= -1) then
525  call close_file (unit)
526  if (verbose > 0 .and. mpp_pe() == 0) &
527  call print_dates (amip_time, &
528  interp % Date1, udate1, &
529  interp % Date2, udate2, fmonth)
530  endif
531 
532 !-----------------------------------------------------------------------
533 !---------- time interpolation (between months) of sst's ---------------
534 !-----------------------------------------------------------------------
535  sst = interp % data1 + fmonth * (interp % data2 - interp % data1)
536 
537 !-------------------------------------------------------------------------------
538 ! SJL mods for NWP and TCSF ---
539 ! Nudging runs: (Note: NCEP SST updated only every 6-hr)
540 ! Compute SST anomaly from global SST datasets for subsequent forecast runs
541 !-------------------------------------------------------------------------------
542  if ( use_ncep_sst .and. no_anom_sst ) then
543  sst_anom(:,:) = sst_ncep(:,:) - (temp1(:,:) + fmonth*(temp2(:,:) - temp1(:,:)) )
544  call horiz_interp ( interp%Hintrp, sst_ncep, sst )
545  call clip_data ('sst', sst)
546  endif
547 
548 !!! DEBUG CODE
549 ! call get_date(Amip_Time,jhctod(1),jhctod(2),jhctod(3),jhctod(4),jhctod(5),jhctod(6))
550 ! if (mpp_pe() == 0) then
551 ! write (*,200) 'JHC: use_daily = F, AMIP_Time: ',jhctod(1),jhctod(2),jhctod(3),jhctod(4),jhctod(5),jhctod(6)
552 ! write (*,300) 'JHC: use_daily = F, interped SST: ', sst(1,1),sst(5,5),sst(10,10)
553 ! endif
554 !!! END DEBUG CODE
555 
556 
557  endif
558 
559 ! add by JHC
560 else
561  call get_date(amip_time,jhctod(1),jhctod(2),jhctod(3),jhctod(4),jhctod(5),jhctod(6))
562  if (mpp_pe() == mpp_root_pe()) write(*,200) 'amip_interp_mod: use_daily = T, Amip_Time = ',jhctod(1),jhctod(2),jhctod(3),jhctod(4),jhctod(5),jhctod(6)
563 
564  yr = jhctod(1); mo = jhctod(2); dy = jhctod(3)
565 
566  write (yyyy,'(i4)') jhctod(1)
567 
568  file_name_sst = 'INPUT/' // 'sst.day.mean.'//yyyy//'.v2.nc'
569  ncfilename = trim(file_name_sst)
570  time_unit = 'days since 1978-01-01 00:00:00'
571 
572  mobs_sst = 1440; nobs_sst = 720
573 
574  call set_sst_grid_edges_daily(mobs_sst, nobs_sst)
575  call horiz_interp_new ( interp%Hintrp2, lon_bnd, lat_bnd, &
576  lon_model, lat_model, interp_method="bilinear" )
577 
578 
579  if ( (.NOT. file_exist(ncfilename)) ) call mpp_error ('amip_interp_mod', &
580  'cannot find daily SST input data file: '//trim(ncfilename), note)
581 
582  if (file_exist(ncfilename)) then
583  if (mpp_pe() == mpp_root_pe()) call mpp_error ('amip_interp_mod', &
584  'Reading NetCDF formatted daily SST from: '//trim(ncfilename), note)
585 
586  call field_size(ncfilename, 'TIME', siz)
587  nrecords = siz(1)
588  if (nrecords < 1) call mpp_error('amip_interp_mod', &
589  'Invalid number of SST records in daily SST data file: '//trim(ncfilename), fatal)
590  allocate(timeval(nrecords), ryr(nrecords), rmo(nrecords), rdy(nrecords))
591 
592  call mpp_open( unit, ncfilename, mpp_rdonly, mpp_netcdf, mpp_multi, mpp_single )
593  call mpp_get_times(unit, timeval)
594  call mpp_close(unit)
595 
596 !!! DEBUG CODE
597 ! if (mpp_pe() == 0) then
598 ! print *, 'JHC: nrecords = ', nrecords
599 ! print *, 'JHC: TIME = ', timeval
600 ! endif
601 !!! END DEBUG CODE
602 
603  ierr = 1
604  do k = 1, nrecords
605 
606  udate = get_cal_time(timeval(k), time_unit, 'julian')
607  call get_date(udate,jhctod(1),jhctod(2),jhctod(3),jhctod(4),jhctod(5),jhctod(6))
608  ryr(k) = jhctod(1); rmo(k) = jhctod(2); rdy(k) = jhctod(3)
609 
610  if ( yr == ryr(k) .and. mo == rmo(k) .and. dy == rdy(k) ) ierr = 0
611  if (ierr==0) exit
612 
613  enddo
614 !!! DEBUG CODE
615  if (mpp_pe() == 0) then
616  print *, 'JHC: k =', k
617  print *, 'JHC: ryr(k) rmo(k) rdy(k)',ryr(k), rmo(k), rdy(k)
618  print *, 'JHC: yr mo dy ',yr, mo, dy
619  endif
620 !!! END DEBUG CODE
621  if (ierr .ne. 0) call mpp_error('amip_interp_mod', &
622  'Model time is out of range not in SST data: '//trim(ncfilename), fatal)
623  endif ! if(file_exist(ncfilename))
624 
625 
626  !---- read NETCDF data ----
627  if ( .not. allocated(tempamip) ) allocate (tempamip(mobs_sst,nobs_sst))
628 
629  if (file_exist(ncfilename)) then
630  call read_data(ncfilename, 'SST', tempamip, timelevel=k, no_domain=.true.)
632 
633 !!! DEBUG CODE
634 ! if (mpp_pe() == 0) then
635 ! print*, 'JHC: TFREEZE = ', TFREEZE
636 ! print*, lbound(sst)
637 ! print*, ubound(sst)
638 ! print*, lbound(tempamip)
639 ! print*, ubound(tempamip)
640 ! write(*,300) 'JHC: tempamip : ', tempamip(100,100), tempamip(200,200), tempamip(300,300)
641 ! endif
642 !!! END DEBUG CODE
643 
644  call horiz_interp ( interp%Hintrp2, tempamip, sst )
645  call clip_data ('sst', sst)
646 
647  endif
648 
649 !!! DEBUG CODE
650 ! if (mpp_pe() == 400) then
651 ! write(*,300)'JHC: use_daily = T, daily SST: ', sst(1,1),sst(5,5),sst(10,10)
652 ! print *,'JHC: use_daily = T, daily SST: ', sst
653 ! endif
654 !!! END DEBUG CODE
655 
656 200 format(a35, 6(i5,1x))
657 300 format(a35, 3(f7.3,2x))
658 
659 endif
660 ! end add by JHC
661 
662 ! add by JHC: add on non-zero sea surface temperature perturbation (namelist option)
663 ! This perturbation may be useful in accessing model sensitivities
664 
665  if ( do_sst_pert ) then
666 
667  if ( trim(sst_pert_type) == 'fixed' ) then
668  sst = sst + sst_pert
669  else if ( trim(sst_pert_type) == 'random' ) then
670  call random_seed()
671 !!! DEBUG CODE
672 ! if (mpp_pe() == 0) then
673 ! print*, 'mobs = ', mobs
674 ! print*, 'nobs = ', nobs
675 ! print*, lbound(sst)
676 ! print*, ubound(sst)
677 ! endif
678 !!! END DEBUG CODE
679  do i = 1, size(sst,1)
680  do j = 1, size(sst,2)
681  call random_number(pert)
682  sst(i,j) = sst(i,j) + sst_pert*((pert-0.5)*2)
683  end do
684  end do
685  endif
686 
687  endif
688 ! end add by JHC
689 
690 !-----------------------------------------------------------------------
691 
692  end subroutine get_amip_sst
693 
694 
695 !#######################################################################
696 ! <SUBROUTINE NAME="get_amip_ice" INTERFACE="get_amip_ice">
697 ! <IN NAME="Time" TYPE="time_type" > </IN>
698 ! <OUT NAME="ice" TYPE="real" DIM="(:,:)"> </OUT>
699 ! <INOUT NAME="Interp" TYPE="amip_interp_type"> </INOUT>
700 ! </SUBROUTINE>
701 
702 subroutine get_amip_ice (Time, Interp, ice, err_msg)
704  type(time_type), intent(in) :: time
705  type(amip_interp_type), intent(inout) :: interp
706  real, intent(out) :: ice(:,:)
707  character(len=*), optional, intent(out) :: err_msg
708 
709  real, dimension(mobs,nobs) :: sice, temp
710 
711  integer :: year1, year2, month1, month2
712  real :: fmonth
713  type(date_type) :: date1, date2, udate1, udate2
714 
715  type(time_type) :: amip_time
716  integer :: tod(3),dum(3)
717 
718  if(present(err_msg)) err_msg = ''
719  if(.not.interp%I_am_initialized) then
720  if(fms_error_handler('get_amip_ice','The amip_interp_type variable is not initialized',err_msg)) return
721  endif
722 
723 !-----------------------------------------------------------------------
724 !----- compute zonally symetric sst ---------------
725 
726 
727  if (any(amip_date>0)) then
728 
729  call get_date(time,dum(1),dum(2),dum(3),tod(1),tod(2),tod(3))
730 
731  amip_time = set_date(amip_date(1),amip_date(2),amip_date(3),tod(1),tod(2),tod(3))
732 
733  else
734 
735  amip_time = time
736 
737  endif
738 
739 
740 if (use_zonal) then
741  call zonal_sst (amip_time, sice, temp)
742  call horiz_interp ( interp%Hintrp, sice, ice )
743 else
744 
745 !-----------------------------------------------------------------------
746 !---------- get new observed sea surface temperature -------------------
747 
748 ! ---- time interpolation for months -----
749 
750  call time_interp (amip_time, fmonth, year1, year2, month1, month2)
751 
752 ! ---- force climatology ----
753  if (interp % use_climo) then
754  year1=0; year2=0
755  endif
756  if (interp % use_annual) then
757  year1=0; year2=0
758  month1=0; month2=0
759  endif
760 ! ---------------------------
761 
762  date1 = date_type( year1, month1, 0 )
763  date2 = date_type( year2, month2, 0 )
764 
765  unit = -1
766 !-----------------------------------------------------------------------
767 
768  if (date1 /= interp % Date1) then
769 ! ---- use Date2 for Date1 ----
770  if (date1 == interp % Date2) then
771  interp % Date1 = interp % Date2
772  interp % data1 = interp % data2
773  else
774 !-- SJL -------------------------------------------------------------
775 ! Can NOT use ncep_sst to determine sea_ice For seasonal forecast
776 ! Use climo sea ice for seasonal runs
777  if ( use_ncep_sst .and. use_ncep_ice ) then
778  where ( sst_ncep <= (tfreeze+tice_crit) )
779  sice = 1.
780  elsewhere
781  sice = 0.
782  endwhere
783  else
784  call read_record ('ice', date1, udate1, sice)
785  endif
786 !--------------------------------------------------------------------
787  call horiz_interp ( interp%Hintrp, sice, interp%data1 )
788  call clip_data ('ice', interp%data1)
789  interp % Date1 = date1
790  endif
791  endif
792 
793 !-----------------------------------------------------------------------
794 
795  if (date2 /= interp % Date2) then
796 
797 !-- SJL -------------------------------------------------------------
798  if ( use_ncep_sst .and. use_ncep_ice ) then
799  where ( sst_ncep <= (tfreeze+tice_crit) )
800  sice = 1.
801  elsewhere
802  sice = 0.
803  endwhere
804  else
805  call read_record ('ice', date2, udate2, sice)
806  endif
807 !--------------------------------------------------------------------
808  call horiz_interp ( interp%Hintrp, sice, interp%data2 )
809  call clip_data ('ice', interp%data2)
810  interp % Date2 = date2
811 
812  endif
813 
814 ! ---- if the unit was opened, close it and print dates ----
815 
816  if (unit /= -1) then
817  call close_file (unit)
818  if (verbose > 0 .and. mpp_pe() == 0) &
819  call print_dates (amip_time, &
820  interp % Date1, udate1, &
821  interp % Date2, udate2, fmonth)
822  endif
823 
824 !-----------------------------------------------------------------------
825 !---------- time interpolation (between months) ------------------------
826 !-----------------------------------------------------------------------
827 
828  ice = interp % data1 + fmonth * (interp % data2 - interp % data1)
829 
830 endif
831 
832 !-----------------------------------------------------------------------
833 
834  end subroutine get_amip_ice
835 
836 
837 
838 !#######################################################################
839 
840 ! <FUNCTION NAME="amip_interp_new_1d" INTERFACE="amip_interp_new">
841 
842 ! <IN NAME="lon" TYPE="real" DIM="(:)"> </IN>
843 ! <IN NAME="lat" TYPE="real" DIM="(:)"> </IN>
844 ! <IN NAME="mask" TYPE="logical" DIM="(:,:)"> </IN>
845 ! <IN NAME="use_climo" TYPE="logical" DEFAULT="use_climo = .false."> </IN>
846 ! <IN NAME="use_annual" TYPE="logical" DEFAULT="use_annual = .false."> </IN>
847 ! <IN NAME="interp_method" TYPE="character(len=*), optional" DEFAULT="interp_method = conservative"></IN>
848 ! <OUT NAME="Interp" TYPE="amip_interp_type"> </OUT>
849 
850  function amip_interp_new_1d ( lon , lat , mask , use_climo, use_annual, &
851  interp_method ) result (Interp)
853  real, intent(in), dimension(:) :: lon, lat
854  logical, intent(in), dimension(:,:) :: mask
855  character(len=*), intent(in), optional :: interp_method
856  logical, intent(in), optional :: use_climo, use_annual
857 
858  type(amip_interp_type) :: interp
859 
861 
862  interp % use_climo = .false.
863  if (present(use_climo)) interp % use_climo = use_climo
864  interp % use_annual = .false.
865  if (present(use_annual)) interp % use_annual = use_annual
866 
867  if ( date_out_of_range == 'fail' .and. interp%use_climo ) &
868  call error_mesg ('amip_interp_new_1d', 'use_climo mismatch', fatal)
869 
870  if ( date_out_of_range == 'fail' .and. interp%use_annual ) &
871  call error_mesg ('amip_interp_new_1d', 'use_annual(climo) mismatch', fatal)
872 
873  interp % Date1 = date_type( -99, -99, -99 )
874  interp % Date2 = date_type( -99, -99, -99 )
875 
876 !-----------------------------------------------------------------------
877 ! ---- initialization of horizontal interpolation ----
878 
879  call horiz_interp_new ( interp%Hintrp, lon_bnd, lat_bnd, &
880  lon, lat, interp_method= interp_method )
881 
882  allocate ( interp % data1 (size(lon(:))-1,size(lat(:))-1), &
883  interp % data2 (size(lon(:))-1,size(lat(:))-1) )
884 
885  interp%I_am_initialized = .true.
886 
887  end function amip_interp_new_1d
888 ! </FUNCTION>
889 
890 !#######################################################################
891 ! <FUNCTION NAME="amip_interp_new_2d" INTERFACE="amip_interp_new">
892 ! <IN NAME="lon" TYPE="real" DIM="(:,:)"> </IN>
893 ! <IN NAME="lat" TYPE="real" DIM="(:,:)"> </IN>
894 ! <IN NAME="mask" TYPE="logical" DIM="(:,:)"> </IN>
895 ! <IN NAME="use_climo" TYPE="logical" DEFAULT="use_climo = .false."> </IN>
896 ! <IN NAME="use_annual" TYPE="logical" DEFAULT="use_annual = .false."> </IN>
897 ! <IN NAME="interp_method" TYPE="character(len=*), optional" DEFAULT="interp_method = conservative "></IN>
898 ! <OUT NAME="Interp" TYPE="amip_interp_type"> </OUT>
899 
900  function amip_interp_new_2d ( lon , lat , mask , use_climo, use_annual, &
901  interp_method ) result (Interp)
903  real, intent(in), dimension(:,:) :: lon, lat
904  logical, intent(in), dimension(:,:) :: mask
905  character(len=*), intent(in), optional :: interp_method
906  logical, intent(in), optional :: use_climo, use_annual
907 
908  type(amip_interp_type) :: interp
909 
911 
912  interp % use_climo = .false.
913  if (present(use_climo)) interp % use_climo = use_climo
914  interp % use_annual = .false.
915  if (present(use_annual)) interp % use_annual = use_annual
916 
917  if ( date_out_of_range == 'fail' .and. interp%use_climo ) &
918  call error_mesg ('amip_interp_new_2d', 'use_climo mismatch', fatal)
919 
920  if ( date_out_of_range == 'fail' .and. interp%use_annual ) &
921  call error_mesg ('amip_interp_new_2d', 'use_annual(climo) mismatch', fatal)
922 
923  interp % Date1 = date_type( -99, -99, -99 )
924  interp % Date2 = date_type( -99, -99, -99 )
925 
926 !-----------------------------------------------------------------------
927 ! ---- initialization of horizontal interpolation ----
928 
929  call horiz_interp_new ( interp%Hintrp, lon_bnd, lat_bnd, &
930  lon, lat, interp_method = interp_method)
931 
932  allocate ( interp % data1 (size(lon,1),size(lat,2)), &
933  interp % data2 (size(lon,1),size(lat,2)))
934 
935  interp%I_am_initialized = .true.
936 
937  end function amip_interp_new_2d
938 ! </FUNCTION>
939 
940 !#######################################################################
941 
942  subroutine amip_interp_init()
944  integer :: unit,io,ierr
945 
946 !-----------------------------------------------------------------------
947 
948  call horiz_interp_init
949 
950 ! ---- read namelist ----
951 
952 #ifdef INTERNAL_FILE_NML
953  read (input_nml_file, amip_interp_nml, iostat=io)
954  ierr = check_nml_error(io,'amip_interp_nml')
955 #else
956  if ( file_exist('input.nml')) then
957  unit = open_namelist_file( )
958  ierr=1; do while (ierr /= 0)
959  read (unit, nml=amip_interp_nml, iostat=io, end=10)
960  ierr = check_nml_error(io,'amip_interp_nml')
961  enddo
962  10 call close_file (unit)
963  endif
964 #endif
965 
966 ! ----- write namelist/version info -----
967  call write_version_number("AMIP_INTERP_MOD", version)
968 
969  unit = stdlog( )
970  if (mpp_pe() == 0) then
971  write (unit,nml=amip_interp_nml)
972  endif
973  call close_file (unit)
974 
975  if ( .not. use_ncep_sst ) interp_oi_sst = .false.
976 
977 ! ---- freezing point of sea water in deg K ---
978 
980  if ( tice_crit_k < 200. ) tice_crit_k = tice_crit_k + tfreeze
981  ice_crit = nint((tice_crit_k-tfreeze)*100.)
982 
983 ! ---- set up file dependent variable ----
984 ! ---- global file name ----
985 ! ---- grid box edges ----
986 ! ---- initialize zero size grid if not pe 0 ------
987 
988  if (lowercase(trim(data_set)) == 'amip1') then
989  file_name_sst = 'INPUT/' // 'amip1_sst.data'
990  file_name_ice = 'INPUT/' // 'amip1_sst.data'
991  mobs = 180; nobs = 91
993  if (mpp_pe() == 0) &
994  call error_mesg ('amip_interp_init', 'using AMIP 1 sst', note)
995  date_end = date_type( 1989, 1, 0 )
996  else if (lowercase(trim(data_set)) == 'amip2') then
997  file_name_sst = 'INPUT/' // 'amip2_sst.data'
998  file_name_ice = 'INPUT/' // 'amip2_ice.data'
999  mobs = 360; nobs = 180
1001 ! --- specfied min for amip2 ---
1002  tice_crit_k = 271.38
1003  if (mpp_pe() == 0) &
1004  call error_mesg ('amip_interp_init', 'using AMIP 2 sst', note)
1005  date_end = date_type( 1996, 3, 0 )
1006  else if (lowercase(trim(data_set)) == 'hurrell') then
1007  file_name_sst = 'INPUT/' // 'hurrell_sst.data'
1008  file_name_ice = 'INPUT/' // 'hurrell_ice.data'
1009  mobs = 360; nobs = 180
1011 ! --- specfied min for hurrell ---
1012  tice_crit_k = 271.38
1013  if (mpp_pe() == 0) &
1014  call error_mesg ('amip_interp_init', 'using HURRELL sst', note)
1015  date_end = date_type( 2011, 8, 16 ) ! updated by JHC
1016 ! add by JHC
1017  else if (lowercase(trim(data_set)) == 'daily') then
1018  file_name_sst = 'INPUT/' // 'hurrell_sst.data'
1019  file_name_ice = 'INPUT/' // 'hurrell_ice.data'
1020  mobs = 360; nobs = 180
1022  if (mpp_pe() == 0) &
1023  call error_mesg ('amip_interp_init', 'using AVHRR daily sst', note)
1024  date_end = date_type( 2011, 8, 16 )
1025 ! end add by JHC
1026  else if (lowercase(trim(data_set)) == 'reynolds_eof') then
1027  file_name_sst = 'INPUT/' // 'reynolds_sst.data'
1028  file_name_ice = 'INPUT/' // 'reynolds_sst.data'
1029  mobs = 180; nobs = 90
1031  if (mpp_pe() == 0) &
1032  call error_mesg ('amip_interp_init', &
1033  'using NCEP Reynolds Historical Reconstructed SST', note)
1034  date_end = date_type( 1998, 12, 0 )
1035  else if (lowercase(trim(data_set)) == 'reynolds_oi') then
1036  file_name_sst = 'INPUT/' // 'reyoi_sst.data'
1037  file_name_ice = 'INPUT/' // 'reyoi_sst.data'
1038 !--- Added by SJL ----------------------------------------------
1039  if ( use_ncep_sst ) then
1040  mobs = i_sst; nobs = j_sst
1041  if (.not. allocated (sst_ncep)) then
1042  allocate (sst_ncep(i_sst,j_sst))
1043  sst_ncep(:,:) = big_number
1044  endif
1045  if (.not. allocated (sst_anom)) then
1046  allocate (sst_anom(i_sst,j_sst))
1047  sst_anom(:,:) = big_number
1048  endif
1049  else
1050  mobs = 360; nobs = 180
1051  endif
1052 !--- Added by SJL ----------------------------------------------
1054  if (mpp_pe() == 0) &
1055  call error_mesg ('amip_interp_init', 'using Reynolds OI SST', &
1056  note)
1057  date_end = date_type( 1999, 1, 0 )
1058  else
1059  call error_mesg ('amip_interp_init', 'the value of the &
1060  &namelist parameter DATA_SET being used is not allowed', fatal)
1061  endif
1062 
1063  if (verbose > 1 .and. mpp_pe() == 0) &
1064  print *, 'ice_crit,tice_crit_k=',ice_crit,tice_crit_k
1065 
1066 ! --- check existence of sst data file ??? ---
1067 
1068  if (.not.file_exist(trim(file_name_sst)) .and. .not.file_exist(trim(file_name_sst)//'.nc')) then
1069  call error_mesg ('amip_interp_init', &
1070  'Neither '//trim(file_name_sst)//' or '//trim(file_name_sst)//'.nc exists', fatal)
1071  endif
1072  if (.not.file_exist(trim(file_name_ice)) .and. .not.file_exist(trim(file_name_ice)//'.nc')) then
1073  call error_mesg ('amip_interp_init', &
1074  'Neither '//trim(file_name_ice)//' or '//trim(file_name_ice)//'.nc exists', fatal)
1075  endif
1076 
1077  module_is_initialized = .true.
1078 
1079  end subroutine amip_interp_init
1080 
1081 !#######################################################################
1082 
1083 ! <SUBROUTINE NAME="amip_interp_del">
1084 
1085 ! <OVERVIEW>
1086 ! Call this routine for all amip_interp_type variables created by amip_interp_new.
1087 ! </OVERVIEW>
1088 ! <DESCRIPTION>
1089 ! Call this routine for all amip_interp_type variables created by amip_interp_new.
1090 ! </DESCRIPTION>
1091 ! <TEMPLATE>
1092 ! call amip_interp_del (Interp)
1093 ! </TEMPLATE>
1094 ! <INOUT NAME="Interp" TYPE="amip_interp_type">
1095 ! A defined data type variable initialized by amip_interp_new
1096 ! and used when calling get_amip_sst and get_amip_ice.
1097 ! </INOUT>
1098 
1099  subroutine amip_interp_del (Interp)
1100  type(amip_interp_type), intent(inout) :: interp
1101 
1102  if(associated(interp%data1)) deallocate(interp%data1)
1103  if(associated(interp%data2)) deallocate(interp%data2)
1104  if(allocated(lon_bnd)) deallocate(lon_bnd)
1105  if(allocated(lat_bnd)) deallocate(lat_bnd)
1106  call horiz_interp_del ( interp%Hintrp )
1107 
1108  interp%I_am_initialized = .false.
1109 
1110  end subroutine amip_interp_del
1111 !#######################################################################
1112 
1113 ! </SUBROUTINE>
1114 
1115 !#######################################################################
1116 
1117  subroutine set_sst_grid_edges_amip1
1119  integer :: i, j
1120  real :: hpie, dlon, dlat, wb, sb
1121 
1122  allocate ( lon_bnd(mobs+1), lat_bnd(nobs+1) )
1123 
1124 ! ---- compute grid edges (do only once) -----
1125 
1126  hpie = 0.5*pi
1127 
1128  dlon = 4.*hpie/float(mobs); wb = -0.5*dlon
1129  do i = 1, mobs+1
1130  lon_bnd(i) = wb + dlon * float(i-1)
1131  enddo
1132  lon_bnd(mobs+1) = lon_bnd(1) + 4.*hpie
1133 
1134  dlat = 2.*hpie/float(nobs-1); sb = -hpie + 0.5*dlat
1135  lat_bnd(1) = -hpie; lat_bnd(nobs+1) = hpie
1136  do j = 2, nobs
1137  lat_bnd(j) = sb + dlat * float(j-2)
1138  enddo
1139 
1140  end subroutine set_sst_grid_edges_amip1
1141 
1142 !#######################################################################
1143  subroutine set_sst_grid_edges_oi
1145  integer :: i, j
1146  real :: hpie, dlon, dlat, wb, sb
1147 
1148 ! add by JHC
1149  if(allocated(lon_bnd)) deallocate(lon_bnd)
1150  if(allocated(lat_bnd)) deallocate(lat_bnd)
1151 ! end add by JHC
1152  allocate ( lon_bnd(mobs+1), lat_bnd(nobs+1) )
1153 
1154 ! ---- compute grid edges (do only once) -----
1155 
1156  hpie = 0.5*pi
1157 
1158  dlon = 4.*hpie/float(mobs); wb = 0.0
1159  lon_bnd(1) = wb
1160  do i = 2, mobs+1
1161  lon_bnd(i) = wb + dlon * float(i-1)
1162  enddo
1163  lon_bnd(mobs+1) = lon_bnd(1) + 4.*hpie
1164 
1165  dlat = 2.*hpie/float(nobs); sb = -hpie
1166  lat_bnd(1) = sb; lat_bnd(nobs+1) = hpie
1167  do j = 2, nobs
1168  lat_bnd(j) = sb + dlat * float(j-1)
1169  enddo
1170 
1171  end subroutine set_sst_grid_edges_oi
1172 !#######################################################################
1173 ! add by JHC
1174  subroutine set_sst_grid_edges_daily(mobs_sst, nobs_sst)
1176  integer :: i, j, mobs_sst, nobs_sst
1177  real :: hpie, dlon, dlat, wb, sb
1178 
1179  if(allocated(lon_bnd)) deallocate(lon_bnd)
1180  if(allocated(lat_bnd)) deallocate(lat_bnd)
1181  allocate ( lon_bnd(mobs_sst+1), lat_bnd(nobs_sst+1) )
1182 
1183 ! ---- compute grid edges (do only once) -----
1184 
1185  hpie = 0.5*pi
1186 
1187  dlon = 4.*hpie/float(mobs_sst); wb = 0.0
1188  lon_bnd(1) = wb
1189  do i = 2, mobs_sst+1
1190  lon_bnd(i) = wb + dlon * float(i-1)
1191  enddo
1192  lon_bnd(mobs_sst+1) = lon_bnd(1) + 4.*hpie
1193 
1194  dlat = 2.*hpie/float(nobs_sst); sb = -hpie
1195  lat_bnd(1) = sb; lat_bnd(nobs_sst+1) = hpie
1196  do j = 2, nobs_sst
1197  lat_bnd(j) = sb + dlat * float(j-1)
1198  enddo
1199 
1200  end subroutine set_sst_grid_edges_daily
1201 ! end add by JHC
1202 !#######################################################################
1203 
1204 
1205  subroutine a2a_bilinear(nx, ny, dat1, n1, n2, dat2)
1206  integer, intent(in):: nx, ny
1207  integer, intent(in):: n1, n2
1208  real, intent(in) :: dat1(nx,ny)
1209  real, intent(out):: dat2(n1,n2) ! output interpolated data
1210 
1211 ! local:
1212  real:: lon1(nx), lat1(ny)
1213  real:: lon2(n1), lat2(n2)
1214  real:: dx1, dy1, dx2, dy2
1215  real:: xc, yc
1216  real:: a1, b1, c1, c2, c3, c4
1217  integer i1, i2, jc, i0, j0, it, jt
1218  integer i,j
1219 
1220 
1221 !-----------------------------------------------------------
1222 ! * Interpolate from "FMS" 1x1 SST data grid to a finer grid
1223 ! lon: 0.5, 1.5, ..., 359.5
1224 ! lat: -89.5, -88.5, ... , 88.5, 89.5
1225 !-----------------------------------------------------------
1226 
1227 ! INput Grid
1228  dx1 = 360./real(nx)
1229  dy1 = 180./real(ny)
1230 
1231  do i=1,nx
1232  lon1(i) = 0.5*dx1 + real(i-1)*dx1
1233  enddo
1234  do j=1,ny
1235  lat1(j) = -90. + 0.5*dy1 + real(j-1)*dy1
1236  enddo
1237 
1238 ! OutPut Grid:
1239  dx2 = 360./real(n1)
1240  dy2 = 180./real(n2)
1241 
1242  do i=1,n1
1243  lon2(i) = 0.5*dx2 + real(i-1)*dx2
1244  enddo
1245  do j=1,n2
1246  lat2(j) = -90. + 0.5*dy2 + real(j-1)*dy2
1247  enddo
1248 
1249  jt = 1
1250  do 5000 j=1,n2
1251 
1252  yc = lat2(j)
1253  if ( yc<lat1(1) ) then
1254  jc = 1
1255  b1 = 0.
1256  elseif ( yc>lat1(ny) ) then
1257  jc = ny-1
1258  b1 = 1.
1259  else
1260  do j0=jt,ny-1
1261  if ( yc>=lat1(j0) .and. yc<=lat1(j0+1) ) then
1262  jc = j0
1263  jt = j0
1264  b1 = (yc-lat1(jc)) / dy1
1265  go to 222
1266  endif
1267  enddo
1268  endif
1269 222 continue
1270 
1271  it = 1
1272  do i=1,n1
1273  xc = lon2(i)
1274  if ( xc>lon1(nx) ) then
1275  i1 = nx; i2 = 1
1276  a1 = (xc-lon1(nx)) / dx1
1277  elseif ( xc<lon1(1) ) then
1278  i1 = nx; i2 = 1
1279  a1 = (xc+360.-lon1(nx)) / dx1
1280  else
1281  do i0=it,nx-1
1282  if ( xc>=lon1(i0) .and. xc<=lon1(i0+1) ) then
1283  i1 = i0; i2 = i0+1
1284  it = i0
1285  a1 = (xc-lon1(i1)) / dx1
1286  go to 111
1287  endif
1288  enddo
1289  endif
1290 111 continue
1291 
1292 ! Debug code:
1293  if ( a1<-0.001 .or. a1>1.001 .or. b1<-0.001 .or. b1>1.001 ) then
1294  write(*,*) i,j,a1, b1
1295  call mpp_error(fatal,'a2a bilinear interpolation')
1296  endif
1297 
1298  c1 = (1.-a1) * (1.-b1)
1299  c2 = a1 * (1.-b1)
1300  c3 = a1 * b1
1301  c4 = (1.-a1) * b1
1302 
1303 ! Bilinear interpolation:
1304  dat2(i,j) = c1*dat1(i1,jc) + c2*dat1(i2,jc) + c3*dat1(i2,jc+1) + c4*dat1(i1,jc+1)
1305 
1306  enddo !i-loop
1307 
1308 5000 continue ! j-loop
1309 
1310  end subroutine a2a_bilinear
1311 
1312 !#######################################################################
1313 
1314 ! <SUBROUTINE NAME="get_sst_grid_size">
1315 
1316 ! <OVERVIEW>
1317 ! Returns the size (i.e., number of longitude and latitude
1318 ! points) of the observed data grid.
1319 ! </OVERVIEW>
1320 ! <DESCRIPTION>
1321 ! Returns the size (i.e., number of longitude and latitude
1322 ! points) of the observed data grid.
1323 ! </DESCRIPTION>
1324 ! <TEMPLATE>
1325 ! call get_sst_grid_size (nlon, nlat)
1326 ! </TEMPLATE>
1327 ! <OUT NAME="nlon" TYPE="integer">
1328 ! The number of longitude points (first dimension) in the
1329 ! observed data grid. For AMIP 1 nlon = 180, and the Reynolds nlon = 360.
1330 ! </OUT>
1331 ! <OUT NAME="nlat" TYPE="integer">
1332 ! The number of latitude points (second dimension) in the
1333 ! observed data grid. For AMIP 1 nlon = 91, and the Reynolds nlon = 180.
1334 ! </OUT>
1335 ! <ERROR MSG="have not called amip_interp_new" STATUS="FATAL">
1336 ! Must call amip_interp_new before get_sst_grid_size.
1337 ! </ERROR>
1338 
1339  subroutine get_sst_grid_size (nlon, nlat)
1341  integer, intent(out) :: nlon, nlat
1342 
1343  if ( .not.module_is_initialized ) call amip_interp_init
1344 
1345  nlon = mobs; nlat = nobs
1346 
1347  end subroutine get_sst_grid_size
1348 ! </SUBROUTINE>
1349 
1350 !#######################################################################
1351 
1352 ! <SUBROUTINE NAME="get_sst_grid_boundary">
1353 
1354 ! <OVERVIEW>
1355 ! Returns the grid box boundaries of the observed data grid.
1356 ! </OVERVIEW>
1357 ! <DESCRIPTION>
1358 ! Returns the grid box boundaries of the observed data grid.
1359 ! </DESCRIPTION>
1360 ! <TEMPLATE>
1361 ! call get_sst_grid_boundary (blon, blat, mask)
1362 ! </TEMPLATE>
1363 ! <OUT NAME="blon" TYPE="real" DIM="(:)">
1364 ! The grid box edges (in radians) for longitude points of the
1365 ! observed data grid. The size of this argument must be nlon+1.
1366 ! </OUT>
1367 ! <OUT NAME="blat" TYPE="real" DIM="(:)">
1368 ! The grid box edges (in radians) for latitude points of the
1369 ! observed data grid. The size of this argument must be nlat+1.
1370 ! </OUT>
1371 ! <ERROR MSG="have not called amip_interp_new" STATUS="FATAL">
1372 ! Must call amip_interp_new before get_sst_grid_boundary.
1373 ! </ERROR>
1374 ! <ERROR MSG="invalid argument dimensions" STATUS="FATAL">
1375 ! The size of the output argument arrays do not agree with
1376 ! the size of the observed data. See the documentation for
1377 ! interfaces get_sst_grid_size and get_sst_grid_boundary.
1378 ! </ERROR>
1379 
1380  subroutine get_sst_grid_boundary (blon, blat, mask)
1382  real, intent(out) :: blon(:), blat(:)
1383  logical, intent(out) :: mask(:,:)
1384 
1385  if ( .not.module_is_initialized ) call amip_interp_init
1386 
1387 ! ---- check size of argument(s) ----
1388 
1389  if (size(blon(:)) /= mobs+1 .or. size(blat(:)) /= nobs+1) &
1390  call error_mesg ('get_sst_grid_boundary in amip_interp_mod', &
1391  'invalid argument dimensions', fatal)
1392 
1393 ! ---- return grid box edges -----
1394 
1395  blon = lon_bnd
1396  blat = lat_bnd
1397 
1398 ! ---- masking (data exists at all points) ----
1399 
1400  mask = .true.
1401 
1402 
1403  end subroutine get_sst_grid_boundary
1404 ! </SUBROUTINE>
1405 
1406 !#######################################################################
1407 
1408  subroutine read_record (type, Date, Adate, dat)
1410  character(len=*), intent(in) :: type
1411  type(date_type), intent(in) :: date
1412  type(date_type), intent(inout) :: adate
1413  real, intent(out) :: dat(mobs,nobs)
1414  real :: tmp_dat(360,180)
1415 
1416  real (R4_KIND) :: dat4(mobs,nobs)
1417  integer(I2_KIND) :: idat(mobs,nobs)
1418  integer :: nrecords, yr, mo, dy, ierr, k
1419  integer, dimension(:), allocatable :: ryr, rmo, rdy
1420  character(len=38) :: mesg
1421  character(len=maxc) :: ncfilename, ncfieldname
1422 
1423  !---- set file and field name for NETCDF data sets ----
1424 
1425  ncfieldname = 'sst'
1426  if(type(1:3) == 'sst') then
1427  ncfilename = trim(file_name_sst)//'.nc'
1428  else if(type(1:3) == 'ice') then
1429  ncfilename = trim(file_name_ice)//'.nc'
1430  if (lowercase(trim(data_set)) == 'amip2' .or. &
1431  lowercase(trim(data_set)) == 'hurrell' .or. &
1432  lowercase(trim(data_set)) == 'daily') ncfieldname = 'ice' ! modified by JHC
1433  endif
1434 
1435  !---- make sure IEEE format file is open ----
1436 
1437  if ( (.NOT. file_exist(ncfilename)) ) then
1438 
1439  ! rewind condition (if unit is open)
1440  if (unit /= -1 .and. curr_date % year == 0 .and. &
1441  date % month <= curr_date % month ) then
1442  if (verbose > 1 .and. mpp_pe() == 0) &
1443  print *, ' rewinding unit = ', unit
1444  rewind unit
1445  endif
1446 
1447  if (unit == -1) then
1448  if (type(1:3) == 'sst') then
1449  unit = open_ieee32_file(file_name_sst, 'read')
1450  else if (type(1:3) == 'ice') then
1451  unit = open_ieee32_file(file_name_ice, 'read')
1452  endif
1453  endif
1454 
1455  endif
1456 
1457  dy = 0 ! only processing monthly data
1458 
1459  if (verbose > 2 .and. mpp_pe() == 0) &
1460  print *, 'looking for date = ', date
1461 
1462  !---- check dates in NETCDF file -----
1463 
1464  ! This code can handle amip1, reynolds, or reyoi type SST data files in netCDF format
1465  if (file_exist(ncfilename)) then
1466  if (mpp_pe() == mpp_root_pe()) call mpp_error ('amip_interp_mod', &
1467  'Reading NetCDF formatted input data file: '//trim(ncfilename), note)
1468  call read_data (ncfilename, 'nrecords', nrecords, no_domain=.true.)
1469  if (nrecords < 1) call mpp_error('amip_interp_mod', &
1470  'Invalid number of SST records in SST datafile: '//trim(ncfilename), fatal)
1471  allocate(ryr(nrecords), rmo(nrecords), rdy(nrecords))
1472  call read_data(ncfilename, 'yr', ryr, no_domain=.true.)
1473  call read_data(ncfilename, 'mo', rmo, no_domain=.true.)
1474  call read_data(ncfilename, 'dy', rdy, no_domain=.true.)
1475  ierr = 1
1476  do k = 1, nrecords
1477  yr = ryr(k); mo = rmo(k)
1478  adate = date_type( yr, mo, 0)
1479  curr_date = adate
1480  if (verbose > 2 .and. mpp_pe() == 0) &
1481  print *, '....... checking ', adate
1482  if (date == adate) ierr = 0
1483  if (yr == 0 .and. mo == date%month) ierr = 0
1484  if (ierr == 0) exit
1485  enddo
1486  if (ierr .ne. 0) call mpp_error('amip_interp_mod', &
1487  'Model time is out of range not in SST data: '//trim(ncfilename), fatal)
1488  deallocate(ryr, rmo, rdy)
1489  !PRINT *, 'New SST data: ', k, yr, mo, dy, Date%year, Date%month, Date%day, ryr(1), rmo(1)
1490 
1491  !---- check dates in IEEE file -----
1492 
1493  else
1494  if (mpp_pe() == mpp_root_pe()) call mpp_error ('amip_interp_mod', &
1495  'Reading native formatted input data file: '//trim(data_set), note)
1496  k = 0
1497  do
1498  k = k + 1
1499  if (lowercase(trim(data_set)) == 'amip2' .or. lowercase(trim(data_set)) == 'hurrell') then
1500  read (unit, end=10) yr, mo, dat4
1501  dat=dat4
1502  else
1503  read (unit, end=10) yr, mo, dy, idat
1504  endif
1505  !new read (unit, end=10) yr, mo, dy
1506  adate = date_type( yr, mo, dy )
1507  curr_date = adate
1508  if (verbose > 2 .and. mpp_pe() == 0) &
1509  print *, '....... checking ', adate
1510 
1511  ! --- found date ---
1512  if (date == adate) exit
1513  if (date%month == mo .and. date%day == dy .and. date%year == yr ) exit
1514  ! --- otherwise use monthly climo ---
1515  if (yr == 0 .and. date % month == mo) exit
1516 
1517  ! --- skip this data record ---
1518  !new if (lowercase(trim(data_set)) /= 'amip2') read (unit)
1519  enddo
1520 
1521  ! --- read data ---
1522  !new if (lowercase(trim(data_set)) /= 'amip2') read (unit) idat
1523 
1524  ! --- check if climo used when not wanted ---
1525 
1526  endif ! if(file_exist(ncfilename))
1527 
1528  !---- check if climatological data should be used ----
1529 
1530  if (yr == 0 .or. mo == 0) then
1531  ierr = 0
1532  if (date_out_of_range == 'fail' ) ierr = 1
1533  if (date_out_of_range == 'initclimo' .and. &
1534  date > date_end ) ierr = 1
1535  if (ierr /= 0) call error_mesg &
1536  ('read_record in amip_interp_mod', &
1537  'climo data read when NO climo data requested', fatal)
1538  endif
1539 
1540  !---- read NETCDF data ----
1541 
1542  if (file_exist(ncfilename)) then
1543  if ( interp_oi_sst ) then
1544  call read_data(ncfilename, ncfieldname, tmp_dat, timelevel=k, no_domain=.true.)
1545 ! interpolate tmp_dat(360, 180) ---> dat(mobs,nobs) (to enable SST anom computation)
1546  if ( mobs/=360 .or. nobs/=180 ) then
1547  call a2a_bilinear(360, 180, tmp_dat, mobs, nobs, dat)
1548  else
1549  dat(:,:) = tmp_dat(:,:)
1550  endif
1551  else
1552  call read_data(ncfilename, ncfieldname, dat, timelevel=k, no_domain=.true.)
1553  endif
1554  idat = nint(dat*100.) ! reconstruct packed data for reproducibity
1555  endif
1556 
1557  !---- unpacking of data ----
1558 
1559  if (type(1:3) == 'ice') then
1560  !---- create fractional [0,1] ice mask
1561  if (lowercase(trim(data_set)) /= 'amip2' .and. lowercase(trim(data_set)) /= 'hurrell') then
1562  where ( idat <= ice_crit )
1563  dat = 1.
1564  elsewhere
1565  dat = 0.
1566  endwhere
1567  else
1568  dat = dat*0.01
1569  endif
1570  else if (type(1:3) == 'sst') then
1571  !---- unpack sst ----
1572  if (lowercase(trim(data_set)) /= 'amip2' .and. lowercase(trim(data_set)) /= 'hurrell') then
1573  dat = real(idat)*0.01 + TFREEZE
1574  endif
1575  endif
1576 
1577 
1578  return
1579 
1580 10 write (mesg, 20) unit
1581  call error_mesg ('read_record in amip_interp_mod', mesg, fatal)
1582 
1583 20 format ('end of file reading unit ',i2,' (sst data)')
1584 
1585  end subroutine read_record
1586 
1587 !#######################################################################
1588 
1589  subroutine clip_data (type, dat)
1591  character(len=*), intent(in) :: type
1592  real, intent(inout) :: dat(:,:)
1593 
1594  if (type(1:3) == 'ice') then
1595  dat = min(max(dat,0.0),1.0)
1596  else if (type(1:3) == 'sst') then
1597  dat = max(tice_crit_k,dat)
1598  endif
1599 
1600  end subroutine clip_data
1601 
1602 !#######################################################################
1603 
1604 function date_equals (Left, Right) result (answer)
1605 type(date_type), intent(in) :: left, right
1606 logical :: answer
1607 
1608  if (left % year == right % year .and. &
1609  left % month == right % month .and. &
1610  left % day == right % day ) then
1611  answer = .true.
1612  else
1613  answer = .false.
1614  endif
1615 
1616 end function date_equals
1617 
1618 !#######################################################################
1619 
1620 function date_not_equals (Left, Right) result (answer)
1621 type(date_type), intent(in) :: left, right
1622 logical :: answer
1623 
1624  if (left % year == right % year .and. &
1625  left % month == right % month .and. &
1626  left % day == right % day ) then
1627  answer = .false.
1628  else
1629  answer = .true.
1630  endif
1631 
1632 end function date_not_equals
1633 
1634 !#######################################################################
1635 
1636 function date_gt (Left, Right) result (answer)
1637 type(date_type), intent(in) :: left, right
1638 logical :: answer
1639 integer :: i, dif(3)
1640 
1641  dif(1) = left%year - right%year
1642  dif(2) = left%month - right%month
1643  dif(3) = left%day - right%day
1644  answer = .false.
1645  do i = 1, 3
1646  if (dif(i) == 0) cycle
1647  if (dif(i) < 0) exit
1648  if (dif(i) > 0) then
1649  answer = .true.
1650  exit
1651  endif
1652  enddo
1653 
1654 end function date_gt
1655 
1656 !#######################################################################
1657 
1658 subroutine print_dates (Time, Date1, Udate1, &
1659  Date2, Udate2, fmonth)
1661  type(time_type), intent(in) :: time
1662  type(date_type), intent(in) :: date1, udate1, date2, udate2
1663  real, intent(in) :: fmonth
1664 
1665  integer :: year, month, day, hour, minute, second
1666 
1667  call get_date (time, year, month, day, hour, minute, second)
1668 
1669  write (*,10) year,month,day, hour,minute,second
1670  write (*,20) fmonth
1671  write (*,30) date1, udate1
1672  write (*,40) date2, udate2
1673 
1674 10 format (/,' date(y/m/d h:m:s) = ',i4,2('/',i2.2),1x,2(i2.2,':'),i2.2)
1675 20 format (' fmonth = ',f9.7)
1676 30 format (' date1(y/m/d) = ',i4,2('/',i2.2),6x, &
1677  'used = ',i4,2('/',i2.2),6x )
1678 40 format (' date2(y/m/d) = ',i4,2('/',i2.2),6x, &
1679  'used = ',i4,2('/',i2.2),6x )
1680 
1681 end subroutine print_dates
1682 
1683 !#######################################################################
1684 
1685 subroutine zonal_sst (Time, ice, sst)
1687  type(time_type), intent(in) :: time
1688  real, intent(out) :: ice(mobs,nobs), sst(mobs,nobs)
1689 
1690  real :: tpi, fdate, eps, ph, sph, sph2, ts
1691  integer :: j
1692 
1693 ! namelist needed
1694 !
1695 ! teq = sst at equator
1696 ! tdif = equator to pole sst difference
1697 ! tann = amplitude of annual cycle
1698 ! tlag = offset for time of year (for annual cycle)
1699 !
1700 
1701  tpi = 2.0*pi
1702 
1703  fdate = fraction_of_year(time)
1704 
1705  eps = sin( tpi*(fdate-tlag) ) * tann
1706 
1707  do j = 1, nobs
1708 
1709  ph = 0.5*(lat_bnd(j)+lat_bnd(j+1))
1710  sph = sin(ph)
1711  sph2 = sph*sph
1712 
1713  ts = teq - tdif*sph2 - eps*sph
1714 
1715  sst(:,j) = ts
1716 
1717  enddo
1718 
1719  where ( sst < tice_crit_k )
1720  ice = 1.0
1721  sst = tice_crit_k
1722  elsewhere
1723  ice = 0.0
1724  endwhere
1725 
1726 
1727 end subroutine zonal_sst
1728 
1729 !#######################################################################
1730 
1731 subroutine amip_interp_type_eq(amip_interp_out, amip_interp_in)
1732  type(amip_interp_type), intent(inout) :: amip_interp_out
1733  type(amip_interp_type), intent(in) :: amip_interp_in
1734 
1735  if(.not.amip_interp_in%I_am_initialized) then
1736  call mpp_error(fatal,'amip_interp_type_eq: amip_interp_type variable on right hand side is unassigned')
1737  endif
1738 
1739  amip_interp_out%Hintrp = amip_interp_in%Hintrp
1740  amip_interp_out%data1 => amip_interp_in%data1
1741  amip_interp_out%data2 => amip_interp_in%data2
1742  amip_interp_out%Date1 = amip_interp_in%Date1
1743  amip_interp_out%Date2 = amip_interp_in%Date2
1744  amip_interp_out%Date1 = amip_interp_in%Date1
1745  amip_interp_out%Date2 = amip_interp_in%Date2
1746  amip_interp_out%use_climo = amip_interp_in%use_climo
1747  amip_interp_out%use_annual = amip_interp_in%use_annual
1748  amip_interp_out%I_am_initialized = .true.
1749 
1750 end subroutine amip_interp_type_eq
1751 
1752 !#######################################################################
1753 
1754 end module amip_interp_mod
1755 ! <INFO>
1756 
1757 ! <FUTURE>
1758 ! Add AMIP 2 data set.
1759 !
1760 ! Other data sets (or extend current data sets).
1761 ! </FUTURE>
1762 
1763 ! </INFO>
Definition: fms.F90:20
subroutine, public get_date(time, year, month, day, hour, minute, second, tick, err_msg)
character(len=maxc) file_name_ice
logical function date_equals(Left, Right)
subroutine get_sst_grid_size(nlon, nlat)
integer, dimension(3) amip_date
subroutine a2a_bilinear(nx, ny, dat1, n1, n2, dat2)
subroutine, public amip_interp_init()
subroutine amip_interp_type_eq(amip_interp_out, amip_interp_in)
subroutine set_sst_grid_edges_amip1
subroutine get_sst_grid_boundary(blon, blat, mask)
real, dimension(:), allocatable lon_bnd
subroutine, public horiz_interp_del(Interp)
logical function date_gt(Left, Right)
logical function date_not_equals(Left, Right)
subroutine, public amip_interp_del(Interp)
integer, parameter r4_kind
Definition: platform.F90:24
subroutine clip_data(type, dat)
logical function, public fms_error_handler(routine, message, err_msg)
Definition: fms.F90:573
real, dimension(:,:), allocatable temp1
type(time_type) function, public get_cal_time(time_increment, units, calendar, permit_calendar_conversion)
Definition: mpp.F90:39
subroutine, public get_amip_sst(Time, Interp, sst, err_msg, lon_model, lat_model)
integer function, public check_nml_error(IOSTAT, NML_NAME)
Definition: fms.F90:658
real, parameter big_number
logical module_is_initialized
character(len=input_str_length), dimension(:), allocatable, target, public input_nml_file
Definition: mpp.F90:1378
real, parameter, public pi
Ratio of circle circumference to diameter [N/A].
Definition: constants.F90:74
subroutine set_sst_grid_edges_daily(mobs_sst, nobs_sst)
type(date_type) curr_date
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! MPP_TRANSMIT !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine MPP_TRANSMIT_(put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, recv_request, send_request)!a message-passing routine intended to be reminiscent equally of both MPI and SHMEM!put_data and get_data are contiguous MPP_TYPE_ arrays!at each call, your put_data array is put to to_pe 's get_data! your get_data array is got from from_pe 's put_data!i.e we assume that typically(e.g updating halo regions) each PE performs a put _and_ a get!special PE designations:! NULL_PE:to disable a put or a get(e.g at boundaries)! ANY_PE:if remote PE for the put or get is to be unspecific! ALL_PES:broadcast and collect operations(collect not yet implemented)!ideally we would not pass length, but this f77-style call performs better(arrays passed by address, not descriptor)!further, this permits< length > contiguous words from an array of any rank to be passed(avoiding f90 rank conformance check)!caller is responsible for completion checks(mpp_sync_self) before and after integer, intent(in) ::put_len, to_pe, get_len, from_pe MPP_TYPE_, intent(in) ::put_data(*) MPP_TYPE_, intent(out) ::get_data(*) logical, intent(in), optional ::block integer, intent(in), optional ::tag integer, intent(out), optional ::recv_request, send_request logical ::block_comm integer ::i MPP_TYPE_, allocatable, save ::local_data(:) !local copy used by non-parallel code(no SHMEM or MPI) integer ::comm_tag integer ::rsize if(.NOT.module_is_initialized) call mpp_error(FATAL, 'MPP_TRANSMIT:You must first call mpp_init.') if(to_pe.EQ.NULL_PE .AND. from_pe.EQ.NULL_PE) return block_comm=.true. if(PRESENT(block)) block_comm=block if(debug) then call SYSTEM_CLOCK(tick) write(stdout_unit,'(a, i18, a, i6, a, 2i6, 2i8)')&'T=', tick, ' PE=', pe, ' MPP_TRANSMIT begin:to_pe, from_pe, put_len, get_len=', to_pe, from_pe, put_len, get_len end if comm_tag=DEFAULT_TAG if(present(tag)) comm_tag=tag!do put first and then get if(to_pe.GE.0 .AND. to_pe.LT.npes) then!use non-blocking sends if(debug .and.(current_clock.NE.0)) call SYSTEM_CLOCK(start_tick)!z1l:truly non-blocking send.! if(request(to_pe).NE.MPI_REQUEST_NULL) then !only one message from pe-> to_pe in queue *PE waiting for to_pe ! call error else get_len so only do gets but you cannot have a pure get with MPI call mpp_error(FATAL, 'MPP_TRANSMIT:you cannot transmit to ANY_PE using MPI.') else if(to_pe.NE.NULL_PE) then !no other valid cases except NULL_PE call mpp_error(FATAL
subroutine, public field_size(filename, fieldname, siz, field_found, domain, no_domain)
Definition: fms_io.F90:4941
real, dimension(:,:), allocatable temp2
logical, public forecast_mode
real, parameter, public tfreeze
Freezing temperature of fresh water [K].
Definition: constants.F90:84
logical use_ncep_ice
logical, public use_ncep_sst
real function, public fraction_of_year(Time)
subroutine, public horiz_interp_init
real, dimension(:,:), allocatable tempamip
real, dimension(:), allocatable lat_bnd
real, dimension(:,:), allocatable, public sst_ncep
type(amip_interp_type) function amip_interp_new_1d(lon, lat, mask, use_climo, use_annual, interp_method)
subroutine print_dates(Time, Date1, Udate1, Date2, Udate2, fmonth)
integer, public j_sst
#define max(a, b)
Definition: mosaic_util.h:33
integer, public i_sst
subroutine read_record(type, Date, Adate, dat)
integer, parameter i2_kind
Definition: platform.F90:24
integer, parameter maxc
subroutine zonal_sst(Time, ice, sst)
integer(i2_kind) ice_crit
character(len=16) date_out_of_range
#define min(a, b)
Definition: mosaic_util.h:32
real, dimension(:,:), allocatable, public sst_anom
subroutine, public error_mesg(routine, message, level)
Definition: fms.F90:529
subroutine set_sst_grid_edges_oi
character(len=24) data_set
subroutine, public get_amip_ice(Time, Interp, ice, err_msg)
character(len=6) sst_pert_type
type(amip_interp_type) function amip_interp_new_2d(lon, lat, mask, use_climo, use_annual, interp_method)
type(date_type) date_end
logical interp_oi_sst
character(len=maxc) file_name_sst