chgres_cube 1.14.0
Loading...
Searching...
No Matches
search_util.F90
Go to the documentation of this file.
1
4
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_f08
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
Replace undefined values with a valid value.
subroutine, public search(field, mask, idim, jdim, tile, field_num, latitude, terrain_land, soilt_climo)
Replace undefined surface values.
subroutine sst_guess(latitude, sst)
Set default Sea Surface Temperature (SST) based on latitude.