FV3 Bundle
ncdw_types.F90
Go to the documentation of this file.
1 module ncdw_types
2  use ncd_kinds, only: i_byte, i_short, i_long, i_llong, &
4  use netcdf, only: nf90_fill_byte, nf90_fill_short, nf90_fill_int, &
5  nf90_fill_float, nf90_fill_double, nf90_fill_char
6 
7  implicit none
8 
9  ! NetCDF4 type struct constants
10  integer(i_byte), parameter :: nlayer_byte = 1
11  integer(i_byte), parameter :: nlayer_short = 2
12  integer(i_byte), parameter :: nlayer_long = 3
13  integer(i_byte), parameter :: nlayer_float = 4
14  integer(i_byte), parameter :: nlayer_double = 5
15  integer(i_byte), parameter :: nlayer_string = 6
16 
17  ! Default number of starting entries
18  integer(i_short), parameter :: nlayer_default_ent = 1024
19 
20  ! NetCDF zlib (/gzip) compression level
21  integer(i_long), parameter :: nlayer_compression = 9
22 
23  ! NetCDF chunking size
24  integer(i_long), parameter :: nlayer_chunking = 16384
25 
26  ! Base used when exponentiated.
27  integer(i_long), parameter :: nlayer_multi_base = 2
28 
29  integer(i_byte), parameter :: nlayer_fill_byte = nf90_fill_byte
30  integer(i_short),parameter :: nlayer_fill_short = nf90_fill_short
31  integer(i_long), parameter :: nlayer_fill_long = nf90_fill_int
32  real(r_single), parameter :: nlayer_fill_float = nf90_fill_float
33  real(r_double), parameter :: nlayer_fill_double = nf90_fill_double
34  character, parameter :: nlayer_fill_char = nf90_fill_char
35 
37  ! Number of channels to store
38  integer(i_long) :: nchans = -1
39 
40  ! The NetCDF dimension ID for nchans
41  ! (This doesn't get set unless we do nc_diag_chaninfo_load_def,
42  ! or we write out the nchans dimension and fetch the ID with
43  ! nc_diag_chaninfo_write_def.)
44  integer(i_long) :: nchans_dimid
45 
46  ! # of times we needed to realloc chaninfo
47  ! also the multiplier factor for allocation (2^x)
48  integer(i_byte) :: alloc_multi
49 
50  ! Did we write anything out yet?
51  ! Definition writing lock and data writing lock
52  logical :: def_lock
53  logical :: data_lock
54 
55  ! Enable strict checking for bounds?
56  ! (Making sure that the sizes are consistent!)
57  ! If true, this makes inconsistency result in an error!
58  logical :: strict_check
59 
60  !-----------------------------------------------------------
61  ! Variable storage
62  !-----------------------------------------------------------
63 
64  ! Name array for each variable
65  ! Size: number of variables stored
66  character(len=100), dimension(:),allocatable :: names
67 
68  ! Type constants array for each variable
69  ! Size: number of variables stored
70  integer(i_byte), dimension(:),allocatable :: types
71 
72  ! Relative positioning for each variable - relative position
73  ! in groups of nchan within each type array. For instance,
74  ! if "asdf" has a relative value of 2, type of BYTE, and nchan
75  ! of 10, then variable "asdf" will start at 1 + [(2 - 1) * 10] = 11
76  ! within the byte storage array. Eqn: 1 + [(REL_VAL - 1) * nchan]
77  !
78  ! Size: number of variables stored
79  integer(i_long), dimension(:),allocatable :: var_rel_pos
80 
81  ! Current variable usage (which, for each element,
82  ! should be <= nchans)
83  ! Size: number of variables stored
84  integer(i_long), dimension(:),allocatable :: var_usage
85 
86  ! Variable IDs (for use with NetCDF API)
87  ! Size: number of variables stored
88  integer(i_long), dimension(:),allocatable :: var_ids
89 
90  ! Maximum string length - only used when the variable
91  ! definitions are locked.
92  ! Size: number of variables stored
93  integer(i_long), dimension(:), allocatable :: max_str_lens
94 
95  ! Relative indexes - for buffer flushing, keep track of the
96  ! relative indexes when we flush data. We store the
97  ! variable count here so that we can reference it when we
98  ! reset our variable counter to zero, allowing us to reuse
99  ! memory while still preserving data order!
100  !
101  ! Note that the relative index follows Fortran order, e.g. we
102  ! start at 1. If it's 1, there's 1 element already stored for
103  ! that variable. We add 1 to the rel_indexes value to make
104  ! things work, since we start 1 after the last stored value.
105  !
106  ! Size: number of variables stored
107  integer(i_long), dimension(:), allocatable :: rel_indexes
108 
109  !-----------------------------------------------------------
110  ! Type metadata storage
111  !-----------------------------------------------------------
112 
113  ! Type array variable usage count - number of variables
114  ! in each type array. For instance, if element 1 (ci_byte) has
115  ! a value of 3 here, it means it has 3 variables stored already.
116  ! (Hypothetically, if nchan = 10, then that particular type has
117  ! 30 stored values.
118  !
119  ! That means I can start creating vars at 1 + [(4-1) * 10] = 31.)
120  ! 1 2 3 4 5 6 7 8 9 10
121  ! 11 12 13 14 15 16 17 18 19 20
122  ! 21 22 23 24 25 26 27 28 29 30
123  ! 31
124  !
125  ! Size: number of types (currently 6)
126  integer(i_long), dimension(6) :: acount_v
127 
128  ! Total variables stored
129  integer(i_long) :: total = 0
130 
131  ! Array size for each type array
132  ! Size: number of types (currently 6)
133  integer(i_long), dimension(6) :: asize
134 
135  ! Array count for each type array - used with the internal
136  ! resizing tool
137  ! (This is basically the number of elements stored in ci_*)
138  ! Size: number of types (currently 6)
139  integer(i_long), dimension(6) :: acount
140 
141  ! Storage arrays for specific types
142  !
143  ! These store the actual data, and can be tracked using the
144  ! information and formula above!
145  !
146  ! Size: variable (dynamically (re)-allocated)
147  integer(i_byte), dimension(:),allocatable :: ci_byte
148  integer(i_short), dimension(:),allocatable :: ci_short
149  integer(i_long), dimension(:),allocatable :: ci_long
150  real(r_single), dimension(:),allocatable :: ci_rsingle
151  real(r_double), dimension(:),allocatable :: ci_rdouble
152  character(len=1000), dimension(:),allocatable :: ci_string
153  end type diag_chaninfo
154 
155  ! diag_metadata struct
156  ! This is a super type to store information for the diag metadata,
157  ! to be stored in the NetCDF4 file.
158  !
159  ! Storage works as follows:
160  ! = Add elements to the metadata structure through the subroutine
161  ! nc_diag_metadata().
162  ! -> The element name is first added to the names variable
163  ! within diag_metadata. Allocation (and/or reallocation)
164  ! occurs if necessary.
165  ! -> The type of the element is stored into the types
166  ! variable within diag_metadata, using the constants
167  ! available above. Allocation (and/or reallocation)
168  ! occurs if necessary.
169  ! -> If the type of the element is a vector, the vectored
170  ! logical is set to true. Otherwise, it's left as false.
171  ! -> If the type of the element is a vector, the
172  ! corresponding index vector is set to the number of
173  ! elements in the vector.
174  ! -> Then the array size and count are validated for the
175  ! specific type. Allocation (and/or reallocation) for the
176  ! specific type array occurs if necessary.
177  ! -> Once ready, we add the actual data into diag_metadata.
178  ! If the type of the element is a vector, we simply
179  ! append the elements to the vector, since we can now
180  ! keep track.
181  ! -> Finally, we increment any counters as necessary, and
182  ! we call it a day!
183  ! = When everything is done, nc_diag_write() is called. This
184  ! will trigger nc_diag_metadata_write(), which will do the
185  ! following:
186  ! -> Fetch the total number of attributes.
187  ! -> Iterate through the names, types, and logical vectored
188  ! variables, using the total number of attributes.
189  ! -> Based on the types and logical vectored variable,
190  ! fetch the actual data from the right spot.
191  ! -> Write said data using the NetCDF4 subroutines.
192  ! -> Increment our own counters to keep track of how much
193  ! we read, especially for the individual variables and
194  ! types.
195  ! -> Not as tedious as queueing the data!
196  !
197  ! Variables:
198  ! names - names of metadata information (attributes) to store.
199  ! This is a 1-D array of names - dimensions based on
200  ! the number of attributes stored.
201  ! types - types (specified as an integer constants located
202  ! above) for each attribute. This is a 1-D array of
203  ! integers - dimensions based on the number of
204  ! attributes stored.
205  ! vectored - whether the attribute stores a 1D vector or not.
206  ! This is a 1-D array of integers - dimensions based
207  ! on the number of attributes stored.
208  ! total - the total number of attributes in diag_metadata
209  ! asize - array size for each type. This is a 1-D array of
210  ! integers - dimensions based on the number of TYPES
211  ! available, including vectored types. In this case,
212  ! we have 6 single types, plus 5 "hidden" vectored
213  ! types (via m_***_vi), so the dimension is 11.
214  ! acount - array count for each type - this is the number of
215  ! elements already stored for each type, including
216  ! vectored types. The dimensions are the same as
217  ! asize - in this case, it's 11.
218  ! m_*** - data storage variables, single element array,
219  ! dimensions based on the number and type of
220  ! attributes stored. If I store one short, one float,
221  ! and one double from scratch, then m_short, m_float,
222  ! and m_double will have a length of 1 each. The rest
223  ! of the m_*** will be empty.
224  ! m_***_vi - length index storage for vectored data, dimensions
225  ! based on the number and type of vectored attributes
226  ! stored. If I store one short vector, one float
227  ! vector, and one double vector from scratch, then
228  ! m_short_vi, m_float_vi, and m_double_vi will have
229  ! a length of 1 vector each. The rest of the m_***_vi
230  ! will be empty. These are only populated when a
231  ! vector of data is added.
233  integer(i_long), dimension(:), allocatable :: index_arr
234  integer(i_long) :: icount
235  integer(i_long) :: isize
236  end type diag_md_iarr
237 
239  character(len=100), dimension(:), allocatable :: names
240  integer(i_byte), dimension(:), allocatable :: types
241  type(diag_md_iarr), dimension(:), allocatable :: stor_i_arr
242  integer(i_byte), dimension(:), allocatable :: alloc_sia_multi
243 
244  ! Maximum string length - only used when the variable
245  ! definitions are locked.
246  integer(i_long), dimension(:), allocatable :: max_str_lens
247 
248  ! Relative indexes - for buffer flushing, keep track of the
249  ! relative indexes when we flush data. We store the
250  ! variable count here so that we can reference it when we
251  ! reset our variable counter to zero, allowing us to reuse
252  ! memory while still preserving data order!
253  integer(i_long), dimension(:), allocatable :: rel_indexes
254 
255  ! Total variables
256  integer(i_long) :: total = 0
257  integer(i_long) :: prealloc_total = 0
258 
259  ! Array sizes
260  integer(i_long), dimension(6) :: asize
261  integer(i_long), dimension(6) :: acount
262 
263  ! # of times we needed to realloc simple metadata
264  ! also the multiplier factor for allocation (2^x)
265  integer(i_byte) :: alloc_s_multi
266 
267  ! # of times we needed to realloc metadata data storage
268  ! also the multiplier factor for allocation (2^x)
269  integer(i_byte), dimension(6) :: alloc_m_multi
270 
271  ! # of times we needed to realloc metadata INDEX data storage
272  ! also the multiplier factor for allocation (2^x)
273  integer(i_byte), dimension(6) :: alloc_mi_multi
274 
275  ! Did we write anything out yet?
276  logical :: def_lock
277  logical :: data_lock
278 
279  ! Strict checking for bounds?
280  ! (Making sure that the sizes are consistent!)
281  logical :: strict_check
282 
283  integer(i_byte), dimension(:),allocatable :: m_byte
284  integer(i_short), dimension(:),allocatable :: m_short
285  integer(i_long), dimension(:),allocatable :: m_long
286  real(r_single), dimension(:),allocatable :: m_rsingle
287  real(r_double), dimension(:),allocatable :: m_rdouble
288  character(len=1000), dimension(:),allocatable :: m_string
289 
290  integer(i_long), dimension(:), allocatable :: var_ids
291  end type diag_metadata
292 
293  ! diag_data2d struct
294  ! This is a super type to store information for the diag data2d,
295  ! to be stored in the NetCDF4 file.
296  !
297  ! Storage works as follows:
298  ! = Add elements to the data2d structure through the subroutine
299  ! nc_diag_data2d().
300  ! -> The element name is first added to the names variable
301  ! within diag_data2d. Allocation (and/or reallocation)
302  ! occurs if necessary.
303  ! -> The type of the element is stored into the types
304  ! variable within diag_data2d, using the constants
305  ! available above. Allocation (and/or reallocation)
306  ! occurs if necessary.
307  ! -> If the type of the element is a vector, the vectored
308  ! logical is set to true. Otherwise, it's left as false.
309  ! -> If the type of the element is a vector, the
310  ! corresponding index vector is set to the number of
311  ! elements in the vector.
312  ! -> Then the array size and count are validated for the
313  ! specific type. Allocation (and/or reallocation) for the
314  ! specific type array occurs if necessary.
315  ! -> Once ready, we add the actual data into diag_data2d.
316  ! If the type of the element is a vector, we simply
317  ! append the elements to the vector, since we can now
318  ! keep track.
319  ! -> Finally, we increment any counters as necessary, and
320  ! we call it a day!
321  ! = When everything is done, nc_diag_write() is called. This
322  ! will trigger nc_diag_data2d_write(), which will do the
323  ! following:
324  ! -> Fetch the total number of attributes.
325  ! -> Iterate through the names, types, and logical vectored
326  ! variables, using the total number of attributes.
327  ! -> Based on the types and logical vectored variable,
328  ! fetch the actual data from the right spot.
329  ! -> Write said data using the NetCDF4 subroutines.
330  ! -> Increment our own counters to keep track of how much
331  ! we read, especially for the individual variables and
332  ! types.
333  ! -> Not as tedious as queueing the data!
334  !
335  ! Variables:
336  ! names - names of data2d information (attributes) to store.
337  ! This is a 1-D array of names - dimensions based on
338  ! the number of attributes stored.
339  ! types - types (specified as an integer constants located
340  ! above) for each attribute. This is a 1-D array of
341  ! integers - dimensions based on the number of
342  ! attributes stored.
343  ! vectored - whether the attribute stores a 1D vector or not.
344  ! This is a 1-D array of integers - dimensions based
345  ! on the number of attributes stored.
346  ! total - the total number of attributes in diag_data2d
347  ! asize - array size for each type. This is a 1-D array of
348  ! integers - dimensions based on the number of TYPES
349  ! available, including vectored types. In this case,
350  ! we have 6 single types, plus 5 "hidden" vectored
351  ! types (via m_***_vi), so the dimension is 11.
352  ! acount - array count for each type - this is the number of
353  ! elements already stored for each type, including
354  ! vectored types. The dimensions are the same as
355  ! asize - in this case, it's 11.
356  ! m_*** - data storage variables, single element array,
357  ! dimensions based on the number and type of
358  ! attributes stored. If I store one short, one float,
359  ! and one double from scratch, then m_short, m_float,
360  ! and m_double will have a length of 1 each. The rest
361  ! of the m_*** will be empty.
362  ! m_***_vi - length index storage for vectored data, dimensions
363  ! based on the number and type of vectored attributes
364  ! stored. If I store one short vector, one float
365  ! vector, and one double vector from scratch, then
366  ! m_short_vi, m_float_vi, and m_double_vi will have
367  ! a length of 1 vector each. The rest of the m_***_vi
368  ! will be empty. These are only populated when a
369  ! vector of data is added.
371  integer(i_long), dimension(:), allocatable :: index_arr
372  integer(i_long), dimension(:), allocatable :: length_arr
373  integer(i_long) :: icount
374  integer(i_long) :: isize
375  end type diag_d2d_iarr
376 
378  character(len=100), dimension(:), allocatable :: names
379  integer(i_byte), dimension(:), allocatable :: types
380  type(diag_d2d_iarr),dimension(:), allocatable :: stor_i_arr
381  integer(i_byte), dimension(:), allocatable :: alloc_sia_multi
382 
383  ! Maximum string length - only used when the variable
384  ! definitions are locked.
385  integer(i_long), dimension(:), allocatable :: max_str_lens
386 
387  ! Maximum variable length - only used when the variable
388  ! definitions are locked.
389  integer(i_long), dimension(:), allocatable :: max_lens
390 
391  ! Relative indexes - for buffer flushing, keep track of the
392  ! relative indexes when we flush data. We store the
393  ! variable count here so that we can reference it when we
394  ! reset our variable counter to zero, allowing us to reuse
395  ! memory while still preserving data order!
396  integer(i_long), dimension(:), allocatable :: rel_indexes
397 
398  ! Total variables
399  integer(i_long) :: total = 0
400  integer(i_long) :: prealloc_total = 0
401 
402  ! Array sizes
403  integer(i_long), dimension(6) :: asize
404  integer(i_long), dimension(6) :: acount
405 
406  ! # of times we needed to realloc simple data2d
407  ! also the multiplier factor for allocation (2^x)
408  integer(i_byte) :: alloc_s_multi
409 
410  ! # of times we needed to realloc data2d data storage
411  ! also the multiplier factor for allocation (2^x)
412  integer(i_byte), dimension(6) :: alloc_m_multi
413 
414  ! # of times we needed to realloc data2d INDEX data storage
415  ! also the multiplier factor for allocation (2^x)
416  integer(i_byte), dimension(6) :: alloc_mi_multi
417 
418  ! Did we write anything out yet?
419  logical :: def_lock
420  logical :: data_lock
421 
422  ! Strict checking for bounds?
423  ! (Making sure that the sizes are consistent!)
424  logical :: strict_check
425 
426  integer(i_byte), dimension(:),allocatable :: m_byte
427  integer(i_short), dimension(:),allocatable :: m_short
428  integer(i_long), dimension(:),allocatable :: m_long
429  real(r_single), dimension(:),allocatable :: m_rsingle
430  real(r_double), dimension(:),allocatable :: m_rdouble
431  character(len=1000), dimension(:),allocatable :: m_string
432 
433  integer(i_long), dimension(:), allocatable :: var_dim_ids
434  integer(i_long), dimension(:), allocatable :: var_ids
435  end type diag_data2d
436 
437  ! Variable type - this stores and handles all of the variables,
438  ! and includes the variable storage type.
440  character(len=100), dimension(:), allocatable :: names
441  integer(i_byte), dimension(:), allocatable :: types
442  integer(i_long), dimension(:), allocatable :: var_ids
443 
444  integer(i_llong) :: total
445 
446  ! Global nobs dimension ID
447  integer(i_long) :: nobs_dim_id = -1
448  end type diag_varattr
449 end module ncdw_types
integer(i_long), parameter nlayer_multi_base
Definition: ncdw_types.F90:27
integer, parameter, public i_byte
Definition: ncd_kinds.F90:45
integer(i_byte), parameter nlayer_short
Definition: ncdw_types.F90:11
integer(i_long), parameter nlayer_fill_long
Definition: ncdw_types.F90:31
integer, parameter, public i_long
Definition: ncd_kinds.F90:47
integer(i_byte), parameter nlayer_fill_byte
Definition: ncdw_types.F90:29
integer(i_byte), parameter nlayer_double
Definition: ncdw_types.F90:14
integer(i_byte), parameter nlayer_string
Definition: ncdw_types.F90:15
integer(i_long), parameter nlayer_compression
Definition: ncdw_types.F90:21
integer(i_short), parameter nlayer_fill_short
Definition: ncdw_types.F90:30
integer, parameter, public i_short
Definition: ncd_kinds.F90:46
integer(i_byte), parameter nlayer_byte
Definition: ncdw_types.F90:10
character, parameter nlayer_fill_char
Definition: ncdw_types.F90:34
integer(i_short), parameter nlayer_default_ent
Definition: ncdw_types.F90:18
real(r_single), parameter nlayer_fill_float
Definition: ncdw_types.F90:32
integer, parameter, public r_double
Definition: ncd_kinds.F90:80
integer(i_long), parameter nlayer_chunking
Definition: ncdw_types.F90:24
integer, parameter, public r_single
Definition: ncd_kinds.F90:79
integer, parameter, public i_llong
Definition: ncd_kinds.F90:49
integer(i_byte), parameter nlayer_float
Definition: ncdw_types.F90:13
integer(i_byte), parameter nlayer_long
Definition: ncdw_types.F90:12
real(r_double), parameter nlayer_fill_double
Definition: ncdw_types.F90:33