9 public add_increment_soil
10 public add_increment_snow
11 public calculate_landinc_mask
12 public apply_land_da_adjustments_stc
13 public apply_land_da_adjustments_snd
15 integer,
parameter :: lsm_noah=1
43 subroutine add_increment_soil(rla,rlo,stc_state,soilsnow_tile, soilsnow_fg_tile, &
44 lensfc,lsoil,idim,jdim, myrank)
48 use read_write_data,
only : idim_gaus, jdim_gaus, &
49 stc_inc_gaus, soilsnow_gaus
54 integer,
intent(in) :: lensfc, lsoil, idim, jdim, myrank
56 integer,
intent(in) :: soilsnow_tile(lensfc), soilsnow_fg_tile(lensfc)
57 real,
intent(inout) :: rla(lensfc), rlo(lensfc)
58 real,
intent(inout) :: stc_state(lensfc, lsoil)
60 integer :: iopt, nret, kgds_gaus(200)
61 integer :: igaus, jgaus, ij
62 integer :: mask_tile, mask_fg_tile
63 integer :: itile, jtile
65 integer :: igausp1, jgausp1
68 integer,
allocatable :: id1(:,:), id2(:,:), jdc(:,:)
71 real :: stc_inc(lsoil)
72 real,
allocatable :: xpts(:), ypts(:), lats(:), lons(:)
73 real,
allocatable :: dum2d(:,:), lats_rad(:), lons_rad(:)
74 real,
allocatable :: agrid(:,:,:), s2c(:,:,:)
76 integer :: k, nother, nsnowupd, nnosoilnear, nsoilupd, nsnowchange
77 logical :: gaus_has_soil
79 integer,
parameter :: lsoil_incr=3
85 kgds_gaus(2) = idim_gaus
86 kgds_gaus(3) = jdim_gaus
91 kgds_gaus(8) = nint(-360000./float(idim_gaus))
92 kgds_gaus(9) = nint((360.0 / float(idim_gaus))*1000.0)
94 kgds_gaus(10) = jdim_gaus/2
99 print*,
'adjust soil temperature using gsi increments on gaussian grid' 100 print*,
'adjusting first ', lsoil_incr,
' surface layers only' 108 allocate(xpts(idim_gaus*jdim_gaus))
109 allocate(ypts(idim_gaus*jdim_gaus))
110 allocate(lats(idim_gaus*jdim_gaus))
111 allocate(lons(idim_gaus*jdim_gaus))
117 call gdswzd(kgds_gaus,iopt,(idim_gaus*jdim_gaus),fill,xpts,ypts,lons,lats,nret)
119 if (nret /= (idim_gaus*jdim_gaus))
then 120 print*,
'fatal error: problem in gdswzd. stop.' 121 call mpi_abort(mpi_comm_world, 12, ierr)
124 deallocate (xpts, ypts)
126 allocate(dum2d(idim_gaus,jdim_gaus))
127 dum2d = reshape(lats, (/idim_gaus,jdim_gaus/) )
130 allocate(lats_rad(jdim_gaus))
133 lats_rad(j) = dum2d(1,jdim_gaus-j+1) * 3.1415926 / 180.0
136 dum2d = reshape(lons, (/idim_gaus,jdim_gaus/) )
138 allocate(lons_rad(idim_gaus))
139 lons_rad = dum2d(:,1) * 3.1415926 / 180.0
143 allocate(agrid(idim,jdim,2))
144 agrid(:,:,1) = reshape(rlo, (/idim,jdim/) )
145 agrid(:,:,2) = reshape(rla, (/idim,jdim/) )
146 agrid = agrid * 3.1415926 / 180.0
148 allocate(id1(idim,jdim))
149 allocate(id2(idim,jdim))
150 allocate(jdc(idim,jdim))
151 allocate(s2c(idim,jdim,4))
159 call remap_coef( 1, idim, 1, jdim, idim_gaus, jdim_gaus, &
160 lons_rad, lats_rad, id1, id2, jdc, s2c, agrid )
162 deallocate(lons_rad, lats_rad, agrid)
176 ij_loop :
do ij = 1, lensfc
178 mask_tile = soilsnow_tile(ij)
179 mask_fg_tile = soilsnow_fg_tile(ij)
185 if (mask_tile <= 0)
then 193 jtile = (ij-1) / idim + 1
195 if (itile==0) itile = idim
202 if ((mask_fg_tile == 2 .and. mask_tile == 1) .or. &
203 (mask_fg_tile == 1 .and. mask_tile == 2) )
then 204 nsnowchange = nsnowchange + 1
212 if (mask_tile == 1)
then 214 igaus = id1(itile,jtile)
215 jgaus = jdc(itile,jtile)
216 igausp1 = id2(itile,jtile)
217 jgausp1 = jdc(itile,jtile)+1
220 gaus_has_soil = .false.
221 if (soilsnow_gaus(igaus,jgaus) == 1 .or. &
222 soilsnow_gaus(igausp1,jgaus) == 1 .or. &
223 soilsnow_gaus(igausp1,jgausp1) == 1 .or. &
224 soilsnow_gaus(igaus,jgausp1) == 1) gaus_has_soil = .true.
226 if (.not. gaus_has_soil)
then 227 nnosoilnear = nnosoilnear + 1
237 nsoilupd = nsoilupd + 1
242 if (soilsnow_gaus(igaus,jgaus) == 1)
then 244 stc_inc(k) = stc_inc(k) + (s2c(itile,jtile,1) * stc_inc_gaus(k,igaus,jgaus))
246 wsum = wsum + s2c(itile,jtile,1)
249 if (soilsnow_gaus(igausp1,jgaus) == 1)
then 251 stc_inc(k) = stc_inc(k) + (s2c(itile,jtile,2) * stc_inc_gaus(k,igausp1,jgaus))
253 wsum = wsum + s2c(itile,jtile,2)
256 if (soilsnow_gaus(igausp1,jgausp1) == 1)
then 258 stc_inc(k) = stc_inc(k) + (s2c(itile,jtile,3) * stc_inc_gaus(k,igausp1,jgausp1))
260 wsum = wsum + s2c(itile,jtile,3)
263 if (soilsnow_gaus(igaus,jgausp1) == 1)
then 265 stc_inc(k) = stc_inc(k) + (s2c(itile,jtile,4) * stc_inc_gaus(k,igaus,jgausp1))
267 wsum = wsum + s2c(itile,jtile,4)
272 stc_inc(k) = stc_inc(k) / wsum
273 stc_state(ij,k) = stc_state(ij,k) + stc_inc(k)
278 elseif(mask_tile==2)
then 279 nsnowupd = nsnowupd + 1
285 write(*,
'(a,i2)')
'statistics of grids number processed for rank : ', myrank
286 write(*,
'(a,i8)')
' soil grid cells updated = ',nsoilupd
287 write(*,
'(a,i8)')
' (not updated) soil grid cells, no soil nearby on gsi grid = ',nnosoilnear
288 write(*,
'(a,i8)')
' (not updated) soil grid cells, change in presence of snow = ', nsnowchange
289 write(*,
'(a,i8)')
' (not updated yet) snow grid cells = ', nsnowupd
290 write(*,
'(a,i8)')
' grid cells, without soil or snow = ', nother
298 deallocate(id1, id2, jdc, s2c)
300 end subroutine add_increment_soil
314 subroutine add_increment_snow(snd_inc,mask,lensfc,snd)
318 integer,
intent(in) :: lensfc
319 real,
intent(in) :: snd_inc(lensfc)
320 integer,
intent(in) :: mask(lensfc)
321 real,
intent(inout) :: snd(lensfc)
327 if (mask(i) > 0)
then 328 snd(i) = max( snd(i) + snd_inc(i), 0.)
332 end subroutine add_increment_snow
344 subroutine calculate_landinc_mask(smc,swe,vtype,lensfc,veg_type_landice,mask)
348 integer,
intent(in) :: lensfc, veg_type_landice
349 real,
intent(in) :: smc(lensfc), swe(lensfc)
350 real,
intent(in) :: vtype(lensfc)
351 integer,
intent(out) :: mask(lensfc)
359 if (smc(i) .LT. 1.0)
then 360 if (swe(i) .GT. 0.001)
then 366 if ( nint(vtype(i)) == veg_type_landice )
then 371 end subroutine calculate_landinc_mask
394 subroutine apply_land_da_adjustments_stc(lsm, isot, ivegsrc,lensfc, &
395 lsoil, rsoiltype, mask, stc_bck, stc_anl, smc_adj, slc_adj )
398 use set_soilveg_snippet_mod,
only: set_soilveg
399 use sflx_snippet,
only: frh2o
403 integer,
intent(in) :: lsm, lensfc, lsoil, isot, ivegsrc
404 real,
intent(in) :: rsoiltype(lensfc)
405 integer,
intent(in) :: mask(lensfc)
406 real,
intent(in) :: stc_bck(lensfc, lsoil) , stc_anl(lensfc, lsoil)
407 real,
intent(inout) :: smc_adj(lensfc,lsoil), slc_adj(lensfc,lsoil)
410 logical :: frzn_bck, frzn_anl
412 integer :: i, l, n_freeze, n_thaw, ierr
413 integer :: myrank, soiltype, iret
417 real,
parameter ::
tfreez=273.16
418 real,
dimension(30) :: maxsmc, bb, satpsi
420 call mpi_comm_rank(mpi_comm_world, myrank, ierr)
422 if (lsm .NE. lsm_noah)
then 423 print *,
'FATAL ERROR: apply_land_da_adjustments not coded for models other than noah', lsm
424 call mpi_abort(mpi_comm_world, 10, ierr)
428 call set_soilveg(isot, ivegsrc, maxsmc, bb, satpsi, iret)
430 print *,
'FATAL ERROR: problem in set_soilveg' 431 call mpi_abort(mpi_comm_world, 10, ierr)
434 print *,
'Adjusting smc after stc DA update' 440 if (mask(i) > 0)
then 442 frzn_bck = (stc_bck(i,l) .LT.
tfreez )
443 frzn_anl = (stc_anl(i,l) .LT.
tfreez )
445 if (frzn_bck .eqv. frzn_anl)
then 447 elseif (frzn_bck .and. .not. frzn_anl)
then 450 n_freeze = n_freeze + 1
454 soiltype = nint(rsoiltype(i))
456 call frh2o(stc_anl(i,l), smc_adj(i,l),slc_adj(i,l), maxsmc(soiltype), &
457 bb(soiltype), satpsi(soiltype),slc_new)
459 slc_adj(i,l) = max( min( slc_new, smc_adj(i,l)), 0.0 )
463 print *,
'adjusted: ', n_thaw,
' thawed,', n_freeze,
' frozen' 465 end subroutine apply_land_da_adjustments_stc
482 subroutine apply_land_da_adjustments_snd(lsm, lensfc, mask, swe_bck, snd_bck, snd_anl, swe_adj)
485 use bulk_snow_module,
only: calc_density
489 integer,
intent(in) :: lsm, lensfc
490 integer,
intent(in) :: mask(lensfc)
491 real,
intent(in) :: swe_bck(lensfc), snd_bck(lensfc)
492 real,
intent(in) :: snd_anl(lensfc)
493 real,
intent(inout) :: swe_adj(lensfc)
495 integer :: ierr, myrank, i
497 real :: density(lensfc)
499 call mpi_comm_rank(mpi_comm_world, myrank, ierr)
501 if (lsm .NE. lsm_noah)
then 502 print *,
'FATAL ERROR: apply_land_da_adjustments not coded for models other than noah', lsm
503 call mpi_abort(mpi_comm_world, 10, ierr)
507 call calc_density(lensfc, mask, swe_bck, snd_bck, myrank, density)
510 if ( mask(i)>0 )
then 511 swe_adj(i) = snd_anl(i)*density(i)
516 end subroutine apply_land_da_adjustments_snd
518 end module land_increments
Module containing utility routines.
real function tfreez(salinity)
Compute the freezing point of water as a function of salinity.