33 public :: extin_update
35 interface extin_update
39 end interface extin_update
49 private :: extin_time_advance
55 integer,
private,
parameter :: i_prev = 1
56 integer,
private,
parameter :: i_next = 2
58 integer,
private,
parameter :: i_periodic_year = 1
59 integer,
private,
parameter :: i_periodic_month = 2
60 integer,
private,
parameter :: i_periodic_day = 3
62 integer,
private,
parameter :: extin_item_limit = 1000
63 integer,
private,
parameter :: extin_step_limit = 10000
64 integer,
private,
parameter :: extin_dim_limit = 3
66 type,
private :: extin_itemcontainer
67 character(len=H_LONG) :: basename
68 character(len=H_SHORT) :: varname
69 integer :: dim_size(extin_dim_limit)
71 real(DP),
allocatable :: time(:)
73 integer :: flag_periodic
75 integer :: data_steppos(2)
76 real(RP),
allocatable ::
value(:,:,:,:)
77 end type extin_itemcontainer
80 integer,
private :: extin_item_count = 0
81 type(extin_itemcontainer),
private,
allocatable :: extin_item(:)
111 character(len=H_LONG) :: basename
112 character(len=H_SHORT) :: varname
113 integer :: step_limit
114 integer :: step_fixed
115 logical :: enable_periodic_year
116 logical :: enable_periodic_month
117 logical :: enable_periodic_day
126 enable_periodic_year, &
127 enable_periodic_month, &
128 enable_periodic_day, &
133 character(len=H_LONG) :: description
134 character(len=H_SHORT) :: unit
137 character(len=H_SHORT) :: dim_name (3)
138 integer :: dim_size (3)
139 real(DP) :: time_start(extin_step_limit)
140 real(DP) :: time_end (extin_step_limit)
141 character(len=H_MID) :: time_units
143 integer :: datadate(6)
144 real(DP) :: datasubsec
147 integer :: offset_year
150 integer :: count, nid, t, n
155 if(
io_l )
write(
io_fid_log,*)
'++++++ Module[EXTIN] / Categ[ATMOS-RM IO] / Origin[SCALElib]' 159 do count = 1, extin_item_limit
164 elseif( ierr > 0 )
then 165 write(*,*)
'xxx Not appropriate names in namelist EXTITEM. Check!', count
169 extin_item_count = count - 1
172 if ( extin_item_count == 0 )
then 176 if(
io_l )
write(
io_fid_log,*)
'*** Number of external item : ', extin_item_count
179 allocate( extin_item(extin_item_count) )
183 do nid = 1, extin_item_count
186 step_limit = extin_step_limit
190 enable_periodic_year = .false.
191 enable_periodic_month = .false.
192 enable_periodic_day = .false.
212 time_start(1:step_limit), &
213 time_end(1:step_limit), &
216 if ( step_nmax == 0 )
then 217 write(*,*)
'xxx Data not found! basename,varname = ', trim(basename),
', ', trim(varname)
226 extin_item(nid)%basename = basename
227 extin_item(nid)%varname = varname
228 extin_item(nid)%dim_size(:) = dim_size(:)
229 extin_item(nid)%step_num = step_nmax
231 if ( enable_periodic_day )
then 232 extin_item(nid)%flag_periodic = i_periodic_day
233 elseif( enable_periodic_month )
then 234 extin_item(nid)%flag_periodic = i_periodic_month
235 elseif( enable_periodic_year )
then 236 extin_item(nid)%flag_periodic = i_periodic_year
238 extin_item(nid)%flag_periodic = 0
241 allocate( extin_item(nid)%value( dim_size(1),dim_size(2),dim_size(3),2) )
242 extin_item(nid)%value(:,:,:,:) = defval
243 extin_item(nid)%offset = offset
245 allocate( extin_item(nid)%time(step_nmax) )
246 extin_item(nid)%time(:) = 0.0_dp
248 do t = 1, extin_item(nid)%step_num
249 cftime = 0.5_dp * ( time_start(t) + time_end(t) )
254 if ( extin_item(nid)%step_num == 1 )
then 260 if ( step_fixed > 0 )
then 262 extin_item(nid)%fixed_step = .true.
263 extin_item(nid)%data_steppos(i_prev) = step_fixed
264 extin_item(nid)%data_steppos(i_next) = step_fixed
268 extin_item(nid)%fixed_step = .false.
271 extin_item(nid)%data_steppos(i_next) = 1
272 do t = 1, extin_item(nid)%step_num
274 extin_item(nid)%data_steppos(i_next) = t + 1
277 extin_item(nid)%data_steppos(i_prev) = extin_item(nid)%data_steppos(i_next) - 1
279 if ( extin_item(nid)%flag_periodic > 0 )
then 281 if ( extin_item(nid)%data_steppos(i_next) == 1 )
then 284 extin_item(nid)%data_steppos(i_prev) = extin_item(nid)%step_num
286 elseif( extin_item(nid)%data_steppos(i_next) == extin_item(nid)%step_num+1 )
then 289 extin_item(nid)%data_steppos(i_next) = 1
292 do t = 1, extin_item(nid)%step_num
294 datasec = extin_item(nid)%time(t)
304 if ( extin_item(nid)%flag_periodic == i_periodic_day )
then 306 elseif( extin_item(nid)%flag_periodic == i_periodic_month )
then 308 elseif( extin_item(nid)%flag_periodic == i_periodic_year )
then 326 if ( extin_item(nid)%data_steppos(i_next) == 1 &
327 .OR. extin_item(nid)%data_steppos(i_next) == extin_item(nid)%step_num+1 )
then 328 write(*,*)
'xxx Current time is out of period of external data! ', extin_item(nid)%varname
337 if ( dim_size(1) >= 1 &
338 .AND. dim_size(2) == 1 &
339 .AND. dim_size(3) == 1 )
then 342 call fileread( extin_item(nid)%value(:,1,1,i_prev), &
343 extin_item(nid)%basename, &
344 extin_item(nid)%varname, &
345 extin_item(nid)%data_steppos(i_prev), &
348 call fileread( extin_item(nid)%value(:,1,1,i_next), &
349 extin_item(nid)%basename, &
350 extin_item(nid)%varname, &
351 extin_item(nid)%data_steppos(i_next), &
354 elseif ( dim_size(1) >= 1 &
355 .AND. dim_size(2) > 1 &
356 .AND. dim_size(3) == 1 )
then 359 call fileread( extin_item(nid)%value(:,:,1,i_prev), &
360 extin_item(nid)%basename, &
361 extin_item(nid)%varname, &
362 extin_item(nid)%data_steppos(i_prev), &
365 call fileread( extin_item(nid)%value(:,:,1,i_next), &
366 extin_item(nid)%basename, &
367 extin_item(nid)%varname, &
368 extin_item(nid)%data_steppos(i_next), &
371 elseif ( dim_size(1) >= 1 &
372 .AND. dim_size(2) > 1 &
373 .AND. dim_size(3) > 1 )
then 376 call fileread( extin_item(nid)%value(:,:,:,i_prev), &
377 extin_item(nid)%basename, &
378 extin_item(nid)%varname, &
379 extin_item(nid)%data_steppos(i_prev), &
382 call fileread( extin_item(nid)%value(:,:,:,i_next), &
383 extin_item(nid)%basename, &
384 extin_item(nid)%varname, &
385 extin_item(nid)%data_steppos(i_next), &
389 write(*,*)
'xxx Unexpected dimsize: ', dim_size(:)
413 real(RP),
intent(out) :: var(:)
414 character(len=*),
intent(in) :: varname
415 character(len=*),
intent(in) :: axistype
416 real(DP),
intent(in) :: current_time
417 logical,
intent(out) :: error
421 logical :: do_readfile
423 integer :: dim1_max, dim1_S, dim1_E, n1, nn1
431 do n = 1, extin_item_count
432 if( varname == extin_item(n)%varname ) nid = n
435 if( nid == 0 )
return 437 if ( axistype ==
'Z' )
then 441 elseif( axistype ==
'X' )
then 445 elseif( axistype ==
'Y' )
then 450 write(*,*)
'xxx unsupported axis type. Check!', trim(axistype),
' item:',trim(varname)
454 if ( dim1_max /= extin_item(nid)%dim_size(1) )
then 455 write(*,*)
'xxx data length does not match! ', trim(axistype),
' item:', trim(varname)
456 write(*,*)
'xxx dim 1 (data,requested) : ', extin_item(nid)%dim_size(1), dim1_max
460 call extin_time_advance( nid, &
465 if ( do_readfile )
then 466 if(
io_l )
write(
io_fid_log,
'(1x,A,A15)')
'*** Read 1D var: ', trim(extin_item(nid)%varname)
469 extin_item(nid)%value(:,:,:,i_prev) = extin_item(nid)%value(:,:,:,i_next)
472 call fileread( extin_item(nid)%value(:,1,1,i_next), &
473 extin_item(nid)%basename, &
474 extin_item(nid)%varname, &
475 extin_item(nid)%data_steppos(i_next), &
481 nn1 = n1 + dim1_s - 1
483 var(nn1) = ( 1.0_rp-weight ) * extin_item(nid)%value(n1,1,1,i_prev) &
484 + ( weight ) * extin_item(nid)%value(n1,1,1,i_next)
507 real(RP),
intent(out) :: var(:,:)
508 character(len=*),
intent(in) :: varname
509 character(len=*),
intent(in) :: axistype
510 real(DP),
intent(in) :: current_time
511 logical,
intent(out) :: error
515 logical :: do_readfile
517 integer :: dim1_max, dim1_S, dim1_E, n1, nn1
518 integer :: dim2_max, dim2_S, dim2_E, n2, nn2
526 do n = 1, extin_item_count
527 if( varname == extin_item(n)%varname ) nid = n
530 if( nid == 0 )
return 532 if ( axistype ==
'XY' )
then 539 elseif( axistype ==
'ZX' )
then 547 write(*,*)
'xxx unsupported axis type. Check!', trim(axistype),
' item:',trim(varname)
551 if ( dim1_max /= extin_item(nid)%dim_size(1) &
552 .OR. dim2_max /= extin_item(nid)%dim_size(2) )
then 553 write(*,*)
'xxx data length does not match! ', trim(axistype),
' item:', trim(varname)
554 write(*,*)
'xxx dim 1 (data,requested) : ', extin_item(nid)%dim_size(1), dim1_max
555 write(*,*)
'xxx dim 2 (data,requested) : ', extin_item(nid)%dim_size(2), dim2_max
559 call extin_time_advance( nid, &
564 if ( do_readfile )
then 566 if(
io_l )
write(
io_fid_log,
'(1x,A,A15)')
'*** Read 2D var: ', trim(extin_item(nid)%varname)
568 extin_item(nid)%value(:,:,:,i_prev) = extin_item(nid)%value(:,:,:,i_next)
571 call fileread( extin_item(nid)%value(:,:,1,i_next), &
572 extin_item(nid)%basename, &
573 extin_item(nid)%varname, &
574 extin_item(nid)%data_steppos(i_next), &
580 nn2 = n2 + dim2_s - 1
582 nn1 = n1 + dim1_s - 1
584 var(nn1,nn2) = ( 1.0_rp-weight ) * extin_item(nid)%value(n1,n2,1,i_prev) &
585 + ( weight ) * extin_item(nid)%value(n1,n2,1,i_next)
609 real(RP),
intent(out) :: var(:,:,:)
610 character(len=*),
intent(in) :: varname
611 character(len=*),
intent(in) :: axistype
612 real(DP),
intent(in) :: current_time
613 logical,
intent(out) :: error
617 logical :: do_readfile
619 integer :: dim1_max, dim1_S, dim1_E, n1, nn1
620 integer :: dim2_max, dim2_S, dim2_E, n2, nn2
621 integer :: dim3_max, dim3_S, dim3_E, n3, nn3
629 do n = 1, extin_item_count
630 if( varname == extin_item(n)%varname ) nid = n
633 if( nid == 0 )
return 635 if ( axistype ==
'ZXY' )
then 645 else if ( axistype ==
'Land' )
then 655 else if ( axistype ==
'Urban' )
then 666 write(*,*)
'xxx unsupported axis type. Check!', trim(axistype),
' item:',trim(varname)
670 if ( dim1_max /= extin_item(nid)%dim_size(1) &
671 .OR. dim2_max /= extin_item(nid)%dim_size(2) &
672 .OR. dim3_max /= extin_item(nid)%dim_size(3) )
then 673 write(*,*)
'xxx data length does not match! ', trim(axistype),
' item:', trim(varname)
674 write(*,*)
'xxx dim 1 (data,requested) : ', extin_item(nid)%dim_size(1), dim1_max
675 write(*,*)
'xxx dim 2 (data,requested) : ', extin_item(nid)%dim_size(2), dim2_max
676 write(*,*)
'xxx dim 3 (data,requested) : ', extin_item(nid)%dim_size(3), dim3_max
680 call extin_time_advance( nid, &
685 if ( do_readfile )
then 686 if(
io_l )
write(
io_fid_log,
'(1x,A,A15)')
'*** Read 3D var: ', trim(extin_item(nid)%varname)
688 extin_item(nid)%value(:,:,:,i_prev) = extin_item(nid)%value(:,:,:,i_next)
691 call fileread( extin_item(nid)%value(:,:,:,i_next), &
692 extin_item(nid)%basename, &
693 extin_item(nid)%varname, &
694 extin_item(nid)%data_steppos(i_next), &
700 nn3 = n3 + dim3_s - 1
702 nn2 = n2 + dim2_s - 1
704 nn1 = n1 + dim1_s - 1
706 var(nn1,nn2,nn3) = ( 1.0_rp-weight ) * extin_item(nid)%value(n1,n2,n3,i_prev) &
707 + ( weight ) * extin_item(nid)%value(n1,n2,n3,i_next)
719 subroutine extin_time_advance( &
734 integer,
intent(in) :: nid
735 real(DP),
intent(in) :: current_time
736 real(RP),
intent(out) :: weight
737 logical,
intent(out) :: do_readfile
739 integer :: datadate(6)
740 real(DP) :: datasubsec
743 integer :: offset_year
745 real(DP) :: prev_time, next_time
749 do_readfile = .false.
751 if ( extin_item(nid)%fixed_step )
then 755 if ( current_time > extin_item(nid)%time( extin_item(nid)%data_steppos(i_next) ) )
then 759 if(
io_l )
write(
io_fid_log,*)
'*** Update external input : ', trim(extin_item(nid)%varname)
762 extin_item(nid)%data_steppos(i_prev) = extin_item(nid)%data_steppos(i_prev) + 1
763 extin_item(nid)%data_steppos(i_next) = extin_item(nid)%data_steppos(i_next) + 1
765 if ( extin_item(nid)%flag_periodic > 0 )
then 767 if ( extin_item(nid)%data_steppos(i_next) == extin_item(nid)%step_num+1 )
then 770 extin_item(nid)%data_steppos(i_next) = 1
773 do t = 1, extin_item(nid)%step_num
775 datasec = extin_item(nid)%time(t)
785 if ( extin_item(nid)%flag_periodic == i_periodic_day )
then 787 elseif( extin_item(nid)%flag_periodic == i_periodic_month )
then 789 elseif( extin_item(nid)%flag_periodic == i_periodic_year )
then 805 if ( extin_item(nid)%data_steppos(i_next) == extin_item(nid)%step_num+1 )
then 806 write(*,*)
'xxx Current time is out of period of external data! ' 817 if ( extin_item(nid)%fixed_step )
then 821 elseif( extin_item(nid)%data_steppos(i_next) == 1 )
then 824 datasec = extin_item(nid)%time( extin_item(nid)%data_steppos(i_prev) )
834 if ( extin_item(nid)%flag_periodic == i_periodic_day )
then 836 elseif( extin_item(nid)%flag_periodic == i_periodic_month )
then 838 elseif( extin_item(nid)%flag_periodic == i_periodic_year )
then 850 next_time = extin_item(nid)%time( extin_item(nid)%data_steppos(i_next) )
852 weight = ( current_time - prev_time ) &
853 / ( next_time - prev_time )
857 prev_time = extin_item(nid)%time( extin_item(nid)%data_steppos(i_prev) )
858 next_time = extin_item(nid)%time( extin_item(nid)%data_steppos(i_next) )
860 weight = ( current_time - prev_time ) &
861 / ( next_time - prev_time )
866 end subroutine extin_time_advance
integer, parameter, public i_month
[index] month
integer, parameter, public i_year
[index] year
subroutine, public prc_mpistop
Abort MPI.
real(dp) function, public calendar_combine_daysec(absday, abssec)
Combine day and second.
logical, public io_l
output log or not? (this process)
real(dp), public time_nowdaysec
second of current time [sec]
real(dp), public time_startdaysec
second of start time [sec]
integer, public ke
end point of inner domain: z, local
real(rp), public const_undef
subroutine, public calendar_adjust_daysec(absday, abssec)
Adjust day and second.
real(dp) function, public calendar_cfunits2sec(cftime, cfunits, offset_year, startdaysec)
Convert time in units of the CF convention to second.
integer, public time_offset_year
time offset [year]
integer, public kmax
of computational cells: z
integer, public ks
start point of inner domain: z, local
integer, public prc_myrank
process num in local communicator
integer, parameter, public i_day
[index] day
subroutine, public calendar_daysec2date(ymdhms, subsec, absday, abssec, offset_year)
Convert from gregorian date to absolute day/second.
integer, public io_fid_conf
Config file ID.
integer, public io_fid_log
Log file ID.
subroutine, public calendar_date2daysec(absday, abssec, ymdhms, subsec, offset_year)
Convert from gregorian date to absolute day/second.