diff --git a/doc/mf6io/mf6ivar/dfn/gwt-cnc.dfn b/doc/mf6io/mf6ivar/dfn/gwt-cnc.dfn index e3ef02bce6c..3a75ccb4cf7 100644 --- a/doc/mf6io/mf6ivar/dfn/gwt-cnc.dfn +++ b/doc/mf6io/mf6ivar/dfn/gwt-cnc.dfn @@ -1,4 +1,5 @@ # --------------------- gwt cnc options --------------------- +# flopy multi-package block options name auxiliary @@ -34,6 +35,7 @@ reader urword optional true longname print input to listing file description REPLACE print_input {'{#1}': 'constant concentration'} +mf6internal iprflow block options name print_flows @@ -42,6 +44,7 @@ reader urword optional true longname print calculated flows to listing file description REPLACE print_flows {'{#1}': 'constant concentration'} +mf6internal ipakcb block options name save_flows @@ -50,6 +53,7 @@ reader urword optional true longname save constant concentration flows to budget file description REPLACE save_flows {'{#1}': 'constant concentration'} +mf6internal iprpak block options name ts_filerecord @@ -160,6 +164,7 @@ shape (maxbound) reader urword longname description +mf6internal spd block period name cellid @@ -181,6 +186,7 @@ reader urword time_series true longname constant concentration value description is the constant concentration value. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. +mf6internal tspvar block period name aux @@ -193,6 +199,7 @@ optional true time_series true longname auxiliary variables description REPLACE aux {'{#1}': 'constant concentration'} +mf6internal auxvar block period name boundname diff --git a/make/makefile b/make/makefile index 22aa3701e45..425cb0d5eaa 100644 --- a/make/makefile +++ b/make/makefile @@ -1,41 +1,41 @@ -# makefile created by pymake (version 1.2.9.dev0) for the 'mf6' executable. +# makefile created by pymake (version 1.2.7) for the 'mf6' executable. include ./makedefaults # Define the source file directories SOURCEDIR1=../src -SOURCEDIR2=../src/Exchange -SOURCEDIR3=../src/Distributed -SOURCEDIR4=../src/Solution -SOURCEDIR5=../src/Solution/LinearMethods -SOURCEDIR6=../src/Solution/ParticleTracker -SOURCEDIR7=../src/Solution/PETSc -SOURCEDIR8=../src/Timing -SOURCEDIR9=../src/Utilities -SOURCEDIR10=../src/Utilities/Idm -SOURCEDIR11=../src/Utilities/Idm/selector -SOURCEDIR12=../src/Utilities/Idm/mf6blockfile -SOURCEDIR13=../src/Utilities/TimeSeries -SOURCEDIR14=../src/Utilities/Memory -SOURCEDIR15=../src/Utilities/OutputControl -SOURCEDIR16=../src/Utilities/ArrayRead -SOURCEDIR17=../src/Utilities/Libraries -SOURCEDIR18=../src/Utilities/Libraries/rcm -SOURCEDIR19=../src/Utilities/Libraries/blas -SOURCEDIR20=../src/Utilities/Libraries/sparskit2 -SOURCEDIR21=../src/Utilities/Libraries/daglib -SOURCEDIR22=../src/Utilities/Libraries/sparsekit -SOURCEDIR23=../src/Utilities/Vector -SOURCEDIR24=../src/Utilities/Matrix -SOURCEDIR25=../src/Utilities/Observation -SOURCEDIR26=../src/Model -SOURCEDIR27=../src/Model/Connection -SOURCEDIR28=../src/Model/GroundWaterTransport -SOURCEDIR29=../src/Model/ModelUtilities -SOURCEDIR30=../src/Model/GroundWaterFlow -SOURCEDIR31=../src/Model/TransportModel -SOURCEDIR32=../src/Model/Geometry +SOURCEDIR2=../src/Distributed +SOURCEDIR3=../src/Exchange +SOURCEDIR4=../src/Model +SOURCEDIR5=../src/Model/Connection +SOURCEDIR6=../src/Model/Geometry +SOURCEDIR7=../src/Model/GroundWaterFlow +SOURCEDIR8=../src/Model/GroundWaterTransport +SOURCEDIR9=../src/Model/ModelUtilities +SOURCEDIR10=../src/Model/TransportModel +SOURCEDIR11=../src/Solution +SOURCEDIR12=../src/Solution/LinearMethods +SOURCEDIR13=../src/Solution/ParticleTracker +SOURCEDIR14=../src/Solution/PETSc +SOURCEDIR15=../src/Timing +SOURCEDIR16=../src/Utilities +SOURCEDIR17=../src/Utilities/ArrayRead +SOURCEDIR18=../src/Utilities/Idm +SOURCEDIR19=../src/Utilities/Idm/mf6blockfile +SOURCEDIR20=../src/Utilities/Idm/selector +SOURCEDIR21=../src/Utilities/Libraries +SOURCEDIR22=../src/Utilities/Libraries/blas +SOURCEDIR23=../src/Utilities/Libraries/daglib +SOURCEDIR24=../src/Utilities/Libraries/rcm +SOURCEDIR25=../src/Utilities/Libraries/sparsekit +SOURCEDIR26=../src/Utilities/Libraries/sparskit2 +SOURCEDIR27=../src/Utilities/Matrix +SOURCEDIR28=../src/Utilities/Memory +SOURCEDIR29=../src/Utilities/Observation +SOURCEDIR30=../src/Utilities/OutputControl +SOURCEDIR31=../src/Utilities/TimeSeries +SOURCEDIR32=../src/Utilities/Vector VPATH = \ ${SOURCEDIR1} \ @@ -69,7 +69,7 @@ ${SOURCEDIR28} \ ${SOURCEDIR29} \ ${SOURCEDIR30} \ ${SOURCEDIR31} \ -${SOURCEDIR32} +$(SOURCEDIR32) .SUFFIXES: .f90 .F90 .o @@ -102,6 +102,7 @@ $(OBJDIR)/gwt1dsp1idm.o \ $(OBJDIR)/gwt1disv1idm.o \ $(OBJDIR)/gwt1disu1idm.o \ $(OBJDIR)/gwt1dis1idm.o \ +$(OBJDIR)/gwt1cnc1idm.o \ $(OBJDIR)/gwf3wel8idm.o \ $(OBJDIR)/gwf3riv8idm.o \ $(OBJDIR)/gwf3rch8idm.o \ diff --git a/msvs/mf6core.vfproj b/msvs/mf6core.vfproj index 38ecb175f39..dbc042f220d 100644 --- a/msvs/mf6core.vfproj +++ b/msvs/mf6core.vfproj @@ -165,6 +165,7 @@ + diff --git a/src/Model/GroundWaterTransport/gwt1.f90 b/src/Model/GroundWaterTransport/gwt1.f90 index fc265aa466f..0a83a5e1abb 100644 --- a/src/Model/GroundWaterTransport/gwt1.f90 +++ b/src/Model/GroundWaterTransport/gwt1.f90 @@ -756,8 +756,8 @@ end subroutine allocate_scalars !! !! Call the package create routines for packages activated by the user. !< - subroutine package_create(this, filtyp, ipakid, ipaknum, pakname, inunit, & - iout) + subroutine package_create(this, filtyp, ipakid, ipaknum, pakname, mempath, & + inunit, iout) ! -- modules use ConstantsModule, only: LINELENGTH use SimModule, only: store_error @@ -776,6 +776,7 @@ subroutine package_create(this, filtyp, ipakid, ipaknum, pakname, inunit, & integer(I4B), intent(in) :: ipakid integer(I4B), intent(in) :: ipaknum character(len=*), intent(in) :: pakname + character(len=*), intent(in) :: mempath integer(I4B), intent(in) :: inunit integer(I4B), intent(in) :: iout ! -- local @@ -786,7 +787,8 @@ subroutine package_create(this, filtyp, ipakid, ipaknum, pakname, inunit, & ! -- This part creates the package object select case (filtyp) case ('CNC6') - call cnc_create(packobj, ipakid, ipaknum, inunit, iout, this%name, pakname) + call cnc_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & + pakname, dvt, filtyp, mempath) case ('SRC6') call src_create(packobj, ipakid, ipaknum, inunit, iout, this%name, pakname) case ('LKT6') @@ -888,8 +890,8 @@ subroutine create_bndpkgs(this, bndpkgs, pkgtypes, pkgnames, & bndptype = pkgtype end if ! - call this%package_create(pkgtype, ipakid, ipaknum, pkgname, inunit, & - this%iout) + call this%package_create(pkgtype, ipakid, ipaknum, pkgname, mempath, & + inunit, this%iout) ipakid = ipakid + 1 ipaknum = ipaknum + 1 end do diff --git a/src/Model/GroundWaterTransport/gwt1cnc1.f90 b/src/Model/GroundWaterTransport/gwt1cnc1.f90 index 5fc5378f078..0aac26342b7 100644 --- a/src/Model/GroundWaterTransport/gwt1cnc1.f90 +++ b/src/Model/GroundWaterTransport/gwt1cnc1.f90 @@ -2,12 +2,16 @@ module GwtCncModule ! use KindModule, only: DP, I4B use ConstantsModule, only: DZERO, DONE, NAMEDBOUNDFLAG, LENFTYPE, & - LENPACKAGENAME + LENPACKAGENAME, LENVARNAME + use SimVariablesModule, only: errmsg + use SimModule, only: count_errors, store_error, store_error_filename use ObsModule, only: DefaultObsIdProcessor use BndModule, only: BndType + use BndExtModule, only: BndExtType use ObserveModule, only: ObserveType use TimeSeriesLinkModule, only: TimeSeriesLinkType, & GetTimeSeriesLinkFromList + use InputOutputModule, only: str_pad_left use MatrixBaseModule ! implicit none @@ -18,9 +22,12 @@ module GwtCncModule character(len=LENFTYPE) :: ftype = 'CNC' character(len=LENPACKAGENAME) :: text = ' CNC' ! - type, extends(BndType) :: GwtCncType + type, extends(BndExtType) :: GwtCncType + + real(DP), dimension(:), pointer, contiguous :: tspvar => null() !< constant head array real(DP), dimension(:), pointer, contiguous :: ratecncin => null() !simulated flows into constant conc (excluding other concs) real(DP), dimension(:), pointer, contiguous :: ratecncout => null() !simulated flows out of constant conc (excluding to other concs) + character(len=LENVARNAME) :: depvartype = '' !< stores string of dependent variable type, depending on model type contains procedure :: bnd_rp => cnc_rp procedure :: bnd_ad => cnc_ad @@ -31,6 +38,7 @@ module GwtCncModule procedure :: bnd_da => cnc_da procedure :: allocate_arrays => cnc_allocate_arrays procedure :: define_listlabel + procedure :: bound_value => cnc_bound_value ! -- methods for observations procedure, public :: bnd_obs_supported => cnc_obs_supported procedure, public :: bnd_df_obs => cnc_df_obs @@ -40,15 +48,12 @@ module GwtCncModule contains - subroutine cnc_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname) -! ****************************************************************************** -! cnc_create -- Create a New Constant Concentration Package -! Subroutine: (1) create new-style package -! (2) point packobj to the new package -! ****************************************************************************** -! -! SPECIFICATIONS: -! ------------------------------------------------------------------------------ + !> @brief Create a new constant concentration or temperature package + !! + !! Routine points packobj to the newly created package + !< + subroutine cnc_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, & + depvartype, ftype, mempath) ! -- dummy class(BndType), pointer :: packobj integer(I4B), intent(in) :: id @@ -57,20 +62,24 @@ subroutine cnc_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname) integer(I4B), intent(in) :: iout character(len=*), intent(in) :: namemodel character(len=*), intent(in) :: pakname + character(len=LENVARNAME), intent(in) :: depvartype + character(len=LENFTYPE), intent(in) :: ftype + character(len=*), intent(in) :: mempath ! -- local type(GwtCncType), pointer :: cncobj -! ------------------------------------------------------------------------------ + character(len=LENPACKAGENAME) :: text ! ! -- allocate the object and assign values to object variables allocate (cncobj) packobj => cncobj ! ! -- create name and memory path - call packobj%set_names(ibcnum, namemodel, pakname, ftype) + call packobj%set_names(ibcnum, namemodel, pakname, ftype, mempath) + text = str_pad_left(ftype(1:3), LENPACKAGENAME) packobj%text = text ! ! -- allocate scalars - call packobj%allocate_scalars() + call cncobj%allocate_scalars() ! ! -- initialize package call packobj%pack_initialize() @@ -83,29 +92,28 @@ subroutine cnc_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname) packobj%ncolbnd = 1 packobj%iscloc = 1 ! + ! -- Store the appropriate label based on the dependent variable + cncobj%depvartype = depvartype + ! ! -- return return end subroutine cnc_create + !> @brief Allocate arrays specific to the constant concentration/tempeature + !! package. + !< subroutine cnc_allocate_arrays(this, nodelist, auxvar) -! ****************************************************************************** -! allocate_scalars -- allocate arrays -! ****************************************************************************** -! -! SPECIFICATIONS: -! ------------------------------------------------------------------------------ ! -- modules - use MemoryManagerModule, only: mem_allocate + use MemoryManagerModule, only: mem_allocate, mem_setptr, mem_checkin ! -- dummy class(GwtCncType) :: this integer(I4B), dimension(:), pointer, contiguous, optional :: nodelist real(DP), dimension(:, :), pointer, contiguous, optional :: auxvar ! -- local integer(I4B) :: i -! ------------------------------------------------------------------------------ ! ! -- call standard BndType allocate scalars - call this%BndType%allocate_arrays() + call this%BndExtType%allocate_arrays(nodelist, auxvar) ! ! -- allocate ratecncex call mem_allocate(this%ratecncin, this%maxbound, 'RATECNCIN', this%memoryPath) @@ -115,24 +123,28 @@ subroutine cnc_allocate_arrays(this, nodelist, auxvar) this%ratecncin(i) = DZERO this%ratecncout(i) = DZERO end do + ! -- set constant head array input context pointer + call mem_setptr(this%tspvar, 'TSPVAR', this%input_mempath) + ! + ! -- checkin constant head array input context pointer + call mem_checkin(this%tspvar, 'TSPVAR', this%memoryPath, & + 'TSPVAR', this%input_mempath) + ! ! ! -- return return end subroutine cnc_allocate_arrays + !> @brief Constant concentration/temperature read and prepare (rp) routine + !< subroutine cnc_rp(this) -! ****************************************************************************** -! cnc_rp -- Read and prepare -! ****************************************************************************** -! -! SPECIFICATIONS: -! ------------------------------------------------------------------------------ use SimModule, only: store_error + use InputOutputModule, only: lowcase implicit none class(GwtCncType), intent(inout) :: this integer(I4B) :: i, node, ibd, ierr character(len=30) :: nodestr -! ------------------------------------------------------------------------------ + character(len=LENVARNAME) :: dvtype ! ! -- Reset previous CNCs to active cell do i = 1, this%nbound @@ -141,7 +153,7 @@ subroutine cnc_rp(this) end do ! ! -- Call the parent class read and prepare - call this%BndType%bnd_rp() + call this%BndExtType%bnd_rp() ! ! -- Set ibound to -(ibcnum + 1) for constant concentration cells ierr = 0 @@ -150,8 +162,10 @@ subroutine cnc_rp(this) ibd = this%ibound(node) if (ibd < 0) then call this%dis%noder_to_string(node, nodestr) - call store_error('Cell is already a constant concentration: ' & - //trim(adjustl(nodestr))) + dvtype = trim(this%depvartype) + call lowcase(dvtype) + call store_error('Cell is already a constant ' & + //dvtype//': '//trim(adjustl(nodestr))) ierr = ierr + 1 else this%ibound(node) = -this%ibcnum @@ -160,20 +174,23 @@ subroutine cnc_rp(this) ! ! -- Stop if errors detected if (ierr > 0) then - call this%parser%StoreErrorUnit() + call store_error_filename(this%input_fname) + end if + ! + ! -- Write the list to iout if requested + if (this%iprpak /= 0) then + call this%write_list() end if ! ! -- return return end subroutine cnc_rp + !> @brief Constant concentration/temperature package advance routine + !! + !! Add package connections to matrix + !< subroutine cnc_ad(this) -! ****************************************************************************** -! cnc_ad -- Advance -! ****************************************************************************** -! -! SPECIFICATIONS: -! ------------------------------------------------------------------------------ ! -- modules ! -- dummy class(GwtCncType) :: this @@ -181,7 +198,6 @@ subroutine cnc_ad(this) integer(I4B) :: i, node real(DP) :: cb ! -- formats -! ------------------------------------------------------------------------------ ! ! -- Advance the time series call this%TsManager%ad() @@ -189,7 +205,11 @@ subroutine cnc_ad(this) ! -- Process each entry in the constant concentration cell list do i = 1, this%nbound node = this%nodelist(i) - cb = this%bound(1, i) + if (this%iauxmultcol > 0) then + cb = this%tspvar(i) * this%auxvar(this%iauxmultcol, i) + else + cb = this%tspvar(i) + end if this%xnew(node) = cb this%xold(node) = this%xnew(node) end do @@ -203,55 +223,47 @@ subroutine cnc_ad(this) return end subroutine cnc_ad + !> @brief Check constant concentration/temperature boundary condition data + !< subroutine cnc_ck(this) -! ****************************************************************************** -! cnc_ck -- Check cnc boundary condition data -! ****************************************************************************** -! -! SPECIFICATIONS: -! ------------------------------------------------------------------------------ ! -- modules - use ConstantsModule, only: LINELENGTH - use SimModule, only: store_error, count_errors, store_error_unit ! -- dummy class(GwtCncType), intent(inout) :: this ! -- local - character(len=LINELENGTH) :: errmsg character(len=30) :: nodestr integer(I4B) :: i integer(I4B) :: node ! -- formats character(len=*), parameter :: fmtcncerr = & - &"('CNC boundary ',i0,' conc (',g0,') is less than zero for cell', a)" -! ------------------------------------------------------------------------------ + &"('Specified dependent variable boundary ',i0, & + &' conc (',g0,') is less than zero for cell', a)" ! ! -- check stress period data do i = 1, this%nbound node = this%nodelist(i) ! -- accumulate errors - if (this%bound(1, i) < DZERO) then + if (this%tspvar(i) < DZERO) then call this%dis%noder_to_string(node, nodestr) - write (errmsg, fmt=fmtcncerr) i, this%bound(1, i), trim(nodestr) + write (errmsg, fmt=fmtcncerr) i, this%tspvar(i), trim(nodestr) call store_error(errmsg) end if end do ! ! -- write summary of cnc package error messages if (count_errors() > 0) then - call this%parser%StoreErrorUnit() + call store_error_filename(this%input_fname) end if ! ! -- return return end subroutine cnc_ck + !> @brief Override bnd_fc and do nothing + !! + !! For constant concentration/temperature boundary type, the call to bnd_fc + !! needs to be overwritten to prevent logic found therein from being applied + !< subroutine cnc_fc(this, rhs, ia, idxglo, matrix_sln) -! ************************************************************************** -! cnc_fc -- Override bnd_fc and do nothing -! ************************************************************************** -! -! SPECIFICATIONS: -! -------------------------------------------------------------------------- ! -- dummy class(GwtCncType) :: this real(DP), dimension(:), intent(inout) :: rhs @@ -259,19 +271,17 @@ subroutine cnc_fc(this, rhs, ia, idxglo, matrix_sln) integer(I4B), dimension(:), intent(in) :: idxglo class(MatrixBaseType), pointer :: matrix_sln ! -- local -! -------------------------------------------------------------------------- ! ! -- return return end subroutine cnc_fc + !> @brief Calculate flow associated with constant concentration/temperature + !! boundary + !! + !! This method overrides bnd_cq() + !< subroutine cnc_cq(this, x, flowja, iadv) -! ****************************************************************************** -! cnc_cq -- Calculate constant concenration flow. This method overrides bnd_cq(). -! ****************************************************************************** -! -! SPECIFICATIONS: -! ------------------------------------------------------------------------------ ! -- modules ! -- dummy class(GwtCncType), intent(inout) :: this @@ -287,7 +297,6 @@ subroutine cnc_cq(this, x, flowja, iadv) real(DP) :: rate real(DP) :: ratein, rateout real(DP) :: q -! ------------------------------------------------------------------------------ ! ! -- If no boundaries, skip flow calculations. if (this%nbound > 0) then @@ -336,57 +345,61 @@ subroutine cnc_cq(this, x, flowja, iadv) return end subroutine cnc_cq + !> @brief Add package ratin/ratout to model budget + !< subroutine cnc_bd(this, model_budget) - ! -- add package ratin/ratout to model budget + ! -- modules use TdisModule, only: delt use BudgetModule, only: BudgetType, rate_accumulator + ! -- dummy class(GwtCncType) :: this + ! -- local type(BudgetType), intent(inout) :: model_budget real(DP) :: ratin real(DP) :: ratout real(DP) :: dum integer(I4B) :: isuppress_output + ! isuppress_output = 0 call rate_accumulator(this%ratecncin(1:this%nbound), ratin, dum) call rate_accumulator(this%ratecncout(1:this%nbound), ratout, dum) call model_budget%addentry(ratin, ratout, delt, this%text, & isuppress_output, this%packName) + ! + ! -- Return + return end subroutine cnc_bd + !> @brief Deallocate memory + !! + !! Method to deallocate memory for the package. + !< subroutine cnc_da(this) -! ****************************************************************************** -! cnc_da -- deallocate -! ****************************************************************************** -! -! SPECIFICATIONS: -! ------------------------------------------------------------------------------ ! -- modules use MemoryManagerModule, only: mem_deallocate ! -- dummy class(GwtCncType) :: this -! ------------------------------------------------------------------------------ ! ! -- Deallocate parent package - call this%BndType%bnd_da() + call this%BndExtType%bnd_da() ! ! -- arrays call mem_deallocate(this%ratecncin) call mem_deallocate(this%ratecncout) + call mem_deallocate(this%tspvar, 'TSPVAR', this%memoryPath) ! ! -- return return end subroutine cnc_da + !> @brief Define labels used in list file + !! + !! Define the list heading that is written to iout when PRINT_INPUT option + !! is used. + !< subroutine define_listlabel(this) -! ****************************************************************************** -! define_listlabel -- Define the list heading that is written to iout when -! PRINT_INPUT option is used. -! ****************************************************************************** -! -! SPECIFICATIONS: -! ------------------------------------------------------------------------------ + ! -- dummy class(GwtCncType), intent(inout) :: this -! ------------------------------------------------------------------------------ ! ! -- create the header list label this%listlabel = trim(this%filtyp)//' NO.' @@ -400,7 +413,8 @@ subroutine define_listlabel(this) else write (this%listlabel, '(a, a7)') trim(this%listlabel), 'NODE' end if - write (this%listlabel, '(a, a16)') trim(this%listlabel), 'CONCENTRATION' + write (this%listlabel, '(a, a16)') trim(this%listlabel), & + trim(this%depvartype) if (this%inamedbound == 1) then write (this%listlabel, '(a, a16)') trim(this%listlabel), 'BOUNDARY NAME' end if @@ -409,43 +423,36 @@ subroutine define_listlabel(this) return end subroutine define_listlabel - ! -- Procedures related to observations - + !> @brief Procedure related to observation processing + !! + !! This routine: + !! - returns true because the SDV package supports observations, + !! - overrides packagetype%_obs_supported() logical function cnc_obs_supported(this) -! ****************************************************************************** -! cnc_obs_supported -! -- Return true because CNC package supports observations. -! -- Overrides packagetype%_obs_supported() -! ****************************************************************************** -! -! SPECIFICATIONS: -! ------------------------------------------------------------------------------ ! -- dummy class(GwtCncType) :: this -! ------------------------------------------------------------------------------ ! cnc_obs_supported = .true. ! - ! -- return + ! -- Return return end function cnc_obs_supported + !> @brief Procedure related to observation processing + !! + !! This routine: + !! - defines observations + !! - stores observation types supported by either of the SDV packages + !! (CNC or CNT), + !! - overrides BndExtType%bnd_df_obs + !< subroutine cnc_df_obs(this) -! ****************************************************************************** -! cnc_df_obs (implements bnd_df_obs) -! -- Store observation type supported by CNC package. -! -- Overrides BndType%bnd_df_obs -! ****************************************************************************** -! -! SPECIFICATIONS: -! ------------------------------------------------------------------------------ ! -- dummy class(GwtCncType) :: this ! -- local integer(I4B) :: indx -! ------------------------------------------------------------------------------ ! - call this%obs%StoreObsType('cnc', .true., indx) + call this%obs%StoreObsType(this%filtyp, .true., indx) this%obs%obsData(indx)%ProcessIdPtr => DefaultObsIdProcessor ! ! -- return @@ -454,22 +461,19 @@ end subroutine cnc_df_obs ! -- Procedure related to time series + !> @brief Procedure related to time series + !! + !! Assign tsLink%Text appropriately for all time series in use by package. + !! For any specified dependent variable package, for example either the + !! constant concentration or constant temperature packages, the dependent + !! variable can be controlled by time series. + !< subroutine cnc_rp_ts(this) -! ****************************************************************************** -! -- Assign tsLink%Text appropriately for -! all time series in use by package. -! In CNC package variable CONCENTRATION -! can be controlled by time series. -! ****************************************************************************** -! -! SPECIFICATIONS: -! ------------------------------------------------------------------------------ ! -- dummy class(GwtCncType), intent(inout) :: this ! -- local integer(I4B) :: i, nlinks type(TimeSeriesLinkType), pointer :: tslink => null() -! ------------------------------------------------------------------------------ ! nlinks = this%TsManager%boundtslinks%Count() do i = 1, nlinks @@ -477,7 +481,7 @@ subroutine cnc_rp_ts(this) if (associated(tslink)) then select case (tslink%JCol) case (1) - tslink%Text = 'CONCENTRATION' + tslink%Text = trim(this%depvartype) end select end if end do @@ -486,4 +490,33 @@ subroutine cnc_rp_ts(this) return end subroutine cnc_rp_ts + !> @ brief Return a bound value + !! + !! Return a bound value associated with an ncolbnd index and row. + !< + function cnc_bound_value(this, col, row) result(bndval) + ! -- modules + use ConstantsModule, only: DZERO + ! -- dummy variables + class(GwtCncType), intent(inout) :: this !< BndExtType object + integer(I4B), intent(in) :: col + integer(I4B), intent(in) :: row + ! -- result + real(DP) :: bndval + ! + select case (col) + case (1) + bndval = this%tspvar(row) + case default + write (errmsg, '(3a)') 'Programming error. ', & + & adjustl(trim(this%filtyp)), ' bound value requested column '& + &'outside range of ncolbnd (1).' + call store_error(errmsg) + call store_error_filename(this%input_fname) + end select + ! + ! -- Return + return + end function cnc_bound_value + end module GwtCncModule diff --git a/src/Model/GroundWaterTransport/gwt1cnc1idm.f90 b/src/Model/GroundWaterTransport/gwt1cnc1idm.f90 new file mode 100644 index 00000000000..98fba5e2882 --- /dev/null +++ b/src/Model/GroundWaterTransport/gwt1cnc1idm.f90 @@ -0,0 +1,414 @@ +! ** Do Not Modify! MODFLOW 6 system generated file. ** +module GwtCncInputModule + use ConstantsModule, only: LENVARNAME + use InputDefinitionModule, only: InputParamDefinitionType, & + InputBlockDefinitionType + private + public gwt_cnc_param_definitions + public gwt_cnc_aggregate_definitions + public gwt_cnc_block_definitions + public GwtCncParamFoundType + public gwt_cnc_multi_package + public gwt_cnc_aux_sfac_param + + type GwtCncParamFoundType + logical :: auxiliary = .false. + logical :: auxmultname = .false. + logical :: boundnames = .false. + logical :: iprflow = .false. + logical :: ipakcb = .false. + logical :: iprpak = .false. + logical :: ts_filerecord = .false. + logical :: ts6 = .false. + logical :: filein = .false. + logical :: ts6_filename = .false. + logical :: obs_filerecord = .false. + logical :: obs6 = .false. + logical :: obs6_filename = .false. + logical :: maxbound = .false. + logical :: cellid = .false. + logical :: tspvar = .false. + logical :: auxvar = .false. + logical :: boundname = .false. + end type GwtCncParamFoundType + + logical :: gwt_cnc_multi_package = .true. + + character(len=LENVARNAME) :: gwt_cnc_aux_sfac_param = '' + + type(InputParamDefinitionType), parameter :: & + gwtcnc_auxiliary = InputParamDefinitionType & + ( & + 'GWT', & ! component + 'CNC', & ! subcomponent + 'OPTIONS', & ! block + 'AUXILIARY', & ! tag name + 'AUXILIARY', & ! fortran variable + 'STRING', & ! type + 'NAUX', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwtcnc_auxmultname = InputParamDefinitionType & + ( & + 'GWT', & ! component + 'CNC', & ! subcomponent + 'OPTIONS', & ! block + 'AUXMULTNAME', & ! tag name + 'AUXMULTNAME', & ! fortran variable + 'STRING', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwtcnc_boundnames = InputParamDefinitionType & + ( & + 'GWT', & ! component + 'CNC', & ! subcomponent + 'OPTIONS', & ! block + 'BOUNDNAMES', & ! tag name + 'BOUNDNAMES', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwtcnc_iprflow = InputParamDefinitionType & + ( & + 'GWT', & ! component + 'CNC', & ! subcomponent + 'OPTIONS', & ! block + 'PRINT_INPUT', & ! tag name + 'IPRFLOW', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwtcnc_ipakcb = InputParamDefinitionType & + ( & + 'GWT', & ! component + 'CNC', & ! subcomponent + 'OPTIONS', & ! block + 'PRINT_FLOWS', & ! tag name + 'IPAKCB', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwtcnc_iprpak = InputParamDefinitionType & + ( & + 'GWT', & ! component + 'CNC', & ! subcomponent + 'OPTIONS', & ! block + 'SAVE_FLOWS', & ! tag name + 'IPRPAK', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwtcnc_ts_filerecord = InputParamDefinitionType & + ( & + 'GWT', & ! component + 'CNC', & ! subcomponent + 'OPTIONS', & ! block + 'TS_FILERECORD', & ! tag name + 'TS_FILERECORD', & ! fortran variable + 'RECORD TS6 FILEIN TS6_FILENAME', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwtcnc_ts6 = InputParamDefinitionType & + ( & + 'GWT', & ! component + 'CNC', & ! subcomponent + 'OPTIONS', & ! block + 'TS6', & ! tag name + 'TS6', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwtcnc_filein = InputParamDefinitionType & + ( & + 'GWT', & ! component + 'CNC', & ! subcomponent + 'OPTIONS', & ! block + 'FILEIN', & ! tag name + 'FILEIN', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwtcnc_ts6_filename = InputParamDefinitionType & + ( & + 'GWT', & ! component + 'CNC', & ! subcomponent + 'OPTIONS', & ! block + 'TS6_FILENAME', & ! tag name + 'TS6_FILENAME', & ! fortran variable + 'STRING', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .true., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwtcnc_obs_filerecord = InputParamDefinitionType & + ( & + 'GWT', & ! component + 'CNC', & ! subcomponent + 'OPTIONS', & ! block + 'OBS_FILERECORD', & ! tag name + 'OBS_FILERECORD', & ! fortran variable + 'RECORD OBS6 FILEIN OBS6_FILENAME', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwtcnc_obs6 = InputParamDefinitionType & + ( & + 'GWT', & ! component + 'CNC', & ! subcomponent + 'OPTIONS', & ! block + 'OBS6', & ! tag name + 'OBS6', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwtcnc_obs6_filename = InputParamDefinitionType & + ( & + 'GWT', & ! component + 'CNC', & ! subcomponent + 'OPTIONS', & ! block + 'OBS6_FILENAME', & ! tag name + 'OBS6_FILENAME', & ! fortran variable + 'STRING', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .true., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwtcnc_maxbound = InputParamDefinitionType & + ( & + 'GWT', & ! component + 'CNC', & ! subcomponent + 'DIMENSIONS', & ! block + 'MAXBOUND', & ! tag name + 'MAXBOUND', & ! fortran variable + 'INTEGER', & ! type + '', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwtcnc_cellid = InputParamDefinitionType & + ( & + 'GWT', & ! component + 'CNC', & ! subcomponent + 'PERIOD', & ! block + 'CELLID', & ! tag name + 'CELLID', & ! fortran variable + 'INTEGER1D', & ! type + 'NCELLDIM', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwtcnc_tspvar = InputParamDefinitionType & + ( & + 'GWT', & ! component + 'CNC', & ! subcomponent + 'PERIOD', & ! block + 'CONC', & ! tag name + 'TSPVAR', & ! fortran variable + 'DOUBLE', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .true. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwtcnc_auxvar = InputParamDefinitionType & + ( & + 'GWT', & ! component + 'CNC', & ! subcomponent + 'PERIOD', & ! block + 'AUX', & ! tag name + 'AUXVAR', & ! fortran variable + 'DOUBLE1D', & ! type + 'NAUX', & ! shape + .false., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .true. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwtcnc_boundname = InputParamDefinitionType & + ( & + 'GWT', & ! component + 'CNC', & ! subcomponent + 'PERIOD', & ! block + 'BOUNDNAME', & ! tag name + 'BOUNDNAME', & ! fortran variable + 'STRING', & ! type + '', & ! shape + .false., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwt_cnc_param_definitions(*) = & + [ & + gwtcnc_auxiliary, & + gwtcnc_auxmultname, & + gwtcnc_boundnames, & + gwtcnc_iprflow, & + gwtcnc_ipakcb, & + gwtcnc_iprpak, & + gwtcnc_ts_filerecord, & + gwtcnc_ts6, & + gwtcnc_filein, & + gwtcnc_ts6_filename, & + gwtcnc_obs_filerecord, & + gwtcnc_obs6, & + gwtcnc_obs6_filename, & + gwtcnc_maxbound, & + gwtcnc_cellid, & + gwtcnc_tspvar, & + gwtcnc_auxvar, & + gwtcnc_boundname & + ] + + type(InputParamDefinitionType), parameter :: & + gwtcnc_spd = InputParamDefinitionType & + ( & + 'GWT', & ! component + 'CNC', & ! subcomponent + 'PERIOD', & ! block + 'STRESS_PERIOD_DATA', & ! tag name + 'SPD', & ! fortran variable + 'RECARRAY CELLID CONC AUX BOUNDNAME', & ! type + 'MAXBOUND', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwt_cnc_aggregate_definitions(*) = & + [ & + gwtcnc_spd & + ] + + type(InputBlockDefinitionType), parameter :: & + gwt_cnc_block_definitions(*) = & + [ & + InputBlockDefinitionType( & + 'OPTIONS', & ! blockname + .false., & ! required + .false., & ! aggregate + .false. & ! block_variable + ), & + InputBlockDefinitionType( & + 'DIMENSIONS', & ! blockname + .true., & ! required + .false., & ! aggregate + .false. & ! block_variable + ), & + InputBlockDefinitionType( & + 'PERIOD', & ! blockname + .true., & ! required + .true., & ! aggregate + .true. & ! block_variable + ) & + ] + +end module GwtCncInputModule diff --git a/src/Utilities/Idm/selector/IdmGwtDfnSelector.f90 b/src/Utilities/Idm/selector/IdmGwtDfnSelector.f90 index 0e089317fa7..a48af422cad 100644 --- a/src/Utilities/Idm/selector/IdmGwtDfnSelector.f90 +++ b/src/Utilities/Idm/selector/IdmGwtDfnSelector.f90 @@ -9,6 +9,7 @@ module IdmGwtDfnSelectorModule use GwtDisuInputModule use GwtDisvInputModule use GwtDspInputModule + use GwtCncInputModule use GwtNamInputModule implicit none @@ -64,6 +65,24 @@ module IdmGwtDfnSelectorModule logical :: ath1 = .false. logical :: ath2 = .false. logical :: atv = .false. + logical :: auxiliary = .false. + logical :: auxmultname = .false. + logical :: boundnames = .false. + logical :: iprflow = .false. + logical :: ipakcb = .false. + logical :: iprpak = .false. + logical :: ts_filerecord = .false. + logical :: ts6 = .false. + logical :: filein = .false. + logical :: ts6_filename = .false. + logical :: obs_filerecord = .false. + logical :: obs6 = .false. + logical :: obs6_filename = .false. + logical :: maxbound = .false. + logical :: cellid = .false. + logical :: tspvar = .false. + logical :: auxvar = .false. + logical :: boundname = .false. logical :: list = .false. logical :: print_input = .false. logical :: print_flows = .false. @@ -100,6 +119,8 @@ function gwt_param_definitions(subcomponent) result(input_definition) call set_param_pointer(input_definition, gwt_disv_param_definitions) case ('DSP') call set_param_pointer(input_definition, gwt_dsp_param_definitions) + case ('CNC') + call set_param_pointer(input_definition, gwt_cnc_param_definitions) case ('NAM') call set_param_pointer(input_definition, gwt_nam_param_definitions) case default @@ -120,6 +141,8 @@ function gwt_aggregate_definitions(subcomponent) result(input_definition) call set_param_pointer(input_definition, gwt_disv_aggregate_definitions) case ('DSP') call set_param_pointer(input_definition, gwt_dsp_aggregate_definitions) + case ('CNC') + call set_param_pointer(input_definition, gwt_cnc_aggregate_definitions) case ('NAM') call set_param_pointer(input_definition, gwt_nam_aggregate_definitions) case default @@ -140,6 +163,8 @@ function gwt_block_definitions(subcomponent) result(input_definition) call set_block_pointer(input_definition, gwt_disv_block_definitions) case ('DSP') call set_block_pointer(input_definition, gwt_dsp_block_definitions) + case ('CNC') + call set_block_pointer(input_definition, gwt_cnc_block_definitions) case ('NAM') call set_block_pointer(input_definition, gwt_nam_block_definitions) case default @@ -159,6 +184,8 @@ function gwt_idm_multi_package(subcomponent) result(multi_package) multi_package = gwt_disv_multi_package case ('DSP') multi_package = gwt_dsp_multi_package + case ('CNC') + multi_package = gwt_cnc_multi_package case ('NAM') multi_package = gwt_nam_multi_package case default @@ -181,6 +208,8 @@ function gwt_idm_sfac_param(subcomponent) result(sfac_param) sfac_param = gwt_disv_aux_sfac_param case ('DSP') sfac_param = gwt_dsp_aux_sfac_param + case ('CNC') + sfac_param = gwt_cnc_aux_sfac_param case ('NAM') sfac_param = gwt_nam_aux_sfac_param case default @@ -204,6 +233,8 @@ function gwt_idm_integrated(subcomponent) result(integrated) integrated = .true. case ('DSP') integrated = .true. + case ('CNC') + integrated = .true. case ('NAM') integrated = .true. case default diff --git a/src/meson.build b/src/meson.build index f0e295b9eb1..c5ee53ab891 100644 --- a/src/meson.build +++ b/src/meson.build @@ -92,6 +92,7 @@ modflow_sources = files( 'Model' / 'GroundWaterTransport' / 'gwt1.f90', 'Model' / 'GroundWaterTransport' / 'gwt1apt1.f90', 'Model' / 'GroundWaterTransport' / 'gwt1cnc1.f90', + 'Model' / 'GroundWaterTransport' / 'gwt1cnc1idm.f90', 'Model' / 'GroundWaterTransport' / 'gwt1dis1idm.f90', 'Model' / 'GroundWaterTransport' / 'gwt1disu1idm.f90', 'Model' / 'GroundWaterTransport' / 'gwt1disv1idm.f90', diff --git a/utils/idmloader/scripts/dfn2f90.py b/utils/idmloader/scripts/dfn2f90.py index 5bd0555817e..fce6a6d7423 100644 --- a/utils/idmloader/scripts/dfn2f90.py +++ b/utils/idmloader/scripts/dfn2f90.py @@ -1036,6 +1036,10 @@ def _write_master_component(self, fh=None): Path("../../../doc/mf6io/mf6ivar/dfn", "gwt-dsp.dfn"), Path("../../../src/Model/GroundWaterTransport", "gwt1dsp1idm.f90"), ], + [ + Path("../../../doc/mf6io/mf6ivar/dfn", "gwt-cnc.dfn"), + Path("../../../src/Model/GroundWaterTransport", "gwt1cnc1idm.f90"), + ], [ Path("../../../doc/mf6io/mf6ivar/dfn", "gwf-nam.dfn"), Path("../../../src/Model/GroundWaterFlow", "gwf3idm.f90"),