TreeMig Code
Loading...
Searching...
No Matches
PrepareNetcdfOutput.f90
Go to the documentation of this file.
1!==============================================================================
2! contains subroutines PrepareNetcdfOutput, InitNCVar, m_check
3!==============================================================================
5
6contains
7
8! ==============================================================================
49
50!==============================================================================
51SUBROUTINE preparenetcdfoutput(nspc)
55
56 use netcdf, only: nf90_char, nf90_global, nf90_int, nf90_netcdf4, nf90_real,&
57 nf90_unlimited, nf90_def_dim, nf90_put_att, nf90_put_var, &
58 nf90_create, nf90_def_var, nf90_enddef
63 IMPLICIT NONE
64
65 INTEGER, INTENT(in) :: nspc
66
67 INTEGER, dimension(:) :: dimYeSpXY(4), dimLimits(3)
68 INTEGER :: dimId_year, dimId_speciesLength,dimId_species, dimId_x, dimId_y, dimId_hc, dimId_lc
69 INTEGER :: varId_year,varId_species, varId_x, varId_y, varId_crs, varId_hc, varId_lc
70
71
72 REAL :: lats(maxlat)
73 REAL :: lons(maxlon)
74 INTEGER :: years(numyrs)
75 INTEGER :: species(nspc+1)
76 INTEGER :: hc(maxhc+1)
77 INTEGER :: lc(maxlc)
78
79 INTEGER :: i, numReportYears, actualYear, rpti
80
81 character*6:: yearChar
82
83 ! variables for date/time
84 INTEGER date_time(8)
85 character*5:: zone
86 character*25 :: dateTimeString
87
88
89 ! if netcdf output is not set, we do nothing
90 if(.not. writeoutput%netcdf) return
91
92 ! create netcdf file; the NC_File_ID is provided by the nf90_create function
93 call m_check(nf90_create(nc_file_name, nf90_netcdf4, nc_file_id), __line__, __file__)
94
95 ! get date/time and store them to a string in a format Netcdf likes
96 call date_and_time(zone=zone, values= date_time)
97 write(datetimestring, '(I4.4,"-",2(I2.2,"-"),"T",2(I2.2,":"),I2.2,A5)') date_time(1),date_time(2),&
98 date_time(3), date_time(5), date_time(6), date_time(7), zone
99 ! define global attributes for file
100 call m_check(nf90_put_att(nc_file_id, nf90_global , "title", "TreeMig model output"), __line__,__file__)
101 call m_check(nf90_put_att(nc_file_id, nf90_global , "institution", &
102 "Swiss Federal Institute for Forest, Snow and Landscape Research WSL"), __line__,__file__)
103
104 call m_check(nf90_put_att(nc_file_id, nf90_global , "institute_id", "WSL"), __line__,__file__)
105 call m_check(nf90_put_att(nc_file_id, nf90_global , "experiment_id", experimentid), __line__,__file__)
106 call m_check(nf90_put_att(nc_file_id, nf90_global , "model_id", "TreeMig"), __line__,__file__)
107 call m_check(nf90_put_att(nc_file_id, nf90_global , "contact", "maintainer_treemig@wsl.ch"),&
108 __line__,__file__)
109
110 call m_check(nf90_put_att(nc_file_id, nf90_global , "reference", "TreeMig model described by Lischke et al., "&
111 "2006 (https://www.dora.lib4ri.ch/wsl/islandora/object/wsl%3A6049)"), __line__,__file__)
112 call m_check(nf90_put_att(nc_file_id, nf90_global , "treeMig_version", "0.0.1"), __line__,__file__)
113 call m_check(nf90_put_att(nc_file_id, nf90_global , "conventions", "CF-1.10"), __line__,__file__)
114 call m_check(nf90_put_att(nc_file_id, nf90_global , "creation_date", datetimestring),&
115 __line__,__file__)
116
117 ! define the dimensions. NetCDF will hand back an ID for each.
118
119 ! setup time dimension
120 call m_check(nf90_def_dim(nc_file_id, "time", nf90_unlimited, dimid_year), __line__,__file__)
121
122 ! setup species dimension
123 call m_check(nf90_def_dim(nc_file_id, "species", nspc+1, dimid_species), __line__,__file__)
124
125 ! setup x,y coordinate dimension
126 call m_check(nf90_def_dim(nc_file_id, "x", maxlon, dimid_x), __line__,__file__)
127 call m_check(nf90_def_dim(nc_file_id, "y", maxlat, dimid_y), __line__,__file__)
128 call m_check(nf90_def_dim(nc_file_id, "string80", 80, dimid_specieslength), __line__,__file__) ! ? maybe number of species
129
130 ! define time variable and its attributes
131 call m_check(nf90_def_var(nc_file_id, "time", nf90_int, dimid_year,varid_year), __line__,__file__)
132
133! axis: T unit year standard_name: time
134 write(yearchar,"(I6)") simustartyear
135 call m_check(nf90_put_att(nc_file_id, varid_year, "axis", "T"), __line__,__file__)
136 call m_check(nf90_put_att(nc_file_id, varid_year, "long_name", "time"), __line__,__file__)
137 call m_check(nf90_put_att(nc_file_id, varid_year, "standard_name", "time"), __line__,__file__)
138
139 call m_check(nf90_put_att(nc_file_id, varid_year, "units", "years since "//trim(yearchar)//"-1-1 0:0:0"),&
140 __line__,__file__)
141
142! define species variable
143 call m_check(nf90_def_var(nc_file_id, "species", nf90_char, &
144 (/ dimid_specieslength, dimid_species /), varid_species),&
145 __line__,__file__)
146! define x variable and its attributes
147 call m_check(nf90_def_var(nc_file_id, "x", nf90_real, dimid_x, varid_x), __line__,__file__)
148 call m_check(nf90_put_att(nc_file_id, varid_x, "standard_name", "projection_x_coordinate"),&
149 __line__,__file__)
150 call m_check(nf90_put_att(nc_file_id, varid_x, "long_name", "x coordinate of projection"),&
151 __line__,__file__)
152 call m_check(nf90_put_att(nc_file_id, varid_x, "units", "m"),__line__,__file__)
153 call m_check(nf90_put_att(nc_file_id, varid_x, "axis", "X"),__line__,__file__)
154! define y variable and its attributes
155 call m_check(nf90_def_var(nc_file_id, "y", nf90_real, dimid_y, varid_y),__line__,__file__)
156 call m_check(nf90_put_att(nc_file_id, varid_y, "standard_name", "projection_y_coordinate"),&
157 __line__,__file__)
158 call m_check(nf90_put_att(nc_file_id, varid_y, "long_name", "y coordinate of projection"),&
159 __line__,__file__)
160 call m_check(nf90_put_att(nc_file_id, varid_y, "units", "m"),__line__,__file__)
161 call m_check(nf90_put_att(nc_file_id, varid_y, "axis", "Y"),__line__,__file__)
162! define coordinates
163 call m_check(nf90_def_var(nc_file_id, "crs", nf90_int, [INTEGER::], varId_crs),__LINE__,__FILE__)
164! from where?
165
166
167 dimyespxy(1:4) = (/ dimid_year,dimid_species, dimid_x, dimid_y /)
168! here finally the different output variables are defined, allocated and initialized
169 if(writeoutput%biodiv)&
170 call initncvar(biodiv_nc, 2, (/ dimid_year,dimid_x, dimid_y/), (/maxlon,maxlat/))
171
172
173 dimlimits(1:3) = (/nspc+1,maxlon, maxlat/)
174 if(writeoutput%biomass)&
175 call initncvar(biomass_nc, 3, dimyespxy, dimlimits)
176 if(writeoutput%number)&
177 call initncvar(number_nc, 3, dimyespxy, dimlimits)
178 if(writeoutput%seeds)&
179 call initncvar(seed_nc, 3, dimyespxy, dimlimits)
180 if(writeoutput%ingrowth)&
181 call initncvar(ingrowth_nc, 3, dimyespxy, dimlimits)
182 if(writeoutput%NPP)&
183 call initncvar(npp_nc, 3, dimyespxy, dimlimits)
184 if(writeoutput%basalArea)&
185 call initncvar(basalarea_nc, 3, dimyespxy, dimlimits)
186 if(writeoutput%antagonists)&
187 call initncvar(antagonist_nc, 3, dimyespxy, dimlimits)
188 if(writeoutput%pollen)&
189 call initncvar(pollen_nc, 3, dimyespxy, dimlimits)
190 if(writeoutput%lai)&
191 call initncvar(lai_nc, 3, dimyespxy, dimlimits)
192 if(writeoutput%hstruct) then
193 do i=1,size(heightstruct_nc)
194 call initncvar(heightstruct_nc(i), 3, dimyespxy, dimlimits)
195 end do
196 end if
197! initializing the light output
198 if(writeoutput%light) then
199 call m_check(nf90_def_dim(nc_file_id, "hc", maxhc+1, dimid_hc),__line__,__file__)
200 call m_check(nf90_def_dim(nc_file_id, "lc", maxlc, dimid_lc), __line__,__file__)
201
202 call m_check(nf90_def_var(nc_file_id, "hc", nf90_int, dimid_hc, varid_hc),&
203 __line__,__file__)
204 call m_check(nf90_put_att(nc_file_id, varid_hc, "long_name", "height class"),&
205 __line__,__file__)
206
207
208 call m_check(nf90_def_var(nc_file_id, "lc", nf90_int, dimid_lc, varid_lc),&
209 __line__,__file__)
210 call m_check(nf90_put_att(nc_file_id, varid_lc, "long_name", "light class"),&
211 __line__,__file__)
212
213
214 call initncvar(light_nc, 4, (/ dimid_year,dimid_hc, dimid_lc, dimid_x, dimid_y /),&
215 (/maxhc+1,maxlc,maxlon, maxlat/))
216 do i=0,(maxhc)
217 hc(i+1) = i
218 end do
219 do i=1,maxlc
220 lc(i) = i
221 end do
222 end if
223! the values for the x and y variable are collected
224 do i=0,(maxlon-1)
226 end do
227 do i=0,(maxlat-1)
229 end do
230! the years for the year variable are collected
231 numreportyears = 0
232 do actualyear=simustartyear, simustartyear+numyrs-1
233 rpti = 1
234 do i=1,nreportintervals ! determine current report interval
235 if (actualyear >= reportintervals(i,2) .and. actualyear <= reportintervals(i,3) ) then
236 rpti=reportintervals(i,1)
237 exit
238 end if
239 end do
240 if(mod(actualyear-simustartyear, rpti) == 0)then
241 years(numreportyears+1) = actualyear
242 numreportyears = numreportyears+1
243 end if
244 end do
245
246 do i=0,(nspc)
247 species(i+1) = (i+1)
248 end do
249 ! ready with the definitions
250 call m_check( nf90_enddef(nc_file_id),__line__,__file__)
251 ! now the x, y and year values are added to the corresponding variables
252 call m_check( nf90_put_var(nc_file_id, varid_y, lats), __line__,__file__)
253
254 call m_check( nf90_put_var(nc_file_id, varid_x, lons), __line__,__file__)
255
256 call m_check( nf90_put_var(nc_file_id, varid_year, years(1:numreportyears)), __line__,__file__)
257
258 call m_check( nf90_put_var(nc_file_id, varid_species, (/(spec(i)%nl, i=1, nspc),"all_species"/)),&
259 __line__,__file__)
260
261 if(writeoutput%light)then
262 call m_check( nf90_put_var(nc_file_id, varid_hc, hc), __line__,__file__)
263
264 call m_check( nf90_put_var(nc_file_id, varid_lc, lc), __line__,__file__)
265
266 end if
267
268end SUBROUTINE preparenetcdfoutput
269
270!==============================================================================
271! @brief InitNCVar
272! *****************************************
289!==============================================================================
290SUBROUTINE initncvar(var, numDims, NCDims, limits)
291 use, intrinsic :: iso_fortran_env
292 use, intrinsic :: ieee_arithmetic
294 use netcdf
295 use loggermodule
296 IMPLICIT NONE
297
298 TYPE(ncvar), INTENT(inout) :: var
299 INTEGER, dimension(:), INTENT(in) :: NCDims
300 INTEGER, INTENT(in) :: numDims
301 INTEGER, dimension(:), INTENT(in) :: limits
302
303 REAL :: fillval
304 INTEGER :: alloc_st
305 character (len=500) :: errormsg
306 fillval = ieee_value(fillval, ieee_quiet_nan) ! ?????
307 ! defines the variable and its attributes
308 call m_check(nf90_def_var(nc_file_id, var%name, nf90_real, ncdims, var%varId, deflate_level = 4),&
309 __line__,__file__)
310 ! sets a fillval ????
311 call m_check(nf90_put_att(nc_file_id, var%varId, "_FillValue", fillval), __line__,__file__)
312
313 ! sets a unit
314 call m_check(nf90_put_att(nc_file_id, var%varId, "units", var%attr_unit), __line__,__file__)
315
316
317 ! depending on the number of dimensions, the arrays for this variable is allocated and filled with fillval
318 select case (numdims)
319 case (4)
320 allocate (var%values4D(1:limits(1), 1:limits(2), 1:limits(3), 1:limits(4)), stat=alloc_st, errmsg=errormsg)
321 var%values4D = fillval
322 case (3)
323 allocate (var%values3D(1:limits(1), 1:limits(2), 1:limits(3)), stat=alloc_st, errmsg=errormsg)
324 var%values3D = fillval
325 case (2)
326 allocate (var%values2D(1:limits(1), 1:limits(2)), stat=alloc_st, errmsg=errormsg)
327 var%values2D = fillval
328 case default
329 call logerror("Invalid number of NETCDF dimensions")
330
331 error stop
332 end select
333 call checkalloc(alloc_st, errormsg, var%name//" Output")
334end SUBROUTINE initncvar
335end module netcdftmmodule
336
337!==============================================================================
355!==============================================================================
356 SUBROUTINE m_check(status, lineNumber, fileName)
357 use loggermodule
358 use netcdf
359 INTEGER, INTENT (in) :: status
360 INTEGER, INTENT (in) :: lineNumber
361 character(len=*), INTENT (in) :: fileName
362 if(status /= nf90_noerr) then
363 write(logmessage,"(A,I3.3)") "Error in "//filename//" on line ", linenumber
364 call logerror(logmessage)
365 call logerror(trim(nf90_strerror(status)))
366 error stop "Execution has been stopped due to a netcdf error"
367 end if
368 end SUBROUTINE m_check
369!==============================================================================
subroutine checkalloc(alloc_st, errormsg, txt)
CheckAlloc.
subroutine m_check(status, linenumber, filename)
m_check
character(len=:), allocatable experimentid
Definition All_par.f90:105
real lonrealstart
Definition All_par.f90:50
integer simustartyear
Definition All_par.f90:27
integer, dimension(10, 3) reportintervals
Definition All_par.f90:29
real, dimension(nalloweddrivernames) values
Definition All_par.f90:115
integer, parameter maxhc
Definition All_par.f90:99
real cellsidelength
Definition All_par.f90:63
real unitofspatialdata
Definition All_par.f90:53
type(specproperties), dimension(maxspc) spec
Definition All_par.f90:345
type(wroutp) writeoutput
Definition All_par.f90:143
integer numyrs
Definition All_par.f90:26
integer, parameter maxlc
Definition All_par.f90:100
real latrealstart
Definition All_par.f90:50
integer maxlon
Definition All_par.f90:46
integer nreportintervals
Definition All_par.f90:30
integer maxlat
Definition All_par.f90:45
type(ncvar) basalarea_nc
type(ncvar) ingrowth_nc
type(ncvar) antagonist_nc
type(ncvar) number_nc
type(ncvar), dimension(16) heightstruct_nc
type(ncvar) light_nc
type(ncvar) lai_nc
type(ncvar) biodiv_nc
type(ncvar) biomass_nc
character(len=:), allocatable nc_file_name
type(ncvar) npp_nc
type(ncvar) pollen_nc
type(ncvar) seed_nc
LoggerModule.
character(len=1024) logmessage
subroutine logerror(msg)
LogError
subroutine initncvar(var, numdims, ncdims, limits)
subroutine preparenetcdfoutput(nspc)
PrepareNetcdfOutput