5.13.3-dev0
mHM
The mesoscale Hydrological Model
Loading...
Searching...
No Matches
mo_meteo_spatial_tools.f90
Go to the documentation of this file.
1!> \file mo_meteo_spatial_tools.f90
2!> \brief \copybrief mo_meteo_spatial_tools
3!> \details \copydetails mo_meteo_spatial_tools
4
5!> \brief Spatial aggegation or disaggregation of meteorological input data.
6!> \details This module contains two subroutines to upscale and downscale, respectively,
7!! the level-2 meterological inputs to a required Level-1 hydrological spatial resolution.
8!> \authors Rohini Kumar
9!> \date Jan 2013
10!> \copyright Copyright 2005-\today, the mHM Developers, Luis Samaniego, Sabine Attinger: All rights reserved.
11!! mHM is released under the LGPLv3+ license \license_note
12!> \ingroup f_meteo
14
15 ! This module provides routines for spatial aggegation or disaggregation of meteorological input data.
16
17 USE mo_kind, ONLY : i4, dp
18
19 IMPLICIT NONE
20
21 PUBLIC :: spatial_aggregation ! Spatial aggregation or upscaling
22 PUBLIC :: spatial_disaggregation ! Spatial disaggregation or downscaling
23
24
25 ! ------------------------------------------------------------------
26
27 ! NAME
28 ! spatial_aggregation
29
30 ! PURPOSE
31 !> \brief Spatial aggregation of meterological variables
32
33 !> \details Aggregate (or upscale) the given level-2 meteorological data to the
34 !> required level-1 spatial resolution for the mHM run.
35
36 ! HISTORY
37 !> \authors Rohini Kumar
38
39 !> \date Jan 2013
40
41 ! Modifications:
42 ! Rohini Kumar Nov 2013 - data1 changed from intent(inout) to intent(out)
43 ! RK, MZ, DS May 2014 - added mask2
44 ! Robert Schweppe Jun 2018 - refactoring and reformatting
45
46
49 END INTERFACE spatial_aggregation
50
51 ! ------------------------------------------------------------------
52
53 ! NAME
54 ! spatial_disaggregation
55
56 ! PURPOSE
57 !> \brief Spatial disaggregation of meterological variables
58
59 !> \details Disaggregate (or downscale) the given level-2 meteorological data to the
60 !> required level-1 spatial resolution for the mHM run.
61
62 ! INTENT(IN)
63 !> \param[in] "real(dp), dimension(:, :, :) :: data2" Level-2 data
64 !> \param[in] "real(dp) :: cellsize2" Level-2 resolution
65 !> \param[in] "real(dp) :: cellsize1" Level-1 resolution
66 !> \param[in] "logical, dimension(:, :) :: mask1" Level-1 mask
67 !> \param[in] "logical, dimension(:, :) :: mask2" Level-2 mask
68
69 ! INTENT(OUT)
70 !> \param[out] "real(dp), dimension(:, :, :) :: data1" Level-1 data
71
72 ! HISTORY
73 !> \authors Rohini Kumar
74
75 !> \date Jan 2013
76
77 ! Modifications:
78 ! Rohini Kumar Nov 2013 - data1 changed from intent(inout) to intent(out)
79 ! RK, MZ, DS May 2014 - added mask2
80
81
84 end INTERFACE spatial_disaggregation
85
86 ! ------------------------------------------------------------------
87
88 PRIVATE
89
90 ! ------------------------------------------------------------------
91
92CONTAINS
93
94 subroutine spatial_aggregation_3d(data2, cellsize2, cellsize1, mask1, mask2, data1)
95
97
98 implicit none
99
100 ! Level-2 data
101 real(dp), dimension(:, :, :), intent(in) :: data2
102
103 ! Level-2 resolution
104 real(dp), intent(in) :: cellsize2
105
106 ! Level-1 resolution
107 real(dp), intent(in) :: cellsize1
108
109 ! Level-1 mask
110 logical, dimension(:, :), intent(in) :: mask1
111
112 ! Level-2 mask
113 logical, dimension(:, :), intent(in) :: mask2
114
115 ! Level-1 data
116 real(dp), dimension(:, :, :), allocatable, intent(out) :: data1
117
118 ! No. of rows and cols at Level-1
119 integer(i4) :: nr2, nc2
120
121 ! No. of rows and cols at Level-1
122 integer(i4) :: nr1, nc1
123
124 real(dp) :: cellFactor
125
126 integer(i4), dimension(:, :), allocatable :: nTCells
127
128 integer(i4) :: nTimeSteps
129
130 integer(i4) :: i, j, ic, jc, t
131
132
133 ! get number of rows and cols at level-2 from mask2
134 ! and the total time steps
135 nr2 = size(data2, 1)
136 nc2 = size(data2, 2)
137 ntimesteps = size(data2, 3)
138
139 ! get number of rows and cols at level-1 from mask1
140 nr1 = size(mask1, 1)
141 nc1 = size(mask1, 2)
142
143 !-----------------------------------------------------------------------
144 ! Allocate and initalize nTCells which comprises
145 ! of number of L2 cells that belongs to a given L1 cell
146 ! NOTE:: 1) cell size of L1 > L2 (see CellFactor)
147 ! 2) nTCells is estimated over the valid masked domain only
148 !-----------------------------------------------------------------------
149
150 ! cellFactor = level-1 resolution (hydro) / level-2 resolution (meteo)
151 cellfactor = cellsize1 / cellsize2
152
153 ! nTCells calculations
154 allocate(ntcells(nr1, nc1))
155 ntcells(:, :) = 0
156
157 do j = 1, nc2
158 jc = ceiling(real(j, dp) / cellfactor)
159 do i = 1, nr2
160 ic = ceiling(real(i, dp) / cellfactor)
161 if(.not. mask2(i, j)) cycle
162 ntcells(ic, jc) = ntcells(ic, jc) + 1
163 end do
164 end do
165
166
167 ! allocate and initalize L1_data
168 allocate(data1(nr1, nc1, ntimesteps))
169 data1(:, :, :) = 0.0_dp
170
171 ! time loop
172 do t = 1, ntimesteps
173
174 ! perform spatial aggregation
175 do j = 1, nc2
176 jc = ceiling(real(j, dp) / cellfactor)
177 do i = 1, nr2
178 ic = ceiling(real(i, dp) / cellfactor)
179
180 ! only in valid masked area
181 if(.not. mask2(i, j)) cycle
182 data1(ic, jc, t) = data1(ic, jc, t) + data2(i, j, t)
183
184 end do
185 end do
186
187 ! perform spatial average only over valid masked domain
188 ! out of the masked domain nTCells(:,:) = 0
189 where(mask1)
190 data1(:, :, t) = data1(:, :, t) / real(ntcells(:, :), dp)
191 elsewhere
192 data1(:, :, t) = nodata_dp
193 endwhere
194
195 end do
196
197 ! free space
198 deallocate(ntcells)
199
200 end subroutine spatial_aggregation_3d
201
202 subroutine spatial_aggregation_4d(data2, cellsize2, cellsize1, mask1, mask2, data1)
203
205
206 implicit none
207
208 ! Level-2 data
209 real(dp), dimension(:, :, :, :), intent(in) :: data2
210
211 ! Level-2 resolution
212 real(dp), intent(in) :: cellsize2
213
214 ! Level-1 resolution
215 real(dp), intent(in) :: cellsize1
216
217 ! Level-1 mask
218 logical, dimension(:, :), intent(in) :: mask1
219
220 ! Level-2 mask
221 logical, dimension(:, :), intent(in) :: mask2
222
223 ! Level-1 data
224 real(dp), dimension(:, :, :, :), allocatable, intent(out) :: data1
225
226 ! No. of rows and cols at Level-1
227 integer(i4) :: nr2, nc2
228
229 ! No. of rows and cols at Level-1
230 integer(i4) :: nr1, nc1
231
232 real(dp) :: cellFactor
233
234 integer(i4), dimension(:, :), allocatable :: nTCells
235
236 integer(i4) :: nMonths, nHours
237
238 integer(i4) :: i, j, ic, jc, t, h
239
240
241 ! get number of rows and cols at level-2 from mask2
242 ! and the total time steps
243 nr2 = size(data2, 1)
244 nc2 = size(data2, 2)
245 nmonths = size(data2, 3)
246 nhours = size(data2, 4)
247
248 ! get number of rows and cols at level-1 from mask1
249 nr1 = size(mask1, 1)
250 nc1 = size(mask1, 2)
251
252 !-----------------------------------------------------------------------
253 ! Allocate and initalize nTCells which comprises
254 ! of number of L2 cells that belongs to a given L1 cell
255 ! NOTE:: 1) cell size of L1 > L2 (see CellFactor)
256 ! 2) nTCells is estimated over the valid masked domain only
257 !-----------------------------------------------------------------------
258
259 ! cellFactor = level-1 resolution (hydro) / level-2 resolution (meteo)
260 cellfactor = cellsize1 / cellsize2
261
262 ! nTCells calculations
263 allocate(ntcells(nr1, nc1))
264 ntcells(:, :) = 0
265
266 do j = 1, nc2
267 jc = ceiling(real(j, dp) / cellfactor)
268 do i = 1, nr2
269 ic = ceiling(real(i, dp) / cellfactor)
270 if(.not. mask2(i, j)) cycle
271 ntcells(ic, jc) = ntcells(ic, jc) + 1
272 end do
273 end do
274
275
276 ! allocate and initalize L1_data
277 allocate(data1(nr1, nc1, nmonths, nhours))
278 data1(:, :, :, :) = 0.0_dp
279
280 ! time loop
281 do t = 1, nmonths
282 do h = 1, nhours
283
284 ! perform spatial aggregation
285 do j = 1, nc2
286 jc = ceiling(real(j, dp) / cellfactor)
287 do i = 1, nr2
288 ic = ceiling(real(i, dp) / cellfactor)
289
290 ! only in valid masked area
291 if(.not. mask2(i, j)) cycle
292 data1(ic, jc, t, h) = data1(ic, jc, t, h) + data2(i, j, t, h)
293
294 end do
295 end do
296
297 ! perform spatial average only over valid masked domain
298 ! out of the masked domain nTCells(:,:) = 0
299 where(mask1)
300 data1(:, :, t, h) = data1(:, :, t, h) / real(ntcells(:, :), dp)
301 elsewhere
302 data1(:, :, t, h) = nodata_dp
303 endwhere
304
305 end do
306 end do
307
308 ! free space
309 deallocate(ntcells)
310
311 end subroutine spatial_aggregation_4d
312
313 subroutine spatial_disaggregation_3d(data2, cellsize2, cellsize1, mask1, mask2, data1)
314
316
317 implicit none
318
319 ! Level-2 data
320 real(dp), dimension(:, :, :), intent(in) :: data2
321
322 ! Level-2 resolution
323 real(dp), intent(in) :: cellsize2
324
325 ! Level-1 resolution
326 real(dp), intent(in) :: cellsize1
327
328 ! Level-1 mask
329 logical, dimension(:, :), intent(in) :: mask1
330
331 ! Level-2 mask
332 logical, dimension(:, :), intent(in) :: mask2
333
334 ! Level-1 data
335 real(dp), dimension(:, :, :), allocatable, intent(out) :: data1
336
337 ! No. of rows and cols at Level-1
338 integer(i4) :: nr1, nc1
339
340 real(dp) :: cellFactor
341
342 integer(i4) :: nTimeSteps
343
344 integer(i4) :: i, j, t, ic, jc
345
346
347 ! get number of rows and cols at level-2 from mask2
348 nr1 = size(mask1, 1)
349 nc1 = size(mask1, 2)
350
351 ! cellFactor = level-2 resolution (meteo) / level-1 resolution (hydro)
352 cellfactor = cellsize2 / cellsize1
353
354 ! total time steps
355 ntimesteps = size(data2, 3)
356
357 ! allocate and initalize L1_data
358 allocate(data1(nr1, nc1, ntimesteps))
359 data1(:, :, :) = nodata_dp
360
361 ! over the time loop
362 do t = 1, ntimesteps
363
364 ! spatial disaggregation
365 do j = 1, nc1
366 jc = ceiling(real(j, dp) / cellfactor)
367 do i = 1, nr1
368 ic = ceiling(real(i, dp) / cellfactor)
369 ! only over the valid masked area
370 if(.not. mask2(ic, jc)) cycle
371 data1(i, j, t) = data2(ic, jc, t)
372 end do
373 end do
374
375 end do
376
377 end subroutine spatial_disaggregation_3d
378
379 subroutine spatial_disaggregation_4d(data2, cellsize2, cellsize1, mask1, mask2, data1)
380
382
383 implicit none
384
385 ! Level-2 data
386 real(dp), dimension(:, :, :, :), intent(in) :: data2
387
388 ! Level-2 resolution
389 real(dp), intent(in) :: cellsize2
390
391 ! Level-1 resolution
392 real(dp), intent(in) :: cellsize1
393
394 ! Level-1 mask
395 logical, dimension(:, :), intent(in) :: mask1
396
397 ! Level-2 mask
398 logical, dimension(:, :), intent(in) :: mask2
399
400 ! Level-1 data
401 real(dp), dimension(:, :, :, :), allocatable, intent(out) :: data1
402
403 ! No. of rows and cols at Level-1
404 integer(i4) :: nr1, nc1
405
406 real(dp) :: cellFactor
407
408 integer(i4) :: nMonths, nHours
409
410 integer(i4) :: i, j, t, ic, jc, h
411
412
413 ! get number of rows and cols at level-2 from mask2
414 nr1 = size(mask1, 1)
415 nc1 = size(mask1, 2)
416
417 ! cellFactor = level-2 resolution (meteo) / level-1 resolution (hydro)
418 cellfactor = cellsize2 / cellsize1
419
420 ! time axis
421 nmonths = size(data2, 3)
422 nhours = size(data2, 4)
423
424 ! allocate and initalize L1_data
425 allocate(data1(nr1, nc1, nmonths, nhours))
426 data1(:, :, :, :) = nodata_dp
427
428 ! over the time loop
429 do t = 1, nmonths
430 do h = 1, nhours
431
432 ! spatial disaggregation
433 do j = 1, nc1
434 jc = ceiling(real(j, dp) / cellfactor)
435 do i = 1, nr1
436 ic = ceiling(real(i, dp) / cellfactor)
437 ! only over the valid masked area
438 if(.not. mask2(ic, jc)) cycle
439 data1(i, j, t, h) = data2(ic, jc, t, h)
440 end do
441 end do
442 end do
443 end do
444
445 end subroutine spatial_disaggregation_4d
446
447END MODULE mo_meteo_spatial_tools
Spatial aggregation of meterological variables.
Spatial disaggregation of meterological variables.
Provides constants commonly used by mHM, mRM and MPR.
real(dp), parameter, public nodata_dp
Spatial aggegation or disaggregation of meteorological input data.
subroutine spatial_aggregation_3d(data2, cellsize2, cellsize1, mask1, mask2, data1)
subroutine spatial_aggregation_4d(data2, cellsize2, cellsize1, mask1, mask2, data1)
subroutine spatial_disaggregation_3d(data2, cellsize2, cellsize1, mask1, mask2, data1)
subroutine spatial_disaggregation_4d(data2, cellsize2, cellsize1, mask1, mask2, data1)