diff --git a/make/makefile b/make/makefile index 1e982450e98..ab2602ca54c 100644 --- a/make/makefile +++ b/make/makefile @@ -404,6 +404,7 @@ $(OBJDIR)/VirtualPrtModel.o \ $(OBJDIR)/VirtualGwtModel.o \ $(OBJDIR)/VirtualGwfModel.o \ $(OBJDIR)/VirtualGweModel.o \ +$(OBJDIR)/ModelRegistrar.o \ $(OBJDIR)/VirtualGwtExchange.o \ $(OBJDIR)/VirtualGwfExchange.o \ $(OBJDIR)/VirtualGweExchange.o \ diff --git a/msvs/mf6core.vfproj b/msvs/mf6core.vfproj index 2d7912e2c17..45f0123ecfc 100644 --- a/msvs/mf6core.vfproj +++ b/msvs/mf6core.vfproj @@ -536,6 +536,7 @@ + diff --git a/src/Distributed/VirtualGweModel.f90 b/src/Distributed/VirtualGweModel.f90 index ef9c93cf696..fc28de0c2c5 100644 --- a/src/Distributed/VirtualGweModel.f90 +++ b/src/Distributed/VirtualGweModel.f90 @@ -8,7 +8,7 @@ module VirtualGweModelModule implicit none private - public :: add_virtual_gwe_model + public :: register_virtual_gwe type, extends(VirtualModelType) :: VirtualGweModelType ! CND @@ -34,7 +34,6 @@ module VirtualGweModelModule type(VirtualIntType), pointer :: inest => null() contains ! public - procedure :: create => vgwe_create procedure :: prepare_stage => vgwe_prepare_stage procedure :: destroy => vgwe_destroy ! private @@ -45,37 +44,26 @@ module VirtualGweModelModule contains - subroutine add_virtual_gwe_model(model_id, model_name, model) + subroutine register_virtual_gwe(model_id, model_name, model) use VirtualDataListsModule, only: virtual_model_list - integer(I4B) :: model_id !< global model id - character(len=*) :: model_name !< model name - class(NumericalModelType), pointer :: model !< the actual model (can be null() when remote) + integer(I4B), intent(in) :: model_id !< global model id + character(len=*), intent(in) :: model_name !< model name + class(NumericalModelType), pointer, intent(inout) :: model !< the actual model (can be null() when remote) ! local class(VirtualGweModelType), pointer :: virtual_gwe_model class(*), pointer :: obj allocate (virtual_gwe_model) - call virtual_gwe_model%create(model_name, model_id, model) + call virtual_gwe_model%VirtualModelType%create(model_name, model_id, model) + virtual_gwe_model%container_type = VDC_GWEMODEL_TYPE + + call virtual_gwe_model%allocate_data() + call virtual_gwe_model%init_virtual_data() obj => virtual_gwe_model call virtual_model_list%Add(obj) - end subroutine add_virtual_gwe_model - - subroutine vgwe_create(this, name, id, model) - class(VirtualGweModelType) :: this - character(len=*) :: name - integer(I4B) :: id - class(NumericalModelType), pointer :: model - - ! create base - call this%VirtualModelType%create(name, id, model) - this%container_type = VDC_GWEMODEL_TYPE - - call this%allocate_data() - call this%init_virtual_data() - - end subroutine vgwe_create + end subroutine register_virtual_gwe subroutine init_virtual_data(this) class(VirtualGweModelType) :: this diff --git a/src/Distributed/VirtualGwfModel.f90 b/src/Distributed/VirtualGwfModel.f90 index 0f6d2390ade..3ac67b49a71 100644 --- a/src/Distributed/VirtualGwfModel.f90 +++ b/src/Distributed/VirtualGwfModel.f90 @@ -8,7 +8,7 @@ module VirtualGwfModelModule implicit none private - public :: add_virtual_gwf_model + public :: register_virtual_gwf type, public, extends(VirtualModelType) :: VirtualGwfModelType ! NPF @@ -28,7 +28,6 @@ module VirtualGwfModelModule type(VirtualDbl1dType), pointer :: buy_dense => null() contains ! public - procedure :: create => vgwf_create procedure :: destroy => vgwf_destroy procedure :: prepare_stage => vgwf_prepare_stage ! private @@ -39,39 +38,28 @@ module VirtualGwfModelModule contains - !> @brief Add virtual GWF model + !> @brief Create and register a virtual GWF model !< - subroutine add_virtual_gwf_model(model_id, model_name, model) + subroutine register_virtual_gwf(model_id, model_name, model) use VirtualDataListsModule, only: virtual_model_list - integer(I4B) :: model_id !< global model id - character(len=*) :: model_name !< model name - class(NumericalModelType), pointer :: model !< the actual model (can be null() when remote) + integer(I4B), intent(in) :: model_id !< global model id + character(len=*), intent(in) :: model_name !< model name + class(NumericalModelType), pointer, intent(inout) :: model !< the actual model (can be null() when remote) ! local class(VirtualGwfModelType), pointer :: virtual_gwf_model class(*), pointer :: obj allocate (virtual_gwf_model) - call virtual_gwf_model%create(model_name, model_id, model) + call virtual_gwf_model%VirtualModelType%create(model_name, model_id, model) + virtual_gwf_model%container_type = VDC_GWFMODEL_TYPE + + call virtual_gwf_model%allocate_data() + call virtual_gwf_model%init_virtual_data() obj => virtual_gwf_model call virtual_model_list%Add(obj) - end subroutine add_virtual_gwf_model - - subroutine vgwf_create(this, name, id, model) - class(VirtualGwfModelType) :: this - character(len=*) :: name - integer(I4B) :: id - class(NumericalModelType), pointer :: model - - ! create base - call this%VirtualModelType%create(name, id, model) - this%container_type = VDC_GWFMODEL_TYPE - - call this%allocate_data() - call this%init_virtual_data() - - end subroutine vgwf_create + end subroutine register_virtual_gwf subroutine init_virtual_data(this) class(VirtualGwfModelType) :: this diff --git a/src/Distributed/VirtualGwtModel.f90 b/src/Distributed/VirtualGwtModel.f90 index 75e796886bc..78739ba237e 100644 --- a/src/Distributed/VirtualGwtModel.f90 +++ b/src/Distributed/VirtualGwtModel.f90 @@ -8,7 +8,7 @@ module VirtualGwtModelModule implicit none private - public :: add_virtual_gwt_model + public :: register_virtual_gwt type, extends(VirtualModelType) :: VirtualGwtModelType ! DSP @@ -32,7 +32,6 @@ module VirtualGwtModelModule type(VirtualIntType), pointer :: inmst => null() contains ! public - procedure :: create => vgwt_create procedure :: prepare_stage => vgwt_prepare_stage procedure :: destroy => vgwt_destroy ! private @@ -43,37 +42,26 @@ module VirtualGwtModelModule contains - subroutine add_virtual_gwt_model(model_id, model_name, model) + subroutine register_virtual_gwt(model_id, model_name, model) use VirtualDataListsModule, only: virtual_model_list - integer(I4B) :: model_id !< global model id - character(len=*) :: model_name !< model name - class(NumericalModelType), pointer :: model !< the actual model (can be null() when remote) + integer(I4B), intent(in) :: model_id !< global model id + character(len=*), intent(in) :: model_name !< model name + class(NumericalModelType), pointer, intent(inout) :: model !< the actual model (can be null() when remote) ! local class(VirtualGwtModelType), pointer :: virtual_gwt_model class(*), pointer :: obj allocate (virtual_gwt_model) - call virtual_gwt_model%create(model_name, model_id, model) + call virtual_gwt_model%VirtualModelType%create(model_name, model_id, model) + virtual_gwt_model%container_type = VDC_GWTMODEL_TYPE + + call virtual_gwt_model%allocate_data() + call virtual_gwt_model%init_virtual_data() obj => virtual_gwt_model call virtual_model_list%Add(obj) - end subroutine add_virtual_gwt_model - - subroutine vgwt_create(this, name, id, model) - class(VirtualGwtModelType) :: this - character(len=*) :: name - integer(I4B) :: id - class(NumericalModelType), pointer :: model - - ! create base - call this%VirtualModelType%create(name, id, model) - this%container_type = VDC_GWTMODEL_TYPE - - call this%allocate_data() - call this%init_virtual_data() - - end subroutine vgwt_create + end subroutine register_virtual_gwt subroutine init_virtual_data(this) class(VirtualGwtModelType) :: this diff --git a/src/Distributed/VirtualPrtModel.f90 b/src/Distributed/VirtualPrtModel.f90 index 80c26a6c1b8..e97cbad1167 100644 --- a/src/Distributed/VirtualPrtModel.f90 +++ b/src/Distributed/VirtualPrtModel.f90 @@ -7,12 +7,11 @@ module VirtualPrtModelModule implicit none private - public :: add_virtual_prt_model + public :: register_virtual_prt type, extends(VirtualModelType) :: VirtualPrtModelType contains ! public - procedure :: create => vprt_create procedure :: prepare_stage => vprt_prepare_stage procedure :: destroy => vprt_destroy ! private @@ -23,20 +22,12 @@ module VirtualPrtModelModule contains - subroutine add_virtual_prt_model(model_id, model_name, model) - integer(I4B) :: model_id !< global model id - character(len=*) :: model_name !< model name - class(NumericalModelType), pointer :: model !< the actual model (can be null() when remote) + subroutine register_virtual_prt(model_id, model_name, model) + integer(I4B), intent(in) :: model_id !< global model id + character(len=*), intent(in) :: model_name !< model name + class(NumericalModelType), pointer, intent(inout) :: model !< the actual model (can be null() when remote) ! noop - end subroutine add_virtual_prt_model - - subroutine vprt_create(this, name, id, model) - class(VirtualPrtModelType) :: this - character(len=*) :: name - integer(I4B) :: id - class(NumericalModelType), pointer :: model - ! noop - end subroutine vprt_create + end subroutine register_virtual_prt subroutine init_virtual_data(this) class(VirtualPrtModelType) :: this diff --git a/src/Distributed/VirtualSwfModel.f90 b/src/Distributed/VirtualSwfModel.f90 index 49edaeaee0f..8f8513ea4e5 100644 --- a/src/Distributed/VirtualSwfModel.f90 +++ b/src/Distributed/VirtualSwfModel.f90 @@ -7,12 +7,11 @@ module VirtualSwfModelModule implicit none private - public :: add_virtual_swf_model + public :: register_virtual_swf type, extends(VirtualModelType) :: VirtualSwfModelType contains ! public - procedure :: create => vswf_create procedure :: prepare_stage => vswf_prepare_stage procedure :: destroy => vswf_destroy ! private @@ -23,20 +22,12 @@ module VirtualSwfModelModule contains - subroutine add_virtual_swf_model(model_id, model_name, model) - integer(I4B) :: model_id !< global model id - character(len=*) :: model_name !< model name - class(NumericalModelType), pointer :: model !< the actual model (can be null() when remote) + subroutine register_virtual_swf(model_id, model_name, model) + integer(I4B), intent(in) :: model_id !< global model id + character(len=*), intent(in) :: model_name !< model name + class(NumericalModelType), pointer, intent(inout) :: model !< the actual model (can be null() when remote) ! noop - end subroutine add_virtual_swf_model - - subroutine vswf_create(this, name, id, model) - class(VirtualSwfModelType) :: this - character(len=*) :: name - integer(I4B) :: id - class(NumericalModelType), pointer :: model - ! noop - end subroutine vswf_create + end subroutine register_virtual_swf subroutine init_virtual_data(this) class(VirtualSwfModelType) :: this diff --git a/src/Model/Connection/GweInterfaceModel.f90 b/src/Model/Connection/GweInterfaceModel.f90 index cc7590e40ec..8de93000d5c 100644 --- a/src/Model/Connection/GweInterfaceModel.f90 +++ b/src/Model/Connection/GweInterfaceModel.f90 @@ -49,7 +49,7 @@ module GweInterfaceModelModule contains !> @brief Create the interface model, analogously to what - !< happens in gwe_cr + !< happens in register_gwe subroutine gweifmod_cr(this, name, iout, gridConn) ! -- modules use GweInputDataModule, only: gweshared_dat_cr diff --git a/src/Model/Connection/GwfInterfaceModel.f90 b/src/Model/Connection/GwfInterfaceModel.f90 index 80f3816c74e..7c4de47105b 100644 --- a/src/Model/Connection/GwfInterfaceModel.f90 +++ b/src/Model/Connection/GwfInterfaceModel.f90 @@ -42,7 +42,7 @@ module GwfInterfaceModelModule contains !> @brief set up the interface model, analogously to what - !< happens in gwf_cr + !< happens in register_gwf subroutine gwfifm_cr(this, name, iout, gridConn) class(GwfInterfaceModelType) :: this !< the GWF interface model character(len=*), intent(in) :: name !< the interface model's name diff --git a/src/Model/Connection/GwtInterfaceModel.f90 b/src/Model/Connection/GwtInterfaceModel.f90 index 6cc3f6bf0f6..1e4721abbc9 100644 --- a/src/Model/Connection/GwtInterfaceModel.f90 +++ b/src/Model/Connection/GwtInterfaceModel.f90 @@ -45,7 +45,7 @@ module GwtInterfaceModelModule contains !> @brief Create the interface model, analogously to what - !< happens in gwt_cr + !< happens in register_gwt subroutine gwtifmod_cr(this, name, iout, gridConn) ! -- dummy class(GwtInterfaceModelType) :: this !< the GWT interface model diff --git a/src/Model/GroundWaterEnergy/gwe.f90 b/src/Model/GroundWaterEnergy/gwe.f90 index f0d34e2354d..fcc42f8246a 100644 --- a/src/Model/GroundWaterEnergy/gwe.f90 +++ b/src/Model/GroundWaterEnergy/gwe.f90 @@ -19,7 +19,7 @@ module GweModule implicit none private - public :: gwe_cr + public :: register_gwe public :: GweModelType public :: CastAsGweModel @@ -92,7 +92,7 @@ module GweModule !> @brief Create a new groundwater energy transport model object !< - subroutine gwe_cr(filename, id, modelname) + subroutine register_gwe(id, modelname, filename) ! -- modules use ListsModule, only: basemodellist use BaseModelModule, only: AddBaseModelToList @@ -103,9 +103,9 @@ subroutine gwe_cr(filename, id, modelname) use BudgetModule, only: budget_cr use GweInputDataModule, only: gweshared_dat_cr ! -- dummy - character(len=*), intent(in) :: filename !< input file integer(I4B), intent(in) :: id !< consecutive model number listed in mfsim.nam character(len=*), intent(in) :: modelname !< name of the model + character(len=*), intent(in) :: filename !< input file ! -- local integer(I4B) :: indis type(GweModelType), pointer :: this @@ -137,7 +137,7 @@ subroutine gwe_cr(filename, id, modelname) ! ! -- Return return - end subroutine gwe_cr + end subroutine register_gwe !> @brief Define packages of the GWE model !! diff --git a/src/Model/GroundWaterFlow/gwf-mvr.f90 b/src/Model/GroundWaterFlow/gwf-mvr.f90 index 0e9fd9594ce..4fc3638d8fc 100644 --- a/src/Model/GroundWaterFlow/gwf-mvr.f90 +++ b/src/Model/GroundWaterFlow/gwf-mvr.f90 @@ -41,7 +41,7 @@ ! water, but this value decreases as the mover object consumes water from ! it. ! -! 2. In gwf_cr create the mover package by calling the CR subroutine: +! 2. In register_gwf create the mover package by calling the CR subroutine: ! ! call mvr_cr(this%mvr, this%name, this%inmvr, this%iout) ! diff --git a/src/Model/GroundWaterFlow/gwf.f90 b/src/Model/GroundWaterFlow/gwf.f90 index 1caed0d0fec..ff0a132f791 100644 --- a/src/Model/GroundWaterFlow/gwf.f90 +++ b/src/Model/GroundWaterFlow/gwf.f90 @@ -27,7 +27,7 @@ module GwfModule implicit none private - public :: gwf_cr + public :: register_gwf public :: GwfModelType public :: CastAsGwfModel public :: GWF_NBASEPKG, GWF_NMULTIPKG @@ -134,7 +134,7 @@ module GwfModule !! (2) assign values !! !< - subroutine gwf_cr(filename, id, modelname) + subroutine register_gwf(id, modelname, filename) ! -- modules use ListsModule, only: basemodellist use BaseModelModule, only: AddBaseModelToList @@ -145,9 +145,9 @@ subroutine gwf_cr(filename, id, modelname) use GwfNamInputModule, only: GwfNamParamFoundType use BudgetModule, only: budget_cr ! -- dummy - character(len=*), intent(in) :: filename !< input file integer(I4B), intent(in) :: id !< consecutive model number listed in mfsim.nam character(len=*), intent(in) :: modelname !< name of the model + character(len=*), intent(in) :: filename !< input file ! -- local type(GwfModelType), pointer :: this class(BaseModelType), pointer :: model @@ -208,7 +208,7 @@ subroutine gwf_cr(filename, id, modelname) ! ! -- return return - end subroutine gwf_cr + end subroutine register_gwf !> @brief Define packages of the model !! diff --git a/src/Model/GroundWaterTransport/gwt.f90 b/src/Model/GroundWaterTransport/gwt.f90 index aef3c247dfc..1f9cbf84e59 100644 --- a/src/Model/GroundWaterTransport/gwt.f90 +++ b/src/Model/GroundWaterTransport/gwt.f90 @@ -23,7 +23,7 @@ module GwtModule implicit none private - public :: gwt_cr + public :: register_gwt public :: GwtModelType public :: CastAsGwtModel public :: GWT_NBASEPKG, GWT_NMULTIPKG @@ -94,7 +94,7 @@ module GwtModule !> @brief Create a new groundwater transport model object !< - subroutine gwt_cr(filename, id, modelname) + subroutine register_gwt(id, modelname, filename) ! -- modules use ListsModule, only: basemodellist use BaseModelModule, only: AddBaseModelToList @@ -104,9 +104,9 @@ subroutine gwt_cr(filename, id, modelname) use GwtNamInputModule, only: GwtNamParamFoundType use BudgetModule, only: budget_cr ! -- dummy - character(len=*), intent(in) :: filename !< input file integer(I4B), intent(in) :: id !< consecutive model number listed in mfsim.nam character(len=*), intent(in) :: modelname !< name of the model + character(len=*), intent(in) :: filename !< input file ! -- local integer(I4B) :: indis type(GwtModelType), pointer :: this @@ -135,7 +135,7 @@ subroutine gwt_cr(filename, id, modelname) ! ! -- Return return - end subroutine gwt_cr + end subroutine register_gwt !> @brief Define packages of the GWT model !! diff --git a/src/Model/ParticleTracking/prt.f90 b/src/Model/ParticleTracking/prt.f90 index 94462f0b940..294c471ae08 100644 --- a/src/Model/ParticleTracking/prt.f90 +++ b/src/Model/ParticleTracking/prt.f90 @@ -28,7 +28,7 @@ module PrtModule implicit none private - public :: prt_cr + public :: register_prt public :: PrtModelType public :: PRT_NBASEPKG, PRT_NMULTIPKG public :: PRT_BASEPKG, PRT_MULTIPKG @@ -119,7 +119,7 @@ module PrtModule contains !> @brief Create a new particle tracking model object - subroutine prt_cr(filename, id, modelname) + subroutine register_prt(id, modelname, filename) ! -- modules use ListsModule, only: basemodellist use BaseModelModule, only: AddBaseModelToList @@ -130,9 +130,9 @@ subroutine prt_cr(filename, id, modelname) use SimVariablesModule, only: idm_context use GwfNamInputModule, only: GwfNamParamFoundType ! -- dummy - character(len=*), intent(in) :: filename integer(I4B), intent(in) :: id character(len=*), intent(in) :: modelname + character(len=*), intent(in) :: filename ! -- local type(PrtModelType), pointer :: this class(BaseModelType), pointer :: model @@ -187,7 +187,7 @@ subroutine prt_cr(filename, id, modelname) ! -- Create model packages call this%create_packages() - end subroutine prt_cr + end subroutine register_prt !> @brief Define packages !! diff --git a/src/Model/SurfaceWaterFlow/swf.f90 b/src/Model/SurfaceWaterFlow/swf.f90 index afa5175eac5..d7a72a933ee 100644 --- a/src/Model/SurfaceWaterFlow/swf.f90 +++ b/src/Model/SurfaceWaterFlow/swf.f90 @@ -58,7 +58,7 @@ module SwfModule implicit none private - public :: swf_cr + public :: register_swf public :: SwfModelType public :: SWF_NBASEPKG, SWF_NMULTIPKG public :: SWF_BASEPKG, SWF_MULTIPKG @@ -141,7 +141,7 @@ module SwfModule !! (2) assign values !! !< - subroutine swf_cr(filename, id, modelname) + subroutine register_swf(id, modelname, filename) ! -- modules use ListsModule, only: basemodellist use BaseModelModule, only: AddBaseModelToList @@ -151,9 +151,9 @@ subroutine swf_cr(filename, id, modelname) use SwfNamInputModule, only: SwfNamParamFoundType use BudgetModule, only: budget_cr ! -- dummy - character(len=*), intent(in) :: filename !< input file integer(I4B), intent(in) :: id !< consecutive model number listed in mfsim.nam character(len=*), intent(in) :: modelname !< name of the model + character(len=*), intent(in) :: filename !< input file ! -- local type(SwfModelType), pointer :: this class(BaseModelType), pointer :: model @@ -214,7 +214,7 @@ subroutine swf_cr(filename, id, modelname) ! ! -- return return - end subroutine swf_cr + end subroutine register_swf !> @brief Allocate memory for scalar members subroutine allocate_scalars(this, modelname) diff --git a/src/ModelFactory.f90 b/src/ModelFactory.f90 index 0649190acaf..36a724b8005 100644 --- a/src/ModelFactory.f90 +++ b/src/ModelFactory.f90 @@ -1,13 +1,11 @@ module ModelFactoryModule use KindModule, only: I4B - use ConstantsModule, only: LENMEMPATH, LINELENGTH, LENMODELNAME - use ListsModule, only: basemodellist - use SimModule, only: store_error, count_errors - use SimVariablesModule, only: iout, model_names, model_ranks, model_loc_idx, & - idm_context, proc_id, nr_procs, simulation_mode - use MemoryHelperModule, only: create_mem_path - use MemoryManagerModule, only: mem_setptr, mem_allocate + use ConstantsModule, only: LINELENGTH, LENMODELNAME + use SimModule, only: check_model_name, store_error + use SimVariablesModule, only: model_names, model_loc_idx, & + proc_id, simulation_mode use CharacterStringModule, only: CharacterStringType + use ModelRegistrarModule implicit none private @@ -15,170 +13,20 @@ module ModelFactoryModule contains - subroutine add_gwf_model(n, im, fname) - ! -- modules - use NumericalModelModule, only: NumericalModelType, & - GetNumericalModelFromList - use GwfModule, only: gwf_cr - use VirtualGwfModelModule, only: add_virtual_gwf_model - ! -- dummy - integer(I4B), intent(in) :: n - integer(I4B), intent(inout) :: im - character(len=*), intent(in) :: fname - ! -- local - class(NumericalModelType), pointer :: model - - model => null() ! can be null for remote models - if (model_ranks(n) == proc_id) then - im = im + 1 - write (iout, '(4x,2a,i0,a)') 'GWF6', ' model ', & - n, ' will be created' - call gwf_cr(fname, n, model_names(n)) - model => GetNumericalModelFromList(basemodellist, im) - model_loc_idx(n) = im - end if - call add_virtual_gwf_model(n, model_names(n), model) - - end subroutine add_gwf_model - - subroutine add_gwt_model(n, im, fname) - ! -- modules - use NumericalModelModule, only: NumericalModelType, & - GetNumericalModelFromList - use GwtModule, only: gwt_cr - use VirtualGwtModelModule, only: add_virtual_gwt_model - ! -- dummy - integer(I4B), intent(in) :: n - integer(I4B), intent(inout) :: im - character(len=*), intent(in) :: fname - ! -- local - class(NumericalModelType), pointer :: model - - model => null() ! can be null for remote models - if (model_ranks(n) == proc_id) then - im = im + 1 - write (iout, '(4x,2a,i0,a)') 'GWT6', ' model ', & - n, ' will be created' - call gwt_cr(fname, n, model_names(n)) - model => GetNumericalModelFromList(basemodellist, im) - model_loc_idx(n) = im - end if - call add_virtual_gwt_model(n, model_names(n), model) - - end subroutine add_gwt_model - - subroutine add_gwe_model(n, im, fname) - ! -- modules - use NumericalModelModule, only: NumericalModelType, & - GetNumericalModelFromList - use GweModule, only: gwe_cr - use VirtualGweModelModule, only: add_virtual_gwe_model - ! -- dummy - integer(I4B), intent(in) :: n - integer(I4B), intent(inout) :: im - character(len=*), intent(in) :: fname - ! -- local - class(NumericalModelType), pointer :: model - - model => null() ! can be null for remote models - if (model_ranks(n) == proc_id) then - im = im + 1 - write (iout, '(4x,2a,i0,a)') 'GWE6', ' model ', & - n, ' will be created' - call gwe_cr(fname, n, model_names(n)) - model => GetNumericalModelFromList(basemodellist, im) - model_loc_idx(n) = im - end if - call add_virtual_gwe_model(n, model_names(n), model) - - end subroutine add_gwe_model - - subroutine add_prt_model(n, im, fname) - ! -- modules - use NumericalModelModule, only: NumericalModelType, & - GetNumericalModelFromList - use PrtModule, only: prt_cr - use VirtualPrtModelModule, only: add_virtual_prt_model - ! -- dummy - integer(I4B), intent(in) :: n - integer(I4B), intent(inout) :: im - character(len=*), intent(in) :: fname - ! -- local - class(NumericalModelType), pointer :: model - - model => null() ! can be null for remote models - if (model_ranks(n) == proc_id) then - im = im + 1 - write (iout, '(4x,2a,i0,a)') 'PRT6', ' model ', & - n, ' will be created' - call prt_cr(fname, n, model_names(n)) - model => GetNumericalModelFromList(basemodellist, im) - model_loc_idx(n) = im - end if - call add_virtual_prt_model(n, model_names(n), model) - - end subroutine add_prt_model - - subroutine add_swf_model(n, im, fname) - ! -- modules - use NumericalModelModule, only: NumericalModelType, & - GetNumericalModelFromList - use SwfModule, only: swf_cr - use VirtualSwfModelModule, only: add_virtual_swf_model - ! -- dummy - integer(I4B), intent(in) :: n - integer(I4B), intent(inout) :: im - character(len=*), intent(in) :: fname - ! -- local - class(NumericalModelType), pointer :: model - - model => null() ! can be null for remote models - if (model_ranks(n) == proc_id) then - im = im + 1 - write (iout, '(4x,2a,i0,a)') 'SWF6', ' model ', & - n, ' will be created' - call swf_cr(fname, n, model_names(n)) - model => GetNumericalModelFromList(basemodellist, im) - model_loc_idx(n) = im - end if - call add_virtual_swf_model(n, model_names(n), model) - - end subroutine add_swf_model - - !> @brief Check that the model name is valid - !< - subroutine check_model_name(mtype, mname) - ! -- dummy - character(len=*), intent(in) :: mtype - character(len=*), intent(inout) :: mname - ! -- local - integer :: ilen - integer :: i - character(len=LINELENGTH) :: errmsg - logical :: terminate = .true. - ! - ilen = len_trim(mname) - if (ilen > LENMODELNAME) then - write (errmsg, '(a,a)') 'Invalid model name: ', trim(mname) - call store_error(errmsg) - write (errmsg, '(a,i0,a,i0)') & - 'Name length of ', ilen, ' exceeds maximum length of ', & - LENMODELNAME - call store_error(errmsg, terminate) - end if - do i = 1, ilen - if (mname(i:i) == ' ') then - write (errmsg, '(a,a)') 'Invalid model name: ', trim(mname) - call store_error(errmsg) - write (errmsg, '(a)') & - 'Model name cannot have spaces within it.' - call store_error(errmsg, terminate) - end if - end do - - end subroutine check_model_name - subroutine create_models(mtypes, mfnames, mnames) + ! -- modules + ! START TEMPLATING + use GwfModule, only: register_gwf + use VirtualGwfModelModule, only: register_virtual_gwf + use GwtModule, only: register_gwt + use VirtualGwtModelModule, only: register_virtual_gwt + use GweModule, only: register_gwe + use VirtualGweModelModule, only: register_virtual_gwe + use PrtModule, only: register_prt + use VirtualPrtModelModule, only: register_virtual_prt + use SwfModule, only: register_swf + use VirtualSwfModelModule, only: register_virtual_swf + ! END TEMPLATING ! -- dummy type(CharacterStringType), dimension(:), contiguous, & pointer, intent(in) :: mtypes !< model types @@ -189,6 +37,8 @@ subroutine create_models(mtypes, mfnames, mnames) ! -- local integer(I4B) :: n, im character(len=LINELENGTH) :: errmsg, model_name, model_type, fname + procedure(register_actual_model), pointer :: ram + procedure(register_virtual_model), pointer :: rvm im = 0 do n = 1, size(mtypes) @@ -203,23 +53,34 @@ subroutine create_models(mtypes, mfnames, mnames) model_names(n) = model_name(1:LENMODELNAME) model_loc_idx(n) = -1 - ! -- add a new (local or global) model + ! -- set model creation procedure pointers + ! todo: hashmaps? (mtype -> create routine) select case (model_type) + ! START TEMPLATING case ('GWF6') - call add_gwf_model(n, im, fname) + ram => register_gwf + rvm => register_virtual_gwf case ('GWT6') - call add_gwt_model(n, im, fname) + ram => register_gwt + rvm => register_virtual_gwt case ('GWE6') - call add_gwe_model(n, im, fname) + ram => register_gwe + rvm => register_virtual_gwe case ('PRT6') - call add_prt_model(n, im, fname) + ram => register_prt + rvm => register_virtual_prt case ('SWF6') - call add_swf_model(n, im, fname) + ram => register_swf + rvm => register_virtual_swf + ! END TEMPLATING case default write (errmsg, '(a,a)') & 'Unknown simulation model type: ', trim(model_type) call store_error(errmsg, terminate=.true.) end select + + ! -- register local or global model + call register_model(ram, rvm, n, im, model_names(n), model_type, fname) end do ! -- sanity check diff --git a/src/ModelRegistrar.f90 b/src/ModelRegistrar.f90 new file mode 100644 index 00000000000..cf62df014f5 --- /dev/null +++ b/src/ModelRegistrar.f90 @@ -0,0 +1,57 @@ +module ModelRegistrarModule + use KindModule, only: I4B + use ListsModule, only: basemodellist + use SimVariablesModule, only: iout, model_ranks, model_loc_idx, proc_id + use NumericalModelModule, only: NumericalModelType, GetNumericalModelFromList + + implicit none + private + public :: register_model, register_actual_model, register_virtual_model + + interface + subroutine register_actual_model(id, name, filename) + import I4B + integer(I4B), intent(in) :: id !< model id (listed in mfsim.nam) + character(len=*), intent(in) :: name !< model name + character(len=*), intent(in) :: filename !< input file + end subroutine + end interface + + interface + subroutine register_virtual_model(id, name, model) + import I4B + import NumericalModelType + integer(I4B), intent(in) :: id !< model id (listed in mfsim.nam) + character(len=*), intent(in) :: name !< model name + class(NumericalModelType), pointer, intent(inout) :: model !< the actual model (can be null() when remote) + end subroutine + end interface + +contains + + subroutine register_model(ram, rvm, n, id, mname, mtype, filename) + ! -- dummy + procedure(register_actual_model), pointer, intent(in) :: ram + procedure(register_virtual_model), pointer, intent(in) :: rvm + integer(I4B), intent(in) :: n + integer(I4B), intent(inout) :: id !< model id (listed in mfsim.nam) + character(len=*), intent(in) :: mname !< model name + character(len=*), intent(in) :: mtype !< model type + character(len=*), intent(in) :: filename !< input file + ! -- local + class(NumericalModelType), pointer :: model + + model => null() ! can be null for remote models + if (model_ranks(n) == proc_id) then + id = id + 1 + write (iout, '(4x,2a,i0,a)') trim(mtype), ' model ', & + n, ' will be created' + call ram(n, mname, filename) + model => GetNumericalModelFromList(basemodellist, id) + model_loc_idx(n) = id + end if + call rvm(n, mname, model) + + end subroutine register_model + +end module ModelRegistrarModule diff --git a/src/Utilities/Sim.f90 b/src/Utilities/Sim.f90 index 14d5a0103fa..7c589b01b42 100644 --- a/src/Utilities/Sim.f90 +++ b/src/Utilities/Sim.f90 @@ -12,7 +12,7 @@ module SimModule use KindModule, only: DP, I4B use ErrorUtilModule, only: pstop use DefinedMacros, only: get_os - use ConstantsModule, only: MAXCHARLEN, LINELENGTH, & + use ConstantsModule, only: MAXCHARLEN, LINELENGTH, LENMODELNAME, & DONE, & IUSTART, IULAST, & VSUMMARY, VALL, VDEBUG, & @@ -25,6 +25,7 @@ module SimModule implicit none private + public :: check_model_name public :: count_errors public :: store_error public :: ustop @@ -48,6 +49,39 @@ module SimModule contains + !> @brief Check that the model name is valid + !< + subroutine check_model_name(mtype, mname) + ! -- dummy + character(len=*), intent(in) :: mtype + character(len=*), intent(inout) :: mname + ! -- local + integer :: ilen + integer :: i + character(len=LINELENGTH) :: errmsg + logical :: terminate = .true. + ! + ilen = len_trim(mname) + if (ilen > LENMODELNAME) then + write (errmsg, '(a,a)') 'Invalid model name: ', trim(mname) + call store_error(errmsg) + write (errmsg, '(a,i0,a,i0)') & + 'Name length of ', ilen, ' exceeds maximum length of ', & + LENMODELNAME + call store_error(errmsg, terminate) + end if + do i = 1, ilen + if (mname(i:i) == ' ') then + write (errmsg, '(a,a)') 'Invalid model name: ', trim(mname) + call store_error(errmsg) + write (errmsg, '(a)') & + 'Model name cannot have spaces within it.' + call store_error(errmsg, terminate) + end if + end do + + end subroutine check_model_name + !> @brief Return number of errors !! !! Function to return the number of errors messages that have been stored. diff --git a/src/meson.build b/src/meson.build index bff40681b64..c42a85b9a45 100644 --- a/src/meson.build +++ b/src/meson.build @@ -359,6 +359,7 @@ modflow_sources = files( 'RunControl.f90', 'RunControlFactory.F90', 'ModelFactory.f90', + 'ModelRegistrar.f90', 'ExchangeFactory.f90' )