Skip to content

Commit 16b61a5

Browse files
mjrenomjreno
andauthored
refactor(netcdf): updates focused on flopy parity (#2163)
* fix dis mesh_face_x array * rotate mesh x and y coordinates * name adjustment for internal global attrs * rework structured export proj and coords, support feet lenuni * add warning when wkt provided for rotated grid with structured export * add filename to warnings * make error string clear --------- Co-authored-by: mjreno <[email protected]>
1 parent c388ad2 commit 16b61a5

File tree

7 files changed

+155
-68
lines changed

7 files changed

+155
-68
lines changed

doc/mf6io/mf6ivar/dfn/utl-ncf.dfn

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ shape lenbigline
1010
reader urword
1111
optional true
1212
longname CRS well-known text (WKT) string
13-
description is the coordinate reference system (CRS) well-known text (WKT) string.
13+
description is the coordinate reference system (CRS) well-known text (WKT) string. Ignored if latitude and longitude griddata arrays have been provided for NETCDF\_STRUCTURED export type.
1414

1515
block options
1616
name deflate
@@ -96,7 +96,7 @@ shape (ncpl)
9696
optional true
9797
reader readarray
9898
longname cell center latitude
99-
description cell center latitude.
99+
description cell center latitude. Only supported for NETCDF\_STRUCTURED export type.
100100

101101
block griddata
102102
name longitude
@@ -105,4 +105,4 @@ shape (ncpl)
105105
optional true
106106
reader readarray
107107
longname cell center longitude
108-
description cell center longitude.
108+
description cell center longitude. Only supported for NETCDF\_STRUCTURED export type.

src/Utilities/Export/DisNCMesh.f90

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ subroutine dis_export_init(this, modelname, modeltype, modelfname, nc_fname, &
6969

7070
! initialize base class
7171
call this%mesh_init(modelname, modeltype, modelfname, nc_fname, disenum, &
72-
nctype, iout)
72+
nctype, this%dis%lenuni, iout)
7373
end subroutine dis_export_init
7474

7575
!> @brief netcdf export dis destroy
@@ -457,12 +457,13 @@ end subroutine define_dim
457457
!> @brief netcdf export add mesh information
458458
!<
459459
subroutine add_mesh_data(this)
460+
use BaseDisModule, only: dis_transform_xy
460461
class(Mesh2dDisExportType), intent(inout) :: this
461462
integer(I4B) :: cnt, maxvert, m
462463
integer(I4B), dimension(:), allocatable :: verts
463464
real(DP), dimension(:), allocatable :: bnds
464465
integer(I4B) :: i, j
465-
real(DP) :: x, y
466+
real(DP) :: x, y, x_transform, y_transform
466467
real(DP), dimension(:), allocatable :: node_x, node_y
467468
real(DP), dimension(:), allocatable :: cell_x, cell_y
468469

@@ -485,13 +486,18 @@ subroutine add_mesh_data(this)
485486
cnt = 0
486487
node_x = NF90_FILL_DOUBLE
487488
node_y = NF90_FILL_DOUBLE
488-
y = this%dis%yorigin + sum(this%dis%delc)
489+
y = sum(this%dis%delc)
489490
do j = this%dis%nrow, 0, -1
490-
x = this%dis%xorigin
491+
x = 0
491492
do i = this%dis%ncol, 0, -1
492493
cnt = cnt + 1
493-
node_x(cnt) = x
494-
node_y(cnt) = y
494+
call dis_transform_xy(x, y, &
495+
this%dis%xorigin, &
496+
this%dis%yorigin, &
497+
this%dis%angrot, &
498+
x_transform, y_transform)
499+
node_x(cnt) = x_transform
500+
node_y(cnt) = y_transform
495501
if (i > 0) x = x + this%dis%delr(i)
496502
end do
497503
if (j > 0) y = y - this%dis%delc(j)
@@ -508,13 +514,17 @@ subroutine add_mesh_data(this)
508514
cell_x = NF90_FILL_DOUBLE
509515
cell_y = NF90_FILL_DOUBLE
510516
do j = 1, this%dis%nrow
511-
x = this%dis%xorigin
512-
y = this%dis%celly(j) + this%dis%yorigin
517+
y = this%dis%celly(j)
513518
do i = 1, this%dis%ncol
514-
cell_x(cnt) = x
515-
cell_y(cnt) = y
519+
x = this%dis%cellx(i)
520+
call dis_transform_xy(x, y, &
521+
this%dis%xorigin, &
522+
this%dis%yorigin, &
523+
this%dis%angrot, &
524+
x_transform, y_transform)
525+
cell_x(cnt) = x_transform
526+
cell_y(cnt) = y_transform
516527
cnt = cnt + 1
517-
x = this%dis%cellx(i) + this%dis%xorigin
518528
end do
519529
end do
520530

src/Utilities/Export/DisNCStructured.f90

Lines changed: 59 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ module DisNCStructuredModule
99

1010
use KindModule, only: DP, I4B, LGP
1111
use ConstantsModule, only: LINELENGTH, LENBIGLINE, LENCOMPONENTNAME, &
12-
LENMEMPATH, LENVARNAME
12+
LENMEMPATH, LENVARNAME, DNODATA, DZERO
1313
use SimVariablesModule, only: errmsg, warnmsg
1414
use SimModule, only: store_error, store_warning, store_error_filename
1515
use MemoryManagerModule, only: mem_setptr
@@ -75,7 +75,7 @@ module DisNCStructuredModule
7575
procedure :: define_dim
7676
procedure :: define_dependent
7777
procedure :: define_gridmap
78-
procedure :: define_projection
78+
procedure :: define_geocoords
7979
procedure :: add_proj_data
8080
procedure :: add_grid_data
8181
end type DisNCStructuredType
@@ -127,6 +127,7 @@ subroutine dis_export_init(this, modelname, modeltype, modelfname, nc_fname, &
127127
! initialize base class
128128
call this%NCModelExportType%init(modelname, modeltype, modelfname, nc_fname, &
129129
disenum, nctype, iout)
130+
130131
! update values from input context
131132
if (this%ncf_mempath /= '') then
132133
call mem_set_value(this%chunk_z, 'CHUNK_Z', this%ncf_mempath, found)
@@ -144,7 +145,7 @@ subroutine dis_export_init(this, modelname, modeltype, modelfname, nc_fname, &
144145
this%chunk_x = -1
145146
write (warnmsg, '(a)') 'Ignoring user provided NetCDF chunking &
146147
&parameters. Define chunk_time, chunk_x, chunk_y and chunk_z input &
147-
&parameters to see an effect.'
148+
&parameters to see an effect in file "'//trim(nc_fname)//'".'
148149
call store_warning(warnmsg)
149150
end if
150151

@@ -153,9 +154,32 @@ subroutine dis_export_init(this, modelname, modeltype, modelfname, nc_fname, &
153154

154155
if (latsz > 0 .and. lonsz > 0) then
155156
this%latlon = .true.
157+
if (this%wkt /= '') then
158+
write (warnmsg, '(a)') 'Ignoring user provided NetCDF wkt parameter &
159+
&as longitude and latitude arrays have been provided. &
160+
&Applies to file "'//trim(nc_fname)//'".'
161+
call store_warning(warnmsg)
162+
this%wkt = ''
163+
this%gridmap_name = ''
164+
end if
156165
call mem_setptr(this%latitude, 'LATITUDE', this%ncf_mempath)
157166
call mem_setptr(this%longitude, 'LONGITUDE', this%ncf_mempath)
158167
end if
168+
169+
if (this%wkt /= '') then
170+
if (this%dis%angrot /= DZERO) then
171+
write (warnmsg, '(a)') 'WKT parameter set with structured rotated &
172+
&grid. Projected coordinates will have grid local values. &
173+
&Applies to file "'//trim(nc_fname)//'".'
174+
call store_warning(warnmsg)
175+
end if
176+
end if
177+
end if
178+
179+
if (this%dis%lenuni == 1) then
180+
this%lenunits = 'ft'
181+
else
182+
this%lenunits = 'm'
159183
end if
160184

161185
! create the netcdf file
@@ -191,7 +215,7 @@ subroutine df(this)
191215
! define root group dimensions and coordinate variables
192216
call this%define_dim()
193217
! define grid projection variables
194-
call this%define_projection()
218+
call this%define_geocoords()
195219
if (isim_mode /= MVALIDATE) then
196220
! define the dependent variable
197221
call this%define_dependent()
@@ -367,7 +391,6 @@ end subroutine export_input_arrays
367391
!> @brief netcdf export package dynamic input with ilayer index variable
368392
!<
369393
subroutine package_step_ilayer(this, export_pkg, ilayer_varname, ilayer)
370-
use ConstantsModule, only: DNODATA, DZERO
371394
use TdisModule, only: kper
372395
use NCModelExportModule, only: ExportPackageType
373396
use DefinitionSelectModule, only: get_param_definition_type
@@ -515,7 +538,6 @@ end subroutine package_step
515538
!<
516539
subroutine export_layer_3d(this, export_pkg, idt, ilayer_read, ialayer, &
517540
dbl1d, nc_varname, input_attr, iaux)
518-
use ConstantsModule, only: DNODATA, DZERO
519541
use TdisModule, only: kper
520542
use NCModelExportModule, only: ExportPackageType
521543
class(DisNCStructuredType), intent(inout) :: this
@@ -640,10 +662,10 @@ subroutine add_global_att(this)
640662
call nf_verify(nf90_put_att(this%ncid, NF90_GLOBAL, 'source', &
641663
this%annotation%source), this%nc_fname)
642664
! export type (MODFLOW 6)
643-
call nf_verify(nf90_put_att(this%ncid, NF90_GLOBAL, 'modflow6_grid', &
665+
call nf_verify(nf90_put_att(this%ncid, NF90_GLOBAL, 'modflow_grid', &
644666
this%annotation%grid), this%nc_fname)
645667
! MODFLOW 6 model type
646-
call nf_verify(nf90_put_att(this%ncid, NF90_GLOBAL, 'modflow6_model', &
668+
call nf_verify(nf90_put_att(this%ncid, NF90_GLOBAL, 'modflow_model', &
647669
this%annotation%model), this%nc_fname)
648670
! generation datetime
649671
call nf_verify(nf90_put_att(this%ncid, NF90_GLOBAL, 'history', &
@@ -707,8 +729,8 @@ subroutine define_dim(this)
707729
this%nc_fname)
708730
call nf_verify(nf90_def_var(this%ncid, 'y', NF90_DOUBLE, this%dim_ids%y, &
709731
this%var_ids%y), this%nc_fname)
710-
call nf_verify(nf90_put_att(this%ncid, this%var_ids%y, 'units', 'm'), &
711-
this%nc_fname)
732+
call nf_verify(nf90_put_att(this%ncid, this%var_ids%y, 'units', &
733+
this%lenunits), this%nc_fname)
712734
call nf_verify(nf90_put_att(this%ncid, this%var_ids%y, 'axis', 'Y'), &
713735
this%nc_fname)
714736
call nf_verify(nf90_put_att(this%ncid, this%var_ids%y, 'standard_name', &
@@ -730,8 +752,8 @@ subroutine define_dim(this)
730752
this%nc_fname)
731753
call nf_verify(nf90_def_var(this%ncid, 'x', NF90_DOUBLE, this%dim_ids%x, &
732754
this%var_ids%x), this%nc_fname)
733-
call nf_verify(nf90_put_att(this%ncid, this%var_ids%x, 'units', 'm'), &
734-
this%nc_fname)
755+
call nf_verify(nf90_put_att(this%ncid, this%var_ids%x, 'units', &
756+
this%lenunits), this%nc_fname)
735757
call nf_verify(nf90_put_att(this%ncid, this%var_ids%x, 'axis', 'X'), &
736758
this%nc_fname)
737759
call nf_verify(nf90_put_att(this%ncid, this%var_ids%x, 'standard_name', &
@@ -782,7 +804,7 @@ subroutine define_dependent(this)
782804

783805
! put attr
784806
call nf_verify(nf90_put_att(this%ncid, this%var_ids%dependent, &
785-
'units', 'm'), this%nc_fname)
807+
'units', this%lenunits), this%nc_fname)
786808
call nf_verify(nf90_put_att(this%ncid, this%var_ids%dependent, &
787809
'standard_name', this%annotation%stdname), &
788810
this%nc_fname)
@@ -816,9 +838,9 @@ end subroutine define_gridmap
816838

817839
!> @brief define grid projection variables
818840
!<
819-
subroutine define_projection(this)
841+
subroutine define_geocoords(this)
820842
class(DisNCStructuredType), intent(inout) :: this
821-
if (this%latlon .and. this%wkt /= '') then
843+
if (this%latlon) then
822844
! lat
823845
call nf_verify(nf90_def_var(this%ncid, 'lat', NF90_DOUBLE, &
824846
(/this%dim_ids%x, this%dim_ids%y/), &
@@ -841,13 +863,13 @@ subroutine define_projection(this)
841863
call nf_verify(nf90_put_att(this%ncid, this%var_ids%longitude, &
842864
'long_name', 'longitude'), this%nc_fname)
843865
end if
844-
end subroutine define_projection
866+
end subroutine define_geocoords
845867

846868
!> @brief add grid projection data
847869
!<
848870
subroutine add_proj_data(this)
849871
class(DisNCStructuredType), intent(inout) :: this
850-
if (this%latlon .and. this%wkt /= '') then
872+
if (this%latlon) then
851873
! lat
852874
call nf_verify(nf90_put_var(this%ncid, this%var_ids%latitude, &
853875
this%latitude, start=(/1, 1/), &
@@ -869,16 +891,25 @@ subroutine add_grid_data(this)
869891
integer(I4B) :: ibnd, n !, k, i, j
870892
real(DP), dimension(:, :), pointer, contiguous :: dbl2d
871893
real(DP), dimension(:), allocatable :: x, y
894+
real(DP) :: xoff, yoff
895+
896+
if (this%dis%angrot /= DZERO) then
897+
xoff = DZERO
898+
yoff = DZERO
899+
else
900+
xoff = this%dis%xorigin
901+
yoff = this%dis%yorigin
902+
end if
872903

873904
allocate (x(size(this%dis%cellx)))
874905
allocate (y(size(this%dis%celly)))
875906

876907
do n = 1, size(this%dis%cellx)
877-
x(n) = this%dis%cellx(n) + this%dis%xorigin
908+
x(n) = this%dis%cellx(n) + xoff
878909
end do
879910

880911
do n = 1, size(this%dis%celly)
881-
y(n) = this%dis%celly(n) + this%dis%yorigin
912+
y(n) = this%dis%celly(n) + yoff
882913
end do
883914

884915
call nf_verify(nf90_put_var(this%ncid, this%var_ids%x, x), &
@@ -897,8 +928,8 @@ subroutine add_grid_data(this)
897928
ibnd = 1
898929
do n = 1, size(this%dis%cellx)
899930
if (ibnd == 1) then
900-
dbl2d(1, ibnd) = this%dis%xorigin
901-
dbl2d(2, ibnd) = this%dis%xorigin + this%dis%delr(ibnd)
931+
dbl2d(1, ibnd) = xoff
932+
dbl2d(2, ibnd) = xoff + this%dis%delr(ibnd)
902933
else
903934
dbl2d(1, ibnd) = dbl2d(1, ibnd - 1) + this%dis%delr(ibnd)
904935
dbl2d(2, ibnd) = dbl2d(2, ibnd - 1) + this%dis%delr(ibnd)
@@ -914,8 +945,8 @@ subroutine add_grid_data(this)
914945
ibnd = 1
915946
do n = size(this%dis%celly), 1, -1
916947
if (ibnd == 1) then
917-
dbl2d(1, ibnd) = this%dis%yorigin + sum(this%dis%delc) - this%dis%delc(n)
918-
dbl2d(2, ibnd) = this%dis%yorigin + sum(this%dis%delc)
948+
dbl2d(1, ibnd) = yoff + sum(this%dis%delc) - this%dis%delc(n)
949+
dbl2d(2, ibnd) = yoff + sum(this%dis%delc)
919950
else
920951
dbl2d(1, ibnd) = dbl2d(1, ibnd - 1) - this%dis%delc(n)
921952
dbl2d(2, ibnd) = dbl2d(2, ibnd - 1) - this%dis%delc(n)
@@ -982,15 +1013,13 @@ subroutine ncvar_gridmap(ncid, varid, gridmap_name, latlon, nc_fname)
9821013
logical(LGP), intent(in) :: latlon
9831014
character(len=*), intent(in) :: nc_fname
9841015
if (gridmap_name /= '') then
985-
if (latlon) then
986-
call nf_verify(nf90_put_att(ncid, varid, 'coordinates', 'lon lat'), &
987-
nc_fname)
988-
else
989-
call nf_verify(nf90_put_att(ncid, varid, 'coordinates', 'x y'), &
990-
nc_fname)
991-
end if
1016+
call nf_verify(nf90_put_att(ncid, varid, 'coordinates', 'x y'), &
1017+
nc_fname)
9921018
call nf_verify(nf90_put_att(ncid, varid, 'grid_mapping', gridmap_name), &
9931019
nc_fname)
1020+
else if (latlon) then
1021+
call nf_verify(nf90_put_att(ncid, varid, 'coordinates', 'lon lat'), &
1022+
nc_fname)
9941023
end if
9951024
end subroutine ncvar_gridmap
9961025

0 commit comments

Comments
 (0)