MODFLOW 6  version 6.7.0.dev2
USGS Modular Hydrologic Model
flowmodelinterfacemodule Module Reference

Data Types

type  flowmodelinterfacetype
 

Functions/Subroutines

subroutine fmi_df (this, dis, idryinactive)
 Define the flow model interface. More...
 
subroutine fmi_ar (this, ibound)
 Allocate the package. More...
 
subroutine fmi_da (this)
 Deallocate variables. More...
 
subroutine allocate_scalars (this)
 Allocate scalars. More...
 
subroutine allocate_arrays (this, nodes)
 Allocate arrays. More...
 
subroutine read_options (this)
 Read options from input file. More...
 
subroutine read_packagedata (this)
 Read packagedata block from input file. More...
 
subroutine initialize_bfr (this)
 Initialize the budget file reader. More...
 
subroutine advance_bfr (this)
 Advance the budget file reader. More...
 
subroutine finalize_bfr (this)
 Finalize the budget file reader. More...
 
subroutine initialize_hfr (this)
 Initialize the head file reader. More...
 
subroutine advance_hfr (this)
 Advance the head file reader. More...
 
subroutine finalize_hfr (this)
 Finalize the head file reader. More...
 
subroutine initialize_gwfterms_from_bfr (this)
 Initialize gwf terms from budget file. More...
 
subroutine initialize_gwfterms_from_gwfbndlist (this)
 Initialize gwf terms from a GWF exchange. More...
 
subroutine allocate_gwfpackages (this, ngwfterms)
 Allocate budget packages. More...
 
subroutine deallocate_gwfpackages (this)
 Deallocate memory in the gwfpackages array. More...
 
subroutine get_package_index (this, name, idx)
 Find the package index for the package with the given name. More...
 

Function/Subroutine Documentation

◆ advance_bfr()

