MODFLOW 6 version 6.9.0.dev0
USGS Modular Hydrologic Model
Loading...
Searching...
No Matches
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
30contains
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 !<
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
102 ! -- dummy
103 ! -- locals
104 character(len=LENMEMPATH) :: input_mempath
105 integer(I4B), pointer :: simcontinue, nocheck, maxerror
106 character(len=:), pointer :: prmem
107 character(len=LINELENGTH) :: errmsg
108 !
109 ! -- set input memory path
110 input_mempath = create_mem_path('SIM', 'NAM', idm_context)
111 !
112 ! -- set pointers to input context option params
113 call mem_setptr(simcontinue, 'CONTINUE', input_mempath)
114 call mem_setptr(nocheck, 'NOCHECK', input_mempath)
115 call mem_setptr(prmem, 'PRMEM', input_mempath)
116 call mem_setptr(maxerror, 'MAXERRORS', input_mempath)
117 !
118 ! -- update sim options
119 isimcontinue = simcontinue
120 if (nocheck == 1) then
121 isimcheck = 0
122 else
123 isimcheck = 1
124 end if
125
126 call maxerrors(maxerror)
127
128 if (prmem /= '') then
129 errmsg = ''
130 call mem_set_print_option(iout, prmem, errmsg)
131 if (errmsg /= '') then
132 call store_error(errmsg, .true.)
133 end if
134 end if
135
136 !
137 ! -- log values to list file
138 if (iout > 0) then
139 write (iout, '(/1x,a)') 'READING SIMULATION OPTIONS'
140 !
141 if (isimcontinue == 1) then
142 write (iout, '(4x, a)') &
143 'SIMULATION WILL CONTINUE EVEN IF THERE IS NONCONVERGENCE.'
144 end if
145 !
146 if (isimcheck == 0) then
147 write (iout, '(4x, a)') &
148 'MODEL DATA WILL NOT BE CHECKED FOR ERRORS.'
149 end if
150 !
151 write (iout, '(4x, a, i0)') &
152 'MAXIMUM NUMBER OF ERRORS THAT WILL BE STORED IS ', maxerror
153 !
154 if (prmem /= '') then
155 write (iout, '(4x, a, a, a)') &
156 'MEMORY_PRINT_OPTION SET TO "', trim(prmem), '".'
157 end if
158 !
159 write (iout, '(1x,a)') 'END OF SIMULATION OPTIONS'
160 end if
161 end subroutine options_create
162
163 !> @brief Set the timing module to be used for the simulation
164 !<
165 subroutine timing_create()
166 ! -- modules
170 use tdismodule, only: tdis_cr
171 ! -- dummy
172 ! -- locals
173 character(len=LENMEMPATH) :: input_mempath
174 character(len=LENMEMPATH) :: tdis_input_mempath
175 character(len=:), pointer :: tdis6
176 logical :: terminate = .true.
177 !
178 ! -- set input memory path
179 input_mempath = create_mem_path('SIM', 'NAM', idm_context)
180 tdis_input_mempath = create_mem_path('SIM', 'TDIS', idm_context)
181 !
182 write (iout, '(/1x,a)') 'READING SIMULATION TIMING'
183 !
184 ! -- set pointers to input context timing params
185 call mem_setptr(tdis6, 'TDIS6', input_mempath)
186 !
187 ! -- create timing
188 if (tdis6 /= '') then
189 call tdis_cr(tdis6, tdis_input_mempath)
190 else
191 call store_error('TIMING block variable TDIS6 is unset'// &
192 ' in simulation control input.', terminate)
193 end if
194 !
195 write (iout, '(1x,a)') 'END OF SIMULATION TIMING'
196 end subroutine timing_create
197
198 !> @brief Set the models to be used for the simulation
199 !<
200 subroutine models_create()
201 ! -- modules
206 use chfmodule, only: chf_cr
207 use gwfmodule, only: gwf_cr
208 use gwtmodule, only: gwt_cr
209 use gwemodule, only: gwe_cr
210 use olfmodule, only: olf_cr
211 use prtmodule, only: prt_cr
217 ! use VirtualPrtModelModule, only: add_virtual_prt_model
219 ! -- dummy
220 ! -- locals
221 type(distributedsimtype), pointer :: ds
222 character(len=LENMEMPATH) :: input_mempath
223 type(characterstringtype), dimension(:), contiguous, &
224 pointer :: mtypes !< model types
225 type(characterstringtype), dimension(:), contiguous, &
226 pointer :: mfnames !< model file names
227 type(characterstringtype), dimension(:), contiguous, &
228 pointer :: mnames !< model names
229 integer(I4B) :: im
230 class(numericalmodeltype), pointer :: num_model
231 class(explicitmodeltype), pointer :: exp_model
232 character(len=LINELENGTH) :: model_type
233 character(len=LINELENGTH) :: fname, model_name
234 integer(I4B) :: n, nr_models_glob
235 integer(I4B), dimension(:), pointer :: model_ranks => null()
236 logical :: terminate = .true.
237 !
238 ! -- set input memory path
239 input_mempath = create_mem_path('SIM', 'NAM', idm_context)
240 !
241 ! -- set pointers to input context model attribute arrays
242 call mem_setptr(mtypes, 'MTYPE', input_mempath)
243 call mem_setptr(mfnames, 'MFNAME', input_mempath)
244 call mem_setptr(mnames, 'MNAME', input_mempath)
245 !
246 ! -- allocate global arrays
247 nr_models_glob = size(mnames)
248 allocate (model_names(nr_models_glob))
249 allocate (model_loc_idx(nr_models_glob))
250 !
251 ! -- get model-to-cpu assignment (in serial all to rank 0)
252 ds => get_dsim()
253 model_ranks => ds%get_load_balance()
254 !
255 ! -- open model logging block
256 write (iout, '(/1x,a)') 'READING SIMULATION MODELS'
257 !
258 ! -- create models
259 im = 0
260 do n = 1, size(mtypes)
261 !
262 ! -- attributes for this model
263 model_type = mtypes(n)
264 fname = mfnames(n)
265 model_name = mnames(n)
266 !
267 call check_model_name(model_type, model_name, model_names(1:n - 1))
268 !
269 ! increment global model id
270 model_names(n) = model_name(1:lenmodelname)
271 model_loc_idx(n) = -1
272 num_model => null()
273 exp_model => null()
274 !
275 ! -- add a new (local or global) model
276 select case (model_type)
277 case ('GWF6')
278 if (model_ranks(n) == proc_id) then
279 im = im + 1
280 write (iout, '(4x,2a,i0,a)') trim(model_type), ' model ', &
281 n, ' will be created'
282 call gwf_cr(fname, n, model_names(n))
284 model_loc_idx(n) = im
285 end if
286 call add_virtual_gwf_model(n, model_names(n), num_model)
287 case ('GWT6')
288 if (model_ranks(n) == proc_id) then
289 im = im + 1
290 write (iout, '(4x,2a,i0,a)') trim(model_type), ' model ', &
291 n, ' will be created'
292 call gwt_cr(fname, n, model_names(n))
294 model_loc_idx(n) = im
295 end if
296 call add_virtual_gwt_model(n, model_names(n), num_model)
297 case ('GWE6')
298 if (model_ranks(n) == proc_id) then
299 im = im + 1
300 write (iout, '(4x,2a,i0,a)') trim(model_type), ' model ', &
301 n, ' will be created'
302 call gwe_cr(fname, n, model_names(n))
304 model_loc_idx(n) = im
305 end if
306 call add_virtual_gwe_model(n, model_names(n), num_model)
307 case ('CHF6')
308 if (model_ranks(n) == proc_id) then
309 im = im + 1
310 write (iout, '(4x,2a,i0,a)') trim(model_type), " model ", &
311 n, " will be created"
312 call chf_cr(fname, n, model_names(n))
313 call developmode('CHF is still under development, install the &
314 &nightly build or compile from source with IDEVELOPMODE = 1.')
316 model_loc_idx(n) = im
317 end if
318 case ('OLF6')
319 if (model_ranks(n) == proc_id) then
320 im = im + 1
321 write (iout, '(4x,2a,i0,a)') trim(model_type), " model ", &
322 n, " will be created"
323 call olf_cr(fname, n, model_names(n))
324 call developmode('OLF is still under development, install the &
325 &nightly build or compile from source with IDEVELOPMODE = 1.')
327 model_loc_idx(n) = im
328 end if
329 case ('PRT6')
330 if (model_ranks(n) == proc_id) then
331 im = im + 1
332 write (iout, '(4x,2a,i0,a)') trim(model_type), ' model ', &
333 n, ' will be created'
334 call prt_cr(fname, n, model_names(n))
336 model_loc_idx(n) = im
337 end if
338 ! When virtual PRT is implemented, uncomment:
339 ! call add_virtual_prt_model(n, model_names(n), exp_model)
340 case default
341 write (errmsg, '(a,a)') &
342 'Unknown simulation model type: ', trim(model_type)
343 call store_error(errmsg, terminate)
344 end select
345 end do
346 !
347 ! -- close model logging block
348 write (iout, '(1x,a)') 'END OF SIMULATION MODELS'
349 !
350 ! -- sanity check
351 if (simulation_mode == 'PARALLEL' .and. im == 0) then
352 write (errmsg, '(a, i0)') &
353 'No MODELS assigned to process ', proc_id
354 call store_error(errmsg, terminate)
355 end if
356 end subroutine models_create
357
358 !> @brief Set the exchanges to be used for the simulation
359 !<
360 subroutine exchanges_create()
361 ! -- modules
365 use chfgwfexchangemodule, only: chfgwf_cr
372 use olfgwfexchangemodule, only: olfgwf_cr
375 ! use VirtualPrtExchangeModule, only: add_virtual_prt_exchange
376 ! -- dummy
377 ! -- locals
378 character(len=LENMEMPATH) :: input_mempath
379 type(characterstringtype), dimension(:), contiguous, &
380 pointer :: etypes !< exg types
381 type(characterstringtype), dimension(:), contiguous, &
382 pointer :: efiles !< exg file names
383 type(characterstringtype), dimension(:), contiguous, &
384 pointer :: emnames_a !< model a names
385 type(characterstringtype), dimension(:), contiguous, &
386 pointer :: emnames_b !< model b names
387 type(characterstringtype), dimension(:), contiguous, &
388 pointer :: emempaths
389 character(len=LINELENGTH) :: exgtype
390 integer(I4B) :: exg_id
391 integer(I4B) :: m1_id, m2_id
392 character(len=LINELENGTH) :: fname, name1, name2
393 character(len=LENEXCHANGENAME) :: exg_name
394 character(len=LENMEMPATH) :: exg_mempath
395 integer(I4B) :: n
396 character(len=LINELENGTH) :: errmsg
397 logical(LGP) :: terminate = .true.
398 logical(LGP) :: both_remote, both_local
399 ! -- formats
400 character(len=*), parameter :: fmtmerr = "('Error in simulation control ', &
401 &'file. Could not find model: ', a)"
402 !
403 ! -- set input memory path
404 input_mempath = create_mem_path('SIM', 'NAM', idm_context)
405 !
406 ! -- set pointers to input context exchange attribute arrays
407 call mem_setptr(etypes, 'EXGTYPE', input_mempath)
408 call mem_setptr(efiles, 'EXGFILE', input_mempath)
409 call mem_setptr(emnames_a, 'EXGMNAMEA', input_mempath)
410 call mem_setptr(emnames_b, 'EXGMNAMEB', input_mempath)
411 call mem_setptr(emempaths, 'EXGMEMPATHS', input_mempath)
412 !
413 ! -- open exchange logging block
414 write (iout, '(/1x,a)') 'READING SIMULATION EXCHANGES'
415 !
416 ! -- initialize
417 exg_id = 0
418 !
419 ! -- create exchanges
420 do n = 1, size(etypes)
421 !
422 ! -- attributes for this exchange
423 exgtype = etypes(n)
424 fname = efiles(n)
425 name1 = emnames_a(n)
426 name2 = emnames_b(n)
427 exg_mempath = emempaths(n)
428
429 exg_id = exg_id + 1
430
431 ! find model index in list
432 m1_id = ifind(model_names, name1)
433 if (m1_id < 0) then
434 write (errmsg, fmtmerr) trim(name1)
435 call store_error(errmsg, terminate)
436 end if
437 m2_id = ifind(model_names, name2)
438 if (m2_id < 0) then
439 write (errmsg, fmtmerr) trim(name2)
440 call store_error(errmsg, terminate)
441 end if
442
443 ! both models on other process? then don't create it here...
444 both_remote = (model_loc_idx(m1_id) == -1 .and. &
445 model_loc_idx(m2_id) == -1)
446 both_local = (model_loc_idx(m1_id) > 0 .and. &
447 model_loc_idx(m2_id) > 0)
448 if (.not. both_remote) then
449 write (iout, '(4x,a,a,i0,a,i0,a,i0)') trim(exgtype), ' exchange ', &
450 exg_id, ' will be created to connect model ', m1_id, &
451 ' with model ', m2_id
452 end if
453
454 select case (exgtype)
455 case ('CHF6-GWF6')
456 write (exg_name, '(a,i0)') 'CHF-GWF_', exg_id
457 if (both_local) then
458 call chfgwf_cr(fname, exg_name, exg_id, m1_id, m2_id, exg_mempath)
459 end if
460 case ('GWF6-GWF6')
461 write (exg_name, '(a,i0)') 'GWF-GWF_', exg_id
462 if (.not. both_remote) then
463 call gwfexchange_create(fname, exg_name, exg_id, m1_id, m2_id, &
464 exg_mempath)
465 end if
466 call add_virtual_gwf_exchange(exg_name, exg_id, m1_id, m2_id)
467 case ('GWF6-GWT6')
468 if (both_local) then
469 call gwfgwt_cr(fname, exg_id, m1_id, m2_id)
470 end if
471 case ('GWF6-GWE6')
472 if (both_local) then
473 call gwfgwe_cr(fname, exg_id, m1_id, m2_id)
474 end if
475 case ('GWF6-PRT6')
476 call gwfprt_cr(fname, exg_id, m1_id, m2_id)
477 case ('GWT6-GWT6')
478 write (exg_name, '(a,i0)') 'GWT-GWT_', exg_id
479 if (.not. both_remote) then
480 call gwtexchange_create(fname, exg_name, exg_id, m1_id, m2_id, &
481 exg_mempath)
482 end if
483 call add_virtual_tsp_exchange(exg_name, exg_id, m1_id, m2_id, &
484 "concentration")
485 case ('GWE6-GWE6')
486 write (exg_name, '(a,i0)') 'GWE-GWE_', exg_id
487 if (.not. both_remote) then
488 call gweexchange_create(fname, exg_name, exg_id, m1_id, m2_id, &
489 exg_mempath)
490 end if
491 call add_virtual_tsp_exchange(exg_name, exg_id, m1_id, m2_id, &
492 "temperature")
493 case ('OLF6-GWF6')
494 write (exg_name, '(a,i0)') 'OLF-GWF_', exg_id
495 if (both_local) then
496 call olfgwf_cr(fname, exg_name, exg_id, m1_id, m2_id, exg_mempath)
497 end if
498 case default
499 write (errmsg, '(a,a)') &
500 'Unknown simulation exchange type: ', trim(exgtype)
501 call store_error(errmsg, terminate)
502 end select
503 end do
504 !
505 ! -- close exchange logging block
506 write (iout, '(1x,a)') 'END OF SIMULATION EXCHANGES'
507 end subroutine exchanges_create
508
509 !> @brief Check a solution_group to be used for the simulation
510 !<
511 subroutine solution_group_check(sgp, sgid, isgpsoln)
512 ! -- modules
513 ! -- dummy
514 type(solutiongrouptype), pointer, intent(inout) :: sgp
515 integer(I4B), intent(in) :: sgid
516 integer(I4B), intent(in) :: isgpsoln
517 ! -- local
518 character(len=LINELENGTH) :: errmsg
519 logical :: terminate = .true.
520 ! -- formats
521 character(len=*), parameter :: fmterrmxiter = &
522 "('MXITER is set to ', i0, ' but there is only one solution', &
523 &' in SOLUTION GROUP ', i0, '. Set MXITER to 1 in simulation control', &
524 &' file.')"
525 !
526 ! -- error check completed group
527 if (sgid > 0) then
528 !
529 ! -- Make sure there is a solution in this solution group
530 if (isgpsoln == 0) then
531 write (errmsg, '(a,i0)') &
532 'There are no solutions for solution group ', sgid
533 call store_error(errmsg, terminate)
534 end if
535 !
536 ! -- If there is only one solution then mxiter should be 1.
537 if (isgpsoln == 1 .and. sgp%mxiter > 1) then
538 write (errmsg, fmterrmxiter) sgp%mxiter, isgpsoln
539 call store_error(errmsg, terminate)
540 end if
541 end if
542 end subroutine solution_group_check
543
544 !> @brief Set the solution_groups to be used for the simulation
545 !<
547 ! -- modules
560 ! -- dummy
561 ! -- local
562 character(len=LENMEMPATH) :: input_mempath
563 type(characterstringtype), dimension(:), contiguous, &
564 pointer :: slntype
565 type(characterstringtype), dimension(:), contiguous, &
566 pointer :: slnfname
567 type(characterstringtype), dimension(:), contiguous, &
568 pointer :: slnmnames
569 integer(I4B), dimension(:), contiguous, pointer :: blocknum
570 character(len=LINELENGTH) :: stype, fname
571 character(len=:), allocatable :: mnames
572 type(solutiongrouptype), pointer :: sgp
573 class(basesolutiontype), pointer :: sp
574 class(basemodeltype), pointer :: mp
575 integer(I4B) :: isoln
576 integer(I4B) :: isgpsoln
577 integer(I4B) :: sgid
578 integer(I4B) :: glo_mid
579 integer(I4B) :: loc_idx
580 integer(I4B) :: i, j, istat, mxiter
581 integer(I4B) :: nwords
582 character(len=LENMODELNAME), dimension(:), allocatable :: words
583 character(len=:), allocatable :: parse_str
584 character(len=LINELENGTH) :: errmsg
585 logical :: terminate = .true.
586 !
587 ! -- set memory path
588 input_mempath = create_mem_path('SIM', 'NAM', idm_context)
589 !
590 ! -- set pointers to input context solution attribute arrays
591 call mem_setptr(slntype, 'SLNTYPE', input_mempath)
592 call mem_setptr(slnfname, 'SLNFNAME', input_mempath)
593 call mem_setptr(slnmnames, 'SLNMNAMES', input_mempath)
594 call mem_setptr(blocknum, 'SOLUTIONGROUPNUM', input_mempath)
595 !
596 ! -- open solution group logging block
597 write (iout, '(/1x,a)') 'READING SOLUTIONGROUP'
598 !
599 ! -- initialize
600 sgid = 0 ! integer id of soln group, tracks with blocknum
601 isoln = 0 ! cumulative solution number
602 !
603 ! -- create solution groups
604 do i = 1, size(blocknum)
605 !
606 ! -- allocate slnmnames string
607 allocate (character(slnmnames(i)%strlen()) :: mnames)
608 !
609 ! -- attributes for this solution
610 stype = slntype(i)
611 fname = slnfname(i)
612 mnames = slnmnames(i)
613
614 if (blocknum(i) /= sgid) then
615 !
616 ! -- check for new soln group
617 if (blocknum(i) == sgid + 1) then
618 !
619 ! -- error check completed group
620 call solution_group_check(sgp, sgid, isgpsoln)
621 !
622 ! -- reinitialize
623 nullify (sgp)
624 isgpsoln = 0 ! solution counter for this solution group
625 !
626 ! -- set sgid
627 sgid = blocknum(i)
628 !
629 ! -- create new soln group and add to global list
630 call solutiongroup_create(sgp, sgid)
632 else
633 write (errmsg, '(a,i0,a,i0,a)') &
634 'Solution group blocks are not listed consecutively. Found ', &
635 blocknum(i), ' when looking for ', sgid + 1, '.'
636 call store_error(errmsg, terminate)
637 end if
638 end if
639 !
640 ! --
641 select case (stype)
642 !
643 case ('MXITER')
644 read (fname, *, iostat=istat) mxiter
645 if (istat == 0) then
646 sgp%mxiter = mxiter
647 end if
648 case ('IMS6')
649 !
650 ! -- increment solution counters
651 isoln = isoln + 1
652 isgpsoln = isgpsoln + 1
653 !
654 ! -- create soln and add to group
655 sp => create_ims_solution(simulation_mode, fname, isoln)
656 call sgp%add_solution(isoln, sp)
657 !
658 ! -- parse model names
659 parse_str = trim(mnames)//' '
660 call parseline(parse_str, nwords, words)
661 !
662 ! -- Find each model id and get model
663 do j = 1, nwords
664 call upcase(words(j))
665 glo_mid = ifind(model_names, words(j))
666 if (glo_mid == -1) then
667 write (errmsg, '(a,a)') 'Invalid model name: ', trim(words(j))
668 call store_error(errmsg, terminate)
669 end if
670 !
671 loc_idx = model_loc_idx(glo_mid)
672 if (loc_idx == -1) then
673 if (simulation_mode == 'PARALLEL') then
674 ! this is still ok
675 cycle
676 end if
677 end if
678 !
679 mp => getbasemodelfromlist(basemodellist, loc_idx)
680 !
681 ! -- Check for solver-model type mismatch
682 select type (mp)
683 class is (explicitmodeltype)
684 write (errmsg, '(4a)') &
685 'Model "', trim(words(j)), &
686 '" is an explicit model and cannot be added to an IMS6 ', &
687 'solution. Explicit models require EMS6.'
688 call store_error(errmsg)
689 end select
690 !
691 ! -- Add the model to the solution
692 call sp%add_model(mp)
693 mp%idsoln = isoln
694 end do
695 !
696 ! -- Check for any errors
697 if (count_errors() > 0) then
698 call store_error_filename('mfsim.nam')
699 end if
700 case ('EMS6')
701 !
702 ! -- increment solution counters
703 isoln = isoln + 1
704 isgpsoln = isgpsoln + 1
705 !
706 ! -- create soln and add to group
707 sp => create_ems_solution(simulation_mode, fname, isoln)
708 call sgp%add_solution(isoln, sp)
709 !
710 ! -- parse model names
711 parse_str = trim(mnames)//' '
712 call parseline(parse_str, nwords, words)
713 !
714 ! -- Find each model id and get model
715 do j = 1, nwords
716 call upcase(words(j))
717 glo_mid = ifind(model_names, words(j))
718 if (glo_mid == -1) then
719 write (errmsg, '(a,a)') 'Invalid model name: ', trim(words(j))
720 call store_error(errmsg, terminate)
721 end if
722 !
723 loc_idx = model_loc_idx(glo_mid)
724 if (loc_idx == -1) then
725 if (simulation_mode == 'PARALLEL') then
726 ! this is still ok
727 cycle
728 end if
729 end if
730 !
731 mp => getbasemodelfromlist(basemodellist, loc_idx)
732 !
733 ! -- Check for solver-model type mismatch
734 select type (mp)
735 class is (numericalmodeltype)
736 write (errmsg, '(4a)') &
737 'Model "', trim(words(j)), &
738 '" is a numerical model and cannot be added to an EMS6 ', &
739 'solution. Numerical models require IMS6.'
740 call store_error(errmsg)
741 end select
742 !
743 ! -- Add the model to the solution
744 call sp%add_model(mp)
745 mp%idsoln = isoln
746 end do
747 !
748 ! -- Check for any errors
749 if (count_errors() > 0) then
750 call store_error_filename('mfsim.nam')
751 end if
752 case default
753 end select
754 !
755 ! -- clean up
756 deallocate (mnames)
757 end do
758 !
759 ! -- error check final group
760 call solution_group_check(sgp, sgid, isgpsoln)
761 !
762 ! -- close exchange logging block
763 write (iout, '(1x,a)') 'END OF SOLUTIONGROUP'
764 !
765 ! -- Check and make sure at least one solution group was found
766 if (solutiongrouplist%Count() == 0) then
767 call store_error('There are no solution groups.', terminate)
768 end if
769 end subroutine solution_groups_create
770
771 !> @brief Check for dangling models, and break with
772 !! error when found
773 !<
775 character(len=LINELENGTH) :: errmsg
776 class(basemodeltype), pointer :: mp
777 integer(I4B) :: im
778
779 do im = 1, basemodellist%Count()
780 mp => getbasemodelfromlist(basemodellist, im)
781 if (mp%idsoln == 0) then
782 write (errmsg, '(a,a)') &
783 'Model was not assigned to a solution: ', mp%name
784 call store_error(errmsg)
785 end if
786 end do
787 if (count_errors() > 0) then
788 call store_error_filename('mfsim.nam')
789 end if
790
791 end subroutine check_model_assignment
792
793 !> @brief Assign exchanges to solutions
794 !!
795 !! This assigns NumericalExchanges to NumericalSolutions,
796 !! based on the link between the models in the solution and
797 !! those exchanges. The BaseExchange%connects_model() function
798 !! should be overridden to indicate if such a link exists.
799 !<
800 subroutine assign_exchanges()
801 ! -- local
802 class(basesolutiontype), pointer :: sp
803 class(baseexchangetype), pointer :: ep
804 class(basemodeltype), pointer :: mp
805 type(listtype), pointer :: models_in_solution
806 integer(I4B) :: is, ie, im
807
808 do is = 1, basesolutionlist%Count()
809 sp => getbasesolutionfromlist(basesolutionlist, is)
810 !
811 ! -- now loop over exchanges
812 do ie = 1, baseexchangelist%Count()
813 ep => getbaseexchangefromlist(baseexchangelist, ie)
814 !
815 ! -- and add when it affects (any model in) the solution matrix
816 models_in_solution => sp%get_models()
817 do im = 1, models_in_solution%Count()
818 mp => getbasemodelfromlist(models_in_solution, im)
819 if (ep%connects_model(mp)) then
820 !
821 ! -- add to solution (and only once)
822 call sp%add_exchange(ep)
823 exit
824 end if
825 end do
826 end do
827 end do
828 end subroutine assign_exchanges
829
830 !> @brief Check that the model name is valid and unique
831 !<
832 subroutine check_model_name(mtype, mname, existing_names)
833 ! -- dummy
834 character(len=*), intent(in) :: mtype
835 character(len=*), intent(inout) :: mname
836 character(len=*), dimension(:), intent(in) :: existing_names !< names of
837 !! models already created earlier in the simulation nam file models block
838 ! -- local
839 integer :: ilen
840 integer :: i
841 character(len=LINELENGTH) :: errmsg
842 logical :: terminate = .true.
843
844 ilen = len_trim(mname)
845 if (ilen > lenmodelname) then
846 write (errmsg, '(a,a)') 'Invalid model name: ', trim(mname)
847 call store_error(errmsg)
848 write (errmsg, '(a,i0,a,i0)') &
849 'Name length of ', ilen, ' exceeds maximum length of ', &
850 lenmodelname
851 call store_error(errmsg, terminate)
852 end if
853 do i = 1, ilen
854 if (mname(i:i) == ' ') then
855 write (errmsg, '(a,a)') 'Invalid model name: ', trim(mname)
856 call store_error(errmsg)
857 write (errmsg, '(a)') &
858 'Model name cannot have spaces within it.'
859 call store_error(errmsg, terminate)
860 end if
861 end do
862 if (ifind(existing_names, mname) > 0) then
863 write (errmsg, '(a,a)') 'Invalid model name: ', trim(mname)
864 call store_error(errmsg)
865 write (errmsg, '(a)') &
866 'Model names must be unique.'
867 call store_error(errmsg, terminate)
868 end if
869 end subroutine check_model_name
870
871end module simulationcreatemodule
subroutine chfgwf_cr(filename, name, id, m1_id, m2_id, input_mempath)
@ brief Create CHF GWF exchange
subroutine olfgwf_cr(filename, name, id, m1_id, m2_id, input_mempath)
@ brief Create OLF GWF exchange
class(baseexchangetype) function, pointer, public getbaseexchangefromlist(list, idx)
Retrieve a specific BaseExchangeType object from a list.
class(basemodeltype) function, pointer, public getbasemodelfromlist(list, idx)
subroutine, public addbasesolutiontolist(list, solution)
class(basesolutiontype) function, pointer, public getbasesolutionfromlist(list, idx)
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
class(distributedsimtype) function, pointer, public get_dsim()
Get pointer to the distributed simulation object.
Models that solve themselves.
class(explicitmodeltype) function, pointer, public getexplicitmodelfromlist(list, idx)
@ brief Get generic object from list and return as explicit model
Disable development features in release mode.
subroutine, public developmode(errmsg, iunit)
Terminate if in release mode (guard development features).
This module contains the GweGweExchangeModule Module.
subroutine, public gweexchange_create(filename, name, id, m1_id, m2_id, input_mempath)
@ brief Create GWT GWT exchange
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.
This module contains the GwfGwfExchangeModule Module.
subroutine, public gwfexchange_create(filename, name, id, m1_id, m2_id, input_mempath)
@ brief Create GWF GWF exchange
subroutine, public gwfgwt_cr(filename, id, m1_id, m2_id)
Create a new GWF to GWT exchange object.
subroutine, public gwf_cr(filename, id, modelname)
Create a new groundwater flow model object.
Definition gwf.f90:139
subroutine, public gwfprt_cr(filename, id, m1id, m2id)
Create a new GWF to PRT exchange object.
This module contains the GwtGwtExchangeModule Module.
subroutine, public gwtexchange_create(filename, name, id, m1_id, m2_id, input_mempath)
@ brief Create GWT GWT exchange
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.
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)
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
subroutine, public prt_cr(filename, id, modelname)
Create a new particle tracking model object.
Definition prt.f90:134
This module contains simulation methods.
Definition Sim.f90:10
subroutine, public store_warning(msg, substring)
Store warning message.
Definition Sim.f90:237
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:204
subroutine models_create()
Set the models to be used for the simulation.
subroutine check_model_name(mtype, mname, existing_names)
Check that the model name is valid and unique.
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 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.
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:55
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:103
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_model(model_id, model_name, model)
subroutine, public add_virtual_tsp_exchange(name, exchange_id, m1_id, m2_id, qtype)
Add a virtual GWT-GWT or GWE-GWE exchange to the simulation.
Highest level model type. All models extend this parent type.
Definition BaseModel.f90:16
This class is used to store a single deferred-length character string. It was designed to work in an ...
Base type for models that solve themselves.
A generic heterogeneous doubly-linked list.
Definition List.f90:14