22 #include <fms_platform.h> 50 use fms_mod,
only : write_version_number
56 mpp_get_tavg_info,
validtype, mpp_is_valid, mpp_get_file_name
73 #include<file_version.h> 95 character(len=128) :: name, units
96 integer :: siz(4), ndim
99 type(
time_type),
dimension(:),
pointer :: time =>null()
100 type(
time_type),
dimension(:),
pointer :: start_time =>null(), end_time =>null()
102 type(
time_type),
dimension(:),
pointer :: period =>null()
103 logical :: modulo_time
104 real,
dimension(:,:,:,:),
pointer :: data =>null()
105 logical,
dimension(:,:,:,:),
pointer :: mask =>null()
106 integer,
dimension(:),
pointer :: ibuf =>null()
107 real,
dimension(:,:,:,:),
pointer :: src_data =>null()
110 logical :: domain_present
111 real(DOUBLE_KIND) :: slope, intercept
112 integer :: isc,iec,jsc,jec
114 logical :: have_modulo_times, correct_leap_year_inconsistency
115 integer :: region_type
116 integer :: is_region, ie_region, js_region, je_region
117 integer :: is_src, ie_src, js_src, je_src
119 integer :: numwindows
120 logical,
dimension(:,:),
pointer :: need_compute=>null()
125 character(len=128) :: filename =
'' 151 integer :: ioun, io_status, logunit, ierr
162 call write_version_number(
"TIME_INTERP_EXTERNAL_MOD", version)
164 #ifdef INTERNAL_FILE_NML 168 ioun = open_namelist_file()
169 ierr=1;
do while (ierr /= 0)
170 read (ioun, nml=time_interp_external_nml, iostat=io_status, end=10)
173 10
call close_file (ioun)
176 write(logunit,time_interp_external_nml)
233 verbose,axis_centers,axis_sizes,override,correct_leap_year_inconsistency,&
234 permit_calendar_conversion,use_comp_domain,ierr, nwindows, ignore_axis_atts )
236 character(len=*),
intent(in) :: file,fieldname
237 integer,
intent(in),
optional :: format, threading
238 logical,
intent(in),
optional :: verbose
239 character(len=*),
intent(in),
optional :: desired_units
240 type(
domain2d),
intent(in),
optional :: domain
241 type(
axistype),
intent(inout),
optional :: axis_centers(4)
242 integer,
intent(inout),
optional :: axis_sizes(4)
243 logical,
intent(in),
optional :: override, correct_leap_year_inconsistency,&
244 permit_calendar_conversion,use_comp_domain
245 integer,
intent(out),
optional :: ierr
246 integer,
intent(in),
optional :: nwindows
247 logical,
optional :: ignore_axis_atts
252 type(
fieldtype),
dimension(:),
allocatable :: flds
253 type(
axistype),
dimension(:),
allocatable :: axes, fld_axes
255 type(
atttype),
allocatable,
dimension(:) :: global_atts
257 real(DOUBLE_KIND) :: slope, intercept
258 integer :: form, thread, fset, unit,ndim,nvar,natt,ntime,i,j
259 integer :: iscomp,iecomp,jscomp,jecomp,isglobal,ieglobal,jsglobal,jeglobal
260 integer :: isdata,iedata,jsdata,jedata, dxsize, dysize,dxsize_max,dysize_max
261 logical :: verb, transpose_xy,use_comp_domain1
262 real,
dimension(:),
allocatable :: tstamp, tstart, tend, tavg
263 character(len=1) :: cart
264 character(len=1),
dimension(4) :: cart_dir
265 character(len=128) :: units, fld_units
266 character(len=128) :: name, msg, calendar_type, timebeg, timeend
267 integer :: siz(4), siz_in(4), gxsize, gysize,gxsize_max, gysize_max
269 integer :: yr, mon, day, hr, minu, sec
270 integer :: len, nfile, nfields_orig, nbuf, nx,ny
271 integer :: numwindows
272 logical :: ignore_axatts
276 if(
present(ierr)) ierr =
success 277 ignore_axatts=.false.
278 cart_dir(1)=
'X';cart_dir(2)=
'Y';cart_dir(3)=
'Z';cart_dir(4)=
'T' 279 if(
present(ignore_axis_atts)) ignore_axatts = ignore_axis_atts
280 use_comp_domain1 = .false.
281 if(
PRESENT(use_comp_domain)) use_comp_domain1 = use_comp_domain
283 if (
PRESENT(format)) form =
format 285 if (
PRESENT(threading)) thread = threading
288 if (
PRESENT(verbose)) verb=verbose
291 if(
present(nwindows)) numwindows = nwindows
294 if (
PRESENT(desired_units))
then 295 units = desired_units
296 call mpp_error(fatal,
'==> Unit conversion via time_interp_external & 297 &has been temporarily deprecated. Previous versions of& 298 &this module used udunits_mod to perform unit conversion.& 299 & Udunits_mod is in the process of being replaced since & 300 &there were portability issues associated with this code.& 301 & Please remove the desired_units argument from calls to & 312 call mpp_open(unit,trim(file),mpp_rdonly,form,threading=thread,&
321 call mpp_error(fatal,
"time_interp_external: num_files is greater than max_files, "// &
322 "increase time_interp_external_nml max_files")
330 call mpp_get_info(unit,ndim,nvar,natt,ntime)
333 write(msg,
'(a15,a,a58)')
'external field ',trim(fieldname),&
334 ' does not have an associated record dimension (REQUIRED) ' 337 allocate(global_atts(natt))
340 call mpp_get_axes(unit, axes, time_axis)
342 call mpp_get_fields(unit,flds)
343 allocate(tstamp(ntime),tstart(ntime),tend(ntime),tavg(ntime))
344 call mpp_get_times(unit,tstamp)
345 transpose_xy = .false.
346 isdata=1; iedata=1; jsdata=1; jedata=1
350 if (
PRESENT(domain))
then 352 nx = iecomp-iscomp+1; ny = jecomp-jscomp+1
353 call mpp_get_data_domain(domain,isdata,iedata,jsdata,jedata,dxsize,dxsize_max,dysize,dysize_max)
354 call mpp_get_global_domain(domain,isglobal,ieglobal,jsglobal,jeglobal,gxsize,gxsize_max,gysize,gysize_max)
355 elseif(use_comp_domain1)
then 356 call mpp_error(fatal,
"init_external_field:"//&
357 " use_comp_domain=true but domain is not present")
361 nfields_orig = num_fields
364 call mpp_get_atts(flds(i),name=name,units=fld_units,ndim=ndim,siz=siz_in)
365 call mpp_get_tavg_info(unit,flds(i),flds,tstamp,tstart,tend,tavg)
368 if (trim(lowercase(name)) /= trim(lowercase(fieldname))) cycle
370 if (verb)
write(outunit,*)
'found field ',trim(fieldname),
' in file !!' 371 num_fields = num_fields + 1
378 call mpp_error(fatal,
"time_interp_external: num_fields is greater than max_fields, "// &
379 "increase time_interp_external_nml max_fields")
383 field(num_fields)%unit = unit
384 field(num_fields)%name = trim(name)
385 field(num_fields)%units = trim(fld_units)
386 field(num_fields)%field = flds(i)
387 field(num_fields)%isc = 1
388 field(num_fields)%iec = 1
389 field(num_fields)%jsc = 1
390 field(num_fields)%jec = 1
392 field(num_fields)%is_region = 0
393 field(num_fields)%ie_region = -1
394 field(num_fields)%js_region = 0
395 field(num_fields)%je_region = -1
396 if (
PRESENT(domain))
then 397 field(num_fields)%domain_present = .true.
398 field(num_fields)%domain = domain
399 field(num_fields)%isc=iscomp;
field(num_fields)%iec = iecomp
400 field(num_fields)%jsc=jscomp;
field(num_fields)%jec = jecomp
402 field(num_fields)%domain_present = .false.
406 allocate(fld_axes(ndim))
409 'invalid array rank <=4d fields supported')
410 field(num_fields)%siz = 1
411 field(num_fields)%ndim = ndim
412 field(num_fields)%tdim = 4
413 field(num_fields)%missing = missing
414 do j=1,
field(num_fields)%ndim
418 if (cart ==
'N' .and. .not. ignore_axatts)
then 419 write(msg,
'(a,"/",a)') trim(file),trim(fieldname)
420 call mpp_error(fatal,
'file/field '//trim(msg)// &
421 ' couldnt recognize axis atts in time_interp_external')
422 else if (cart ==
'N' .and. ignore_axatts)
then 427 if (j.eq.2) transpose_xy = .true.
428 if (.not.
PRESENT(domain) .and. .not.
PRESENT(override))
then 433 field(num_fields)%isc=iscomp;
field(num_fields)%iec=iecomp
434 elseif (
PRESENT(override))
then 436 if (
PRESENT(axis_sizes)) axis_sizes(1) = len
438 field(num_fields)%axes(1) = fld_axes(j)
439 if(use_comp_domain1)
then 440 field(num_fields)%siz(1) = nx
442 field(num_fields)%siz(1) = dxsize
444 if (len /= gxsize)
then 445 write(msg,
'(a,"/",a)') trim(file),trim(fieldname)
446 call mpp_error(fatal,
'time_interp_ext, file/field '//trim(msg)//
' x dim doesnt match model')
449 field(num_fields)%axes(2) = fld_axes(j)
450 if (.not.
PRESENT(domain) .and. .not.
PRESENT(override))
then 455 field(num_fields)%jsc=jscomp;
field(num_fields)%jec=jecomp
456 elseif (
PRESENT(override))
then 458 if (
PRESENT(axis_sizes)) axis_sizes(2) = len
460 if(use_comp_domain1)
then 461 field(num_fields)%siz(2) = ny
463 field(num_fields)%siz(2) = dysize
465 if (len /= gysize)
then 466 write(msg,
'(a,"/",a)') trim(file),trim(fieldname)
467 call mpp_error(fatal,
'time_interp_ext, file/field '//trim(msg)//
' y dim doesnt match model')
470 field(num_fields)%axes(3) = fld_axes(j)
471 field(num_fields)%siz(3) = siz_in(3)
473 field(num_fields)%axes(4) = fld_axes(j)
474 field(num_fields)%siz(4) = ntime
475 field(num_fields)%tdim = j
478 siz =
field(num_fields)%siz
480 if (
PRESENT(axis_centers))
then 481 axis_centers =
field(num_fields)%axes
484 if (
PRESENT(axis_sizes) .and. .not.
PRESENT(override))
then 485 axis_sizes =
field(num_fields)%siz
489 if (verb)
write(outunit,
'(a,4i6)')
'field x,y,z,t local size= ',siz
490 if (verb)
write(outunit,*)
'field contains data in units = ',trim(
field(num_fields)%units)
491 if (transpose_xy)
call mpp_error(fatal,
'axis ordering not supported')
495 field(num_fields)%numwindows = numwindows
496 allocate(
field(num_fields)%need_compute(nbuf, numwindows))
497 field(num_fields)%need_compute = .true.
499 allocate(
field(num_fields)%data(isdata:iedata,jsdata:jedata,siz(3),nbuf),&
500 field(num_fields)%mask(isdata:iedata,jsdata:jedata,siz(3),nbuf) )
501 field(num_fields)%mask = .false.
502 field(num_fields)%data = 0.0
503 slope=1.0;intercept=0.0
509 field(num_fields)%slope = slope
510 field(num_fields)%intercept = intercept
511 allocate(
field(num_fields)%ibuf(nbuf))
512 field(num_fields)%ibuf = -1
513 field(num_fields)%nbuf = 0
514 if(
PRESENT(override))
then 515 field(num_fields)%is_src = 1
516 field(num_fields)%ie_src = gxsize
517 field(num_fields)%js_src = 1
518 field(num_fields)%je_src = gysize
519 allocate(
field(num_fields)%src_data(gxsize,gysize,siz(3),nbuf))
521 field(num_fields)%is_src = isdata
522 field(num_fields)%ie_src = iedata
523 field(num_fields)%js_src = jsdata
524 field(num_fields)%je_src = jedata
525 allocate(
field(num_fields)%src_data(isdata:iedata,jsdata:jedata,siz(3),nbuf))
528 allocate(
field(num_fields)%time(ntime))
529 allocate(
field(num_fields)%period(ntime))
530 allocate(
field(num_fields)%start_time(ntime))
531 allocate(
field(num_fields)%end_time(ntime))
533 call mpp_get_atts(time_axis,units=units,calendar=calendar_type)
535 field(num_fields)%time(j) =
get_cal_time(tstamp(j),trim(units),trim(calendar_type),permit_calendar_conversion)
536 field(num_fields)%start_time(j) =
get_cal_time(tstart(j),trim(units),trim(calendar_type),permit_calendar_conversion)
537 field(num_fields)%end_time(j) =
get_cal_time( tend(j),trim(units),trim(calendar_type),permit_calendar_conversion)
540 if (
field(num_fields)%modulo_time)
then 546 if(
present(correct_leap_year_inconsistency))
then 547 field(num_fields)%correct_leap_year_inconsistency = correct_leap_year_inconsistency
549 field(num_fields)%correct_leap_year_inconsistency = .false.
560 field(num_fields)%have_modulo_times = .true.
562 field(num_fields)%have_modulo_times = .false.
565 call mpp_error(note,
'time_interp_external_mod: file '//trim(file)//
' has only one time level')
568 field(num_fields)%period(j) =
field(num_fields)%end_time(j)-
field(num_fields)%start_time(j)
571 sec = sec/2+mod(day,2)*43200
573 field(num_fields)%time(j) =
field(num_fields)%start_time(j)+&
576 if (j > 1 .and. j < ntime)
then 577 tdiff =
field(num_fields)%time(j+1) -
field(num_fields)%time(j-1)
579 sec = sec/2+mod(day,2)*43200
582 sec = sec/2+mod(day,2)*43200
586 elseif ( j == 1)
then 587 tdiff =
field(num_fields)%time(2) -
field(num_fields)%time(1)
590 sec = sec/2+mod(day,2)*43200
595 tdiff =
field(num_fields)%time(ntime) -
field(num_fields)%time(ntime-1)
598 sec = sec/2+mod(day,2)*43200
608 if (
field(num_fields)%time(j) >=
field(num_fields)%time(j+1))
then 609 write(msg,
'(A,i20)')
"times not monotonically increasing. Filename: " &
610 //trim(file)//
" field: "//trim(fieldname)//
" timeslice: ", j
618 if (
field(num_fields)%modulo_time)
write(outunit,*)
'data are being treated as modulo in time' 620 write(outunit,*)
'time index, ', j
621 call get_date(
field(num_fields)%start_time(j),yr,mon,day,hr,minu,sec)
622 write(outunit,
'(a,i4,a,i2,a,i2,1x,i2,a,i2,a,i2)') &
623 'start time: yyyy/mm/dd hh:mm:ss= ',yr,
'/',mon,
'/',day,hr,
':',minu,
':',sec
624 call get_date(
field(num_fields)%time(j),yr,mon,day,hr,minu,sec)
625 write(outunit,
'(a,i4,a,i2,a,i2,1x,i2,a,i2,a,i2)') &
626 'mid time: yyyy/mm/dd hh:mm:ss= ',yr,
'/',mon,
'/',day,hr,
':',minu,
':',sec
627 call get_date(
field(num_fields)%end_time(j),yr,mon,day,hr,minu,sec)
628 write(outunit,
'(a,i4,a,i2,a,i2,1x,i2,a,i2,a,i2)') &
629 'end time: yyyy/mm/dd hh:mm:ss= ',yr,
'/',mon,
'/',day,hr,
':',minu,
':',sec
635 if (num_fields == nfields_orig)
then 636 if (
present(ierr))
then 639 call mpp_error(fatal,
'external field "'//trim(fieldname)//
'" not found in file "'//trim(file)//
'"')
643 deallocate(global_atts)
646 deallocate(tstamp, tstart, tend, tavg)
656 is_in, ie_in, js_in, je_in, window_id)
658 integer,
intent(in) :: index
659 type(time_type),
intent(in) :: time
660 real,
dimension(:,:),
intent(inout) :: data_in
661 integer,
intent(in),
optional :: interp
662 logical,
intent(in),
optional :: verbose
663 type(horiz_interp_type),
intent(in),
optional :: horz_interp
664 logical,
dimension(:,:),
intent(out),
optional :: mask_out
665 integer,
intent(in),
optional :: is_in, ie_in, js_in, je_in
666 integer,
intent(in),
optional :: window_id
668 real ,
dimension(size(data_in,1), size(data_in,2), 1) :: data_out
669 logical,
dimension(size(data_in,1), size(data_in,2), 1) :: mask3d
671 data_out(:,:,1) = data_in(:,:)
673 is_in=is_in,ie_in=ie_in,js_in=js_in,je_in=je_in,window_id=window_id)
674 data_in(:,:) = data_out(:,:,1)
675 if (
PRESENT(mask_out)) mask_out(:,:) = mask3d(:,:,1)
705 subroutine time_interp_external_3d(index, time, data, interp,verbose,horz_interp, mask_out, is_in, ie_in, js_in, je_in, window_id)
707 integer,
intent(in) :: index
708 type(time_type),
intent(in) :: time
709 real,
dimension(:,:,:),
intent(inout) :: data
710 integer,
intent(in),
optional :: interp
711 logical,
intent(in),
optional :: verbose
712 type(horiz_interp_type),
intent(in),
optional :: horz_interp
713 logical,
dimension(:,:,:),
intent(out),
optional :: mask_out
714 integer,
intent(in),
optional :: is_in, ie_in, js_in, je_in
715 integer,
intent(in),
optional :: window_id
717 integer :: nx, ny, nz, interp_method, t1, t2
718 integer :: i1, i2, isc, iec, jsc, jec, mod_time
719 integer :: yy, mm, dd, hh, min, ss
720 character(len=256) :: err_msg, filename
722 integer :: isw, iew, jsw, jew, nxw, nyw
730 character(len=16) :: message1, message2
737 if (
PRESENT(interp)) interp_method = interp
739 if (
PRESENT(verbose)) verb=verbose
742 if (index < 1.or.index > num_fields) &
743 call mpp_error(fatal,
'invalid index in call to time_interp_ext -- field was not initialized or failed to initialize')
748 if(
field(index)%numwindows == 1 )
then 752 if( .not.
present(is_in) .or. .not.
present(ie_in) .or. .not.
present(js_in) .or. .not.
present(je_in) )
then 753 call mpp_error(fatal,
'time_interp_external: is_in, ie_in, js_in and je_in must be present ' // &
754 'when numwindows > 1, field='//trim(
field(index)%name))
756 nxw = ie_in - is_in + 1
757 nyw = je_in - js_in + 1
758 isc = isc + is_in - 1
759 iec = isc + ie_in - is_in
760 jsc = jsc + js_in - 1
761 jec = jsc + je_in - js_in
764 isw = (nx-nxw)/2+1; iew = isw+nxw-1
765 jsw = (ny-nyw)/2+1; jew = jsw+nyw-1
767 if (nx < nxw .or. ny < nyw .or. nz <
field(index)%siz(3))
then 768 write(message1,
'(i6,2i5)') nx,ny,nz
769 call mpp_error(fatal,
'field '//trim(
field(index)%name)//
' Array size mismatch in time_interp_external.'// &
770 ' Array "data" is too small. shape(data)='//message1)
772 if(
PRESENT(mask_out))
then 773 if (
size(mask_out,1) /= nx .or.
size(mask_out,2) /= ny .or.
size(mask_out,3) /= nz)
then 774 write(message1,
'(i6,2i5)') nx,ny,nz
775 write(message2,
'(i6,2i5)')
size(mask_out,1),
size(mask_out,2),
size(mask_out,3)
776 call mpp_error(fatal,
'field '//trim(
field(index)%name)//
' array size mismatch in time_interp_external.'// &
777 ' Shape of array "mask_out" does not match that of array "data".'// &
778 ' shape(data)='//message1//
' shape(mask_out)='//message2)
782 if (
field(index)%siz(4) == 1)
then 784 call load_record(
field(index),1,horz_interp, is_in, ie_in ,js_in, je_in,window_id)
787 where(
field(index)%mask(isc:iec,jsc:jec,:,i1))
788 data(isw:iew,jsw:jew,:) =
field(index)%data(isc:iec,jsc:jec,:,i1)
791 data(isw:iew,jsw:jew,:) =
field(index)%missing
794 where(
field(index)%mask(isc:iec,jsc:jec,:,i1))
795 data(isw:iew,jsw:jew,:) =
field(index)%data(isc:iec,jsc:jec,:,i1)
798 if(
PRESENT(mask_out)) &
799 mask_out(isw:iew,jsw:jew,:) =
field(index)%mask(isc:iec,jsc:jec,:,i1)
801 if(
field(index)%have_modulo_times)
then 803 w2, t1, t2,
field(index)%correct_leap_year_inconsistency, err_msg=err_msg)
804 if(err_msg .NE.
'')
then 805 filename = mpp_get_file_name(
field(index)%unit)
806 call mpp_error(fatal,
"time_interp_external 1: "//trim(err_msg)//&
807 ",file="//trim(filename)//
",field="//trim(
field(index)%name) )
810 if(
field(index)%modulo_time)
then 815 call time_interp(time,
field(index)%time(:),w2,t1,t2,modtime=mod_time, err_msg=err_msg)
816 if(err_msg .NE.
'')
then 817 filename = mpp_get_file_name(
field(index)%unit)
818 call mpp_error(fatal,
"time_interp_external 2: "//trim(err_msg)//&
819 ",file="//trim(filename)//
",field="//trim(
field(index)%name) )
824 call get_date(time,yy,mm,dd,hh,min,ss)
825 write(outunit,
'(a,i4,a,i2,a,i2,1x,i2,a,i2,a,i2)') &
826 'target time yyyy/mm/dd hh:mm:ss= ',yy,
'/',mm,
'/',dd,hh,
':',min,
':',ss
827 write(outunit,*)
't1, t2, w1, w2= ', t1, t2, w1, w2
830 call load_record(
field(index),t1,horz_interp, is_in, ie_in ,js_in, je_in, window_id)
831 call load_record(
field(index),t2,horz_interp, is_in, ie_in ,js_in, je_in, window_id)
835 call mpp_error(fatal,
'time_interp_external : records were not loaded correctly in memory')
838 write(outunit,*)
'ibuf= ',
field(index)%ibuf
839 write(outunit,*)
'i1,i2= ',i1, i2
843 where(
field(index)%mask(isc:iec,jsc:jec,:,i1).and.
field(index)%mask(isc:iec,jsc:jec,:,i2))
844 data(isw:iew,jsw:jew,:) =
field(index)%data(isc:iec,jsc:jec,:,i1)*w1 + &
845 field(index)%data(isc:iec,jsc:jec,:,i2)*w2
848 data(isw:iew,jsw:jew,:) =
field(index)%missing
851 where(
field(index)%mask(isc:iec,jsc:jec,:,i1).and.
field(index)%mask(isc:iec,jsc:jec,:,i2))
852 data(isw:iew,jsw:jew,:) =
field(index)%data(isc:iec,jsc:jec,:,i1)*w1 + &
853 field(index)%data(isc:iec,jsc:jec,:,i2)*w2
856 if(
PRESENT(mask_out)) &
857 mask_out(isw:iew,jsw:jew,:) = &
858 field(index)%mask(isc:iec,jsc:jec,:,i1).and.&
859 field(index)%mask(isc:iec,jsc:jec,:,i2)
867 integer,
intent(in) :: index
868 type(time_type),
intent(in) :: time
869 real,
intent(inout) :: data
870 logical,
intent(in),
optional :: verbose
873 integer :: i1, i2, mod_time
874 integer :: yy, mm, dd, hh, min, ss
875 character(len=256) :: err_msg, filename
881 if (
PRESENT(verbose)) verb=verbose
884 if (index < 1.or.index > num_fields) &
885 call mpp_error(fatal,
'invalid index in call to time_interp_ext -- field was not initialized or failed to initialize')
887 if (
field(index)%siz(4) == 1)
then 891 data =
field(index)%data(1,1,1,i1)
893 if(
field(index)%have_modulo_times)
then 895 w2, t1, t2,
field(index)%correct_leap_year_inconsistency, err_msg=err_msg)
896 if(err_msg .NE.
'')
then 897 filename = mpp_get_file_name(
field(index)%unit)
898 call mpp_error(fatal,
"time_interp_external 3:"//trim(err_msg)//&
899 ",file="//trim(filename)//
",field="//trim(
field(index)%name) )
902 if(
field(index)%modulo_time)
then 907 call time_interp(time,
field(index)%time(:),w2,t1,t2,modtime=mod_time, err_msg=err_msg)
908 if(err_msg .NE.
'')
then 909 filename = mpp_get_file_name(
field(index)%unit)
910 call mpp_error(fatal,
"time_interp_external 4:"//trim(err_msg)// &
911 ",file="//trim(filename)//
",field="//trim(
field(index)%name) )
916 call get_date(time,yy,mm,dd,hh,min,ss)
917 write(outunit,
'(a,i4,a,i2,a,i2,1x,i2,a,i2,a,i2)') &
918 'target time yyyy/mm/dd hh:mm:ss= ',yy,
'/',mm,
'/',dd,hh,
':',min,
':',ss
919 write(outunit,*)
't1, t2, w1, w2= ', t1, t2, w1, w2
927 call mpp_error(fatal,
'time_interp_external : records were not loaded correctly in memory')
928 data =
field(index)%data(1,1,1,i1)*w1 +
field(index)%data(1,1,1,i2)*w2
930 write(outunit,*)
'ibuf= ',
field(index)%ibuf
931 write(outunit,*)
'i1,i2= ',i1, i2
939 type(
time_type),
intent(inout),
dimension(:) :: time
942 integer :: yr, mon, dy, hr, minu, sec
944 ntime =
size(time(:))
947 call get_date(time(n), yr, mon, dy, hr, minu, sec)
949 time(n) =
set_date(yr, mon, dy, hr, minu, sec)
957 subroutine load_record(field, rec, interp, is_in, ie_in, js_in, je_in, window_id_in)
958 type(ext_fieldtype),
intent(inout) :: field
959 integer ,
intent(in) :: rec
960 type(horiz_interp_type),
intent(in),
optional :: interp
961 integer,
intent(in),
optional :: is_in, ie_in, js_in, je_in
962 integer,
intent(in),
optional :: window_id_in
966 integer :: isw,iew,jsw,jew
967 integer :: is_region, ie_region, js_region, je_region, i, j, n
968 integer :: start(4), nread(4)
969 logical :: need_compute
970 real :: mask_in(size(field%src_data,1),size(field%src_data,2),size(field%src_data,3))
971 real,
allocatable :: mask_out(:,:,:)
975 if(
PRESENT(window_id_in) ) window_id = window_id_in
976 need_compute = .true.
983 need_compute = .false.
986 field%nbuf = field%nbuf + 1
987 if(field%nbuf >
size(field%data,4).or.field%nbuf <= 0) field%nbuf = 1
990 field%need_compute(ib,:) = .true.
992 if (field%domain_present .and. .not.
PRESENT(interp))
then 993 if (
debug_this_module)
write(outunit,*)
'reading record with domain for field ',trim(field%name)
994 call mpp_read(field%unit,field%field,field%domain,field%src_data(:,:,:,ib),rec)
996 if (
debug_this_module)
write(outunit,*)
'reading record without domain for field ',trim(field%name)
998 start(1) = field%is_src; nread(1) = field%ie_src - field%is_src + 1
999 start(2) = field%js_src; nread(2) = field%je_src - field%js_src + 1
1000 start(3) = 1; nread(3) =
size(field%src_data,3)
1001 start(field%tdim) = rec; nread(field%tdim) = 1
1002 call mpp_read(field%unit,field%field,field%src_data(:,:,:,ib),start,nread)
1006 isw=field%isc;iew=field%iec
1007 jsw=field%jsc;jew=field%jec
1009 if( field%numwindows > 1)
then 1010 if( .NOT.
PRESENT(is_in) .OR. .NOT.
PRESENT(ie_in) .OR. .NOT.
PRESENT(js_in) .OR. .NOT.
PRESENT(je_in) )
then 1011 call mpp_error(fatal,
'time_interp_external(load_record): is_in, ie_in, js_in, je_in must be present when numwindows>1')
1013 isw = isw + is_in - 1
1014 iew = isw + ie_in - is_in
1015 jsw = jsw + js_in - 1
1016 jew = jsw + je_in - js_in
1021 need_compute = field%need_compute(ib, window_id)
1022 if(need_compute)
then 1023 if(
PRESENT(interp))
then 1024 is_region = field%is_region; ie_region = field%ie_region
1025 js_region = field%js_region; je_region = field%je_region
1027 where (mpp_is_valid(field%src_data(:,:,:,ib), field%valid)) mask_in = 1.0
1028 if ( field%region_type .NE.
no_region )
then 1029 if( any(mask_in == 0.0) )
then 1030 call mpp_error(fatal,
"time_interp_external: mask_in should be all 1 when region_type is not NO_REGION")
1033 do j = js_region, je_region
1034 do i = is_region, ie_region
1035 mask_in(i,j,:) = 0.0
1039 do j = 1,
size(mask_in,2)
1040 do i = 1,
size(mask_in,1)
1041 if( j<js_region .OR. j>je_region .OR. i<is_region .OR. i>ie_region ) mask_in(i,j,:) = 0.0
1046 allocate(mask_out(isw:iew,jsw:jew,
size(field%src_data,3)))
1047 call horiz_interp(interp,field%src_data(:,:,:,ib),field%data(isw:iew,jsw:jew,:,ib), &
1051 field%mask(isw:iew,jsw:jew,:,ib) = mask_out(isw:iew,jsw:jew,:) > 0
1052 deallocate(mask_out)
1053 field%need_compute(ib, window_id) = .false.
1055 if ( field%region_type .NE.
no_region )
then 1056 call mpp_error(fatal,
"time_interp_external: region_type should be NO_REGION when interp is not present")
1058 field%data(isw:iew,jsw:jew,:,ib) = field%src_data(isw:iew,jsw:jew,:,ib)
1059 field%mask(isw:iew,jsw:jew,:,ib) = mpp_is_valid(field%data(isw:iew,jsw:jew,:,ib),field%valid)
1062 where(field%mask(isw:iew,jsw:jew,:,ib)) field%data(isw:iew,jsw:jew,:,ib) = &
1063 field%data(isw:iew,jsw:jew,:,ib)*field%slope + field%intercept
1070 type(ext_fieldtype),
intent(inout) :: field
1071 integer ,
intent(in) :: rec
1074 integer :: start(4), nread(4)
1082 field%nbuf = field%nbuf + 1
1083 if(field%nbuf >
size(field%data,4).or.field%nbuf <= 0) field%nbuf = 1
1085 field%ibuf(ib) = rec
1087 if (
debug_this_module)
write(outunit,*)
'reading record without domain for field ',trim(field%name)
1088 start = 1; nread = 1
1089 start(3) = 1; nread(3) =
size(field%src_data,3)
1090 start(field%tdim) = rec; nread(field%tdim) = 1
1091 call mpp_read(field%unit,field%field,field%src_data(:,:,:,ib),start,nread)
1092 if ( field%region_type .NE.
no_region )
then 1093 call mpp_error(fatal,
"time_interp_external: region_type should be NO_REGION when field is scalar")
1095 field%data(1,1,:,ib) = field%src_data(1,1,:,ib)
1096 field%mask(1,1,:,ib) = mpp_is_valid(field%data(1,1,:,ib),field%valid)
1098 where(field%mask(1,1,:,ib)) field%data(1,1,:,ib) = &
1099 field%data(1,1,:,ib)*field%slope + field%intercept
1106 integer,
intent(in) :: index
1107 integer,
intent(in) :: is, ie, js, je
1110 if( is ==
field(index)%is_src .AND. ie ==
field(index)%ie_src .AND. &
1111 js ==
field(index)%js_src .AND. ie ==
field(index)%je_src )
return 1113 if( .NOT.
ASSOCIATED(
field(index)%src_data) )
call mpp_error(fatal, &
1114 "time_interp_external: field(index)%src_data is not associated")
1115 nk =
size(
field(index)%src_data,3)
1116 nbuf =
size(
field(index)%src_data,4)
1117 deallocate(
field(index)%src_data)
1118 allocate(
field(index)%src_data(is:ie,js:je,nk,nbuf))
1119 field(index)%is_src = is
1120 field(index)%ie_src = ie
1121 field(index)%js_src = js
1122 field(index)%je_src = je
1128 subroutine set_override_region(index, region_type, is_region, ie_region, js_region, je_region)
1129 integer,
intent(in) :: index, region_type
1130 integer,
intent(in) :: is_region, ie_region, js_region, je_region
1132 field(index)%region_type = region_type
1133 field(index)%is_region = is_region
1134 field(index)%ie_region = ie_region
1135 field(index)%js_region = js_region
1136 field(index)%je_region = je_region
1145 integer,
intent(in) :: n
1147 type(filetype),
pointer :: ptr(:)
1156 ptr(i)%filename =
'' 1171 integer,
intent(in) :: n
1173 type(ext_fieldtype),
pointer :: ptr(:)
1176 if (
associated(
field))
then 1177 if (n <=
size(
field))
return 1189 if (
ASSOCIATED(ptr(i)%time))
DEALLOCATE(ptr(i)%time, stat=ier)
1190 if (
ASSOCIATED(ptr(i)%start_time))
DEALLOCATE(ptr(i)%start_time, stat=ier)
1191 if (
ASSOCIATED(ptr(i)%end_time))
DEALLOCATE(ptr(i)%end_time, stat=ier)
1193 if (
ASSOCIATED(ptr(i)%period))
DEALLOCATE(ptr(i)%period, stat=ier)
1194 ptr(i)%modulo_time=.false.
1195 if (
ASSOCIATED(ptr(i)%data))
DEALLOCATE(ptr(i)%data, stat=ier)
1196 if (
ASSOCIATED(ptr(i)%ibuf))
DEALLOCATE(ptr(i)%ibuf, stat=ier)
1197 if (
ASSOCIATED(ptr(i)%src_data))
DEALLOCATE(ptr(i)%src_data, stat=ier)
1199 ptr(i)%domain_present=.false.
1201 ptr(i)%intercept=0.0
1202 ptr(i)%isc=-1;ptr(i)%iec=-1
1203 ptr(i)%jsc=-1;ptr(i)%jec=-1
1205 if (
associated(
field))
then 1216 integer,
dimension(:) :: buf
1226 if (buf(i) == indx)
then 1251 if (index .lt. 1 .or. index .gt. num_fields) &
1252 call mpp_error(fatal,
'invalid index in call to get_external_field_size')
1280 if (index .lt. 1 .or. index .gt. num_fields) &
1281 call mpp_error(fatal,
'invalid index in call to get_external_field_size')
1307 if (index .lt. 1 .or. index .gt. num_fields) &
1308 call mpp_error(fatal,
'invalid index in call to get_external_field_size')
1321 integer ,
intent(in) :: index
1326 if (index < 1.or.index > num_fields) &
1327 call mpp_error(fatal,
'invalid index in call to get_time_axis')
1329 n =
min(
size(time),
size(
field(index)%time))
1331 time(1:n) =
field(index)%time(1:n)
1350 if (
ASSOCIATED(
field(i)%src_data))
deallocate(
field(i)%src_data)
1358 field(i)%intercept = 0.
1373 #ifdef test_time_interp_external 1375 program test_time_interp_ext
1378 use mpp_mod,
only : mpp_init, mpp_exit, mpp_npes, stdout, stdlog, fatal,
mpp_error 1380 use mpp_io_mod,
only : mpp_io_init, mpp_io_exit, mpp_open, mpp_rdonly, mpp_ascii, mpp_close, &
1384 mpp_domains_set_stack_size
1395 integer :: id, i, io_status, unit, ierr
1396 character(len=128) :: filename, fieldname
1398 real,
allocatable,
dimension(:,:,:) :: data_d, data_g
1399 logical,
allocatable,
dimension(:,:,:) :: mask_d
1400 type(
domain2d) :: domain, domain_out
1401 integer :: layout(2), fld_size(4)
1402 integer :: isc, iec, jsc, jec, isd, ied, jsd, jed
1403 integer :: yy, mm, dd, hh, ss
1405 character(len=12) :: cal_type
1406 integer :: ntime=12,year0=1991,month0=1,day0=1,days_inc=31
1407 type(horiz_interp_type) :: hinterp
1408 type(
axistype) :: axis_centers(4), axis_bounds(4)
1409 real :: lon_out(180,89), lat_out(180,89)
1410 real,
allocatable,
dimension(:,:) :: lon_local_out, lat_local_out
1411 real,
allocatable,
dimension(:) :: lon_in, lat_in
1412 integer :: isc_o, iec_o, jsc_o, jec_o, outunit
1414 namelist /test_time_interp_ext_nml/ filename, fieldname,ntime,year0,month0,&
1415 day0,days_inc, cal_type
1420 call mpp_domains_init
1425 #ifdef INTERNAL_FILE_NML 1426 read (
input_nml_file, test_time_interp_ext_nml, iostat=io_status)
1429 unit = open_namelist_file()
1430 ierr=1;
do while (ierr /= 0)
1431 read (unit, nml=test_time_interp_ext_nml, iostat=io_status, end=10)
1434 10
call close_file (unit)
1438 write(outunit,test_time_interp_ext_nml)
1440 select case (trim(cal_type))
1446 call mpp_error(fatal,
'invalid calendar type')
1450 write(outunit,*)
'INTERPOLATING NON DECOMPOSED FIELDS' 1451 write(outunit,*)
'======================================' 1459 allocate(data_g(fld_size(1),fld_size(2),fld_size(3)))
1462 time =
set_date(year0,month0,day0,0,0,0)
1469 write(outunit,*)
'sum= ', sm
1470 write(outunit,*)
'max= ', mx
1471 write(outunit,*)
'min= ', mn
1480 call mpp_domains_set_stack_size(fld_size(1)*fld_size(2)*
min(fld_size(3),1)*2)
1481 allocate(data_d(isd:ied,jsd:jed,fld_size(3)))
1484 write(outunit,*)
'INTERPOLATING DOMAIN DECOMPOSED FIELDS' 1485 write(outunit,*)
'======================================' 1496 write(outunit,*)
'global sum= ', sm
1497 write(outunit,*)
'global max= ', mx
1498 write(outunit,*)
'global min= ', mn
1502 write(outunit,*)
'INTERPOLATING DOMAIN DECOMPOSED FIELDS USING HORIZ INTERP' 1503 write(outunit,*)
'======================================' 1509 lon_out(i,:) = 2.0*i*atan(1.0)/45.0
1513 lat_out(:,i) = (i-45)*2.0*atan(1.0)/45.0
1521 verbose=.true., override=.true.)
1523 allocate (lon_local_out(isc_o:iec_o,jsc_o:jec_o))
1524 allocate (lat_local_out(isc_o:iec_o,jsc_o:jec_o))
1526 lon_local_out(isc_o:iec_o,jsc_o:jec_o) = lon_out(isc_o:iec_o,jsc_o:jec_o)
1527 lat_local_out(isc_o:iec_o,jsc_o:jec_o) = lat_out(isc_o:iec_o,jsc_o:jec_o)
1532 allocate(lon_in(fld_size(1)+1))
1533 allocate(lat_in(fld_size(2)+1))
1535 call mpp_get_axis_data(axis_bounds(1), lon_in) ; lon_in = lon_in*atan(1.0)/45
1536 call mpp_get_axis_data(axis_bounds(2), lat_in) ; lat_in = lat_in*atan(1.0)/45
1538 call horiz_interp_new(hinterp,lon_in,lat_in, lon_local_out, lat_local_out, &
1539 interp_method=
'bilinear')
1544 allocate(data_d(isc_o:iec_o,jsc_o:jec_o,fld_size(3)))
1545 allocate(mask_d(isc_o:iec_o,jsc_o:jec_o,fld_size(3)))
1552 write(outunit,*)
'global sum= ', sm
1553 write(outunit,*)
'global max= ', mx
1554 write(outunit,*)
'global min= ', mn
1562 write(outunit,*)
'n valid points= ', sm
1577 end program test_time_interp_ext
subroutine, public time_interp_init()
type(time_type) function, public increment_time(Time, seconds, days, ticks, err_msg, allow_neg_inc)
subroutine, public get_date(time, year, month, day, hour, minute, second, tick, err_msg)
type(ext_fieldtype), dimension(:), pointer, save, private field
subroutine, public get_time_axis(index, time)
integer, parameter, public noleap
subroutine realloc_files(n)
subroutine, public time_interp_external_init()
subroutine time_interp_external_0d(index, time, data, verbose)
subroutine, public horiz_interp_del(Interp)
integer function, private find_buf_index(indx, buf)
integer, parameter, public inside_region
logical function, public get_axis_modulo(axis)
logical function, public get_axis_modulo_times(axis, tbeg, tend)
type(time_type) function, public get_cal_time(time_increment, units, calendar, permit_calendar_conversion)
logical, private debug_this_module
integer function, public check_nml_error(IOSTAT, NML_NAME)
subroutine, public time_interp_external_exit()
logical, private module_initialized
subroutine time_interp_external_2d(index, time, data_in, interp, verbose, horz_interp, mask_out, is_in, ie_in, js_in, je_in, window_id)
character(len=input_str_length), dimension(:), allocatable, target, public input_nml_file
subroutine, public set_calendar_type(type, err_msg)
type(domain2d), save, public null_domain2d
integer function, public init_external_field(file, fieldname, format, threading, domain, desired_units, verbose, axis_centers, axis_sizes, override, correct_leap_year_inconsistency, permit_calendar_conversion, use_comp_domain, ierr, nwindows, ignore_axis_atts)
integer, parameter, private modulo_year
integer, parameter, private linear_time_interp
integer function, public days_in_month(Time, err_msg)
integer, parameter, public julian
integer, private max_files
subroutine, public get_axis_cart(axis, cart)
integer function, public get_calendar_type()
subroutine load_record(field, rec, interp, is_in, ie_in, js_in, je_in, window_id_in)
type(axistype), save, public default_axis
integer, parameter, public success
integer function, dimension(4), public get_external_field_size(index)
integer, parameter, public err_field_not_found
subroutine, public time_manager_init()
subroutine, public horiz_interp_init
integer, parameter, public no_region
integer, parameter, public no_calendar
integer, private num_files
subroutine, public reset_src_data_region(index, is, ie, js, je)
subroutine, public set_override_region(index, region_type, is_region, ie_region, js_region, je_region)
subroutine, public get_axis_bounds(axis, axis_bound, axes, bnd_name, err_msg)
type(axistype) function, dimension(4), public get_external_field_axes(index)
real(double_kind), parameter, private time_interp_missing
integer, private num_io_buffers
integer function, public days_in_year(Time)
type(filetype), dimension(:), pointer, save, private opened_files
subroutine, private set_time_modulo(Time)
subroutine, public get_time(Time, seconds, days, ticks, err_msg)
real function, public get_external_field_missing(index)
subroutine time_interp_external_3d(index, time, data, interp, verbose, horz_interp, mask_out, is_in, ie_in, js_in, je_in, window_id)
subroutine, public constants_init
dummy routine.
type(fieldtype), save, public default_field
subroutine load_record_0d(field, rec)
integer, private max_fields
subroutine realloc_fields(n)
integer, parameter, public outside_region