subroutine flowmodelinterfacemodule::advance_bfr ( class(flowmodelinterfacetype this)
private

Advance the budget file reader by reading the next chunk of information for the current time step and stress period.

Definition at line 586 of file FlowModelInterface.f90.

587  ! -- modules
588  use tdismodule, only: kstp, kper
589  ! -- dummy
590  class(FlowModelInterfaceType) :: this
591  ! -- local
592  logical :: success
593  integer(I4B) :: n
594  integer(I4B) :: ipos
595  integer(I4B) :: nu, nr
596  integer(I4B) :: ip, i
597  logical :: readnext
598  ! -- format
599  character(len=*), parameter :: fmtkstpkper = &
600  "(1x,/1x,'FMI READING BUDGET TERMS &
601  &FOR KSTP ', i0, ' KPER ', i0)"
602  character(len=*), parameter :: fmtbudkstpkper = &
603  "(1x,/1x, 'FMI SETTING BUDGET TERMS &
604  &FOR KSTP ', i0, ' AND KPER ', &
605  &i0, ' TO BUDGET FILE TERMS FROM &
606  &KSTP ', i0, ' AND KPER ', i0)"
607  !
608  ! -- If the latest record read from the budget file is from a stress
609  ! -- period with only one time step, reuse that record (do not read a
610  ! -- new record) if the running model is still in that same stress period,
611  ! -- or if that record is the last one in the budget file.
612  readnext = .true.
613  if (kstp * kper > 1) then
614  if (this%bfr%kstp == 1) then
615  if (this%bfr%kpernext == kper + 1) then
616  readnext = .false.
617  else if (this%bfr%endoffile) then
618  readnext = .false.
619  end if
620  else if (this%bfr%endoffile) then
621  write (errmsg, '(4x,a)') 'REACHED END OF GWF BUDGET &
622  &FILE BEFORE READING SUFFICIENT BUDGET INFORMATION FOR THIS &
623  &GWT SIMULATION.'
624  call store_error(errmsg)
625  call store_error_unit(this%iubud)
626  end if
627  end if
628  !
629  ! -- Read the next record
630  if (readnext) then
631  !
632  ! -- Write the current time step and stress period
633  write (this%iout, fmtkstpkper) kstp, kper
634  !
635  ! -- loop through the budget terms for this stress period
636  ! i is the counter for gwf flow packages
637  ip = 1
638  do n = 1, this%bfr%nbudterms
639  call this%bfr%read_record(success, this%iout)
640  if (.not. success) then
641  write (errmsg, '(4x,a)') 'GWF BUDGET READ NOT SUCCESSFUL'
642  call store_error(errmsg)
643  call store_error_unit(this%iubud)
644  end if
645  !
646  ! -- Ensure kper is same between model and budget file
647  if (kper /= this%bfr%kper) then
648  write (errmsg, '(4x,a)') 'PERIOD NUMBER IN BUDGET FILE &
649  &DOES NOT MATCH PERIOD NUMBER IN TRANSPORT MODEL. IF THERE &
650  &IS MORE THAN ONE TIME STEP IN THE BUDGET FILE FOR A GIVEN &
651  &STRESS PERIOD, BUDGET FILE TIME STEPS MUST MATCH GWT MODEL &
652  &TIME STEPS ONE-FOR-ONE IN THAT STRESS PERIOD.'
653  call store_error(errmsg)
654  call store_error_unit(this%iubud)
655  end if
656  !
657  ! -- if budget file kstp > 1, then kstp must match
658  if (this%bfr%kstp > 1 .and. (kstp /= this%bfr%kstp)) then
659  write (errmsg, '(4x,a)') 'TIME STEP NUMBER IN BUDGET FILE &
660  &DOES NOT MATCH TIME STEP NUMBER IN TRANSPORT MODEL. IF THERE &
661  &IS MORE THAN ONE TIME STEP IN THE BUDGET FILE FOR A GIVEN STRESS &
662  &PERIOD, BUDGET FILE TIME STEPS MUST MATCH GWT MODEL TIME STEPS &
663  &ONE-FOR-ONE IN THAT STRESS PERIOD.'
664  call store_error(errmsg)
665  call store_error_unit(this%iubud)
666  end if
667  !
668  ! -- parse based on the type of data, and compress all user node
669  ! numbers into reduced node numbers
670  select case (trim(adjustl(this%bfr%budtxt)))
671  case ('FLOW-JA-FACE')
672  !
673  ! -- bfr%flowja contains only reduced connections so there is
674  ! a one-to-one match with this%gwfflowja
675  do ipos = 1, size(this%bfr%flowja)
676  this%gwfflowja(ipos) = this%bfr%flowja(ipos)
677  end do
678  case ('DATA-SPDIS')
679  do i = 1, this%bfr%nlist
680  nu = this%bfr%nodesrc(i)
681  nr = this%dis%get_nodenumber(nu, 0)
682  if (nr <= 0) cycle
683  this%gwfspdis(1, nr) = this%bfr%auxvar(1, i)
684  this%gwfspdis(2, nr) = this%bfr%auxvar(2, i)
685  this%gwfspdis(3, nr) = this%bfr%auxvar(3, i)
686  end do
687  case ('DATA-SAT')
688  do i = 1, this%bfr%nlist
689  nu = this%bfr%nodesrc(i)
690  nr = this%dis%get_nodenumber(nu, 0)
691  if (nr <= 0) cycle
692  this%gwfsat(nr) = this%bfr%auxvar(1, i)
693  end do
694  case ('STO-SS')
695  do nu = 1, this%dis%nodesuser
696  nr = this%dis%get_nodenumber(nu, 0)
697  if (nr <= 0) cycle
698  this%gwfstrgss(nr) = this%bfr%flow(nu)
699  end do
700  case ('STO-SY')
701  do nu = 1, this%dis%nodesuser
702  nr = this%dis%get_nodenumber(nu, 0)
703  if (nr <= 0) cycle
704  this%gwfstrgsy(nr) = this%bfr%flow(nu)
705  end do
706  case default
707  call this%gwfpackages(ip)%copy_values( &
708  this%bfr%nlist, &
709  this%bfr%nodesrc, &
710  this%bfr%flow, &
711  this%bfr%auxvar)
712  do i = 1, this%gwfpackages(ip)%nbound
713  nu = this%gwfpackages(ip)%nodelist(i)
714  nr = this%dis%get_nodenumber(nu, 0)
715  this%gwfpackages(ip)%nodelist(i) = nr
716  end do
717  ip = ip + 1
718  end select
719  end do
720  else
721  !
722  ! -- write message to indicate that flows are being reused
723  write (this%iout, fmtbudkstpkper) kstp, kper, this%bfr%kstp, this%bfr%kper
724  !
725  ! -- set the flag to indicate that flows were not updated
726  this%iflowsupdated = 0
727  end if
integer(i4b), pointer, public kstp
current time step number
Definition: tdis.f90:24
integer(i4b), pointer, public kper
current stress period number
Definition: tdis.f90:23
Here is the call graph for this function:

◆ advance_hfr()

subroutine flowmodelinterfacemodule::advance_hfr ( class(flowmodelinterfacetype this)
private

Definition at line 745 of file FlowModelInterface.f90.

746  ! modules
747  use tdismodule, only: kstp, kper
748  class(FlowModelInterfaceType) :: this
749  integer(I4B) :: nu, nr, i, ilay
750  integer(I4B) :: ncpl
751  real(DP) :: val
752  logical :: readnext
753  logical :: success
754  character(len=*), parameter :: fmtkstpkper = &
755  "(1x,/1x,'FMI READING HEAD FOR &
756  &KSTP ', i0, ' KPER ', i0)"
757  character(len=*), parameter :: fmthdskstpkper = &
758  "(1x,/1x, 'FMI SETTING HEAD FOR KSTP ', i0, ' AND KPER ', &
759  &i0, ' TO BINARY FILE HEADS FROM KSTP ', i0, ' AND KPER ', i0)"
760  !
761  ! -- If the latest record read from the head file is from a stress
762  ! -- period with only one time step, reuse that record (do not read a
763  ! -- new record) if the running model is still in that same stress period,
764  ! -- or if that record is the last one in the head file.
765  readnext = .true.
766  if (kstp * kper > 1) then
767  if (this%hfr%kstp == 1) then
768  if (this%hfr%kpernext == kper + 1) then
769  readnext = .false.
770  else if (this%hfr%endoffile) then
771  readnext = .false.
772  end if
773  else if (this%hfr%endoffile) then
774  write (errmsg, '(4x,a)') 'REACHED END OF GWF HEAD &
775  &FILE BEFORE READING SUFFICIENT HEAD INFORMATION FOR THIS &
776  &GWT SIMULATION.'
777  call store_error(errmsg)
778  call store_error_unit(this%iuhds)
779  end if
780  end if
781  !
782  ! -- Read the next record
783  if (readnext) then
784  !
785  ! -- write to list file that heads are being read
786  write (this%iout, fmtkstpkper) kstp, kper
787  !
788  ! -- loop through the layered heads for this time step
789  do ilay = 1, this%hfr%nlay
790  !
791  ! -- read next head chunk
792  call this%hfr%read_record(success, this%iout)
793  if (.not. success) then
794  write (errmsg, '(4x,a)') 'GWF HEAD READ NOT SUCCESSFUL'
795  call store_error(errmsg)
796  call store_error_unit(this%iuhds)
797  end if
798  !
799  ! -- Ensure kper is same between model and head file
800  if (kper /= this%hfr%kper) then
801  write (errmsg, '(4x,a)') 'PERIOD NUMBER IN HEAD FILE &
802  &DOES NOT MATCH PERIOD NUMBER IN TRANSPORT MODEL. IF THERE &
803  &IS MORE THAN ONE TIME STEP IN THE HEAD FILE FOR A GIVEN STRESS &
804  &PERIOD, HEAD FILE TIME STEPS MUST MATCH GWT MODEL TIME STEPS &
805  &ONE-FOR-ONE IN THAT STRESS PERIOD.'
806  call store_error(errmsg)
807  call store_error_unit(this%iuhds)
808  end if
809  !
810  ! -- if head file kstp > 1, then kstp must match
811  if (this%hfr%kstp > 1 .and. (kstp /= this%hfr%kstp)) then
812  write (errmsg, '(4x,a)') 'TIME STEP NUMBER IN HEAD FILE &
813  &DOES NOT MATCH TIME STEP NUMBER IN TRANSPORT MODEL. IF THERE &
814  &IS MORE THAN ONE TIME STEP IN THE HEAD FILE FOR A GIVEN STRESS &
815  &PERIOD, HEAD FILE TIME STEPS MUST MATCH GWT MODEL TIME STEPS &
816  &ONE-FOR-ONE IN THAT STRESS PERIOD.'
817  call store_error(errmsg)
818  call store_error_unit(this%iuhds)
819  end if
820  !
821  ! -- fill the head array for this layer and
822  ! compress into reduced form
823  ncpl = size(this%hfr%head)
824  do i = 1, ncpl
825  nu = (ilay - 1) * ncpl + i
826  nr = this%dis%get_nodenumber(nu, 0)
827  val = this%hfr%head(i)
828  if (nr > 0) this%gwfhead(nr) = val
829  end do
830  end do
831  else
832  write (this%iout, fmthdskstpkper) kstp, kper, this%hfr%kstp, this%hfr%kper
833  end if
Here is the call graph for this function:

◆ allocate_arrays()

subroutine flowmodelinterfacemodule::allocate_arrays ( class(flowmodelinterfacetype this,
integer(i4b), intent(in)  nodes 
)

Definition at line 235 of file FlowModelInterface.f90.

237  !modules
238  use constantsmodule, only: dzero
239  ! -- dummy
240  class(FlowModelInterfaceType) :: this
241  integer(I4B), intent(in) :: nodes
242  ! -- local
243  integer(I4B) :: n
244  !
245  ! -- Allocate ibdgwfsat0, which is an indicator array marking cells with
246  ! saturation greater than 0.0 with a value of 1
247  call mem_allocate(this%ibdgwfsat0, nodes, 'IBDGWFSAT0', this%memoryPath)
248  do n = 1, nodes
249  this%ibdgwfsat0(n) = 1
250  end do
251  !
252  ! -- Allocate differently depending on whether or not flows are
253  ! being read from a file.
254  if (this%flows_from_file) then
255  call mem_allocate(this%gwfflowja, this%dis%con%nja, &
256  'GWFFLOWJA', this%memoryPath)
257  call mem_allocate(this%gwfsat, nodes, 'GWFSAT', this%memoryPath)
258  call mem_allocate(this%gwfhead, nodes, 'GWFHEAD', this%memoryPath)
259  call mem_allocate(this%gwfspdis, 3, nodes, 'GWFSPDIS', this%memoryPath)
260  do n = 1, nodes
261  this%gwfsat(n) = done
262  this%gwfhead(n) = dzero
263  this%gwfspdis(:, n) = dzero
264  end do
265  do n = 1, size(this%gwfflowja)
266  this%gwfflowja(n) = dzero
267  end do
268  !
269  ! -- allocate and initialize storage arrays
270  if (this%igwfstrgss == 0) then
271  call mem_allocate(this%gwfstrgss, 1, 'GWFSTRGSS', this%memoryPath)
272  else
273  call mem_allocate(this%gwfstrgss, nodes, 'GWFSTRGSS', this%memoryPath)
274  end if
275  if (this%igwfstrgsy == 0) then
276  call mem_allocate(this%gwfstrgsy, 1, 'GWFSTRGSY', this%memoryPath)
277  else
278  call mem_allocate(this%gwfstrgsy, nodes, 'GWFSTRGSY', this%memoryPath)
279  end if
280  do n = 1, size(this%gwfstrgss)
281  this%gwfstrgss(n) = dzero
282  end do
283  do n = 1, size(this%gwfstrgsy)
284  this%gwfstrgsy(n) = dzero
285  end do
286  !
287  ! -- If there is no fmi package, then there are no flows at all or a
288  ! connected GWF model, so allocate gwfpackages to zero
289  if (this%inunit == 0) call this%allocate_gwfpackages(this%nflowpack)
290  end if
This module contains simulation constants.
Definition: Constants.f90:9
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:65

◆ allocate_gwfpackages()

subroutine flowmodelinterfacemodule::allocate_gwfpackages ( class(flowmodelinterfacetype this,
integer(i4b), intent(in)  ngwfterms 
)

gwfpackages is an array of PackageBudget objects. This routine allocates gwfpackages to the proper size and initializes some member variables.

Definition at line 1010 of file FlowModelInterface.f90.

1011  ! -- modules
1012  use constantsmodule, only: lenmempath
1014  ! -- dummy
1015  class(FlowModelInterfaceType) :: this
1016  integer(I4B), intent(in) :: ngwfterms
1017  ! -- local
1018  integer(I4B) :: n
1019  character(len=LENMEMPATH) :: memPath
1020  !
1021  ! -- direct allocate
1022  allocate (this%gwfpackages(ngwfterms))
1023  allocate (this%flowpacknamearray(ngwfterms))
1024  !
1025  ! -- mem_allocate
1026  call mem_allocate(this%igwfmvrterm, ngwfterms, 'IGWFMVRTERM', this%memoryPath)
1027  !
1028  ! -- initialize
1029  this%nflowpack = ngwfterms
1030  do n = 1, this%nflowpack
1031  this%igwfmvrterm(n) = 0
1032  this%flowpacknamearray(n) = ''
1033  !
1034  ! -- Create a mempath for each individual flow package data set
1035  ! of the form, MODELNAME/FMI-FTn
1036  write (mempath, '(a, i0)') trim(this%memoryPath)//'-FT', n
1037  call this%gwfpackages(n)%initialize(mempath)
1038  end do
integer(i4b), parameter lenmempath
maximum length of the memory path
Definition: Constants.f90:27

◆ allocate_scalars()

subroutine flowmodelinterfacemodule::allocate_scalars ( class(flowmodelinterfacetype this)

Definition at line 197 of file FlowModelInterface.f90.

198  ! -- modules
200  ! -- dummy
201  class(FlowModelInterfaceType) :: this
202  ! -- local
203  !
204  ! -- allocate scalars in NumericalPackageType
205  call this%NumericalPackageType%allocate_scalars()
206  !
207  ! -- Allocate
208  call mem_allocate(this%flows_from_file, 'FLOWS_FROM_FILE', this%memoryPath)
209  call mem_allocate(this%iflowsupdated, 'IFLOWSUPDATED', this%memoryPath)
210  call mem_allocate(this%igwfstrgss, 'IGWFSTRGSS', this%memoryPath)
211  call mem_allocate(this%igwfstrgsy, 'IGWFSTRGSY', this%memoryPath)
212  call mem_allocate(this%iubud, 'IUBUD', this%memoryPath)
213  call mem_allocate(this%iuhds, 'IUHDS', this%memoryPath)
214  call mem_allocate(this%iumvr, 'IUMVR', this%memoryPath)
215  call mem_allocate(this%iugrb, 'IUGRB', this%memoryPath)
216  call mem_allocate(this%nflowpack, 'NFLOWPACK', this%memoryPath)
217  call mem_allocate(this%idryinactive, "IDRYINACTIVE", this%memoryPath)
218  !
219  ! !
220  ! -- Initialize
221  this%flows_from_file = .true.
222  this%iflowsupdated = 1
223  this%igwfstrgss = 0
224  this%igwfstrgsy = 0
225  this%iubud = 0
226  this%iuhds = 0
227  this%iumvr = 0
228  this%iugrb = 0
229  this%nflowpack = 0
230  this%idryinactive = 1

◆ deallocate_gwfpackages()

subroutine flowmodelinterfacemodule::deallocate_gwfpackages ( class(flowmodelinterfacetype this)

Definition at line 1042 of file FlowModelInterface.f90.

1043  class(FlowModelInterfaceType) :: this
1044  integer(I4B) :: n
1045 
1046  do n = 1, this%nflowpack
1047  call this%gwfpackages(n)%da()
1048  end do

◆ finalize_bfr()

subroutine flowmodelinterfacemodule::finalize_bfr ( class(flowmodelinterfacetype this)

Definition at line 731 of file FlowModelInterface.f90.

732  class(FlowModelInterfaceType) :: this
733  call this%bfr%finalize()

◆ finalize_hfr()

subroutine flowmodelinterfacemodule::finalize_hfr ( class(flowmodelinterfacetype this)

Definition at line 837 of file FlowModelInterface.f90.

838  class(FlowModelInterfaceType) :: this
839  close (this%iuhds)

◆ fmi_ar()

subroutine flowmodelinterfacemodule::fmi_ar ( class(flowmodelinterfacetype this,
integer(i4b), dimension(:), pointer, contiguous  ibound 
)

Definition at line 136 of file FlowModelInterface.f90.

137  ! -- modules
138  use simmodule, only: store_error
139  ! -- dummy
140  class(FlowModelInterfaceType) :: this
141  integer(I4B), dimension(:), pointer, contiguous :: ibound
142  !
143  ! -- store pointers to arguments that were passed in
144  this%ibound => ibound
145  !
146  ! -- Allocate arrays
147  call this%allocate_arrays(this%dis%nodes)
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public store_error(msg, terminate)
Store an error message.
Definition: Sim.f90:92
Here is the call graph for this function:

◆ fmi_da()

subroutine flowmodelinterfacemodule::fmi_da ( class(flowmodelinterfacetype this)

Definition at line 152 of file FlowModelInterface.f90.

153  ! -- modules
155  ! -- dummy
156  class(FlowModelInterfaceType) :: this
157  ! -- todo: finalize hfr and bfr either here or in a finalize routine
158  !
159  ! -- deallocate any memory stored with gwfpackages
160  call this%deallocate_gwfpackages()
161  !
162  ! -- deallocate fmi arrays
163  deallocate (this%gwfpackages)
164  deallocate (this%flowpacknamearray)
165  call mem_deallocate(this%igwfmvrterm)
166  call mem_deallocate(this%ibdgwfsat0)
167  !
168  if (this%flows_from_file) then
169  call mem_deallocate(this%gwfstrgss)
170  call mem_deallocate(this%gwfstrgsy)
171  end if
172  !
173  ! -- special treatment, these could be from mem_checkin
174  call mem_deallocate(this%gwfhead, 'GWFHEAD', this%memoryPath)
175  call mem_deallocate(this%gwfsat, 'GWFSAT', this%memoryPath)
176  call mem_deallocate(this%gwfspdis, 'GWFSPDIS', this%memoryPath)
177  call mem_deallocate(this%gwfflowja, 'GWFFLOWJA', this%memoryPath)
178  !
179  ! -- deallocate scalars
180  call mem_deallocate(this%flows_from_file)
181  call mem_deallocate(this%iflowsupdated)
182  call mem_deallocate(this%igwfstrgss)
183  call mem_deallocate(this%igwfstrgsy)
184  call mem_deallocate(this%iubud)
185  call mem_deallocate(this%iuhds)
186  call mem_deallocate(this%iumvr)
187  call mem_deallocate(this%iugrb)
188  call mem_deallocate(this%nflowpack)
189  call mem_deallocate(this%idryinactive)
190  !
191  ! -- deallocate parent
192  call this%NumericalPackageType%da()

◆ fmi_df()

subroutine flowmodelinterfacemodule::fmi_df ( class(flowmodelinterfacetype this,
class(disbasetype), intent(in), pointer  dis,
integer(i4b), intent(in)  idryinactive 
)
private

Definition at line 79 of file FlowModelInterface.f90.

80  ! -- modules
81  use simmodule, only: store_error
82  ! -- dummy
83  class(FlowModelInterfaceType) :: this
84  class(DisBaseType), pointer, intent(in) :: dis
85  integer(I4B), intent(in) :: idryinactive
86  ! -- formats
87  character(len=*), parameter :: fmtfmi = &
88  "(1x,/1x,'FMI -- FLOW MODEL INTERFACE, VERSION 2, 8/17/2023', &
89  &' INPUT READ FROM UNIT ', i0, //)"
90  character(len=*), parameter :: fmtfmi0 = &
91  "(1x,/1x,'FMI -- FLOW MODEL INTERFACE,'&
92  &' VERSION 2, 8/17/2023')"
93  !
94  ! --print a message identifying the FMI package.
95  if (this%iout > 0) then
96  if (this%inunit /= 0) then
97  write (this%iout, fmtfmi) this%inunit
98  else
99  write (this%iout, fmtfmi0)
100  if (this%flows_from_file) then
101  write (this%iout, '(a)') ' FLOWS ARE ASSUMED TO BE ZERO.'
102  else
103  write (this%iout, '(a)') ' FLOWS PROVIDED BY A GWF MODEL IN THIS &
104  &SIMULATION'
105  end if
106  end if
107  end if
108  !
109  ! -- Store pointers
110  this%dis => dis
111  !
112  ! -- Read fmi options
113  if (this%inunit /= 0) then
114  call this%read_options()
115  end if
116  !
117  ! -- Read packagedata options
118  if (this%inunit /= 0 .and. this%flows_from_file) then
119  call this%read_packagedata()
120  call this%initialize_gwfterms_from_bfr()
121  end if
122  !
123  ! -- If GWF-Model exchange is active, setup flow terms
124  if (.not. this%flows_from_file) then
125  call this%initialize_gwfterms_from_gwfbndlist()
126  end if
127  !
128  ! -- Set flag that stops dry flows from being deactivated in a GWE
129  ! transport model since conduction will still be simulated.
130  ! 0: GWE (skip deactivation step); 1: GWT (default: use existing code)
131  this%idryinactive = idryinactive
Here is the call graph for this function:

◆ get_package_index()

subroutine flowmodelinterfacemodule::get_package_index ( class(flowmodelinterfacetype this,
character(len=*), intent(in)  name,
integer(i4b), intent(inout)  idx 
)
private

Definition at line 1052 of file FlowModelInterface.f90.

1053  use bndmodule, only: bndtype, getbndfromlist
1054  class(FlowModelInterfaceType) :: this
1055  character(len=*), intent(in) :: name
1056  integer(I4B), intent(inout) :: idx
1057  ! -- local
1058  integer(I4B) :: ip
1059  !
1060  ! -- Look through all the packages and return the index with name
1061  idx = 0
1062  do ip = 1, size(this%flowpacknamearray)
1063  if (this%flowpacknamearray(ip) == name) then
1064  idx = ip
1065  exit
1066  end if
1067  end do
1068  if (idx == 0) then
1069  call store_error('Error in get_package_index. Could not find '//name, &
1070  terminate=.true.)
1071  end if
This module contains the base boundary package.
class(bndtype) function, pointer, public getbndfromlist(list, idx)
Get boundary from package list.
@ brief BndType
Here is the call graph for this function:

◆ initialize_bfr()

subroutine flowmodelinterfacemodule::initialize_bfr ( class(flowmodelinterfacetype this)

Definition at line 573 of file FlowModelInterface.f90.

574  class(FlowModelInterfaceType) :: this
575  integer(I4B) :: ncrbud
576  call this%bfr%initialize(this%iubud, this%iout, ncrbud)
577  ! todo: need to run through the budget terms
578  ! and do some checking

◆ initialize_gwfterms_from_bfr()

subroutine flowmodelinterfacemodule::initialize_gwfterms_from_bfr ( class(flowmodelinterfacetype this)
private

initialize terms and figure out how many different terms and packages are contained within the file

Definition at line 847 of file FlowModelInterface.f90.

848  ! -- modules
851  ! -- dummy
852  class(FlowModelInterfaceType) :: this
853  ! -- local
854  integer(I4B) :: nflowpack
855  integer(I4B) :: i, ip
856  integer(I4B) :: naux
857  logical :: found_flowja
858  logical :: found_dataspdis
859  logical :: found_datasat
860  logical :: found_stoss
861  logical :: found_stosy
862  integer(I4B), dimension(:), allocatable :: imap
863  !
864  ! -- Calculate the number of gwf flow packages
865  allocate (imap(this%bfr%nbudterms))
866  imap(:) = 0
867  nflowpack = 0
868  found_flowja = .false.
869  found_dataspdis = .false.
870  found_datasat = .false.
871  found_stoss = .false.
872  found_stosy = .false.
873  do i = 1, this%bfr%nbudterms
874  select case (trim(adjustl(this%bfr%budtxtarray(i))))
875  case ('FLOW-JA-FACE')
876  found_flowja = .true.
877  case ('DATA-SPDIS')
878  found_dataspdis = .true.
879  case ('DATA-SAT')
880  found_datasat = .true.
881  case ('STO-SS')
882  found_stoss = .true.
883  this%igwfstrgss = 1
884  case ('STO-SY')
885  found_stosy = .true.
886  this%igwfstrgsy = 1
887  case default
888  nflowpack = nflowpack + 1
889  imap(i) = 1
890  end select
891  end do
892  !
893  ! -- allocate gwfpackage arrays
894  call this%allocate_gwfpackages(nflowpack)
895  !
896  ! -- Copy the package name and aux names from budget file reader
897  ! to the gwfpackages derived-type variable
898  ip = 1
899  do i = 1, this%bfr%nbudterms
900  if (imap(i) == 0) cycle
901  call this%gwfpackages(ip)%set_name(this%bfr%dstpackagenamearray(i), &
902  this%bfr%budtxtarray(i))
903  naux = this%bfr%nauxarray(i)
904  call this%gwfpackages(ip)%set_auxname(naux, this%bfr%auxtxtarray(1:naux, i))
905  ip = ip + 1
906  end do
907  !
908  ! -- Copy just the package names for the boundary packages into
909  ! the flowpacknamearray
910  ip = 1
911  do i = 1, size(imap)
912  if (imap(i) == 1) then
913  this%flowpacknamearray(ip) = this%bfr%dstpackagenamearray(i)
914  ip = ip + 1
915  end if
916  end do
917  !
918  ! -- Error if specific discharge, saturation or flowja not found
919  if (.not. found_dataspdis) then
920  write (errmsg, '(4x,a)') 'SPECIFIC DISCHARGE NOT FOUND IN &
921  &BUDGET FILE. SAVE_SPECIFIC_DISCHARGE AND &
922  &SAVE_FLOWS MUST BE ACTIVATED IN THE NPF PACKAGE.'
923  call store_error(errmsg)
924  end if
925  if (.not. found_datasat) then
926  write (errmsg, '(4x,a)') 'SATURATION NOT FOUND IN &
927  &BUDGET FILE. SAVE_SATURATION AND &
928  &SAVE_FLOWS MUST BE ACTIVATED IN THE NPF PACKAGE.'
929  call store_error(errmsg)
930  end if
931  if (.not. found_flowja) then
932  write (errmsg, '(4x,a)') 'FLOWJA NOT FOUND IN &
933  &BUDGET FILE. SAVE_FLOWS MUST &
934  &BE ACTIVATED IN THE NPF PACKAGE.'
935  call store_error(errmsg)
936  end if
937  if (count_errors() > 0) then
938  call this%parser%StoreErrorUnit()
939  end if
integer(i4b) function, public count_errors()
Return number of errors.
Definition: Sim.f90:59
subroutine, public store_error_unit(iunit, terminate)
Store the file unit number.
Definition: Sim.f90:168
Here is the call graph for this function:

◆ initialize_gwfterms_from_gwfbndlist()

subroutine flowmodelinterfacemodule::initialize_gwfterms_from_gwfbndlist ( class(flowmodelinterfacetype this)

Definition at line 943 of file FlowModelInterface.f90.

944  ! -- modules
945  use bndmodule, only: bndtype, getbndfromlist
946  ! -- dummy
947  class(FlowModelInterfaceType) :: this
948  ! -- local
949  integer(I4B) :: ngwfpack
950  integer(I4B) :: ngwfterms
951  integer(I4B) :: ip
952  integer(I4B) :: imover
953  integer(I4B) :: ntomvr
954  integer(I4B) :: iterm
955  character(len=LENPACKAGENAME) :: budtxt
956  class(BndType), pointer :: packobj => null()
957  !
958  ! -- determine size of gwf terms
959  ngwfpack = this%gwfbndlist%Count()
960  !
961  ! -- Count number of to-mvr terms, but do not include advanced packages
962  ! as those mover terms are not losses from the cell, but rather flows
963  ! within the advanced package
964  ntomvr = 0
965  do ip = 1, ngwfpack
966  packobj => getbndfromlist(this%gwfbndlist, ip)
967  imover = packobj%imover
968  if (packobj%isadvpak /= 0) imover = 0
969  if (imover /= 0) then
970  ntomvr = ntomvr + 1
971  end if
972  end do
973  !
974  ! -- Allocate arrays in fmi of size ngwfterms, which is the number of
975  ! packages plus the number of packages with mover terms.
976  ngwfterms = ngwfpack + ntomvr
977  call this%allocate_gwfpackages(ngwfterms)
978  !
979  ! -- Assign values in the fmi package
980  iterm = 1
981  do ip = 1, ngwfpack
982  !
983  ! -- set and store names
984  packobj => getbndfromlist(this%gwfbndlist, ip)
985  budtxt = adjustl(packobj%text)
986  call this%gwfpackages(iterm)%set_name(packobj%packName, budtxt)
987  this%flowpacknamearray(iterm) = packobj%packName
988  iterm = iterm + 1
989  !
990  ! -- if this package has a mover associated with it, then add another
991  ! term that corresponds to the mover flows
992  imover = packobj%imover
993  if (packobj%isadvpak /= 0) imover = 0
994  if (imover /= 0) then
995  budtxt = trim(adjustl(packobj%text))//'-TO-MVR'
996  call this%gwfpackages(iterm)%set_name(packobj%packName, budtxt)
997  this%flowpacknamearray(iterm) = packobj%packName
998  this%igwfmvrterm(iterm) = 1
999  iterm = iterm + 1
1000  end if
1001  end do
Here is the call graph for this function:

◆ initialize_hfr()

subroutine flowmodelinterfacemodule::initialize_hfr ( class(flowmodelinterfacetype this)
private

Definition at line 737 of file FlowModelInterface.f90.

738  class(FlowModelInterfaceType) :: this
739  call this%hfr%initialize(this%iuhds, this%iout)
740  ! todo: need to run through the head terms
741  ! and do some checking

◆ read_options()

subroutine flowmodelinterfacemodule::read_options ( class(flowmodelinterfacetype this)

Definition at line 295 of file FlowModelInterface.f90.

296  ! -- modules
297  use constantsmodule, only: linelength, dem6
300  ! -- dummy
301  class(FlowModelInterfaceType) :: this
302  ! -- local
303  character(len=LINELENGTH) :: keyword
304  integer(I4B) :: ierr
305  logical :: isfound, endOfBlock
306  !
307  ! -- get options block
308  call this%parser%GetBlock('OPTIONS', isfound, ierr, blockrequired=.false., &
309  supportopenclose=.true.)
310  !
311  ! -- parse options block if detected
312  if (isfound) then
313  write (this%iout, '(1x,a)') 'PROCESSING FMI OPTIONS'
314  do
315  call this%parser%GetNextLine(endofblock)
316  if (endofblock) exit
317  call this%parser%GetStringCaps(keyword)
318  select case (keyword)
319  case ('SAVE_FLOWS')
320  this%ipakcb = -1
321  case default
322  write (errmsg, '(a,3(1x,a))') &
323  'UNKNOWN', trim(adjustl(this%text)), 'OPTION:', trim(keyword)
324  call store_error(errmsg)
325  call this%parser%StoreErrorUnit()
326  end select
327  end do
328  write (this%iout, '(1x,a)') 'END OF FMI OPTIONS'
329  end if
integer(i4b), parameter linelength
maximum length of a standard line
Definition: Constants.f90:45
real(dp), parameter dem6
real constant 1e-6
Definition: Constants.f90:109
subroutine, public urdaux(naux, inunit, iout, lloc, istart, istop, auxname, line, text)
Read auxiliary variables from an input line.
integer(i4b) function, public getunit()
Get a free unit number.
subroutine, public openfile(iu, iout, fname, ftype, fmtarg_opt, accarg_opt, filstat_opt, mode_opt)
Open a file.
Definition: InputOutput.f90:30
Here is the call graph for this function:

◆ read_packagedata()

subroutine flowmodelinterfacemodule::read_packagedata ( class(flowmodelinterfacetype this)

Definition at line 334 of file FlowModelInterface.f90.

335  ! -- modules
336  use openspecmodule, only: access, form
340  use dismodule, only: distype
341  use disvmodule, only: disvtype
342  use disumodule, only: disutype
343  use dis2dmodule, only: dis2dtype
344  use disv2dmodule, only: disv2dtype
345  use disv1dmodule, only: disv1dtype
346  ! -- dummy
347  class(FlowModelInterfaceType) :: this
348  ! -- local
349  character(len=LINELENGTH) :: keyword, fname
350  integer(I4B) :: ierr
351  integer(I4B) :: inunit
352  integer(I4B) :: iapt
353  integer(I4B) :: user_nodes
354  logical :: isfound, endOfBlock
355  logical :: blockrequired
356  logical :: exist
357  integer(I4B), allocatable :: idomain1d(:), idomain2d(:, :), idomain3d(:, :, :)
358  ! -- formats
359  character(len=*), parameter :: fmtdiserr = &
360  "('Error in ',a,': Models do not have the same discretization. &
361  &GWF model has ', i0, ' user nodes, this model has ', i0, '. &
362  &Ensure discretization packages, including IDOMAIN, are identical.')"
363  character(len=*), parameter :: fmtidomerr = &
364  "('Error in ',a,': models do not have the same discretization. &
365  &Models have different IDOMAIN arrays. &
366  &Ensure discretization packages, including IDOMAIN, are identical.')"
367  !
368  ! -- initialize
369  iapt = 0
370  blockrequired = .true.
371  !
372  ! -- get packagedata block
373  call this%parser%GetBlock('PACKAGEDATA', isfound, ierr, &
374  blockrequired=blockrequired, &
375  supportopenclose=.true.)
376  !
377  ! -- parse packagedata block if detected
378  if (isfound) then
379  write (this%iout, '(1x,a)') 'PROCESSING FMI PACKAGEDATA'
380  do
381  call this%parser%GetNextLine(endofblock)
382  if (endofblock) exit
383  call this%parser%GetStringCaps(keyword)
384  select case (keyword)
385  case ('GWFBUDGET')
386  call this%parser%GetStringCaps(keyword)
387  if (keyword /= 'FILEIN') then
388  call store_error('GWFBUDGET KEYWORD MUST BE FOLLOWED BY '// &
389  '"FILEIN" then by filename.')
390  call this%parser%StoreErrorUnit()
391  end if
392  call this%parser%GetString(fname)
393  inunit = getunit()
394  inquire (file=trim(fname), exist=exist)
395  if (.not. exist) then
396  call store_error('Could not find file '//trim(fname))
397  call this%parser%StoreErrorUnit()
398  end if
399  call openfile(inunit, this%iout, fname, 'DATA(BINARY)', form, &
400  access, 'UNKNOWN')
401  this%iubud = inunit
402  call this%initialize_bfr()
403  case ('GWFHEAD')
404  call this%parser%GetStringCaps(keyword)
405  if (keyword /= 'FILEIN') then
406  call store_error('GWFHEAD KEYWORD MUST BE FOLLOWED BY '// &
407  '"FILEIN" then by filename.')
408  call this%parser%StoreErrorUnit()
409  end if
410  call this%parser%GetString(fname)
411  inquire (file=trim(fname), exist=exist)
412  if (.not. exist) then
413  call store_error('Could not find file '//trim(fname))
414  call this%parser%StoreErrorUnit()
415  end if
416  inunit = getunit()
417  call openfile(inunit, this%iout, fname, 'DATA(BINARY)', form, &
418  access, 'UNKNOWN')
419  this%iuhds = inunit
420  call this%initialize_hfr()
421  case ('GWFMOVER')
422  call this%parser%GetStringCaps(keyword)
423  if (keyword /= 'FILEIN') then
424  call store_error('GWFMOVER KEYWORD MUST BE FOLLOWED BY '// &
425  '"FILEIN" then by filename.')
426  call this%parser%StoreErrorUnit()
427  end if
428  call this%parser%GetString(fname)
429  inunit = getunit()
430  call openfile(inunit, this%iout, fname, 'DATA(BINARY)', form, &
431  access, 'UNKNOWN')
432  this%iumvr = inunit
433  call budgetobject_cr_bfr(this%mvrbudobj, 'MVT', this%iumvr, &
434  this%iout)
435  call this%mvrbudobj%fill_from_bfr(this%dis, this%iout)
436  case ('GWFGRID')
437  call this%parser%GetStringCaps(keyword)
438  if (keyword /= 'FILEIN') then
439  call store_error('GWFGRID KEYWORD MUST BE FOLLOWED BY '// &
440  '"FILEIN" then by filename.')
441  call this%parser%StoreErrorUnit()
442  end if
443  call this%parser%GetString(fname)
444  inunit = getunit()
445  call openfile(inunit, this%iout, fname, 'DATA(BINARY)', &
446  form, access, 'UNKNOWN')
447  this%iugrb = inunit
448  call this%gfr%initialize(this%iugrb)
449 
450  ! check grid equivalence
451  select case (this%gfr%grid_type)
452  case ('DIS')
453  select type (dis => this%dis)
454  type is (distype)
455  user_nodes = this%gfr%read_int("NCELLS")
456  if (user_nodes /= this%dis%nodesuser) then
457  write (errmsg, fmtdiserr) &
458  trim(this%text), user_nodes, this%dis%nodesuser
459  call store_error(errmsg, terminate=.true.)
460  end if
461  idomain1d = this%gfr%read_int_1d("IDOMAIN")
462  idomain3d = reshape(idomain1d, [ &
463  this%gfr%read_int("NCOL"), &
464  this%gfr%read_int("NROW"), &
465  this%gfr%read_int("NLAY") &
466  ])
467  if (.not. all(dis%idomain == idomain3d)) then
468  write (errmsg, fmtidomerr) trim(this%text)
469  call store_error(errmsg, terminate=.true.)
470  end if
471  end select
472  case ('DISV')
473  select type (dis => this%dis)
474  type is (disvtype)
475  user_nodes = this%gfr%read_int("NCELLS")
476  if (user_nodes /= this%dis%nodesuser) then
477  write (errmsg, fmtdiserr) &
478  trim(this%text), user_nodes, this%dis%nodesuser
479  call store_error(errmsg, terminate=.true.)
480  end if
481  idomain1d = this%gfr%read_int_1d("IDOMAIN")
482  idomain2d = reshape(idomain1d, [ &
483  this%gfr%read_int("NCPL"), &
484  this%gfr%read_int("NLAY") &
485  ])
486  if (.not. all(dis%idomain == idomain2d)) then
487  write (errmsg, fmtidomerr) trim(this%text)
488  call store_error(errmsg, terminate=.true.)
489  end if
490  end select
491  case ('DISU')
492  select type (dis => this%dis)
493  type is (disutype)
494  user_nodes = this%gfr%read_int("NODES")
495  if (user_nodes /= this%dis%nodesuser) then
496  write (errmsg, fmtdiserr) &
497  trim(this%text), user_nodes, this%dis%nodesuser
498  call store_error(errmsg, terminate=.true.)
499  end if
500  idomain1d = this%gfr%read_int_1d("IDOMAIN")
501  if (.not. all(dis%idomain == idomain1d)) then
502  write (errmsg, fmtidomerr) trim(this%text)
503  call store_error(errmsg, terminate=.true.)
504  end if
505  end select
506  case ('DIS2D')
507  select type (dis => this%dis)
508  type is (dis2dtype)
509  user_nodes = this%gfr%read_int("NCELLS")
510  if (user_nodes /= this%dis%nodesuser) then
511  write (errmsg, fmtdiserr) &
512  trim(this%text), user_nodes, this%dis%nodesuser
513  call store_error(errmsg, terminate=.true.)
514  end if
515  idomain1d = this%gfr%read_int_1d("IDOMAIN")
516  idomain2d = reshape(idomain1d, [ &
517  this%gfr%read_int("NCOL"), &
518  this%gfr%read_int("NROW") &
519  ])
520  if (.not. all(dis%idomain == idomain2d)) then
521  write (errmsg, fmtidomerr) trim(this%text)
522  call store_error(errmsg, terminate=.true.)
523  end if
524  end select
525  case ('DISV2D')
526  select type (dis => this%dis)
527  type is (disv2dtype)
528  user_nodes = this%gfr%read_int("NODES")
529  if (user_nodes /= this%dis%nodesuser) then
530  write (errmsg, fmtdiserr) &
531  trim(this%text), user_nodes, this%dis%nodesuser
532  call store_error(errmsg, terminate=.true.)
533  end if
534  idomain1d = this%gfr%read_int_1d("IDOMAIN")
535  if (.not. all(dis%idomain == idomain1d)) then
536  write (errmsg, fmtidomerr) trim(this%text)
537  call store_error(errmsg, terminate=.true.)
538  end if
539  end select
540  case ('DISV1D')
541  select type (dis => this%dis)
542  type is (disv1dtype)
543  user_nodes = this%gfr%read_int("NCELLS")
544  if (user_nodes /= this%dis%nodesuser) then
545  write (errmsg, fmtdiserr) &
546  trim(this%text), user_nodes, this%dis%nodesuser
547  call store_error(errmsg, terminate=.true.)
548  end if
549  idomain1d = this%gfr%read_int_1d("IDOMAIN")
550  if (.not. all(dis%idomain == idomain1d)) then
551  write (errmsg, fmtidomerr) trim(this%text)
552  call store_error(errmsg, terminate=.true.)
553  end if
554  end select
555  end select
556 
557  if (allocated(idomain3d)) deallocate (idomain3d)
558  if (allocated(idomain2d)) deallocate (idomain2d)
559  if (allocated(idomain1d)) deallocate (idomain1d)
560 
561  call this%gfr%finalize()
562  case default
563  write (errmsg, '(a,3(1x,a))') &
564  'UNKNOWN', trim(adjustl(this%text)), 'PACKAGEDATA:', trim(keyword)
565  call store_error(errmsg)
566  end select
567  end do
568  write (this%iout, '(1x,a)') 'END OF FMI PACKAGEDATA'
569  end if
integer(i4b), parameter lenpackagename
maximum length of the package name
Definition: Constants.f90:23
Definition: Dis.f90:1
character(len=20) access
Definition: OpenSpec.f90:7
character(len=20) form
Definition: OpenSpec.f90:7
Structured grid discretization.
Definition: Dis2d.f90:23
Structured grid discretization.
Definition: Dis.f90:23
Unstructured grid discretization.
Definition: Disu.f90:28
Vertex grid discretization.
Definition: Disv2d.f90:24
Vertex grid discretization.
Definition: Disv.f90:24
Here is the call graph for this function: