42 real(RP),
private :: LAND_DYN_BUCKET_T_frz
44 logical,
private :: LAND_DYN_BUCKET_update_bottom_temp = .false.
45 logical,
private :: LAND_DYN_BUCKET_update_bottom_water = .false.
47 logical,
private :: LAND_DYN_BUCKET_nudging = .false.
48 real(DP),
private :: LAND_DYN_BUCKET_nudging_tau = 0.0_dp
49 character(len=H_SHORT),
private :: LAND_DYN_BUCKET_nudging_tau_unit =
"SEC"
50 character(len=H_LONG),
private :: LAND_DYN_BUCKET_nudging_basename =
''
51 logical,
private :: LAND_DYN_BUCKET_nudging_basename_add_num = .false.
52 integer,
private :: LAND_DYN_BUCKET_nudging_number_of_files = 1
53 logical,
private :: LAND_DYN_BUCKET_nudging_enable_periodic_year = .false.
54 logical,
private :: LAND_DYN_BUCKET_nudging_enable_periodic_month = .false.
55 logical,
private :: LAND_DYN_BUCKET_nudging_enable_periodic_day = .false.
56 integer,
private :: LAND_DYN_BUCKET_nudging_step_fixed = 0
57 real(RP),
private :: LAND_DYN_BUCKET_nudging_offset = 0.0_rp
58 real(RP),
private :: LAND_DYN_BUCKET_nudging_defval
59 logical,
private :: LAND_DYN_BUCKET_nudging_check_coordinates = .true.
60 integer,
private :: LAND_DYN_BUCKET_nudging_step_limit = 0
62 real(RP),
private :: WATER_DENSCS
63 real(RP),
private :: ICE_DENSCS
64 real(DP),
private :: LAND_DYN_BUCKET_nudging_tausec
66 logical,
private :: replace = .false.
89 namelist / param_land_dyn_bucket / &
90 land_dyn_bucket_t_frz, &
91 land_dyn_bucket_nudging, &
92 land_dyn_bucket_nudging_tau, &
93 land_dyn_bucket_nudging_tau_unit, &
94 land_dyn_bucket_nudging_basename, &
95 land_dyn_bucket_nudging_basename_add_num, &
96 land_dyn_bucket_nudging_number_of_files, &
97 land_dyn_bucket_nudging_enable_periodic_year, &
98 land_dyn_bucket_nudging_enable_periodic_month, &
99 land_dyn_bucket_nudging_enable_periodic_day, &
100 land_dyn_bucket_nudging_step_fixed, &
101 land_dyn_bucket_nudging_offset, &
102 land_dyn_bucket_nudging_defval, &
103 land_dyn_bucket_nudging_check_coordinates, &
104 land_dyn_bucket_nudging_step_limit, &
105 land_dyn_bucket_update_bottom_temp, &
106 land_dyn_bucket_update_bottom_water
112 log_info(
"LAND_DYN_BUCKET_setup",*)
'Setup'
114 land_dyn_bucket_nudging_defval = undef
115 land_dyn_bucket_t_frz = tem00
119 read(
io_fid_conf,nml=param_land_dyn_bucket,iostat=ierr)
121 log_info(
"LAND_DYN_BUCKET_setup",*)
'Not found namelist. Default used.'
122 elseif( ierr > 0 )
then
123 log_error(
"LAND_DYN_BUCKET_setup",*)
'Not appropriate names in namelist PARAM_LAND_DYN_BUCKET. Check!'
126 log_nml(param_land_dyn_bucket)
128 if ( land_dyn_bucket_nudging )
then
129 call calendar_unit2sec( land_dyn_bucket_nudging_tausec, land_dyn_bucket_nudging_tau, land_dyn_bucket_nudging_tau_unit )
131 log_info(
"LAND_DYN_BUCKET_setup",*)
'Use nudging for LAND physics : ON'
132 log_info(
"LAND_DYN_BUCKET_setup",*)
'Relaxation time Tau [sec] : ', land_dyn_bucket_nudging_tausec
134 if ( land_dyn_bucket_nudging_tausec <= 0.0_rp )
then
135 log_info(
"LAND_DYN_BUCKET_setup",*)
'Tau<=0 means that LST is completely replaced by the external data.'
139 if ( land_dyn_bucket_nudging_basename ==
'' )
then
140 log_error(
"LAND_DYN_BUCKET_setup",*)
'LAND_DYN_BUCKET_nudging_basename is necessary !!'
145 land_dyn_bucket_nudging_basename_add_num, &
146 land_dyn_bucket_nudging_number_of_files, &
149 land_dyn_bucket_nudging_enable_periodic_year, &
150 land_dyn_bucket_nudging_enable_periodic_month, &
151 land_dyn_bucket_nudging_enable_periodic_day, &
152 land_dyn_bucket_nudging_step_fixed, &
153 land_dyn_bucket_nudging_offset, &
154 land_dyn_bucket_nudging_defval, &
155 check_coordinates = land_dyn_bucket_nudging_check_coordinates, &
156 step_limit = land_dyn_bucket_nudging_step_limit, &
157 allow_missing = (.not. replace) )
160 land_dyn_bucket_nudging_basename_add_num, &
161 land_dyn_bucket_nudging_number_of_files, &
164 land_dyn_bucket_nudging_enable_periodic_year, &
165 land_dyn_bucket_nudging_enable_periodic_month, &
166 land_dyn_bucket_nudging_enable_periodic_day, &
167 land_dyn_bucket_nudging_step_fixed, &
168 land_dyn_bucket_nudging_offset, &
169 land_dyn_bucket_nudging_defval, &
170 check_coordinates = land_dyn_bucket_nudging_check_coordinates, &
171 step_limit = land_dyn_bucket_nudging_step_limit, &
172 allow_missing = (.not. replace) )
174 log_info(
"LAND_DYN_BUCKET_setup",*)
'Use nudging for Land physics: ON'
176 log_info(
"LAND_DYN_BUCKET_setup",*)
'Use nudging for Land physics: OFF'
180 ice_denscs = dice *
cv_ice
183 log_info(
"LAND_DYN_BUCKET_setup",*)
'Update soil temperature of bottom layer? : ', land_dyn_bucket_update_bottom_temp
184 log_info(
"LAND_DYN_BUCKET_setup",*)
'Update soil moisture of bottom layer? : ', land_dyn_bucket_update_bottom_water
192 LKMAX, LKS, LKE, LIA, LIS, LIE, LJA, LJS, LJE, &
193 TEMP_t, WATER_t, ICE_t, &
198 SFLX_GH, SFLX_water, &
203 RUNOFF, RUNOFF_ENGI )
212 file_external_input_update
214 matrix_solver_tridiagonal
220 integer,
intent(in) :: lkmax, lks, lke
221 integer,
intent(in) :: lia, lis, lie
222 integer,
intent(in) :: lja, ljs, lje
224 real(rp),
intent(in) :: temp_t (lkmax,lia,lja)
225 real(rp),
intent(in) :: water_t (lkmax,lia,lja)
226 real(rp),
intent(in) :: ice_t (lkmax,lia,lja)
227 real(rp),
intent(in) :: waterlimit (lia,lja)
228 real(rp),
intent(in) :: thermalcond (lia,lja)
229 real(rp),
intent(in) :: heatcapacity(lia,lja)
230 real(rp),
intent(in) :: waterdiff (lia,lja)
231 real(rp),
intent(in) :: sflx_gh (lia,lja)
232 real(rp),
intent(in) :: sflx_water (lia,lja)
233 real(rp),
intent(in) :: sflx_rhoe (lia,lja)
234 logical,
intent(in) :: exists_land (lia,lja)
235 real(rp),
intent(in) :: cdz (lkmax)
236 real(dp),
intent(in) :: dt
237 real(dp),
intent(in) :: nowdaysec
239 real(rp),
intent(inout) :: temp (lkmax,lia,lja)
240 real(rp),
intent(inout) :: water(lkmax,lia,lja)
241 real(rp),
intent(inout) :: ice (lkmax,lia,lja)
243 real(rp),
intent(out) :: runoff (lia,lja)
244 real(rp),
intent(out) :: runoff_engi(lia,lja)
248 real(rp) :: temp1 (lkmax,lia,lja)
249 real(rp) :: water1(lkmax,lia,lja)
250 real(rp) :: ice1 (lkmax,lia,lja)
252 real(rp) :: kappa (lkmax)
254 real(rp) :: u(lkmax,lia,lja)
255 real(rp) :: m(lkmax,lia,lja)
256 real(rp) :: l(lkmax,lia,lja)
257 real(rp) :: v(lkmax,lia,lja)
259 real(rp) :: ndg_temp (lkmax,lia,lja)
260 real(rp) :: ndg_water(lkmax,lia,lja)
262 real(rp) :: mass_total(lkmax)
263 real(rp) :: mass_water(lkmax)
264 real(rp) :: mass_ice(lkmax)
266 real(rp) :: engi(lkmax,lia,lja)
270 real(rp) :: flux(lks-1:lke)
272 real(rp) :: ro, rw, ri
278 log_progress(*)
'land / dynamics / bucket'
280 if ( land_dyn_bucket_nudging )
then
282 call file_external_input_update( &
288 log_error(
"LAND_DYN_BUCKET",*)
'Requested data is not found!'
292 call file_external_input_update( &
298 log_error(
"LAND_DYN_BUCKET",*)
'Requested data is not found!'
302 if ( .not. replace )
then
309 if ( temp1(k,i,j) == undef )
then
310 ndg_temp(k,i,j) = 0.0_rp
312 ndg_temp(k,i,j) = ( temp1(k,i,j) - temp(k,i,j) ) / land_dyn_bucket_nudging_tausec * dt
322 if ( water1(k,i,j) == undef )
then
323 ndg_water(k,i,j) = 0.0_rp
325 ndg_water(k,i,j) = ( water1(k,i,j) - ( water(k,i,j) + ice(k,i,j) ) ) / land_dyn_bucket_nudging_tausec * dt
333 if ( .not. land_dyn_bucket_update_bottom_water )
then
337 ndg_water(lke,i,j) = 0.0_rp
342 if ( .not. land_dyn_bucket_update_bottom_temp )
then
346 ndg_temp(lke,i,j) = 0.0_rp
358 ndg_temp(k,i,j) = 0.0_rp
359 ndg_water(k,i,j) = 0.0_rp
366 if ( .not. replace )
then
372 if ( exists_land(i,j) )
then
374 mass_total(k) = dwatr * water(k,i,j) + dice * ice(k,i,j)
376 mass_total(lks) = mass_total(lks) + dt * sflx_water(i,j) / cdz(lks)
378 cs = ( 1.0_rp - waterlimit(i,j) ) * heatcapacity(i,j)
380 engi(k,i,j) = ( cs + water_denscs * water(k,i,j) + ice_denscs * ice(k,i,j) ) * temp(k,i,j) -
lhf * dice * ice(k,i,j)
382 engi(lks,i,j) = engi(lks,i,j) + dt * ( sflx_gh(i,j) + sflx_rhoe(i,j) ) / cdz(lks)
386 mass_ice(k) = min( mass_total(k), max( 0.0_rp, &
387 ( engi(k,i,j) - ( cs +
cv_water * mass_total(k) ) * land_dyn_bucket_t_frz ) &
390 mass_water(k) = mass_total(k) - mass_ice(k)
391 v(k,i,j) = mass_water(k) / dwatr
392 ice1(k,i,j) = mass_ice(k) / dice
393 temp1(k,i,j) = ( engi(k,i,j) +
lhf * mass_ice(k) ) &
404 if ( exists_land(i,j) )
then
406 u(lks,i,j) = -2.0_rp * waterdiff(i,j) / ( cdz(lks) * ( cdz(lks) + cdz(lks+1) ) ) * dt
407 m(lks,i,j) = 1.0_rp - l(lks,i,j) - u(lks,i,j)
412 if ( land_dyn_bucket_update_bottom_water )
then
416 if ( exists_land(i,j) )
then
417 l(lke,i,j) = -2.0_rp * waterdiff(i,j) / ( cdz(lke) * ( cdz(lke) + cdz(lke-1) ) ) * dt
425 if ( exists_land(i,j) )
then
434 if ( exists_land(i,j) )
then
436 m(lke,i,j) = 1.0_rp - l(lke,i,j) - u(lke,i,j)
445 if ( exists_land(i,j) )
then
446 l(k,i,j) = -2.0_rp * waterdiff(i,j) / ( cdz(k) * ( cdz(k) + cdz(k-1) ) ) * dt
447 u(k,i,j) = -2.0_rp * waterdiff(i,j) / ( cdz(k) * ( cdz(k) + cdz(k+1) ) ) * dt
448 m(k,i,j) = 1.0_rp - l(k,i,j) - u(k,i,j)
454 call matrix_solver_tridiagonal( lkmax, 1, lkmax, &
457 u(:,:,:), m(:,:,:), l(:,:,:), &
460 mask = exists_land(:,:) )
472 if ( exists_land(i,j) )
then
474 cs = ( 1.0_rp - waterlimit(i,j) ) * heatcapacity(i,j)
476 kappa(k) = thermalcond(i,j) + 0.5_rp * water1(k,i,j)**(1.0_rp/3.0_rp)
480 flux(k) = - 2.0_rp * dwatr * waterdiff(i,j) * ( water1(k+1,i,j) - water1(k,i,j) ) / ( cdz(k+1) + cdz(k) )
481 sw = 0.5_rp - sign( 0.5_rp, flux(k) )
482 flux(k) = flux(k) *
cv_water * ( temp1(k+1,i,j) * sw + temp1(k,i,j) * ( 1.0_rp - sw ) )
484 if ( .not. land_dyn_bucket_update_bottom_temp )
then
485 flux(lke) = flux(lke-1)
489 v(k,i,j) = engi(k,i,j) +
lhf * dice * ice1(k,i,j) &
490 - dt * ( flux(k) - flux(k-1) ) / cdz(k)
493 cl = cs + water_denscs * water1(lks,i,j) + ice_denscs * ice1(lks,i,j)
495 u(lks,i,j) = - ( kappa(lks) + kappa(lks+1) ) / ( cdz(lks) * ( cdz(lks) + cdz(lks+1) ) ) * dt
496 m(lks,i,j) = cl - l(lks,i,j) - u(lks,i,j)
498 cl = cs + water_denscs * water1(lke,i,j) + ice_denscs * ice1(lke,i,j)
499 if ( land_dyn_bucket_update_bottom_water )
then
501 l(lke,i,j) = - ( kappa(lke) + kappa(lke-1) ) / ( cdz(lke) * ( cdz(lke) + cdz(lke-1) ) ) * dt
506 m(lke,i,j) = cl - l(lke,i,j) - u(lke,i,j)
509 cl = cs + water_denscs * water1(k,i,j) + ice_denscs * ice1(k,i,j)
510 l(k,i,j) = - ( kappa(k) + kappa(k-1) ) / ( cdz(k) * ( cdz(k) + cdz(k-1) ) ) * dt
511 u(k,i,j) = - ( kappa(k) + kappa(k+1) ) / ( cdz(k) * ( cdz(k) + cdz(k+1) ) ) * dt
512 m(k,i,j) = cl - l(k,i,j) - u(k,i,j)
519 call matrix_solver_tridiagonal( lkmax, 1, lkmax, &
522 u(:,:,:), m(:,:,:), l(:,:,:), &
525 mask = exists_land(:,:) )
531 if ( exists_land(i,j) )
then
533 temp1(k,i,j) = temp1(k,i,j) + ndg_temp(k,i,j)
544 if ( exists_land(i,j) )
then
546 if ( temp1(k,i,j) >= land_dyn_bucket_t_frz )
then
547 water1(k,i,j) = water1(k,i,j) + ndg_water(k,i,j)
549 ice1(k,i,j) = ice1(k,i,j) + ndg_water(k,i,j)
555 runoff_engi(i,j) = 0.0_rp
557 ro = max( water1(k,i,j) + ice1(k,i,j) - waterlimit(i,j), 0.0_rp )
558 rw = min( ro, water1(k,i,j) )
560 water1(k,i,j) = water1(k,i,j) - rw
561 ice1(k,i,j) = ice1(k,i,j) - ri
564 runoff(i,j) = runoff(i,j) + ( rw + ri ) * cdz(k)
565 runoff_engi(i,j) = runoff_engi(i,j) &
573 if ( .not. land_dyn_bucket_update_bottom_water )
then
577 if ( exists_land(i,j) )
then
578 water1(lke,i,j) = water(lke,i,j)
579 ice1(lke,i,j) = ice(lke,i,j)
585 if ( .not. land_dyn_bucket_update_bottom_temp )
then
589 if ( exists_land(i,j) )
then
590 temp1(lke,i,j) = temp(lke,i,j)
602 if( exists_land(i,j) )
then
604 temp(k,i,j) = temp1(k,i,j)
605 water(k,i,j) = water1(k,i,j)
606 ice(k,i,j) = ice1(k,i,j)