chgres_cube  1.4.0
 All Data Structures Files Functions Variables
search_util.F90
Go to the documentation of this file.
1 
4 
15  module search_util
16 
17  private
18 
19  public :: search
20 
21  contains
22 
46  subroutine search (field, mask, idim, jdim, tile, field_num, latitude, terrain_land, soilt_climo)
47 
48  use mpi
49  use esmf
50 
51  implicit none
52 
53 
54  integer, intent(in) :: idim, jdim, tile, field_num
55  integer(esmf_kind_i8), intent(in) :: mask(idim,jdim)
56 
57  real(esmf_kind_r8), intent(in), optional :: latitude(idim,jdim)
58  real(esmf_kind_r8), intent(in), optional :: terrain_land(idim,jdim)
59  real(esmf_kind_r8), intent(in), optional :: soilt_climo(idim,jdim)
60 
61  real(esmf_kind_r8), intent(inout) :: field(idim,jdim)
62 
63  integer :: i, j, krad, ii, jj
64  integer :: istart, iend
65  integer :: jstart, jend
66  integer :: ierr
67 
68  real :: default_value
69  real(esmf_kind_r8) :: field_save(idim,jdim)
70  integer :: repl_nearby, repl_default
71 
72 !-----------------------------------------------------------------------
73 ! Set default value.
74 !-----------------------------------------------------------------------
75 
76  select case (field_num)
77  case (0) ! most nst fields
78  default_value = 0.0
79  case (1) ! ifd
80  default_value = 1.0
81  case (7) ! terrain height, flag value to turn off terrain adjustment
82  ! of soil temperatures.
83  default_value = -99999.9
84  case (11) ! water temperature will use latitude-dependent value
85  default_value = -999.0
86  case (21) ! ice temperature
87  default_value = 265.0
88  case (30) ! xz
89  default_value = 30.0
90  case (65) ! snow liq equivalent
91  default_value = 0.0
92  case (66) ! snow depth
93  default_value = 0.0
94  case (83) ! z0 (cm)
95  default_value = 0.01
96  case (85) ! soil temp
97  default_value = 280.0
98  case (86) ! soil moisture (volumetric)
99  default_value = 0.18
100  case (91) ! sea ice fraction
101  default_value = 0.5
102  case (92) ! sea ice depth (meters)
103  default_value = 1.0
104  case (223) ! canopy moist
105  default_value = 0.0
106  case (224) ! soil type, flag value to turn off soil moisture rescaling.
107  default_value = -99999.9
108  case (225) ! vegetation type, flag value to be replaced
109  default_value = -99999.9
110  case (226) ! vegetation fraction, flag value to be replaced
111  default_value = 0.5
112  case (227) ! max vegetation fraction, flag value to be replaced
113  default_value = 0.5
114  case (228) ! min vegetation fraction, flag value to be replaced
115  default_value = 0.5
116  case (229) ! lai, flag value to be replaced
117  default_value = 1.0
118  case (230) ! soil type on the input grid
119  default_value = 11.0
120  case default
121  print*,'- FATAL ERROR. UNIDENTIFIED FIELD NUMBER : ', field_num
122  call mpi_abort(mpi_comm_world, 77, ierr)
123  end select
124 
125 !-----------------------------------------------------------------------
126 ! Perform search and replace.
127 !-----------------------------------------------------------------------
128 
129  field_save = field
130  repl_nearby = 0
131  repl_default = 0
132 !$OMP PARALLEL DO DEFAULT(NONE), &
133 !$OMP SHARED(IDIM,JDIM,MASK,FIELD_SAVE,FIELD,TILE,LATITUDE,DEFAULT_VALUE,FIELD_NUM,REPL_NEARBY,REPL_DEFAULT,SOILT_CLIMO,TERRAIN_LAND), &
134 !$OMP PRIVATE(I,J,KRAD,ISTART,IEND,JSTART,JEND,II,JJ)
135 
136  j_loop : do j = 1, jdim
137  i_loop : do i = 1, idim
138 
139  if (mask(i,j) == 1 .and. field_save(i,j) < -9999.0) then
140 
141  krad_loop : do krad = 1, 100
142 
143  istart = i - krad
144  iend = i + krad
145  jstart = j - krad
146  jend = j + krad
147 
148  jj_loop : do jj = jstart, jend
149  ii_loop : do ii = istart, iend
150 
151 !-----------------------------------------------------------------------
152 ! Search only along outer square.
153 !-----------------------------------------------------------------------
154 
155  if ((jj == jstart) .or. (jj == jend) .or. &
156  (ii == istart) .or. (ii == iend)) then
157 
158  if (jj < 1 .or. jj > jdim) cycle jj_loop
159  if (ii < 1 .or. ii > idim) cycle ii_loop
160 
161  if (mask(ii,jj) == 1 .and. field_save(ii,jj) > -9999.0) then
162  field(i,j) = field_save(ii,jj)
163  ! write(6,100) field_num,tile,i,j,ii,jj,field(i,j)
164  ! When using non-GFS data, there are a lot of these print statements even
165  ! when everything is working correctly. Count instead of printing each
166  repl_nearby = repl_nearby + 1
167  cycle i_loop
168  endif
169 
170  endif
171 
172  enddo ii_loop
173  enddo jj_loop
174 
175  enddo krad_loop
176 
177  if (field_num == 11) then
178  call sst_guess(latitude(i,j), field(i,j))
179  elseif (field_num == 91) then ! sea ice fract
180  if (abs(latitude(i,j)) > 55.0) then
181  field(i,j) = default_value
182  repl_default = repl_default + 1
183  else
184  field(i,j) = 0.0
185  repl_default = repl_default + 1
186  endif
187  elseif (field_num == 7 .and. present(terrain_land)) then
188  ! Terrain heights for isolated landice points never get a correct value, so replace
189  ! with terrain height from the input grid interpolated to the target grid
190  field(i,j) = terrain_land(i,j)
191  repl_default = repl_default + 1
192  elseif (field_num == 224 .and. present(soilt_climo)) then
193  ! When using input soil type fields instead of climatological data on the
194  ! target grid, isolated land locations that exist in the target grid but
195  ! not the input grid don't receiving proper soil type information, so replace
196  ! with climatological values
197  field(i,j) = soilt_climo(i,j)
198  repl_default = repl_default + 1
199  else
200  field(i,j) = default_value
201  repl_default = repl_default + 1
202  endif
203 
204  !write(6,101) field_num,tile,i,j,field(i,j)
205 
206  endif
207  enddo i_loop
208  enddo j_loop
209 !$OMP END PARALLEL DO
210 
211 ! 100 format(1x,"- MISSING POINT FIELD ",i4," TILE: ",i2," I/J: ",i5,i5," SET TO VALUE AT: ",i5,i5,". NEW VALUE IS: ",f8.3)
212 ! 101 format(1x,"- MISSING POINT FIELD ",i4," TILE: ",i2," I/J: ",i5,i5," SET TO DEFAULT VALUE OF: ",f8.3)
213  print*, "- TOTAL POINTS FOR VAR ", field_num, " REPLACED BY NEARBY VALUES: ", repl_nearby
214  print*, "- TOTAL POINTS FOR VAR ", field_num, " REPLACED BY DEFAULT VALUE: ", repl_default
215 
216  end subroutine search
217 
232  subroutine sst_guess(latitude, sst)
233 
234  use esmf
235 
236  implicit none
237 
238  real(esmf_kind_r8), parameter :: sst_polar_in_kelvin = 273.16
240  real(esmf_kind_r8), parameter :: sst_tropical_in_kelvin = 300.0
242  real(esmf_kind_r8), parameter :: polar_latitude = 60.0
244  real(esmf_kind_r8), parameter :: tropical_latitude = 30.0
246  real(esmf_kind_r8), parameter :: dsst_dlat = -0.8947
248  real(esmf_kind_r8), parameter :: sst_y_intercept = 326.84
250 
251  real(esmf_kind_r8), intent(in) :: latitude
252 
253  real(esmf_kind_r8), intent(out) :: sst
254 
255  if (abs(latitude) >= polar_latitude) then
256  sst = sst_polar_in_kelvin
257  elseif (abs(latitude) <= tropical_latitude) then
258  sst = sst_tropical_in_kelvin
259  else
260  sst = dsst_dlat * abs(latitude) + sst_y_intercept
261  endif
262 
263  end subroutine sst_guess
264 
265  end module search_util
subroutine sst_guess(latitude, sst)
Set default Sea Surface Temperature (SST) based on latitude.
Replace undefined values with a valid value.
Definition: search_util.F90:15
subroutine, public search(field, mask, idim, jdim, tile, field_num, latitude, terrain_land, soilt_climo)
Replace undefined surface values.
Definition: search_util.F90:46