MODFLOW 6  version 6.5.0.dev2
MODFLOW 6 Code Documentation
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  !
39  ! -- Source simulation nam input context and create objects
41  !
42  ! -- Return
43  return
44  end subroutine simulation_cr
45 
46  !> @brief Deallocate simulation variables
47  !<
48  subroutine simulation_da()
49  ! -- modules
52  ! -- local
53  type(distributedsimtype), pointer :: ds
54 ! ------------------------------------------------------------------------------
55  !
56  ! -- variables
57  !
58  ds => get_dsim()
59  call ds%destroy()
60  !
61  deallocate (model_names)
62  deallocate (model_loc_idx)
63  !
64  ! -- Return
65  return
66  end subroutine simulation_da
67 
68  !> @brief Source the simulation name file
69  !!
70  !! Source from the simulation nam input context to initialize the models,
71  !! exchanges, solutions, solutions groups. Then add the exchanges to
72  !! the appropriate solutions.
73  !!
74  !<
75  subroutine source_simulation_nam()
76  ! -- dummy
77  ! -- local
78 ! ------------------------------------------------------------------------------
79  !
80  ! -- Process OPTIONS block in namfile
81  call options_create()
82  !
83  ! -- Process TIMING block in namfile
84  call timing_create()
85  !
86  ! -- Process MODELS block in namfile
87  call models_create()
88  !
89  ! -- Process EXCHANGES block in namfile
90  call exchanges_create()
91  !
92  ! -- Process SOLUTION_GROUPS blocks in namfile
94  !
95  ! -- Go through each model and make sure that it has been assigned to
96  ! a solution.
98  !
99  ! -- Go through each solution and assign exchanges accordingly
100  call assign_exchanges()
101  !
102  ! -- Return
103  return
104  end subroutine source_simulation_nam
105 
106  !> @brief Set the simulation options
107  !<
108  subroutine options_create()
109  ! -- modules
115  ! -- dummy
116  ! -- locals
117  character(len=LENMEMPATH) :: input_mempath
118  integer(I4B), pointer :: simcontinue, nocheck, maxerror
119  character(len=:), pointer :: prmem
120  character(len=LINELENGTH) :: errmsg
121  !
122  ! -- set input memory path
123  input_mempath = create_mem_path('SIM', 'NAM', idm_context)
124  !
125  ! -- set pointers to input context option params
126  call mem_setptr(simcontinue, 'CONTINUE', input_mempath)
127  call mem_setptr(nocheck, 'NOCHECK', input_mempath)
128  call mem_setptr(prmem, 'PRMEM', input_mempath)
129  call mem_setptr(maxerror, 'MAXERRORS', input_mempath)
130  !
131  ! -- update sim options
132  isimcontinue = simcontinue
133  isimcheck = nocheck
134  call maxerrors(maxerror)
135  !
136  if (prmem /= '') then
137  errmsg = ''
138  call mem_set_print_option(iout, prmem, errmsg)
139  if (errmsg /= '') then
140  call store_error(errmsg, .true.)
141  end if
142  end if
143  !
144  ! -- log values to list file
145  if (iout > 0) then
146  write (iout, '(/1x,a)') 'READING SIMULATION OPTIONS'
147  !
148  if (isimcontinue == 1) then
149  write (iout, '(4x, a)') &
150  'SIMULATION WILL CONTINUE EVEN IF THERE IS NONCONVERGENCE.'
151  end if
152  !
153  if (isimcheck == 0) then
154  write (iout, '(4x, a)') &
155  'MODEL DATA WILL NOT BE CHECKED FOR ERRORS.'
156  end if
157  !
158  write (iout, '(4x, a, i0)') &
159  'MAXIMUM NUMBER OF ERRORS THAT WILL BE STORED IS ', maxerror
160  !
161  if (prmem /= '') then
162  write (iout, '(4x, a, a, a)') &
163  'MEMORY_PRINT_OPTION SET TO "', trim(prmem), '".'
164  end if
165  !
166  write (iout, '(1x,a)') 'END OF SIMULATION OPTIONS'
167  end if
168  !
169  ! -- return
170  return
171  end subroutine options_create
172 
173  !> @brief Set the timing module to be used for the simulation
174  !<
175  subroutine timing_create()
176  ! -- modules
180  use tdismodule, only: tdis_cr
181  ! -- dummy
182  ! -- locals
183  character(len=LENMEMPATH) :: input_mempath
184  character(len=LENMEMPATH) :: tdis_input_mempath
185  character(len=:), pointer :: tdis6
186  logical :: terminate = .true.
187  !
188  ! -- set input memory path
189  input_mempath = create_mem_path('SIM', 'NAM', idm_context)
190  tdis_input_mempath = create_mem_path('SIM', 'TDIS', idm_context)
191  !
192  write (iout, '(/1x,a)') 'READING SIMULATION TIMING'
193  !
194  ! -- set pointers to input context timing params
195  call mem_setptr(tdis6, 'TDIS6', input_mempath)
196  !
197  ! -- create timing
198  if (tdis6 /= '') then
199  call tdis_cr(tdis6, tdis_input_mempath)
200  else
201  call store_error('TIMING block variable TDIS6 is unset'// &
202  ' in simulation control input.', terminate)
203  end if
204  !
205  write (iout, '(1x,a)') 'END OF SIMULATION TIMING'
206  !
207  ! -- return
208  return
209  end subroutine timing_create
210 
211  !> @brief Set the models to be used for the simulation
212  !<
213  subroutine models_create()
214  ! -- modules
219  use gwfmodule, only: gwf_cr
220  use gwtmodule, only: gwt_cr
221  use gwemodule, only: gwe_cr
222  use swfmodule, only: swf_cr
223  use prtmodule, only: prt_cr
228  ! use VirtualPrtModelModule, only: add_virtual_prt_model
229  use constantsmodule, only: lenmodelname
230  ! -- dummy
231  ! -- locals
232  type(distributedsimtype), pointer :: ds
233  character(len=LENMEMPATH) :: input_mempath
234  type(characterstringtype), dimension(:), contiguous, &
235  pointer :: mtypes !< model types
236  type(characterstringtype), dimension(:), contiguous, &
237  pointer :: mfnames !< model file names
238  type(characterstringtype), dimension(:), contiguous, &
239  pointer :: mnames !< model names
240  integer(I4B) :: im
241  class(numericalmodeltype), pointer :: num_model
242  character(len=LINELENGTH) :: model_type
243  character(len=LINELENGTH) :: fname, model_name
244  integer(I4B) :: n, nr_models_glob
245  integer(I4B), dimension(:), pointer :: model_ranks => null()
246  logical :: terminate = .true.
247  !
248  ! -- set input memory path
249  input_mempath = create_mem_path('SIM', 'NAM', idm_context)
250  !
251  ! -- set pointers to input context model attribute arrays
252  call mem_setptr(mtypes, 'MTYPE', input_mempath)
253  call mem_setptr(mfnames, 'MFNAME', input_mempath)
254  call mem_setptr(mnames, 'MNAME', input_mempath)
255  !
256  ! -- allocate global arrays
257  nr_models_glob = size(mnames)
258  allocate (model_names(nr_models_glob))
259  allocate (model_loc_idx(nr_models_glob))
260  !
261  ! -- get model-to-cpu assignment (in serial all to rank 0)
262  ds => get_dsim()
263  model_ranks => ds%get_load_balance()
264  !
265  ! -- open model logging block
266  write (iout, '(/1x,a)') 'READING SIMULATION MODELS'
267  !
268  ! -- create models
269  im = 0
270  do n = 1, size(mtypes)
271  !
272  ! -- attributes for this model
273  model_type = mtypes(n)
274  fname = mfnames(n)
275  model_name = mnames(n)
276  !
277  call check_model_name(model_type, model_name)
278  !
279  ! increment global model id
280  model_names(n) = model_name(1:lenmodelname)
281  model_loc_idx(n) = -1
282  num_model => null()
283  !
284  ! -- add a new (local or global) model
285  select case (model_type)
286  case ('GWF6')
287  if (model_ranks(n) == proc_id) then
288  im = im + 1
289  write (iout, '(4x,2a,i0,a)') trim(model_type), ' model ', &
290  n, ' will be created'
291  call gwf_cr(fname, n, model_names(n))
292  num_model => getnumericalmodelfromlist(basemodellist, im)
293  model_loc_idx(n) = im
294  end if
295  call add_virtual_gwf_model(n, model_names(n), num_model)
296  case ('GWT6')
297  if (model_ranks(n) == proc_id) then
298  im = im + 1
299  write (iout, '(4x,2a,i0,a)') trim(model_type), ' model ', &
300  n, ' will be created'
301  call gwt_cr(fname, n, model_names(n))
302  num_model => getnumericalmodelfromlist(basemodellist, im)
303  model_loc_idx(n) = im
304  end if
305  call add_virtual_gwt_model(n, model_names(n), num_model)
306  case ('GWE6')
307  if (model_ranks(n) == proc_id) then
308  im = im + 1
309  write (iout, '(4x,2a,i0,a)') trim(model_type), ' model ', &
310  n, ' will be created'
311  call gwe_cr(fname, n, model_names(n))
312  num_model => getnumericalmodelfromlist(basemodellist, im)
313  model_loc_idx(n) = im
314  end if
315  call add_virtual_gwe_model(n, model_names(n), num_model)
316  case ('SWF6')
317  if (model_ranks(n) == proc_id) then
318  im = im + 1
319  write (iout, '(4x,2a,i0,a)') trim(model_type), " model ", &
320  n, " will be created"
321  call swf_cr(fname, n, model_names(n))
322  call dev_feature('SWF is still under development, install the &
323  &nightly build or compile from source with IDEVELOPMODE = 1.')
324  num_model => getnumericalmodelfromlist(basemodellist, im)
325  model_loc_idx(n) = im
326  end if
327  case ('PRT6')
328  im = im + 1
329  write (iout, '(4x,2a,i0,a)') trim(model_type), ' model ', &
330  n, ' will be created'
331  call prt_cr(fname, n, model_names(n))
332  call dev_feature('PRT is still under development, install the &
333  &nightly build or compile from source with IDEVELOPMODE = 1.')
334  num_model => getnumericalmodelfromlist(basemodellist, im)
335  model_loc_idx(n) = im
336  case default
337  write (errmsg, '(a,a)') &
338  'Unknown simulation model type: ', trim(model_type)
339  call store_error(errmsg, terminate)
340  end select
341  end do
342  !
343  ! -- close model logging block
344  write (iout, '(1x,a)') 'END OF SIMULATION MODELS'
345  !
346  ! -- sanity check
347  if (simulation_mode == 'PARALLEL' .and. im == 0) then
348  write (errmsg, '(a, i0)') &
349  'No MODELS assigned to process ', proc_id
350  call store_error(errmsg, terminate)
351  end if
352  !
353  ! -- return
354  return
355  end subroutine models_create
356 
357  !> @brief Set the exchanges to be used for the simulation
358  !<
359  subroutine exchanges_create()
360  ! -- 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 ('GWF6-GWF6')
455  write (exg_name, '(a,i0)') 'GWF-GWF_', exg_id
456  if (.not. both_remote) then
457  call gwfexchange_create(fname, exg_name, exg_id, m1_id, m2_id, &
458  exg_mempath)
459  end if
460  call add_virtual_gwf_exchange(exg_name, exg_id, m1_id, m2_id)
461  case ('GWF6-GWT6')
462  if (both_local) then
463  call gwfgwt_cr(fname, exg_id, m1_id, m2_id)
464  end if
465  case ('GWF6-GWE6')
466  if (both_local) then
467  call gwfgwe_cr(fname, exg_id, m1_id, m2_id)
468  end if
469  case ('GWF6-PRT6')
470  call gwfprt_cr(fname, exg_id, m1_id, m2_id)
471  case ('GWT6-GWT6')
472  write (exg_name, '(a,i0)') 'GWT-GWT_', exg_id
473  if (.not. both_remote) then
474  call gwtexchange_create(fname, exg_name, exg_id, m1_id, m2_id, &
475  exg_mempath)
476  end if
477  call add_virtual_gwt_exchange(exg_name, exg_id, m1_id, m2_id)
478  case ('GWE6-GWE6')
479  write (exg_name, '(a,i0)') 'GWE-GWE_', exg_id
480  if (.not. both_remote) then
481  call gweexchange_create(fname, exg_name, exg_id, m1_id, m2_id, &
482  exg_mempath)
483  end if
484  call add_virtual_gwe_exchange(exg_name, exg_id, m1_id, m2_id)
485  case ('SWF6-GWF6')
486  write (exg_name, '(a,i0)') 'SWF-GWF_', exg_id
487  if (both_local) then
488  call swfgwf_cr(fname, exg_name, exg_id, m1_id, m2_id, exg_mempath)
489  end if
490  case default
491  write (errmsg, '(a,a)') &
492  'Unknown simulation exchange type: ', trim(exgtype)
493  call store_error(errmsg, terminate)
494  end select
495  end do
496  !
497  ! -- close exchange logging block
498  write (iout, '(1x,a)') 'END OF SIMULATION EXCHANGES'
499  !
500  ! -- return
501  return
502  end subroutine exchanges_create
503 
504  !> @brief Check a solution_group to be used for the simulation
505  !<
506  subroutine solution_group_check(sgp, sgid, isgpsoln)
507  ! -- modules
508  ! -- dummy
509  type(solutiongrouptype), pointer, intent(inout) :: sgp
510  integer(I4B), intent(in) :: sgid
511  integer(I4B), intent(in) :: isgpsoln
512  ! -- local
513  character(len=LINELENGTH) :: errmsg
514  logical :: terminate = .true.
515  ! -- formats
516  character(len=*), parameter :: fmterrmxiter = &
517  "('MXITER is set to ', i0, ' but there is only one solution', &
518  &' in SOLUTION GROUP ', i0, '. Set MXITER to 1 in simulation control', &
519  &' file.')"
520  !
521  ! -- error check completed group
522  if (sgid > 0) then
523  !
524  ! -- Make sure there is a solution in this solution group
525  if (isgpsoln == 0) then
526  write (errmsg, '(a,i0)') &
527  'There are no solutions for solution group ', sgid
528  call store_error(errmsg, terminate)
529  end if
530  !
531  ! -- If there is only one solution then mxiter should be 1.
532  if (isgpsoln == 1 .and. sgp%mxiter > 1) then
533  write (errmsg, fmterrmxiter) sgp%mxiter, isgpsoln
534  call store_error(errmsg, terminate)
535  end if
536  end if
537  !
538  ! -- return
539  return
540  end subroutine solution_group_check
541 
542  !> @brief Set the solution_groups to be used for the simulation
543  !<
545  ! -- modules
553  use basemodelmodule, only: basemodeltype
556  ! -- dummy
557  ! -- local
558  character(len=LENMEMPATH) :: input_mempath
559  type(characterstringtype), dimension(:), contiguous, &
560  pointer :: slntype
561  type(characterstringtype), dimension(:), contiguous, &
562  pointer :: slnfname
563  type(characterstringtype), dimension(:), contiguous, &
564  pointer :: slnmnames
565  integer(I4B), dimension(:), contiguous, pointer :: blocknum
566  character(len=LINELENGTH) :: stype, fname
567  character(len=:), allocatable :: mnames
568  type(solutiongrouptype), pointer :: sgp
569  class(basesolutiontype), pointer :: sp
570  class(basemodeltype), pointer :: mp
571  integer(I4B) :: isoln
572  integer(I4B) :: isgpsoln
573  integer(I4B) :: sgid
574  integer(I4B) :: glo_mid
575  integer(I4B) :: loc_idx
576  integer(I4B) :: i, j, istat, mxiter
577  integer(I4B) :: nwords
578  character(len=LENMODELNAME), dimension(:), allocatable :: words
579  character(len=:), allocatable :: parse_str
580  character(len=LINELENGTH) :: errmsg
581  logical :: terminate = .true.
582 ! ------------------------------------------------------------------------------
583  !
584  ! -- set memory path
585  input_mempath = create_mem_path('SIM', 'NAM', idm_context)
586  !
587  ! -- set pointers to input context solution attribute arrays
588  call mem_setptr(slntype, 'SLNTYPE', input_mempath)
589  call mem_setptr(slnfname, 'SLNFNAME', input_mempath)
590  call mem_setptr(slnmnames, 'SLNMNAMES', input_mempath)
591  call mem_setptr(blocknum, 'SOLUTIONGROUPNUM', input_mempath)
592  !
593  ! -- open solution group logging block
594  write (iout, '(/1x,a)') 'READING SOLUTIONGROUP'
595  !
596  ! -- initialize
597  sgid = 0 ! integer id of soln group, tracks with blocknum
598  isoln = 0 ! cumulative solution number
599  !
600  ! -- create solution groups
601  do i = 1, size(blocknum)
602  !
603  ! -- allocate slnmnames string
604  allocate (character(slnmnames(i)%strlen()) :: mnames)
605  !
606  ! -- attributes for this solution
607  stype = slntype(i)
608  fname = slnfname(i)
609  mnames = slnmnames(i)
610 
611  if (blocknum(i) /= sgid) then
612  !
613  ! -- check for new soln group
614  if (blocknum(i) == sgid + 1) then
615  !
616  ! -- error check completed group
617  call solution_group_check(sgp, sgid, isgpsoln)
618  !
619  ! -- reinitialize
620  nullify (sgp)
621  isgpsoln = 0 ! solution counter for this solution group
622  !
623  ! -- set sgid
624  sgid = blocknum(i)
625  !
626  ! -- create new soln group and add to global list
627  call solutiongroup_create(sgp, sgid)
628  call addsolutiongrouptolist(solutiongrouplist, sgp)
629  else
630  write (errmsg, '(a,i0,a,i0,a)') &
631  'Solution group blocks are not listed consecutively. Found ', &
632  blocknum(i), ' when looking for ', sgid + 1, '.'
633  call store_error(errmsg, terminate)
634  end if
635  end if
636  !
637  ! --
638  select case (stype)
639  !
640  case ('MXITER')
641  read (fname, *, iostat=istat) mxiter
642  if (istat == 0) then
643  sgp%mxiter = mxiter
644  end if
645  case ('IMS6')
646  !
647  ! -- increment solution counters
648  isoln = isoln + 1
649  isgpsoln = isgpsoln + 1
650  !
651  ! -- create soln and add to group
652  sp => create_ims_solution(simulation_mode, fname, isoln)
653  call sgp%add_solution(isoln, sp)
654  !
655  ! -- parse model names
656  parse_str = trim(mnames)//' '
657  call parseline(parse_str, nwords, words)
658  !
659  ! -- Find each model id and get model
660  do j = 1, nwords
661  call upcase(words(j))
662  glo_mid = ifind(model_names, words(j))
663  if (glo_mid == -1) then
664  write (errmsg, '(a,a)') 'Invalid model name: ', trim(words(j))
665  call store_error(errmsg, terminate)
666  end if
667  !
668  loc_idx = model_loc_idx(glo_mid)
669  if (loc_idx == -1) then
670  if (simulation_mode == 'PARALLEL') then
671  ! this is still ok
672  cycle
673  end if
674  end if
675  !
676  mp => getbasemodelfromlist(basemodellist, loc_idx)
677  !
678  ! -- Add the model to the solution
679  call sp%add_model(mp)
680  mp%idsoln = isoln
681  end do
682  case ('EMS6')
683  !
684  ! -- increment solution counters
685  isoln = isoln + 1
686  isgpsoln = isgpsoln + 1
687  !
688  ! -- create soln and add to group
689  sp => create_ems_solution(simulation_mode, fname, isoln)
690  call sgp%add_solution(isoln, sp)
691  !
692  ! -- parse model names
693  parse_str = trim(mnames)//' '
694  call parseline(parse_str, nwords, words)
695  !
696  ! -- Find each model id and get model
697  do j = 1, nwords
698  call upcase(words(j))
699  glo_mid = ifind(model_names, words(j))
700  if (glo_mid == -1) then
701  write (errmsg, '(a,a)') 'Invalid model name: ', trim(words(j))
702  call store_error(errmsg, terminate)
703  end if
704  !
705  loc_idx = model_loc_idx(glo_mid)
706  if (loc_idx == -1) then
707  if (simulation_mode == 'PARALLEL') then
708  ! this is still ok
709  cycle
710  end if
711  end if
712  !
713  mp => getbasemodelfromlist(basemodellist, loc_idx)
714  !
715  ! -- Add the model to the solution
716  call sp%add_model(mp)
717  mp%idsoln = isoln
718  end do
719  case default
720  end select
721  !
722  ! -- clean up
723  deallocate (mnames)
724  end do
725  !
726  ! -- error check final group
727  call solution_group_check(sgp, sgid, isgpsoln)
728  !
729  ! -- close exchange logging block
730  write (iout, '(1x,a)') 'END OF SOLUTIONGROUP'
731  !
732  ! -- Check and make sure at least one solution group was found
733  if (solutiongrouplist%Count() == 0) then
734  call store_error('There are no solution groups.', terminate)
735  end if
736  !
737  ! -- return
738  return
739  end subroutine solution_groups_create
740 
741  !> @brief Check for dangling models, and break with
742  !! error when found
743  !<
745  character(len=LINELENGTH) :: errmsg
746  class(basemodeltype), pointer :: mp
747  integer(I4B) :: im
748 
749  do im = 1, basemodellist%Count()
751  if (mp%idsoln == 0) then
752  write (errmsg, '(a,a)') &
753  'Model was not assigned to a solution: ', mp%name
754  call store_error(errmsg)
755  end if
756  end do
757  if (count_errors() > 0) then
758  call store_error_filename('mfsim.nam')
759  end if
760 
761  end subroutine check_model_assignment
762 
763  !> @brief Assign exchanges to solutions
764  !!
765  !! This assigns NumericalExchanges to NumericalSolutions,
766  !! based on the link between the models in the solution and
767  !! those exchanges. The BaseExchange%connects_model() function
768  !! should be overridden to indicate if such a link exists.
769  !<
770  subroutine assign_exchanges()
771  ! -- local
772  class(basesolutiontype), pointer :: sp
773  class(baseexchangetype), pointer :: ep
774  class(basemodeltype), pointer :: mp
775  type(listtype), pointer :: models_in_solution
776  integer(I4B) :: is, ie, im
777 
778  do is = 1, basesolutionlist%Count()
780  !
781  ! -- now loop over exchanges
782  do ie = 1, baseexchangelist%Count()
784  !
785  ! -- and add when it affects (any model in) the solution matrix
786  models_in_solution => sp%get_models()
787  do im = 1, models_in_solution%Count()
788  mp => getbasemodelfromlist(models_in_solution, im)
789  if (ep%connects_model(mp)) then
790  !
791  ! -- add to solution (and only once)
792  call sp%add_exchange(ep)
793  exit
794  end if
795  end do
796  end do
797  end do
798  end subroutine assign_exchanges
799 
800  !> @brief Check that the model name is valid
801  !<
802  subroutine check_model_name(mtype, mname)
803  ! -- dummy
804  character(len=*), intent(in) :: mtype
805  character(len=*), intent(inout) :: mname
806  ! -- local
807  integer :: ilen
808  integer :: i
809  character(len=LINELENGTH) :: errmsg
810  logical :: terminate = .true.
811  ! ------------------------------------------------------------------------------
812  ilen = len_trim(mname)
813  if (ilen > lenmodelname) then
814  write (errmsg, '(a,a)') 'Invalid model name: ', trim(mname)
815  call store_error(errmsg)
816  write (errmsg, '(a,i0,a,i0)') &
817  'Name length of ', ilen, ' exceeds maximum length of ', &
819  call store_error(errmsg, terminate)
820  end if
821  do i = 1, ilen
822  if (mname(i:i) == ' ') then
823  write (errmsg, '(a,a)') 'Invalid model name: ', trim(mname)
824  call store_error(errmsg)
825  write (errmsg, '(a)') &
826  'Model name cannot have spaces within it.'
827  call store_error(errmsg, terminate)
828  end if
829  end do
830  !
831  ! -- return
832  return
833  end subroutine check_model_name
834 
835 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 simulation constants.
Definition: Constants.f90:9
integer(i4b), parameter linelength
maximum length of a standard line
Definition: Constants.f90:44
integer(i4b), parameter lenmodelname
maximum length of the model name
Definition: Constants.f90:21
integer(i4b), parameter lenexchangename
maximum length of the exchange name
Definition: Constants.f90:23
integer(i4b), parameter lenpackagetype
maximum length of a package type (DIS6, SFR6, CSUB6, etc.)
Definition: Constants.f90:37
integer(i4b), parameter lenbigline
maximum length of a big line
Definition: Constants.f90:15
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
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:111
Definition: gwe.f90:3
subroutine, public gwe_cr(filename, id, modelname)
Create a new groundwater energy transport model object.
Definition: gwe.f90:96
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:47
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:98
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)
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)
subroutine, public addsolutiongrouptolist(list, solutiongroup)
This module contains the SwfGwfExchangeModule Module.
Definition: exg-swfgwf.f90:7
subroutine, public swfgwf_cr(filename, name, id, m1_id, m2_id, input_mempath)
@ brief Create SWF GWF exchange
Definition: exg-swfgwf.f90:97
Stream Network Flow (SWF) Module.
Definition: swf.f90:38
subroutine, public swf_cr(filename, id, modelname)
Create a new stream network flow model object.
Definition: swf.f90:145
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:10