25 module fms_netcdf_domain_io_mod
37 integer,
parameter :: no_domain_decomposed_dimension = 0
38 integer,
parameter,
public :: max_num_domain_decomposed_dims = 10
39 integer,
parameter :: variable_not_found = 0
40 integer,
parameter :: default_domain_position = center
41 character(len=16),
parameter :: domain_pos_att =
"domain_position"
42 character(len=16),
parameter :: domain_axis_att_name =
"domain_axis"
43 character(len=16),
parameter :: x =
"x"
44 character(len=16),
parameter :: y =
"y"
51 character(len=nf90_max_name) :: varname
68 character(len=FMS_PATH_LEN) :: non_mangled_path
69 logical :: adjust_indices
121 character(len=*),
intent(in) :: name_
123 integer,
intent(in) :: size_
128 index_ = variable_not_found
141 character(len=*),
intent(in) :: name_
142 integer,
intent(in) :: position_
144 integer,
intent(inout) :: size_
150 call error(
"variable "//trim(name_)//
" already registered.")
154 if (size_ .gt.
size(array))
then
155 call error(
"number of domain decomposed variables exceeds limit.")
157 call string_copy(array(size_)%varname, name_)
158 array(size_)%pos = position_
167 character(len=*),
intent(in) :: name_
169 integer,
intent(in) :: size_
173 if (dpos .ne. variable_not_found)
then
174 dpos = array(dpos)%pos
188 character(len=*),
intent(in) :: variable_name
189 character(len=*),
intent(in) :: xory
192 logical,
intent(in),
optional :: broadcast
200 character(len=nf90_max_name),
dimension(:),
allocatable :: dim_names
205 index_ = no_domain_decomposed_dimension
206 if (fileobj%is_root)
then
208 allocate(dim_names(ndims))
218 call error(
"unrecognized xory flag value.")
220 do i = 1,
size(dim_names)
226 deallocate(dim_names)
228 if (
present(broadcast))
then
229 if (.not. broadcast)
then
233 call mpp_broadcast(index_, fileobj%io_root, pelist=fileobj%pelist)
240 xindex, yindex, xpos, ypos) &
241 result(is_decomposed)
244 character(len=*),
intent(in) :: variable_name
245 logical,
intent(in),
optional :: broadcast
250 integer,
intent(out),
optional :: xindex
252 integer,
intent(out),
optional :: yindex
254 integer,
intent(out),
optional :: xpos
255 integer,
intent(out),
optional :: ypos
256 logical :: is_decomposed
258 integer,
dimension(2) :: indices
260 character(len=nf90_max_name),
dimension(:),
allocatable :: dim_names
263 if (
present(xindex))
then
267 if (
present(yindex))
then
270 is_decomposed = (indices(1) .ne. no_domain_decomposed_dimension) .and. &
271 (indices(2) .ne. no_domain_decomposed_dimension)
272 if (is_decomposed)
then
273 if (.not.
present(xpos) .and. .not.
present(ypos))
then
277 allocate(dim_names(ndims))
280 if (
present(xpos))
then
283 if (
present(ypos))
then
286 deallocate(dim_names)
288 if (
present(xpos))
then
291 if (
present(ypos))
then
301 result(is_registered)
304 character(len=*),
intent(in) :: dimension_name
307 logical :: is_registered
311 is_registered = .false.
313 if (dpos .ne. variable_not_found)
then
314 is_registered = .true.
317 if (dpos .ne. variable_not_found) is_registered = .true.
325 function open_domain_file(fileobj, path, mode, domain, nc_format, is_restart, dont_add_res_to_filename) &
329 character(len=*),
intent(in) :: path
330 character(len=*),
intent(in) :: mode
333 type(
domain2d),
intent(in) :: domain
334 character(len=*),
intent(in),
optional :: nc_format
340 logical,
intent(in),
optional :: is_restart
343 logical,
intent(in),
optional :: dont_add_res_to_filename
347 integer,
dimension(2) :: io_layout
348 integer,
dimension(1) :: tile_id
349 character(len=FMS_PATH_LEN) :: combined_filepath
350 type(
domain2d),
pointer :: io_domain
351 character(len=FMS_PATH_LEN) :: distributed_filepath
352 integer :: pelist_size
353 integer,
dimension(:),
allocatable :: pelist
366 call string_copy(combined_filepath, path)
371 if (.not.
associated(io_domain))
then
372 call error(
"The domain associated with the file:"//trim(path)//
" does not have an io_domain.")
374 if (io_layout(1)*io_layout(2) .gt. 1)
then
378 call string_copy(distributed_filepath, combined_filepath)
383 allocate(pelist(pelist_size))
385 fileobj%adjust_indices = .true.
388 success =
netcdf_file_open(fileobj, distributed_filepath, mode, nc_format, pelist, &
389 is_restart, dont_add_res_to_filename)
392 if (.not.
string_compare(distributed_filepath, combined_filepath))
then
393 success2 =
netcdf_file_open(fileobj2, combined_filepath, mode, nc_format, pelist, &
394 is_restart, dont_add_res_to_filename)
396 call error(
"The domain decomposed file:"//trim(path)// &
397 &
" contains both combined (*.nc) and distributed files (*.nc.XXXX).")
401 success =
netcdf_file_open(fileobj, combined_filepath, mode, nc_format, pelist, &
402 is_restart, dont_add_res_to_filename)
404 if (success .and. (io_layout(1)*io_layout(2) .gt. 1)) fileobj%adjust_indices = .false.
407 if (.not. success)
then
413 call string_copy(fileobj%non_mangled_path, path)
414 fileobj%domain = domain
415 allocate(fileobj%xdims(max_num_domain_decomposed_dims))
417 allocate(fileobj%ydims(max_num_domain_decomposed_dims))
419 call string_copy(fileobj%non_mangled_path, path)
434 deallocate(fileobj%xdims)
436 deallocate(fileobj%ydims)
445 character(len=*),
intent(in) :: dim_name
446 character(len=*),
intent(in) :: xory
450 integer,
intent(in),
optional :: domain_position
453 type(
domain2d),
pointer :: io_domain
454 integer :: domain_size
457 dpos = default_domain_position
459 dpos = domain_position
463 if (dpos .ne. center .and. dpos .ne. east)
then
464 call error(
"Only domain_position=center or domain_position=EAST is supported for x dimensions."// &
465 &
" Fix your register_axis call for file:"&
466 &//trim(fileobj%path)//
" and dimension:"//trim(dim_name))
471 if (dpos .ne. center .and. dpos .ne. north)
then
472 call error(
"Only domain_position=center or domain_position=NORTH is supported for y dimensions."// &
473 &
" Fix your register_axis call for file:"&
474 &//trim(fileobj%path)//
" and dimension:"//trim(dim_name))
479 call error(
"The register_axis call for file:"//trim(fileobj%path)//
" and dimension:"//trim(dim_name)// &
480 &
" has an unrecognized xory flag value:"&
481 &//trim(xory)//
" only 'x' and 'y' are allowed.")
483 if (fileobj%is_readonly .or. (fileobj%mode_is_append .and.
dimension_exists(fileobj, dim_name)))
then
485 if (dim_size .lt. domain_size)
then
486 call error(
"dimension "//trim(dim_name)//
" in the file "//trim(fileobj%path)//
" is smaller than the size of" &
487 //
" the associated domain "//trim(xory)//
" axis.")
501 character(len=*),
intent(in) :: variable_name
503 type(
domain2d),
pointer :: io_domain
509 integer,
dimension(2) :: io_layout
514 if (io_layout(1) .eq. 1 .and. io_layout(2) .eq. 1)
return
518 if (dpos .ne. variable_not_found)
then
519 dpos = fileobj%xdims(dpos)%pos
526 if (dpos .ne. variable_not_found)
then
527 dpos = fileobj%ydims(dpos)%pos
541 character(len=*),
intent(in) :: variable_name
542 character(len=*),
intent(in) :: variable_type
545 character(len=*),
dimension(:),
intent(in),
optional :: dimensions
546 integer,
intent(in),
optional :: chunksizes(:)
548 if (.not. fileobj%is_readonly)
then
550 if (
present(dimensions))
then
551 if (
size(dimensions) .eq. 1)
then
564 integer,
intent(in),
optional :: unlim_dim_level
567 character(len=32) :: chksum
568 logical :: is_decomposed
570 if (.not. fileobj%is_restart)
then
571 call error(
"file "//trim(fileobj%path)// &
572 &
" is not a restart file. You must set is_restart=.true. in your open_file call.")
576 do i = 1, fileobj%num_restart_vars
577 if (
associated(fileobj%restart_vars(i)%data2d))
then
579 fileobj%restart_vars(i)%data2d, is_decomposed)
580 if (is_decomposed)
then
582 "checksum", chksum(1:len(chksum)), str_len=len(chksum))
584 elseif (
associated(fileobj%restart_vars(i)%data3d))
then
586 fileobj%restart_vars(i)%data3d, is_decomposed)
587 if (is_decomposed)
then
589 "checksum", chksum(1:len(chksum)), str_len=len(chksum))
591 elseif (
associated(fileobj%restart_vars(i)%data4d))
then
593 fileobj%restart_vars(i)%data4d, is_decomposed)
594 if (is_decomposed)
then
596 "checksum", chksum(1:len(chksum)), str_len=len(chksum))
602 do i = 1, fileobj%num_restart_vars
603 if (
associated(fileobj%restart_vars(i)%data0d))
then
605 fileobj%restart_vars(i)%data0d, unlim_dim_level=unlim_dim_level)
606 elseif (
associated(fileobj%restart_vars(i)%data1d))
then
608 fileobj%restart_vars(i)%data1d, unlim_dim_level=unlim_dim_level)
609 elseif (
associated(fileobj%restart_vars(i)%data2d))
then
611 fileobj%restart_vars(i)%data2d, unlim_dim_level=unlim_dim_level)
612 elseif (
associated(fileobj%restart_vars(i)%data3d))
then
614 fileobj%restart_vars(i)%data3d, unlim_dim_level=unlim_dim_level)
615 elseif (
associated(fileobj%restart_vars(i)%data4d))
then
617 fileobj%restart_vars(i)%data4d, unlim_dim_level=unlim_dim_level)
619 call error(
"This routine only accepts data that is scalar, 1d 2d 3d or 4d."//&
620 " The data sent in has an unsupported dimensionality")
632 integer,
intent(in),
optional :: unlim_dim_level
633 logical,
intent(in),
optional :: ignore_checksum
636 character(len=32) :: chksum_in_file
637 character(len=32) :: chksum
638 logical :: chksum_ignore = .false.
640 logical :: is_decomposed
642 if (
PRESENT(ignore_checksum)) chksum_ignore = ignore_checksum
644 if (.not. fileobj%is_restart)
then
645 call error(
"file "//trim(fileobj%path)// &
646 &
" is not a restart file. You must set is_restart=.true. in your open_file call.")
648 do i = 1, fileobj%num_restart_vars
649 if (
associated(fileobj%restart_vars(i)%data0d))
then
651 fileobj%restart_vars(i)%data0d, unlim_dim_level=unlim_dim_level)
652 elseif (
associated(fileobj%restart_vars(i)%data1d))
then
654 fileobj%restart_vars(i)%data1d, unlim_dim_level=unlim_dim_level)
655 elseif (
associated(fileobj%restart_vars(i)%data2d))
then
657 fileobj%restart_vars(i)%data2d, unlim_dim_level=unlim_dim_level)
658 if (.not.chksum_ignore)
then
660 fileobj%restart_vars(i)%data2d, is_decomposed)
664 "checksum", chksum_in_file)
665 if (.not.
string_compare(trim(adjustl(chksum_in_file)), trim(adjustl(chksum))))
then
666 call error(
"The checksum in the file:"//trim(fileobj%path)//
" and variable:"// &
667 & trim(fileobj%restart_vars(i)%varname)// &
668 &
" does not match the checksum calculated from the data. file:"//trim(adjustl(chksum_in_file))//&
669 &
" from data:"//trim(adjustl(chksum)))
673 elseif (
associated(fileobj%restart_vars(i)%data3d))
then
675 fileobj%restart_vars(i)%data3d, unlim_dim_level=unlim_dim_level)
676 if (.not.chksum_ignore)
then
678 fileobj%restart_vars(i)%data3d, is_decomposed)
682 "checksum", chksum_in_file(1:len(chksum_in_file)))
683 if (.not.
string_compare(trim(adjustl(chksum_in_file)), trim(adjustl(chksum))))
then
684 call error(
"The checksum in the file:"//trim(fileobj%path)//
" and variable:"// &
685 & trim(fileobj%restart_vars(i)%varname)//&
686 &
" does not match the checksum calculated from the data. file:"//trim(adjustl(chksum_in_file))//&
687 &
" from data:"//trim(adjustl(chksum)))
691 elseif (
associated(fileobj%restart_vars(i)%data4d))
then
693 fileobj%restart_vars(i)%data4d, unlim_dim_level=unlim_dim_level)
694 if (.not.chksum_ignore)
then
696 fileobj%restart_vars(i)%data4d, is_decomposed)
700 "checksum", chksum_in_file)
701 if (.not.
string_compare(trim(adjustl(chksum_in_file)), trim(adjustl(chksum))))
then
702 call error(
"The checksum in the file:"//trim(fileobj%path)//
" and variable:"// &
703 & trim(fileobj%restart_vars(i)%varname)//&
704 &
" does not match the checksum calculated from the data. file:"//trim(adjustl(chksum_in_file))//&
705 &
" from data:"//trim(adjustl(chksum)))
710 call error(
"There is no data associated with the variable: "//trim(fileobj%restart_vars(i)%varname)//&
711 &
" and the file: "//trim(fileobj%path)//
". Check your register_restart_variable call")
721 character(len=*),
intent(in) :: dimname
722 integer,
dimension(:),
allocatable,
intent(inout) :: indices
724 type(
domain2d),
pointer :: io_domain
732 if (dpos .ne. variable_not_found)
then
733 dpos = fileobj%xdims(dpos)%pos
737 if (dpos .ne. variable_not_found)
then
738 dpos = fileobj%ydims(dpos)%pos
741 call error(
"get_compute_domain_dimension_indices: the input dimension:"//trim(dimname)// &
742 &
" is not domain decomposed.")
745 if (
allocated(indices))
then
748 allocate(indices(e-s+1))
758 isd, isc, xc_size, jsd, jsc, yc_size, &
759 buffer_includes_halos, extra_x_point, &
762 integer,
intent(in) :: data_xsize
763 integer,
intent(in) :: data_ysize
764 type(
domain2d),
intent(in) :: domain
765 integer,
intent(in) :: xpos
766 integer,
intent(in) :: ypos
767 integer,
intent(out) :: isd
768 integer,
intent(out) :: isc
769 integer,
intent(out) :: xc_size
770 integer,
intent(out) :: jsd
771 integer,
intent(out) :: jsc
772 integer,
intent(out) :: yc_size
773 logical,
intent(out) :: buffer_includes_halos
774 logical,
intent(out),
optional :: extra_x_point
775 logical,
intent(out),
optional :: extra_y_point
776 character(len=*),
intent(in),
optional :: msg
784 type(
domain2d),
pointer :: io_domain
796 if (
present(extra_x_point))
then
797 if ((xpos .eq. east) .and. (iec .ne. xmax))
then
798 extra_x_point = .true.
800 extra_x_point = .false.
807 if (
present(extra_y_point))
then
808 if ((ypos .eq. north) .and. (jec .ne. ymax))
then
809 extra_y_point = .true.
811 extra_y_point = .false.
815 buffer_includes_halos = (data_xsize .eq. xd_size) .and. (data_ysize .eq. yd_size)
816 if (.not. buffer_includes_halos .and. data_xsize .ne. xc_size .and. data_ysize &
818 print *,
"buffer_includes_halos:", buffer_includes_halos,
" data_xsize:", &
819 data_xsize,
" xc_size:", xc_size,
" data_ysize:", data_ysize,
" yc_size:", &
821 call error(trim(msg)//
" The data is not on the compute domain or the data domain")
831 character(len=*),
intent(in) :: dimname
832 integer,
intent(out) :: is
833 integer,
intent(out) :: ie
834 integer,
dimension(:),
allocatable,
intent(out),
optional :: indices
836 type(
domain2d),
pointer :: io_domain
842 if (dpos .ne. variable_not_found)
then
843 dpos = fileobj%xdims(dpos)%pos
847 if (dpos .ne. variable_not_found)
then
848 dpos = fileobj%ydims(dpos)%pos
851 call error(
"get_global_io_domain_indices: the dimension "//trim(dimname)//
" in the file: "//trim(fileobj%path)//&
852 &
" is not domain decomposed. Check your register_axis call")
858 if (
present(indices))
then
859 if(
allocated(indices))
then
860 call error(
"get_global_io_domain_indices: the variable indices should not be allocated.")
862 allocate(indices(ie-is+1))
874 character(len=*),
intent(out) :: grid_file
877 character(len=*),
intent(in) :: mosaic_file
878 type(
domain2d),
intent(in) :: domain
879 integer,
intent(in),
optional :: tile_count
885 integer,
dimension(:),
allocatable :: tile_id
889 if(
present(tile_count)) tile = tile_count
891 allocate(tile_id(ntileme))
895 call netcdf_read_data(fileobj,
"gridfiles", grid_file, corner=tile_id(tile))
896 grid_file =
'INPUT/'//trim(grid_file)
902 include
"register_domain_restart_variable.inc"
903 include
"domain_read.inc"
904 include
"domain_write.inc"
905 #include "compute_global_checksum.inc"
908 end module fms_netcdf_domain_io_mod
subroutine domain_read_0d(fileobj, variable_name, vdata, unlim_dim_level, corner)
I/O domain root reads in a domain decomposed variable at a specific unlimited dimension level and sca...
subroutine domain_write_3d(fileobj, variable_name, vdata, unlim_dim_level, corner, edge_lengths)
Gather "compute" domain data on the I/O root rank and then have the I/O root write out the data that ...
subroutine register_domain_restart_variable_3d(fileobj, variable_name, vdata, dimensions, is_optional, chunksizes)
Add a domain decomposed variable.
subroutine domain_write_4d(fileobj, variable_name, vdata, unlim_dim_level, corner, edge_lengths)
Gather "compute" domain data on the I/O root rank and then have the I/O root write out the data that ...
subroutine register_domain_restart_variable_1d(fileobj, variable_name, vdata, dimensions, is_optional, chunksizes)
Add a domain decomposed variable.
subroutine domain_write_1d(fileobj, variable_name, vdata, unlim_dim_level, corner, edge_lengths)
Gather "compute" domain data on the I/O root rank and then have the I/O root write out the data that ...
subroutine domain_write_5d(fileobj, variable_name, vdata, unlim_dim_level, corner, edge_lengths)
Gather "compute" domain data on the I/O root rank and then have the I/O root write out the data that ...
subroutine register_domain_restart_variable_5d(fileobj, variable_name, vdata, dimensions, is_optional, chunksizes)
Add a domain decomposed variable.
subroutine domain_write_0d(fileobj, variable_name, vdata, unlim_dim_level, corner)
Gather "compute" domain data on the I/O root rank and then have the I/O root write out the data that ...
subroutine domain_write_2d(fileobj, variable_name, vdata, unlim_dim_level, corner, edge_lengths)
Gather "compute" domain data on the I/O root rank and then have the I/O root write out the data that ...
subroutine domain_read_3d(fileobj, variable_name, vdata, unlim_dim_level, corner, edge_lengths)
I/O domain root reads in a domain decomposed variable at a specific unlimited dimension level and sca...
subroutine register_domain_restart_variable_4d(fileobj, variable_name, vdata, dimensions, is_optional, chunksizes)
Add a domain decomposed variable.
subroutine domain_read_1d(fileobj, variable_name, vdata, unlim_dim_level, corner, edge_lengths)
I/O domain root reads in a domain decomposed variable at a specific unlimited dimension level and sca...
subroutine domain_read_2d(fileobj, variable_name, vdata, unlim_dim_level, corner, edge_lengths)
I/O domain root reads in a domain decomposed variable at a specific unlimited dimension level and sca...
subroutine domain_read_4d(fileobj, variable_name, vdata, unlim_dim_level, corner, edge_lengths)
I/O domain root reads in a domain decomposed variable at a specific unlimited dimension level and sca...
subroutine domain_read_5d(fileobj, variable_name, vdata, unlim_dim_level, corner, edge_lengths)
I/O domain root reads in a domain decomposed variable at a specific unlimited dimension level and sca...
subroutine register_domain_restart_variable_0d(fileobj, variable_name, vdata, dimensions, is_optional, chunksizes)
Add a domain decomposed variable.
subroutine register_domain_restart_variable_2d(fileobj, variable_name, vdata, dimensions, is_optional, chunksizes)
Add a domain decomposed variable.
subroutine, public io_domain_tile_filepath_mangle(dest, source, io_domain_tile_id)
Add the I/O domain tile id to an input filepath.
logical function, public string_compare(string1, string2, ignore_case)
Compare strings.
subroutine, public domain_tile_filepath_mangle(dest, source, domain_tile_id)
Add the domain tile id to an input filepath.
subroutine add_domain_attribute(fileobj, variable_name)
Add a "domain_decomposed" attribute to the axis variables because it is required by mppnccombine.
integer function get_domain_decomposed_dimension_index(fileobj, variable_name, xory, broadcast)
Given a variable, get the index of the "x" or "y" domain decomposed dimension.
integer function get_domain_decomposed_index(name_, array, size_)
Get the index of a domain decomposed dimension.
subroutine, public save_domain_restart(fileobj, unlim_dim_level)
Loop through registered restart variables and write them to a netcdf file.
logical function is_variable_domain_decomposed(fileobj, variable_name, broadcast, xindex, yindex, xpos, ypos)
Determine if a variable is "domain decomposed.".
logical function, public is_dimension_registered(fileobj, dimension_name)
Determine whether a domain-decomposed dimension has been registered to the file object.
logical function, public open_domain_file(fileobj, path, mode, domain, nc_format, is_restart, dont_add_res_to_filename)
Open a domain netcdf file.
subroutine domain_offsets(data_xsize, data_ysize, domain, xpos, ypos, isd, isc, xc_size, jsd, jsc, yc_size, buffer_includes_halos, extra_x_point, extra_y_point, msg)
Utility routine that retrieves domain indices.
subroutine, public get_global_io_domain_indices(fileobj, dimname, is, ie, indices)
Get starting/ending global indices of the I/O domain for a domain decomposed file.
subroutine, public register_domain_variable(fileobj, variable_name, variable_type, dimensions, chunksizes)
Add a domain decomposed variable.
subroutine, public get_mosaic_tile_grid(grid_file, mosaic_file, domain, tile_count)
Read a mosaic_file and get the grid filename for the current tile or for the tile specified.
subroutine, public register_domain_decomposed_dimension(fileobj, dim_name, xory, domain_position)
Add a dimension to a file associated with a two-dimensional domain.
subroutine, public close_domain_file(fileobj)
Close a domain netcdf file.
character(len=32) function compute_global_checksum_3d(fileobj, variable_name, variable_data, is_decomposed)
@briefs Calculates a variable's checksum across all ranks in the current pelist.
subroutine, public restore_domain_state(fileobj, unlim_dim_level, ignore_checksum)
Loop through registered restart variables and read them from a netcdf file.
character(len=32) function compute_global_checksum_4d(fileobj, variable_name, variable_data, is_decomposed)
@briefs Calculates a variable's checksum across all ranks in the current pelist.
subroutine append_domain_decomposed_dimension(name_, position_, array, size_)
Add a domain decomposed dimension to an array.
character(len=32) function compute_global_checksum_2d(fileobj, variable_name, variable_data, is_decomposed)
@briefs Calculates a variable's checksum across all ranks in the current pelist.
subroutine, public get_compute_domain_dimension_indices(fileobj, dimname, indices)
Return an array of compute domain indices.
integer function get_domain_position(name_, array, size_)
Given a domain decomposed dimension, get its domain position.
integer function mpp_get_domain_npes(domain)
Set user stack size.
integer function, dimension(size(domain%tile_id(:))) mpp_get_tile_id(domain)
Returns the tile_id on current pe.
logical function mpp_domain_is_symmetry(domain)
Set user stack size.
integer function mpp_get_current_ntile(domain)
Returns number of tile on current pe.
integer function mpp_get_ntile_count(domain)
Returns number of tiles in mosaic.
integer function, dimension(2) mpp_get_io_domain_layout(domain)
Set user stack size.
type(domain2d) function, pointer mpp_get_io_domain(domain)
Set user stack size.
These routines retrieve the axis specifications associated with the compute domains....
These routines retrieve the axis specifications associated with the data domains. The domain is a der...
These routines retrieve the axis specifications associated with the global domains....
Retrieve list of PEs associated with a domain decomposition. The 1D version of this call returns an a...
The domain2D type contains all the necessary information to define the global, compute and data domai...
Perform parallel broadcasts.
subroutine, public netcdf_file_close(fileobj)
Close a netcdf file.
logical function, public netcdf_file_open(fileobj, path, mode, nc_format, pelist, is_restart, dont_add_res_to_filename)
Open a netcdf file.
subroutine, public netcdf_add_dimension(fileobj, dimension_name, dimension_length, is_compressed)
Add a dimension to a file.
integer function, public get_variable_num_dimensions(fileobj, variable_name, broadcast)
Get the number of dimensions a variable depends on.
subroutine, public get_dimension_size(fileobj, dimension_name, dim_size, broadcast)
Get the length of a dimension.
logical function, public dimension_exists(fileobj, dimension_name, broadcast)
Determine if a dimension exists.
logical function, public variable_att_exists(fileobj, variable_name, attribute_name, broadcast)
Determine if a variable's attribute exists.
subroutine, public get_variable_dimension_names(fileobj, variable_name, dim_names, broadcast)
Get the name of a variable's dimensions.
subroutine, public netcdf_add_variable(fileobj, variable_name, variable_type, dimensions, chunksizes)
Add a variable to a file.