chgres_cube  1.7.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 (231) ! soil type at land ice points
121  default_value = 16.0
122  case default
123  print*,'- FATAL ERROR. UNIDENTIFIED FIELD NUMBER : ', field_num
124  call mpi_abort(mpi_comm_world, 77, ierr)
125  end select
126 
127 !-----------------------------------------------------------------------
128 ! Perform search and replace.
129 !-----------------------------------------------------------------------
130 
131  field_save = field
132  repl_nearby = 0
133  repl_default = 0
134 !$OMP PARALLEL DO DEFAULT(NONE), &
135 !$OMP SHARED(IDIM,JDIM,MASK,FIELD_SAVE,FIELD,TILE,LATITUDE,DEFAULT_VALUE,FIELD_NUM,REPL_NEARBY,REPL_DEFAULT,SOILT_CLIMO,TERRAIN_LAND), &
136 !$OMP PRIVATE(I,J,KRAD,ISTART,IEND,JSTART,JEND,II,JJ)
137 
138  j_loop : do j = 1, jdim
139  i_loop : do i = 1, idim
140 
141  if (mask(i,j) == 1 .and. field_save(i,j) < -9999.0) then
142 
143  krad_loop : do krad = 1, 100
144 
145  istart = i - krad
146  iend = i + krad
147  jstart = j - krad
148  jend = j + krad
149 
150  jj_loop : do jj = jstart, jend
151  ii_loop : do ii = istart, iend
152 
153 !-----------------------------------------------------------------------
154 ! Search only along outer square.
155 !-----------------------------------------------------------------------
156 
157  if ((jj == jstart) .or. (jj == jend) .or. &
158  (ii == istart) .or. (ii == iend)) then
159 
160  if (jj < 1 .or. jj > jdim) cycle jj_loop
161  if (ii < 1 .or. ii > idim) cycle ii_loop
162 
163  if (mask(ii,jj) == 1 .and. field_save(ii,jj) > -9999.0) then
164  field(i,j) = field_save(ii,jj)
165  ! write(6,100) field_num,tile,i,j,ii,jj,field(i,j)
166  ! When using non-GFS data, there are a lot of these print statements even
167  ! when everything is working correctly. Count instead of printing each
168  repl_nearby = repl_nearby + 1
169  cycle i_loop
170  endif
171 
172  endif
173 
174  enddo ii_loop
175  enddo jj_loop
176 
177  enddo krad_loop
178 
179  if (field_num == 11) then
180  call sst_guess(latitude(i,j), field(i,j))
181  elseif (field_num == 91) then ! sea ice fract
182  if (abs(latitude(i,j)) > 55.0) then
183  field(i,j) = default_value
184  repl_default = repl_default + 1
185  else
186  field(i,j) = 0.0
187  repl_default = repl_default + 1
188  endif
189  elseif (field_num == 7 .and. present(terrain_land)) then
190  ! Terrain heights for isolated landice points never get a correct value, so replace
191  ! with terrain height from the input grid interpolated to the target grid
192  field(i,j) = terrain_land(i,j)
193  repl_default = repl_default + 1
194  elseif (field_num == 224 .and. present(soilt_climo)) then
195  ! When using input soil type fields instead of climatological data on the
196  ! target grid, isolated land locations that exist in the target grid but
197  ! not the input grid don't receiving proper soil type information, so replace
198  ! with climatological values
199  field(i,j) = soilt_climo(i,j)
200  repl_default = repl_default + 1
201  else
202  field(i,j) = default_value
203  repl_default = repl_default + 1
204  endif
205 
206  !write(6,101) field_num,tile,i,j,field(i,j)
207 
208  endif
209  enddo i_loop
210  enddo j_loop
211 !$OMP END PARALLEL DO
212 
213 ! 100 format(1x,"- MISSING POINT FIELD ",i4," TILE: ",i2," I/J: ",i5,i5," SET TO VALUE AT: ",i5,i5,". NEW VALUE IS: ",f8.3)
214 ! 101 format(1x,"- MISSING POINT FIELD ",i4," TILE: ",i2," I/J: ",i5,i5," SET TO DEFAULT VALUE OF: ",f8.3)
215  print*, "- TOTAL POINTS FOR VAR ", field_num, " REPLACED BY NEARBY VALUES: ", repl_nearby
216  print*, "- TOTAL POINTS FOR VAR ", field_num, " REPLACED BY DEFAULT VALUE: ", repl_default
217 
218  end subroutine search
219 
234  subroutine sst_guess(latitude, sst)
235 
236  use esmf
237 
238  implicit none
239 
240  real(esmf_kind_r8), parameter :: sst_polar_in_kelvin = 273.16
242  real(esmf_kind_r8), parameter :: sst_tropical_in_kelvin = 300.0
244  real(esmf_kind_r8), parameter :: polar_latitude = 60.0
246  real(esmf_kind_r8), parameter :: tropical_latitude = 30.0
248  real(esmf_kind_r8), parameter :: dsst_dlat = -0.8947
250  real(esmf_kind_r8), parameter :: sst_y_intercept = 326.84
252 
253  real(esmf_kind_r8), intent(in) :: latitude
254 
255  real(esmf_kind_r8), intent(out) :: sst
256 
257  if (abs(latitude) >= polar_latitude) then
258  sst = sst_polar_in_kelvin
259  elseif (abs(latitude) <= tropical_latitude) then
260  sst = sst_tropical_in_kelvin
261  else
262  sst = dsst_dlat * abs(latitude) + sst_y_intercept
263  endif
264 
265  end subroutine sst_guess
266 
267  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