24module interpolator_mod
35use mpp_domains_mod,
only : mpp_domains_init, &
45use fms_mod,
only : lowercase, write_version_number, &
47 mpp_root_pe, stdlog, &
49use fms2_io_mod,
only : fmsnetcdffile_t, fms2_io_file_exist => file_exists, dimension_exists, &
51 variable_exists, get_variable_num_dimensions, &
52 get_num_variables, get_dimension_size, &
53 get_variable_units, get_variable_names, &
55 get_variable_dimension_names, get_variable_sense
57use horiz_interp_mod,
only : horiz_interp_type, &
72 get_date_julian, set_date_no_leap, &
73 set_date_julian, get_date_no_leap, &
83use constants_mod,
only : grav, pi, seconds_per_day
84use platform_mod,
only : r4_kind, r8_kind, r16_kind, fms_path_len, fms_file_len
156 module procedure interpolator_4d_r4, interpolator_4d_r8
157 module procedure interpolator_3d_r4, interpolator_3d_r8
158 module procedure interpolator_2d_r4, interpolator_2d_r8
159 module procedure interpolator_4d_no_time_axis_r4, interpolator_4d_no_time_axis_r8
160 module procedure interpolator_3d_no_time_axis_r4, interpolator_3d_no_time_axis_r8
161 module procedure interpolator_2d_no_time_axis_r4, interpolator_2d_no_time_axis_r8
166interface assignment(=)
171 module procedure interpolator_init_r4
172 module procedure interpolator_init_r8
176 module procedure fms2io_interpolator_init_r4
177 module procedure fms2io_interpolator_init_r8
181 module procedure get_axis_latlon_data_r4
182 module procedure get_axis_latlon_data_r8
186 module procedure get_axis_level_data_r4
187 module procedure get_axis_level_data_r8
191 module procedure cell_center2_r4
192 module procedure cell_center2_r8
196 module procedure cart_to_latlon_r4
197 module procedure cart_to_latlon_r8
201 module procedure latlon2xyz_r4
202 module procedure latlon2xyz_r8
206 module procedure diag_read_data_r4
207 module procedure diag_read_data_r8
211 module procedure read_data_r4
212 module procedure read_data_r8
216 module procedure read_data_no_time_axis_r4
217 module procedure read_data_no_time_axis_r8
221 module procedure interp_linear_r4
222 module procedure interp_linear_r8
239 module procedure interp_weighted_scalar_1d_r4, interp_weighted_scalar_1d_r8
240 module procedure interp_weighted_scalar_2d_r4, interp_weighted_scalar_2d_r8
247#include<file_version.h>
253logical :: is_allocated = .false.
254real(r4_kind),
allocatable :: lat(:)
255real(r4_kind),
allocatable :: lon(:)
256real(r4_kind),
allocatable :: latb(:)
257real(r4_kind),
allocatable :: lonb(:)
258real(r4_kind),
allocatable :: levs(:)
259real(r4_kind),
allocatable :: halflevs(:)
260real(r4_kind),
allocatable :: data5d(:,:,:,:,:)
261real(r4_kind),
allocatable :: pmon_pyear(:,:,:,:)
262real(r4_kind),
allocatable :: pmon_nyear(:,:,:,:)
263real(r4_kind),
allocatable :: nmon_nyear(:,:,:,:)
264real(r4_kind),
allocatable :: nmon_pyear(:,:,:,:)
265real(r4_kind) :: tweight
266real(r4_kind) :: tweight1
267real(r4_kind) :: tweight2
268real(r4_kind) :: tweight3
272logical :: is_allocated = .false.
273real(r8_kind),
allocatable :: lat(:)
274real(r8_kind),
allocatable :: lon(:)
275real(r8_kind),
allocatable :: latb(:)
276real(r8_kind),
allocatable :: lonb(:)
277real(r8_kind),
allocatable :: levs(:)
278real(r8_kind),
allocatable :: halflevs(:)
279real(r8_kind),
allocatable :: data5d(:,:,:,:,:)
280real(r8_kind),
allocatable :: pmon_pyear(:,:,:,:)
281real(r8_kind),
allocatable :: pmon_nyear(:,:,:,:)
282real(r8_kind),
allocatable :: nmon_nyear(:,:,:,:)
283real(r8_kind),
allocatable :: nmon_pyear(:,:,:,:)
284real(r8_kind) :: tweight
285real(r8_kind) :: tweight1
286real(r8_kind) :: tweight2
287real(r8_kind) :: tweight3
294type(interpolate_r4_type) :: r4_type
295type(interpolate_r8_type) :: r8_type
296type(horiz_interp_type) :: interph
298type(fmsnetcdffile_t) :: fileobj
299character(len=FMS_PATH_LEN) :: file_name
302integer :: is,ie,js,je
303integer :: vertical_indices
305logical :: climatological_year
308character(len=64),
allocatable :: field_name(:)
309logical,
allocatable :: has_level(:)
310integer,
allocatable :: time_init(:,:)
312integer,
allocatable :: mr(:)
313integer,
allocatable :: out_of_bounds(:)
315integer,
allocatable :: vert_interp(:)
318integer,
dimension(:),
allocatable :: indexm
319integer,
dimension(:),
allocatable :: indexp
320integer,
dimension(:),
allocatable :: climatology
323logical :: separate_time_vary_calc
332logical :: module_is_initialized = .false.
333logical :: clim_diag_initialized = .false.
360integer,
parameter :: linear = 1, seasonal = 2, bilinear = 3,
notime = 4
367integer,
parameter :: pressure = 1,
sigma = 2
372integer,
parameter :: no_conv = 1,
kg_m2 = 2
378integer,
parameter,
public :: constant = 1,
zero = 2
382integer,
parameter,
public :: interp_weighted_p = 10, interp_linear_p = 20,
interp_log_p = 30
386real(r8_kind),
parameter :: tpi = (2.0_r8_kind*pi)
387real(r8_kind),
parameter :: dtr = tpi/360._r8_kind
397#ifdef ENABLE_QUAD_PRECISION
399 integer,
parameter::
f_p = r16_kind
402 integer,
parameter::
f_p = r8_kind
411namelist /interpolator_nml/ &
423 if(in%r4_type%is_allocated)
then
424 if (
allocated(in%r4_type%lat)) out%r4_type%lat = in%r4_type%lat
425 if (
allocated(in%r4_type%lon)) out%r4_type%lon = in%r4_type%lon
426 if (
allocated(in%r4_type%latb)) out%r4_type%latb = in%r4_type%latb
427 if (
allocated(in%r4_type%lonb)) out%r4_type%lonb = in%r4_type%lonb
428 if (
allocated(in%r4_type%levs)) out%r4_type%levs = in%r4_type%levs
429 if (
allocated(in%r4_type%halflevs)) out%r4_type%halflevs = in%r4_type%halflevs
430 else if(in%r8_type%is_allocated)
then
431 if (
allocated(in%r8_type%lat)) out%r8_type%lat = in%r8_type%lat
432 if (
allocated(in%r8_type%lon)) out%r8_type%lon = in%r8_type%lon
433 if (
allocated(in%r8_type%latb)) out%r8_type%latb = in%r8_type%latb
434 if (
allocated(in%r8_type%lonb)) out%r8_type%lonb = in%r8_type%lonb
435 if (
allocated(in%r8_type%levs)) out%r8_type%levs = in%r8_type%levs
436 if (
allocated(in%r8_type%halflevs)) out%r8_type%halflevs = in%r8_type%halflevs
439 out%interph = in%interph
440 if (
allocated(in%time_slice)) out%time_slice = in%time_slice
441 out%file_name = in%file_name
442 out%time_flag = in%time_flag
443 out%level_type = in%level_type
448 out%vertical_indices = in%vertical_indices
449 out%climatological_year = in%climatological_year
450 if (
allocated(in%has_level )) out%has_level = in%has_level
451 if (
allocated(in%field_name )) out%field_name = in%field_name
452 if (
allocated(in%time_init )) out%time_init = in%time_init
453 if (
allocated(in%mr )) out%mr = in%mr
454 if (
allocated(in%out_of_bounds)) out%out_of_bounds = in%out_of_bounds
455 if (
allocated(in%vert_interp )) out%vert_interp = in%vert_interp
456 if(in%r4_type%is_allocated)
then
457 if (
allocated(in%r4_type%data5d )) out%r4_type%data5d = in%r4_type%data5d
458 if (
allocated(in%r4_type%pmon_pyear )) out%r4_type%pmon_pyear = in%r4_type%pmon_pyear
459 if (
allocated(in%r4_type%pmon_nyear )) out%r4_type%pmon_nyear = in%r4_type%pmon_nyear
460 if (
allocated(in%r4_type%nmon_nyear )) out%r4_type%nmon_nyear = in%r4_type%nmon_nyear
461 if (
allocated(in%r4_type%nmon_pyear )) out%r4_type%nmon_pyear = in%r4_type%nmon_pyear
462 else if(in%r8_type%is_allocated)
then
463 if (
allocated(in%r8_type%data5d )) out%r8_type%data5d = in%r8_type%data5d
464 if (
allocated(in%r8_type%pmon_pyear )) out%r8_type%pmon_pyear = in%r8_type%pmon_pyear
465 if (
allocated(in%r8_type%pmon_nyear )) out%r8_type%pmon_nyear = in%r8_type%pmon_nyear
466 if (
allocated(in%r8_type%nmon_nyear )) out%r8_type%nmon_nyear = in%r8_type%nmon_nyear
467 if (
allocated(in%r8_type%nmon_pyear )) out%r8_type%nmon_pyear = in%r8_type%nmon_pyear
469 if (
allocated(in%indexm )) out%indexm = in%indexm
470 if (
allocated(in%indexp )) out%indexp = in%indexp
471 if (
allocated(in%climatology )) out%climatology = in%climatology
472 if (
allocated(in%clim_times )) out%clim_times = in%clim_times
473 out%separate_time_vary_calc = in%separate_time_vary_calc
474 if(in%r4_type%is_allocated)
then
475 out%r4_type%tweight = in%r4_type%tweight
476 out%r4_type%tweight1 = in%r4_type%tweight1
477 out%r4_type%tweight2 = in%r4_type%tweight2
478 out%r4_type%tweight3 = in%r4_type%tweight3
479 else if(in%r8_type%is_allocated)
then
480 out%r8_type%tweight = in%r8_type%tweight
481 out%r8_type%tweight1 = in%r8_type%tweight1
482 out%r8_type%tweight2 = in%r8_type%tweight2
483 out%r8_type%tweight3 = in%r8_type%tweight3
488 out%r4_type%is_allocated = in%r4_type%is_allocated
489 out%r8_type%is_allocated = out%r8_type%is_allocated
514character(len=*),
intent(in) ::
units
520 case(
'kg/m2',
'kg/m^2',
'kg/m**2',
'kg m^-2',
'kg m**-2')
522 case(
'molecules/cm2/s',
'molecule/cm2/s',
'molec/cm2/s')
564integer ,
intent(in) :: mod_axes(:)
567integer :: axes(2),nxd,nyd,ndivs,i
569integer :: domain_layout(2), iscomp, iecomp,jscomp,jecomp
571if(clim_type%r4_type%is_allocated)
call init_clim_diag_r4(clim_type, mod_axes, init_time)
572if(clim_type%r8_type%is_allocated)
call init_clim_diag_r8(clim_type, mod_axes, init_time)
611integer :: modyear, modmonth, modday, modhour, modminute, modsecond
612integer :: climyear, climmonth, climday, climhour, climminute, climsecond
613integer :: year1, month1, day, hour, minute, second
614integer :: climatology, m
617integer :: indexm, indexp, yearm, yearp
619character(len=256) :: err_msg
621if(clim_type%r4_type%is_allocated)
call obtain_interpolator_time_slices_r4(clim_type, time)
622if(clim_type%r8_type%is_allocated)
call obtain_interpolator_time_slices_r8(clim_type, time)
640 clim_type%separate_time_vary_calc = .false.
663if ( mpp_pe() == mpp_root_pe() )
then
664 write (logunit,
'(/,(a))')
'Exiting interpolator, have a nice day ...'
667if(clim_type%r4_type%is_allocated)
then
668 if (
allocated (clim_type%r4_type%lat ))
deallocate(clim_type%r4_type%lat)
669 if (
allocated (clim_type%r4_type%lon ))
deallocate(clim_type%r4_type%lon)
670 if (
allocated (clim_type%r4_type%latb ))
deallocate(clim_type%r4_type%latb)
671 if (
allocated (clim_type%r4_type%lonb ))
deallocate(clim_type%r4_type%lonb)
672 if (
allocated (clim_type%r4_type%levs ))
deallocate(clim_type%r4_type%levs)
673 if (
allocated (clim_type%r4_type%halflevs))
deallocate(clim_type%r4_type%halflevs)
674 if (
allocated (clim_type%r4_type%data5d ))
deallocate(clim_type%r4_type%data5d)
675else if(clim_type%r8_type%is_allocated)
then
676 if (
allocated (clim_type%r8_type%lat ))
deallocate(clim_type%r8_type%lat)
677 if (
allocated (clim_type%r8_type%lon ))
deallocate(clim_type%r8_type%lon)
678 if (
allocated (clim_type%r8_type%latb ))
deallocate(clim_type%r8_type%latb)
679 if (
allocated (clim_type%r8_type%lonb ))
deallocate(clim_type%r8_type%lonb)
680 if (
allocated (clim_type%r8_type%levs ))
deallocate(clim_type%r8_type%levs)
681 if (
allocated (clim_type%r8_type%halflevs))
deallocate(clim_type%r8_type%halflevs)
682 if (
allocated (clim_type%r8_type%data5d))
deallocate(clim_type%r8_type%data5d)
685if (
allocated (clim_type%time_slice))
deallocate(clim_type%time_slice)
686if (
allocated (clim_type%field_name))
deallocate(clim_type%field_name)
687if (
allocated (clim_type%time_init ))
deallocate(clim_type%time_init)
688if (
allocated (clim_type%has_level))
deallocate(clim_type%has_level)
689if (
allocated (clim_type%mr ))
deallocate(clim_type%mr)
690if (
allocated (clim_type%out_of_bounds ))
deallocate(clim_type%out_of_bounds)
691if (
allocated (clim_type%vert_interp ))
deallocate(clim_type%vert_interp)
692if (
allocated(clim_type%indexm))
deallocate(clim_type%indexm)
693if (
allocated(clim_type%indexp))
deallocate(clim_type%indexp)
694if (
allocated(clim_type%clim_times))
deallocate(clim_type%clim_times)
695if (
allocated(clim_type%climatology))
deallocate(clim_type%climatology)
699if(clim_type%r4_type%is_allocated)
then
700 if (
allocated(clim_type%r4_type%pmon_pyear))
then
701 deallocate(clim_type%r4_type%pmon_pyear)
702 deallocate(clim_type%r4_type%pmon_nyear)
703 deallocate(clim_type%r4_type%nmon_nyear)
704 deallocate(clim_type%r4_type%nmon_pyear)
706else if(clim_type%r8_type%is_allocated)
then
707 if (
allocated(clim_type%r8_type%pmon_pyear))
then
708 deallocate(clim_type%r8_type%pmon_pyear)
709 deallocate(clim_type%r8_type%pmon_nyear)
710 deallocate(clim_type%r8_type%nmon_nyear)
711 deallocate(clim_type%r8_type%nmon_pyear)
715clim_type%r4_type%is_allocated=.false.
716clim_type%r8_type%is_allocated=.false.
720 .and. (clim_type%TIME_FLAG.ne.
notime) )
then
726module_is_initialized = .false.
746integer,
intent(out),
optional :: nfields
747character(len=*),
dimension(:),
intent(out),
optional :: field_names
749if(
present( nfields ) ) nfields =
SIZE( clim_type%field_name(:) )
750if(
present( field_names ) ) field_names = clim_type%field_name
766character(len=*),
intent(in) :: string
767character(len=64) ::
chomp
771len = len_trim(string)
772if (string(len:len) == char(0)) len = len -1
780#include "interpolator_r4.fh"
781#include "interpolator_r8.fh"
783end module interpolator_mod
subroutine, public diag_manager_init(diag_model_subset, time_init, err_msg)
Initialize Diagnostics Manager.
Register a diagnostic field for a given module.
Send data over to output fields.
Close a netcdf or domain file opened with open_file or open_virtual_file.
Opens a given netcdf or domain file.
subroutine, public horiz_interp_init
Initialize module and writes version number to logfile.out.
subroutine, public horiz_interp_del(interp)
Deallocates memory used by "horiz_interp_type" variables. Must be called before reinitializing with h...
Subroutine for performing the horizontal interpolation between two grids.
integer nlat
No description.
subroutine, public query_interpolator(clim_type, nfields, field_names)
query_interpolator receives an interpolate type as input and returns the number of fields and field n...
integer, parameter increasing_upward
Flags to indicate direction of vertical axis in data file.
character(len=64) units
No description.
integer ndim
No description.
integer, parameter f_p
64-bit precision (kind=8)
integer ntime
No description.
subroutine, public obtain_interpolator_time_slices(clim_type, time)
obtain_interpolator_time_slices makes sure that the appropriate time slices are available for interpo...
integer, parameter sigma
Flags to indicate where climatology pressure levels are pressure or sigma levels.
integer function check_climo_units(units)
check_climo_units checks the units that the climatology data is using. This is needed to allow for co...
subroutine, public interpolate_type_eq(out, in)
Assignment overload routine for interpolate_type, to be used through the assignment interface.
integer, parameter, public zero
Flags to indicate what to do when the model surface pressure exceeds the climatology surface pressure...
integer, dimension(max_diag_fields) hinterp_id
No description.
integer nlev
No description.
logical use_mpp_io
Set to true to use mpp_io, otherwise fms2io is used.
integer, parameter max_diag_fields
No description.
character(len=64), dimension(max_diag_fields) climo_diag_name
No description.
character(len=64) function chomp(string)
chomp receives a string from NetCDF files and removes CHAR(0) from the end of this string.
integer nlon
No description.
integer, parameter kg_m2
Flags to indicate whether the climatology units are mixing ratio (kg/kg) or column integral (kg/m2)....
integer sense
No description.
integer nvar
No description.
logical retain_cm3_bug
No description.
integer verbose
No description.
logical read_all_on_init
No description.
integer nlatb
No description.
integer, parameter, public interp_log_p
Flags to indicate the type of vertical interpolation.
integer nlonb
No description.
integer nlevh
No description.
integer num_fields
No description.
integer num_clim_diag
No description.
real(r8_kind) missing_value
No description.
subroutine, public init_clim_diag(clim_type, mod_axes, init_time)
init_clim_diag is a routine to register diagnostic fields for the climatology file....
subroutine, public unset_interpolator_time_flag(clim_type)
unset_interpolator_time_flag sets a flag in clim_type to false.
integer, parameter notime
Flags to indicate whether the time interpolation should be linear or some other scheme for seasonal d...
logical conservative_interp
No description.
subroutine, public interpolator_end(clim_type)
interpolator_end receives interpolate data as input and deallocates its memory.
Private interface for weighted scalar interpolation.
Interpolates a field to a model grid.
Set up a domain decomposition.
Retrieve layout associated with a domain decomposition. Given a global 2D domain and the number of di...
These routines retrieve the axis specifications associated with the compute domains....
Fill in a global array from domain-decomposed arrays.
Performs halo updates for a given domain.
The domain2D type contains all the necessary information to define the global, compute and data domai...
Returns a weight and dates or indices for interpolating between two dates. The interface fraction_of_...
subroutine, public print_date(time, str, unit)
Prints the time to standard output (or optional unit) as a date.
integer function, public days_in_year(time)
Returns the number of days in the calendar year corresponding to the date represented by time for the...
type(time_type) function, public decrement_time(time, seconds, days, ticks, err_msg, allow_neg_inc)
Decrements a time by seconds and days.
integer function, public get_calendar_type()
Returns default calendar type for mapping from time to date.
logical function, public leap_year(time, err_msg)
Returns true if the year corresponding to the input time is a leap year (for default calendar)....
real(kind=r8_kind) function, public time_type_to_real(time)
Converts time to seconds and returns it as a real number.
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.
Allocates space and initializes a derived-type variable that contains pre-computed interpolation indi...
Redundant climatology data between fields.