MODFLOW 6  version 6.7.0.dev0
USGS Modular Hydrologic Model
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_dt
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_dt(this)
151  class(explicitsolutiontype) :: this !< ExplicitSolutionType instance
152  end subroutine sln_dt
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  integer(I4B) :: kiter
202 
203  kiter = 1
204 
205  ! advance the models and solution
206  call this%prepareSolve()
207 
208  select case (isim_mode)
209  case (mvalidate)
210  line = 'mode="validation" -- Skipping assembly and solution.'
211  fmt = "(/,1x,a,/)"
212  do im = 1, this%modellist%Count()
213  mp => getnumericalmodelfromlist(this%modellist, im)
214  call mp%model_message(line, fmt=fmt)
215  end do
216  case (mnormal)
217 
218  ! solve the models
219  call this%solve(kiter)
220 
221  ! finish up
222  call this%finalizeSolve(kiter, isgcnvg, isuppress_output)
223  end select
224  end subroutine sln_ca
225 
226  !> @ brief Prepare to solve
227  !<
228  subroutine preparesolve(this)
229  ! -- dummy variables
230  class(explicitsolutiontype) :: this !< ExplicitSolutionType instance
231  ! -- local variables
232  integer(I4B) :: im
233  class(numericalmodeltype), pointer :: mp => null()
234 
235  ! -- Model advance
236  do im = 1, this%modellist%Count()
237  mp => getnumericalmodelfromlist(this%modellist, im)
238  call mp%model_ad()
239  end do
240 
241  ! advance solution
242  call this%sln_ad()
243  end subroutine preparesolve
244 
245  !> @ brief Solve each model
246  !<
247  subroutine solve(this, kiter)
248  ! -- dummy variables
249  class(explicitsolutiontype) :: this !< ExplicitSolutionType instance
250  integer(I4B), intent(in) :: kiter !< Picard iteration (1 for explicit)
251  ! -- local variables
252  class(numericalmodeltype), pointer :: mp => null()
253  integer(I4B) :: im
254  real(DP) :: ttsoln
255 
256  call code_timer(0, ttsoln, this%ttsoln)
257  do im = 1, this%modellist%Count()
258  mp => getnumericalmodelfromlist(this%modellist, im)
259  call mp%model_solve()
260  end do
261  call code_timer(1, ttsoln, this%ttsoln)
262  this%icnvg = 1
263  end subroutine solve
264 
265  !> @ brief Finalize solve
266  !<
267  subroutine finalizesolve(this, kiter, isgcnvg, isuppress_output)
268  ! -- dummy variables
269  class(explicitsolutiontype) :: this !< ExplicitSolutionType instance
270  integer(I4B), intent(in) :: kiter !< Picard iteration number (always 1 for explicit)
271  integer(I4B), intent(inout) :: isgcnvg !< solution group convergence flag
272  integer(I4B), intent(in) :: isuppress_output !< flag for suppressing output
273  ! -- local variables
274  integer(I4B) :: im
275  class(numericalmodeltype), pointer :: mp => null()
276 
277  ! -- Calculate flow for each model
278  do im = 1, this%modellist%Count()
279  mp => getnumericalmodelfromlist(this%modellist, im)
280  call mp%model_cq(this%icnvg, isuppress_output)
281  end do
282 
283  ! -- Budget terms for each model
284  do im = 1, this%modellist%Count()
285  mp => getnumericalmodelfromlist(this%modellist, im)
286  call mp%model_bd(this%icnvg, isuppress_output)
287  end do
288  end subroutine finalizesolve
289 
290  !> @ brief Save output
291  !<
292  subroutine save(this, filename)
293  ! -- dummy variables
294  class(explicitsolutiontype) :: this !< ExplicitSolutionType instance
295  character(len=*), intent(in) :: filename !< filename to save solution data
296  ! -- local variables
297  integer(I4B) :: inunit
298 
299  inunit = getunit()
300  open (unit=inunit, file=filename, status='unknown')
301  write (inunit, *) 'The save routine currently writes nothing'
302  close (inunit)
303  end subroutine save
304 
305  !> @ brief Add explicit model to list
306  !<
307  subroutine add_model(this, mp)
308  ! -- dummy variables
309  class(explicitsolutiontype) :: this !< ExplicitSolutionType instance
310  class(basemodeltype), pointer, intent(in) :: mp !< model instance
311  ! -- local variables
312  class(numericalmodeltype), pointer :: m => null()
313 
314  ! -- add a model
315  select type (mp)
316  class is (numericalmodeltype)
317  m => mp
318  call addnumericalmodeltolist(this%modellist, m)
319  end select
320  end subroutine add_model
321 
322  !> @brief Get a pointer to a list of models in the solution
323  !<
324  function get_models(this) result(models)
325  type(listtype), pointer :: models !< pointer to the model list
326  class(explicitsolutiontype) :: this !< ExplicitSolutionType instance
327 
328  models => this%modellist
329  end function get_models
330 
331  !> @ brief Add exchange to list of exchanges
332  !<
333  subroutine add_exchange(this, exchange)
334  class(explicitsolutiontype) :: this
335  class(baseexchangetype), pointer, intent(in) :: exchange
336  end subroutine add_exchange
337 
338  !> @ brief Get list of exchanges
339  !<
340  function get_exchanges(this) result(exchanges)
341  class(explicitsolutiontype) :: this
342  type(listtype), pointer :: exchanges
343  end function get_exchanges
344 
345 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:45
@ mvalidate
validation mode - do not run time steps
Definition: Constants.f90:205
@ mnormal
normal output mode
Definition: Constants.f90:206
integer(i4b), parameter lensolutionname
maximum length of the solution name
Definition: Constants.f90:21
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:65
integer(i4b), parameter lenmempath
maximum length of the memory path
Definition: Constants.f90:27
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 save(this, filename)
@ brief Save output
subroutine finalizesolve(this, kiter, isgcnvg, isuppress_output)
@ brief Finalize solve
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:159
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:14