MODFLOW 6  version 6.5.0.dev2
MODFLOW 6 Code Documentation
ExplicitSolution.f90
Go to the documentation of this file.
1 !> @brief Explicit Solution Module
2 !!
3 !! This module contains the Explicit Solution, which is a
4 !! class for solving explicit models. The explicit solution
5 !! scrolls through a list of explicit models and calls
6 !! methods in a prescribed sequence.
7 !!
8 !<
10  use kindmodule, only: i4b, dp
11  use timermodule, only: code_timer
21  use listmodule, only: listtype
22  use listsmodule, only: basesolutionlist
26  use inputoutputmodule, only: getunit
27 
28  implicit none
29  private
30 
31  public :: create_explicit_solution
32  public :: explicitsolutiontype
33 
34  !> @brief Manages and solves explicit models.
35  !!
36  !! An explicit solution simply scrolls through a list of explicit
37  !! models and calls solution procedures in a prescribed sequence.
38  !<
40  character(len=LENMEMPATH) :: memorypath !< the path for storing solution variables in the memory manager
41  type(listtype), pointer :: modellist !< list of models in solution
42  integer(I4B), pointer :: id !< solution number
43  integer(I4B), pointer :: iu !< input file unit
44  real(dp), pointer :: ttsoln !< timer - total solution time
45  integer(I4B), pointer :: icnvg => null() !< convergence flag
46  type(blockparsertype) :: parser !< block parser object
47  contains
48  procedure :: sln_df
49  procedure :: sln_ar
50  procedure :: sln_calculate_delt
51  procedure :: sln_ad
52  procedure :: sln_ot
53  procedure :: sln_ca
54  procedure :: sln_fp
55  procedure :: sln_da
56  procedure :: add_model
57  procedure :: add_exchange
58  procedure :: get_models
59  procedure :: get_exchanges
60  procedure :: save
61 
62  procedure, private :: allocate_scalars
63 
64  ! Expose these for use through the BMI/XMI:
65  procedure, public :: preparesolve
66  procedure, public :: solve
67  procedure, public :: finalizesolve
68 
69  end type explicitsolutiontype
70 
71 contains
72 
73  !> @ brief Create a new solution
74  !!
75  !! Create a new solution using the data in filename, assign this new
76  !! solution an id number and store the solution in the basesolutionlist.
77  !! Also open the filename for later reading.
78  !<
79  subroutine create_explicit_solution(exp_sol, filename, id)
80  ! -- modules
82  ! -- dummy variables
83  class(explicitsolutiontype), pointer :: exp_sol !< the create solution
84  character(len=*), intent(in) :: filename !< solution input file name
85  integer(I4B), intent(in) :: id !< solution id
86  ! -- local variables
87  integer(I4B) :: inunit
88  class(basesolutiontype), pointer :: solbase => null()
89  character(len=LENSOLUTIONNAME) :: solutionname
90 
91  ! -- Create a new solution and add it to the basesolutionlist container
92  solbase => exp_sol
93  write (solutionname, '(a, i0)') 'SLN_', id
94  exp_sol%name = solutionname
95  exp_sol%memoryPath = create_mem_path(solutionname)
96  allocate (exp_sol%modellist)
97  !todo: do we need this? allocate (exp_sol%exchangelist)
98  call exp_sol%allocate_scalars()
100  exp_sol%id = id
101 
102  ! -- Open solution input file for reading later after problem size is known
103  ! Check to see if the file is already opened, which can happen when
104  ! running in single model mode
105  inquire (file=filename, number=inunit)
106  if (inunit < 0) inunit = getunit()
107  exp_sol%iu = inunit
108  write (iout, '(/a,a/)') ' Creating explicit solution (EMS): ', exp_sol%name
109  call openfile(exp_sol%iu, iout, filename, 'IMS')
110 
111  ! -- Initialize block parser
112  call exp_sol%parser%Initialize(exp_sol%iu, iout)
113  end subroutine create_explicit_solution
114 
115  !> @ brief Allocate scalars
116  !<
117  subroutine allocate_scalars(this)
118  class(explicitsolutiontype) :: this !< ExplicitSolutionType instance
119 
120  ! -- allocate scalars
121  call mem_allocate(this%id, 'ID', this%memoryPath)
122  call mem_allocate(this%iu, 'IU', this%memoryPath)
123  call mem_allocate(this%ttsoln, 'TTSOLN', this%memoryPath)
124  call mem_allocate(this%icnvg, 'ICNVG', this%memoryPath)
125 
126  ! -- initialize
127  this%id = 0
128  this%iu = 0
129  this%ttsoln = dzero
130  this%icnvg = 0
131  end subroutine allocate_scalars
132 
133  !> @ brief Define the solution
134  !<
135  subroutine sln_df(this)
136  class(explicitsolutiontype) :: this
137  end subroutine
138 
139  !> @ brief Allocate and read
140  !<
141  subroutine sln_ar(this)
142  class(explicitsolutiontype) :: this !< ExplicitSolutionType instance
143 
144  ! -- close ems input file
145  call this%parser%Clear()
146  end subroutine sln_ar
147 
148  !> @ brief Calculate time step length
149  !<
150  subroutine sln_calculate_delt(this)
151  class(explicitsolutiontype) :: this !< ExplicitSolutionType instance
152  end subroutine sln_calculate_delt
153 
154  !> @ brief Advance the solution
155  !<
156  subroutine sln_ad(this)
157  class(explicitsolutiontype) :: this !< ExplicitSolutionType instance
158 
159  ! -- reset convergence flag
160  this%icnvg = 0
161  end subroutine sln_ad
162 
163  !> @ brief Solution output
164  !<
165  subroutine sln_ot(this)
166  class(explicitsolutiontype) :: this !< ExplicitSolutionType instance
167  end subroutine sln_ot
168 
169  subroutine sln_fp(this)
170  class(explicitsolutiontype) :: this !< ExplicitSolutionType instance
171  end subroutine sln_fp
172 
173  !> @ brief Deallocate
174  !<
175  subroutine sln_da(this)
176  class(explicitsolutiontype) :: this !< ExplicitSolutionType instance
177 
178  ! -- lists
179  call this%modellist%Clear()
180  deallocate (this%modellist)
181 
182  ! -- Scalars
183  call mem_deallocate(this%id)
184  call mem_deallocate(this%iu)
185  call mem_deallocate(this%ttsoln)
186  call mem_deallocate(this%icnvg)
187  end subroutine sln_da
188 
189  !> @ brief Calculate
190  !<
191  subroutine sln_ca(this, isgcnvg, isuppress_output)
192  ! -- dummy variables
193  class(explicitsolutiontype) :: this !< ExplicitSolutionType instance
194  integer(I4B), intent(inout) :: isgcnvg !< solution group convergence flag
195  integer(I4B), intent(in) :: isuppress_output !< flag for suppressing output
196  ! -- local variables
197  class(numericalmodeltype), pointer :: mp => null()
198  character(len=LINELENGTH) :: line
199  character(len=LINELENGTH) :: fmt
200  integer(I4B) :: im
201 
202  ! advance the models and solution
203  call this%prepareSolve()
204 
205  select case (isim_mode)
206  case (mvalidate)
207  line = 'mode="validation" -- Skipping assembly and solution.'
208  fmt = "(/,1x,a,/)"
209  do im = 1, this%modellist%Count()
210  mp => getnumericalmodelfromlist(this%modellist, im)
211  call mp%model_message(line, fmt=fmt)
212  end do
213  case (mnormal)
214 
215  ! solve the models
216  call this%solve()
217 
218  ! finish up
219  call this%finalizeSolve(isgcnvg, isuppress_output)
220  end select
221  end subroutine sln_ca
222 
223  !> @ brief Prepare to solve
224  !<
225  subroutine preparesolve(this)
226  ! -- dummy variables
227  class(explicitsolutiontype) :: this !< ExplicitSolutionType instance
228  ! -- local variables
229  integer(I4B) :: im
230  class(numericalmodeltype), pointer :: mp => null()
231 
232  ! -- Model advance
233  do im = 1, this%modellist%Count()
234  mp => getnumericalmodelfromlist(this%modellist, im)
235  call mp%model_ad()
236  end do
237 
238  ! advance solution
239  call this%sln_ad()
240  end subroutine preparesolve
241 
242  !> @ brief Solve each model
243  !<
244  subroutine solve(this)
245  ! -- dummy variables
246  class(explicitsolutiontype) :: this !< ExplicitSolutionType instance
247  ! -- local variables
248  class(numericalmodeltype), pointer :: mp => null()
249  integer(I4B) :: im
250  real(DP) :: ttsoln
251 
252  call code_timer(0, ttsoln, this%ttsoln)
253  do im = 1, this%modellist%Count()
254  mp => getnumericalmodelfromlist(this%modellist, im)
255  call mp%model_solve()
256  end do
257  call code_timer(1, ttsoln, this%ttsoln)
258  this%icnvg = 1
259  end subroutine solve
260 
261  !> @ brief Finalize solve
262  !<
263  subroutine finalizesolve(this, isgcnvg, isuppress_output)
264  ! -- dummy variables
265  class(explicitsolutiontype) :: this !< ExplicitSolutionType instance
266  integer(I4B), intent(inout) :: isgcnvg !< solution group convergence flag
267  integer(I4B), intent(in) :: isuppress_output !< flag for suppressing output
268  ! -- local variables
269  integer(I4B) :: im
270  class(numericalmodeltype), pointer :: mp => null()
271 
272  ! -- Calculate flow for each model
273  do im = 1, this%modellist%Count()
274  mp => getnumericalmodelfromlist(this%modellist, im)
275  call mp%model_cq(this%icnvg, isuppress_output)
276  end do
277 
278  ! -- Budget terms for each model
279  do im = 1, this%modellist%Count()
280  mp => getnumericalmodelfromlist(this%modellist, im)
281  call mp%model_bd(this%icnvg, isuppress_output)
282  end do
283  end subroutine finalizesolve
284 
285  !> @ brief Save output
286  !<
287  subroutine save(this, filename)
288  ! -- dummy variables
289  class(explicitsolutiontype) :: this !< ExplicitSolutionType instance
290  character(len=*), intent(in) :: filename !< filename to save solution data
291  ! -- local variables
292  integer(I4B) :: inunit
293 
294  inunit = getunit()
295  open (unit=inunit, file=filename, status='unknown')
296  write (inunit, *) 'The save routine currently writes nothing'
297  close (inunit)
298  end subroutine save
299 
300  !> @ brief Add explicit model to list
301  !<
302  subroutine add_model(this, mp)
303  ! -- dummy variables
304  class(explicitsolutiontype) :: this !< ExplicitSolutionType instance
305  class(basemodeltype), pointer, intent(in) :: mp !< model instance
306  ! -- local variables
307  class(numericalmodeltype), pointer :: m => null()
308 
309  ! -- add a model
310  select type (mp)
311  class is (numericalmodeltype)
312  m => mp
313  call addnumericalmodeltolist(this%modellist, m)
314  end select
315  end subroutine add_model
316 
317  !> @brief Get a pointer to a list of models in the solution
318  !<
319  function get_models(this) result(models)
320  type(listtype), pointer :: models !< pointer to the model list
321  class(explicitsolutiontype) :: this !< ExplicitSolutionType instance
322 
323  models => this%modellist
324  end function get_models
325 
326  !> @ brief Add exchange to list of exchanges
327  !<
328  subroutine add_exchange(this, exchange)
329  class(explicitsolutiontype) :: this
330  class(baseexchangetype), pointer, intent(in) :: exchange
331  end subroutine add_exchange
332 
333  !> @ brief Get list of exchanges
334  !<
335  function get_exchanges(this) result(exchanges)
336  class(explicitsolutiontype) :: this
337  type(listtype), pointer :: exchanges
338  end function get_exchanges
339 
340 end module explicitsolutionmodule
subroutine, public addbasesolutiontolist(list, solution)
This module contains block parser methods.
Definition: BlockParser.f90:7
This module contains simulation constants.
Definition: Constants.f90:9
integer(i4b), parameter linelength
maximum length of a standard line
Definition: Constants.f90:44
@ mvalidate
validation mode - do not run time steps
Definition: Constants.f90:204
@ mnormal
normal output mode
Definition: Constants.f90:205
integer(i4b), parameter lensolutionname
maximum length of the solution name
Definition: Constants.f90:20
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:64
integer(i4b), parameter lenmempath
maximum length of the memory path
Definition: Constants.f90:26
Explicit Solution Module.
subroutine preparesolve(this)
@ brief Prepare to solve
type(listtype) function, pointer get_models(this)
Get a pointer to a list of models in the solution.
subroutine, public create_explicit_solution(exp_sol, filename, id)
@ brief Create a new solution
subroutine add_model(this, mp)
@ brief Add explicit model to list
subroutine add_exchange(this, exchange)
@ brief Add exchange to list of exchanges
type(listtype) function, pointer get_exchanges(this)
@ brief Get list of exchanges
subroutine finalizesolve(this, isgcnvg, isuppress_output)
@ brief Finalize solve
subroutine save(this, filename)
@ brief Save output
subroutine solve(this)
@ brief Solve each model
subroutine allocate_scalars(this)
@ brief Allocate scalars
integer(i4b) function, public getunit()
Get a free unit number.
subroutine, public openfile(iu, iout, fname, ftype, fmtarg_opt, accarg_opt, filstat_opt, mode_opt)
Open a file.
Definition: InputOutput.f90:30
This module defines variable data types.
Definition: kind.f90:8
type(listtype), public basesolutionlist
Definition: mf6lists.f90:19
character(len=lenmempath) function create_mem_path(component, subcomponent, context)
returns the path to the memory object
subroutine, public addnumericalmodeltolist(list, model)
class(numericalmodeltype) function, pointer, public getnumericalmodelfromlist(list, idx)
This module contains simulation variables.
Definition: SimVariables.f90:9
integer(i4b) iout
file unit number for simulation output
integer(i4b) isim_mode
simulation mode
subroutine, public code_timer(it, t1, ts)
Get end time and calculate elapsed time.
Definition: Timer.f90:165
Highest level model type. All models extend this parent type.
Definition: BaseModel.f90:13
Manages and solves explicit models.
A generic heterogeneous doubly-linked list.
Definition: List.f90:10