MODFLOW 6  version 6.8.0.dev0
USGS Modular Hydrologic Model
MeshNCModel.f90
Go to the documentation of this file.
1 !> @brief This module contains the MeshModelModule
2 !!
3 !! This module defines a base class for UGRID based
4 !! (mesh) model netcdf exports. It is dependent on
5 !! external netcdf libraries.
6 !<
8 
9  use kindmodule, only: dp, i4b, lgp
19  use netcdfcommonmodule, only: nf_verify
20  use netcdf
21 
22  implicit none
23  private
25  public :: mesh2dmodeltype
26  public :: ncvar_chunk
27  public :: ncvar_deflate
28  public :: ncvar_gridmap
29  public :: ncvar_mf6attr
30 
31  !> @brief type for storing model export dimension ids
32  !<
34  integer(I4B) :: nmesh_node !< number of nodes in mesh
35  integer(I4B) :: nmesh_face !< number of faces in mesh
36  integer(I4B) :: max_nmesh_face_nodes !< max number of nodes in a single face
37  integer(I4B) :: time !< number of steps
38  integer(I4B) :: layer !< number of layers
39  contains
40  end type meshncdimidtype
41 
42  !> @brief type for storing model export variable ids
43  !<
45  integer(I4B) :: mesh !< mesh container variable
46  integer(I4B) :: mesh_node_x !< mesh nodes x array
47  integer(I4B) :: mesh_node_y !< mesh nodes y array
48  integer(I4B) :: mesh_face_x !< mesh faces x location array
49  integer(I4B) :: mesh_face_y !< mesh faces y location array
50  integer(I4B) :: mesh_face_xbnds !< mesh faces 2D x bounds array
51  integer(I4B) :: mesh_face_ybnds !< mesh faces 2D y bounds array
52  integer(I4B) :: mesh_face_nodes !< mesh faces 2D nodes array
53  integer(I4B) :: time !< time coordinate variable
54  integer(I4B) :: layer !< layer coordinate variable
55  integer(I4B), dimension(:), allocatable :: export !< in scope layer export
56  integer(I4B), dimension(:), allocatable :: dependent !< layered dependent variables array
57  contains
58  end type meshncvaridtype
59 
60  !> @brief base ugrid netcdf export type
61  !<
62  type, abstract, extends(ncbasemodelexporttype) :: meshmodeltype
63  type(meshncdimidtype) :: dim_ids !< dimension ids
64  type(meshncvaridtype) :: var_ids !< variable ids
65  integer(I4B) :: nlay !< number of layers
66  integer(I4B), pointer :: chunk_face !< chunking parameter for face dimension
67  contains
68  procedure :: mesh_init
69  procedure :: mesh_destroy
70  procedure :: df_export
71  procedure :: export_df
72  procedure :: create_timeseries
73  procedure :: add_global_att
74  procedure(nc_array_export_if), deferred :: export_input_array
75  procedure :: export_input_arrays
76  procedure :: add_pkg_data
77  procedure :: define_dependent
78  procedure :: define_gridmap
79  end type meshmodeltype
80 
81  !> @brief abstract interfaces for derived ugrid netcd export types
82  !<
83  abstract interface
84  subroutine nc_array_export_if(this, pkgtype, pkgname, mempath, idt)
86  class(meshmodeltype), intent(inout) :: this
87  character(len=*), intent(in) :: pkgtype
88  character(len=*), intent(in) :: pkgname
89  character(len=*), intent(in) :: mempath
90  type(inputparamdefinitiontype), pointer, intent(in) :: idt
91  end subroutine
92  end interface
93 
94  type, abstract, extends(meshmodeltype) :: mesh2dmodeltype
95  contains
96  procedure :: create_mesh
97  end type mesh2dmodeltype
98 
99 contains
100 
101  !> @brief initialize
102  !<
103  subroutine mesh_init(this, modelname, modeltype, modelfname, nc_fname, &
104  disenum, nctype, lenuni, iout)
106  class(meshmodeltype), intent(inout) :: this
107  character(len=*), intent(in) :: modelname
108  character(len=*), intent(in) :: modeltype
109  character(len=*), intent(in) :: modelfname
110  character(len=*), intent(in) :: nc_fname
111  integer(I4B), intent(in) :: disenum
112  integer(I4B), intent(in) :: nctype
113  integer(I4B), intent(in) :: lenuni
114  integer(I4B), intent(in) :: iout
115  logical(LGP) :: found
116 
117  ! initialize base class
118  call this%NCModelExportType%init(modelname, modeltype, modelfname, nc_fname, &
119  disenum, nctype, iout)
120 
121  ! allocate and initialize
122  allocate (this%chunk_face)
123  this%chunk_face = -1
124 
125  ! update values from input context
126  if (this%ncf_mempath /= '') then
127  call mem_set_value(this%chunk_face, 'CHUNK_FACE', this%ncf_mempath, found)
128  end if
129 
130  if (this%chunk_time > 0 .and. this%chunk_face > 0) then
131  this%chunking_active = .true.
132  else if (this%chunk_time > 0 .or. this%chunk_face > 0) then
133  this%chunk_face = -1
134  this%chunk_time = -1
135  write (warnmsg, '(a)') 'Ignoring user provided NetCDF chunking parameter. &
136  &Define chunk_time and chunk_face input parameters to see an effect in &
137  &file "'//trim(nc_fname)//'".'
138  call store_warning(warnmsg)
139  end if
140 
141  if (lenuni == 1) then
142  this%lenunits = 'ft'
143  else
144  this%lenunits = 'm'
145  end if
146 
147  ! create the netcdf file
148  call nf_verify(nf90_create(this%nc_fname, &
149  ior(nf90_clobber, nf90_netcdf4), this%ncid), &
150  this%nc_fname)
151  end subroutine mesh_init
152 
153  !> @brief initialize
154  !<
155  subroutine mesh_destroy(this)
157  class(meshmodeltype), intent(inout) :: this
158  call nf_verify(nf90_close(this%ncid), this%nc_fname)
159  deallocate (this%chunk_face)
160  nullify (this%chunk_face)
161  end subroutine mesh_destroy
162 
163  !> @brief define timeseries input variables
164  !<
165  subroutine df_export(this)
167  class(meshmodeltype), intent(inout) :: this
168  class(exportpackagetype), pointer :: export_pkg
169  integer(I4B) :: idx
170  do idx = 1, this%pkglist%Count()
171  export_pkg => this%get(idx)
172  call this%export_df(export_pkg)
173  end do
174  end subroutine df_export
175 
176  !> @brief define export package
177  !<
178  subroutine export_df(this, export_pkg)
181  class(meshmodeltype), intent(inout) :: this
182  class(exportpackagetype), pointer, intent(in) :: export_pkg
183  type(inputparamdefinitiontype), pointer :: idt
184  integer(I4B) :: iparam, iaux, layer
185 
186  ! export defined period input
187  do iparam = 1, export_pkg%nparam
188  ! initialize
189  iaux = 0
190  layer = 0
191  ! set input definition
192  idt => &
193  get_param_definition_type(export_pkg%mf6_input%param_dfns, &
194  export_pkg%mf6_input%component_type, &
195  export_pkg%mf6_input%subcomponent_type, &
196  'PERIOD', export_pkg%param_names(iparam), '')
197 
198  select case (idt%shape)
199  case ('NCPL')
200  call this%create_timeseries(idt, iparam, iaux, layer, export_pkg)
201  case ('NODES')
202  do layer = 1, this%nlay
203  call this%create_timeseries(idt, iparam, iaux, layer, export_pkg)
204  end do
205  case ('NAUX NCPL')
206  do iaux = 1, export_pkg%naux
207  call this%create_timeseries(idt, iparam, iaux, layer, export_pkg)
208  end do
209  case ('NAUX NODES')
210  do iaux = 1, export_pkg%naux
211  do layer = 1, this%nlay
212  call this%create_timeseries(idt, iparam, iaux, layer, export_pkg)
213  end do
214  end do
215  case default
216  end select
217  end do
218  end subroutine export_df
219 
220  !> @brief create timeseries export variable
221  !<
222  subroutine create_timeseries(this, idt, iparam, iaux, layer, export_pkg)
223  use constantsmodule, only: dnodata
225  class(meshmodeltype), intent(inout) :: this
226  type(inputparamdefinitiontype), pointer, intent(in) :: idt
227  integer(I4B), intent(in) :: iparam
228  integer(I4B), intent(in) :: iaux
229  integer(I4B), intent(in) :: layer
230  class(exportpackagetype), pointer, intent(in) :: export_pkg
231  character(len=LINELENGTH) :: varname, longname, nc_tag
232  integer(I4B) :: varid
233 
234  ! set variable input tag
235  nc_tag = this%input_attribute(export_pkg%mf6_input%subcomponent_name, &
236  idt)
237 
238  ! set names
239  varname = export_varname(export_pkg%mf6_input%subcomponent_name, &
240  idt%tagname, export_pkg%mf6_input%mempath, &
241  layer=layer, iaux=iaux)
242  longname = export_longname(idt%longname, &
243  export_pkg%mf6_input%subcomponent_name, &
244  idt%tagname, export_pkg%mf6_input%mempath, &
245  layer=layer, iaux=iaux, &
246  component_type=idt%component_type, &
247  subcomponent_type=idt%subcomponent_type)
248 
249  ! create the netcdf dependent layer variable
250  select case (idt%datatype)
251  case ('DOUBLE1D', 'DOUBLE2D')
252  call nf_verify(nf90_def_var(this%ncid, varname, nf90_double, &
253  (/this%dim_ids%nmesh_face, &
254  this%dim_ids%time/), &
255  varid), &
256  this%nc_fname)
257  call nf_verify(nf90_put_att(this%ncid, varid, &
258  '_FillValue', (/dnodata/)), &
259  this%nc_fname)
260  case ('INTEGER1D')
261  call nf_verify(nf90_def_var(this%ncid, varname, nf90_int, &
262  (/this%dim_ids%nmesh_face, &
263  this%dim_ids%time/), &
264  varid), &
265  this%nc_fname)
266  call nf_verify(nf90_put_att(this%ncid, varid, &
267  '_FillValue', (/nf90_fill_int/)), &
268  this%nc_fname)
269  end select
270 
271  ! apply chunking parameters
272  if (this%chunking_active) then
273  call nf_verify(nf90_def_var_chunking(this%ncid, &
274  varid, &
275  nf90_chunked, &
276  (/this%chunk_face, &
277  this%chunk_time/)), &
278  this%nc_fname)
279  end if
280 
281  ! deflate and shuffle
282  call ncvar_deflate(this%ncid, varid, this%deflate, &
283  this%shuffle, this%nc_fname)
284 
285  ! assign variable attributes
286  call nf_verify(nf90_put_att(this%ncid, varid, &
287  'units', this%lenunits), this%nc_fname)
288  call nf_verify(nf90_put_att(this%ncid, varid, &
289  'long_name', longname), this%nc_fname)
290 
291  ! add grid mapping and mf6 attr (mesh, location, coordinates, grid_mapping)
292  call ncvar_gridmap(this%ncid, varid, &
293  this%gridmap_name, this%nc_fname)
294  call ncvar_mf6attr(this%ncid, varid, layer, iaux, nc_tag, this%nc_fname)
295 
296  ! store variable id
297  if (idt%tagname == 'AUX') then
298  if (layer > 0) then
299  export_pkg%varids_aux(iaux, layer) = varid
300  else
301  export_pkg%varids_aux(iaux, 1) = varid
302  end if
303  else
304  if (layer > 0) then
305  export_pkg%varids_param(iparam, layer) = varid
306  else
307  export_pkg%varids_param(iparam, 1) = varid
308  end if
309  end if
310  end subroutine create_timeseries
311 
312  !> @brief create file (group) attributes
313  !<
314  subroutine add_global_att(this)
315  class(meshmodeltype), intent(inout) :: this
316  ! file scoped title
317  call nf_verify(nf90_put_att(this%ncid, nf90_global, 'title', &
318  this%annotation%title), this%nc_fname)
319  ! source (MODFLOW 6)
320  call nf_verify(nf90_put_att(this%ncid, nf90_global, 'source', &
321  this%annotation%source), this%nc_fname)
322  ! grid type (MODFLOW 6)
323  call nf_verify(nf90_put_att(this%ncid, nf90_global, 'modflow_grid', &
324  this%annotation%grid), this%nc_fname)
325  ! mesh type (MODFLOW 6)
326  if (this%annotation%mesh /= '') then
327  call nf_verify(nf90_put_att(this%ncid, nf90_global, 'mesh', &
328  this%annotation%mesh), this%nc_fname)
329 
330  end if
331  ! MODFLOW 6 model type
332  call nf_verify(nf90_put_att(this%ncid, nf90_global, 'modflow_model', &
333  this%annotation%model), this%nc_fname)
334  ! generation datetime
335  call nf_verify(nf90_put_att(this%ncid, nf90_global, 'history', &
336  this%annotation%history), this%nc_fname)
337  ! supported conventions
338  call nf_verify(nf90_put_att(this%ncid, nf90_global, 'Conventions', &
339  this%annotation%conventions), &
340  this%nc_fname)
341  end subroutine add_global_att
342 
343  !> @brief write package gridded input data
344  !<
345  subroutine export_input_arrays(this, pkgtype, pkgname, mempath, param_dfns)
346  use memorymanagermodule, only: get_isize
347  class(meshmodeltype), intent(inout) :: this
348  character(len=*), intent(in) :: pkgtype
349  character(len=*), intent(in) :: pkgname
350  character(len=*), intent(in) :: mempath
351  type(inputparamdefinitiontype), dimension(:), pointer, &
352  intent(in) :: param_dfns
353  type(inputparamdefinitiontype), pointer :: idt
354  integer(I4B) :: iparam, isize
355  ! export griddata block parameters
356  do iparam = 1, size(param_dfns)
357  ! assign param definition pointer
358  idt => param_dfns(iparam)
359  ! for now only griddata is exported
360  if (idt%blockname == 'GRIDDATA') then
361  ! veriy variable is allocated
362  call get_isize(idt%mf6varname, mempath, isize)
363  if (isize > 0) then
364  call this%export_input_array(pkgtype, pkgname, mempath, idt)
365  end if
366  end if
367  end do
368  end subroutine export_input_arrays
369 
370  !> @brief determine packages to write gridded input
371  !<
372  subroutine add_pkg_data(this)
379  class(meshmodeltype), intent(inout) :: this
380  character(LENCOMPONENTNAME) :: ptype, pname, pkgtype
381  character(len=LENMEMPATH) :: input_mempath
382  type(characterstringtype), dimension(:), contiguous, &
383  pointer :: pkgtypes => null()
384  type(characterstringtype), dimension(:), contiguous, &
385  pointer :: pkgnames => null()
386  type(characterstringtype), dimension(:), contiguous, &
387  pointer :: mempaths => null()
388  type(inputparamdefinitiontype), dimension(:), pointer :: param_dfns
389  character(len=LENMEMPATH) :: mempath
390  integer(I4B) :: n
391  integer(I4B), pointer :: export_arrays
392  logical(LGP) :: found
393 
394  input_mempath = create_mem_path(component=this%modelname, context=idm_context)
395 
396  ! set pointers to model path package info
397  call mem_setptr(pkgtypes, 'PKGTYPES', input_mempath)
398  call mem_setptr(pkgnames, 'PKGNAMES', input_mempath)
399  call mem_setptr(mempaths, 'MEMPATHS', input_mempath)
400 
401  allocate (export_arrays)
402 
403  do n = 1, size(mempaths)
404  ! initialize export_arrays
405  export_arrays = 0
406 
407  ! set package attributes
408  mempath = mempaths(n)
409  pname = pkgnames(n)
410  ptype = pkgtypes(n)
411 
412  ! export input arrays
413  if (mempath /= '') then
414  ! update export
415  call mem_set_value(export_arrays, 'EXPORT_NC', mempath, found, &
416  release=.false.)
417  if (export_arrays > 0) then
418  pkgtype = idm_subcomponent_type(this%modeltype, ptype)
419  param_dfns => param_definitions(this%modeltype, pkgtype)
420  call this%export_input_arrays(ptype, pname, mempath, param_dfns)
421  end if
422  end if
423  end do
424 
425  ! cleanup
426  deallocate (export_arrays)
427  end subroutine add_pkg_data
428 
429  !> @brief create the model layer dependent variables
430  !<
431  subroutine define_dependent(this)
432  class(meshmodeltype), intent(inout) :: this
433  character(len=LINELENGTH) :: varname, longname
434  integer(I4B) :: k
435 
436  ! create a dependent variable for each layer
437  do k = 1, this%nlay
438  ! initialize names
439  varname = ''
440  longname = ''
441 
442  ! set layer variable and longnames
443  write (varname, '(a,i0)') trim(this%xname)//'_l', k
444  write (longname, '(a,i0,a)') trim(this%annotation%longname)// &
445  ' (layer ', k, ')'
446 
447  ! create the netcdf dependent layer variable
448  call nf_verify(nf90_def_var(this%ncid, varname, nf90_double, &
449  (/this%dim_ids%nmesh_face, &
450  this%dim_ids%time/), &
451  this%var_ids%dependent(k)), &
452  this%nc_fname)
453 
454  ! apply chunking parameters
455  if (this%chunking_active) then
456  call nf_verify(nf90_def_var_chunking(this%ncid, &
457  this%var_ids%dependent(k), &
458  nf90_chunked, &
459  (/this%chunk_face, &
460  this%chunk_time/)), &
461  this%nc_fname)
462  end if
463 
464  ! deflate and shuffle
465  call ncvar_deflate(this%ncid, this%var_ids%dependent(k), this%deflate, &
466  this%shuffle, this%nc_fname)
467 
468  ! assign variable attributes
469  call nf_verify(nf90_put_att(this%ncid, this%var_ids%dependent(k), &
470  'units', this%lenunits), this%nc_fname)
471  call nf_verify(nf90_put_att(this%ncid, this%var_ids%dependent(k), &
472  'long_name', longname), this%nc_fname)
473  call nf_verify(nf90_put_att(this%ncid, this%var_ids%dependent(k), &
474  '_FillValue', (/dhnoflo/)), &
475  this%nc_fname)
476 
477  ! add grid mapping (mesh, location, coordinates, grid_mapping)
478  call ncvar_gridmap(this%ncid, this%var_ids%dependent(k), &
479  this%gridmap_name, this%nc_fname)
480  end do
481  end subroutine define_dependent
482 
483  !> @brief create the file grid mapping container variable
484  !<
485  subroutine define_gridmap(this)
486  class(meshmodeltype), intent(inout) :: this
487  integer(I4B) :: var_id
488  character(len=LINELENGTH) :: gmname
489  character(len=LENBIGLINE) :: effective_crs_wkt
490 
491  ! was projection info provided
492  if (this%wkt /= '' .or. this%crs_wkt /= '') then
493  ! create projection variable
494  call nf_verify(nf90_redef(this%ncid), this%nc_fname)
495  call nf_verify(nf90_def_var(this%ncid, this%gridmap_name, nf90_int, &
496  var_id), this%nc_fname)
497  ! wkt (WKT1, OGC 01-009) -- for legacy/QGIS compatibility
498  if (this%wkt /= '') then
499  call nf_verify(nf90_put_att(this%ncid, var_id, 'wkt', this%wkt), &
500  this%nc_fname)
501  end if
502  ! crs_wkt (WKT2, ISO 19162:2019) -- required by CF-1.11
503  if (this%crs_wkt /= '') then
504  effective_crs_wkt = this%crs_wkt
505  else
506  effective_crs_wkt = this%wkt
507  end if
508  call nf_verify(nf90_put_att(this%ncid, var_id, 'crs_wkt', &
509  trim(effective_crs_wkt)), this%nc_fname)
510  ! grid_mapping_name derived from WKT projection keyword
511  gmname = wkt_to_cf_gridmapping(trim(effective_crs_wkt))
512  if (gmname /= '') then
513  call nf_verify(nf90_put_att(this%ncid, var_id, 'grid_mapping_name', &
514  trim(gmname)), this%nc_fname)
515  end if
516  call nf_verify(nf90_enddef(this%ncid), this%nc_fname)
517  call nf_verify(nf90_put_var(this%ncid, var_id, 1), &
518  this%nc_fname)
519  end if
520  end subroutine define_gridmap
521 
522  !> @brief create the file mesh container variable
523  !<
524  subroutine create_mesh(this)
525  class(mesh2dmodeltype), intent(inout) :: this
526 
527  ! create mesh container variable
528  call nf_verify(nf90_def_var(this%ncid, this%mesh_name, nf90_int, &
529  this%var_ids%mesh), this%nc_fname)
530 
531  ! assign container variable attributes
532  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh, 'cf_role', &
533  'mesh_topology'), this%nc_fname)
534  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh, 'long_name', &
535  '2D mesh topology'), this%nc_fname)
536  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh, &
537  'topology_dimension', 2), this%nc_fname)
538  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh, 'face_dimension', &
539  'nmesh_face'), this%nc_fname)
540  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh, &
541  'node_coordinates', 'mesh_node_x mesh_node_y'), &
542  this%nc_fname)
543  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh, &
544  'face_coordinates', 'mesh_face_x mesh_face_y'), &
545  this%nc_fname)
546  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh, &
547  'face_node_connectivity', 'mesh_face_nodes'), &
548  this%nc_fname)
549 
550  ! create mesh x node (mesh vertex) variable
551  call nf_verify(nf90_def_var(this%ncid, 'mesh_node_x', nf90_double, &
552  (/this%dim_ids%nmesh_node/), &
553  this%var_ids%mesh_node_x), this%nc_fname)
554 
555  ! assign mesh x node variable attributes
556  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh_node_x, &
557  'units', this%lenunits), this%nc_fname)
558  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh_node_x, &
559  'standard_name', 'projection_x_coordinate'), &
560  this%nc_fname)
561  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh_node_x, &
562  'long_name', 'Easting'), this%nc_fname)
563 
564  if (this%gridmap_name /= '') then
565  ! associate with projection
566  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh_node_x, &
567  'grid_mapping', this%gridmap_name), &
568  this%nc_fname)
569  end if
570 
571  ! create mesh y node (mesh vertex) variable
572  call nf_verify(nf90_def_var(this%ncid, 'mesh_node_y', nf90_double, &
573  (/this%dim_ids%nmesh_node/), &
574  this%var_ids%mesh_node_y), this%nc_fname)
575 
576  ! assign mesh y variable attributes
577  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh_node_y, &
578  'units', this%lenunits), this%nc_fname)
579  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh_node_y, &
580  'standard_name', 'projection_y_coordinate'), &
581  this%nc_fname)
582  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh_node_y, &
583  'long_name', 'Northing'), this%nc_fname)
584 
585  if (this%gridmap_name /= '') then
586  ! associate with projection
587  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh_node_y, &
588  'grid_mapping', this%gridmap_name), &
589  this%nc_fname)
590  end if
591 
592  ! create mesh x face (cell vertex) variable
593  call nf_verify(nf90_def_var(this%ncid, 'mesh_face_x', nf90_double, &
594  (/this%dim_ids%nmesh_face/), &
595  this%var_ids%mesh_face_x), this%nc_fname)
596 
597  ! assign mesh x face variable attributes
598  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh_face_x, &
599  'units', this%lenunits), this%nc_fname)
600  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh_face_x, &
601  'standard_name', 'projection_x_coordinate'), &
602  this%nc_fname)
603  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh_face_x, &
604  'long_name', 'Easting'), this%nc_fname)
605  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh_face_x, 'bounds', &
606  'mesh_face_xbnds'), this%nc_fname)
607  if (this%gridmap_name /= '') then
608  ! associate with projection
609  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh_face_x, &
610  'grid_mapping', this%gridmap_name), &
611  this%nc_fname)
612  end if
613 
614  ! create mesh x cell bounds variable
615  call nf_verify(nf90_def_var(this%ncid, 'mesh_face_xbnds', nf90_double, &
616  (/this%dim_ids%max_nmesh_face_nodes, &
617  this%dim_ids%nmesh_face/), &
618  this%var_ids%mesh_face_xbnds), &
619  this%nc_fname)
620 
621  ! create mesh y face (cell vertex) variable
622  call nf_verify(nf90_def_var(this%ncid, 'mesh_face_y', nf90_double, &
623  (/this%dim_ids%nmesh_face/), &
624  this%var_ids%mesh_face_y), this%nc_fname)
625 
626  ! assign mesh y face variable attributes
627  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh_face_y, &
628  'units', this%lenunits), this%nc_fname)
629  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh_face_y, &
630  'standard_name', 'projection_y_coordinate'), &
631  this%nc_fname)
632  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh_face_y, &
633  'long_name', 'Northing'), this%nc_fname)
634  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh_face_y, 'bounds', &
635  'mesh_face_ybnds'), this%nc_fname)
636 
637  if (this%gridmap_name /= '') then
638  ! associate with projection
639  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh_face_y, &
640  'grid_mapping', this%gridmap_name), &
641  this%nc_fname)
642  end if
643 
644  ! create mesh y cell bounds variable
645  call nf_verify(nf90_def_var(this%ncid, 'mesh_face_ybnds', nf90_double, &
646  (/this%dim_ids%max_nmesh_face_nodes, &
647  this%dim_ids%nmesh_face/), &
648  this%var_ids%mesh_face_ybnds), &
649  this%nc_fname)
650 
651  ! create mesh face nodes variable
652  call nf_verify(nf90_def_var(this%ncid, 'mesh_face_nodes', nf90_int, &
653  (/this%dim_ids%max_nmesh_face_nodes, &
654  this%dim_ids%nmesh_face/), &
655  this%var_ids%mesh_face_nodes), &
656  this%nc_fname)
657 
658  ! assign variable attributes
659  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh_face_nodes, &
660  'cf_role', 'face_node_connectivity'), &
661  this%nc_fname)
662  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh_face_nodes, &
663  'long_name', &
664  'Vertices bounding cell (counterclockwise)'), &
665  this%nc_fname)
666  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh_face_nodes, &
667  '_FillValue', (/nf90_fill_int/)), &
668  this%nc_fname)
669  call nf_verify(nf90_put_att(this%ncid, this%var_ids%mesh_face_nodes, &
670  'start_index', 1), this%nc_fname)
671  end subroutine create_mesh
672 
673  !> @brief define variable chunking
674  !<
675  subroutine ncvar_chunk(ncid, varid, chunk_face, nc_fname)
676  integer(I4B), intent(in) :: ncid
677  integer(I4B), intent(in) :: varid
678  integer(I4B), intent(in) :: chunk_face
679  character(len=*), intent(in) :: nc_fname
680  if (chunk_face > 0) then
681  call nf_verify(nf90_def_var_chunking(ncid, varid, nf90_chunked, &
682  (/chunk_face/)), nc_fname)
683  end if
684  end subroutine ncvar_chunk
685 
686  !> @brief define variable compression
687  !<
688  subroutine ncvar_deflate(ncid, varid, deflate, shuffle, nc_fname)
689  integer(I4B), intent(in) :: ncid
690  integer(I4B), intent(in) :: varid
691  integer(I4B), intent(in) :: deflate
692  integer(I4B), intent(in) :: shuffle
693  character(len=*), intent(in) :: nc_fname
694  if (deflate >= 0) then
695  call nf_verify(nf90_def_var_deflate(ncid, varid, shuffle=shuffle, &
696  deflate=1, deflate_level=deflate), &
697  nc_fname)
698  end if
699  end subroutine ncvar_deflate
700 
701  !> @brief put variable gridmap attributes
702  !<
703  subroutine ncvar_gridmap(ncid, varid, gridmap_name, nc_fname)
704  integer(I4B), intent(in) :: ncid
705  integer(I4B), intent(in) :: varid
706  character(len=*), intent(in) :: gridmap_name
707  character(len=*), intent(in) :: nc_fname
708  ! UGRID topology attrs are CRS-independent -- always written on face vars
709  call nf_verify(nf90_put_att(ncid, varid, 'mesh', 'mesh'), nc_fname)
710  call nf_verify(nf90_put_att(ncid, varid, 'location', 'face'), nc_fname)
711  call nf_verify(nf90_put_att(ncid, varid, 'coordinates', &
712  'mesh_face_x mesh_face_y'), nc_fname)
713  ! grid_mapping only written when a CRS is configured
714  if (gridmap_name /= '') then
715  call nf_verify(nf90_put_att(ncid, varid, 'grid_mapping', &
716  gridmap_name), nc_fname)
717  end if
718  end subroutine ncvar_gridmap
719 
720  !> @brief put variable internal attributes
721  !<
722  subroutine ncvar_mf6attr(ncid, varid, layer, iaux, nc_tag, nc_fname)
723  integer(I4B), intent(in) :: ncid
724  integer(I4B), intent(in) :: varid
725  integer(I4B), intent(in) :: layer
726  integer(I4B), intent(in) :: iaux
727  character(len=*), intent(in) :: nc_tag
728  character(len=*), intent(in) :: nc_fname
729  if (nc_tag /= '') then
730  call nf_verify(nf90_put_att(ncid, varid, 'modflow_input', &
731  nc_tag), nc_fname)
732  if (layer > 0) then
733  call nf_verify(nf90_put_att(ncid, varid, 'layer', &
734  layer), nc_fname)
735  end if
736  if (iaux > 0) then
737  call nf_verify(nf90_put_att(ncid, varid, 'modflow_iaux', &
738  iaux), nc_fname)
739  end if
740  end if
741  end subroutine ncvar_mf6attr
742 
743 end module meshmodelmodule
abstract interfaces for derived ugrid netcd export types
Definition: MeshNCModel.f90:84
This module contains simulation constants.
Definition: Constants.f90:9
integer(i4b), parameter linelength
maximum length of a standard line
Definition: Constants.f90:45
integer(i4b), parameter lencomponentname
maximum length of a component name
Definition: Constants.f90:18
real(dp), parameter dnodata
real no data constant
Definition: Constants.f90:95
integer(i4b), parameter lenbigline
maximum length of a big line
Definition: Constants.f90:15
real(dp), parameter dhnoflo
real no flow constant
Definition: Constants.f90:93
integer(i4b), parameter lenmempath
maximum length of the memory path
Definition: Constants.f90:27
This module contains the DefinitionSelectModule.
type(inputparamdefinitiontype) function, pointer, public get_param_definition_type(input_definition_types, component_type, subcomponent_type, blockname, tagname, filename, found)
Return parameter definition.
type(inputparamdefinitiontype) function, dimension(:), pointer, public param_definitions(component, subcomponent)
logical function, public idm_multi_package(component, subcomponent)
Input definition module.
This module defines variable data types.
Definition: kind.f90:8
character(len=lenmempath) function create_mem_path(component, subcomponent, context)
returns the path to the memory object
subroutine, public get_isize(name, mem_path, isize)
@ brief Get the number of elements for this variable
This module contains the MeshModelModule.
Definition: MeshNCModel.f90:7
subroutine, public ncvar_mf6attr(ncid, varid, layer, iaux, nc_tag, nc_fname)
put variable internal attributes
subroutine define_gridmap(this)
create the file grid mapping container variable
subroutine create_timeseries(this, idt, iparam, iaux, layer, export_pkg)
create timeseries export variable
subroutine, public ncvar_gridmap(ncid, varid, gridmap_name, nc_fname)
put variable gridmap attributes
subroutine, public ncvar_chunk(ncid, varid, chunk_face, nc_fname)
define variable chunking
subroutine mesh_init(this, modelname, modeltype, modelfname, nc_fname, disenum, nctype, lenuni, iout)
initialize
subroutine mesh_destroy(this)
initialize
subroutine add_global_att(this)
create file (group) attributes
subroutine add_pkg_data(this)
determine packages to write gridded input
subroutine df_export(this)
define timeseries input variables
subroutine export_df(this, export_pkg)
define export package
subroutine export_input_arrays(this, pkgtype, pkgname, mempath, param_dfns)
write package gridded input data
subroutine define_dependent(this)
create the model layer dependent variables
subroutine, public ncvar_deflate(ncid, varid, deflate, shuffle, nc_fname)
define variable compression
subroutine create_mesh(this)
create the file mesh container variable
This module contains the NCModelExportModule.
Definition: NCModel.f90:8
character(len=linelength) function, public wkt_to_cf_gridmapping(wkt)
map a WKT string to a CF-1.11 grid_mapping_name
Definition: NCModel.f90:571
character(len=linelength) function, public export_varname(pkgname, tagname, mempath, layer, iaux)
build netcdf variable name
Definition: NCModel.f90:452
character(len=linelength) function, public export_longname(longname, pkgname, tagname, mempath, layer, iaux, component_type, subcomponent_type)
build netcdf variable longname
Definition: NCModel.f90:493
This module contains the NetCDFCommonModule.
Definition: NetCDFCommon.f90:6
subroutine, public nf_verify(res, nc_fname)
error check a netcdf-fortran interface call
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public store_warning(msg, substring)
Store warning message.
Definition: Sim.f90:236
subroutine, public store_error(msg, terminate)
Store an error message.
Definition: Sim.f90:92
subroutine, public store_error_filename(filename, terminate)
Store the erroring file name.
Definition: Sim.f90:203
This module contains simulation variables.
Definition: SimVariables.f90:9
character(len=maxcharlen) errmsg
error message string
character(len=linelength) idm_context
character(len=maxcharlen) warnmsg
warning message string
This module contains the SourceCommonModule.
Definition: SourceCommon.f90:7
character(len=lencomponentname) function, public idm_subcomponent_type(component, subcomponent)
component from package or model type
This class is used to store a single deferred-length character string. It was designed to work in an ...
Definition: CharString.f90:23
Input parameter definition. Describes an input parameter.
base ugrid netcdf export type
Definition: MeshNCModel.f90:62
type for storing model export dimension ids
Definition: MeshNCModel.f90:33
type for storing model export variable ids
Definition: MeshNCModel.f90:44
abstract type for model netcdf export type
Definition: NCModel.f90:108