init_subsurface_flow.F90 coverage: 100.00 %func 73.02 %block
1) module Init_Subsurface_Flow_module
2)
3) use PFLOTRAN_Constants_module
4)
5) implicit none
6)
7) private
8)
9) #include "petsc/finclude/petscsys.h"
10)
11) public :: InitSubsurfFlowSetupRealization, &
12) InitSubsurfFlowSetupSolvers
13)
14) contains
15)
16) ! ************************************************************************** !
17)
18) subroutine InitSubsurfFlowSetupRealization(realization)
19) !
20) ! Initializes material property data structres and assign them to the domain.
21) !
22) ! Author: Glenn Hammond
23) ! Date: 12/04/14
24) !
25) use Realization_Subsurface_class
26) use Patch_module
27) use Option_module
28) use Init_Common_module
29) use Material_module
30)
31) use Flash2_module
32) use Mphase_module
33) use Immis_module
34) use Miscible_module
35) use Richards_module
36) use TH_module
37) use General_module
38) use TOilIms_module
39) use Condition_Control_module
40) use co2_sw_module, only : init_span_wagner
41)
42) implicit none
43)
44) class(realization_subsurface_type) :: realization
45)
46) type(option_type), pointer :: option
47) type(patch_type), pointer :: patch
48) PetscErrorCode :: ierr
49)
50) option => realization%option
51) patch => realization%patch
52)
53) ! initialize FLOW
54) ! set up auxillary variable arrays
55) if (option%nflowdof > 0) then
56) select case(option%iflowmode)
57) case(TH_MODE)
58) call THSetup(realization)
59) case(RICHARDS_MODE)
60) call MaterialSetup(realization%patch%aux%Material%material_parameter, &
61) patch%material_property_array, &
62) patch%characteristic_curves_array, &
63) realization%option)
64) call RichardsSetup(realization)
65) case(MPH_MODE)
66) call init_span_wagner(option)
67) call MphaseSetup(realization)
68) case(IMS_MODE)
69) call init_span_wagner(option)
70) call ImmisSetup(realization)
71) case(MIS_MODE)
72) call MiscibleSetup(realization)
73) case(FLASH2_MODE)
74) call init_span_wagner(option)
75) call Flash2Setup(realization)
76) case(G_MODE)
77) call MaterialSetup(realization%patch%aux%Material%material_parameter, &
78) patch%material_property_array, &
79) patch%characteristic_curves_array, &
80) realization%option)
81) call GeneralSetup(realization)
82) case(TOIL_IMS_MODE)
83) call MaterialSetup(realization%patch%aux%Material%material_parameter, &
84) patch%material_property_array, &
85) patch%characteristic_curves_array, &
86) realization%option)
87) call TOilImsSetup(realization)
88) end select
89)
90) ! assign initial conditionsRealizAssignFlowInitCond
91) call CondControlAssignFlowInitCond(realization)
92)
93) ! override initial conditions if they are to be read from a file
94) if (len_trim(option%initialize_flow_filename) > 1) then
95) call InitSubsurfFlowReadInitCond(realization, &
96) option%initialize_flow_filename)
97) endif
98)
99) select case(option%iflowmode)
100) case(TH_MODE)
101) call THUpdateAuxVars(realization)
102) case(RICHARDS_MODE)
103) call RichardsUpdateAuxVars(realization)
104) case(MPH_MODE)
105) call MphaseUpdateAuxVars(realization)
106) case(IMS_MODE)
107) call ImmisUpdateAuxVars(realization)
108) case(MIS_MODE)
109) call MiscibleUpdateAuxVars(realization)
110) case(FLASH2_MODE)
111) call Flash2UpdateAuxVars(realization)
112) case(G_MODE)
113) !geh: cannot update state during initialization as the guess will be
114) ! assigned as the initial conditin if the state changes. therefore,
115) ! pass in PETSC_FALSE
116) call GeneralUpdateAuxVars(realization,PETSC_FALSE)
117) case(TOIL_IMS_MODE)
118) call TOilImsUpdateAuxVars(realization)
119) end select
120) else ! no flow mode specified
121) if (len_trim(realization%nonuniform_velocity_filename) > 0) then
122) #if defined(PETSC_HAVE_HDF5)
123) call InitCommonReadVelocityField(realization)
124) #else
125) write(option%io_buffer,'("PFLOTRAN must be compiled with HDF5 to ", &
126) &"read HDF5 formatted fluxes in for transport with no flow.")')
127) call printErrMsg(option)
128) #endif
129) endif
130) endif
131)
132) end subroutine InitSubsurfFlowSetupRealization
133)
134) ! ************************************************************************** !
135)
136) subroutine InitSubsurfFlowSetupSolvers(realization,convergence_context,solver)
137) !
138) ! Initializes material property data structres and assign them to the domain.
139) !
140) ! Author: Glenn Hammond
141) ! Date: 12/04/14
142) !
143) use Realization_Subsurface_class
144) use Option_module
145) use Init_Common_module
146)
147) use Flash2_module
148) use Mphase_module
149) use Immis_module
150) use Miscible_module
151) use Richards_module
152) use TH_module
153) use General_module
154) use Solver_module
155) use Convergence_module
156) use Discretization_module
157)
158) implicit none
159)
160) #include "petsc/finclude/petscvec.h"
161) #include "petsc/finclude/petscvec.h90"
162) #include "petsc/finclude/petscmat.h"
163) #include "petsc/finclude/petscmat.h90"
164) #include "petsc/finclude/petscsnes.h"
165) #include "petsc/finclude/petscpc.h"
166)
167) class(realization_subsurface_type) :: realization
168) type(convergence_context_type), pointer :: convergence_context
169) type(solver_type), pointer :: solver
170)
171) type(option_type), pointer :: option
172) SNESLineSearch :: linesearch
173) character(len=MAXSTRINGLENGTH) :: string
174) PetscErrorCode :: ierr
175)
176) option => realization%option
177)
178) call printMsg(option," Beginning setup of FLOW SNES ")
179)
180) if (solver%J_mat_type == MATAIJ) then
181) select case(option%iflowmode)
182) case(MPH_MODE,TH_MODE,IMS_MODE, FLASH2_MODE, G_MODE, MIS_MODE)
183) option%io_buffer = 'AIJ matrix not supported for current mode: '// &
184) option%flowmode
185) call printErrMsg(option)
186) end select
187) endif
188)
189) if (OptionPrintToScreen(option)) then
190) write(*,'(" number of dofs = ",i3,", number of phases = ",i3,i2)') &
191) option%nflowdof,option%nphase
192) select case(option%iflowmode)
193) case(FLASH2_MODE)
194) write(*,'(" mode = FLASH2: p, T, s/X")')
195) case(MPH_MODE)
196) write(*,'(" mode = MPH: p, T, s/X")')
197) case(IMS_MODE)
198) write(*,'(" mode = IMS: p, T, s")')
199) case(MIS_MODE)
200) write(*,'(" mode = MIS: p, Xs")')
201) case(TH_MODE)
202) write(*,'(" mode = TH: p, T")')
203) case(RICHARDS_MODE)
204) write(*,'(" mode = Richards: p")')
205) case(G_MODE)
206) case(TOIL_IMS_MODE)
207) end select
208) endif
209)
210) call SolverCreateSNES(solver,option%mycomm)
211) call SNESSetOptionsPrefix(solver%snes, "flow_",ierr);CHKERRQ(ierr)
212) call SolverCheckCommandLine(solver)
213)
214) if (solver%Jpre_mat_type == '') then
215) if (solver%J_mat_type /= MATMFFD) then
216) solver%Jpre_mat_type = solver%J_mat_type
217) else
218) solver%Jpre_mat_type = MATBAIJ
219) endif
220) endif
221)
222) call DiscretizationCreateJacobian(realization%discretization,NFLOWDOF, &
223) solver%Jpre_mat_type, &
224) solver%Jpre, &
225) option)
226)
227) call MatSetOptionsPrefix(solver%Jpre,"flow_",ierr);CHKERRQ(ierr)
228)
229) if (solver%J_mat_type /= MATMFFD) then
230) solver%J = solver%Jpre
231) endif
232)
233) if (solver%use_galerkin_mg) then
234) call DiscretizationCreateInterpolation(realization%discretization,NFLOWDOF, &
235) solver%interpolation, &
236) solver%galerkin_mg_levels_x, &
237) solver%galerkin_mg_levels_y, &
238) solver%galerkin_mg_levels_z, &
239) option)
240) endif
241)
242) if (solver%J_mat_type == MATMFFD) then
243) call MatCreateSNESMF(solver%snes,solver%J,ierr);CHKERRQ(ierr)
244) endif
245)
246) ! by default turn off line search
247) call SNESGetLineSearch(solver%snes, linesearch, ierr);CHKERRQ(ierr)
248) call SNESLineSearchSetType(linesearch, SNESLINESEARCHBASIC, &
249) ierr);CHKERRQ(ierr)
250) ! Have PETSc do a SNES_View() at the end of each solve if verbosity > 0.
251) if (option%verbosity >= 2) then
252) string = '-flow_snes_view'
253) call PetscOptionsInsertString(PETSC_NULL_OBJECT,string, ierr);CHKERRQ(ierr)
254) endif
255)
256) call SolverSetSNESOptions(solver)
257)
258) ! If we are using a structured grid, set the corresponding flow DA
259) ! as the DA for the PCEXOTIC preconditioner, in case we choose to use it.
260) ! The PCSetDA() call is ignored if the PCEXOTIC preconditioner is
261) ! no used. We need to put this call after SolverCreateSNES() so that
262) ! KSPSetFromOptions() will already have been called.
263) ! I also note that this preconditioner is intended only for the flow
264) ! solver. --RTM
265) if (realization%discretization%itype == STRUCTURED_GRID) then
266) call PCSetDM(solver%pc, &
267) realization%discretization%dm_nflowdof,ierr);CHKERRQ(ierr)
268) endif
269)
270) option%io_buffer = 'Solver: ' // trim(solver%ksp_type)
271) call printMsg(option)
272) option%io_buffer = 'Preconditioner: ' // trim(solver%pc_type)
273) call printMsg(option)
274)
275) ! shell for custom convergence test. The default SNES convergence test
276) ! is call within this function.
277) convergence_context => ConvergenceContextCreate(solver,option, &
278) realization%patch%grid)
279) call SNESSetConvergenceTest(solver%snes,ConvergenceTest, &
280) convergence_context, &
281) PETSC_NULL_FUNCTION,ierr);CHKERRQ(ierr)
282)
283) call printMsg(option," Finished setting up FLOW SNES ")
284)
285) end subroutine InitSubsurfFlowSetupSolvers
286)
287) ! ************************************************************************** !
288)
289) subroutine InitSubsurfFlowReadInitCond(realization,filename)
290) !
291) ! Assigns flow initial condition from HDF5 file
292) !
293) ! Author: Glenn Hammond
294) ! Date: 03/05/10, 12/04/14
295) !
296)
297) use Realization_Subsurface_class
298) use Option_module
299) use Field_module
300) use Grid_module
301) use Patch_module
302) use Discretization_module
303) use HDF5_module
304)
305) implicit none
306)
307) #include "petsc/finclude/petscvec.h"
308) #include "petsc/finclude/petscvec.h90"
309)
310) class(realization_subsurface_type) :: realization
311) character(len=MAXSTRINGLENGTH) :: filename
312)
313) PetscInt :: local_id, idx, offset
314) PetscReal, pointer :: xx_p(:)
315) character(len=MAXSTRINGLENGTH) :: group_name
316) character(len=MAXSTRINGLENGTH) :: dataset_name
317) PetscReal, pointer :: vec_p(:)
318) PetscErrorCode :: ierr
319)
320) type(option_type), pointer :: option
321) type(field_type), pointer :: field
322) type(patch_type), pointer :: patch
323) type(grid_type), pointer :: grid
324) type(discretization_type), pointer :: discretization
325) type(patch_type), pointer :: cur_patch
326)
327) option => realization%option
328) discretization => realization%discretization
329) field => realization%field
330) patch => realization%patch
331)
332) if (option%iflowmode /= RICHARDS_MODE) then
333) option%io_buffer = 'Reading of flow initial conditions from HDF5 ' // &
334) 'file (' // trim(filename) // &
335) 'not currently not supported for mode: ' // &
336)
337) trim(option%flowmode)
338) endif
339)
340) cur_patch => realization%patch_list%first
341) do
342) if (.not.associated(cur_patch)) exit
343)
344) grid => cur_patch%grid
345)
346) ! assign initial conditions values to domain
347) call VecGetArrayF90(field%flow_xx, xx_p, ierr);CHKERRQ(ierr)
348)
349) ! Pressure for all modes
350) offset = 1
351) group_name = ''
352) dataset_name = 'Pressure'
353) call HDF5ReadCellIndexedRealArray(realization,field%work, &
354) filename,group_name, &
355) dataset_name,option%id>0)
356) call VecGetArrayF90(field%work,vec_p,ierr);CHKERRQ(ierr)
357) do local_id=1, grid%nlmax
358) if (cur_patch%imat(grid%nL2G(local_id)) <= 0) cycle
359) if (dabs(vec_p(local_id)) < 1.d-40) then
360) print *, option%myrank, grid%nG2A(grid%nL2G(local_id)), &
361) ': Potential error - zero pressure in Initial Condition read from file.'
362) endif
363) idx = (local_id-1)*option%nflowdof + offset
364) xx_p(idx) = vec_p(local_id)
365) enddo
366) call VecRestoreArrayF90(field%work,vec_p,ierr);CHKERRQ(ierr)
367)
368) call VecRestoreArrayF90(field%flow_xx,xx_p, ierr);CHKERRQ(ierr)
369)
370) cur_patch => cur_patch%next
371) enddo
372)
373) ! update dependent vectors
374) call DiscretizationGlobalToLocal(discretization,field%flow_xx, &
375) field%flow_xx_loc,NFLOWDOF)
376) call VecCopy(field%flow_xx, field%flow_yy, ierr);CHKERRQ(ierr)
377)
378) end subroutine InitSubsurfFlowReadInitCond
379)
380) end module Init_Subsurface_Flow_module