From 3957ce80c88628cc6f7cfb1652c8d871288e0794 Mon Sep 17 00:00:00 2001 From: Joseph Hughes Date: Tue, 17 Dec 2024 17:29:02 -0600 Subject: [PATCH 1/6] fix(csub): CSUB observations Make mf6io and code consistent. Closes #1447 --- doc/Common/gwf-csubobs.tex | 20 ++++---- doc/mf6io/mf6io.tex | 2 +- src/Model/GroundWaterFlow/gwf-csub.f90 | 66 ++++++++++++++------------ 3 files changed, 46 insertions(+), 42 deletions(-) diff --git a/doc/Common/gwf-csubobs.tex b/doc/Common/gwf-csubobs.tex index 8d718c45a8f..8cda8cd940c 100644 --- a/doc/Common/gwf-csubobs.tex +++ b/doc/Common/gwf-csubobs.tex @@ -25,20 +25,20 @@ CSUB & coarse-thickness & cellid & -- & thickness of coarse-grained materials in a GWF cell. \\ CSUB & thickness-cell & cellid & -- & total thickness of coarse-grained materials and all interbeds in a GWF cell. \\ -CSUB & theta & icsubno & -- & porosity of a interbed . \\ +CSUB & theta & icsubno or boundname & -- & porosity of a interbed or group of interbeds. \\ CSUB & coarse-theta & cellid & -- & porosity of coarse-grained materials in a GWF cell. \\ CSUB & theta-cell & cellid & -- & thickness-weighted porosity of coarse-grained materials and all interbeds in a GWF cell. \\ -CSUB & delay-flowtop & icsubno & -- & Flow between the groundwater system and a delay interbed across the top of the interbed. \\ -CSUB & delay-flowbot & icsubno & -- & Flow between the groundwater system and a delay interbed across the bottom of the interbed. \\ +CSUB & delay-flowtop & icsubno or boundname & -- & Flow between the groundwater system and a delay interbed or group of interbeds across the top of the interbed(s). \\ +CSUB & delay-flowbot & icsubno or boundname & -- & Flow between the groundwater system and a delay interbed or group of interbeds across the bottom of the interbed(s). \\ -CSUB & delay-head & icsubno & idcellno & head in interbed delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). The NODATA value is reported for steady-state stress periods. \\ -CSUB & delay-gstress & icsubno & idcellno & geostatic stress in interbed delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). The NODATA value is reported for steady-state stress periods. \\ -CSUB & delay-estress & icsubno & idcellno & effective stress in interbed delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). The NODATA value is reported for steady-state stress periods. \\ -CSUB & delay-preconstress & icsubno & idcellno & preconsolidation stress in interbed delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). The NODATA value is reported for steady-state stress periods. \\ -CSUB & delay-compaction & icsubno & idcellno & compaction in interbed delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). \\ -CSUB & delay-thickness & icsubno & idcellno & thickness of interbed delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). \\ -CSUB & delay-theta & icsubno & idcellno & porosity of interbed delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). \\ +CSUB & delay-head & icsubno or boundname & idcellno & head in interbed or group of interbeds in delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). The NODATA value is reported for steady-state stress periods. \\ +CSUB & delay-gstress & icsubno or boundname & idcellno & geostatic stress in interbed or group of interbeds in delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). The NODATA value is reported for steady-state stress periods. \\ +CSUB & delay-estress & icsubno or boundname & idcellno & effective stress in interbed or group of interbeds in delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). The NODATA value is reported for steady-state stress periods. \\ +CSUB & delay-preconstress & icsubno or boundname & idcellno & preconsolidation stress in interbed or group of interbeds in delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). The NODATA value is reported for steady-state stress periods. \\ +CSUB & delay-compaction & icsubno or boundname & idcellno & compaction in interbed or group of interbeds in delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). \\ +CSUB & delay-thickness & icsubno or boundname & idcellno & thickness of interbed or group of interbeds in delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). \\ +CSUB & delay-theta & icsubno or boundname & idcellno & porosity of interbed or group of interbeds in delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). \\ CSUB & preconstress-cell & cellid & -- & preconsolidation stress in a GWF cell containing at least one interbed. The NODATA value is reported for steady-state stress periods. diff --git a/doc/mf6io/mf6io.tex b/doc/mf6io/mf6io.tex index 2172bac78db..d3461616dd5 100644 --- a/doc/mf6io/mf6io.tex +++ b/doc/mf6io/mf6io.tex @@ -73,7 +73,7 @@ \renewcommand\labelitemi{\tiny$\bullet$} \renewcommand{\cooperator} -{the \textusgs\ Water Availability and Use Science Program} +{Water Availability and Use Science Program} \renewcommand{\reporttitle} {MODFLOW 6 -- Description of Input and Output} diff --git a/src/Model/GroundWaterFlow/gwf-csub.f90 b/src/Model/GroundWaterFlow/gwf-csub.f90 index c8aba18c1fa..bb1174e73b6 100644 --- a/src/Model/GroundWaterFlow/gwf-csub.f90 +++ b/src/Model/GroundWaterFlow/gwf-csub.f90 @@ -6790,22 +6790,22 @@ subroutine csub_df_obs(this) ! ! -- Store obs type and assign procedure pointer ! for interbed ske observation type. - call this%obs%StoreObsType('ske', .true., indx) + call this%obs%StoreObsType('ske', .false., indx) this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsID ! ! -- Store obs type and assign procedure pointer ! for interbed sk observation type. - call this%obs%StoreObsType('sk', .true., indx) + call this%obs%StoreObsType('sk', .false., indx) this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsID ! ! -- Store obs type and assign procedure pointer ! for ske-cell observation type. - call this%obs%StoreObsType('ske-cell', .true., indx) + call this%obs%StoreObsType('ske-cell', .false., indx) this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsID ! ! -- Store obs type and assign procedure pointer ! for sk-cell observation type. - call this%obs%StoreObsType('sk-cell', .true., indx) + call this%obs%StoreObsType('sk-cell', .false., indx) this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsID ! ! -- Store obs type and assign procedure pointer @@ -6820,17 +6820,17 @@ subroutine csub_df_obs(this) ! ! -- Store obs type and assign procedure pointer ! for total-compaction observation type. - call this%obs%StoreObsType('interbed-compaction', .true., indx) + call this%obs%StoreObsType('interbed-compaction', .false., indx) this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsID ! ! -- Store obs type and assign procedure pointer ! for inelastic-compaction observation type. - call this%obs%StoreObsType('inelastic-compaction', .true., indx) + call this%obs%StoreObsType('inelastic-compaction', .false., indx) this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsID ! ! -- Store obs type and assign procedure pointer ! for inelastic-compaction observation type. - call this%obs%StoreObsType('elastic-compaction', .true., indx) + call this%obs%StoreObsType('elastic-compaction', .false., indx) this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsID ! ! -- Store obs type and assign procedure pointer @@ -6840,22 +6840,22 @@ subroutine csub_df_obs(this) ! ! -- Store obs type and assign procedure pointer ! for inelastic-compaction-cell observation type. - call this%obs%StoreObsType('inelastic-compaction-cell', .true., indx) + call this%obs%StoreObsType('inelastic-compaction-cell', .false., indx) this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsID ! ! -- Store obs type and assign procedure pointer ! for elastic-compaction-cell observation type. - call this%obs%StoreObsType('elastic-compaction-cell', .true., indx) + call this%obs%StoreObsType('elastic-compaction-cell', .false., indx) this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsID ! ! -- Store obs type and assign procedure pointer ! for compaction-cell observation type. - call this%obs%StoreObsType('compaction-cell', .true., indx) + call this%obs%StoreObsType('compaction-cell', .false., indx) this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsID ! ! -- Store obs type and assign procedure pointer ! for interbed thickness observation type. - call this%obs%StoreObsType('thickness', .true., indx) + call this%obs%StoreObsType('thickness', .false., indx) this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsID ! ! -- Store obs type and assign procedure pointer @@ -6870,7 +6870,7 @@ subroutine csub_df_obs(this) ! ! -- Store obs type and assign procedure pointer ! for interbed theta observation type. - call this%obs%StoreObsType('theta', .true., indx) + call this%obs%StoreObsType('theta', .false., indx) this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsID ! ! -- Store obs type and assign procedure pointer @@ -6880,7 +6880,7 @@ subroutine csub_df_obs(this) ! ! -- Store obs type and assign procedure pointer ! for theta-cell observation type. - call this%obs%StoreObsType('theta-cell', .true., indx) + call this%obs%StoreObsType('theta-cell', .false., indx) this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsID ! ! -- Store obs type and assign procedure pointer @@ -7355,20 +7355,20 @@ subroutine csub_process_obsID(obsrv, dis, inunitobs, iout) if (obsrv%ObsTypeId == 'CSUB' .or. & obsrv%ObsTypeId == 'INELASTIC-CSUB' .or. & obsrv%ObsTypeId == 'ELASTIC-CSUB' .or. & - obsrv%ObsTypeId == 'SK' .or. & - obsrv%ObsTypeId == 'SKE' .or. & - obsrv%ObsTypeId == 'THETA' .or. & - obsrv%ObsTypeId == 'THICKNESS' .or. & - obsrv%ObsTypeId == 'INTERBED-COMPACTION' .or. & - obsrv%ObsTypeId == 'INELASTIC-COMPACTION' .or. & - obsrv%ObsTypeId == 'ELASTIC-COMPACTION' .or. & - obsrv%ObsTypeId == 'DELAY-HEAD' .or. & - obsrv%ObsTypeId == 'DELAY-GSTRESS' .or. & - obsrv%ObsTypeId == 'DELAY-ESTRESS' .or. & - obsrv%ObsTypeId == 'DELAY-PRECONSTRESS' .or. & - obsrv%ObsTypeId == 'DELAY-COMPACTION' .or. & - obsrv%ObsTypeId == 'DELAY-THICKNESS' .or. & - obsrv%ObsTypeId == 'DELAY-THETA' .or. & + ! obsrv%ObsTypeId == 'SK' .or. & + ! obsrv%ObsTypeId == 'SKE' .or. & + ! obsrv%ObsTypeId == 'THETA' .or. & + ! obsrv%ObsTypeId == 'THICKNESS' .or. & + ! obsrv%ObsTypeId == 'INTERBED-COMPACTION' .or. & + ! obsrv%ObsTypeId == 'INELASTIC-COMPACTION' .or. & + ! obsrv%ObsTypeId == 'ELASTIC-COMPACTION' .or. & + ! obsrv%ObsTypeId == 'DELAY-HEAD' .or. & + ! obsrv%ObsTypeId == 'DELAY-GSTRESS' .or. & + ! obsrv%ObsTypeId == 'DELAY-ESTRESS' .or. & + ! obsrv%ObsTypeId == 'DELAY-PRECONSTRESS' .or. & + ! obsrv%ObsTypeId == 'DELAY-COMPACTION' .or. & + ! obsrv%ObsTypeId == 'DELAY-THICKNESS' .or. & + ! obsrv%ObsTypeId == 'DELAY-THETA' .or. & obsrv%ObsTypeId == 'DELAY-FLOWTOP' .or. & obsrv%ObsTypeId == 'DELAY-FLOWBOT') then call extract_idnum_or_bndname(string, icol, istart, istop, nn1, bndname) @@ -7388,16 +7388,20 @@ subroutine csub_process_obsID(obsrv, dis, inunitobs, iout) obsrv%ObsTypeId == 'DELAY-THETA') then call extract_idnum_or_bndname(string, icol, istart, istop, nn2, bndname) if (nn2 == NAMEDBOUNDFLAG) then - obsrv%FeatureName = bndname - ! -- reset nn1 - nn1 = nn2 + write (errmsg, '(3a)') & + "BOUNDNAME cannot be specified for CSUB package '", & + trim(obsrv%ObsTypeId), "' observation type." + call store_error(errmsg) + ! obsrv%FeatureName = bndname + ! ! -- reset nn1 + ! nn1 = nn2 else obsrv%NodeNumber2 = nn2 end if end if end if ! - ! -- store reach number (NodeNumber) + ! -- store observation location (NodeNumber) obsrv%NodeNumber = nn1 end subroutine csub_process_obsID From 0f9463b44c6c24bb615fd8c2577ed7bf75895e32 Mon Sep 17 00:00:00 2001 From: Joseph Hughes Date: Wed, 18 Dec 2024 17:27:40 -0600 Subject: [PATCH 2/6] add observation test --- autotest/test_gwf_csub_obs.py | 221 +++++++++++++++++++++++++ doc/Common/gwf-csubobs.tex | 36 ++-- doc/mf6io/gwf/csub.tex | 1 + src/Model/GroundWaterFlow/gwf-csub.f90 | 129 +++++++++------ 4 files changed, 321 insertions(+), 66 deletions(-) create mode 100644 autotest/test_gwf_csub_obs.py diff --git a/autotest/test_gwf_csub_obs.py b/autotest/test_gwf_csub_obs.py new file mode 100644 index 00000000000..9ed986a7a33 --- /dev/null +++ b/autotest/test_gwf_csub_obs.py @@ -0,0 +1,221 @@ +import os + +import flopy +import numpy as np +import pytest +from framework import TestFramework + +obs_names = [ + "delay-flowtop", "delay-flowtop", + "delay-flowbot", "delay-flowbot", + "delay-head", "delay-head", + ] +boundname = [ + False, True, + False, True, + False, True, + ] +test_fail = [ + False, False, + False, False, + False, True, + ] +cases = [f"csub_obs{idx + 1:02d}" for idx, _ in enumerate(obs_names)] + +paktest = "csub" +budtol = 1e-2 +ndcell = [19] * len(cases) + +# static model data +# spatial discretization +nlay, nrow, ncol = 1, 1, 3 +shape3d = (nlay, nrow, ncol) +size3d = nlay * nrow * ncol +delr, delc = 1.0, 1.0 +top = 0.0 +botm = [-100.0] + +# temporal discretization +nper = 1 +perlen = [1000.0 for _ in range(nper)] +nstp = [100 for _ in range(nper)] +tsmult = [1.05 for _ in range(nper)] +steady = [False for _ in range(nper)] + +strt = 0.0 +strt6 = 1.0 +hnoflo = 1e30 +hdry = -1e30 +hk = 1e6 +laytyp = [0] +S = 1e-4 +sy = 0.0 + +nouter, ninner = 1000, 300 +hclose, rclose, relax = 1e-6, 1e-6, 0.97 + +tdis_rc = [] +for i in range(nper): + tdis_rc.append((perlen[i], nstp[i], tsmult[i])) + +ib = 1 + +c = [] +c6 = [] +for j in range(0, ncol, 2): + c.append([0, 0, j, strt, strt]) + c6.append([(0, 0, j), strt]) +cd = {0: c} +cd6 = {0: c6} + +# sub data +ndb = 1 +nndb = 0 +cc = 100.0 +cr = 1.0 +void = 0.82 +theta = void / (1.0 + void) +kv = 0.025 +sgm = 0.0 +sgs = 0.0 +ini_stress = 1.0 +thick = [1.0] +sfe = cr * thick[0] +sfv = cc * thick[0] +lnd = [0] +ldnd = [0] +dp = [[kv, cr, cc]] +ss = S / (100.0 - thick[0]) + +ds15 = [0, 0, 0, 2052, 0, 0, 0, 0, 0, 0, 0, 0] +ds16 = [0, 0, 0, 100, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1] + + +def get_model(idx, ws): + name = cases[idx] + + sim = flopy.mf6.MFSimulation( + sim_name=name, version="mf6", exe_name="mf6", sim_ws=ws + ) + # create tdis package + tdis = flopy.mf6.ModflowTdis(sim, time_units="DAYS", nper=nper, perioddata=tdis_rc) + + # create iterative model solution + ims = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="CG", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + ) + + # create gwf model + gwf = flopy.mf6.ModflowGwf(sim, modelname=name) + + dis = flopy.mf6.ModflowGwfdis( + gwf, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + filename=f"{name}.dis", + ) + + # initial conditions + ic = flopy.mf6.ModflowGwfic(gwf, strt=strt, filename=f"{name}.ic") + + # node property flow + npf = flopy.mf6.ModflowGwfnpf(gwf, save_flows=False, icelltype=laytyp, k=hk, k33=hk) + # storage + sto = flopy.mf6.ModflowGwfsto( + gwf, + save_flows=False, + iconvert=laytyp, + ss=0.0, + sy=sy, + storagecoefficient=True, + transient={0: True}, + ) + + # chd files + chd = flopy.mf6.modflow.mfgwfchd.ModflowGwfchd( + gwf, maxbound=len(c6), stress_period_data=cd6, save_flows=False + ) + + # csub files + sub6 = [ + [ + 0, + (0, 0, 1), + "delay", + ini_stress, + thick[0], + 1.0, + 230.258658761733000, + 2.302586587617330, + theta, + kv, + ini_stress, + ] + ] + bname = "interbed" + if boundname[idx]: + sub6[0].append(bname) + obs_idx = ("obs_value", obs_names[idx], bname) + else: + obs_idx = ("obs_value", obs_names[idx], (0,), (0,)) + + opth = f"{name}.csub.obs" + csub = flopy.mf6.ModflowGwfcsub( + gwf, + boundnames=boundname[idx], + head_based=False, + print_input=True, + save_flows=True, + ndelaycells=ndcell[idx], + ninterbeds=1, + beta=0.0, + cg_ske_cr=ss, + packagedata=sub6, + ) + orecarray = {} + orecarray["csub_obs.csv"] = [obs_idx] + csub_obs_package = csub.obs.initialize( + filename=opth, digits=10, print_input=True, continuous=orecarray + ) + + # output control + oc = flopy.mf6.ModflowGwfoc( + gwf, + printrecord=[("BUDGET", "ALL")], + ) + + return sim + + +def build_models(idx, test): + sim = get_model(idx, test.workspace) + + return sim, None + + +@pytest.mark.parametrize("idx, name", enumerate(cases)) +def test_mf6model(idx, name, function_tmpdir, targets): + test = TestFramework( + name=name, + workspace=function_tmpdir, + build=lambda t: build_models(idx, t), + targets=targets, + xfail=test_fail[idx], + ) + test.run() diff --git a/doc/Common/gwf-csubobs.tex b/doc/Common/gwf-csubobs.tex index 8cda8cd940c..bb3614c5218 100644 --- a/doc/Common/gwf-csubobs.tex +++ b/doc/Common/gwf-csubobs.tex @@ -5,25 +5,25 @@ CSUB & csub-cell & cellid & -- & Flow between the groundwater system for all interbeds and coarse-grained materials in a GWF cell. \\ CSUB & wcomp-csub-cell & cellid & -- & Flow between the groundwater system for all interbeds and coarse-grained materials in a GWF cell from water compressibility. \\ -CSUB & sk & icsubno or boundname & -- & Convertible interbed storativity in a interbed or group of interbeds. Convertible interbed storativity is inelastic interbed storativity if the current effective stress is greater than the preconsolidation stress. The NODATA value is reported for steady-state stress periods. \\ -CSUB & ske & icsubno or boundname & -- & Elastic interbed storativity in a interbed or group of interbeds. The NODATA value is reported for steady-state stress periods. \\ -CSUB & sk-cell & cellid & -- & Convertible interbed and coarse-grained material storativity in a GWF cell. Convertible interbed storativity is inelastic interbed storativity if the current effective stress is greater than the preconsolidation stress. The NODATA value is reported for steady-state stress periods. \\ -CSUB & ske-cell & cellid & -- & Elastic interbed and coarse-grained material storativity in a GWF cell. The NODATA value is reported for steady-state stress periods. \\ +CSUB & sk & icsubno & -- & Convertible interbed storativity in a interbed. Convertible interbed storativity is inelastic interbed storativity if the current effective stress is greater than the preconsolidation stress. \\ +CSUB & ske & icsubno & -- & Elastic interbed storativity in a interbed. \\ +CSUB & sk-cell & cellid & -- & Convertible interbed and coarse-grained material storativity in a GWF cell. Convertible interbed storativity is inelastic interbed storativity if the current effective stress is greater than the preconsolidation stress. \\ +CSUB & ske-cell & cellid & -- & Elastic interbed and coarse-grained material storativity in a GWF cell. \\ CSUB & estress-cell & cellid & -- & effective stress in a GWF cell. \\ CSUB & gstress-cell & cellid & -- & geostatic stress in a GWF cell. \\ -CSUB & interbed-compaction & icsubno or boundname & -- & interbed compaction in a interbed or group of interbeds. \\ -CSUB & inelastic-compaction & icsubno or boundname & -- & inelastic interbed compaction in a interbed or group of interbeds. \\ -CSUB & elastic-compaction & icsubno or boundname & -- & elastic interbed compaction a interbed or group of interbeds. \\ +CSUB & interbed-compaction & icsubno & -- & interbed compaction in a interbed. \\ +CSUB & inelastic-compaction & icsubno & -- & inelastic interbed compaction in a interbed. \\ +CSUB & elastic-compaction & icsubno & -- & elastic interbed compaction a interbed. \\ CSUB & coarse-compaction & cellid & -- & elastic compaction in coarse-grained materials in a GWF cell. \\ CSUB & inelastic-compaction-cell & cellid & -- & inelastic compaction in all interbeds in a GWF cell. \\ CSUB & elastic-compaction-cell & cellid & -- & elastic compaction in coarse-grained materials and all interbeds in a GWF cell. \\ CSUB & compaction-cell & cellid & -- & total compaction in coarse-grained materials and all interbeds in a GWF cell. \\ -CSUB & thickness & icsubno or boundname & -- & thickness of a interbed or group of interbeds. \\ -CSUB & coarse-thickness & cellid & -- & thickness of coarse-grained materials in a GWF cell. \\ -CSUB & thickness-cell & cellid & -- & total thickness of coarse-grained materials and all interbeds in a GWF cell. \\ +CSUB & thickness & icsubno & -- & thickness of a interbed. \\ +CSUB & coarse-thickness & cellid & -- & thickness of coarse-grained materials in a GWF cell. \\ +CSUB & thickness-cell & cellid & -- & total thickness of coarse-grained materials and all interbeds in a GWF cell. \\ CSUB & theta & icsubno or boundname & -- & porosity of a interbed or group of interbeds. \\ CSUB & coarse-theta & cellid & -- & porosity of coarse-grained materials in a GWF cell. \\ @@ -32,13 +32,13 @@ CSUB & delay-flowtop & icsubno or boundname & -- & Flow between the groundwater system and a delay interbed or group of interbeds across the top of the interbed(s). \\ CSUB & delay-flowbot & icsubno or boundname & -- & Flow between the groundwater system and a delay interbed or group of interbeds across the bottom of the interbed(s). \\ -CSUB & delay-head & icsubno or boundname & idcellno & head in interbed or group of interbeds in delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). The NODATA value is reported for steady-state stress periods. \\ -CSUB & delay-gstress & icsubno or boundname & idcellno & geostatic stress in interbed or group of interbeds in delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). The NODATA value is reported for steady-state stress periods. \\ -CSUB & delay-estress & icsubno or boundname & idcellno & effective stress in interbed or group of interbeds in delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). The NODATA value is reported for steady-state stress periods. \\ -CSUB & delay-preconstress & icsubno or boundname & idcellno & preconsolidation stress in interbed or group of interbeds in delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). The NODATA value is reported for steady-state stress periods. \\ -CSUB & delay-compaction & icsubno or boundname & idcellno & compaction in interbed or group of interbeds in delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). \\ -CSUB & delay-thickness & icsubno or boundname & idcellno & thickness of interbed or group of interbeds in delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). \\ -CSUB & delay-theta & icsubno or boundname & idcellno & porosity of interbed or group of interbeds in delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). \\ +CSUB & delay-head & icsubno & idcellno & head in interbed in delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). \\ +CSUB & delay-gstress & icsubno & idcellno & geostatic stress in interbed in delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). \\ +CSUB & delay-estress & icsubno & idcellno & effective stress in interbed in delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). \\ +CSUB & delay-preconstress & icsubno & idcellno & preconsolidation stress in interbed in delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). \\ +CSUB & delay-compaction & icsubno & idcellno & compaction in interbed in delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). \\ +CSUB & delay-thickness & icsubno & idcellno & thickness of interbed or group of interbeds in delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). \\ +CSUB & delay-theta & icsubno & idcellno & porosity of interbed in delay cell idcellno (1 $<=$ idcellno $<=$ NDELAYCELLS). \\ -CSUB & preconstress-cell & cellid & -- & preconsolidation stress in a GWF cell containing at least one interbed. The NODATA value is reported for steady-state stress periods. +CSUB & preconstress-cell & cellid & -- & preconsolidation stress in a GWF cell containing at least one interbed. diff --git a/doc/mf6io/gwf/csub.tex b/doc/mf6io/gwf/csub.tex index 65ec0558246..e42d4fc1d4f 100644 --- a/doc/mf6io/gwf/csub.tex +++ b/doc/mf6io/gwf/csub.tex @@ -49,6 +49,7 @@ \subsubsection{Available observation types} \endhead \hline +\multicolumn{5}{l}{\textbf{NOTE}: The NODATA value is reported for steady-state stress periods.} \\ \endfoot \input{../Common/gwf-csubobs.tex} diff --git a/src/Model/GroundWaterFlow/gwf-csub.f90 b/src/Model/GroundWaterFlow/gwf-csub.f90 index bb1174e73b6..4c19c64d58f 100644 --- a/src/Model/GroundWaterFlow/gwf-csub.f90 +++ b/src/Model/GroundWaterFlow/gwf-csub.f90 @@ -6790,22 +6790,22 @@ subroutine csub_df_obs(this) ! ! -- Store obs type and assign procedure pointer ! for interbed ske observation type. - call this%obs%StoreObsType('ske', .false., indx) + call this%obs%StoreObsType('ske', .true., indx) this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsID ! ! -- Store obs type and assign procedure pointer ! for interbed sk observation type. - call this%obs%StoreObsType('sk', .false., indx) + call this%obs%StoreObsType('sk', .true., indx) this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsID ! ! -- Store obs type and assign procedure pointer ! for ske-cell observation type. - call this%obs%StoreObsType('ske-cell', .false., indx) + call this%obs%StoreObsType('ske-cell', .true., indx) this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsID ! ! -- Store obs type and assign procedure pointer ! for sk-cell observation type. - call this%obs%StoreObsType('sk-cell', .false., indx) + call this%obs%StoreObsType('sk-cell', .true., indx) this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsID ! ! -- Store obs type and assign procedure pointer @@ -6820,17 +6820,17 @@ subroutine csub_df_obs(this) ! ! -- Store obs type and assign procedure pointer ! for total-compaction observation type. - call this%obs%StoreObsType('interbed-compaction', .false., indx) + call this%obs%StoreObsType('interbed-compaction', .true., indx) this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsID ! ! -- Store obs type and assign procedure pointer ! for inelastic-compaction observation type. - call this%obs%StoreObsType('inelastic-compaction', .false., indx) + call this%obs%StoreObsType('inelastic-compaction', .true., indx) this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsID ! ! -- Store obs type and assign procedure pointer ! for inelastic-compaction observation type. - call this%obs%StoreObsType('elastic-compaction', .false., indx) + call this%obs%StoreObsType('elastic-compaction', .true., indx) this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsID ! ! -- Store obs type and assign procedure pointer @@ -6840,22 +6840,22 @@ subroutine csub_df_obs(this) ! ! -- Store obs type and assign procedure pointer ! for inelastic-compaction-cell observation type. - call this%obs%StoreObsType('inelastic-compaction-cell', .false., indx) + call this%obs%StoreObsType('inelastic-compaction-cell', .true., indx) this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsID ! ! -- Store obs type and assign procedure pointer ! for elastic-compaction-cell observation type. - call this%obs%StoreObsType('elastic-compaction-cell', .false., indx) + call this%obs%StoreObsType('elastic-compaction-cell', .true., indx) this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsID ! ! -- Store obs type and assign procedure pointer ! for compaction-cell observation type. - call this%obs%StoreObsType('compaction-cell', .false., indx) + call this%obs%StoreObsType('compaction-cell', .true., indx) this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsID ! ! -- Store obs type and assign procedure pointer ! for interbed thickness observation type. - call this%obs%StoreObsType('thickness', .false., indx) + call this%obs%StoreObsType('thickness', .true., indx) this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsID ! ! -- Store obs type and assign procedure pointer @@ -6870,7 +6870,7 @@ subroutine csub_df_obs(this) ! ! -- Store obs type and assign procedure pointer ! for interbed theta observation type. - call this%obs%StoreObsType('theta', .false., indx) + call this%obs%StoreObsType('theta', .true., indx) this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsID ! ! -- Store obs type and assign procedure pointer @@ -6880,7 +6880,7 @@ subroutine csub_df_obs(this) ! ! -- Store obs type and assign procedure pointer ! for theta-cell observation type. - call this%obs%StoreObsType('theta-cell', .false., indx) + call this%obs%StoreObsType('theta-cell', .true., indx) this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsID ! ! -- Store obs type and assign procedure pointer @@ -7355,53 +7355,86 @@ subroutine csub_process_obsID(obsrv, dis, inunitobs, iout) if (obsrv%ObsTypeId == 'CSUB' .or. & obsrv%ObsTypeId == 'INELASTIC-CSUB' .or. & obsrv%ObsTypeId == 'ELASTIC-CSUB' .or. & - ! obsrv%ObsTypeId == 'SK' .or. & - ! obsrv%ObsTypeId == 'SKE' .or. & - ! obsrv%ObsTypeId == 'THETA' .or. & - ! obsrv%ObsTypeId == 'THICKNESS' .or. & - ! obsrv%ObsTypeId == 'INTERBED-COMPACTION' .or. & - ! obsrv%ObsTypeId == 'INELASTIC-COMPACTION' .or. & - ! obsrv%ObsTypeId == 'ELASTIC-COMPACTION' .or. & - ! obsrv%ObsTypeId == 'DELAY-HEAD' .or. & - ! obsrv%ObsTypeId == 'DELAY-GSTRESS' .or. & - ! obsrv%ObsTypeId == 'DELAY-ESTRESS' .or. & - ! obsrv%ObsTypeId == 'DELAY-PRECONSTRESS' .or. & - ! obsrv%ObsTypeId == 'DELAY-COMPACTION' .or. & - ! obsrv%ObsTypeId == 'DELAY-THICKNESS' .or. & - ! obsrv%ObsTypeId == 'DELAY-THETA' .or. & + obsrv%ObsTypeId == 'SK' .or. & + obsrv%ObsTypeId == 'SKE' .or. & + obsrv%ObsTypeId == 'THETA' .or. & + obsrv%ObsTypeId == 'THICKNESS' .or. & + obsrv%ObsTypeId == 'INTERBED-COMPACTION' .or. & + obsrv%ObsTypeId == 'INELASTIC-COMPACTION' .or. & + obsrv%ObsTypeId == 'ELASTIC-COMPACTION' .or. & + obsrv%ObsTypeId == 'DELAY-HEAD' .or. & + obsrv%ObsTypeId == 'DELAY-GSTRESS' .or. & + obsrv%ObsTypeId == 'DELAY-ESTRESS' .or. & + obsrv%ObsTypeId == 'DELAY-PRECONSTRESS' .or. & + obsrv%ObsTypeId == 'DELAY-COMPACTION' .or. & + obsrv%ObsTypeId == 'DELAY-THICKNESS' .or. & + obsrv%ObsTypeId == 'DELAY-THETA' .or. & obsrv%ObsTypeId == 'DELAY-FLOWTOP' .or. & obsrv%ObsTypeId == 'DELAY-FLOWBOT') then call extract_idnum_or_bndname(string, icol, istart, istop, nn1, bndname) + ! read cellid else nn1 = dis%noder_from_string(icol, istart, istop, inunitobs, & iout, string, flag_string) end if - if (nn1 == NAMEDBOUNDFLAG) then - obsrv%FeatureName = bndname - else - if (obsrv%ObsTypeId == 'DELAY-HEAD' .or. & - obsrv%ObsTypeId == 'DELAY-GSTRESS' .or. & - obsrv%ObsTypeId == 'DELAY-ESTRESS' .or. & - obsrv%ObsTypeId == 'DELAY-PRECONSTRESS' .or. & - obsrv%ObsTypeId == 'DELAY-COMPACTION' .or. & - obsrv%ObsTypeId == 'DELAY-THICKNESS' .or. & - obsrv%ObsTypeId == 'DELAY-THETA') then - call extract_idnum_or_bndname(string, icol, istart, istop, nn2, bndname) - if (nn2 == NAMEDBOUNDFLAG) then - write (errmsg, '(3a)') & - "BOUNDNAME cannot be specified for CSUB package '", & - trim(obsrv%ObsTypeId), "' observation type." + ! boundnames are not allowed for these observation types + if (obsrv%ObsTypeId == 'SK' .or. & + obsrv%ObsTypeId == 'SKE' .or. & + obsrv%ObsTypeId == 'THETA' .or. & + obsrv%ObsTypeId == 'THICKNESS' .or. & + obsrv%ObsTypeId == 'DELAY-HEAD' .or. & + obsrv%ObsTypeId == 'DELAY-GSTRESS' .or. & + obsrv%ObsTypeId == 'DELAY-ESTRESS' .or. & + obsrv%ObsTypeId == 'DELAY-PRECONSTRESS' .or. & + obsrv%ObsTypeId == 'DELAY-COMPACTION' .or. & + obsrv%ObsTypeId == 'DELAY-THICKNESS' .or. & + obsrv%ObsTypeId == 'DELAY-THETA') then + if (nn1 == NAMEDBOUNDFLAG) then + write (errmsg, '(5a)') & + "BOUNDNAME ('", trim(adjustl(bndname)), & + "') not allowed for CSUB observation type '", & + trim(adjustl(obsrv%ObsTypeId)), "'." call store_error(errmsg) - ! obsrv%FeatureName = bndname - ! ! -- reset nn1 - ! nn1 = nn2 - else - obsrv%NodeNumber2 = nn2 + end if + ! boundnames are allowed for these observation types + else if (obsrv%ObsTypeId == 'CSUB' .or. & + obsrv%ObsTypeId == 'INELASTIC-CSUB' .or. & + obsrv%ObsTypeId == 'ELASTIC-CSUB' .or. & + ! obsrv%ObsTypeId == 'THICKNESS' .or. & + obsrv%ObsTypeId == 'INTERBED-COMPACTION' .or. & + obsrv%ObsTypeId == 'INELASTIC-COMPACTION' .or. & + obsrv%ObsTypeId == 'ELASTIC-COMPACTION' .or. & + obsrv%ObsTypeId == 'DELAY-FLOWTOP' .or. & + obsrv%ObsTypeId == 'DELAY-FLOWBOT') then + if (nn1 == NAMEDBOUNDFLAG) then + obsrv%FeatureName = bndname + else + if (obsrv%ObsTypeId == 'DELAY-HEAD' .or. & + obsrv%ObsTypeId == 'DELAY-GSTRESS' .or. & + obsrv%ObsTypeId == 'DELAY-ESTRESS' .or. & + obsrv%ObsTypeId == 'DELAY-PRECONSTRESS' .or. & + obsrv%ObsTypeId == 'DELAY-COMPACTION' .or. & + obsrv%ObsTypeId == 'DELAY-THICKNESS' .or. & + obsrv%ObsTypeId == 'DELAY-THETA') then + call extract_idnum_or_bndname(string, icol, istart, istop, nn2, bndname) + if (nn2 == NAMEDBOUNDFLAG) then + write (errmsg, '(5a)') & + "BOUNDNAME ('", trim(adjustl(bndname)), & + "') not allowed for CSUB observation type '", & + trim(adjustl(obsrv%ObsTypeId)), "' idcellno." + call store_error(errmsg) + ! obsrv%FeatureName = bndname + ! ! -- reset nn1 + ! nn1 = nn2 + else + obsrv%NodeNumber2 = nn2 + end if end if end if end if + ! - ! -- store observation location (NodeNumber) + ! -- store reach number (NodeNumber) obsrv%NodeNumber = nn1 end subroutine csub_process_obsID From 8bd4985aabf83250bb211d6f4c561ea1fd0c2e59 Mon Sep 17 00:00:00 2001 From: Joseph Hughes Date: Thu, 19 Dec 2024 13:48:55 -0600 Subject: [PATCH 3/6] Update csub autotests to be consistent with redefined observations options --- autotest/test_gwf_csub_obs.py | 39 ++++++++++++-- autotest/test_gwf_csub_sub03.py | 6 +-- autotest/test_gwf_csub_subwt01.py | 2 +- autotest/test_gwf_csub_subwt02.py | 18 +++---- autotest/test_gwf_csub_zdisp01.py | 8 +-- doc/Common/gwf-csubobs.tex | 2 +- src/Model/GroundWaterFlow/gwf-csub.f90 | 73 ++++++++++++++------------ 7 files changed, 92 insertions(+), 56 deletions(-) diff --git a/autotest/test_gwf_csub_obs.py b/autotest/test_gwf_csub_obs.py index 9ed986a7a33..c2d0014dfe7 100644 --- a/autotest/test_gwf_csub_obs.py +++ b/autotest/test_gwf_csub_obs.py @@ -1,7 +1,4 @@ -import os - import flopy -import numpy as np import pytest from framework import TestFramework @@ -9,8 +6,32 @@ "delay-flowtop", "delay-flowtop", "delay-flowbot", "delay-flowbot", "delay-head", "delay-head", + "delay-gstress", "delay-gstress", + "delay-estress", "delay-estress", + "delay-preconstress", "delay-preconstress", + "delay-compaction", "delay-compaction", + "delay-thickness", "delay-thickness", + "delay-theta", "delay-theta", + "csub", "csub", + "inelastic-csub", "inelastic-csub", + "elastic-csub", "elastic-csub", + "interbed-compaction", "interbed-compaction", + "inelastic-compaction", "inelastic-compaction", + "elastic-compaction", "elastic-compaction", ] boundname = [ + False, True, + False, True, + False, True, + False, True, + False, True, + False, True, + False, True, + False, True, + False, True, + False, True, + False, True, + False, True, False, True, False, True, False, True, @@ -19,6 +40,18 @@ False, False, False, False, False, True, + False, True, + False, True, + False, True, + False, True, + False, True, + False, True, + False, False, + False, False, + False, False, + False, True, + False, True, + False, True, ] cases = [f"csub_obs{idx + 1:02d}" for idx, _ in enumerate(obs_names)] diff --git a/autotest/test_gwf_csub_sub03.py b/autotest/test_gwf_csub_sub03.py index 4ef5c0ba7de..141f27bcf8c 100644 --- a/autotest/test_gwf_csub_sub03.py +++ b/autotest/test_gwf_csub_sub03.py @@ -318,9 +318,9 @@ def get_model(idx, ws): ) orecarray = {} orecarray["csub_obs.csv"] = [ - ("tcomp1", "interbed-compaction", "01_05_05"), - ("tcomp2", "interbed-compaction", "02_05_05"), - ("tcomp3", "interbed-compaction", "03_05_05"), + ("tcomp1", "interbed-compaction", (44,)), + ("tcomp2", "interbed-compaction", (140,)), + ("tcomp3", "interbed-compaction", (240,)), ] csub_obs_package = csub.obs.initialize( filename=opth, digits=10, print_input=True, continuous=orecarray diff --git a/autotest/test_gwf_csub_subwt01.py b/autotest/test_gwf_csub_subwt01.py index 3815ecbc08f..e14824bd0c3 100644 --- a/autotest/test_gwf_csub_subwt01.py +++ b/autotest/test_gwf_csub_subwt01.py @@ -212,7 +212,7 @@ def get_model(idx, ws): ) orecarray = {} orecarray["csub_obs.csv"] = [ - ("w1l1", "interbed-compaction", "01_01_02"), + ("w1l1", "compaction-cell", (0, 0, 1)), ("w1l1t", "csub-cell", (0, 0, 1)), ] csub_obs_package = csub.obs.initialize( diff --git a/autotest/test_gwf_csub_subwt02.py b/autotest/test_gwf_csub_subwt02.py index 2cab25980bd..26f8656ec66 100644 --- a/autotest/test_gwf_csub_subwt02.py +++ b/autotest/test_gwf_csub_subwt02.py @@ -344,14 +344,14 @@ def get_model(idx, ws): ) cobs = [ - ("w1l1", "interbed-compaction", "01_09_10"), - ("w1l2", "interbed-compaction", "02_09_10"), - ("w1l3", "interbed-compaction", "03_09_10"), - ("w1l4", "interbed-compaction", "04_09_10"), - ("w2l1", "interbed-compaction", "01_12_07"), - ("w2l2", "interbed-compaction", "02_12_07"), - ("w2l3", "interbed-compaction", "03_12_07"), - ("w2l4", "interbed-compaction", "04_12_07"), + ("w1l1", "interbed-compaction", (89,)), + ("w1l2", "interbed-compaction", (299,)), + ("w1l3", "interbed-compaction", (509,)), + ("w1l4", "interbed-compaction", (719,)), + ("w2l1", "interbed-compaction", (130,)), + ("w2l2", "interbed-compaction", (340,)), + ("w2l3", "interbed-compaction", (550,)), + ("w2l4", "interbed-compaction",(760,)), ("s1l1", "coarse-compaction", (0, 8, 9)), ("s1l2", "coarse-compaction", (1, 8, 9)), ("s1l3", "coarse-compaction", (2, 8, 9)), @@ -383,7 +383,7 @@ def get_model(idx, ws): ("pc4", "preconstress-cell", (3, 8, 9)), ("sk1l2", "ske-cell", (1, 8, 9)), ("sk2l4", "ske-cell", (3, 11, 6)), - ("t1l2", "theta", "02_09_10"), + ("t1l2", "theta", (1, 8, 9)), ] orecarray = {"csub_obs.csv": cobs} diff --git a/autotest/test_gwf_csub_zdisp01.py b/autotest/test_gwf_csub_zdisp01.py index 050e55aba89..9ca531120ba 100644 --- a/autotest/test_gwf_csub_zdisp01.py +++ b/autotest/test_gwf_csub_zdisp01.py @@ -283,13 +283,13 @@ def build_models(idx, test): packagedata=sub6, ) orecarray = {} - tag = f"{3:02d}_{wrp[0] + 1:02d}_{wcp[0] + 1:02d}" oloc = (2, wrp[0], wcp[0]) + ibloc = (449,) orecarray["csub_obs.csv"] = [ - ("tcomp3", "interbed-compaction", tag), + ("tcomp3", "interbed-compaction", ibloc), ("sk-tcomp3", "coarse-compaction", oloc), - ("ibi-tcomp3", "inelastic-compaction", tag), - ("ibe-tcomp3", "elastic-compaction", tag), + ("ibi-tcomp3", "inelastic-compaction", ibloc), + ("ibe-tcomp3", "elastic-compaction", ibloc), ] csub_obs_package = csub.obs.initialize( filename=opth, digits=10, print_input=True, continuous=orecarray diff --git a/doc/Common/gwf-csubobs.tex b/doc/Common/gwf-csubobs.tex index bb3614c5218..7c7fa18bca7 100644 --- a/doc/Common/gwf-csubobs.tex +++ b/doc/Common/gwf-csubobs.tex @@ -25,7 +25,7 @@ CSUB & coarse-thickness & cellid & -- & thickness of coarse-grained materials in a GWF cell. \\ CSUB & thickness-cell & cellid & -- & total thickness of coarse-grained materials and all interbeds in a GWF cell. \\ -CSUB & theta & icsubno or boundname & -- & porosity of a interbed or group of interbeds. \\ +CSUB & theta & icsubno & -- & porosity of a interbed. \\ CSUB & coarse-theta & cellid & -- & porosity of coarse-grained materials in a GWF cell. \\ CSUB & theta-cell & cellid & -- & thickness-weighted porosity of coarse-grained materials and all interbeds in a GWF cell. \\ diff --git a/src/Model/GroundWaterFlow/gwf-csub.f90 b/src/Model/GroundWaterFlow/gwf-csub.f90 index 4c19c64d58f..0f614473a1b 100644 --- a/src/Model/GroundWaterFlow/gwf-csub.f90 +++ b/src/Model/GroundWaterFlow/gwf-csub.f90 @@ -7341,10 +7341,18 @@ subroutine csub_process_obsID(obsrv, dis, inunitobs, iout) character(len=LINELENGTH) :: string character(len=LENBOUNDNAME) :: bndname logical(LGP) :: flag_string + logical(LGP) :: flag_idcellno + logical(LGP) :: flag_error ! ! -- initialize variables string = obsrv%IDstring flag_string = .TRUE. + flag_idcellno = .FALSE. + flag_error = .FALSE. + if (obsrv%ObsTypeId(1:5) == "DELAY" .AND. & + obsrv%ObsTypeId(1:10) /= "DELAY-FLOW") then + flag_idcellno = .TRUE. + end if ! ! -- Extract reach number from string and store it. ! If 1st item is not an integer(I4B), it should be a @@ -7372,7 +7380,7 @@ subroutine csub_process_obsID(obsrv, dis, inunitobs, iout) obsrv%ObsTypeId == 'DELAY-FLOWTOP' .or. & obsrv%ObsTypeId == 'DELAY-FLOWBOT') then call extract_idnum_or_bndname(string, icol, istart, istop, nn1, bndname) - ! read cellid + ! read cellid else nn1 = dis%noder_from_string(icol, istart, istop, inunitobs, & iout, string, flag_string) @@ -7382,6 +7390,9 @@ subroutine csub_process_obsID(obsrv, dis, inunitobs, iout) obsrv%ObsTypeId == 'SKE' .or. & obsrv%ObsTypeId == 'THETA' .or. & obsrv%ObsTypeId == 'THICKNESS' .or. & + obsrv%ObsTypeId == 'INTERBED-COMPACTION' .or. & + obsrv%ObsTypeId == 'INELASTIC-COMPACTION' .or. & + obsrv%ObsTypeId == 'ELASTIC-COMPACTION' .or. & obsrv%ObsTypeId == 'DELAY-HEAD' .or. & obsrv%ObsTypeId == 'DELAY-GSTRESS' .or. & obsrv%ObsTypeId == 'DELAY-ESTRESS' .or. & @@ -7389,50 +7400,42 @@ subroutine csub_process_obsID(obsrv, dis, inunitobs, iout) obsrv%ObsTypeId == 'DELAY-COMPACTION' .or. & obsrv%ObsTypeId == 'DELAY-THICKNESS' .or. & obsrv%ObsTypeId == 'DELAY-THETA') then - if (nn1 == NAMEDBOUNDFLAG) then - write (errmsg, '(5a)') & - "BOUNDNAME ('", trim(adjustl(bndname)), & - "') not allowed for CSUB observation type '", & - trim(adjustl(obsrv%ObsTypeId)), "'." - call store_error(errmsg) - end if - ! boundnames are allowed for these observation types + if (nn1 == NAMEDBOUNDFLAG) then + write (errmsg, '(5a)') & + "BOUNDNAME ('", trim(adjustl(bndname)), & + "') not allowed for CSUB observation type '", & + trim(adjustl(obsrv%ObsTypeId)), "'." + call store_error(errmsg) + flag_error = .TRUE. + end if + ! boundnames are allowed for these observation types else if (obsrv%ObsTypeId == 'CSUB' .or. & obsrv%ObsTypeId == 'INELASTIC-CSUB' .or. & obsrv%ObsTypeId == 'ELASTIC-CSUB' .or. & - ! obsrv%ObsTypeId == 'THICKNESS' .or. & - obsrv%ObsTypeId == 'INTERBED-COMPACTION' .or. & - obsrv%ObsTypeId == 'INELASTIC-COMPACTION' .or. & - obsrv%ObsTypeId == 'ELASTIC-COMPACTION' .or. & + ! obsrv%ObsTypeId == 'INTERBED-COMPACTION' .or. & + ! obsrv%ObsTypeId == 'INELASTIC-COMPACTION' .or. & + ! obsrv%ObsTypeId == 'ELASTIC-COMPACTION' .or. & obsrv%ObsTypeId == 'DELAY-FLOWTOP' .or. & obsrv%ObsTypeId == 'DELAY-FLOWBOT') then if (nn1 == NAMEDBOUNDFLAG) then obsrv%FeatureName = bndname - else - if (obsrv%ObsTypeId == 'DELAY-HEAD' .or. & - obsrv%ObsTypeId == 'DELAY-GSTRESS' .or. & - obsrv%ObsTypeId == 'DELAY-ESTRESS' .or. & - obsrv%ObsTypeId == 'DELAY-PRECONSTRESS' .or. & - obsrv%ObsTypeId == 'DELAY-COMPACTION' .or. & - obsrv%ObsTypeId == 'DELAY-THICKNESS' .or. & - obsrv%ObsTypeId == 'DELAY-THETA') then - call extract_idnum_or_bndname(string, icol, istart, istop, nn2, bndname) - if (nn2 == NAMEDBOUNDFLAG) then - write (errmsg, '(5a)') & - "BOUNDNAME ('", trim(adjustl(bndname)), & - "') not allowed for CSUB observation type '", & - trim(adjustl(obsrv%ObsTypeId)), "' idcellno." - call store_error(errmsg) - ! obsrv%FeatureName = bndname - ! ! -- reset nn1 - ! nn1 = nn2 - else - obsrv%NodeNumber2 = nn2 - end if + end if + end if + ! read idcellno for delay observations + if (flag_idcellno .EQV. .TRUE. .AND. flag_error .EQV. .FALSE.) then + if (nn1 /= NAMEDBOUNDFLAG) then + call extract_idnum_or_bndname(string, icol, istart, istop, nn2, bndname) + if (nn2 == NAMEDBOUNDFLAG) then + write (errmsg, '(5a)') & + "BOUNDNAME ('", trim(adjustl(bndname)), & + "') not allowed for CSUB observation type '", & + trim(adjustl(obsrv%ObsTypeId)), "' idcellno." + call store_error(errmsg) + else + obsrv%NodeNumber2 = nn2 end if end if end if - ! ! -- store reach number (NodeNumber) obsrv%NodeNumber = nn1 From f5813b1b9473ee646db82b717029efcd1e5718a7 Mon Sep 17 00:00:00 2001 From: Joseph Hughes Date: Thu, 19 Dec 2024 14:21:31 -0600 Subject: [PATCH 4/6] update release notes --- doc/ReleaseNotes/ReleaseNotes.tex | 2 +- doc/ReleaseNotes/develop.tex | 1 + doc/mf6io/mf6ivar/examples/gwf-csub-example-obs.dat | 6 ++++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/doc/ReleaseNotes/ReleaseNotes.tex b/doc/ReleaseNotes/ReleaseNotes.tex index ba2f1fdd0df..0b5d22e48ad 100644 --- a/doc/ReleaseNotes/ReleaseNotes.tex +++ b/doc/ReleaseNotes/ReleaseNotes.tex @@ -49,7 +49,7 @@ \renewcommand{\cooperator} -{the \textusgs\ Water Availability and Use Science Program} +{Water Availability and Use Science Program} \renewcommand{\reporttitle} {MODFLOW~6 Release Notes} \renewcommand{\coverphoto}{coverimage.jpg} diff --git a/doc/ReleaseNotes/develop.tex b/doc/ReleaseNotes/develop.tex index b0d6316f9e5..188b500f734 100644 --- a/doc/ReleaseNotes/develop.tex +++ b/doc/ReleaseNotes/develop.tex @@ -56,6 +56,7 @@ \item The PRT model now allows more control over vertical particle motion in dry conditions. In addition to the existing DRAPE option, which controls release-time behavior, the PRP package now provides a DRY\_TRACKING\_METHOD option which configures how dry particles (particles in dry cells, or above the water table in partially saturated cells) behave at tracking time. This option is relevant only when the Newton formulation is used, in which case dry cells remain active; otherwise, dry cells are inactive and particles will terminate. See the MF6IO document for a detailed explanation of DRY\_TRACKING\_METHOD. \item The PRT model's Particle Release Point (PRP) package now provides an option EXIT\_SOLVE\_TOLERANCE which configures the tolerance to use when solving for a particle's exit location from a triangular subcell of an unstructured grid cell. This value is only used for the generalized (ternary) tracking method on vertex grids. A value of 0.00001 is set by default. This value works well for many problems, but the value that strikes the best balance between accuracy and runtime is problem-dependent. \item The PRT model could write duplicative output, in volumes increasing with the current time step, due to a bug in the output file management logic. This bug has been fixed. + \item CSUB package observations that could use BOUNDNAMES was inconsistent with the input and output guide. CSUB package flow observations are the only observations that can use BOUNDNAMES. \end{itemize} %\underline{INTERNAL FLOW PACKAGES} diff --git a/doc/mf6io/mf6ivar/examples/gwf-csub-example-obs.dat b/doc/mf6io/mf6ivar/examples/gwf-csub-example-obs.dat index c2598240009..7ddedecfd19 100644 --- a/doc/mf6io/mf6ivar/examples/gwf-csub-example-obs.dat +++ b/doc/mf6io/mf6ivar/examples/gwf-csub-example-obs.dat @@ -1,6 +1,8 @@ BEGIN CONTINUOUS FILEOUT my_model.csub.csv tcomp3 compaction-cell 1 1 7 - ibcensystm0 elastic-compaction nsystm0 - ibcinsystm0 inelastic-compaction nsystm0 + ibcensystm0 elastic-compaction 2 + ibcinsystm0 inelastic-compaction 2 + ibcensystm0 elastic-csub nsystm0 + ibcinsystm0 inelastic-csum nsystm0 END CONTINUOUS From 229f2f5ed4a3d8d21beb774d668a1e4e84401b48 Mon Sep 17 00:00:00 2001 From: Joseph Hughes Date: Thu, 19 Dec 2024 14:28:30 -0600 Subject: [PATCH 5/6] format --- src/Model/GroundWaterFlow/gwf-csub.f90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Model/GroundWaterFlow/gwf-csub.f90 b/src/Model/GroundWaterFlow/gwf-csub.f90 index 0f614473a1b..c3d8f415a85 100644 --- a/src/Model/GroundWaterFlow/gwf-csub.f90 +++ b/src/Model/GroundWaterFlow/gwf-csub.f90 @@ -7412,9 +7412,9 @@ subroutine csub_process_obsID(obsrv, dis, inunitobs, iout) else if (obsrv%ObsTypeId == 'CSUB' .or. & obsrv%ObsTypeId == 'INELASTIC-CSUB' .or. & obsrv%ObsTypeId == 'ELASTIC-CSUB' .or. & - ! obsrv%ObsTypeId == 'INTERBED-COMPACTION' .or. & - ! obsrv%ObsTypeId == 'INELASTIC-COMPACTION' .or. & - ! obsrv%ObsTypeId == 'ELASTIC-COMPACTION' .or. & + ! obsrv%ObsTypeId == 'INTERBED-COMPACTION' .or. & + ! obsrv%ObsTypeId == 'INELASTIC-COMPACTION' .or. & + ! obsrv%ObsTypeId == 'ELASTIC-COMPACTION' .or. & obsrv%ObsTypeId == 'DELAY-FLOWTOP' .or. & obsrv%ObsTypeId == 'DELAY-FLOWBOT') then if (nn1 == NAMEDBOUNDFLAG) then From 5dc51a5a26c494ab96db2a2065ce3caa77e7616f Mon Sep 17 00:00:00 2001 From: Joseph Hughes Date: Thu, 19 Dec 2024 14:50:10 -0600 Subject: [PATCH 6/6] format python autotests --- autotest/test_gwf_csub_obs.py | 3 +++ autotest/test_gwf_csub_subwt02.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/autotest/test_gwf_csub_obs.py b/autotest/test_gwf_csub_obs.py index c2d0014dfe7..abc694c0391 100644 --- a/autotest/test_gwf_csub_obs.py +++ b/autotest/test_gwf_csub_obs.py @@ -2,6 +2,7 @@ import pytest from framework import TestFramework +# fmt: off obs_names = [ "delay-flowtop", "delay-flowtop", "delay-flowbot", "delay-flowbot", @@ -19,6 +20,7 @@ "inelastic-compaction", "inelastic-compaction", "elastic-compaction", "elastic-compaction", ] +# fmt: off boundname = [ False, True, False, True, @@ -36,6 +38,7 @@ False, True, False, True, ] +# fmt: off test_fail = [ False, False, False, False, diff --git a/autotest/test_gwf_csub_subwt02.py b/autotest/test_gwf_csub_subwt02.py index 26f8656ec66..8c4d6e397f6 100644 --- a/autotest/test_gwf_csub_subwt02.py +++ b/autotest/test_gwf_csub_subwt02.py @@ -351,7 +351,7 @@ def get_model(idx, ws): ("w2l1", "interbed-compaction", (130,)), ("w2l2", "interbed-compaction", (340,)), ("w2l3", "interbed-compaction", (550,)), - ("w2l4", "interbed-compaction",(760,)), + ("w2l4", "interbed-compaction", (760,)), ("s1l1", "coarse-compaction", (0, 8, 9)), ("s1l2", "coarse-compaction", (1, 8, 9)), ("s1l3", "coarse-compaction", (2, 8, 9)),