23 use mo_kind,
only : i4, dp, sp
29 use mo_netcdf,
only : ncdataset, ncdimension, ncvariable
39 type(ncvariable) :: nc
40 logical :: avg = .false.
41 logical,
pointer :: mask(:, :)
42 real(dp),
allocatable :: data(:)
43 integer(i4) :: counter = 0
57 integer(i4) :: idomain
60 integer(i4) :: counter
61 integer(i4) :: previous_time
62 integer(i4) :: time_unit_factor
63 integer(i4) :: outputs_frequence
64 integer(i4) :: time_reference
65 logical :: double_precision
84 logical,
intent(in) :: double_precision
85 if ( double_precision )
then
98 data_dims = (/
"easting ",
"northing",
"time "/)
114 type(ncdataset),
intent(in) :: nc
115 character(*),
intent(in) :: name
116 character(*),
intent(in) :: dtype
117 character(16),
intent(in),
dimension(3) :: dims
118 integer(i4),
intent(in) :: ncells
119 logical,
intent(in),
target,
dimension(:, :) :: mask
120 integer(i4),
intent(in) :: deflate_level
121 logical,
intent(in),
optional :: avg
125 allocate(out%data(ncells))
126 out%nc = nc%setVariable(name, dtype, dims, deflate_level = deflate_level, shuffle = .true.)
129 if (
present(avg)) out%avg = avg
144 real(dp),
intent(in),
dimension(:) :: data
146 self%data = self%data +
data
147 self%counter = self%counter + 1
164 integer(i4),
intent(in) :: current_time_step
167 self%data = self%data / real(self%counter, dp)
170 call self%nc%setData(unpack(self%data, self%mask,
nodata_dp), &
171 (/1, 1, current_time_step/))
189 function newoutputdataset( iDomain, level, file_name, double_precision, outputs_frequence, time_reference )
result(out)
192 integer(i4),
intent(in) :: idomain
193 type(
grid),
dimension(:),
allocatable,
target,
intent(in) :: level
194 character(*),
intent(in) :: file_name
195 logical,
intent(in) :: double_precision
196 integer(i4),
intent(in) :: outputs_frequence
197 integer(i4),
intent(in) :: time_reference
201 out%nc =
createoutputfile(idomain, level, file_name, double_precision, outputs_frequence, time_reference)
202 out%iDomain = idomain
205 if ( (outputs_frequence > 0) &
206 .and. (mod(
timestep * outputs_frequence, 2) == 1) &
207 .and. (time_reference == 1) &
209 out%time_unit_factor = 60
211 out%time_unit_factor = 1
213 out%outputs_frequence = outputs_frequence
214 out%time_reference = time_reference
215 out%double_precision = double_precision
216 out%previous_time = 0
234 integer(i4),
intent(in) :: current_time_step
238 type(ncvariable) :: tvar
240 self%counter = self%counter + 1
243 tvar = self%nc%getVariable(
"time")
244 select case( self%time_reference )
246 call tvar%setData(self%previous_time * self%time_unit_factor, (/self%counter/))
248 call tvar%setData((self%previous_time + current_time_step) * self%time_unit_factor / 2, (/self%counter/))
250 call tvar%setData(current_time_step * self%time_unit_factor, (/self%counter/))
253 tvar = self%nc%getVariable(
"time_bnds")
254 call tvar%setData(self%previous_time * self%time_unit_factor, (/1, self%counter/))
255 call tvar%setData(current_time_step * self%time_unit_factor, (/2, self%counter/))
256 self%previous_time = current_time_step
258 do ii = 1,
size(self%vars)
259 call self%vars(ii)%writeVariableTimestep(self%counter)
275 use mo_string_utils,
only : num2str
276 use mo_message,
only : message
283 call message(
' OUTPUT: saved netCDF file for domain', trim(num2str(self%iDomain)))
284 call message(
' to ', trim(self%nc%fname))
301 function createoutputfile(iDomain, level, file_name, double_precision, outputs_frequence, time_reference)
result(nc)
305 use mo_julian,
only : dec2date
310 integer(i4),
intent(in) :: idomain
311 type(
grid),
dimension(:),
allocatable,
intent(in) :: level
312 character(*),
intent(in) :: file_name
313 logical,
intent(in) :: double_precision
314 integer(i4),
intent(in) :: outputs_frequence
315 integer(i4),
intent(in) :: time_reference
317 type(ncdataset) :: nc
318 type(ncdimension),
dimension(4) :: dimids1
319 type(ncvariable) :: var
320 integer(i4) :: day, month, year
321 character(1028) :: fname
322 character(128) :: unit, date, time, datetime
323 real(dp),
allocatable,
dimension(:) :: easting, northing
324 real(dp),
allocatable,
dimension(:, :) :: x_bnds, y_bnds
325 real(dp) :: half_step
326 real(dp),
allocatable,
dimension(:) :: lat1d, lon1d
327 real(dp),
allocatable,
dimension(:, :) :: lat2d, lon2d
329 character(3) :: dtype
334 half_step = level(idomain)%cellsize / 2.0_dp
336 fname = trim(
dirout(idomain)) // trim(file_name)
339 nc = ncdataset(trim(fname),
"w")
347 allocate(x_bnds(2,
size(easting)))
348 allocate(y_bnds(2,
size(northing)))
349 x_bnds(1, :) = easting - half_step
350 x_bnds(2, :) = easting + half_step
351 y_bnds(1, :) = northing - half_step
352 y_bnds(2, :) = northing + half_step
355 nc%setDimension(
"easting",
size(easting)), &
356 nc%setDimension(
"northing",
size(northing)), &
357 nc%setDimension(
"time", 0), &
358 nc%setDimension(
"bnds", 2) &
361 var = nc%setVariable(
"easting", dtype, (/ dimids1(1) /))
362 call set_attributes(var,
"x-coordinate in the given coordinate system", &
363 unit=
"m", standard_name=
"projection_x_coordinate", add_coords=.false., axis=
"X", bounds=
"easting_bnds")
364 call var%setData(easting)
365 var = nc%setVariable(
"easting_bnds", dtype, (/ dimids1(4), dimids1(1) /))
366 call var%setData(x_bnds)
368 var = nc%setVariable(
"northing", dtype, (/ dimids1(2) /))
369 call set_attributes(var,
"y-coordinate in the given coordinate system", &
370 unit=
"m", standard_name=
"projection_y_coordinate", add_coords=.false., axis=
"Y", bounds=
"northing_bnds")
371 call var%setData(northing)
372 var = nc%setVariable(
"northing_bnds", dtype, (/ dimids1(4), dimids1(2) /))
373 call var%setData(y_bnds)
375 var = nc%setVariable(
"lon", dtype, dimids1(1 : 2))
377 double_precision=double_precision, add_coords=.false., standard_name=
"longitude")
378 call var%setData(lon2d)
380 var = nc%setVariable(
"lat", dtype, dimids1(1 : 2))
382 double_precision=double_precision, add_coords=.false., standard_name=
"latitude")
383 call var%setData(lat2d)
391 allocate(x_bnds(2,
size(lon1d)))
392 allocate(y_bnds(2,
size(lat1d)))
394 x_bnds(1, :) = lon1d - half_step
395 x_bnds(2, :) = lon1d + half_step
396 y_bnds(1, :) = lat1d - half_step
397 y_bnds(2, :) = lat1d + half_step
400 nc%setDimension(
"lon",
size(lon1d)), &
401 nc%setDimension(
"lat",
size(lat1d)), &
402 nc%setDimension(
"time", 0), &
403 nc%setDimension(
"bnds", 2) &
406 var = nc%setVariable(
"lon", dtype, (/ dimids1(1) /))
408 add_coords=.false., standard_name=
"longitude", axis=
"X", bounds=
"lon_bnds")
409 call var%setData(lon1d)
410 var = nc%setVariable(
"lon_bnds", dtype, (/ dimids1(4), dimids1(1) /))
411 call var%setData(x_bnds)
413 var = nc%setVariable(
"lat", dtype, (/ dimids1(2) /))
415 add_coords=.false., standard_name=
"latitude", axis=
"Y", bounds=
"lat_bnds")
416 call var%setData(lat1d)
417 var = nc%setVariable(
"lat_bnds", dtype, (/ dimids1(4), dimids1(2) /))
418 call var%setData(y_bnds)
424 call dec2date(real(
evalper(idomain)%julStart, dp), dd = day, mm = month, yy = year)
427 if ( (outputs_frequence > 0) &
428 .and. (mod(
timestep * outputs_frequence, 2) == 1) &
429 .and. (time_reference == 1) &
431 write(unit,
"('minutes since ', i4, '-' ,i2.2, '-', i2.2, 1x, '00:00:00')") year, month, day
433 write(unit,
"('hours since ', i4, '-' ,i2.2, '-', i2.2, 1x, '00:00:00')") year, month, day
437 var = nc%setVariable(
"time",
"i32", (/ dimids1(3) /))
438 call set_attributes(var,
"time", unit=unit, add_coords=.false., standard_name=
"time", axis=
"T", bounds=
"time_bnds")
439 var = nc%setVariable(
"time_bnds",
"i32", (/ dimids1(4), dimids1(3) /))
442 call date_and_time(date = date, time = time)
443 write(datetime,
"(a4,'-',a2,'-',a2,1x,a2,':',a2,':',a2)") date(1 : 4), &
444 date(5 : 6), date(7 : 8), time(1 : 2), time(3 : 4), time(5 : 6)
450 call nc%setAttribute(
"contact",
contact)
451 call nc%setAttribute(
"mHM_details", trim(
mhm_details) //
", release mHMv" // trim(
version))
452 call nc%setAttribute(
"history", trim(datetime) //
", " //
history)
454 call nc%setAttribute(
"creation_date", datetime)
463 subroutine set_attributes(var, long_name, unit, double_precision, add_coords, standard_name, axis, bounds)
466 type(ncvariable),
intent(inout) :: var
467 character(*),
intent(in),
optional :: long_name
468 character(*),
intent(in),
optional :: unit
469 logical,
intent(in),
optional :: double_precision
470 logical,
intent(in),
optional :: add_coords
471 character(*),
intent(in),
optional :: standard_name
472 character(*),
intent(in),
optional :: axis
473 character(*),
intent(in),
optional :: bounds
475 logical :: add_coords_
478 if (
present(add_coords)) add_coords_ = add_coords
480 if (
present(double_precision))
then
481 if (double_precision)
then
483 call var%setAttribute(
"missing_value",
nodata_dp)
486 call var%setFillValue(real(
nodata_dp, kind=sp))
487 call var%setAttribute(
"missing_value", real(
nodata_dp, kind=sp))
491 if (
present(long_name))
call var%setAttribute(
"long_name", long_name)
492 if (
present(unit))
call var%setAttribute(
"units", unit)
493 if (add_coords_)
call var%setAttribute(
"coordinates",
"lat lon")
494 if (
present(standard_name))
call var%setAttribute(
"standard_name", standard_name)
495 if (
present(axis))
call var%setAttribute(
"axis", axis)
496 if (
present(bounds))
call var%setAttribute(
"bounds", bounds)
Provides constants commonly used by mHM, mRM and MPR.
real(dp), parameter, public nodata_dp
Provides structures needed by mHM, mRM and/or mpr.
integer(i4), public timestep
type(period), dimension(:), allocatable, public evalper
Provides common types needed by mHM, mRM and/or mpr.
Provides structures needed by mHM, mRM and/or mpr.
character(1024), public history
character(1024), public setup_description
character(1024), public project_details
character(1024), public contact
character(256), public conventions
character(1024), public simulation_type
character(256), dimension(:), allocatable, public dirout
integer(i4), public iflag_cordinate_sys
character(1024), public mhm_details
Provides file names and units for mHM.
character(len=*), parameter version
Current mHM model version (will be set to )
subroutine, public mapcoordinates(level, y, x)
Generate map coordinates.
subroutine, public geocoordinates(level, lat, lon)
Generate geographic coordinates.
Creates NetCDF output for different fluxes and state variables of mHM.
character(16) function, dimension(3), public data_dims()
Output variable dimension names.
character(3) function, public data_dtype(double_precision)
Output variable dtype for single or double precision.
subroutine updatevariable(self, data)
Update OutputVariable.
subroutine, public set_attributes(var, long_name, unit, double_precision, add_coords, standard_name, axis, bounds)
Write output variable attributes.
type(outputdataset) function newoutputdataset(idomain, level, file_name, double_precision, outputs_frequence, time_reference)
Initialize OutputDataset.
subroutine close(self)
Close the file.
type(ncdataset) function createoutputfile(idomain, level, file_name, double_precision, outputs_frequence, time_reference)
Create and initialize output file for X & Y coordinate system.
subroutine writetimestep(self, current_time_step)
Write all accumulated data.
subroutine writevariabletimestep(self, current_time_step)
Write timestep to file.
type(outputvariable) function newoutputvariable(nc, name, dtype, dims, ncells, mask, deflate_level, avg)
Initialize OutputVariable.