42subroutine interpolator_init_( clim_type, file_name, lonb_mod, latb_mod, &
43 data_names, data_out_of_bounds, &
44 vert_interp, clim_units, single_year_file)
45type(interpolate_type),
intent(inout) :: clim_type
46character(len=*),
intent(in) :: file_name
47real(FMS_INTP_KIND_),
intent(in) :: lonb_mod(:,:), latb_mod(:,:)
48character(len=*),
intent(in) ,
optional :: data_names(:)
50integer ,
intent(in) :: data_out_of_bounds(:)
51integer ,
intent(in),
optional :: vert_interp(:)
53character(len=*),
intent(out),
optional :: clim_units(:)
54logical,
intent(out),
optional :: single_year_file
73if (.not. module_is_initialized)
then
75 call diag_manager_init
76 call horiz_interp_init
82 read (input_nml_file, nml=interpolator_nml, iostat=io)
83 ierr = check_nml_error(io,
'interpolator_nml')
86 if (retain_cm3_bug)
then
87 call mpp_error(fatal,
"interpolator_init: You have overridden the default value of " // &
88 "retain_cm3_bug and set it to .true. in interpolator_nml. This was a temporary workaround " // &
89 "that is no longer supported. Please remove this namelist variable.")
95call write_version_number(
"INTERPOLATOR_MOD", version)
97if (mpp_pe() == mpp_root_pe() )
write (stdlog(), nml=interpolator_nml)
99module_is_initialized = .true.
103 call mpp_error(fatal,
"Interpolator::nml=interpolator_nml " //&
104 'MPP_IO is no longer supported. Please remove from use_mpp_io from interpolator_nml')
107clim_type%FMS_INTP_TYPE_%is_allocated = .true.
109call fms2io_interpolator_init(clim_type, file_name, lonb_mod, latb_mod, &
110 data_names, data_out_of_bounds, &
111 vert_interp, clim_units, single_year_file)
113end subroutine interpolator_init_
115subroutine fms2io_interpolator_init_(clim_type, file_name, lonb_mod, latb_mod, &
116 data_names, data_out_of_bounds, &
117 vert_interp, clim_units, single_year_file)
119type(interpolate_type),
intent(inout) :: clim_type
120character(len=*),
intent(in) :: file_name
121real(FMS_INTP_KIND_) ,
intent(in) :: lonb_mod(:,:), latb_mod(:,:)
122character(len=*),
intent(in) ,
optional :: data_names(:)
124integer ,
intent(in) :: data_out_of_bounds(:)
125integer ,
intent(in),
optional :: vert_interp(:)
127character(len=*),
intent(out),
optional :: clim_units(:)
128logical,
intent(out),
optional :: single_year_file
130character(len=FMS_FILE_LEN) :: src_file
132real(FMS_INTP_KIND_) :: dlat, dlon
134type(time_type) :: base_time
135integer :: fileday, filemon, fileyr, filehr, filemin,filesec, m,m1
136character(len= 20) :: fileunits
137character(len=128) :: var_dimname(6)
138character(len=128),
allocatable :: var_names(:)
139integer,
allocatable :: var_ndims(:)
141logical :: non_monthly
142character(len=24) :: file_calendar
143character(len=256) :: error_mesg
144integer :: model_calendar
145integer :: yr, mo, dy, hr, mn, sc
147type(time_type) :: Julian_time, Noleap_time
148real(r8_kind),
allocatable :: time_in(:)
149real(FMS_INTP_KIND_),
allocatable,
save :: agrid_mod(:,:,:)
151type(FmsNetcdfFile_t) :: fileobj
153integer,
parameter :: lkind=fms_intp_kind_
154real(FMS_INTP_KIND_),
parameter :: lPI=real(pi,fms_intp_kind_)
159integer :: base_year, base_month, base_day, base_hour, base_minute, base_second
161logical :: noleap_file_calendar
162real(r8_kind) :: num_days, frac_year
163type(time_type) :: n_time
165clim_type%separate_time_vary_calc = .false.
172src_file =
'INPUT/'//trim(file_name)
174if(fms2_io_file_exist(trim(src_file)))
then
175 if(.not. open_file(clim_type%fileobj, trim(src_file),
'read')) &
176 call mpp_error(fatal,
'Interpolator_init: Error in opening file '//trim(src_file))
177 fileobj = clim_type%fileobj
180 call mpp_error(fatal,
'Interpolator_init : Data file '//trim(src_file)//
' does not exist')
184clim_type%file_name = trim(file_name)
185nvar = get_num_variables(fileobj)
187if(
present(data_names))
then
188 num_fields=
size(data_names(:))
190 allocate(var_names(nvar), var_ndims(nvar))
191 call get_variable_names(fileobj, var_names)
194 var_ndims(i) = get_variable_num_dimensions(fileobj, var_names(i))
196 num_fields = count(var_ndims>1)
210clim_type%level_type = 0
219 clim_type%vertical_indices = 0
222if(dimension_exists(fileobj,
"lat"))
then
223 call get_dimension_size(fileobj,
"lat", nlat)
225 call mpp_error(fatal,
'Interpolator_init : dimension lat does not exist in file '//trim(src_file) )
227allocate(clim_type%FMS_INTP_TYPE_%lat(nlat))
228call get_axis_latlon_data(fileobj,
'lat', clim_type%FMS_INTP_TYPE_%lat)
231if(dimension_exists(fileobj,
"lon"))
then
232 call get_dimension_size(fileobj,
"lon", nlon)
234 call mpp_error(fatal,
'Interpolator_init : dimension lon does not exist in file '//trim(src_file) )
236allocate(clim_type%FMS_INTP_TYPE_%lon(nlon))
237call get_axis_latlon_data(fileobj,
'lon', clim_type%FMS_INTP_TYPE_%lon)
240if(dimension_exists(fileobj,
"latb"))
then
241 call get_dimension_size(fileobj,
"latb", nlatb)
242 allocate(clim_type%FMS_INTP_TYPE_%latb(nlatb))
243 call get_axis_latlon_data(fileobj,
'latb', clim_type%FMS_INTP_TYPE_%latb)
245 if(nlat == 1)
call mpp_error(fatal,
'Interpolator_init : nlat is 1')
248 allocate(clim_type%FMS_INTP_TYPE_%latb(nlat+1))
249 dlat = (clim_type%FMS_INTP_TYPE_%lat(2)-clim_type%FMS_INTP_TYPE_%lat(1)) * 0.5_lkind
251 clim_type%FMS_INTP_TYPE_%latb(1) = min( lpi/2._lkind, max(-lpi/2._lkind, clim_type%FMS_INTP_TYPE_%lat(1) - dlat) )
252 clim_type%FMS_INTP_TYPE_%latb(2:nlat) = ( clim_type%FMS_INTP_TYPE_%lat(1:nlat-1) + &
253 clim_type%FMS_INTP_TYPE_%lat(2:nlat) ) * 0.5_lkind
254 dlat = ( clim_type%FMS_INTP_TYPE_%lat(nlat) - clim_type%FMS_INTP_TYPE_%lat(nlat-1) ) * 0.5_lkind
256 clim_type%FMS_INTP_TYPE_%latb(nlat+1) = min( lpi/2._lkind, max(-lpi/2._lkind, &
257 clim_type%FMS_INTP_TYPE_%lat(nlat) + dlat) )
261if(dimension_exists(fileobj,
"lonb"))
then
262 call get_dimension_size(fileobj,
"lonb", nlonb)
263 allocate(clim_type%FMS_INTP_TYPE_%lonb(nlonb))
264 call get_axis_latlon_data(fileobj,
'lonb', clim_type%FMS_INTP_TYPE_%lonb)
268 if (
size(clim_type%FMS_INTP_TYPE_%lon(:)) /= 1)
then
269 allocate(clim_type%FMS_INTP_TYPE_%lonb(
size(clim_type%FMS_INTP_TYPE_%lon(:))+1))
270 dlon = ( clim_type%FMS_INTP_TYPE_%lon(2)-clim_type%FMS_INTP_TYPE_%lon(1) )/2.0_lkind
271 clim_type%FMS_INTP_TYPE_%lonb(1) = clim_type%FMS_INTP_TYPE_%lon(1) - dlon
272 clim_type%FMS_INTP_TYPE_%lonb(2:) = clim_type%FMS_INTP_TYPE_%lon(1:) + dlon
276 allocate(clim_type%FMS_INTP_TYPE_%lonb(2))
277 clim_type%FMS_INTP_TYPE_%lonb(1) = -360.0_lkind*real(dtr,fms_intp_kind_)
278 clim_type%FMS_INTP_TYPE_%lonb(2) = 360.0_lkind*real(dtr,fms_intp_kind_)
279 clim_type%FMS_INTP_TYPE_%lon(1) = 0.0_lkind
284clim_type%level_type = 0
285clim_type%vertical_indices = 0
286if(dimension_exists(fileobj,
"pfull"))
then
287 call get_dimension_size(fileobj,
"pfull", nlev)
288 allocate(clim_type%FMS_INTP_TYPE_%levs(nlev))
289 call get_axis_level_data(fileobj,
'pfull', clim_type%FMS_INTP_TYPE_%levs, &
290 clim_type%level_type, clim_type%vertical_indices)
291else if(dimension_exists(fileobj,
"sigma_full"))
then
292 call get_dimension_size(fileobj,
"sigma_full", nlev)
293 allocate(clim_type%FMS_INTP_TYPE_%levs(nlev))
294 call fms2_io_read_data(fileobj,
"sigma_full", clim_type%FMS_INTP_TYPE_%levs)
295 clim_type%level_type = sigma
302 allocate( clim_type%FMS_INTP_TYPE_%levs(nlev) )
303 clim_type%FMS_INTP_TYPE_%levs = 0.0_lkind
307if(dimension_exists(fileobj,
"phalf"))
then
308 call get_dimension_size(fileobj,
"phalf", nlevh)
309 allocate(clim_type%FMS_INTP_TYPE_%halflevs(nlevh))
310 call get_axis_level_data(fileobj,
'phalf', clim_type%FMS_INTP_TYPE_%halflevs, &
311 clim_type%level_type, clim_type%vertical_indices)
312else if(dimension_exists(fileobj,
"sigma_half"))
then
313 call get_dimension_size(fileobj,
"sigma_half", nlevh)
314 allocate(clim_type%FMS_INTP_TYPE_%halflevs(nlevh))
315 call fms2_io_read_data(fileobj,
"sigma_half", clim_type%FMS_INTP_TYPE_%halflevs)
316 clim_type%level_type = sigma
318 allocate( clim_type%FMS_INTP_TYPE_%halflevs(nlev+1) )
319 clim_type%FMS_INTP_TYPE_%halflevs(1) = 0.0_lkind
320 if (clim_type%level_type == pressure)
then
321 clim_type%FMS_INTP_TYPE_%halflevs(nlev+1) = 1013.25_lkind* 100.0_lkind
322 else if (clim_type%level_type == sigma )
then
323 clim_type%FMS_INTP_TYPE_%halflevs(nlev+1) = 1.0_lkind
326 clim_type%FMS_INTP_TYPE_%halflevs(n) = 0.5_lkind*(clim_type%FMS_INTP_TYPE_%levs(n) + &
327 clim_type%FMS_INTP_TYPE_%levs(n-1))
332if(dimension_exists(fileobj,
"time"))
then
333 call get_dimension_size(fileobj,
"time", ntime)
335 call get_variable_units(fileobj,
"time", units)
336 call get_time_calendar(fileobj,
"time", file_calendar)
337 model_calendar = get_calendar_type()
345 select case(units(:3))
347 fileunits = units(12:)
348 if ( len_trim(fileunits) < 19 )
then
349 write(error_mesg,
'(A49,A,A49,A)' ) &
350 'Interpolator_init : Incorrect time units in file ', &
351 trim(file_name),
'. Expecting days since YYYY-MM-DD HH:MM:SS, found', &
353 call mpp_error(fatal,error_mesg)
355 read(fileunits(1:4) , *) fileyr
356 read(fileunits(6:7) , *) filemon
357 read(fileunits(9:10) , *) fileday
358 read(fileunits(12:13), *) filehr
359 read(fileunits(15:16), *) filemin
360 read(fileunits(18:19), *) filesec
362 fileunits = units(14:)
363 if ( len_trim(fileunits) < 19 )
then
364 write(error_mesg,
'(A49,A,A51,A)' ) &
365 'Interpolator_init : Incorrect time units in file ', &
366 trim(file_name),
'. Expecting months since YYYY-MM-DD HH:MM:SS, found', &
368 call mpp_error(fatal,error_mesg)
370 read(fileunits(1:4) , *) fileyr
371 read(fileunits(6:7) , *) filemon
372 read(fileunits(9:10) , *) fileday
373 read(fileunits(12:13), *) filehr
374 read(fileunits(15:16), *) filemin
375 read(fileunits(18:19), *) filesec
377 fileunits = units(13:)
378 if ( len_trim(fileunits) < 19 )
then
379 write(error_mesg,
'(A49,A,A51,A)' ) &
380 'Interpolator_init : Incorrect time units in file ', &
381 trim(file_name),
'. Expecting years since YYYY-MM-DD HH:MM:SS, found', &
383 call mpp_error(fatal,error_mesg)
385 read(fileunits(1:4) , *) fileyr
386 read(fileunits(6:7) , *) filemon
387 read(fileunits(9:10) , *) fileday
388 read(fileunits(12:13), *) filehr
389 read(fileunits(15:16), *) filemin
390 read(fileunits(18:19), *) filesec
393 call mpp_error(fatal,
'Interpolator_init : Time units not recognized in file '//file_name)
396 clim_type%climatological_year = (fileyr == 0)
398 if (.not. clim_type%climatological_year)
then
404 noleap_file_calendar=.false.
405 if ( (model_calendar == julian .and. trim(adjustl(lowercase(file_calendar))) ==
'julian'))
then
406 call mpp_error (note,
'interpolator_mod: Model and file&
407 & calendars are the same for file ' // &
408 & trim(file_name) //
'; no calendar conversion &
410 base_time = set_date(fileyr, filemon, fileday, filehr,filemin,filesec)
411 noleap_file_calendar=.false.
412 else if((model_calendar == noleap .and. trim(adjustl(lowercase(file_calendar))) ==
'noleap') )
then
413 call mpp_error (note,
'interpolator_mod: Model and file&
414 & calendars are the same for file ' // &
415 & trim(file_name) //
'; no calendar conversion &
417 base_time = set_date(fileyr, filemon, fileday, filehr,filemin,filesec)
418 noleap_file_calendar=.true.
419 else if ( (model_calendar == julian .and. trim(adjustl(lowercase(file_calendar))) ==
'noleap'))
then
420 call mpp_error (note,
'interpolator_mod: Using julian &
421 &model calendar and noleap file calendar&
422 & for file ' // trim(file_name) // &
423 &
'; calendar conversion needed')
424 base_time = set_date_no_leap(fileyr, filemon, fileday,filehr, filemin, filesec)
425 noleap_file_calendar=.true.
426 else if ( (model_calendar == noleap .and. trim(adjustl(lowercase(file_calendar))) ==
'julian'))
then
427 call mpp_error (note,
'interpolator_mod: Using noleap &
428 &model calendar and julian file calendar&
429 & for file ' // trim(file_name) // &
430 &
'; calendar conversion needed')
431 base_time = set_date_julian(fileyr, filemon, fileday,filehr, filemin, filesec)
432 noleap_file_calendar=.false.
434 call mpp_error (fatal ,
'interpolator_mod: Model and file&
435 & calendars ( ' // trim(file_calendar) //
' ) differ &
436 &for file ' // trim(file_name) //
'; this calendar &
437 &conversion not currently available')
449 base_time = get_base_time()
455 allocate(time_in(ntime), clim_type%time_slice(ntime))
456 allocate(clim_type%clim_times(12,(ntime+11)/12))
457 time_in = 0.0_r8_kind
458 clim_type%time_slice = set_time(0,0) + base_time
459 clim_type%clim_times = set_time(0,0) + base_time
460 call fms2_io_read_data(fileobj,
"time", time_in)
465 if(.not.noleap_file_calendar)
then
467 num_years = int(time_in(n))
468 frac_year = time_in(n) - real(num_years, r8_kind)
469 call get_date_julian(base_time, base_year, base_month, base_day, base_hour, base_minute, base_second)
470 num_days = 0.0_r8_kind
472 if( mod(base_year+nn-1,4)==0) num_days = num_days + 366._r8_kind
473 if( mod(base_year+nn-1,4)/=0) num_days = num_days + 365._r8_kind
475 if( mod(base_year+num_years,4)==0) num_days = num_days + 366._r8_kind*frac_year
476 if( mod(base_year+num_years,4)/=0) num_days = num_days + 365._r8_kind*frac_year
478 num_days = time_in(n)*365._r8_kind
485 non_monthly = .false.
488 if (time_in(n+1) > (time_in(n) + 32._r8_kind))
then
493 if (clim_type%climatological_year)
then
494 call mpp_error (note,
'interpolator_mod :' // &
495 & trim(file_name) //
' is a year-independent climatology file')
497 call mpp_error (note,
'interpolator_mod :' // &
498 & trim(file_name) //
' is a timeseries file')
505 if (clim_type%climatological_year)
then
511 clim_type%time_slice(n) = set_time( int( (time_in(n)-real(int(time_in(n)),r8_kind))*seconds_per_day), &
524 if ( (model_calendar == julian .and. trim(adjustl(lowercase(file_calendar))) ==
'julian') .or. &
525 & (model_calendar == noleap .and. trim(adjustl(lowercase(file_calendar))) ==
'noleap') )
then
530 clim_type%time_slice(n) = &
531 set_time( int( (time_in(n)-real(int(time_in(n)),r8_kind))*seconds_per_day), &
532 int(time_in(n))) + base_time
537 else if ( (model_calendar == julian .and. trim(adjustl(lowercase(file_calendar))) ==
'noleap'))
then
538 noleap_time = set_time(0, int(time_in(n))) + base_time
539 call get_date_no_leap (noleap_time, yr, mo, dy, hr, mn, sc)
540 clim_type%time_slice(n) = set_date_julian(yr, mo, dy, hr, mn, sc)
542 call print_date (clim_type%time_slice(1), &
543 str=
'for file ' // trim(file_name) //
', the first time slice is mapped to :')
546 call print_date (clim_type%time_slice(ntime), &
547 str=
'for file ' // trim(file_name) //
', the last time slice is mapped to:')
554 else if ( (model_calendar == noleap .and. trim(adjustl(lowercase(file_calendar))) ==
'julian'))
then
555 julian_time = set_time(0, int(time_in(n))) + base_time
556 call get_date_julian (julian_time, yr, mo, dy, hr, mn, sc)
557 clim_type%time_slice(n) = set_date_no_leap(yr, mo, dy,hr, mn, sc)
559 call print_date (clim_type%time_slice(1), &
560 str=
'for file ' // trim(file_name) //
', the first time slice is mapped to :')
563 call print_date (clim_type%time_slice(ntime), &
564 str=
'for file ' // trim(file_name) //
', the last time slice is mapped to:')
574 m = (n-1)/12 +1 ; m1 = n- (m-1)*12
575 clim_type%clim_times(m1,m) = clim_type%time_slice(n)
578 allocate(time_in(1), clim_type%time_slice(1))
579 allocate(clim_type%clim_times(1,1))
580 time_in = 0.0_r8_kind
581 clim_type%time_slice = set_time(0,0) + base_time
582 clim_type%clim_times(1,1) = set_time(0,0) + base_time
586 call mpp_error(fatal,
'Interpolator_init: time axis does not exist in file '//trim(src_file))
591 if (conservative_interp)
then
592 call horiz_interp_new (clim_type%interph, &
593 clim_type%FMS_INTP_TYPE_%lonb, clim_type%FMS_INTP_TYPE_%latb, &
597 call mpp_error(note,
"Using Bilinear interpolation")
600 if (.not.
allocated(agrid_mod))
then
601 nx =
size(lonb_mod,1)-1
602 ny =
size(latb_mod,2)-1
603 allocate(agrid_mod(nx,ny,2))
606 call cell_center2((/lonb_mod(i,j),latb_mod(i,j)/), &
607 (/lonb_mod(i+1,j),latb_mod(i+1,j)/), &
608 (/lonb_mod(i,j+1),latb_mod(i,j+1)/), &
609 (/lonb_mod(i+1,j+1),latb_mod(i+1,j+1)/), agrid_mod(i,j,:))
616 call horiz_interp_new (clim_type%interph, &
617 clim_type%FMS_INTP_TYPE_%lonb, clim_type%FMS_INTP_TYPE_%latb, &
618 agrid_mod(:,:,1), agrid_mod(:,:,2), interp_method=
"bilinear")
639 if (non_monthly)
then
642 allocate(clim_type%FMS_INTP_TYPE_%pmon_pyear(
size(lonb_mod,1)-1,
size(latb_mod,2)-1, nlev, num_fields))
643 allocate(clim_type%FMS_INTP_TYPE_%pmon_nyear(
size(lonb_mod,1)-1,
size(latb_mod,2)-1, nlev, num_fields))
644 allocate(clim_type%FMS_INTP_TYPE_%nmon_nyear(
size(lonb_mod,1)-1,
size(latb_mod,2)-1, nlev, num_fields))
645 allocate(clim_type%FMS_INTP_TYPE_%nmon_pyear(
size(lonb_mod,1)-1,
size(latb_mod,2)-1, nlev, num_fields))
646 clim_type%FMS_INTP_TYPE_%pmon_pyear = 0.0_lkind
647 clim_type%FMS_INTP_TYPE_%pmon_nyear = 0.0_lkind
648 clim_type%FMS_INTP_TYPE_%nmon_nyear = 0.0_lkind
649 clim_type%FMS_INTP_TYPE_%nmon_pyear = 0.0_lkind
650 clim_type%TIME_FLAG = bilinear
653 if ( .not. read_all_on_init)
then
654 allocate(clim_type%FMS_INTP_TYPE_%data5d(
size(lonb_mod,1)-1,
size(latb_mod,2)-1, nlev, 2, num_fields))
656 allocate(clim_type%FMS_INTP_TYPE_%data5d(
size(lonb_mod,1)-1,
size(latb_mod,2)-1, nlev, &
659 clim_type%FMS_INTP_TYPE_%data5d = 0.0_lkind
660 clim_type%TIME_FLAG = linear
670 if ( .not. read_all_on_init)
then
671 allocate(clim_type%FMS_INTP_TYPE_%data5d(
size(lonb_mod,1)-1,
size(latb_mod,2)-1, nlev, 2, num_fields))
673 allocate(clim_type%FMS_INTP_TYPE_%data5d(
size(lonb_mod,1)-1,
size(latb_mod,2)-1, nlev, &
676 clim_type%FMS_INTP_TYPE_%data5d = 0.0_lkind
677 clim_type%TIME_FLAG = linear
689 clim_type%TIME_FLAG = notime
690 allocate(clim_type%FMS_INTP_TYPE_%data5d(
size(lonb_mod,1)-1,
size(latb_mod,2)-1, nlev, 1, num_fields))
699 if(clim_type%TIME_FLAG .eq. linear )
then
700 allocate(clim_type%time_init(num_fields,2))
702 allocate(clim_type%time_init(num_fields,ntime))
704 allocate (clim_type%indexm(num_fields), &
705 clim_type%indexp(num_fields), &
706 clim_type%climatology(num_fields))
707 clim_type%time_init(:,:) = 0
708 clim_type%indexm(:) = 0
709 clim_type%indexp(:) = 0
710 clim_type%climatology(:) = 0
712allocate(clim_type%has_level(num_fields))
713allocate(clim_type%field_name(num_fields))
714allocate(clim_type%mr(num_fields))
715allocate(clim_type%out_of_bounds(num_fields))
716clim_type%out_of_bounds(:)=0
717allocate(clim_type%vert_interp(num_fields))
718clim_type%vert_interp(:)=0
720if(
present(data_names))
then
723 if (
size(data_out_of_bounds(:)) /=
size(data_names(:)) .and.
size(data_out_of_bounds(:)) /= 1 ) &
724 call mpp_error(fatal,
'interpolator_init : The size of the data_out_of_bounds array must be 1&
725 & or size(data_names)')
726 if (
present(vert_interp))
then
727 if(
size(vert_interp(:)) /=
size(data_names(:)) .and.
size(vert_interp(:)) /= 1 ) &
728 call mpp_error(fatal,
'interpolator_init : The size of the vert_interp array must be 1&
729 & or size(data_names)')
732 do j=1,
size(data_names(:))
733 if(variable_exists(fileobj, data_names(j)) )
then
734 call get_variable_units(fileobj, data_names(j), units)
735 ndim = get_variable_num_dimensions(fileobj, data_names(j))
736 clim_type%has_level(j) = .false.
738 call get_variable_dimension_names(fileobj, data_names(j), var_dimname(1:ndim))
739 if(trim(var_dimname(3)) ==
"pfull" .OR. trim(var_dimname(3)) ==
"sigma_full") &
740 & clim_type%has_level(j) = .true.
744 if (mpp_pe() == 0 )
write(*,*)
'Initializing src field : ',trim(data_names(j))
745 clim_type%field_name(j) = data_names(j)
746 clim_type%mr(j) = check_climo_units(units)
747 if (
present(clim_units)) clim_units(j) = units
748 clim_type%out_of_bounds(j) = data_out_of_bounds( min(j,
SIZE(data_out_of_bounds(:))) )
749 if( clim_type%out_of_bounds(j) /= constant .and. clim_type%out_of_bounds(j) /= zero ) &
750 call mpp_error(fatal,
"Interpolator_init: data_out_of_bounds must be&
751 & set to ZERO or CONSTANT")
752 if(
present(vert_interp) )
then
753 clim_type%vert_interp(j) = vert_interp( min(j,
SIZE(vert_interp(:))) )
754 if( clim_type%vert_interp(j) /= interp_weighted_p .and. clim_type%vert_interp(j) /= interp_linear_p ) &
755 call mpp_error(fatal,
"Interpolator_init: vert_interp must be&
756 & set to INTERP_WEIGHTED_P or INTERP_LINEAR_P")
758 clim_type%vert_interp(j) = interp_weighted_p
761 call mpp_error(fatal,
'interpolator_init : Check names of fields being passed. ' &
762 &//trim(data_names(j))//
' does not exist.')
766 if (
size(data_out_of_bounds(:)) /= nvar .and.
size(data_out_of_bounds(:)) /= 1 ) &
767 call mpp_error(fatal,
'interpolator_init : The size of the out of bounds array must be 1&
768 & or the number of fields in the climatology dataset')
769 if (
present(vert_interp) )
then
770 if (
size(vert_interp(:)) /= nvar .and.
size(vert_interp(:)) /= 1 ) &
771 call mpp_error(fatal,
'interpolator_init : The size of the vert_interp array must be 1&
772 & or the number of fields in the climatology dataset')
779 if(ndim .LE. 1) cycle
781 clim_type%has_level(j) = .false.
783 call get_variable_dimension_names(fileobj, var_names(i), var_dimname(1:ndim))
784 if(trim(var_dimname(3)) ==
"pfull" .OR. trim(var_dimname(3)) ==
"sigma_full") clim_type%has_level(j) = .true.
787 call get_variable_units(fileobj, var_names(i), units)
788 if (mpp_pe() ==0 )
write(*,*)
'Initializing src field : ',trim(var_names(i))
789 clim_type%field_name(j) = trim(var_names(i))
790 clim_type%mr(j) = check_climo_units(units)
791 if (
present(clim_units)) clim_units(j) = units
792 clim_type%out_of_bounds(j) = data_out_of_bounds( min(i,
SIZE(data_out_of_bounds(:))) )
793 if( clim_type%out_of_bounds(j) /= constant .and. &
794 clim_type%out_of_bounds(j) /= zero ) &
795 call mpp_error(fatal,
"Interpolator_init: data_out_of_bounds must be&
796 & set to ZERO or CONSTANT")
797 if(
present(vert_interp) )
then
798 clim_type%vert_interp(j) = vert_interp( min(i,
SIZE(vert_interp(:))) )
799 if( clim_type%vert_interp(j) /= interp_weighted_p .and. &
800 clim_type%vert_interp(j) /= interp_linear_p ) &
801 call mpp_error(fatal,
"Interpolator_init: vert_interp must be&
802 & set to INTERP_WEIGHTED_P or INTERP_LINEAR_P")
804 clim_type%vert_interp(j) = interp_weighted_p
807 if(j .NE. num_fields)
call mpp_error(fatal,
"Interpolator_init: j does not equal to num_fields")
808 deallocate(var_names, var_ndims)
812if( clim_type%TIME_FLAG .eq. seasonal )
then
816 call read_data( clim_type, clim_type%field_name(i), &
817 clim_type%FMS_INTP_TYPE_%data5d(:,:,:,n,i), n, i, base_time )
822if( clim_type%TIME_FLAG .eq. linear .and. read_all_on_init)
then
826 call read_data( clim_type, clim_type%field_name(i), &
827 clim_type%FMS_INTP_TYPE_%data5d(:,:,:,n,i), n, i, base_time )
831 call close_file (fileobj)
834if( clim_type%TIME_FLAG .eq. notime )
then
837 call read_data_no_time_axis( clim_type, clim_type%field_name(i), &
838 clim_type%FMS_INTP_TYPE_%data5d(:,:,:,1,i), i )
840 call close_file (fileobj)
843if (
present (single_year_file))
then
844 single_year_file = clim_type%climatological_year
847end subroutine fms2io_interpolator_init_
849subroutine get_axis_latlon_data_(fileobj, name, latlon_data)
850 type(FmsNetcdfFile_t),
intent(in) :: fileobj
851 character(len=*),
intent(in) :: name
852 real(FMS_INTP_KIND_),
dimension(:),
intent(out) :: latlon_data
855 if(variable_exists(fileobj, name))
then
856 call fms2_io_read_data(fileobj, name, latlon_data)
858 call mpp_error(fatal,
'get_axis_latlon_data: variable '// &
859 & trim(name)//
' does not exist in file '//trim(fileobj%path) )
861 call get_variable_units(fileobj, name, units)
862 select case(units(1:6))
864 latlon_data = latlon_data*real(dtr,fms_intp_kind_)
867 call mpp_error(fatal,
"get_axis_latlon_data : Units for '// &
868 & trim(name)//' not recognised in file "//trim(fileobj%path))
871 end subroutine get_axis_latlon_data_
874subroutine get_axis_level_data_(fileobj, name, level_data, level_type, vertical_indices)
875 type(FmsNetcdfFile_t),
intent(in) :: fileobj
876 character(len=*),
intent(in) :: name
877 real(FMS_INTP_KIND_),
dimension(:),
intent(out) :: level_data
878 integer,
intent(out) :: level_type, vertical_indices
879 real(FMS_INTP_KIND_),
dimension(:),
allocatable :: alpha
882 integer,
parameter :: lkind=fms_intp_kind_
884 if(variable_exists(fileobj, name))
then
885 call fms2_io_read_data(fileobj, name, level_data)
887 call mpp_error(fatal,
'get_axis_level_data: variable '// &
888 & trim(name)//
' does not exist in file '//trim(fileobj%path) )
890 call get_variable_units(fileobj, name, units)
891 level_type = pressure
893 if( trim(adjustl(lowercase(chomp(units)))) ==
"mb" .or. trim(adjustl(lowercase(chomp(units)))) ==
"hpa")
then
894 level_data = level_data * 100._lkind
896 nlev =
size(level_data(:))
897 sense = get_variable_sense(fileobj, name)
901 if( sense == 1 )
then
902 vertical_indices = increasing_upward
903 allocate (alpha(nlev))
905 alpha(n) = level_data(nlev-n+1)
908 level_data(n) = alpha(n)
912 vertical_indices = increasing_downward
916end subroutine get_axis_level_data_
930 subroutine cell_center2_(q1, q2, q3, q4, e2)
931 real(FMS_INTP_KIND_) ,
intent(in ) :: q1(2), q2(2), q3(2), q4(2)
932 real(FMS_INTP_KIND_) ,
intent(out) :: e2(2)
934 real(FMS_INTP_KIND_) :: p1(3), p2(3), p3(3), p4(3)
935 real(FMS_INTP_KIND_) :: ec(3,1)
936 real(FMS_INTP_KIND_) :: dd
939 call latlon2xyz(q1, p1)
940 call latlon2xyz(q2, p2)
941 call latlon2xyz(q3, p3)
942 call latlon2xyz(q4, p4)
945 ec(k,1) = p1(k) + p2(k) + p3(k) + p4(k)
947 dd = sqrt( ec(1,1)**2 + ec(2,1)**2 + ec(3,1)**2 )
950 ec(k,1) = ec(k,1) / dd
953 call cart_to_latlon(1, ec, e2(1:1), e2(2:2))
955 end subroutine cell_center2_
965 subroutine cart_to_latlon_(np, q, xs, ys)
967 integer,
intent(in):: np
968 real(FMS_INTP_KIND_),
intent(inout):: q(3,np)
969 real(FMS_INTP_KIND_),
intent(inout):: xs(np), ys(np)
971 real(f_p),
parameter:: esl=1.e-10_f_p
973 real(f_p):: dist, lat, lon
978 p(k) = real(q(k,i), f_p)
980 dist = sqrt(p(1)**2 + p(2)**2 + p(3)**2)
985 if ( (abs(p(1))+abs(p(2))) < esl )
then
988 lon = atan2( p(2), p(1) )
991 if ( lon < 0._f_p ) lon = 2._f_p*real(pi,f_p) + lon
994 xs(i) = real(lon,fms_intp_kind_)
995 ys(i) = real(lat,fms_intp_kind_)
998 q(k,i) = real(p(k),fms_intp_kind_)
1002 end subroutine cart_to_latlon_
1010 subroutine latlon2xyz_(p, e)
1014 real(FMS_INTP_KIND_),
intent(in) :: p(2)
1015 real(FMS_INTP_KIND_),
intent(out):: e(3)
1019 real (f_p):: e1, e2, e3
1022 q(n) = real(p(n),f_p)
1025 e1 = cos(q(2)) * cos(q(1))
1026 e2 = cos(q(2)) * sin(q(1))
1031 e(1) = real(e1,fms_intp_kind_)
1032 e(2) = real(e2,fms_intp_kind_)
1033 e(3) = real(e3,fms_intp_kind_)
1035 end subroutine latlon2xyz_
1055subroutine init_clim_diag_(clim_type, mod_axes, init_time)
1071type(interpolate_type),
intent(inout) :: clim_type
1072integer ,
intent(in) :: mod_axes(:)
1073type(time_type) ,
intent(in) :: init_time
1075integer :: axes(2),nxd,nyd,ndivs,i
1076type(domain2d) :: domain
1077integer :: domain_layout(2), iscomp, iecomp,jscomp,jecomp
1080if (.not. module_is_initialized .or. .not.
allocated(clim_type%FMS_INTP_TYPE_%lon)) &
1081 call mpp_error(fatal,
"init_clim_diag : You must call interpolator_init before calling init_clim_diag")
1085nxd =
size(clim_type%FMS_INTP_TYPE_%lon(:))
1086nyd =
size(clim_type%FMS_INTP_TYPE_%lat(:))
1089call mpp_define_layout ((/1,nxd,1,nyd/), ndivs, domain_layout)
1090call mpp_define_domains((/1,nxd,1,nyd/),domain_layout, domain,xhalo=0,yhalo=0)
1091call mpp_get_compute_domain(domain, iscomp, iecomp, jscomp, jecomp)
1092axes(1) = diag_axis_init(clim_type%file_name(1:5)//
'x',clim_type%FMS_INTP_TYPE_%lon,units=
'degrees',&
1093 cart_name=
'x',domain2=domain)
1094axes(2) = diag_axis_init(clim_type%file_name(1:5)//
'y',clim_type%FMS_INTP_TYPE_%lat,units=
'degrees',&
1095 cart_name=
'y',domain2=domain)
1096clim_type%is = iscomp
1097clim_type%ie = iecomp
1098clim_type%js = jscomp
1099clim_type%je = jecomp
1103if ((num_clim_diag +
size(clim_type%field_name(:))) .gt. max_diag_fields ) &
1104 call mpp_error(fatal,
"init_clim_diag : Trying to set up too many diagnostic fields for the climatology data")
1105do i=1,
size(clim_type%field_name(:))
1106climo_diag_name(i+num_clim_diag) = clim_type%field_name(i)
1107climo_diag_id(i+num_clim_diag) = register_diag_field(
'climo',clim_type%field_name(i),axes(1:2),init_time,&
1108 'climo_'//clim_type%field_name(i),
'kg/kg', missing_value)
1109hinterp_id(i+num_clim_diag) = register_diag_field(
'hinterp',clim_type%field_name(i),mod_axes(1:2),init_time,&
1110 'interp_'//clim_type%field_name(i),
'kg/kg' , missing_value)
1115num_clim_diag = num_clim_diag+
size(clim_type%field_name(:))
1117clim_diag_initialized = .true.
1119end subroutine init_clim_diag_
1141subroutine obtain_interpolator_time_slices_ (clim_type, Time)
1152type(interpolate_type),
intent(inout) :: clim_type
1153type(time_type) ,
intent(in) :: Time
1155integer :: taum, taup
1156integer :: modyear, modmonth, modday, modhour, modminute, modsecond
1157integer :: climyear, climmonth, climday, climhour, climminute, climsecond
1158integer :: year1, month1, day, hour, minute, second
1159integer :: climatology, m
1160type(time_type) :: t_prev, t_next
1161type(time_type),
dimension(2) :: month
1162integer :: indexm, indexp, yearm, yearp
1164character(len=256) :: err_msg
1166integer,
parameter :: lkind=fms_intp_kind_
1168 if (clim_type%climatological_year)
then
1170 if (
size(clim_type%time_slice) > 1)
then
1171 call time_interp(time, clim_type%time_slice, clim_type%FMS_INTP_TYPE_%tweight, &
1172 taum, taup, modtime=year, err_msg=err_msg )
1173 if(trim(err_msg) /=
'')
then
1174 call mpp_error(fatal,
'interpolator_timeslice 1: '// &
1175 & trim(err_msg)//
' file='//trim(clim_type%file_name), fatal)
1180 clim_type%FMS_INTP_TYPE_%tweight = 0._lkind
1184 call time_interp(time, clim_type%time_slice, clim_type%FMS_INTP_TYPE_%tweight, taum, taup, err_msg=err_msg )
1185 if(trim(err_msg) /=
'')
then
1186 call mpp_error(fatal,
'interpolator_timeslice 2: '//trim(err_msg)//
' file='//trim(clim_type%file_name), fatal)
1190 if(clim_type%TIME_FLAG .eq. bilinear )
then
1192 if ( (time - clim_type%time_slice(taum) ) > ( clim_type%time_slice(2)- clim_type%time_slice(1) ) .or. &
1193 (clim_type%time_slice(taup) - time) > ( clim_type%time_slice(2)- clim_type%time_slice(1) ) )
then
1204 call get_date(time, modyear, modmonth, modday, modhour, modminute, modsecond)
1205 call get_date(clim_type%time_slice(taum), climyear, climmonth, climday, climhour, climminute, climsecond)
1208 do m = 1,
size(clim_type%clim_times(:,:),2)
1210 call get_date(clim_type%clim_times(1,m), year1, month1, day, hour, minute, second)
1211 if (year1 == climyear) climatology = m
1215 call get_date(clim_type%clim_times(m,climatology), year1, month1, day, hour, minute, second)
1216 if ( month1 == modmonth )
then
1218 if ( modday < day )
then
1219 indexm = m-1 ; indexp = m
1221 indexm = m ; indexp = m+1
1226 if ( indexm == 0 )
then
1232 call get_date(clim_type%time_slice(indexm+(climatology-1)*12), &
1233 climyear, climmonth, climday, climhour, climminute, climsecond)
1234 month(1) = set_date(yearm, indexm, climday, climhour, climminute, climsecond)
1235 if ( indexp == 13 )
then
1241 call get_date(clim_type%time_slice(indexp+(climatology-1)*12), &
1242 climyear, climmonth, climday, climhour, climminute, climsecond)
1243 month(2) = set_date(yearp, indexp, climday, climhour, climminute, climsecond)
1245 call time_interp(time, month, clim_type%FMS_INTP_TYPE_%tweight3, taum, taup, err_msg=err_msg )
1248 if (taum==2 .and. taup==2) clim_type%FMS_INTP_TYPE_%tweight3 = 1._lkind
1249 if(trim(err_msg) /=
'')
then
1250 call mpp_error(fatal,
'interpolator_timeslice 3: '//trim(err_msg)//
' file='//trim(clim_type%file_name), fatal)
1253 month(1) = clim_type%time_slice(indexm+(climatology-1)*12)
1254 month(2) = clim_type%time_slice(indexm+climatology*12)
1255 call get_date(month(1), climyear, climmonth, climday, climhour, climminute, climsecond)
1256 t_prev = set_date(yearm, climmonth, climday, climhour, climminute, climsecond)
1257 call time_interp(t_prev, month, clim_type%FMS_INTP_TYPE_%tweight1, taum, taup, err_msg=err_msg )
1260 if (taum==2 .and. taup==2) clim_type%FMS_INTP_TYPE_%tweight1 = 1._lkind
1261 if(trim(err_msg) /=
'')
then
1262 call mpp_error(fatal,
'interpolator_timeslice 4: '// &
1263 & trim(err_msg)//
' file='//trim(clim_type%file_name), fatal)
1266 month(1) = clim_type%time_slice(indexp+(climatology-1)*12)
1267 month(2) = clim_type%time_slice(indexp+climatology*12)
1268 call get_date(month(1), climyear, climmonth, climday, climhour, climminute, climsecond)
1269 t_next = set_date(yearp, climmonth, climday, climhour, climminute, climsecond)
1270 call time_interp(t_next, month, clim_type%FMS_INTP_TYPE_%tweight2, taum, taup, err_msg=err_msg )
1273 if (taum==2 .and. taup==2) clim_type%FMS_INTP_TYPE_%tweight2 = 1._lkind
1274 if(trim(err_msg) /=
'')
then
1275 call mpp_error(fatal,
'interpolator_timeslice 5: '// &
1276 & trim(err_msg)//
' file='//trim(clim_type%file_name), fatal)
1279 if (indexm == clim_type%indexm(1) .and. &
1280 indexp == clim_type%indexp(1) .and. &
1281 climatology == clim_type%climatology(1))
then
1283 clim_type%indexm(:) = indexm
1284 clim_type%indexp(:) = indexp
1285 clim_type%climatology(:) = climatology
1286 do i=1,
size(clim_type%field_name(:))
1287 call read_data(clim_type,clim_type%field_name(i), &
1288 clim_type%FMS_INTP_TYPE_%pmon_pyear(:,:,:,i), &
1289 clim_type%indexm(i)+(clim_type%climatology(i)-1)*12,i,time)
1291 call read_data(clim_type,clim_type%field_name(i), &
1292 clim_type%FMS_INTP_TYPE_%nmon_pyear(:,:,:,i), &
1293 clim_type%indexp(i)+(clim_type%climatology(i)-1)*12,i,time)
1294 call read_data(clim_type,clim_type%field_name(i), &
1295 clim_type%FMS_INTP_TYPE_%pmon_nyear(:,:,:,i), &
1296 clim_type%indexm(i)+clim_type%climatology(i)*12,i,time)
1297 call read_data(clim_type,clim_type%field_name(i), &
1298 clim_type%FMS_INTP_TYPE_%nmon_nyear(:,:,:,i), &
1299 clim_type%indexp(i)+clim_type%climatology(i)*12,i,time)
1306 do i=1,
size(clim_type%field_name(:))
1307 if (taum /= clim_type%time_init(i,1) .or. &
1308 taup /= clim_type%time_init(i,2) )
then
1311 call read_data(clim_type,clim_type%field_name(i), &
1312 clim_type%FMS_INTP_TYPE_%pmon_pyear(:,:,:,i), taum,i,time)
1314 call read_data(clim_type,clim_type%field_name(i), &
1315 clim_type%FMS_INTP_TYPE_%nmon_pyear(:,:,:,i), taup,i,time)
1316 clim_type%time_init(i,1) = taum
1317 clim_type%time_init(i,2) = taup
1326 clim_type%indexm(:) = 0
1327 clim_type%indexp(:) = 0
1328 clim_type%climatology(:) = 0
1332 clim_type%FMS_INTP_TYPE_%tweight1 = 0.0_lkind
1333 clim_type%FMS_INTP_TYPE_%tweight2 = 0.0_lkind
1334 clim_type%FMS_INTP_TYPE_%tweight3 = clim_type%FMS_INTP_TYPE_%tweight
1338 if(clim_type%TIME_FLAG .eq. linear .and. &
1339 (.not. read_all_on_init) )
then
1343 do n=1,
size(clim_type%time_init,2)
1344 if (clim_type%time_init(1,n) .eq. taum ) clim_type%itaum = n
1345 if (clim_type%time_init(1,n) .eq. taup ) clim_type%itaup = n
1348 if (clim_type%itaum.eq.0 .and. clim_type%itaup.eq.0)
then
1353 do i=1,
size(clim_type%field_name(:))
1354 call read_data(clim_type,clim_type%field_name(i), clim_type%FMS_INTP_TYPE_%data5d(:,:,:,1,i), taum,i,time)
1355 clim_type%time_init(i,1) = taum
1357 call read_data(clim_type,clim_type%field_name(i), clim_type%FMS_INTP_TYPE_%data5d(:,:,:,2,i), taup,i,time)
1358 clim_type%time_init(i,2) = taup
1362 if (clim_type%itaum.eq.0 .and. clim_type%itaup.ne.0)
then
1364 call mpp_error(fatal,
'interpolator_timeslice : No data from the previous climatology time &
1365 & but we have the next time. How did this happen?')
1367 if (clim_type%itaum.ne.0 .and. clim_type%itaup.eq.0)
then
1370 if (clim_type%itaum .eq. 1 ) clim_type%itaup = 2
1371 do i=1,
size(clim_type%field_name(:))
1372 call read_data(clim_type,clim_type%field_name(i), &
1373 clim_type%FMS_INTP_TYPE_%data5d(:,:,:,clim_type%itaup,i), taup,i, time)
1374 clim_type%time_init(i,clim_type%itaup)=taup
1381 clim_type%separate_time_vary_calc = .true.
1386 end subroutine obtain_interpolator_time_slices_
1420subroutine interpolator_4d_(clim_type, Time, phalf, interp_data, &
1421 field_name, is,js, clim_units)
1441type(interpolate_type),
intent(inout) :: clim_type
1442character(len=*) ,
intent(in) :: field_name
1443type(time_type) ,
intent(in) :: Time
1444real(FMS_INTP_KIND_),
dimension(:,:,:),
intent(in) :: phalf
1445real(FMS_INTP_KIND_),
dimension(:,:,:,:),
intent(out) :: interp_data
1446integer ,
intent(in) ,
optional :: is,js
1447character(len=*) ,
intent(out),
optional :: clim_units
1448integer :: taum, taup, ilon
1449real(FMS_INTP_KIND_) :: hinterp_data(size(interp_data,1),size(interp_data,2),&
1450 size(clim_type%FMS_INTP_TYPE_%levs(:)),size(clim_type%field_name(:)))
1451real(FMS_INTP_KIND_) :: p_fact(size(interp_data,1),size(interp_data,2))
1452real(FMS_INTP_KIND_) :: col_data(size(interp_data,1),size(interp_data,2), &
1453 size(clim_type%field_name(:)))
1454real(FMS_INTP_KIND_) :: pclim(size(clim_type%FMS_INTP_TYPE_%halflevs(:)))
1455integer :: istart,iend,jstart,jend
1456logical :: result, found
1457logical :: found_field=.false.
1458integer :: modyear, modmonth, modday, modhour, modminute, modsecond
1459integer :: climyear, climmonth, climday, climhour, climminute, climsecond
1460integer :: year1, month1, day, hour, minute, second
1461integer :: climatology, m
1462type(time_type) :: t_prev, t_next
1463type(time_type),
dimension(2) :: month
1464integer :: indexm, indexp, yearm, yearp
1465integer :: i, j, k, n
1466character(len=256) :: err_msg
1468integer,
parameter :: lkind=fms_intp_kind_
1470if (.not. module_is_initialized .or. .not.
allocated(clim_type%FMS_INTP_TYPE_%lon)) &
1471 call mpp_error(fatal,
"interpolator_4D : You must call interpolator_init before calling interpolator")
1473 do n=2,
size(clim_type%field_name(:))
1474 if (clim_type%vert_interp(n) /= clim_type%vert_interp(n-1) .or. &
1475 clim_type%out_of_bounds(n) /= clim_type%out_of_bounds(n-1))
then
1476 if (mpp_pe() == mpp_root_pe() )
then
1477 print *,
'processing file ' // trim(clim_type%file_name)
1479 call mpp_error (fatal,
'interpolator_mod: &
1480 &cannot use 4D interface to interpolator for this file')
1488if (
present(is)) istart = is
1489iend = istart - 1 +
size(interp_data,1)
1492if (
present(js)) jstart = js
1493jend = jstart - 1 +
size(interp_data,2)
1495 do i= 1,
size(clim_type%field_name(:))
1497 if ( trim(adjustl(lowercase(field_name))) == trim(adjustl(lowercase(clim_type%field_name(i)))) )
then
1505 if(
present(clim_units))
then
1506 call get_variable_units(clim_type%fileobj, clim_type%field_name(i), clim_units)
1516if ( .not. clim_type%separate_time_vary_calc)
then
1520 if (clim_type%climatological_year)
then
1522 if (
size(clim_type%time_slice) > 1)
then
1523 call time_interp(time, clim_type%time_slice, clim_type%FMS_INTP_TYPE_%tweight, &
1524 taum, taup, modtime=year, err_msg=err_msg )
1525 if(trim(err_msg) /=
'')
then
1526 call mpp_error(fatal,
'interpolator_4D 1: '//trim(err_msg)//
' file='//trim(clim_type%file_name), fatal)
1531 clim_type%FMS_INTP_TYPE_%tweight = 0._lkind
1535 call time_interp(time, clim_type%time_slice, clim_type%FMS_INTP_TYPE_%tweight, taum, taup, err_msg=err_msg )
1536 if(trim(err_msg) /=
'')
then
1537 call mpp_error(fatal,
'interpolator_4D 2: '//trim(err_msg)//
' file='//trim(clim_type%file_name), fatal)
1541 if(clim_type%TIME_FLAG .eq. bilinear )
then
1543 if ( (time - clim_type%time_slice(taum) ) > ( clim_type%time_slice(2)- clim_type%time_slice(1) ) .or. &
1544 (clim_type%time_slice(taup) - time) > ( clim_type%time_slice(2)- clim_type%time_slice(1) ) )
then
1555 call get_date(time, modyear, modmonth, modday, modhour, modminute, modsecond)
1556 call get_date(clim_type%time_slice(taum), climyear, climmonth, climday, climhour, climminute, climsecond)
1559 do m = 1,
size(clim_type%clim_times(:,:),2)
1561 call get_date(clim_type%clim_times(1,m), year1, month1, day, hour, minute, second)
1562 if (year1 == climyear) climatology = m
1566 call get_date(clim_type%clim_times(m,climatology), year1, month1, day, hour, minute, second)
1567 if ( month1 == modmonth )
then
1569 if ( modday < day )
then
1570 indexm = m-1 ; indexp = m
1572 indexm = m ; indexp = m+1
1577 if ( indexm == 0 )
then
1583 call get_date(clim_type%time_slice(indexm+(climatology-1)*12), &
1584 climyear, climmonth, climday, climhour, climminute, climsecond)
1585 month(1) = set_date(yearm, indexm, climday, climhour, climminute, climsecond)
1586 if ( indexp == 13 )
then
1592 call get_date(clim_type%time_slice(indexp+(climatology-1)*12), &
1593 climyear, climmonth, climday, climhour, climminute, climsecond)
1594 month(2) = set_date(yearp, indexp, climday, climhour, climminute, climsecond)
1596 call time_interp(time, month, clim_type%FMS_INTP_TYPE_%tweight3, taum, taup, err_msg=err_msg )
1599 if (taum==2 .and. taup==2) clim_type%FMS_INTP_TYPE_%tweight3 = 1._lkind
1600 if(trim(err_msg) /=
'')
then
1601 call mpp_error(fatal,
'interpolator_4D 3: '//trim(err_msg)//
' file='//trim(clim_type%file_name), fatal)
1604 month(1) = clim_type%time_slice(indexm+(climatology-1)*12)
1605 month(2) = clim_type%time_slice(indexm+climatology*12)
1606 call get_date(month(1), climyear, climmonth, climday, climhour, climminute, climsecond)
1607 t_prev = set_date(yearm, climmonth, climday, climhour, climminute, climsecond)
1608 call time_interp(t_prev, month, clim_type%FMS_INTP_TYPE_%tweight1, taum, taup, err_msg=err_msg )
1611 if (taum==2 .and. taup==2) clim_type%FMS_INTP_TYPE_%tweight1 = 1._lkind
1612 if(trim(err_msg) /=
'')
then
1613 call mpp_error(fatal,
'interpolator_4D 4: '//trim(err_msg)//
' file='//trim(clim_type%file_name), fatal)
1615 month(1) = clim_type%time_slice(indexp+(climatology-1)*12)
1616 month(2) = clim_type%time_slice(indexp+climatology*12)
1617 call get_date(month(1), climyear, climmonth, climday, climhour, climminute, climsecond)
1618 t_next = set_date(yearp, climmonth, climday, climhour, climminute, climsecond)
1619 call time_interp(t_next, month, clim_type%FMS_INTP_TYPE_%tweight2, taum, taup, err_msg=err_msg )
1622 if (taum==2 .and. taup==2) clim_type%FMS_INTP_TYPE_%tweight2 = 1._lkind
1623 if(trim(err_msg) /=
'')
then
1624 call mpp_error(fatal,
'interpolator_4D 5: '//trim(err_msg)//
' file='//trim(clim_type%file_name), fatal)
1627 if (indexm == clim_type%indexm(1) .and. &
1628 indexp == clim_type%indexp(1) .and. &
1629 climatology == clim_type%climatology(1))
then
1631 clim_type%indexm(:) = indexm
1632 clim_type%indexp(:) = indexp
1633 clim_type%climatology(:) = climatology
1634 do i=1,
size(clim_type%field_name(:))
1635 call read_data(clim_type,clim_type%field_name(i), &
1636 clim_type%FMS_INTP_TYPE_%pmon_pyear(:,:,:,i), &
1637 clim_type%indexm(i)+(clim_type%climatology(i)-1)*12,i,time)
1639 call read_data(clim_type,clim_type%field_name(i), &
1640 clim_type%FMS_INTP_TYPE_%nmon_pyear(:,:,:,i), &
1641 clim_type%indexp(i)+(clim_type%climatology(i)-1)*12,i,time)
1642 call read_data(clim_type,clim_type%field_name(i), &
1643 clim_type%FMS_INTP_TYPE_%pmon_nyear(:,:,:,i), &
1644 clim_type%indexm(i)+clim_type%climatology(i)*12,i,time)
1645 call read_data(clim_type,clim_type%field_name(i), &
1646 clim_type%FMS_INTP_TYPE_%nmon_nyear(:,:,:,i), &
1647 clim_type%indexp(i)+clim_type%climatology(i)*12,i,time)
1655 do i=1,
size(clim_type%field_name(:))
1656 if (taum /= clim_type%time_init(i,1) .or. &
1657 taup /= clim_type%time_init(i,2) )
then
1660 call read_data(clim_type,clim_type%field_name(i), &
1661 clim_type%FMS_INTP_TYPE_%pmon_pyear(:,:,:,i), taum,i,time)
1663 call read_data(clim_type,clim_type%field_name(i), &
1664 clim_type%FMS_INTP_TYPE_%nmon_pyear(:,:,:,i), taup,i,time)
1665 clim_type%time_init(i,1) = taum
1666 clim_type%time_init(i,2) = taup
1675 clim_type%indexm(:) = 0
1676 clim_type%indexp(:) = 0
1677 clim_type%climatology(:) = 0
1681 clim_type%FMS_INTP_TYPE_%tweight1 = 0.0_lkind
1682 clim_type%FMS_INTP_TYPE_%tweight2 = 0.0_lkind
1683 clim_type%FMS_INTP_TYPE_%tweight3 = clim_type%FMS_INTP_TYPE_%tweight
1687 if(clim_type%TIME_FLAG .eq. linear .and. &
1688 (.not. read_all_on_init) )
then
1692 do n=1,
size(clim_type%time_init,2)
1693 if (clim_type%time_init(1,n) .eq. taum ) clim_type%itaum = n
1694 if (clim_type%time_init(1,n) .eq. taup ) clim_type%itaup = n
1697 if (clim_type%itaum.eq.0 .and. clim_type%itaup.eq.0)
then
1702 do i=1,
size(clim_type%field_name(:))
1703 call read_data(clim_type,clim_type%field_name(i), clim_type%FMS_INTP_TYPE_%data5d(:,:,:,1,i), taum,i,time)
1704 clim_type%time_init(i,1) = taum
1706 call read_data(clim_type,clim_type%field_name(i), clim_type%FMS_INTP_TYPE_%data5d(:,:,:,2,i), taup,i,time)
1707 clim_type%time_init(i,2) = taup
1711 if (clim_type%itaum.eq.0 .and. clim_type%itaup.ne.0)
then
1713 call mpp_error(fatal,
'interpolator_3D : No data from the previous climatology time &
1714 & but we have the next time. How did this happen?')
1716 if (clim_type%itaum.ne.0 .and. clim_type%itaup.eq.0)
then
1719 if (clim_type%itaum .eq. 1 ) clim_type%itaup = 2
1720 do i=1,
size(clim_type%field_name(:))
1721 call read_data(clim_type,clim_type%field_name(i), &
1722 clim_type%FMS_INTP_TYPE_%data5d(:,:,:,clim_type%itaup,i), taup,i, time)
1723 clim_type%time_init(i,clim_type%itaup)=taup
1734select case(clim_type%TIME_FLAG)
1736 do n=1,
size(clim_type%field_name(:))
1737 hinterp_data(:,:,:,n) = (1._lkind-clim_type%FMS_INTP_TYPE_%tweight)* &
1738 clim_type%FMS_INTP_TYPE_%data5d(istart:iend,jstart:jend,:,clim_type%itaum,n) + &
1739 clim_type%FMS_INTP_TYPE_%tweight* &
1740 clim_type%FMS_INTP_TYPE_%data5d(istart:iend,jstart:jend,:,clim_type%itaup,n)
1745 do n=1,
size(clim_type%field_name(:))
1746 hinterp_data(:,:,:,n) = (1._lkind-clim_type%FMS_INTP_TYPE_%tweight1)*&
1747 (1._lkind-clim_type%FMS_INTP_TYPE_%tweight3)* &
1748 clim_type%FMS_INTP_TYPE_%pmon_pyear(istart:iend,jstart:jend,:,n) + &
1749 (1._lkind-clim_type%FMS_INTP_TYPE_%tweight2)*clim_type%FMS_INTP_TYPE_%tweight3* &
1750 clim_type%FMS_INTP_TYPE_%nmon_pyear(istart:iend,jstart:jend,:,n) + &
1751 clim_type%FMS_INTP_TYPE_%tweight1* (1._lkind-clim_type%FMS_INTP_TYPE_%tweight3)*&
1752 clim_type%FMS_INTP_TYPE_%pmon_nyear(istart:iend,jstart:jend,:,n) + &
1753 clim_type%FMS_INTP_TYPE_%tweight2* clim_type%FMS_INTP_TYPE_%tweight3* &
1754 clim_type%FMS_INTP_TYPE_%nmon_nyear(istart:iend,jstart:jend,:,n)
1760select case(clim_type%level_type)
1764 p_fact = maxval(phalf,3)
1767col_data(:,:,:)=0.0_lkind
1768 do i= 1,
size(clim_type%field_name(:))
1770select case(clim_type%mr(i))
1772 do k = 1,
size(hinterp_data,3)
1773 col_data(:,:,i) = col_data(:,:,i) + hinterp_data(:,:,k,i)* &
1774 (clim_type%FMS_INTP_TYPE_%halflevs(k+1)-clim_type%FMS_INTP_TYPE_%halflevs(k))/real(grav,fms_intp_kind_)
1778 do k = 1,
size(hinterp_data,3)
1779 col_data(:,:,i) = col_data(:,:,i) + hinterp_data(:,:,k,i)
1780 hinterp_data(:,:,k,i) = hinterp_data(:,:,k,i)/ &
1781 ((clim_type%FMS_INTP_TYPE_%halflevs(k+1)-clim_type%FMS_INTP_TYPE_%halflevs(k))*p_fact)
1786 do i= 1,
size(clim_type%field_name(:))
1788do j = 1,
size(climo_diag_name(:))
1789 if ( trim(adjustl(lowercase(climo_diag_name(j)))) .eq. trim(adjustl(lowercase(clim_type%field_name(i)))))
then
1796 if (hinterp_id(j) > 0 )
then
1797 result = send_data(hinterp_id(j),col_data(:,:,i),time,is_in=istart,js_in=jstart)
1806do j = 1,
size(phalf,2)
1807 do ilon=1,
size(phalf,1)
1808 pclim = p_fact(ilon,j)*clim_type%FMS_INTP_TYPE_%halflevs
1809 if ( maxval(phalf(ilon,j,:)) > maxval(pclim) )
then
1810 if (verbose > 3)
then
1811 call mpp_error(note,
"Interpolator: model surface pressure&
1812 & is greater than climatology surface pressure for "&
1813 // trim(clim_type%file_name))
1815 select case(clim_type%out_of_bounds(i))
1817 pclim( maxloc(pclim) ) = maxval( phalf(ilon,j,:) )
1822 if ( minval(phalf(ilon,j,:)) < minval(pclim) )
then
1823 if (verbose > 3)
then
1824 call mpp_error(note,
"Interpolator: model top pressure&
1825 & is less than climatology top pressure for "&
1826 & // trim(clim_type%file_name))
1828 select case(clim_type%out_of_bounds(i))
1830 pclim( minloc(pclim) ) = minval( phalf(ilon,j,:) )
1835 select case(clim_type%vert_interp(i))
1836 case(interp_weighted_p)
1837 call interp_weighted_scalar(pclim, phalf(ilon,j,:),hinterp_data(ilon,j,:,:),interp_data(ilon,j,:,:))
1838 case(interp_linear_p)
1839 do n=1,
size(clim_type%field_name(:))
1840 call interp_linear(pclim, phalf(ilon,j,:),hinterp_data(ilon,j,:,n),interp_data(ilon,j,:,n))
1848 do i= 1,
size(clim_type%field_name(:))
1850select case(clim_type%mr(i))
1852 do k = 1,
size(interp_data,3)
1853 interp_data(:,:,k,i) = interp_data(:,:,k,i)*(phalf(:,:,k+1)-phalf(:,:,k))
1859if( .not. found_field)
then
1860 call mpp_error(fatal,
"Interpolator: the field name is not contained in this &
1861 &intepolate_type: "//trim(field_name))
1863end subroutine interpolator_4d_
1896subroutine interpolator_3d_(clim_type, Time, phalf, interp_data,field_name, is,js, clim_units)
1913type(interpolate_type),
intent(inout) :: clim_type
1914character(len=*) ,
intent(in) :: field_name
1915type(time_type) ,
intent(in) :: Time
1916real(FMS_INTP_KIND_),
dimension(:,:,:),
intent(in) :: phalf
1917real(FMS_INTP_KIND_),
dimension(:,:,:),
intent(out) :: interp_data
1918integer ,
intent(in) ,
optional :: is,js
1919character(len=*) ,
intent(out),
optional :: clim_units
1920integer :: taum, taup, ilon
1921real(FMS_INTP_KIND_) :: hinterp_data(size(interp_data,1),&
1922 size(interp_data,2),size(clim_type%FMS_INTP_TYPE_%levs(:)))
1923real(FMS_INTP_KIND_) :: p_fact(size(interp_data,1),size(interp_data,2))
1924real(FMS_INTP_KIND_) :: col_data(size(interp_data,1),size(interp_data,2))
1925real(FMS_INTP_KIND_) :: pclim(size(clim_type%FMS_INTP_TYPE_%halflevs(:)))
1926integer :: istart,iend,jstart,jend
1927logical :: result, found
1928logical :: found_field=.false.
1929integer :: modyear, modmonth, modday, modhour, modminute, modsecond
1930integer :: climyear, climmonth, climday, climhour, climminute, climsecond
1931integer :: year1, month1, day, hour, minute, second
1932integer :: climatology, m
1933type(time_type) :: t_prev, t_next
1934type(time_type),
dimension(2) :: month
1935integer :: indexm, indexp, yearm, yearp
1936integer :: i, j, k, n
1937character(len=256) :: err_msg
1939integer,
parameter :: lkind=fms_intp_kind_
1941if (.not. module_is_initialized .or. .not.
allocated(clim_type%FMS_INTP_TYPE_%lon)) &
1942 call mpp_error(fatal,
"interpolator_3D : You must call interpolator_init before calling interpolator")
1945if (
present(is)) istart = is
1946iend = istart - 1 +
size(interp_data,1)
1949if (
present(js)) jstart = js
1950jend = jstart - 1 +
size(interp_data,2)
1952do i= 1,
size(clim_type%field_name(:))
1954 if ( trim(adjustl(lowercase(field_name))) == trim(adjustl(lowercase(clim_type%field_name(i)))) )
then
1957 if(
present(clim_units))
then
1958 call get_variable_units(clim_type%fileobj, clim_type%field_name(i), clim_units)
1959 clim_units = chomp(clim_units)
1968if ( .not. clim_type%separate_time_vary_calc)
then
1971 if (clim_type%climatological_year)
then
1973 if (
size(clim_type%time_slice) > 1)
then
1974 call time_interp(time, clim_type%time_slice, clim_type%FMS_INTP_TYPE_%tweight, &
1975 taum, taup, modtime=year, err_msg=err_msg )
1976 if(trim(err_msg) /=
'')
then
1977 call mpp_error(fatal,
'interpolator_3D 1: '//trim(err_msg)//
' file='//trim(clim_type%file_name), fatal)
1982 clim_type%FMS_INTP_TYPE_%tweight = 0._lkind
1986 call time_interp(time, clim_type%time_slice, clim_type%FMS_INTP_TYPE_%tweight, taum, taup, err_msg=err_msg )
1987 if(trim(err_msg) /=
'')
then
1988 call mpp_error(fatal,
'interpolator_3D 2: '//trim(err_msg)//
' file='//trim(clim_type%file_name), fatal)
1993 if(clim_type%TIME_FLAG .ne. linear .or. read_all_on_init )
then
1994 clim_type%itaum=taum
1995 clim_type%itaup=taup
1998 if(clim_type%TIME_FLAG .eq. bilinear )
then
2000 if ( (time - clim_type%time_slice(taum) ) > ( clim_type%time_slice(2)- clim_type%time_slice(1) ) .or. &
2001 (clim_type%time_slice(taup) - time) > ( clim_type%time_slice(2)- clim_type%time_slice(1) ) )
then
2012 call get_date(time, modyear, modmonth, modday, modhour, modminute, modsecond)
2013 call get_date(clim_type%time_slice(taum), climyear, climmonth, climday, climhour, climminute, climsecond)
2016 do m = 1,
size(clim_type%clim_times(:,:),2)
2018 call get_date(clim_type%clim_times(1,m), year1, month1, day, hour, minute, second)
2019 if (year1 == climyear) climatology = m
2023 call get_date(clim_type%clim_times(m,climatology), year1, month1, day, hour, minute, second)
2024 if ( month1 == modmonth )
then
2026 if ( modday < day )
then
2027 indexm = m-1 ; indexp = m
2029 indexm = m ; indexp = m+1
2034 if ( indexm == 0 )
then
2040 call get_date(clim_type%time_slice(indexm+(climatology-1)*12), &
2041 climyear, climmonth, climday, climhour, climminute, climsecond)
2042 month(1) = set_date(yearm, indexm, climday, climhour, climminute, climsecond)
2043 if ( indexp == 13 )
then
2049 call get_date(clim_type%time_slice(indexp+(climatology-1)*12), &
2050 climyear, climmonth, climday, climhour, climminute, climsecond)
2051 month(2) = set_date(yearp, indexp, climday, climhour, climminute, climsecond)
2053 call time_interp(time, month, clim_type%FMS_INTP_TYPE_%tweight3, taum, taup, err_msg=err_msg )
2055 if (taum==2 .and. taup==2) &
2056 clim_type%FMS_INTP_TYPE_%tweight3 = 1._lkind
2057 if(trim(err_msg) /=
'')
then
2058 call mpp_error(fatal,
'interpolator_3D 3: '//trim(err_msg)//
' file='//trim(clim_type%file_name), fatal)
2061 month(1) = clim_type%time_slice(indexm+(climatology-1)*12)
2062 month(2) = clim_type%time_slice(indexm+climatology*12)
2063 call get_date(month(1), climyear, climmonth, climday, climhour, climminute, climsecond)
2064 t_prev = set_date(yearm, climmonth, climday, climhour, climminute, climsecond)
2065 call time_interp(t_prev, month, clim_type%FMS_INTP_TYPE_%tweight1, taum, taup, err_msg=err_msg )
2067 if (taum==2 .and. taup==2) &
2068 clim_type%FMS_INTP_TYPE_%tweight1 = 1._lkind
2069 if(trim(err_msg) /=
'')
then
2070 call mpp_error(fatal,
'interpolator_3D 4: '//trim(err_msg)//
' file='//trim(clim_type%file_name), fatal)
2073 month(1) = clim_type%time_slice(indexp+(climatology-1)*12)
2074 month(2) = clim_type%time_slice(indexp+climatology*12)
2075 call get_date(month(1), climyear, climmonth, climday, climhour, climminute, climsecond)
2076 t_next = set_date(yearp, climmonth, climday, climhour, climminute, climsecond)
2077 call time_interp(t_next, month, clim_type%FMS_INTP_TYPE_%tweight2, taum, taup, err_msg=err_msg )
2079 if (taum==2 .and. taup==2) &
2080 clim_type%FMS_INTP_TYPE_%tweight2 = 1._lkind
2081 if(trim(err_msg) /=
'')
then
2082 call mpp_error(fatal,
'interpolator_3D 5: '//trim(err_msg)//
' file='//trim(clim_type%file_name), fatal)
2086 if (indexm == clim_type%indexm(i) .and. &
2087 indexp == clim_type%indexp(i) .and. &
2088 climatology == clim_type%climatology(i))
then
2090 clim_type%indexm(i) = indexm
2091 clim_type%indexp(i) = indexp
2092 clim_type%climatology(i) = climatology
2093 call read_data(clim_type,clim_type%field_name(i), &
2094 clim_type%FMS_INTP_TYPE_%pmon_pyear(:,:,:,i), &
2095 clim_type%indexm(i)+(clim_type%climatology(i)-1)*12,i,time)
2097 call read_data(clim_type,clim_type%field_name(i), &
2098 clim_type%FMS_INTP_TYPE_%nmon_pyear(:,:,:,i), &
2099 clim_type%indexp(i)+(clim_type%climatology(i)-1)*12,i,time)
2100 call read_data(clim_type,clim_type%field_name(i), &
2101 clim_type%FMS_INTP_TYPE_%pmon_nyear(:,:,:,i), &
2102 clim_type%indexm(i)+clim_type%climatology(i)*12,i,time)
2103 call read_data(clim_type,clim_type%field_name(i), &
2104 clim_type%FMS_INTP_TYPE_%nmon_nyear(:,:,:,i), &
2105 clim_type%indexp(i)+clim_type%climatology(i)*12,i,time)
2113 if (taum /= clim_type%time_init(i,1) .or. &
2114 taup /= clim_type%time_init(i,2) )
then
2116 call read_data(clim_type,clim_type%field_name(i), clim_type%FMS_INTP_TYPE_%pmon_pyear(:,:,:,i), taum,i,time)
2118 call read_data(clim_type,clim_type%field_name(i), clim_type%FMS_INTP_TYPE_%nmon_pyear(:,:,:,i), taup,i,time)
2128 clim_type%indexm(i) = 0
2129 clim_type%indexp(i) = 0
2130 clim_type%climatology(i) = 0
2133 clim_type%time_init(i,1) = taum
2134 clim_type%time_init(i,2) = taup
2137 clim_type%FMS_INTP_TYPE_%tweight1 = 0.0_lkind ; clim_type%FMS_INTP_TYPE_%tweight2 = 0.0_lkind
2138 clim_type%FMS_INTP_TYPE_%tweight3 = clim_type%FMS_INTP_TYPE_%tweight
2144 if(clim_type%TIME_FLAG .eq. linear .and. &
2145 (.not. read_all_on_init) )
then
2149 do n=1,
size(clim_type%time_init,2)
2150 if (clim_type%time_init(i,n) .eq. taum ) clim_type%itaum = n
2151 if (clim_type%time_init(i,n) .eq. taup ) clim_type%itaup = n
2154 if (clim_type%itaum.eq.0 .and. clim_type%itaup.eq.0)
then
2159 call read_data(clim_type,clim_type%field_name(i), clim_type%FMS_INTP_TYPE_%data5d(:,:,:,1,i), taum,i,time)
2160 clim_type%time_init(i,1) = taum
2162 call read_data(clim_type,clim_type%field_name(i), clim_type%FMS_INTP_TYPE_%data5d(:,:,:,2,i), taup,i,time)
2163 clim_type%time_init(i,2) = taup
2166 if (clim_type%itaum.eq.0 .and. clim_type%itaup.ne.0)
then
2168 call mpp_error(fatal,
'interpolator_3D : No data from the previous climatology time &
2169 & but we have the next time. How did this happen?')
2171 if (clim_type%itaum.ne.0 .and. clim_type%itaup.eq.0)
then
2174 if (clim_type%itaum .eq. 1 ) clim_type%itaup = 2
2175 call read_data(clim_type,clim_type%field_name(i), &
2176 clim_type%FMS_INTP_TYPE_%data5d(:,:,:,clim_type%itaup,i), taup,i, time)
2177 clim_type%time_init(i,clim_type%itaup)=taup
2184select case(clim_type%TIME_FLAG)
2186 hinterp_data = (1._lkind-clim_type%FMS_INTP_TYPE_%tweight) * &
2187 clim_type%FMS_INTP_TYPE_%data5d(istart:iend,jstart:jend,:,clim_type%itaum,i) + &
2188 clim_type%FMS_INTP_TYPE_%tweight * &
2189 clim_type%FMS_INTP_TYPE_%data5d(istart:iend,jstart:jend,:,clim_type%itaup,i)
2194 (1._lkind-clim_type%FMS_INTP_TYPE_%tweight1)*&
2195 (1._lkind-clim_type%FMS_INTP_TYPE_%tweight3)*clim_type%FMS_INTP_TYPE_%pmon_pyear(istart:iend,jstart:jend,:,i) + &
2196 (1._lkind-clim_type%FMS_INTP_TYPE_%tweight2) * clim_type%FMS_INTP_TYPE_%tweight3 &
2197 * clim_type%FMS_INTP_TYPE_%nmon_pyear(istart:iend,jstart:jend,:,i) + &
2198 clim_type%FMS_INTP_TYPE_%tweight1 * (1._lkind-clim_type%FMS_INTP_TYPE_%tweight3) * &
2199 clim_type%FMS_INTP_TYPE_%pmon_nyear(istart:iend,jstart:jend,:,i) + &
2200 clim_type%FMS_INTP_TYPE_%tweight2 * clim_type%FMS_INTP_TYPE_%tweight3 * &
2201 clim_type%FMS_INTP_TYPE_%nmon_nyear(istart:iend,jstart:jend,:,i)
2207select case(clim_type%level_type)
2211 p_fact = maxval(phalf,3)
2216col_data(:,:)=0.0_lkind
2217select case(clim_type%mr(i))
2219 do k = 1,
size(hinterp_data,3)
2220 col_data(:,:) = col_data(:,:) + hinterp_data(:,:,k)* &
2221 (clim_type%FMS_INTP_TYPE_%halflevs(k+1)-clim_type%FMS_INTP_TYPE_%halflevs(k))/real(grav,fms_intp_kind_)
2225 do k = 1,
size(hinterp_data,3)
2226 col_data(:,:) = col_data(:,:) + hinterp_data(:,:,k)
2227 hinterp_data(:,:,k) = hinterp_data(:,:,k)/ &
2228 ((clim_type%FMS_INTP_TYPE_%halflevs(k+1)-clim_type%FMS_INTP_TYPE_%halflevs(k))*p_fact)
2233do j = 1,
size(climo_diag_name(:))
2234 if ( trim(adjustl(lowercase(climo_diag_name(j)))) .eq. trim(adjustl(lowercase(clim_type%field_name(i)))))
then
2241 if (hinterp_id(j) > 0 )
then
2242 result = send_data(hinterp_id(j),col_data,time,is_in=istart,js_in=jstart)
2248do j = 1,
size(phalf,2)
2249 do ilon=1,
size(phalf,1)
2250 pclim = p_fact(ilon,j)*clim_type%FMS_INTP_TYPE_%halflevs
2251 if ( maxval(phalf(ilon,j,:)) > maxval(pclim) )
then
2252 if (verbose > 3)
then
2253 call mpp_error(note,
"Interpolator: model surface pressure&
2254 & is greater than climatology surface pressure for "&
2255 // trim(clim_type%file_name))
2257 select case(clim_type%out_of_bounds(i))
2259 pclim( maxloc(pclim) ) = maxval( phalf(ilon,j,:) )
2264 if ( minval(phalf(ilon,j,:)) < minval(pclim) )
then
2265 if (verbose > 3)
then
2266 call mpp_error(note,
"Interpolator: model top pressure&
2267 & is less than climatology top pressure for "&
2268 // trim(clim_type%file_name))
2270 select case(clim_type%out_of_bounds(i))
2272 pclim( minloc(pclim) ) = minval( phalf(ilon,j,:) )
2277 select case(clim_type%vert_interp(i))
2278 case(interp_weighted_p)
2279 call interp_weighted_scalar(pclim, phalf(ilon,j,:),hinterp_data(ilon,j,:),interp_data(ilon,j,:))
2280 case(interp_linear_p)
2281 call interp_linear(pclim, phalf(ilon,j,:),hinterp_data(ilon,j,:),interp_data(ilon,j,:))
2288select case(clim_type%mr(i))
2290 do k = 1,
size(interp_data,3)
2291 interp_data(:,:,k) = interp_data(:,:,k)*(phalf(:,:,k+1)-phalf(:,:,k))
2296if( .not. found_field)
then
2297 call mpp_error(fatal,
"Interpolator: the field name is not contained in this &
2298 &intepolate_type: "//trim(field_name))
2300end subroutine interpolator_3d_
2328subroutine interpolator_2d_(clim_type, Time, interp_data, field_name, is, js, clim_units)
2345type(interpolate_type),
intent(inout) :: clim_type
2346character(len=*) ,
intent(in) :: field_name
2347type(time_type) ,
intent(in) :: Time
2348real(FMS_INTP_KIND_),
dimension(:,:),
intent(out) :: interp_data
2349integer ,
intent(in) ,
optional :: is,js
2350character(len=*) ,
intent(out),
optional :: clim_units
2351integer :: taum, taup
2352real(FMS_INTP_KIND_) :: hinterp_data(size(interp_data,1),size(interp_data,2),size(clim_type%FMS_INTP_TYPE_%levs(:)))
2353integer :: istart,iend,jstart,jend
2354logical :: result, found
2355logical :: found_field=.false.
2356integer :: modyear, modmonth, modday, modhour, modminute, modsecond
2357integer :: climyear, climmonth, climday, climhour, climminute, climsecond
2358integer :: year1, month1, day, hour, minute, second
2359integer :: climatology, m
2360type(time_type) :: t_prev, t_next
2361type(time_type),
dimension(2) :: month
2362integer :: indexm, indexp, yearm, yearp
2364character(len=256) :: err_msg
2366integer,
parameter :: lkind=fms_intp_kind_
2368if (.not. module_is_initialized .or. .not.
allocated(clim_type%FMS_INTP_TYPE_%lon)) &
2369 call mpp_error(fatal,
"interpolator_2D : You must call interpolator_init before calling interpolator")
2372if (
present(is)) istart = is
2373iend = istart - 1 +
size(interp_data,1)
2376if (
present(js)) jstart = js
2377jend = jstart - 1 +
size(interp_data,2)
2379do i= 1,
size(clim_type%field_name(:))
2381 if ( trim(adjustl(lowercase(field_name))) == trim(adjustl(lowercase(clim_type%field_name(i)))) )
then
2386 if(
present(clim_units))
then
2387 call get_variable_units(clim_type%fileobj, clim_type%field_name(i), clim_units)
2388 clim_units = chomp(clim_units)
2397if ( .not. clim_type%separate_time_vary_calc)
then
2400 if (clim_type%climatological_year)
then
2402 if (
size(clim_type%time_slice) > 1)
then
2403 call time_interp(time, clim_type%time_slice, clim_type%FMS_INTP_TYPE_%tweight, &
2404 taum, taup, modtime=year, err_msg=err_msg )
2405 if(trim(err_msg) /=
'')
then
2406 call mpp_error(fatal,
'interpolator_2D 1: '//trim(err_msg)//
' file='//trim(clim_type%file_name), fatal)
2411 clim_type%FMS_INTP_TYPE_%tweight = 0._lkind
2415 call time_interp(time, clim_type%time_slice, clim_type%FMS_INTP_TYPE_%tweight, taum, taup, err_msg=err_msg )
2416 if(trim(err_msg) /=
'')
then
2417 call mpp_error(fatal,
'interpolator_2D 2: '//trim(err_msg)//
' file='//trim(clim_type%file_name), fatal)
2424 if(clim_type%TIME_FLAG .ne. linear .or. read_all_on_init)
then
2425 clim_type%itaum=taum
2426 clim_type%itaup=taup
2453 if(clim_type%TIME_FLAG .eq. bilinear )
then
2455 if ( (time - clim_type%time_slice(taum) ) > ( clim_type%time_slice(2)- clim_type%time_slice(1) ) .or. &
2456 (clim_type%time_slice(taup) - time) > ( clim_type%time_slice(2)- clim_type%time_slice(1) ) )
then
2467 call get_date(time, modyear, modmonth, modday, modhour, modminute, modsecond)
2468 call get_date(clim_type%time_slice(taum), climyear, climmonth, climday, climhour, climminute, climsecond)
2471 do m = 1,
size(clim_type%clim_times(:,:),2)
2473 call get_date(clim_type%clim_times(1,m), year1, month1, day, hour, minute, second)
2474 if (year1 == climyear) climatology = m
2478 call get_date(clim_type%clim_times(m,climatology), year1, month1, day, hour, minute, second)
2479 if ( month1 == modmonth )
then
2481 if ( modday < day )
then
2482 indexm = m-1 ; indexp = m
2484 indexm = m ; indexp = m+1
2489 if ( indexm == 0 )
then
2495 call get_date(clim_type%time_slice(indexm+(climatology-1)*12), &
2496 climyear, climmonth, climday, climhour, climminute, climsecond)
2497 month(1) = set_date(yearm, indexm, climday, climhour, climminute, climsecond)
2498 if ( indexp == 13 )
then
2504 call get_date(clim_type%time_slice(indexp+(climatology-1)*12), &
2505 climyear, climmonth, climday, climhour, climminute, climsecond)
2506 month(2) = set_date(yearp, indexp, climday, climhour, climminute, climsecond)
2508 call time_interp(time, month, clim_type%FMS_INTP_TYPE_%tweight3, taum, taup, err_msg=err_msg )
2510 if (taum==2 .and. taup==2) &
2511 clim_type%FMS_INTP_TYPE_%tweight3 = 1._lkind
2512 if(trim(err_msg) /=
'')
then
2513 call mpp_error(fatal,
'interpolator_2D 3: '//trim(err_msg)//
' file='//trim(clim_type%file_name), fatal)
2516 month(1) = clim_type%time_slice(indexm+(climatology-1)*12)
2517 month(2) = clim_type%time_slice(indexm+climatology*12)
2518 call get_date(month(1), climyear, climmonth, climday, climhour, climminute, climsecond)
2519 t_prev = set_date(yearm, climmonth, climday, climhour, climminute, climsecond)
2520 call time_interp(t_prev, month, clim_type%FMS_INTP_TYPE_%tweight1, taum, taup, err_msg=err_msg )
2523 if (taum==2 .and. taup==2) clim_type%FMS_INTP_TYPE_%tweight1 = 1._lkind
2524 if(trim(err_msg) /=
'')
then
2525 call mpp_error(fatal,
'interpolator_2D 4: '//trim(err_msg)//
' file='//trim(clim_type%file_name), fatal)
2528 month(1) = clim_type%time_slice(indexp+(climatology-1)*12)
2529 month(2) = clim_type%time_slice(indexp+climatology*12)
2530 call get_date(month(1), climyear, climmonth, climday, climhour, climminute, climsecond)
2531 t_next = set_date(yearp, climmonth, climday, climhour, climminute, climsecond)
2532 call time_interp(t_next, month, clim_type%FMS_INTP_TYPE_%tweight2, taum, taup, err_msg=err_msg )
2535 if (taum==2 .and. taup==2) clim_type%FMS_INTP_TYPE_%tweight2 = 1._lkind
2536 if(trim(err_msg) /=
'')
then
2537 call mpp_error(fatal,
'interpolator_2D 5: '//trim(err_msg)//
' file='//trim(clim_type%file_name), fatal)
2541 if (indexm == clim_type%indexm(i) .and. &
2542 indexp == clim_type%indexp(i) .and. &
2543 climatology == clim_type%climatology(i))
then
2545 clim_type%indexm(i) = indexm
2546 clim_type%indexp(i) = indexp
2547 clim_type%climatology(i) = climatology
2548 call read_data(clim_type,clim_type%field_name(i), &
2549 clim_type%FMS_INTP_TYPE_%pmon_pyear(:,:,:,i), &
2550 clim_type%indexm(i)+(clim_type%climatology(i)-1)*12,i,time)
2552 call read_data(clim_type,clim_type%field_name(i), &
2553 clim_type%FMS_INTP_TYPE_%nmon_pyear(:,:,:,i), &
2554 clim_type%indexp(i)+(clim_type%climatology(i)-1)*12,i,time)
2555 call read_data(clim_type,clim_type%field_name(i), &
2556 clim_type%FMS_INTP_TYPE_%pmon_nyear(:,:,:,i), &
2557 clim_type%indexm(i)+clim_type%climatology(i)*12,i,time)
2558 call read_data(clim_type,clim_type%field_name(i), &
2559 clim_type%FMS_INTP_TYPE_%nmon_nyear(:,:,:,i), &
2560 clim_type%indexp(i)+clim_type%climatology(i)*12,i,time)
2568 if (taum /= clim_type%time_init(i,1) .or. &
2569 taup /= clim_type%time_init(i,2) )
then
2571 call read_data(clim_type,clim_type%field_name(i), clim_type%FMS_INTP_TYPE_%pmon_pyear(:,:,:,i), taum,i,time)
2573 call read_data(clim_type,clim_type%field_name(i), clim_type%FMS_INTP_TYPE_%nmon_pyear(:,:,:,i), taup,i,time)
2583 clim_type%indexm(i) = 0
2584 clim_type%indexp(i) = 0
2585 clim_type%climatology(i) = 0
2588 clim_type%time_init(i,1) = taum
2589 clim_type%time_init(i,2) = taup
2592 clim_type%FMS_INTP_TYPE_%tweight1 = 0.0_lkind
2593 clim_type%FMS_INTP_TYPE_%tweight2 = 0.0_lkind
2594 clim_type%FMS_INTP_TYPE_%tweight3 = clim_type%FMS_INTP_TYPE_%tweight
2599 if(clim_type%TIME_FLAG .eq. linear .and. &
2600 (.not. read_all_on_init) )
then
2604 do n=1,
size(clim_type%time_init,2)
2605 if (clim_type%time_init(i,n) .eq. taum ) clim_type%itaum = n
2606 if (clim_type%time_init(i,n) .eq. taup ) clim_type%itaup = n
2609 if (clim_type%itaum.eq.0 .and. clim_type%itaup.eq.0)
then
2614 call read_data(clim_type,clim_type%field_name(i), clim_type%FMS_INTP_TYPE_%data5d(:,:,:,1,i), taum,i,time)
2615 clim_type%time_init(i,1) = taum
2617 call read_data(clim_type,clim_type%field_name(i), clim_type%FMS_INTP_TYPE_%data5d(:,:,:,2,i), taup,i,time)
2618 clim_type%time_init(i,2) = taup
2621 if (clim_type%itaum.eq.0 .and. clim_type%itaup.ne.0)
then
2623 call mpp_error(fatal,
'interpolator_2D : No data from the previous climatology time but we have&
2624 & the next time. How did this happen?')
2626 if (clim_type%itaum.ne.0 .and. clim_type%itaup.eq.0)
then
2629 if (clim_type%itaum .eq. 1 ) clim_type%itaup = 2
2630 call read_data(clim_type,clim_type%field_name(i), &
2631 clim_type%FMS_INTP_TYPE_%data5d(:,:,:,clim_type%itaup,i), taup,i, time)
2632 clim_type%time_init(i,clim_type%itaup)=taup
2640select case(clim_type%TIME_FLAG)
2642 hinterp_data = (1._lkind-clim_type%FMS_INTP_TYPE_%tweight)*&
2643 clim_type%FMS_INTP_TYPE_%data5d(istart:iend,jstart:jend,:,clim_type%itaum,i) &
2644 + clim_type%FMS_INTP_TYPE_%tweight*clim_type%FMS_INTP_TYPE_%data5d &
2645 (istart:iend,jstart:jend,:,clim_type%itaup,i)
2650 (1._lkind-clim_type%FMS_INTP_TYPE_%tweight1) * &
2651 (1._lkind-clim_type%FMS_INTP_TYPE_%tweight3) * &
2652 clim_type%FMS_INTP_TYPE_%pmon_pyear(istart:iend,jstart:jend,:,i) + &
2653 (1._lkind-clim_type%FMS_INTP_TYPE_%tweight2) * &
2654 clim_type%FMS_INTP_TYPE_%tweight3 * clim_type%FMS_INTP_TYPE_%nmon_pyear(istart:iend,jstart:jend,:,i) + &
2655 clim_type%FMS_INTP_TYPE_%tweight1 * (1._lkind-clim_type%FMS_INTP_TYPE_%tweight3) * &
2656 clim_type%FMS_INTP_TYPE_%pmon_nyear(istart:iend,jstart:jend,:,i) + &
2657 clim_type%FMS_INTP_TYPE_%tweight2 * clim_type%FMS_INTP_TYPE_%tweight3 * &
2658 clim_type%FMS_INTP_TYPE_%nmon_nyear(istart:iend,jstart:jend,:,i)
2663do j = 1,
size(climo_diag_name(:))
2664 if (trim(adjustl(lowercase(climo_diag_name(j)))) .eq. trim(adjustl(lowercase(clim_type%field_name(i)))))
then
2671 if (hinterp_id(j) > 0 )
then
2672 result = send_data(hinterp_id(j),hinterp_data,time,is_in=istart,js_in=jstart)
2676 interp_data(:,:) = hinterp_data(:,:,1)
2681if( .not. found_field)
then
2682 call mpp_error(fatal,
"Interpolator: the field name is not contained in this &
2683 &intepolate_type: "//trim(field_name))
2685end subroutine interpolator_2d_
2712subroutine interpolator_4d_no_time_axis_(clim_type, phalf, interp_data, field_name, is,js, clim_units)
2731type(interpolate_type),
intent(inout) :: clim_type
2732character(len=*) ,
intent(in) :: field_name
2733real(FMS_INTP_KIND_),
dimension(:,:,:),
intent(in) :: phalf
2734real(FMS_INTP_KIND_),
dimension(:,:,:,:),
intent(out) :: interp_data
2735integer ,
intent(in) ,
optional :: is,js
2736character(len=*) ,
intent(out),
optional :: clim_units
2738real(FMS_INTP_KIND_) :: hinterp_data(size(interp_data,1),&
2739 size(interp_data,2),size(clim_type%FMS_INTP_TYPE_%levs(:)),size(clim_type%field_name(:)))
2740real(FMS_INTP_KIND_) :: p_fact(size(interp_data,1),size(interp_data,2))
2741real(FMS_INTP_KIND_) :: pclim(size(clim_type%FMS_INTP_TYPE_%halflevs(:)))
2742integer :: istart,iend,jstart,jend
2743logical :: found_field=.false.
2744integer :: i, j, k, n
2746integer,
parameter :: lkind=fms_intp_kind_
2748if (.not. module_is_initialized .or. .not.
allocated(clim_type%FMS_INTP_TYPE_%lon)) &
2749 call mpp_error(fatal,
"interpolator_4D_no_time_axis : You must call interpolator_init before calling interpolator")
2751do n=2,
size(clim_type%field_name(:))
2752 if (clim_type%vert_interp(n) /= clim_type%vert_interp(n-1) .or. &
2753 clim_type%out_of_bounds(n) /= clim_type%out_of_bounds(n-1))
then
2754 if (mpp_pe() == mpp_root_pe() )
then
2755 print *,
'processing file ' // trim(clim_type%file_name)
2757 call mpp_error (fatal,
'interpolator_mod: &
2758 &cannot use 4D interface to interpolator for this file')
2763if (
present(is)) istart = is
2764iend = istart - 1 +
size(interp_data,1)
2767if (
present(js)) jstart = js
2768jend = jstart - 1 +
size(interp_data,2)
2770do i= 1,
size(clim_type%field_name(:))
2771 if ( trim(adjustl(lowercase(field_name))) == trim(adjustl(lowercase(clim_type%field_name(i)))) )
then
2778if(
present(clim_units))
then
2779 call get_variable_units(clim_type%fileobj, clim_type%field_name(i), clim_units)
2780 clim_units = chomp(clim_units)
2783do n=1,
size(clim_type%field_name(:))
2784 hinterp_data(:,:,:,n) = clim_type%FMS_INTP_TYPE_%data5d(istart:iend,jstart:jend,:,1,n)
2787select case(clim_type%level_type)
2791 p_fact = maxval(phalf,3)
2794 do i= 1,
size(clim_type%field_name(:))
2795 select case(clim_type%mr(i))
2797 do k = 1,
size(hinterp_data,3)
2798 hinterp_data(:,:,k,i) = hinterp_data(:,:,k,i)/&
2799 ((clim_type%FMS_INTP_TYPE_%halflevs(k+1)-clim_type%FMS_INTP_TYPE_%halflevs(k))*p_fact)
2806do j = 1,
size(phalf,2)
2807 do ilon=1,
size(phalf,1)
2808 pclim = p_fact(ilon,j)*clim_type%FMS_INTP_TYPE_%halflevs
2809 if ( maxval(phalf(ilon,j,:)) > maxval(pclim) )
then
2810 if (verbose > 3)
then
2811 call mpp_error(note,
"Interpolator: model surface pressure&
2812 & is greater than surface pressure of input data for "&
2813 // trim(clim_type%file_name))
2815 select case(clim_type%out_of_bounds(i))
2817 pclim( maxloc(pclim) ) = maxval( phalf(ilon,j,:) )
2820 if ( minval(phalf(ilon,j,:)) < minval(pclim) )
then
2821 if (verbose > 3)
then
2822 call mpp_error(note,
"Interpolator: model top pressure&
2823 & is less than top pressure of input data for "&
2824 // trim(clim_type%file_name))
2826 select case(clim_type%out_of_bounds(i))
2828 pclim( minloc(pclim) ) = minval( phalf(ilon,j,:) )
2831 select case(clim_type%vert_interp(i))
2832 case(interp_weighted_p)
2833 call interp_weighted_scalar(pclim, phalf(ilon,j,:),hinterp_data(ilon,j,:,:),interp_data(ilon,j,:,:))
2834 case(interp_linear_p)
2835 do n=1,
size(clim_type%field_name(:))
2836 call interp_linear(pclim, phalf(ilon,j,:),hinterp_data(ilon,j,:,n),interp_data(ilon,j,:,n))
2842 do i= 1,
size(clim_type%field_name(:))
2844select case(clim_type%mr(i))
2846 do k = 1,
size(interp_data,3)
2847 interp_data(:,:,k,i) = interp_data(:,:,k,i)*(phalf(:,:,k+1)-phalf(:,:,k))
2853if( .not. found_field)
then
2854 call mpp_error(fatal,
"Interpolator: the field name is not contained in this &
2855 &intepolate_type: "//trim(field_name))
2857end subroutine interpolator_4d_no_time_axis_
2883subroutine interpolator_3d_no_time_axis_(clim_type, phalf, interp_data, field_name, is,js, clim_units)
2899type(interpolate_type),
intent(inout) :: clim_type
2900character(len=*) ,
intent(in) :: field_name
2901real(FMS_INTP_KIND_),
dimension(:,:,:),
intent(in) :: phalf
2902real(FMS_INTP_KIND_),
dimension(:,:,:),
intent(out) :: interp_data
2903integer ,
intent(in) ,
optional :: is,js
2904character(len=*) ,
intent(out),
optional :: clim_units
2906real(FMS_INTP_KIND_) :: hinterp_data(size(interp_data,1),&
2907 size(interp_data,2),size(clim_type%FMS_INTP_TYPE_%levs(:)))
2908real(FMS_INTP_KIND_) :: p_fact(size(interp_data,1),size(interp_data,2))
2909real(FMS_INTP_KIND_) :: pclim(size(clim_type%FMS_INTP_TYPE_%halflevs(:)))
2910integer :: istart,iend,jstart,jend
2911logical :: found_field=.false.
2914integer,
parameter :: lkind=fms_intp_kind_
2916if (.not. module_is_initialized .or. .not.
allocated(clim_type%FMS_INTP_TYPE_%lon)) &
2917 call mpp_error(fatal,
"interpolator_3D_no_time_axis : You must call interpolator_init before calling interpolator")
2920if (
present(is)) istart = is
2921iend = istart - 1 +
size(interp_data,1)
2924if (
present(js)) jstart = js
2925jend = jstart - 1 +
size(interp_data,2)
2927do i= 1,
size(clim_type%field_name(:))
2928 if ( trim(adjustl(lowercase(field_name))) == trim(adjustl(lowercase(clim_type%field_name(i)))) )
then
2930 if(
present(clim_units))
then
2931 call get_variable_units(clim_type%fileobj, clim_type%field_name(i), clim_units)
2932 clim_units = chomp(clim_units)
2935 hinterp_data = clim_type%FMS_INTP_TYPE_%data5d(istart:iend,jstart:jend,:,1,i)
2937select case(clim_type%level_type)
2941 p_fact = maxval(phalf,3)
2944select case(clim_type%mr(i))
2946 do k = 1,
size(hinterp_data,3)
2947 hinterp_data(:,:,k) = hinterp_data(:,:,k)/&
2948 ((clim_type%FMS_INTP_TYPE_%halflevs(k+1)-clim_type%FMS_INTP_TYPE_%halflevs(k))*p_fact)
2952do j = 1,
size(phalf,2)
2953 do ilon=1,
size(phalf,1)
2954 pclim = p_fact(ilon,j)*clim_type%FMS_INTP_TYPE_%halflevs
2955 if ( maxval(phalf(ilon,j,:)) > maxval(pclim) )
then
2956 if (verbose > 3)
then
2957 call mpp_error(note,
"Interpolator: model surface pressure&
2958 & is greater than climatology surface pressure for "&
2959 // trim(clim_type%file_name))
2961 select case(clim_type%out_of_bounds(i))
2963 pclim( maxloc(pclim) ) = maxval( phalf(ilon,j,:) )
2966 if ( minval(phalf(ilon,j,:)) < minval(pclim) )
then
2967 if (verbose > 3)
then
2968 call mpp_error(note,
"Interpolator: model top pressure&
2969 & is less than climatology top pressure for "&
2970 // trim(clim_type%file_name))
2972 select case(clim_type%out_of_bounds(i))
2974 pclim( minloc(pclim) ) = minval( phalf(ilon,j,:) )
2977 select case(clim_type%vert_interp(i))
2978 case(interp_weighted_p)
2979 call interp_weighted_scalar(pclim, phalf(ilon,j,:),hinterp_data(ilon,j,:),interp_data(ilon,j,:))
2980 case(interp_linear_p)
2981 call interp_linear(pclim, phalf(ilon,j,:),hinterp_data(ilon,j,:),interp_data(ilon,j,:))
2986select case(clim_type%mr(i))
2988 do k = 1,
size(interp_data,3)
2989 interp_data(:,:,k) = interp_data(:,:,k)*(phalf(:,:,k+1)-phalf(:,:,k))
2995if( .not. found_field)
then
2996 call mpp_error(fatal,
"Interpolator: the field name is not contained in this &
2997 &intepolate_type: "//trim(field_name))
2999end subroutine interpolator_3d_no_time_axis_
3018subroutine interpolator_2d_no_time_axis_(clim_type, interp_data, field_name, is, js, clim_units)
3033type(interpolate_type),
intent(inout) :: clim_type
3034character(len=*) ,
intent(in) :: field_name
3035real(FMS_INTP_KIND_),
dimension(:,:),
intent(out) :: interp_data
3036integer ,
intent(in) ,
optional :: is,js
3037character(len=*) ,
intent(out),
optional :: clim_units
3038real(FMS_INTP_KIND_) :: hinterp_data(size(interp_data,1),&
3039 size(interp_data,2),size(clim_type%FMS_INTP_TYPE_%levs(:)))
3040integer :: istart,iend,jstart,jend
3041logical :: found_field=.false.
3044if (.not. module_is_initialized .or. .not.
allocated(clim_type%FMS_INTP_TYPE_%lon)) &
3045 call mpp_error(fatal,
"interpolator_2D_no_time_axis : You must call interpolator_init before calling interpolator")
3048if (
present(is)) istart = is
3049iend = istart - 1 +
size(interp_data,1)
3052if (
present(js)) jstart = js
3053jend = jstart - 1 +
size(interp_data,2)
3055do i= 1,
size(clim_type%field_name(:))
3056 if ( trim(adjustl(lowercase(field_name))) == trim(adjustl(lowercase(clim_type%field_name(i)))) )
then
3060 if(
present(clim_units))
then
3061 call get_variable_units(clim_type%fileobj, clim_type%field_name(i), clim_units)
3062 clim_units = chomp(clim_units)
3065 hinterp_data = clim_type%FMS_INTP_TYPE_%data5d(istart:iend,jstart:jend,:,1,i)
3067 interp_data(:,:) = hinterp_data(:,:,1)
3072if( .not. found_field)
then
3073 call mpp_error(fatal,
"Interpolator: the field name is not contained in this &
3074 &intepolate_type: "//trim(field_name))
3077end subroutine interpolator_2d_no_time_axis_
3092subroutine read_data_(clim_type,field_name, hdata, nt,i, Time)
3106type(interpolate_type) ,
intent(in) :: clim_type
3107character(len=*) ,
intent(in) :: field_name
3108integer ,
intent(in) :: nt
3109real(FMS_INTP_KIND_) ,
intent(out) :: hdata(:,:,:)
3110integer ,
intent(in) :: i
3111type(time_type),
optional,
intent(in) :: Time
3115real(FMS_INTP_KIND_),
allocatable :: climdata(:,:,:), climdata2(:,:,:)
3117 allocate(climdata(
size(clim_type%FMS_INTP_TYPE_%lon(:)),
size(clim_type%FMS_INTP_TYPE_%lat(:)), &
3118 size(clim_type%FMS_INTP_TYPE_%levs(:))))
3119 if(clim_type%has_level(i))
then
3120 call fms2_io_read_data(clim_type%fileobj,field_name, climdata,nt)
3122 call fms2_io_read_data(clim_type%fileobj,field_name, climdata(:,:,1),nt)
3128 if (clim_type%vertical_indices == increasing_upward)
then
3129 allocate(climdata2(
size(clim_type%FMS_INTP_TYPE_%lon(:)), &
3130 size(clim_type%FMS_INTP_TYPE_%lat(:)), &
3131 size(clim_type%FMS_INTP_TYPE_%levs(:))))
3132 km =
size(clim_type%FMS_INTP_TYPE_%levs(:))
3134 climdata2(:,:,k) = climdata(:,:,km+1-k)
3136 climdata = climdata2
3137 deallocate (climdata2)
3139 call horiz_interp(clim_type%interph, climdata, hdata)
3140 if (clim_diag_initialized) &
3141 call diag_read_data(clim_type,climdata,i, time)
3142 deallocate(climdata)
3145 end subroutine read_data_
3159subroutine read_data_no_time_axis_(clim_type,field_name, hdata, i)
3171type(interpolate_type) ,
intent(in) :: clim_type
3172character(len=*) ,
intent(in) :: field_name
3173real(FMS_INTP_KIND_) ,
intent(out) :: hdata(:,:,:)
3174integer ,
intent(in) :: i
3178real(FMS_INTP_KIND_),
allocatable :: climdata(:,:,:), climdata2(:,:,:)
3180 allocate(climdata(
size(clim_type%FMS_INTP_TYPE_%lon(:)),&
3181 size(clim_type%FMS_INTP_TYPE_%lat(:)),&
3182 size(clim_type%FMS_INTP_TYPE_%levs(:))))
3184 if(clim_type%has_level(i))
then
3185 call fms2_io_read_data(clim_type%fileobj,field_name, climdata)
3187 call fms2_io_read_data(clim_type%fileobj,field_name, climdata(:,:,1))
3192 if (clim_type%vertical_indices == increasing_upward)
then
3193 allocate(climdata2(
size(clim_type%FMS_INTP_TYPE_%lon(:)), &
3194 size(clim_type%FMS_INTP_TYPE_%lat(:)), &
3195 size(clim_type%FMS_INTP_TYPE_%levs(:))))
3196 km =
size(clim_type%FMS_INTP_TYPE_%levs(:))
3198 climdata2(:,:,k) = climdata(:,:,km+1-k)
3200 climdata = climdata2
3201 deallocate (climdata2)
3204 call horiz_interp(clim_type%interph, climdata, hdata)
3205 deallocate(climdata)
3207end subroutine read_data_no_time_axis_
3219subroutine diag_read_data_(clim_type,model_data, i, Time)
3229type(interpolate_type),
intent(in) :: clim_type
3230real(FMS_INTP_KIND_) ,
intent(in) :: model_data(:,:,:)
3231integer ,
intent(in) :: i
3232type(time_type) ,
intent(in) :: Time
3235real(FMS_INTP_KIND_) :: col_data(size(model_data,1),size(model_data,2))
3236logical :: result, found
3238integer,
parameter :: lkind=fms_intp_kind_
3241do j = 1,
size(climo_diag_name(:))
3242 if (trim(adjustl(lowercase(climo_diag_name(j)))) .eq. trim(adjustl(lowercase(clim_type%field_name(i)))))
then
3249 if(climo_diag_id(j)>0)
then
3250 col_data(:,:)=0.0_lkind
3251 do k=1,
size(model_data,3)
3252 col_data(:,:) = col_data(:,:) + &
3253 model_data(:,:,k)* &
3254 (clim_type%FMS_INTP_TYPE_%halflevs(k+1)-clim_type%FMS_INTP_TYPE_%halflevs(k))/real(grav,fms_intp_kind_)
3256 result = send_data(climo_diag_id(j),col_data(clim_type%is:clim_type%ie,clim_type%js:clim_type%je),time)
3260end subroutine diag_read_data_
3273subroutine interp_weighted_scalar_2d_ (grdin, grdout, datin, datout )
3274real(FMS_INTP_KIND_),
intent(in),
dimension(:) :: grdin, grdout
3275real(FMS_INTP_KIND_),
intent(in),
dimension(:,:) :: datin
3276real(FMS_INTP_KIND_),
intent(out),
dimension(:,:) :: datout
3279integer,
parameter :: lkind=fms_intp_kind_
3281if (
size(grdin(:)).ne. (
size(datin,1)+1)) &
3282 call mpp_error(fatal,
'interp_weighted_scalar : input data and pressure do not have the same number of levels')
3283if (
size(grdout(:)).ne. (
size(datout,1 )+1)) &
3284 call mpp_error(fatal,
'interp_weighted_scalar : output data and pressure do not have the same number of levels')
3286 do k = 1,
size(datout,1 )
3287 datout(k,:) = 0.0_lkind
3289 do j = 1,
size(datin,1 )
3291 if ( grdin(j) <= grdout(k) .and. &
3292 grdin(j+1) >= grdout(k) .and. &
3293 grdin(j+1) <= grdout(k+1) )
then
3295 do n= 1,
size(datin,2)
3296 datout(k,n) = datout(k,n) + datin(j,n)*(grdin(j+1)-grdout(k))
3299 else if ( grdin(j) >= grdout(k) .and. &
3300 grdin(j) <= grdout(k+1) .and. &
3301 grdin(j+1) >= grdout(k+1) )
then
3303 do n= 1,
size(datin,2)
3304 datout(k,n) = datout(k,n) + datin(j,n)*(grdout(k+1)-grdin(j))
3307 else if ( grdin(j) >= grdout(k) .and. &
3308 grdin(j+1) <= grdout(k+1) )
then
3310 do n= 1,
size(datin,2)
3311 datout(k,n) = datout(k,n) + datin(j,n)*(grdin(j+1)-grdin(j))
3314 else if ( grdin(j) <= grdout(k) .and. &
3315 grdin(j+1) >= grdout(k+1) )
then
3317 do n= 1,
size(datin,2)
3318 datout(k,n) = datout(k,n) + datin(j,n)*(grdout(k+1)-grdout(k))
3325 do n= 1,
size(datin,2)
3326 datout(k,n) = datout(k,n)/(grdout(k+1)-grdout(k))
3331end subroutine interp_weighted_scalar_2d_
3341subroutine interp_weighted_scalar_1d_ (grdin, grdout, datin, datout )
3342real(FMS_INTP_KIND_),
intent(in),
dimension(:) :: grdin, grdout, datin
3343real(FMS_INTP_KIND_),
intent(out),
dimension(:) :: datout
3346integer,
parameter :: lkind=fms_intp_kind_
3348if (
size(grdin(:)).ne. (
size(datin(:))+1)) &
3349 call mpp_error(fatal,
'interp_weighted_scalar : input data and pressure do not have the same number of levels')
3350if (
size(grdout(:)).ne. (
size(datout(:))+1)) &
3351 call mpp_error(fatal,
'interp_weighted_scalar : output data and pressure do not have the same number of levels')
3353 do k = 1,
size(datout(:))
3354 datout(k) = 0.0_lkind
3356 do j = 1,
size(datin(:))
3358 if ( grdin(j) <= grdout(k) .and. &
3359 grdin(j+1) >= grdout(k) .and. &
3360 grdin(j+1) <= grdout(k+1) )
then
3362 datout(k) = datout(k) + datin(j)*(grdin(j+1)-grdout(k))
3364 else if ( grdin(j) >= grdout(k) .and. &
3365 grdin(j) <= grdout(k+1) .and. &
3366 grdin(j+1) >= grdout(k+1) )
then
3368 datout(k) = datout(k) + datin(j)*(grdout(k+1)-grdin(j))
3370 else if ( grdin(j) >= grdout(k) .and. &
3371 grdin(j+1) <= grdout(k+1) )
then
3373 datout(k) = datout(k) + datin(j)*(grdin(j+1)-grdin(j))
3375 else if ( grdin(j) <= grdout(k) .and. &
3376 grdin(j+1) >= grdout(k+1) )
then
3378 datout(k) = datout(k) + datin(j)*(grdout(k+1)-grdout(k))
3384 datout(k) = datout(k)/(grdout(k+1)-grdout(k))
3388end subroutine interp_weighted_scalar_1d_
3401subroutine interp_linear_ ( grdin, grdout, datin, datout )
3402real(FMS_INTP_KIND_),
intent(in),
dimension(:) :: grdin, grdout, datin
3403real(FMS_INTP_KIND_),
intent(out),
dimension(:) :: datout
3406real(FMS_INTP_KIND_) :: wt
3408integer,
parameter :: lkind=fms_intp_kind_
3410if (
size(grdin(:)).ne. (
size(datin(:))+1)) &
3411 call mpp_error(fatal,
'interp_linear : input data and pressure do not have the same number of levels')
3412if (
size(grdout(:)).ne. (
size(datout(:))+1)) &
3413 call mpp_error(fatal,
'interp_linear : output data and pressure do not have the same number of levels')
3418 do k= 1,
size(datout(:))
3421 if (grdin(1) < grdin(n))
then
3422 do j = 2,
size(grdin(:))-1
3423 if (grdout(k) <= grdin(j))
exit
3427 do j =
size(grdin(:)), 3, -1
3428 if (grdout(k) <= grdin(j-1))
exit
3433 wt = (grdout(k)-grdin(j-1)) / (grdin(j)-grdin(j-1))
3438 datout(k) = (1._lkind-wt)*datin(j-1) + wt*datin(j)
3442end subroutine interp_linear_