35 lensfc,lsoil,idim,jdim, myrank)
40 stc_inc_gaus, soilsnow_gaus
45 integer,
intent(in) :: lensfc, lsoil, idim, jdim, myrank
47 integer,
intent(in) :: soilsnow_tile(lensfc), soilsnow_fg_tile(lensfc)
48 real,
intent(inout) :: rla(lensfc), rlo(lensfc)
49 real,
intent(inout) :: stc_state(lensfc, lsoil)
51 integer :: iopt, nret, kgds_gaus(200)
52 integer :: igaus, jgaus, ij
53 integer :: mask_tile, mask_fg_tile
54 integer :: itile, jtile
56 integer :: igausp1, jgausp1
59 integer,
allocatable :: id1(:,:), id2(:,:), jdc(:,:)
62 real :: stc_inc(lsoil)
63 real,
allocatable :: xpts(:), ypts(:), lats(:), lons(:)
64 real,
allocatable :: dum2d(:,:), lats_rad(:), lons_rad(:)
65 real,
allocatable :: agrid(:,:,:), s2c(:,:,:)
67 integer :: k, nother, nsnowupd, nnosoilnear, nsoilupd, nsnowchange
68 logical :: gaus_has_soil
70 integer,
parameter :: lsoil_incr=3
76 kgds_gaus(2) = idim_gaus
77 kgds_gaus(3) = jdim_gaus
82 kgds_gaus(8) = nint(-360000./float(idim_gaus))
83 kgds_gaus(9) = nint((360.0 / float(idim_gaus))*1000.0)
85 kgds_gaus(10) = jdim_gaus/2
90 print*,
'adjust soil temperature using gsi increments on gaussian grid'
91 print*,
'adjusting first ', lsoil_incr,
' surface layers only'
99 allocate(xpts(idim_gaus*jdim_gaus))
100 allocate(ypts(idim_gaus*jdim_gaus))
101 allocate(lats(idim_gaus*jdim_gaus))
102 allocate(lons(idim_gaus*jdim_gaus))
108 call gdswzd(kgds_gaus,iopt,(idim_gaus*jdim_gaus),fill,xpts,ypts,lons,lats,nret)
110 if (nret /= (idim_gaus*jdim_gaus))
then
111 print*,
'fatal error: problem in gdswzd. stop.'
112 call mpi_abort(mpi_comm_world, 12, ierr)
115 deallocate (xpts, ypts)
117 allocate(dum2d(idim_gaus,jdim_gaus))
118 dum2d = reshape(lats, (/idim_gaus,jdim_gaus/) )
121 allocate(lats_rad(jdim_gaus))
124 lats_rad(j) = dum2d(1,jdim_gaus-j+1) * 3.1415926 / 180.0
127 dum2d = reshape(lons, (/idim_gaus,jdim_gaus/) )
129 allocate(lons_rad(idim_gaus))
130 lons_rad = dum2d(:,1) * 3.1415926 / 180.0
134 allocate(agrid(idim,jdim,2))
135 agrid(:,:,1) = reshape(rlo, (/idim,jdim/) )
136 agrid(:,:,2) = reshape(rla, (/idim,jdim/) )
137 agrid = agrid * 3.1415926 / 180.0
139 allocate(id1(idim,jdim))
140 allocate(id2(idim,jdim))
141 allocate(jdc(idim,jdim))
142 allocate(s2c(idim,jdim,4))
150 call
remap_coef( 1, idim, 1, jdim, idim_gaus, jdim_gaus, &
151 lons_rad, lats_rad, id1, id2, jdc, s2c, agrid )
153 deallocate(lons_rad, lats_rad, agrid)
167 ij_loop :
do ij = 1, lensfc
174 mask_tile = soilsnow_tile(ij)
175 mask_fg_tile = soilsnow_fg_tile(ij)
181 if (mask_tile == 0)
then
189 jtile = (ij-1) / idim + 1
191 if (itile==0) itile = idim
198 if ((mask_fg_tile == 2 .and. mask_tile == 1) .or. &
199 (mask_fg_tile == 1 .and. mask_tile == 2) )
then
200 nsnowchange = nsnowchange + 1
208 if (mask_tile == 1)
then
210 igaus = id1(itile,jtile)
211 jgaus = jdc(itile,jtile)
212 igausp1 = id2(itile,jtile)
213 jgausp1 = jdc(itile,jtile)+1
216 gaus_has_soil = .false.
217 if (soilsnow_gaus(igaus,jgaus) == 1 .or. &
218 soilsnow_gaus(igausp1,jgaus) == 1 .or. &
219 soilsnow_gaus(igausp1,jgausp1) == 1 .or. &
220 soilsnow_gaus(igaus,jgausp1) == 1) gaus_has_soil = .true.
222 if (.not. gaus_has_soil)
then
223 nnosoilnear = nnosoilnear + 1
233 nsoilupd = nsoilupd + 1
238 if (soilsnow_gaus(igaus,jgaus) == 1)
then
240 stc_inc(k) = stc_inc(k) + (s2c(itile,jtile,1) * stc_inc_gaus(k,igaus,jgaus))
242 wsum = wsum + s2c(itile,jtile,1)
245 if (soilsnow_gaus(igausp1,jgaus) == 1)
then
247 stc_inc(k) = stc_inc(k) + (s2c(itile,jtile,2) * stc_inc_gaus(k,igausp1,jgaus))
249 wsum = wsum + s2c(itile,jtile,2)
252 if (soilsnow_gaus(igausp1,jgausp1) == 1)
then
254 stc_inc(k) = stc_inc(k) + (s2c(itile,jtile,3) * stc_inc_gaus(k,igausp1,jgausp1))
256 wsum = wsum + s2c(itile,jtile,3)
259 if (soilsnow_gaus(igaus,jgausp1) == 1)
then
261 stc_inc(k) = stc_inc(k) + (s2c(itile,jtile,4) * stc_inc_gaus(k,igaus,jgausp1))
263 wsum = wsum + s2c(itile,jtile,4)
268 stc_inc(k) = stc_inc(k) / wsum
269 stc_state(ij,k) = stc_state(ij,k) + stc_inc(k)
273 elseif(mask_tile==2)
then
275 nsnowupd = nsnowupd + 1
281 write(*,
'(a,i2)')
'statistics of grids number processed for rank : ', myrank
282 write(*,
'(a,i8)')
' soil grid cells updated = ',nsoilupd
283 write(*,
'(a,i8)')
' (not updated) soil grid cells, no soil nearby on gsi grid = ',nnosoilnear
284 write(*,
'(a,i8)')
' (not updated) soil grid cells, change in presence of snow = ', nsnowchange
285 write(*,
'(a,i8)')
' (not updated yet) snow grid cells = ', nsnowupd
286 write(*,
'(a,i8)')
' grid cells, without soil of snow = ', nother
294 deallocate(id1, id2, jdc, s2c)
309 integer,
intent(in) :: lensfc
310 real,
intent(in) :: smc(lensfc), swe(lensfc)
311 integer,
intent(out) :: mask(lensfc)
317 if (smc(i) .LT. 1.0)
then
323 if (swe(i) .GT. 0.001)
then
353 lsoil, rsoiltype, smc_bck, slc_bck,stc_bck, smc_anl, slc_anl, stc_anl)
356 use set_soilveg_snippet_mod
, only: set_soilveg
357 use sflx_snippet
, only: frh2o
361 character(len=3),
intent(in) :: update_type
362 integer,
intent(in) :: lsm, lensfc, lsoil, isot, ivegsrc
363 real,
intent(in) :: rsoiltype(lensfc)
364 real,
intent(in) :: smc_bck(lensfc,lsoil), slc_bck(lensfc,lsoil)
365 real,
intent(in) :: stc_bck(lensfc, lsoil)
366 real,
intent(inout) :: smc_anl(lensfc,lsoil), slc_anl(lensfc,lsoil)
367 real,
intent(inout) :: stc_anl(lensfc, lsoil)
369 logical :: frzn_bck, frzn_anl
371 integer :: i, l, n_freeze, n_thaw, ierr
372 integer :: myrank, soiltype, iret
376 integer,
parameter :: lsm_noah=1
378 real,
parameter ::
tfreez=273.16
379 real,
dimension(30) :: maxsmc, bb, satpsi
381 call mpi_comm_rank(mpi_comm_world, myrank, ierr)
383 if (lsm .NE. lsm_noah)
then
384 print *,
'FATAL ERROR: apply_land_da_adjustments not coded for models other than noah', lsm
385 call mpi_abort(mpi_comm_world, 10, ierr)
389 call set_soilveg(isot, ivegsrc, maxsmc, bb, satpsi, iret)
391 print *,
'FATAL ERROR: problem in set_soilveg'
392 call mpi_abort(mpi_comm_world, 10, ierr)
395 select case (update_type)
398 print *,
'Adjusting smc after stc DA update'
405 if (smc_bck(i,l) < 1.0)
then
406 frzn_bck = (stc_bck(i,l) .LT.
tfreez )
407 frzn_anl = (stc_anl(i,l) .LT.
tfreez )
409 if (frzn_bck .eqv. frzn_anl)
then
411 elseif (frzn_bck .and. .not. frzn_anl)
then
414 n_freeze = n_freeze + 1
418 soiltype = nint(rsoiltype(i))
420 call frh2o(stc_anl(i,l), smc_anl(i,l),slc_anl(i,l), maxsmc(soiltype), &
421 bb(soiltype), satpsi(soiltype),slc_new)
423 slc_anl(i,l) = max( min( slc_new, smc_anl(i,l)), 0.0 )
428 print *,
'adjusted: ', n_thaw,
' thawed,', n_freeze,
' frozen'
431 print *,
'FATAL ERROR: apply_land_da_adjustments not code for variable', lsm
432 call mpi_abort(mpi_comm_world, 10, ierr)
subroutine, public calculate_soilsnowmask(smc, swe, lensfc, mask)
Calculate soil mask for land on model grid.
subroutine, public add_increment_soil(rla, rlo, stc_state, soilsnow_tile, soilsnow_fg_tile, lensfc, lsoil, idim, jdim, myrank)
Read in gsi file with soil state increments (on the gaussian grid), interpolate increments to the cub...
subroutine, public apply_land_da_adjustments(update_type, lsm, isot, ivegsrc, lensfc, lsoil, rsoiltype, smc_bck, slc_bck, stc_bck, smc_anl, slc_anl, stc_anl)
Make adjustments to dependent variables after applying land increments.
subroutine, public remap_coef(is, ie, js, je, im, jm, lon, lat, id1, id2, jdc, s2c, agrid)
Generate the weights and index of the grids used in the bilinear interpolation.
real function tfreez(salinity)
Compute the freezing point of water as a function of salinity.
This module contains routines that read and write data.
Module containing utility routines.