FV3 Bundle
ncdw_ciresize.F90
Go to the documentation of this file.
1 ! nc_diag_write - NetCDF Layer Diag Writing Module
2 ! Copyright 2015 Albert Huang - SSAI/NASA for NASA GSFC GMAO (610.1).
3 !
4 ! Licensed under the Apache License, Version 2.0 (the "License");
5 ! you may not use this file except in compliance with the License.
6 ! You may obtain a copy of the License at
7 !
8 ! http://www.apache.org/licenses/LICENSE-2.0
9 !
10 ! Unless required by applicable law or agreed to in writing, software
11 ! distributed under the License is distributed on an "AS IS" BASIS,
12 ! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13 ! implied. See the License for the specific language governing
14 ! permissions and limitations under the License.
15 !
16 ! chaninfo variable data storage resizing module - ncdw_ciresize
17 !
19  ! Module that provides chaninfo variable data storage resizing.
20  !
21  ! This module has all of the subroutines needed to resize chaninfo
22  ! variable data storage. It includes resizing subroutines for all
23  ! variable data storage types, including:
24  ! integer(i_byte) for byte integer storage
25  ! integer(i_short) for short integer storage
26  ! integer(i_long) for long integer storage
27  ! real(r_single) for float storage
28  ! real(r_double) for double storage
29  ! character(len=*) for string storage
30  !
31  ! The subroutines here serve as "smart" wrappers for the real
32  ! reallocation subroutines in ncdw_realloc.
33  !
34  ! For each subroutine:
35  !
36  ! -> It first checks if the type-specific variable data storage
37  ! field (ci_*) has been allocated or not.
38  !
39  ! -> If it hasn't been allocated:
40  ! -> If the storage count is to be updated, it is set to the
41  ! specified number of entries.
42  ! -> The field is then allocated with the specified number of
43  ! entries, plus the default initial number of entries.
44  !
45  ! -> If it has been allocated:
46  ! -> If the storage count is to be updated, the number of fields
47  ! to allocate for are added to the count.
48  ! -> The (potentially updated) field storage count is checked
49  ! against the cached allocated size.
50  ! -> If the count is greater than or equal to the cached
51  ! allocated size, the proper reallocation subroutine from
52  ! nc_diag_realloc is called, the cached allocated size is
53  ! updated to the new size, and the allocation multiplier is
54  ! incremented.
55  ! -> Otherwise, nothing happens.
56  !
57 
58  ! Load our numerical types from kinds
59  ! Note that i_llong is not a type we store - it's just for keeping
60  ! track of numeric indexes. (Maybe this is too excessive...)
61  use ncd_kinds, only: i_byte, i_short, i_long, i_llong, r_single, &
62  r_double
63 
64  ! Load state variables! We just need to know:
65  ! diag_chaninfo_store - ...chaninfo variable information.
66  ! We pretty much do everything related to
67  ! chaninfo here, so we're using everything
68  ! inside this derived type! (Especially the
69  ! variable data storage fields, ci_*!)
71 
72  ! Load types! We need:
73  ! NLAYER_DEFAULT_ENT - default starting number of element entries.
74  ! This is for the initial allocation of
75  ! space for data storage arrays, e.g.
76  ! the ci_* data arrays within diag_chaninfo.
77  ! NLAYER_MULTI_BASE - the base number to use when exponentiating
78  ! to allocate or reallocate data storage
79  ! arrays.
81 
82  ! Load our fun reallocation subroutine - we need this to reallocate
83  ! within our "smart" chaninfo reallocation subroutines:
84  use ncdw_realloc, only: nc_diag_realloc
85 
86 #ifdef ENABLE_ACTION_MSGS
88 #endif
89 
90  implicit none
91 
92  contains
93  ! Make enough space in the internal variable data storage field
94  ! for byte integer storage.
95  !
96  ! This attempts to resize the internal variable data storage
97  ! field to accompany additional entries. If the size is already
98  ! big enough to fit the existing data plus the additional
99  ! entries, no actual memory reallocation will occur.
100  !
101  ! The storage count for the type is also updated, unless
102  ! otherwise optionally disabled via an optional argument.
103  !
104  ! Disabling the storage count update can be useful for
105  ! preallocation, where the preallocation can occur without
106  ! updating the count, since the count stores the amount of data
107  ! stored in the storage field. Since preallocation does not
108  ! store any data, the count updating should be disabled.
109  !
110  ! This is an internal subroutine, and is NOT meant to be called
111  ! outside of nc_diag_write. Calling this subroutine in your
112  ! program may result in unexpected behavior and/or data
113  ! corruption!
114  !
115  ! Args:
116  ! addl_num_entries (integer(i_llong)): the number of entries
117  ! to make enough space for.
118  ! update_acount_in (logical, optional): whether to update
119  ! the internal variable data storage count or not. If
120  ! not specified, the count will be updated.
121  !
122  ! Raises:
123  ! The following errors will trigger indirectly from other
124  ! subroutines called here:
125  !
126  ! If data reallocation fails, this will result in an error.
127  !
128  ! Other errors may result from invalid data storage, NetCDF
129  ! errors, or even a bug. See the called subroutines'
130  ! documentation for details.
131  !
132  subroutine nc_diag_chaninfo_resize_byte(addl_num_entries, update_acount_in)
133  integer(i_llong), intent(in) :: addl_num_entries
134  logical, intent(in), optional :: update_acount_in
135 
136  ! This is the Size Count index (sc_index) - we'll just set
137  ! this and then just change the variable we're altering
138  ! every time.
139  integer(i_long) :: sc_index
140 
141  logical :: update_acount
142 
143  ! Assume true by default
144  if (.NOT. present(update_acount_in)) then
145  update_acount = .true.
146  else
147  update_acount = update_acount_in
148  end if
149 
150  ! Here, we increment the count by the number of additional entries,
151  ! and the size by that amount as well.
152  !
153  ! If we didn't allocate yet, we simply set the count to the number of
154  ! initial entries, and then allocate that number + our default
155  ! initialization amount. Our initial size is that number + the initial
156  ! amount.
157 
158  ! NLAYER_BYTE is located at the first index, 1.
159  sc_index = 1
160 
161  ! Check if the variable data storage field is allocated
162  if (allocated(diag_chaninfo_store%ci_byte)) then
163  ! If necessary, update the variable data storage count
164  if (update_acount) diag_chaninfo_store%acount(sc_index) = diag_chaninfo_store%acount(sc_index) + addl_num_entries
165 
166  ! Check to see if we have enough memory space
167  if (diag_chaninfo_store%acount(sc_index) >= diag_chaninfo_store%asize(sc_index)) then
168 #ifdef ENABLE_ACTION_MSGS
169  if (nclayer_enable_action) then
170  call nclayer_actionm("nc_diag_chaninfo_resize_byte: doing reallocation!")
171  end if
172 #endif
173  ! Reallocate to grow the variable data storage array
174  call nc_diag_realloc(diag_chaninfo_store%ci_byte, int8(addl_num_entries + (nlayer_default_ent * (nlayer_multi_base ** diag_chaninfo_store%alloc_multi))))
175 
176  ! Update the variable storage size with the new
177  ! reallocated size
178  diag_chaninfo_store%asize(sc_index) = size(diag_chaninfo_store%ci_byte)
179 
180  ! Increment the allocation multiplier
181  diag_chaninfo_store%alloc_multi = diag_chaninfo_store%alloc_multi + 1
182  end if
183  else
184  ! If necessary, update the variable data storage count
185  if (update_acount) diag_chaninfo_store%acount(sc_index) = addl_num_entries
186 
187  ! Allocate the number of entries to add + default
188  ! initial size
189  allocate(diag_chaninfo_store%ci_byte(addl_num_entries + nlayer_default_ent))
190 
191  ! Set variable storage size to same amount
192  diag_chaninfo_store%asize(sc_index) = addl_num_entries + nlayer_default_ent
193  end if
194  end subroutine nc_diag_chaninfo_resize_byte
195 
196  ! Make enough space in the internal variable data storage field
197  ! for short integer storage.
198  !
199  ! This attempts to resize the internal variable data storage
200  ! field to accompany additional entries. If the size is already
201  ! big enough to fit the existing data plus the additional
202  ! entries, no actual memory reallocation will occur.
203  !
204  ! The storage count for the type is also updated, unless
205  ! otherwise optionally disabled via an optional argument.
206  !
207  ! Disabling the storage count update can be useful for
208  ! preallocation, where the preallocation can occur without
209  ! updating the count, since the count stores the amount of data
210  ! stored in the storage field. Since preallocation does not
211  ! store any data, the count updating should be disabled.
212  !
213  ! This is an internal subroutine, and is NOT meant to be called
214  ! outside of nc_diag_write. Calling this subroutine in your
215  ! program may result in unexpected behavior and/or data
216  ! corruption!
217  !
218  ! Args:
219  ! addl_num_entries (integer(i_llong)): the number of entries
220  ! to make enough space for.
221  ! update_acount_in (logical, optional): whether to update
222  ! the internal variable data storage count or not. If
223  ! not specified, the count will be updated.
224  !
225  ! Raises:
226  ! The following errors will trigger indirectly from other
227  ! subroutines called here:
228  !
229  ! If data reallocation fails, this will result in an error.
230  !
231  ! Other errors may result from invalid data storage, NetCDF
232  ! errors, or even a bug. See the called subroutines'
233  ! documentation for details.
234  !
235  subroutine nc_diag_chaninfo_resize_short(addl_num_entries, update_acount_in)
236  integer(i_llong), intent(in) :: addl_num_entries
237  logical, intent(in), optional :: update_acount_in
238 
239  ! This is the Size Count index (sc_index) - we'll just set
240  ! this and then just change the variable we're altering
241  ! every time.
242  integer(i_long) :: sc_index
243 
244  logical :: update_acount
245 
246  ! Assume true by default
247  if (.NOT. present(update_acount_in)) then
248  update_acount = .true.
249  else
250  update_acount = update_acount_in
251  end if
252 
253  ! Here, we increment the count by the number of additional entries,
254  ! and the size by that amount as well.
255  !
256  ! If we didn't allocate yet, we simply set the count to the number of
257  ! initial entries, and then allocate that number + our default
258  ! initialization amount. Our initial size is that number + the initial
259  ! amount.
260 
261  ! NLAYER_SHORT is located at the second index, 2.
262  sc_index = 2
263 
264  ! Check if the variable data storage field is allocated
265  if (allocated(diag_chaninfo_store%ci_short)) then
266  ! If necessary, update the variable data storage count
267  if (update_acount) diag_chaninfo_store%acount(sc_index) = diag_chaninfo_store%acount(sc_index) + addl_num_entries
268 
269  ! Check to see if we have enough memory space
270  if (diag_chaninfo_store%acount(sc_index) >= diag_chaninfo_store%asize(sc_index)) then
271 #ifdef ENABLE_ACTION_MSGS
272  if (nclayer_enable_action) then
273  call nclayer_actionm("nc_diag_chaninfo_resize_short: doing reallocation!")
274  end if
275 #endif
276  ! Reallocate to grow the variable data storage array
277  call nc_diag_realloc(diag_chaninfo_store%ci_short, int8(addl_num_entries + (nlayer_default_ent * (nlayer_multi_base ** diag_chaninfo_store%alloc_multi))))
278 
279  ! Update the variable storage size with the new
280  ! reallocated size
281  diag_chaninfo_store%asize(sc_index) = size(diag_chaninfo_store%ci_short)
282 
283  ! Increment the allocation multiplier
284  diag_chaninfo_store%alloc_multi = diag_chaninfo_store%alloc_multi + 1
285  end if
286  else
287  ! If necessary, update the variable data storage count
288  if (update_acount) diag_chaninfo_store%acount(sc_index) = addl_num_entries
289 
290  ! Allocate the number of entries to add + default
291  ! initial size
292  allocate(diag_chaninfo_store%ci_short(addl_num_entries + nlayer_default_ent))
293 
294  ! Set variable storage size to same amount
295  diag_chaninfo_store%asize(sc_index) = addl_num_entries + nlayer_default_ent
296  end if
297  end subroutine nc_diag_chaninfo_resize_short
298 
299  ! Make enough space in the internal variable data storage field
300  ! for long integer storage.
301  !
302  ! This attempts to resize the internal variable data storage
303  ! field to accompany additional entries. If the size is already
304  ! big enough to fit the existing data plus the additional
305  ! entries, no actual memory reallocation will occur.
306  !
307  ! The storage count for the type is also updated, unless
308  ! otherwise optionally disabled via an optional argument.
309  !
310  ! Disabling the storage count update can be useful for
311  ! preallocation, where the preallocation can occur without
312  ! updating the count, since the count stores the amount of data
313  ! stored in the storage field. Since preallocation does not
314  ! store any data, the count updating should be disabled.
315  !
316  ! This is an internal subroutine, and is NOT meant to be called
317  ! outside of nc_diag_write. Calling this subroutine in your
318  ! program may result in unexpected behavior and/or data
319  ! corruption!
320  !
321  ! Args:
322  ! addl_num_entries (integer(i_llong)): the number of entries
323  ! to make enough space for.
324  ! update_acount_in (logical, optional): whether to update
325  ! the internal variable data storage count or not. If
326  ! not specified, the count will be updated.
327  !
328  ! Raises:
329  ! The following errors will trigger indirectly from other
330  ! subroutines called here:
331  !
332  ! If data reallocation fails, this will result in an error.
333  !
334  ! Other errors may result from invalid data storage, NetCDF
335  ! errors, or even a bug. See the called subroutines'
336  ! documentation for details.
337  !
338  subroutine nc_diag_chaninfo_resize_long(addl_num_entries, update_acount_in)
339  integer(i_llong), intent(in) :: addl_num_entries
340  logical, intent(in), optional :: update_acount_in
341 
342  ! Did we realloc at all?
343  !logical :: chaninfo_realloc
344 
345  ! This is the Size Count index (sc_index) - we'll just set
346  ! this and then just change the variable we're altering
347  ! every time.
348  integer(i_long) :: sc_index
349 
350  logical :: update_acount
351 
352  ! Assume true by default
353  if (.NOT. present(update_acount_in)) then
354  update_acount = .true.
355  else
356  update_acount = update_acount_in
357  end if
358 
359  ! Here, we increment the count by the number of additional entries,
360  ! and the size by that amount as well.
361  !
362  ! If we didn't allocate yet, we simply set the count to the number of
363  ! initial entries, and then allocate that number + our default
364  ! initialization amount. Our initial size is that number + the initial
365  ! amount.
366 
367  ! NLAYER_LONG is located at the third index, 3.
368  sc_index = 3
369 
370  ! Check if the variable data storage field is allocated
371  if (allocated(diag_chaninfo_store%ci_long)) then
372  ! If necessary, update the variable data storage count
373  if (update_acount) diag_chaninfo_store%acount(sc_index) = diag_chaninfo_store%acount(sc_index) + addl_num_entries
374 
375 
376  ! Check to see if we have enough memory space
377  if (diag_chaninfo_store%acount(sc_index) >= diag_chaninfo_store%asize(sc_index)) then
378 #ifdef _DEBUG_MEM_
379  print *, "realloc needed for chaninfo long!"
380  write (*, "(A, I0, A, I0, A)") "(size needed / size available: ", diag_chaninfo_store%acount(sc_index), " / ", diag_chaninfo_store%asize(sc_index), ")"
381 #endif
382 #ifdef ENABLE_ACTION_MSGS
383  if (nclayer_enable_action) then
384  call nclayer_actionm("nc_diag_chaninfo_resize_long: doing reallocation!")
385  end if
386 #endif
387  ! Reallocate to grow the variable data storage array
388  call nc_diag_realloc(diag_chaninfo_store%ci_long, int8(addl_num_entries + (nlayer_default_ent * (nlayer_multi_base ** diag_chaninfo_store%alloc_multi))))
389 
390  ! Update the variable storage size with the new
391  ! reallocated size
392  diag_chaninfo_store%asize(sc_index) = size(diag_chaninfo_store%ci_long)
393 
394  ! Increment the allocation multiplier
395  diag_chaninfo_store%alloc_multi = diag_chaninfo_store%alloc_multi + 1
396  end if
397  else
398  ! If necessary, update the variable data storage count
399  if (update_acount) diag_chaninfo_store%acount(sc_index) = addl_num_entries
400 
401  ! Allocate the number of entries to add + default
402  ! initial size
403  allocate(diag_chaninfo_store%ci_long(addl_num_entries + nlayer_default_ent))
404 
405  ! Set variable storage size to same amount
406  diag_chaninfo_store%asize(sc_index) = addl_num_entries + nlayer_default_ent
407  end if
408  end subroutine nc_diag_chaninfo_resize_long
409 
410  ! Make enough space in the internal variable data storage field
411  ! for float storage.
412  !
413  ! This attempts to resize the internal variable data storage
414  ! field to accompany additional entries. If the size is already
415  ! big enough to fit the existing data plus the additional
416  ! entries, no actual memory reallocation will occur.
417  !
418  ! The storage count for the type is also updated, unless
419  ! otherwise optionally disabled via an optional argument.
420  !
421  ! Disabling the storage count update can be useful for
422  ! preallocation, where the preallocation can occur without
423  ! updating the count, since the count stores the amount of data
424  ! stored in the storage field. Since preallocation does not
425  ! store any data, the count updating should be disabled.
426  !
427  ! This is an internal subroutine, and is NOT meant to be called
428  ! outside of nc_diag_write. Calling this subroutine in your
429  ! program may result in unexpected behavior and/or data
430  ! corruption!
431  !
432  ! Args:
433  ! addl_num_entries (integer(i_llong)): the number of entries
434  ! to make enough space for.
435  ! update_acount_in (logical, optional): whether to update
436  ! the internal variable data storage count or not. If
437  ! not specified, the count will be updated.
438  !
439  ! Raises:
440  ! The following errors will trigger indirectly from other
441  ! subroutines called here:
442  !
443  ! If data reallocation fails, this will result in an error.
444  !
445  ! Other errors may result from invalid data storage, NetCDF
446  ! errors, or even a bug. See the called subroutines'
447  ! documentation for details.
448  !
449  subroutine nc_diag_chaninfo_resize_rsingle(addl_num_entries, update_acount_in)
450  integer(i_llong), intent(in) :: addl_num_entries
451  logical, intent(in), optional :: update_acount_in
452 
453  ! This is the Size Count index (sc_index) - we'll just set
454  ! this and then just change the variable we're altering
455  ! every time.
456  integer(i_long) :: sc_index
457 
458  logical :: update_acount
459 
460  ! Assume true by default
461  if (.NOT. present(update_acount_in)) then
462  update_acount = .true.
463  else
464  update_acount = update_acount_in
465  end if
466 
467  ! Here, we increment the count by the number of additional entries,
468  ! and the size by that amount as well.
469  !
470  ! If we didn't allocate yet, we simply set the count to the number of
471  ! initial entries, and then allocate that number + our default
472  ! initialization amount. Our initial size is that number + the initial
473  ! amount.
474 
475  ! NLAYER_FLOAT is located at the fourth index, 4.
476  sc_index = 4
477 
478  ! Check if the variable data storage field is allocated
479  if (allocated(diag_chaninfo_store%ci_rsingle)) then
480  ! If necessary, update the variable data storage count
481  if (update_acount) diag_chaninfo_store%acount(sc_index) = diag_chaninfo_store%acount(sc_index) + addl_num_entries
482 
483  ! Check to see if we have enough memory space
484  if (diag_chaninfo_store%acount(sc_index) >= diag_chaninfo_store%asize(sc_index)) then
485 #ifdef ENABLE_ACTION_MSGS
486  if (nclayer_enable_action) then
487  call nclayer_actionm("nc_diag_chaninfo_resize_rsingle: doing reallocation!")
488  end if
489 #endif
490  ! Reallocate to grow the variable data storage array
491  call nc_diag_realloc(diag_chaninfo_store%ci_rsingle, int8(addl_num_entries + (nlayer_default_ent * (nlayer_multi_base ** diag_chaninfo_store%alloc_multi))))
492 
493  ! Update the variable storage size with the new
494  ! reallocated size
495  diag_chaninfo_store%asize(sc_index) = size(diag_chaninfo_store%ci_rsingle)
496 
497  ! Increment the allocation multiplier
498  diag_chaninfo_store%alloc_multi = diag_chaninfo_store%alloc_multi + 1
499  end if
500  else
501  ! If necessary, update the variable data storage count
502  if (update_acount) diag_chaninfo_store%acount(sc_index) = addl_num_entries
503 
504  ! Allocate the number of entries to add + default
505  ! initial size
506  allocate(diag_chaninfo_store%ci_rsingle(addl_num_entries + nlayer_default_ent))
507 
508  ! Set variable storage size to same amount
509  diag_chaninfo_store%asize(sc_index) = addl_num_entries + nlayer_default_ent
510  end if
511  end subroutine nc_diag_chaninfo_resize_rsingle
512 
513  ! Make enough space in the internal variable data storage field
514  ! for double storage.
515  !
516  ! This attempts to resize the internal variable data storage
517  ! field to accompany additional entries. If the size is already
518  ! big enough to fit the existing data plus the additional
519  ! entries, no actual memory reallocation will occur.
520  !
521  ! The storage count for the type is also updated, unless
522  ! otherwise optionally disabled via an optional argument.
523  !
524  ! Disabling the storage count update can be useful for
525  ! preallocation, where the preallocation can occur without
526  ! updating the count, since the count stores the amount of data
527  ! stored in the storage field. Since preallocation does not
528  ! store any data, the count updating should be disabled.
529  !
530  ! This is an internal subroutine, and is NOT meant to be called
531  ! outside of nc_diag_write. Calling this subroutine in your
532  ! program may result in unexpected behavior and/or data
533  ! corruption!
534  !
535  ! Args:
536  ! addl_num_entries (integer(i_llong)): the number of entries
537  ! to make enough space for.
538  ! update_acount_in (logical, optional): whether to update
539  ! the internal variable data storage count or not. If
540  ! not specified, the count will be updated.
541  !
542  ! Raises:
543  ! The following errors will trigger indirectly from other
544  ! subroutines called here:
545  !
546  ! If data reallocation fails, this will result in an error.
547  !
548  ! Other errors may result from invalid data storage, NetCDF
549  ! errors, or even a bug. See the called subroutines'
550  ! documentation for details.
551  !
552  subroutine nc_diag_chaninfo_resize_rdouble(addl_num_entries, update_acount_in)
553  integer(i_llong), intent(in) :: addl_num_entries
554  logical, intent(in), optional :: update_acount_in
555 
556  ! This is the Size Count index (sc_index) - we'll just set
557  ! this and then just change the variable we're altering
558  ! every time.
559  integer(i_long) :: sc_index
560 
561  logical :: update_acount
562 
563  ! Assume true by default
564  if (.NOT. present(update_acount_in)) then
565  update_acount = .true.
566  else
567  update_acount = update_acount_in
568  end if
569 
570  ! Here, we increment the count by the number of additional entries,
571  ! and the size by that amount as well.
572  !
573  ! If we didn't allocate yet, we simply set the count to the number of
574  ! initial entries, and then allocate that number + our default
575  ! initialization amount. Our initial size is that number + the initial
576  ! amount.
577 
578  ! NLAYER_DOUBLE is located at the fifth index, 5.
579  sc_index = 5
580 
581  ! Check if the variable data storage field is allocated
582  if (allocated(diag_chaninfo_store%ci_rdouble)) then
583  ! If necessary, update the variable data storage count
584  if (update_acount) diag_chaninfo_store%acount(sc_index) = diag_chaninfo_store%acount(sc_index) + addl_num_entries
585 
586  ! Check to see if we have enough memory space
587  if (diag_chaninfo_store%acount(sc_index) >= diag_chaninfo_store%asize(sc_index)) then
588 #ifdef ENABLE_ACTION_MSGS
589  if (nclayer_enable_action) then
590  call nclayer_actionm("nc_diag_chaninfo_resize_rdouble: doing reallocation!")
591  end if
592 #endif
593  ! Reallocate to grow the variable data storage array
594  call nc_diag_realloc(diag_chaninfo_store%ci_rdouble, int8(addl_num_entries + (nlayer_default_ent * (nlayer_multi_base ** diag_chaninfo_store%alloc_multi))))
595 
596  ! Update the variable storage size with the new
597  ! reallocated size
598  diag_chaninfo_store%asize(sc_index) = size(diag_chaninfo_store%ci_rdouble)
599 
600  ! Increment the allocation multiplier
601  diag_chaninfo_store%alloc_multi = diag_chaninfo_store%alloc_multi + 1
602  end if
603  else
604  ! If necessary, update the variable data storage count
605  if (update_acount) diag_chaninfo_store%acount(sc_index) = addl_num_entries
606 
607  ! Allocate the number of entries to add + default
608  ! initial size
609  allocate(diag_chaninfo_store%ci_rdouble(addl_num_entries + nlayer_default_ent))
610 
611  ! Set variable storage size to same amount
612  diag_chaninfo_store%asize(sc_index) = addl_num_entries + nlayer_default_ent
613  end if
614  end subroutine nc_diag_chaninfo_resize_rdouble
615 
616  ! Make enough space in the internal variable data storage field
617  ! for string storage.
618  !
619  ! This attempts to resize the internal variable data storage
620  ! field to accompany additional entries. If the size is already
621  ! big enough to fit the existing data plus the additional
622  ! entries, no actual memory reallocation will occur.
623  !
624  ! The storage count for the type is also updated, unless
625  ! otherwise optionally disabled via an optional argument.
626  !
627  ! Disabling the storage count update can be useful for
628  ! preallocation, where the preallocation can occur without
629  ! updating the count, since the count stores the amount of data
630  ! stored in the storage field. Since preallocation does not
631  ! store any data, the count updating should be disabled.
632  !
633  ! This is an internal subroutine, and is NOT meant to be called
634  ! outside of nc_diag_write. Calling this subroutine in your
635  ! program may result in unexpected behavior and/or data
636  ! corruption!
637  !
638  ! Args:
639  ! addl_num_entries (integer(i_llong)): the number of entries
640  ! to make enough space for.
641  ! update_acount_in (logical, optional): whether to update
642  ! the internal variable data storage count or not. If
643  ! not specified, the count will be updated.
644  !
645  ! Raises:
646  ! The following errors will trigger indirectly from other
647  ! subroutines called here:
648  !
649  ! If data reallocation fails, this will result in an error.
650  !
651  ! Other errors may result from invalid data storage, NetCDF
652  ! errors, or even a bug. See the called subroutines'
653  ! documentation for details.
654  !
655  subroutine nc_diag_chaninfo_resize_string(addl_num_entries, update_acount_in)
656  integer(i_llong), intent(in) :: addl_num_entries
657  logical, intent(in), optional :: update_acount_in
658 
659  ! This is the Size Count index (sc_index) - we'll just set
660  ! this and then just change the variable we're altering
661  ! every time.
662  integer(i_long) :: sc_index
663 
664  logical :: update_acount
665 
666  ! Assume true by default
667  if (.NOT. present(update_acount_in)) then
668  update_acount = .true.
669  else
670  update_acount = update_acount_in
671  end if
672 
673  ! Here, we increment the count by the number of additional entries,
674  ! and the size by that amount as well.
675  !
676  ! If we didn't allocate yet, we simply set the count to the number of
677  ! initial entries, and then allocate that number + our default
678  ! initialization amount. Our initial size is that number + the initial
679  ! amount.
680 
681  ! NLAYER_STRING is located at the sixth index, 6.
682  sc_index = 6
683 
684  ! Check if the variable data storage field is allocated
685  if (allocated(diag_chaninfo_store%ci_string)) then
686  ! If necessary, update the variable data storage count
687  if (update_acount) diag_chaninfo_store%acount(sc_index) = diag_chaninfo_store%acount(sc_index) + addl_num_entries
688 
689  ! Check to see if we have enough memory space
690  if (diag_chaninfo_store%acount(sc_index) >= diag_chaninfo_store%asize(sc_index)) then
691 #ifdef ENABLE_ACTION_MSGS
692  if (nclayer_enable_action) then
693  call nclayer_actionm("nc_diag_chaninfo_resize_string: doing reallocation!")
694  end if
695 #endif
696  ! Reallocate to grow the variable data storage array
697  call nc_diag_realloc(diag_chaninfo_store%ci_string, int8(addl_num_entries + (nlayer_default_ent * (nlayer_multi_base ** diag_chaninfo_store%alloc_multi))))
698 
699  ! Update the variable storage size with the new
700  ! reallocated size
701  diag_chaninfo_store%asize(sc_index) = size(diag_chaninfo_store%ci_string)
702 
703  ! Increment the allocation multiplier
704  diag_chaninfo_store%alloc_multi = diag_chaninfo_store%alloc_multi + 1
705  end if
706  else
707  ! If necessary, update the variable data storage count
708  if (update_acount) diag_chaninfo_store%acount(sc_index) = addl_num_entries
709 
710  ! Allocate the number of entries to add + default
711  ! initial size
712  allocate(diag_chaninfo_store%ci_string(addl_num_entries + nlayer_default_ent))
713 
714  ! Set variable storage size to same amount
715  diag_chaninfo_store%asize(sc_index) = addl_num_entries + nlayer_default_ent
716  end if
717  end subroutine nc_diag_chaninfo_resize_string
718 end module ncdw_ciresize
subroutine nc_diag_chaninfo_resize_string(addl_num_entries, update_acount_in)
type(diag_chaninfo), allocatable diag_chaninfo_store
Definition: ncdw_state.f90:16
integer(i_long), parameter nlayer_multi_base
Definition: ncdw_types.F90:27
subroutine nc_diag_chaninfo_resize_short(addl_num_entries, update_acount_in)
integer, parameter, public i_byte
Definition: ncd_kinds.F90:45
integer, parameter, public i_long
Definition: ncd_kinds.F90:47
logical nclayer_enable_action
Definition: ncdw_climsg.F90:70
subroutine nc_diag_chaninfo_resize_byte(addl_num_entries, update_acount_in)
subroutine nc_diag_chaninfo_resize_long(addl_num_entries, update_acount_in)
subroutine nc_diag_chaninfo_resize_rsingle(addl_num_entries, update_acount_in)
integer, parameter, public i_short
Definition: ncd_kinds.F90:46
integer(i_short), parameter nlayer_default_ent
Definition: ncdw_types.F90:18
subroutine nc_diag_chaninfo_resize_rdouble(addl_num_entries, update_acount_in)
integer, parameter, public r_double
Definition: ncd_kinds.F90:80
integer, parameter, public r_single
Definition: ncd_kinds.F90:79
integer, parameter, public i_llong
Definition: ncd_kinds.F90:49
subroutine nclayer_actionm(act)