MODFLOW 6  version 6.7.0.dev2
USGS Modular Hydrologic Model
SimulationCreate.f90
Go to the documentation of this file.
2 
3  use kindmodule, only: dp, i4b, lgp, write_kindinfo
23  use listmodule, only: listtype
24 
25  implicit none
26  private
27  public :: simulation_cr
28  public :: simulation_da
29 
30 contains
31 
32  !> @brief Read the simulation name file and initialize the models, exchanges
33  !<
34  subroutine simulation_cr()
35  ! -- modules
36  ! -- local
37  !
38  ! -- Source simulation nam input context and create objects
40  end subroutine simulation_cr
41 
42  !> @brief Deallocate simulation variables
43  !<
44  subroutine simulation_da()
45  ! -- modules
48  ! -- local
49  type(distributedsimtype), pointer :: ds
50 
51  ! -- variables
52  ds => get_dsim()
53  call ds%destroy()
54  !
55  deallocate (model_names)
56  deallocate (model_loc_idx)
57  end subroutine simulation_da
58 
59  !> @brief Source the simulation name file
60  !!
61  !! Source from the simulation nam input context to initialize the models,
62  !! exchanges, solutions, solutions groups. Then add the exchanges to
63  !! the appropriate solutions.
64  !!
65  !<
66  subroutine source_simulation_nam()
67  ! -- dummy
68  ! -- local
69  !
70  ! -- Process OPTIONS block in namfile
71  call options_create()
72  !
73  ! -- Process TIMING block in namfile
74  call timing_create()
75  !
76  ! -- Process MODELS block in namfile
77  call models_create()
78  !
79  ! -- Process EXCHANGES block in namfile
80  call exchanges_create()
81  !
82  ! -- Process SOLUTION_GROUPS blocks in namfile
84  !
85  ! -- Go through each model and make sure that it has been assigned to
86  ! a solution.
88  !
89  ! -- Go through each solution and assign exchanges accordingly
90  call assign_exchanges()
91  end subroutine source_simulation_nam
92 
93  !> @brief Set the simulation options
94  !<
95  subroutine options_create()
96  ! -- modules
101  use profilermodule, only: g_prof
103  ! -- dummy
104  ! -- locals
105  character(len=LENMEMPATH) :: input_mempath
106  integer(I4B), pointer :: simcontinue, nocheck, maxerror
107  character(len=:), pointer :: prmem, prprof
108  character(len=LINELENGTH) :: errmsg
109  !
110  ! -- set input memory path
111  input_mempath = create_mem_path('SIM', 'NAM', idm_context)
112  !
113  ! -- set pointers to input context option params
114  call mem_setptr(simcontinue, 'CONTINUE', input_mempath)
115  call mem_setptr(nocheck, 'NOCHECK', input_mempath)
116  call mem_setptr(prmem, 'PRMEM', input_mempath)
117  call mem_setptr(prprof, 'PRPROF', input_mempath)
118  call mem_setptr(maxerror, 'MAXERRORS', input_mempath)
119  !
120  ! -- update sim options
121  isimcontinue = simcontinue
122  if (nocheck == 1) then
123  isimcheck = 0
124  else
125  isimcheck = 1
126  end if
127 
128  call maxerrors(maxerror)
129 
130  if (prmem /= '') then
131  errmsg = ''
132  call mem_set_print_option(iout, prmem, errmsg)
133  if (errmsg /= '') then
134  call store_error(errmsg, .true.)
135  end if
136  end if
137 
138  ! set profiler print option
139  call g_prof%set_print_option(prprof)
140 
141  !
142  ! -- log values to list file
143  if (iout > 0) then
144  write (iout, '(/1x,a)') 'READING SIMULATION OPTIONS'
145  !
146  if (isimcontinue == 1) then
147  write (iout, '(4x, a)') &
148  'SIMULATION WILL CONTINUE EVEN IF THERE IS NONCONVERGENCE.'
149  end if
150  !
151  if (isimcheck == 0) then
152  write (iout, '(4x, a)') &
153  'MODEL DATA WILL NOT BE CHECKED FOR ERRORS.'
154  end if
155  !
156  write (iout, '(4x, a, i0)') &
157  'MAXIMUM NUMBER OF ERRORS THAT WILL BE STORED IS ', maxerror
158  !
159  if (prmem /= '') then
160  write (iout, '(4x, a, a, a)') &
161  'MEMORY_PRINT_OPTION SET TO "', trim(prmem), '".'
162  end if
163  !
164  write (iout, '(1x,a)') 'END OF SIMULATION OPTIONS'
165  end if
166  end subroutine options_create
167 
168  !> @brief Set the timing module to be used for the simulation
169  !<
170  subroutine timing_create()
171  ! -- modules
175  use tdismodule, only: tdis_cr
176  ! -- dummy
177  ! -- locals
178  character(len=LENMEMPATH) :: input_mempath
179  character(len=LENMEMPATH) :: tdis_input_mempath
180  character(len=:), pointer :: tdis6
181  logical :: terminate = .true.
182  !
183  ! -- set input memory path
184  input_mempath = create_mem_path('SIM', 'NAM', idm_context)
185  tdis_input_mempath = create_mem_path('SIM', 'TDIS', idm_context)
186  !
187  write (iout, '(/1x,a)') 'READING SIMULATION TIMING'
188  !
189  ! -- set pointers to input context timing params
190  call mem_setptr(tdis6, 'TDIS6', input_mempath)
191  !
192  ! -- create timing
193  if (tdis6 /= '') then
194  call tdis_cr(tdis6, tdis_input_mempath)
195  else
196  call store_error('TIMING block variable TDIS6 is unset'// &
197  ' in simulation control input.', terminate)
198  end if
199  !
200  write (iout, '(1x,a)') 'END OF SIMULATION TIMING'
201  end subroutine timing_create
202 
203  !> @brief Set the models to be used for the simulation
204  !<
205  subroutine models_create()
206  ! -- modules
211  use chfmodule, only: chf_cr
212  use gwfmodule, only: gwf_cr
213  use gwtmodule, only: gwt_cr
214  use gwemodule, only: gwe_cr
215  use olfmodule, only: olf_cr
216  use prtmodule, only: prt_cr
221  ! use VirtualPrtModelModule, only: add_virtual_prt_model
222  use constantsmodule, only: lenmodelname
223  ! -- dummy
224  ! -- locals
225  type(distributedsimtype), pointer :: ds
226  character(len=LENMEMPATH) :: input_mempath
227  type(characterstringtype), dimension(:), contiguous, &
228  pointer :: mtypes !< model types
229  type(characterstringtype), dimension(:), contiguous, &
230  pointer :: mfnames !< model file names
231  type(characterstringtype), dimension(:), contiguous, &
232  pointer :: mnames !< model names
233  integer(I4B) :: im
234  class(numericalmodeltype), pointer :: num_model
235  character(len=LINELENGTH) :: model_type
236  character(len=LINELENGTH) :: fname, model_name
237  integer(I4B) :: n, nr_models_glob
238  integer(I4B), dimension(:), pointer :: model_ranks => null()
239  logical :: terminate = .true.
240  !
241  ! -- set input memory path
242  input_mempath = create_mem_path('SIM', 'NAM', idm_context)
243  !
244  ! -- set pointers to input context model attribute arrays
245  call mem_setptr(mtypes, 'MTYPE', input_mempath)
246  call mem_setptr(mfnames, 'MFNAME', input_mempath)
247  call mem_setptr(mnames, 'MNAME', input_mempath)
248  !
249  ! -- allocate global arrays
250  nr_models_glob = size(mnames)
251  allocate (model_names(nr_models_glob))
252  allocate (model_loc_idx(nr_models_glob))
253  !
254  ! -- get model-to-cpu assignment (in serial all to rank 0)
255  ds => get_dsim()
256  model_ranks => ds%get_load_balance()
257  !
258  ! -- open model logging block
259  write (iout, '(/1x,a)') 'READING SIMULATION MODELS'
260  !
261  ! -- create models
262  im = 0
263  do n = 1, size(mtypes)
264  !
265  ! -- attributes for this model
266  model_type = mtypes(n)
267  fname = mfnames(n)
268  model_name = mnames(n)
269  !
270  call check_model_name(model_type, model_name)
271  !
272  ! increment global model id
273  model_names(n) = model_name(1:lenmodelname)
274  model_loc_idx(n) = -1
275  num_model => null()
276  !
277  ! -- add a new (local or global) model
278  select case (model_type)
279  case ('GWF6')
280  if (model_ranks(n) == proc_id) then
281  im = im + 1
282  write (iout, '(4x,2a,i0,a)') trim(model_type), ' model ', &
283  n, ' will be created'
284  call gwf_cr(fname, n, model_names(n))
285  num_model => getnumericalmodelfromlist(basemodellist, im)
286  model_loc_idx(n) = im
287  end if
288  call add_virtual_gwf_model(n, model_names(n), num_model)
289  case ('GWT6')
290  if (model_ranks(n) == proc_id) then
291  im = im + 1
292  write (iout, '(4x,2a,i0,a)') trim(model_type), ' model ', &
293  n, ' will be created'
294  call gwt_cr(fname, n, model_names(n))
295  num_model => getnumericalmodelfromlist(basemodellist, im)
296  model_loc_idx(n) = im
297  end if
298  call add_virtual_gwt_model(n, model_names(n), num_model)
299  case ('GWE6')
300  if (model_ranks(n) == proc_id) then
301  im = im + 1
302  write (iout, '(4x,2a,i0,a)') trim(model_type), ' model ', &
303  n, ' will be created'
304  call gwe_cr(fname, n, model_names(n))
305  num_model => getnumericalmodelfromlist(basemodellist, im)
306  model_loc_idx(n) = im
307  end if
308  call add_virtual_gwe_model(n, model_names(n), num_model)
309  case ('CHF6')
310  if (model_ranks(n) == proc_id) then
311  im = im + 1
312  write (iout, '(4x,2a,i0,a)') trim(model_type), " model ", &
313  n, " will be created"
314  call chf_cr(fname, n, model_names(n))
315  call dev_feature('CHF is still under development, install the &
316  &nightly build or compile from source with IDEVELOPMODE = 1.')
317  num_model => getnumericalmodelfromlist(basemodellist, im)
318  model_loc_idx(n) = im
319  end if
320  case ('OLF6')
321  if (model_ranks(n) == proc_id) then
322  im = im + 1
323  write (iout, '(4x,2a,i0,a)') trim(model_type), " model ", &
324  n, " will be created"
325  call olf_cr(fname, n, model_names(n))
326  call dev_feature('OLF is still under development, install the &
327  &nightly build or compile from source with IDEVELOPMODE = 1.')
328  num_model => getnumericalmodelfromlist(basemodellist, im)
329  model_loc_idx(n) = im
330  end if
331  case ('PRT6')
332  im = im + 1
333  write (iout, '(4x,2a,i0,a)') trim(model_type), ' model ', &
334  n, ' will be created'
335  call prt_cr(fname, n, model_names(n))
336  num_model => getnumericalmodelfromlist(basemodellist, im)
337  model_loc_idx(n) = im
338  case default
339  write (errmsg, '(a,a)') &
340  'Unknown simulation model type: ', trim(model_type)
341  call store_error(errmsg, terminate)
342  end select
343  end do
344  !
345  ! -- close model logging block
346  write (iout, '(1x,a)') 'END OF SIMULATION MODELS'
347  !
348  ! -- sanity check
349  if (simulation_mode == 'PARALLEL' .and. im == 0) then
350  write (errmsg, '(a, i0)') &
351  'No MODELS assigned to process ', proc_id
352  call store_error(errmsg, terminate)
353  end if
354  end subroutine models_create
355 
356  !> @brief Set the exchanges to be used for the simulation
357  !<
358  subroutine exchanges_create()
359  ! -- modules
374  ! use VirtualPrtExchangeModule, only: add_virtual_prt_exchange
375  ! -- dummy
376  ! -- locals
377  character(len=LENMEMPATH) :: input_mempath
378  type(characterstringtype), dimension(:), contiguous, &
379  pointer :: etypes !< exg types
380  type(characterstringtype), dimension(:), contiguous, &
381  pointer :: efiles !< exg file names
382  type(characterstringtype), dimension(:), contiguous, &
383  pointer :: emnames_a !< model a names
384  type(characterstringtype), dimension(:), contiguous, &
385  pointer :: emnames_b !< model b names
386  type(characterstringtype), dimension(:), contiguous, &
387  pointer :: emempaths
388  character(len=LINELENGTH) :: exgtype
389  integer(I4B) :: exg_id
390  integer(I4B) :: m1_id, m2_id
391  character(len=LINELENGTH) :: fname, name1, name2
392  character(len=LENEXCHANGENAME) :: exg_name
393  character(len=LENMEMPATH) :: exg_mempath
394  integer(I4B) :: n
395  character(len=LINELENGTH) :: errmsg
396  logical(LGP) :: terminate = .true.
397  logical(LGP) :: both_remote, both_local
398  ! -- formats
399  character(len=*), parameter :: fmtmerr = "('Error in simulation control ', &
400  &'file. Could not find model: ', a)"
401  !
402  ! -- set input memory path
403  input_mempath = create_mem_path('SIM', 'NAM', idm_context)
404  !
405  ! -- set pointers to input context exchange attribute arrays
406  call mem_setptr(etypes, 'EXGTYPE', input_mempath)
407  call mem_setptr(efiles, 'EXGFILE', input_mempath)
408  call mem_setptr(emnames_a, 'EXGMNAMEA', input_mempath)
409  call mem_setptr(emnames_b, 'EXGMNAMEB', input_mempath)
410  call mem_setptr(emempaths, 'EXGMEMPATHS', input_mempath)
411  !
412  ! -- open exchange logging block
413  write (iout, '(/1x,a)') 'READING SIMULATION EXCHANGES'
414  !
415  ! -- initialize
416  exg_id = 0
417  !
418  ! -- create exchanges
419  do n = 1, size(etypes)
420  !
421  ! -- attributes for this exchange
422  exgtype = etypes(n)
423  fname = efiles(n)
424  name1 = emnames_a(n)
425  name2 = emnames_b(n)
426  exg_mempath = emempaths(n)
427 
428  exg_id = exg_id + 1
429 
430  ! find model index in list
431  m1_id = ifind(model_names, name1)
432  if (m1_id < 0) then
433  write (errmsg, fmtmerr) trim(name1)
434  call store_error(errmsg, terminate)
435  end if
436  m2_id = ifind(model_names, name2)
437  if (m2_id < 0) then
438  write (errmsg, fmtmerr) trim(name2)
439  call store_error(errmsg, terminate)
440  end if
441 
442  ! both models on other process? then don't create it here...
443  both_remote = (model_loc_idx(m1_id) == -1 .and. &
444  model_loc_idx(m2_id) == -1)
445  both_local = (model_loc_idx(m1_id) > 0 .and. &
446  model_loc_idx(m2_id) > 0)
447  if (.not. both_remote) then
448  write (iout, '(4x,a,a,i0,a,i0,a,i0)') trim(exgtype), ' exchange ', &
449  exg_id, ' will be created to connect model ', m1_id, &
450  ' with model ', m2_id
451  end if
452 
453  select case (exgtype)
454  case ('CHF6-GWF6')
455  write (exg_name, '(a,i0)') 'CHF-GWF_', exg_id
456  if (both_local) then
457  call chfgwf_cr(fname, exg_name, exg_id, m1_id, m2_id, exg_mempath)
458  end if
459  case ('GWF6-GWF6')
460  write (exg_name, '(a,i0)') 'GWF-GWF_', exg_id
461  if (.not. both_remote) then
462  call gwfexchange_create(fname, exg_name, exg_id, m1_id, m2_id, &
463  exg_mempath)
464  end if
465  call add_virtual_gwf_exchange(exg_name, exg_id, m1_id, m2_id)
466  case ('GWF6-GWT6')
467  if (both_local) then
468  call gwfgwt_cr(fname, exg_id, m1_id, m2_id)
469  end if
470  case ('GWF6-GWE6')
471  if (both_local) then
472  call gwfgwe_cr(fname, exg_id, m1_id, m2_id)
473  end if
474  case ('GWF6-PRT6')
475  call gwfprt_cr(fname, exg_id, m1_id, m2_id)
476  case ('GWT6-GWT6')
477  write (exg_name, '(a,i0)') 'GWT-GWT_', exg_id
478  if (.not. both_remote) then
479  call gwtexchange_create(fname, exg_name, exg_id, m1_id, m2_id, &
480  exg_mempath)
481  end if
482  call add_virtual_gwt_exchange(exg_name, exg_id, m1_id, m2_id)
483  case ('GWE6-GWE6')
484  write (exg_name, '(a,i0)') 'GWE-GWE_', exg_id
485  if (.not. both_remote) then
486  call gweexchange_create(fname, exg_name, exg_id, m1_id, m2_id, &
487  exg_mempath)
488  end if
489  call add_virtual_gwe_exchange(exg_name, exg_id, m1_id, m2_id)
490  case ('OLF6-GWF6')
491  write (exg_name, '(a,i0)') 'OLF-GWF_', exg_id
492  if (both_local) then
493  call olfgwf_cr(fname, exg_name, exg_id, m1_id, m2_id, exg_mempath)
494  end if
495  case default
496  write (errmsg, '(a,a)') &
497  'Unknown simulation exchange type: ', trim(exgtype)
498  call store_error(errmsg, terminate)
499  end select
500  end do
501  !
502  ! -- close exchange logging block
503  write (iout, '(1x,a)') 'END OF SIMULATION EXCHANGES'
504  end subroutine exchanges_create
505 
506  !> @brief Check a solution_group to be used for the simulation
507  !<
508  subroutine solution_group_check(sgp, sgid, isgpsoln)
509  ! -- modules
510  ! -- dummy
511  type(solutiongrouptype), pointer, intent(inout) :: sgp
512  integer(I4B), intent(in) :: sgid
513  integer(I4B), intent(in) :: isgpsoln
514  ! -- local
515  character(len=LINELENGTH) :: errmsg
516  logical :: terminate = .true.
517  ! -- formats
518  character(len=*), parameter :: fmterrmxiter = &
519  "('MXITER is set to ', i0, ' but there is only one solution', &
520  &' in SOLUTION GROUP ', i0, '. Set MXITER to 1 in simulation control', &
521  &' file.')"
522  !
523  ! -- error check completed group
524  if (sgid > 0) then
525  !
526  ! -- Make sure there is a solution in this solution group
527  if (isgpsoln == 0) then
528  write (errmsg, '(a,i0)') &
529  'There are no solutions for solution group ', sgid
530  call store_error(errmsg, terminate)
531  end if
532  !
533  ! -- If there is only one solution then mxiter should be 1.
534  if (isgpsoln == 1 .and. sgp%mxiter > 1) then
535  write (errmsg, fmterrmxiter) sgp%mxiter, isgpsoln
536  call store_error(errmsg, terminate)
537  end if
538  end if
539  end subroutine solution_group_check
540 
541  !> @brief Set the solution_groups to be used for the simulation
542  !<
544  ! -- modules
552  use basemodelmodule, only: basemodeltype
555  ! -- dummy
556  ! -- local
557  character(len=LENMEMPATH) :: input_mempath
558  type(characterstringtype), dimension(:), contiguous, &
559  pointer :: slntype
560  type(characterstringtype), dimension(:), contiguous, &
561  pointer :: slnfname
562  type(characterstringtype), dimension(:), contiguous, &
563  pointer :: slnmnames
564  integer(I4B), dimension(:), contiguous, pointer :: blocknum
565  character(len=LINELENGTH) :: stype, fname
566  character(len=:), allocatable :: mnames
567  type(solutiongrouptype), pointer :: sgp
568  class(basesolutiontype), pointer :: sp
569  class(basemodeltype), pointer :: mp
570  integer(I4B) :: isoln
571  integer(I4B) :: isgpsoln
572  integer(I4B) :: sgid
573  integer(I4B) :: glo_mid
574  integer(I4B) :: loc_idx
575  integer(I4B) :: i, j, istat, mxiter
576  integer(I4B) :: nwords
577  character(len=LENMODELNAME), dimension(:), allocatable :: words
578  character(len=:), allocatable :: parse_str
579  character(len=LINELENGTH) :: errmsg
580  logical :: terminate = .true.
581  !
582  ! -- set memory path
583  input_mempath = create_mem_path('SIM', 'NAM', idm_context)
584  !
585  ! -- set pointers to input context solution attribute arrays
586  call mem_setptr(slntype, 'SLNTYPE', input_mempath)
587  call mem_setptr(slnfname, 'SLNFNAME', input_mempath)
588  call mem_setptr(slnmnames, 'SLNMNAMES', input_mempath)
589  call mem_setptr(blocknum, 'SOLUTIONGROUPNUM', input_mempath)
590  !
591  ! -- open solution group logging block
592  write (iout, '(/1x,a)') 'READING SOLUTIONGROUP'
593  !
594  ! -- initialize
595  sgid = 0 ! integer id of soln group, tracks with blocknum
596  isoln = 0 ! cumulative solution number
597  !
598  ! -- create solution groups
599  do i = 1, size(blocknum)
600  !
601  ! -- allocate slnmnames string
602  allocate (character(slnmnames(i)%strlen()) :: mnames)
603  !
604  ! -- attributes for this solution
605  stype = slntype(i)
606  fname = slnfname(i)
607  mnames = slnmnames(i)
608 
609  if (blocknum(i) /= sgid) then
610  !
611  ! -- check for new soln group
612  if (blocknum(i) == sgid + 1) then
613  !
614  ! -- error check completed group
615  call solution_group_check(sgp, sgid, isgpsoln)
616  !
617  ! -- reinitialize
618  nullify (sgp)
619  isgpsoln = 0 ! solution counter for this solution group
620  !
621  ! -- set sgid
622  sgid = blocknum(i)
623  !
624  ! -- create new soln group and add to global list
625  call solutiongroup_create(sgp, sgid)
626  call addsolutiongrouptolist(solutiongrouplist, sgp)
627  else
628  write (errmsg, '(a,i0,a,i0,a)') &
629  'Solution group blocks are not listed consecutively. Found ', &
630  blocknum(i), ' when looking for ', sgid + 1, '.'
631  call store_error(errmsg, terminate)
632  end if
633  end if
634  !
635  ! --
636  select case (stype)
637  !
638  case ('MXITER')
639  read (fname, *, iostat=istat) mxiter
640  if (istat == 0) then
641  sgp%mxiter = mxiter
642  end if
643  case ('IMS6')
644  !
645  ! -- increment solution counters
646  isoln = isoln + 1
647  isgpsoln = isgpsoln + 1
648  !
649  ! -- create soln and add to group
650  sp => create_ims_solution(simulation_mode, fname, isoln)
651  call sgp%add_solution(isoln, sp)
652  !
653  ! -- parse model names
654  parse_str = trim(mnames)//' '
655  call parseline(parse_str, nwords, words)
656  !
657  ! -- Find each model id and get model
658  do j = 1, nwords
659  call upcase(words(j))
660  glo_mid = ifind(model_names, words(j))
661  if (glo_mid == -1) then
662  write (errmsg, '(a,a)') 'Invalid model name: ', trim(words(j))
663  call store_error(errmsg, terminate)
664  end if
665  !
666  loc_idx = model_loc_idx(glo_mid)
667  if (loc_idx == -1) then
668  if (simulation_mode == 'PARALLEL') then
669  ! this is still ok
670  cycle
671  end if
672  end if
673  !
674  mp => getbasemodelfromlist(basemodellist, loc_idx)
675  !
676  ! -- Add the model to the solution
677  call sp%add_model(mp)
678  mp%idsoln = isoln
679  end do
680  case ('EMS6')
681  !
682  ! -- increment solution counters
683  isoln = isoln + 1
684  isgpsoln = isgpsoln + 1
685  !
686  ! -- create soln and add to group
687  sp => create_ems_solution(simulation_mode, fname, isoln)
688  call sgp%add_solution(isoln, sp)
689  !
690  ! -- parse model names
691  parse_str = trim(mnames)//' '
692  call parseline(parse_str, nwords, words)
693  !
694  ! -- Find each model id and get model
695  do j = 1, nwords
696  call upcase(words(j))
697  glo_mid = ifind(model_names, words(j))
698  if (glo_mid == -1) then
699  write (errmsg, '(a,a)') 'Invalid model name: ', trim(words(j))
700  call store_error(errmsg, terminate)
701  end if
702  !
703  loc_idx = model_loc_idx(glo_mid)
704  if (loc_idx == -1) then
705  if (simulation_mode == 'PARALLEL') then
706  ! this is still ok
707  cycle
708  end if
709  end if
710  !
711  mp => getbasemodelfromlist(basemodellist, loc_idx)
712  !
713  ! -- Add the model to the solution
714  call sp%add_model(mp)
715  mp%idsoln = isoln
716  end do
717  case default
718  end select
719  !
720  ! -- clean up
721  deallocate (mnames)
722  end do
723  !
724  ! -- error check final group
725  call solution_group_check(sgp, sgid, isgpsoln)
726  !
727  ! -- close exchange logging block
728  write (iout, '(1x,a)') 'END OF SOLUTIONGROUP'
729  !
730  ! -- Check and make sure at least one solution group was found
731  if (solutiongrouplist%Count() == 0) then
732  call store_error('There are no solution groups.', terminate)
733  end if
734  end subroutine solution_groups_create
735 
736  !> @brief Check for dangling models, and break with
737  !! error when found
738  !<
740  character(len=LINELENGTH) :: errmsg
741  class(basemodeltype), pointer :: mp
742  integer(I4B) :: im
743 
744  do im = 1, basemodellist%Count()
746  if (mp%idsoln == 0) then
747  write (errmsg, '(a,a)') &
748  'Model was not assigned to a solution: ', mp%name
749  call store_error(errmsg)
750  end if
751  end do
752  if (count_errors() > 0) then
753  call store_error_filename('mfsim.nam')
754  end if
755 
756  end subroutine check_model_assignment
757 
758  !> @brief Assign exchanges to solutions
759  !!
760  !! This assigns NumericalExchanges to NumericalSolutions,
761  !! based on the link between the models in the solution and
762  !! those exchanges. The BaseExchange%connects_model() function
763  !! should be overridden to indicate if such a link exists.
764  !<
765  subroutine assign_exchanges()
766  ! -- local
767  class(basesolutiontype), pointer :: sp
768  class(baseexchangetype), pointer :: ep
769  class(basemodeltype), pointer :: mp
770  type(listtype), pointer :: models_in_solution
771  integer(I4B) :: is, ie, im
772 
773  do is = 1, basesolutionlist%Count()
775  !
776  ! -- now loop over exchanges
777  do ie = 1, baseexchangelist%Count()
779  !
780  ! -- and add when it affects (any model in) the solution matrix
781  models_in_solution => sp%get_models()
782  do im = 1, models_in_solution%Count()
783  mp => getbasemodelfromlist(models_in_solution, im)
784  if (ep%connects_model(mp)) then
785  !
786  ! -- add to solution (and only once)
787  call sp%add_exchange(ep)
788  exit
789  end if
790  end do
791  end do
792  end do
793  end subroutine assign_exchanges
794 
795  !> @brief Check that the model name is valid
796  !<
797  subroutine check_model_name(mtype, mname)
798  ! -- dummy
799  character(len=*), intent(in) :: mtype
800  character(len=*), intent(inout) :: mname
801  ! -- local
802  integer :: ilen
803  integer :: i
804  character(len=LINELENGTH) :: errmsg
805  logical :: terminate = .true.
806 
807  ilen = len_trim(mname)
808  if (ilen > lenmodelname) then
809  write (errmsg, '(a,a)') 'Invalid model name: ', trim(mname)
810  call store_error(errmsg)
811  write (errmsg, '(a,i0,a,i0)') &
812  'Name length of ', ilen, ' exceeds maximum length of ', &
814  call store_error(errmsg, terminate)
815  end if
816  do i = 1, ilen
817  if (mname(i:i) == ' ') then
818  write (errmsg, '(a,a)') 'Invalid model name: ', trim(mname)
819  call store_error(errmsg)
820  write (errmsg, '(a)') &
821  'Model name cannot have spaces within it.'
822  call store_error(errmsg, terminate)
823  end if
824  end do
825  end subroutine check_model_name
826 
827 end module simulationcreatemodule
class(baseexchangetype) function, pointer, public getbaseexchangefromlist(list, idx)
Retrieve a specific BaseExchangeType object from a list.
class(basemodeltype) function, pointer, public getbasemodelfromlist(list, idx)
Definition: BaseModel.f90:172
subroutine, public addbasesolutiontolist(list, solution)
class(basesolutiontype) function, pointer, public getbasesolutionfromlist(list, idx)
This module contains the ChfGwfExchangeModule Module.
Definition: exg-chfgwf.f90:6
subroutine, public chfgwf_cr(filename, name, id, m1_id, m2_id, input_mempath)
@ brief Create CHF GWF exchange
Definition: exg-chfgwf.f90:41
Channel Flow (CHF) Module.
Definition: chf.f90:3
subroutine, public chf_cr(filename, id, modelname)
Create a new surface water flow model object.
Definition: chf.f90:56
This module contains simulation constants.
Definition: Constants.f90:9
integer(i4b), parameter linelength
maximum length of a standard line
Definition: Constants.f90:45
integer(i4b), parameter lenmodelname
maximum length of the model name
Definition: Constants.f90:22
integer(i4b), parameter lenexchangename
maximum length of the exchange name
Definition: Constants.f90:24
integer(i4b), parameter lenpackagetype
maximum length of a package type (DIS6, SFR6, CSUB6, etc.)
Definition: Constants.f90:38
integer(i4b), parameter lenbigline
maximum length of a big line
Definition: Constants.f90:15
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
Disable development features in release mode.
Definition: DevFeature.f90:2
subroutine, public dev_feature(errmsg, iunit)
Terminate if in release mode (guard development features)
Definition: DevFeature.f90:21
class(distributedsimtype) function, pointer, public get_dsim()
Get pointer to the distributed simulation object.
This module contains the GweGweExchangeModule Module.
Definition: exg-gwegwe.f90:10
subroutine, public gweexchange_create(filename, name, id, m1_id, m2_id, input_mempath)
@ brief Create GWT GWT exchange
Definition: exg-gwegwe.f90:112
Definition: gwe.f90:3
subroutine, public gwe_cr(filename, id, modelname)
Create a new groundwater energy transport model object.
Definition: gwe.f90:98
subroutine, public gwfgwe_cr(filename, id, m1_id, m2_id)
Create a new GWF to GWE exchange object.
Definition: exg-gwfgwe.f90:47
This module contains the GwfGwfExchangeModule Module.
Definition: exg-gwfgwf.f90:10
subroutine, public gwfexchange_create(filename, name, id, m1_id, m2_id, input_mempath)
@ brief Create GWF GWF exchange
Definition: exg-gwfgwf.f90:122
subroutine, public gwfgwt_cr(filename, id, m1_id, m2_id)
Create a new GWF to GWT exchange object.
Definition: exg-gwfgwt.f90:49
Definition: gwf.f90:1
subroutine, public gwf_cr(filename, id, modelname)
Create a new groundwater flow model object.
Definition: gwf.f90:138
subroutine, public gwfprt_cr(filename, id, m1id, m2id)
Create a new GWF to PRT exchange object.
Definition: exg-gwfprt.f90:40
This module contains the GwtGwtExchangeModule Module.
Definition: exg-gwtgwt.f90:10
subroutine, public gwtexchange_create(filename, name, id, m1_id, m2_id, input_mempath)
@ brief Create GWT GWT exchange
Definition: exg-gwtgwt.f90:110
Definition: gwt.f90:8
subroutine, public gwt_cr(filename, id, modelname)
Create a new groundwater transport model object.
Definition: gwt.f90:101
integer(i4b) function, public getunit()
Get a free unit number.
subroutine, public parseline(line, nwords, words, inunit, filename)
Parse a line into words.
subroutine, public upcase(word)
Convert to upper case.
subroutine, public openfile(iu, iout, fname, ftype, fmtarg_opt, accarg_opt, filstat_opt, mode_opt)
Open a file.
Definition: InputOutput.f90:30
subroutine, public urword(line, icol, istart, istop, ncode, n, r, iout, in)
Extract a word from a string.
This module defines variable data types.
Definition: kind.f90:8
subroutine, public write_kindinfo(iout)
Write variable data types.
Definition: kind.f90:27
type(listtype), public basemodellist
Definition: mf6lists.f90:16
type(listtype), public baseexchangelist
Definition: mf6lists.f90:25
type(listtype), public solutiongrouplist
Definition: mf6lists.f90:22
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 mem_set_print_option(iout, keyword, error_msg)
Set the memory print option.
class(numericalmodeltype) function, pointer, public getnumericalmodelfromlist(list, idx)
This module contains the OlfGwfExchangeModule Module.
Definition: exg-olfgwf.f90:6
subroutine, public olfgwf_cr(filename, name, id, m1_id, m2_id, input_mempath)
@ brief Create OLF GWF exchange
Definition: exg-olfgwf.f90:41
Channel Flow (OLF) Module.
Definition: olf.f90:3
subroutine, public olf_cr(filename, id, modelname)
Create a new overland flow model object.
Definition: olf.f90:56
type(profilertype), public g_prof
the global timer object (to reduce trivial lines of code)
Definition: Profiler.f90:65
Definition: prt.f90:1
subroutine, public prt_cr(filename, id, modelname)
Create a new particle tracking model object.
Definition: prt.f90:123
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public store_warning(msg, substring)
Store warning message.
Definition: Sim.f90:236
subroutine, public store_error(msg, terminate)
Store an error message.
Definition: Sim.f90:92
subroutine, public maxerrors(imax)
Set the maximum number of errors to be stored.
Definition: Sim.f90:85
integer(i4b) function, public count_errors()
Return number of errors.
Definition: Sim.f90:59
subroutine, public store_error_filename(filename, terminate)
Store the erroring file name.
Definition: Sim.f90:203
subroutine models_create()
Set the models to be used for the simulation.
subroutine check_model_assignment()
Check for dangling models, and break with error when found.
subroutine, public simulation_da()
Deallocate simulation variables.
subroutine options_create()
Set the simulation options.
subroutine check_model_name(mtype, mname)
Check that the model name is valid.
subroutine source_simulation_nam()
Source the simulation name file.
subroutine solution_groups_create()
Set the solution_groups to be used for the simulation.
subroutine timing_create()
Set the timing module to be used for the simulation.
subroutine exchanges_create()
Set the exchanges to be used for the simulation.
subroutine assign_exchanges()
Assign exchanges to solutions.
subroutine solution_group_check(sgp, sgid, isgpsoln)
Check a solution_group to be used for the simulation.
subroutine, public simulation_cr()
Read the simulation name file and initialize the models, exchanges.
This module contains simulation variables.
Definition: SimVariables.f90:9
character(len=maxcharlen) errmsg
error message string
character(len=linelength) idm_context
integer(i4b) isimcheck
simulation input check flag (1) to check input, (0) to ignore checks
integer(i4b) isimcontinue
simulation continue flag (1) to continue if isimcnvg = 0, (0) to terminate
character(len=linelength) simulation_mode
integer(i4b) nr_procs
integer(i4b), dimension(:), allocatable model_loc_idx
equals the local index into the basemodel list (-1 when not available)
integer(i4b) iout
file unit number for simulation output
character(len=lenmodelname), dimension(:), allocatable model_names
all model names in the (global) simulation
integer(i4b) proc_id
class(basesolutiontype) function, pointer, public create_ims_solution(sim_mode, filename, sol_id)
Create an IMS solution of type NumericalSolution for serial runs or its sub-type ParallelSolution for...
class(basesolutiontype) function, pointer, public create_ems_solution(sim_mode, filename, sol_id)
Create an EMS solution of type ExplicitSolution for serial runs or its sub-type ParallelSolution for.
subroutine, public solutiongroup_create(sgp, id)
Create a new solution group.
subroutine, public addsolutiongrouptolist(list, solutiongroup)
subroutine, public tdis_cr(fname, inmempath)
Create temporal discretization.
Definition: tdis.f90:50
This module contains version information.
Definition: version.f90:7
subroutine write_listfile_header(iout, cmodel_type, write_sys_command, write_kind_info)
@ brief Write program header
Definition: version.f90:98
subroutine, public add_virtual_gwe_exchange(name, exchange_id, model1_id, model2_id)
Add a virtual GWE-GWE exchange to the simulation.
subroutine, public add_virtual_gwe_model(model_id, model_name, model)
subroutine, public add_virtual_gwf_exchange(name, exchange_id, model1_id, model2_id)
Add a virtual GWF-GWF exchange to the simulation.
subroutine, public add_virtual_gwf_model(model_id, model_name, model)
Add virtual GWF model.
subroutine, public add_virtual_gwt_exchange(name, exchange_id, model1_id, model2_id)
Add a virtual GWT-GWT exchange to the simulation.
subroutine, public add_virtual_gwt_model(model_id, model_name, model)
Highest level model type. All models extend this parent type.
Definition: BaseModel.f90:13
This class is used to store a single deferred-length character string. It was designed to work in an ...
Definition: CharString.f90:23
A generic heterogeneous doubly-linked list.
Definition: List.f90:14