factory_geomechanics.F90 coverage: 100.00 %func 72.18 %block
1)
2) module Factory_Geomechanics_module
3)
4) use Simulation_Geomechanics_class
5) use PFLOTRAN_Constants_module
6)
7) implicit none
8)
9) private
10)
11) #include "petsc/finclude/petscsys.h"
12)
13) public :: GeomechanicsInitialize
14)
15) contains
16)
17) ! ************************************************************************** !
18)
19) subroutine GeomechanicsInitialize(simulation)
20) !
21) ! This routine
22) !
23) ! Author: Gautam Bisht, LBNL
24) ! Date: 01/01/14
25) !
26)
27) implicit none
28)
29) class(simulation_geomechanics_type) :: simulation
30)
31) ! NOTE: PETSc must already have been initialized here!
32) call GeomechanicsInitializePostPETSc(simulation)
33)
34) end subroutine GeomechanicsInitialize
35)
36) ! ************************************************************************** !
37)
38) subroutine GeomechanicsInitializePostPETSc(simulation)
39) !
40) ! This routine
41) !
42) ! Author: Gautam Bisht, LBNL and Satish Karra, LANL
43) ! Date: 01/01/14, 02/10/15
44) !
45)
46) use Simulation_Geomechanics_class
47) use Simulation_Subsurface_class
48) use Factory_Subsurface_module
49) use Init_Common_module
50) use Option_module
51) use PM_Base_class
52) use PM_Base_Pointer_module
53) use PM_Geomechanics_Force_class
54) use PMC_Base_class
55) use PMC_Geomechanics_class
56) use PFLOTRAN_Constants_module
57) use Geomechanics_Discretization_module
58) use Geomechanics_Force_module
59) use Geomechanics_Realization_class
60) use Geomechanics_Regression_module
61) use Simulation_Aux_module
62) use Realization_Subsurface_class
63) use Timestepper_Steady_class
64) use Input_Aux_module
65) use Logging_module
66) use Output_Aux_module
67)
68) implicit none
69) #include "petsc/finclude/petscvec.h"
70) #include "petsc/finclude/petscvec.h90"
71)
72) class(simulation_geomechanics_type) :: simulation
73)
74) type(option_type), pointer :: option
75) class(realization_subsurface_type), pointer :: subsurf_realization
76) class(realization_geomech_type), pointer :: geomech_realization
77) class(pmc_base_type), pointer :: cur_process_model_coupler
78) type(gmdm_ptr_type), pointer :: dm_ptr
79) class(pm_base_type), pointer :: cur_pm, prev_pm
80) class(pm_geomech_force_type), pointer :: pm_geomech
81) class(pmc_geomechanics_type), pointer :: pmc_geomech
82) class(timestepper_steady_type), pointer :: timestepper
83) character(len=MAXSTRINGLENGTH) :: string
84) type(waypoint_type), pointer :: waypoint
85) type(input_type), pointer :: input
86) PetscErrorCode :: ierr
87)
88) option => simulation%option
89)
90) nullify(prev_pm)
91) cur_pm => simulation%process_model_list
92) do
93) if (.not.associated(cur_pm)) exit
94) select type(cur_pm)
95) class is(pm_geomech_force_type)
96) pm_geomech => cur_pm
97) if (associated(prev_pm)) then
98) prev_pm%next => cur_pm%next
99) else
100) simulation%process_model_list => cur_pm%next
101) endif
102) exit
103) class default
104) end select
105) prev_pm => cur_pm
106) cur_pm => cur_pm%next
107) enddo
108)
109) call SubsurfaceInitializePostPetsc(simulation)
110) simulation%process_model_coupler_list%is_master = PETSC_TRUE
111)
112) if (option%geomech_on) then
113) simulation%geomech_realization => GeomechRealizCreate(option)
114) geomech_realization => simulation%geomech_realization
115) subsurf_realization => simulation%realization
116) subsurf_realization%output_option => OutputOptionDuplicate(simulation%output_option)
117) geomech_realization%input => InputCreate(IN_UNIT,option%input_filename,option)
118) call GeomechicsInitReadRequiredCards(geomech_realization)
119) pmc_geomech => PMCGeomechanicsCreate()
120) pmc_geomech%name = 'PMCGeomech'
121) simulation%geomech_process_model_coupler => pmc_geomech
122) pmc_geomech%option => option
123) pmc_geomech%checkpoint_option => simulation%checkpoint_option
124) pmc_geomech%waypoint_list => simulation%waypoint_list_subsurface
125) pmc_geomech%pm_list => pm_geomech
126) pmc_geomech%pm_ptr%pm => pm_geomech
127) pmc_geomech%geomech_realization => simulation%geomech_realization
128) pmc_geomech%subsurf_realization => simulation%realization
129) timestepper => TimestepperSteadyCreate()
130) pmc_geomech%timestepper => timestepper
131) ! set up logging stage
132) string = trim(pmc_geomech%name) // 'Geomechanics'
133) call LoggingCreateStage(string,pmc_geomech%stage)
134)
135) input => InputCreate(IN_UNIT,option%input_filename,option)
136) string = 'GEOMECHANICS'
137) call InputFindStringInFile(input,option,string)
138) call InputFindStringErrorMsg(input,option,string)
139) geomech_realization%output_option => OutputOptionDuplicate(simulation%output_option)
140) nullify(geomech_realization%output_option%output_snap_variable_list)
141) nullify(geomech_realization%output_option%output_obs_variable_list)
142) geomech_realization%output_option%output_snap_variable_list => OutputVariableListCreate()
143) geomech_realization%output_option%output_obs_variable_list => OutputVariableListCreate()
144) call GeomechanicsInitReadInput(simulation,timestepper%solver,input)
145) pm_geomech%output_option => geomech_realization%output_option
146)
147)
148)
149) ! Hijack subsurface waypoint to geomechanics waypoint
150) ! Subsurface controls the output now
151) ! Always have snapshot on at t=0
152) pmc_geomech%waypoint_list%first%print_snap_output = PETSC_TRUE
153)
154)
155) ! link geomech and flow timestepper waypoints to geomech way point list
156) if (associated(simulation%geomech_process_model_coupler)) then
157) if (associated(simulation%geomech_process_model_coupler% &
158) timestepper)) then
159) simulation%geomech_process_model_coupler%timestepper%cur_waypoint => &
160) pmc_geomech%waypoint_list%first
161) endif
162)
163) if (associated(simulation%flow_process_model_coupler%timestepper)) then
164) simulation%flow_process_model_coupler%timestepper%cur_waypoint => &
165) pmc_geomech%waypoint_list%first
166) endif
167) endif
168)
169) ! print the waypoints when debug flag is on
170) if (geomech_realization%geomech_debug%print_waypoints) then
171) call WaypointListPrint(pmc_geomech%waypoint_list,option, &
172) geomech_realization%output_option)
173) endif
174)
175) ! initialize geomech realization
176) call GeomechInitSetupRealization(simulation)
177)
178) ! Solver set up
179) call GeomechInitSetupSolvers(geomech_realization,subsurf_realization, &
180) timestepper%convergence_context, &
181) timestepper%solver)
182)
183)
184) call pm_geomech%PMGeomechForceSetRealization(geomech_realization)
185) call pm_geomech%Setup()
186) ! Here I first calculate the linear part of the jacobian and store it
187) ! since the jacobian is always linear with geomech (even when coupled with
188) ! flow since we are performing sequential coupling). Although
189) ! SNESSetJacobian is called, nothing is done there and PETSc just
190) ! re-uses the linear Jacobian at all iterations and times
191) call GeomechForceJacobianLinearPart(timestepper%solver%J,geomech_realization)
192) call SNESSetFunction(timestepper%solver%snes, &
193) pm_geomech%residual_vec, &
194) PMResidual, &
195) pmc_geomech%pm_ptr, &
196) ierr);CHKERRQ(ierr)
197) call SNESSetJacobian(timestepper%solver%snes, &
198) timestepper%solver%J, &
199) timestepper%solver%Jpre, &
200) PMJacobian, &
201) pmc_geomech%pm_ptr, &
202) ierr);CHKERRQ(ierr)
203)
204) nullify(simulation%process_model_coupler_list)
205) endif
206) ! sim_aux: Create PETSc Vectors and VectorScatters
207) if (option%ngeomechdof > 0) then
208)
209) call GeomechCreateGeomechSubsurfVec(subsurf_realization, &
210) geomech_realization)
211) call SimAuxCopySubsurfVec(simulation%sim_aux,subsurf_realization%field%work)
212)
213) call GeomechCreateSubsurfStressStrainVec(subsurf_realization, &
214) geomech_realization)
215) call SimAuxCopySubsurfGeomechVec(simulation%sim_aux, &
216) geomech_realization%geomech_field%strain_subsurf)
217)
218) call GeomechRealizMapSubsurfGeomechGrid(subsurf_realization, &
219) geomech_realization, &
220) option)
221)
222) dm_ptr => GeomechDiscretizationGetDMPtrFromIndex( &
223) geomech_realization%geomech_discretization, ONEDOF)
224)
225) call SimAuxCopyVecScatter(simulation%sim_aux, &
226) dm_ptr%gmdm%scatter_subsurf_to_geomech_ndof, &
227) SUBSURF_TO_GEOMECHANICS)
228) call SimAuxCopyVecScatter(simulation%sim_aux, &
229) dm_ptr%gmdm%scatter_geomech_to_subsurf_ndof, &
230) GEOMECHANICS_TO_SUBSURF)
231) endif
232)
233) call GeomechanicsRegressionCreateMapping(simulation%geomech_regression, &
234) geomech_realization)
235)
236) ! sim_aux: Set pointer
237) simulation%flow_process_model_coupler%sim_aux => simulation%sim_aux
238) if (associated(simulation%rt_process_model_coupler)) &
239) simulation%rt_process_model_coupler%sim_aux => simulation%sim_aux
240) if (option%ngeomechdof>0 .and. &
241) associated(simulation%geomech_process_model_coupler)) &
242) simulation%geomech_process_model_coupler%sim_aux => simulation%sim_aux
243)
244) ! set geomech as not master
245) simulation%geomech_process_model_coupler%is_master = PETSC_FALSE
246) ! link geomech and master
247) simulation%process_model_coupler_list => &
248) simulation%geomech_process_model_coupler
249) ! link subsurface flow as peer
250) simulation%process_model_coupler_list%peer => &
251) simulation%flow_process_model_coupler
252)
253)
254) ! Set data in sim_aux
255) cur_process_model_coupler => simulation%process_model_coupler_list
256) call cur_process_model_coupler%SetAuxData()
257) if (associated(cur_process_model_coupler%peer)) then
258) cur_process_model_coupler => cur_process_model_coupler%peer
259) call cur_process_model_coupler%GetAuxData()
260) call cur_process_model_coupler%SetAuxData()
261) select type(pmc => cur_process_model_coupler)
262) class is(pmc_geomechanics_type)
263) call GeomechStoreInitialPressTemp(pmc%geomech_realization)
264) end select
265) endif
266)
267) call GeomechanicsJumpStart(simulation)
268) call InputDestroy(geomech_realization%input)
269)
270) end subroutine GeomechanicsInitializePostPETSc
271)
272) ! ************************************************************************** !
273)
274) subroutine GeomechanicsJumpStart(simulation)
275) !
276) ! This routine
277) !
278) ! Author: Gautam Bisht, LBNL
279) ! Date: 01/01/14
280) !
281)
282) use Geomechanics_Realization_class
283) use Option_module
284) use Timestepper_Steady_class
285) use Output_Aux_module
286) use Output_module, only : Output, OutputPrintCouplers
287) use Output_Geomechanics_module
288) use Logging_module
289) use Condition_Control_module
290)
291) implicit none
292)
293) type(simulation_geomechanics_type) :: simulation
294)
295) class(realization_geomech_type), pointer :: geomch_realization
296) class(timestepper_steady_type), pointer :: master_timestepper
297) class(timestepper_steady_type), pointer :: geomech_timestepper
298) type(option_type), pointer :: option
299) type(output_option_type), pointer :: output_option
300)
301) character(len=MAXSTRINGLENGTH) :: string
302) PetscBool :: snapshot_plot_flag,observation_plot_flag,massbal_plot_flag
303) PetscBool :: geomech_read
304) PetscBool :: failure
305) PetscErrorCode :: ierr
306)
307) geomch_realization => simulation%geomech_realization
308)
309) select type(ts => simulation%geomech_process_model_coupler%timestepper)
310) class is(timestepper_steady_type)
311) geomech_timestepper => ts
312) end select
313) nullify(master_timestepper)
314)
315) option => geomch_realization%option
316)
317) call PetscOptionsHasName(PETSC_NULL_OBJECT, &
318) PETSC_NULL_CHARACTER, "-vecload_block_size", &
319) failure, ierr);CHKERRQ(ierr)
320)
321) if (option%steady_state) then
322) option%io_buffer = 'Running in steady-state not yet supported for &
323) &surface-flow.'
324) call printErrMsg(option)
325) return
326) endif
327)
328) geomech_timestepper%name = 'GEOMECHANICS'
329)
330) master_timestepper => geomech_timestepper
331)
332) snapshot_plot_flag = PETSC_FALSE
333) observation_plot_flag = PETSC_FALSE
334) massbal_plot_flag = PETSC_FALSE
335) geomech_read = PETSC_FALSE
336) failure = PETSC_FALSE
337)
338) call OutputGeomechInit(master_timestepper%steps)
339)
340) ! pushed in INIT_STAGE()
341) call PetscLogStagePop(ierr);CHKERRQ(ierr)
342)
343) ! popped in TS_STAGE()
344) call PetscLogStagePush(logging%stage(TS_STAGE),ierr);CHKERRQ(ierr)
345)
346) end subroutine GeomechanicsJumpStart
347)
348) ! ************************************************************************** !
349)
350) subroutine GeomechicsInitReadRequiredCards(geomech_realization)
351) !
352) ! Reads the required input file cards
353) ! related to geomechanics
354) !
355) ! Author: Satish Karra, LANL
356) ! Date: 05/23/13
357) !
358)
359) use Geomechanics_Discretization_module
360) use Geomechanics_Realization_class
361) use Geomechanics_Patch_module
362) use Geomechanics_Grid_module
363) use Input_Aux_module
364) use String_module
365) use Patch_module
366) use Option_module
367)
368) implicit none
369)
370) class(realization_geomech_type) :: geomech_realization
371) type(geomech_discretization_type), pointer :: geomech_discretization
372)
373) character(len=MAXSTRINGLENGTH) :: string
374)
375) type(option_type), pointer :: option
376) type(input_type), pointer :: input
377)
378) option => geomech_realization%option
379) input => geomech_realization%input
380)
381) ! Read in select required cards
382) !.........................................................................
383)
384) ! GEOMECHANICS information
385) string = "GEOMECHANICS"
386) call InputFindStringInFile(input,option,string)
387) if (InputError(input)) return
388) option%ngeomechdof = 3 ! displacements in x, y, z directions
389) option%n_stress_strain_dof = 6
390)
391) string = "GEOMECHANICS_GRID"
392) call InputFindStringInFile(input,option,string)
393) call GeomechanicsInit(geomech_realization,input,option)
394)
395)
396) end subroutine GeomechicsInitReadRequiredCards
397)
398) ! ************************************************************************** !
399)
400) subroutine GeomechanicsInit(geomech_realization,input,option)
401) !
402) ! Reads the required geomechanics data from input file
403) !
404) ! Author: Satish Karra, LANL
405) ! Date: 05/23/13
406) !
407)
408) use Option_module
409) use Input_Aux_module
410) use String_module
411) use Geomechanics_Grid_module
412) use Geomechanics_Grid_Aux_module
413) use Geomechanics_Discretization_module
414) use Geomechanics_Realization_class
415) use Geomechanics_Patch_module
416) use Grid_Unstructured_Aux_module
417) use Grid_Unstructured_module
418)
419) implicit none
420)
421) class(realization_geomech_type) :: geomech_realization
422) type(geomech_discretization_type), pointer :: geomech_discretization
423) type(geomech_patch_type), pointer :: patch
424) type(input_type), pointer :: input
425) type(option_type), pointer :: option
426) character(len=MAXWORDLENGTH) :: word
427) type(grid_unstructured_type), pointer :: ugrid
428) character(len=MAXWORDLENGTH) :: card
429)
430) geomech_discretization => geomech_realization%geomech_discretization
431)
432) input%ierr = 0
433) ! we initialize the word to blanks to avoid error reported by valgrind
434) word = ''
435)
436) do
437) call InputReadPflotranString(input,option)
438) call InputReadStringErrorMsg(input,option,card)
439) if (InputCheckExit(input,option)) exit
440) call InputReadWord(input,option,word,PETSC_TRUE)
441) call InputErrorMsg(input,option,'keyword','GEOMECHANICS')
442) call StringToUpper(word)
443)
444) select case(trim(word))
445) case ('TYPE')
446) call InputReadWord(input,option,word,PETSC_TRUE)
447) call InputErrorMsg(input,option,'keyword','TYPE')
448) call StringToUpper(word)
449)
450) select case(trim(word))
451) case ('UNSTRUCTURED')
452) geomech_discretization%itype = UNSTRUCTURED_GRID
453) call InputReadNChars(input,option, &
454) geomech_discretization%filename, &
455) MAXSTRINGLENGTH, &
456) PETSC_TRUE)
457) call InputErrorMsg(input,option,'keyword','filename')
458)
459) geomech_discretization%grid => GMGridCreate()
460) ugrid => UGridCreate()
461) call UGridRead(ugrid,geomech_discretization%filename,option)
462) call UGridDecompose(ugrid,option)
463) call CopySubsurfaceGridtoGeomechGrid(ugrid, &
464) geomech_discretization%grid, &
465) option)
466) patch => GeomechanicsPatchCreate()
467) patch%geomech_grid => geomech_discretization%grid
468) geomech_realization%geomech_patch => patch
469) case default
470) option%io_buffer = 'Geomechanics supports only unstructured grid'
471) call printErrMsg(option)
472) end select
473) case ('GRAVITY')
474) call InputReadDouble(input,option,option%geomech_gravity(X_DIRECTION))
475) call InputErrorMsg(input,option,'x-direction','GEOMECH GRAVITY')
476) call InputReadDouble(input,option,option%geomech_gravity(Y_DIRECTION))
477) call InputErrorMsg(input,option,'y-direction','GEOMECH GRAVITY')
478) call InputReadDouble(input,option,option%geomech_gravity(Z_DIRECTION))
479) call InputErrorMsg(input,option,'z-direction','GEOMECH GRAVITY')
480) if (option%myrank == option%io_rank .and. &
481) option%print_to_screen) &
482) write(option%fid_out,'(/," *GEOMECH_GRAV",/, &
483) & " gravity = "," [m/s^2]",3x,1p3e12.4 &
484) & )') option%geomech_gravity(1:3)
485) case default
486) call InputKeywordUnrecognized(word,'GEOMECHANICS_GRID',option)
487) end select
488) enddo
489)
490) end subroutine GeomechanicsInit
491)
492) ! ************************************************************************** !
493)
494) subroutine GeomechanicsInitReadInput(simulation,geomech_solver, &
495) input)
496) !
497) ! Reads the geomechanics input data
498) !
499) ! Author: Satish Karra, LANL
500) ! Date: 05/23/13
501) !
502) use Simulation_Geomechanics_class
503) use Option_module
504) use Input_Aux_module
505) use String_module
506) use Geomechanics_Discretization_module
507) use Geomechanics_Realization_class
508) use Geomechanics_Patch_module
509) use Geomechanics_Grid_module
510) use Geomechanics_Grid_Aux_module
511) use Geomechanics_Material_module
512) use Geomechanics_Region_module
513) use Geomechanics_Debug_module
514) use Geomechanics_Strata_module
515) use Geomechanics_Condition_module
516) use Geomechanics_Coupler_module
517) use Geomechanics_Regression_module
518) use Output_Aux_module
519) use Output_Tecplot_module
520) use Solver_module
521) use Units_module
522) use Waypoint_module
523) use Utility_module, only : DeallocateArray, UtilityReadArray
524)
525) ! Still need to add other geomech modules for output, etc once created
526)
527) implicit none
528)
529) class(simulation_geomechanics_type) :: simulation
530) type(solver_type) :: geomech_solver
531) type(input_type), pointer :: input
532)
533) class(realization_geomech_type), pointer :: geomech_realization
534) type(option_type), pointer :: option
535) type(geomech_discretization_type), pointer :: geomech_discretization
536) type(geomech_material_property_type),pointer :: geomech_material_property
537) type(waypoint_type), pointer :: waypoint
538) type(geomech_grid_type), pointer :: grid
539) type(gm_region_type), pointer :: region
540) type(geomech_debug_type), pointer :: debug
541) type(geomech_strata_type), pointer :: strata
542) type(geomech_condition_type), pointer :: condition
543) type(geomech_coupler_type), pointer :: coupler
544) type(output_option_type), pointer :: output_option
545) type(waypoint_list_type), pointer :: waypoint_list
546) PetscReal :: units_conversion
547)
548) character(len=MAXWORDLENGTH) :: word, internal_units
549) character(len=MAXWORDLENGTH) :: card
550) character(len=MAXSTRINGLENGTH) :: string
551) character(len=1) :: backslash
552)
553) PetscReal :: temp_real, temp_real2
554) PetscReal, pointer :: temp_real_array(:)
555) PetscInt :: i
556) backslash = achar(92) ! 92 = "\" Some compilers choke on \" thinking it
557) ! is a double quote as in c/c++
558) input%ierr = 0
559) ! we initialize the word to blanks to avoid error reported by valgrind
560) word = ''
561)
562) waypoint_list => simulation%waypoint_list_geomechanics
563) geomech_realization => simulation%geomech_realization
564) option => simulation%option
565) geomech_discretization => geomech_realization%geomech_discretization
566) output_option => simulation%output_option
567)
568) if (associated(geomech_realization%geomech_patch)) grid => &
569) geomech_realization%geomech_patch%geomech_grid
570)
571) do
572) call InputReadPflotranString(input,option)
573) if (InputCheckExit(input,option)) exit
574)
575) call InputReadWord(input,option,word,PETSC_TRUE)
576) call InputErrorMsg(input,option,'keyword','GEOMECHANICS')
577) call StringToUpper(word)
578) option%io_buffer = 'word :: ' // trim(word)
579) call printMsg(option)
580)
581) select case(trim(word))
582)
583) !.........................................................................
584) ! Read geomechanics grid information
585) case ('GEOMECHANICS_GRID')
586) call InputSkipToEND(input,option,trim(word))
587)
588) !.........................................................................
589) ! Read geomechanics material information
590) case ('GEOMECHANICS_MATERIAL_PROPERTY')
591) geomech_material_property => GeomechanicsMaterialPropertyCreate()
592)
593) call InputReadWord(input,option,geomech_material_property%name, &
594) PETSC_TRUE)
595)
596) call InputErrorMsg(input,option,'name','GEOMECHANICS_MATERIAL_PROPERTY')
597) call GeomechanicsMaterialPropertyRead(geomech_material_property,input, &
598) option)
599) call GeomechanicsMaterialPropertyAddToList(geomech_material_property, &
600) geomech_realization%geomech_material_properties)
601) nullify(geomech_material_property)
602)
603) !.........................................................................
604) case ('GEOMECHANICS_REGION')
605) region => GeomechRegionCreate()
606) call InputReadWord(input,option,region%name,PETSC_TRUE)
607) call InputErrorMsg(input,option,'name','GEOMECHANICS_REGION')
608) call printMsg(option,region%name)
609) call GeomechRegionRead(region,input,option)
610) ! we don't copy regions down to patches quite yet, since we
611) ! don't want to duplicate IO in reading the regions
612) call GeomechRegionAddToList(region,geomech_realization%geomech_region_list)
613) nullify(region)
614)
615) !.........................................................................
616) case ('GEOMECHANICS_CONDITION')
617) condition => GeomechConditionCreate(option)
618) call InputReadWord(input,option,condition%name,PETSC_TRUE)
619) call InputErrorMsg(input,option,'GEOMECHANICS_CONDITION','name')
620) call printMsg(option,condition%name)
621) call GeomechConditionRead(condition,input,option)
622) call GeomechConditionAddToList(condition,geomech_realization%geomech_conditions)
623) nullify(condition)
624)
625) !.........................................................................
626) case ('GEOMECHANICS_BOUNDARY_CONDITION')
627) coupler => GeomechCouplerCreate(GM_BOUNDARY_COUPLER_TYPE)
628) call InputReadWord(input,option,coupler%name,PETSC_TRUE)
629) call InputDefaultMsg(input,option,'Geomech Boundary Condition name')
630) call GeomechCouplerRead(coupler,input,option)
631) call GeomechRealizAddGeomechCoupler(geomech_realization,coupler)
632) nullify(coupler)
633)
634) !.........................................................................
635) case ('GEOMECHANICS_SRC_SINK')
636) coupler => GeomechCouplerCreate(GM_SRC_SINK_COUPLER_TYPE)
637) call InputReadWord(input,option,coupler%name,PETSC_TRUE)
638) call InputDefaultMsg(input,option,'Source Sink name')
639) call GeomechCouplerRead(coupler,input,option)
640) call GeomechRealizAddGeomechCoupler(geomech_realization,coupler)
641) nullify(coupler)
642)
643) !.........................................................................
644) case('NEWTON_SOLVER')
645) call InputReadWord(input,option,word,PETSC_FALSE)
646) call StringToUpper(word)
647) select case(word)
648) case('GEOMECHANICS')
649) call SolverReadNewton(geomech_solver,input,option)
650) end select
651)
652) !....................
653) case ('LINEAR_SOLVER')
654) call InputReadWord(input,option,word,PETSC_FALSE)
655) call StringToUpper(word)
656) select case(word)
657) case('GEOMECHANICS')
658) call SolverReadLinear(geomech_solver,input,option)
659) end select
660)
661) !.....................
662) case ('GEOMECHANICS_REGRESSION')
663) call GeomechanicsRegressionRead(simulation%geomech_regression,input,option)
664)
665) !.........................................................................
666) case ('GEOMECHANICS_TIME')
667) do
668) call InputReadPflotranString(input,option)
669) call InputReadStringErrorMsg(input,option,card)
670) if (InputCheckExit(input,option)) exit
671) call InputReadWord(input,option,word,PETSC_TRUE)
672) call InputErrorMsg(input,option,'word','GEOMECHANICS_TIME')
673) select case(trim(word))
674) case('COUPLING_TIMESTEP_SIZE')
675) internal_units = 'sec'
676) call InputReadDouble(input,option,temp_real)
677) call InputErrorMsg(input,option, &
678) 'Coupling Timestep Size','GEOMECHANICS_TIME')
679) call InputReadWord(input,option,word,PETSC_TRUE)
680) call InputErrorMsg(input,option, &
681) 'Coupling Timestep Size Time Units','GEOMECHANICS_TIME')
682) geomech_realization%dt_coupling = &
683) temp_real*UnitsConvertToInternal(word, &
684) internal_units,option)
685) case default
686) call InputKeywordUnrecognized(word,'GEOMECHANICS_TIME',option)
687) end select
688) enddo
689)
690) !.........................................................................
691) case ('GEOMECHANICS_DEBUG')
692) call GeomechDebugRead(geomech_realization%geomech_debug,input,option)
693)
694) !.........................................................................
695) case ('GEOMECHANICS_SUBSURFACE_COUPLING')
696) option%geomech_subsurf_coupling = -1
697) call InputReadWord(input,option,word,PETSC_FALSE)
698) call StringToUpper(word)
699) select case (word)
700) case ('ONE_WAY_COUPLED')
701) option%geomech_subsurf_coupling = GEOMECH_ONE_WAY_COUPLED
702) case ('TWO_WAY_COUPLED')
703) option%geomech_subsurf_coupling = GEOMECH_TWO_WAY_COUPLED
704) case default
705) call InputKeywordUnrecognized(word, &
706) 'GEOMECHANICS_SUBSURFACE_COUPLING',option)
707) end select
708) do
709) call InputReadPflotranString(input,option)
710) call InputReadStringErrorMsg(input,option,card)
711) if (InputCheckExit(input,option)) exit
712) call InputReadWord(input,option,word,PETSC_TRUE)
713) call InputErrorMsg(input,option,'keyword','MAPPING_FILE')
714) call InputReadNChars(input,option, &
715) grid%mapping_filename, &
716) MAXSTRINGLENGTH, &
717) PETSC_TRUE)
718) call InputErrorMsg(input,option,'keyword','mapping_file')
719) call GeomechSubsurfMapFromFilename(grid,grid%mapping_filename, &
720) option)
721) enddo
722) !.........................................................................
723) case ('GEOMECHANICS_OUTPUT')
724) do
725) call InputReadPflotranString(input,option)
726) call InputReadStringErrorMsg(input,option,card)
727) if (InputCheckExit(input,option)) exit
728) call InputReadWord(input,option,word,PETSC_TRUE)
729) call InputErrorMsg(input,option,'keyword','GEOMECHANICS_OUTPUT')
730) call StringToUpper(word)
731) select case(trim(word))
732) case('TIMES')
733) option%io_buffer = 'Subsurface times are now used for ' // &
734) 'geomechanics as well. No need for TIMES keyword under ' // &
735) 'GEOMECHANICS_OUTPUT.'
736) call printWrnMsg(option)
737) case('FORMAT')
738) call InputReadWord(input,option,word,PETSC_TRUE)
739) call InputErrorMsg(input,option,'keyword','GEOMECHANICS_OUTPUT,&
740) &FORMAT')
741) call StringToUpper(word)
742) select case(trim(word))
743) case ('HDF5')
744) output_option%print_hdf5 = PETSC_TRUE
745) call InputReadWord(input,option,word,PETSC_TRUE)
746) call InputDefaultMsg(input,option, &
747) 'GEOMECHANICS_OUTPUT,FORMAT,HDF5,&
748) &# FILES')
749) if (len_trim(word) > 1) then
750) call StringToUpper(word)
751) select case(trim(word))
752) case('SINGLE_FILE')
753) output_option%print_single_h5_file = PETSC_TRUE
754) case('MULTIPLE_FILES')
755) output_option%print_single_h5_file = PETSC_FALSE
756) case default
757) option%io_buffer = 'HDF5 keyword (' // trim(word) // &
758) ') not recongnized. Use "SINGLE_FILE" or ' // &
759) '"MULTIPLE_FILES".'
760) call printErrMsg(option)
761) end select
762) endif
763) case ('MAD')
764) output_option%print_mad = PETSC_TRUE
765) case ('TECPLOT')
766) output_option%print_tecplot = PETSC_TRUE
767) call InputReadWord(input,option,word,PETSC_TRUE)
768) call InputErrorMsg(input,option,'TECPLOT','GEOMECHANICS_OUTPUT,FORMAT')
769) call StringToUpper(word)
770) output_option%tecplot_format = TECPLOT_FEQUADRILATERAL_FORMAT ! By default it is unstructured
771) case ('VTK')
772) output_option%print_vtk = PETSC_TRUE
773) case default
774) call InputKeywordUnrecognized(word, &
775) 'GEOMECHANICS_OUTPUT,FORMAT',option)
776) end select
777) case default
778) call InputKeywordUnrecognized(word, &
779) 'GEOMECHANICS_OUTPUT',option)
780) end select
781) enddo
782)
783) !.........................................................................
784) case ('GEOMECHANICS_STRATIGRAPHY','GEOMECHANICS_STRATA')
785) strata => GeomechStrataCreate()
786) call GeomechStrataRead(strata,input,option)
787) call GeomechRealizAddStrata(geomech_realization,strata)
788) nullify(strata)
789) !.........................................................................
790) case ('END_GEOMECHANICS')
791) exit
792)
793) !.........................................................................
794) case default
795) call InputKeywordUnrecognized(word, &
796) 'GeomechanicsInitReadInput',option)
797) end select
798) enddo
799)
800) end subroutine GeomechanicsInitReadInput
801)
802) ! ************************************************************************** !
803)
804) subroutine GeomechInitMatPropToGeomechRegions(geomech_realization)
805) !
806) ! This routine assigns geomech material
807) ! properties to associated regions
808) !
809) ! Author: Satish Karra, LANL
810) ! Date: 06/17/13
811) !
812)
813) use Geomechanics_Realization_class
814) use Geomechanics_Discretization_module
815) use Geomechanics_Strata_module
816) use Geomechanics_Region_module
817) use Geomechanics_Material_module
818) use Geomechanics_Grid_module
819) use Geomechanics_Grid_Aux_module
820) use Geomechanics_Field_module
821) use Geomechanics_Patch_module
822) use Option_module
823)
824) implicit none
825) #include "petsc/finclude/petscvec.h"
826) #include "petsc/finclude/petscvec.h90"
827)
828) class(realization_geomech_type) :: geomech_realization
829)
830) PetscReal, pointer :: vec_p(:)
831)
832) PetscInt :: ivertex, local_id, ghosted_id, natural_id, geomech_material_id
833) PetscInt :: istart, iend
834) character(len=MAXSTRINGLENGTH) :: group_name
835) character(len=MAXSTRINGLENGTH) :: dataset_name
836) PetscErrorCode :: ierr
837)
838) type(option_type), pointer :: option
839) type(geomech_grid_type), pointer :: grid
840) type(geomech_discretization_type), pointer :: geomech_discretization
841) type(geomech_field_type), pointer :: field
842) type(geomech_strata_type), pointer :: strata
843) type(geomech_patch_type), pointer :: patch
844)
845) type(geomech_material_property_type), pointer :: geomech_material_property
846) type(geomech_material_property_type), pointer :: null_geomech_material_property
847) type(gm_region_type), pointer :: region
848) PetscBool :: update_ghosted_material_ids
849) PetscReal, pointer :: imech_loc_p(:)
850)
851) option => geomech_realization%option
852) geomech_discretization => geomech_realization%geomech_discretization
853) field => geomech_realization%geomech_field
854) patch => geomech_realization%geomech_patch
855)
856) ! loop over all patches and allocation material id arrays
857) if (.not.associated(patch%imat)) then
858) allocate(patch%imat(patch%geomech_grid%ngmax_node))
859) ! initialize to "unset"
860) patch%imat = UNINITIALIZED_INTEGER
861) endif
862)
863) ! if material ids are set based on region, as opposed to being read in
864) ! we must communicate the ghosted ids. This flag toggles this operation.
865) update_ghosted_material_ids = PETSC_FALSE
866) grid => patch%geomech_grid
867) strata => patch%geomech_strata_list%first
868) do
869) if (.not.associated(strata)) exit
870) ! Read in cell by cell material ids if they exist
871) if (.not.associated(strata%region) .and. strata%active) then
872) option%io_buffer = 'Reading of material prop from file for' // &
873) ' geomech is not implemented.'
874) call printErrMsgByRank(option)
875) ! Otherwise, set based on region
876) else if (strata%active) then
877) update_ghosted_material_ids = PETSC_TRUE
878) region => strata%region
879) geomech_material_property => strata%material_property
880) if (associated(region)) then
881) istart = 1
882) iend = region%num_verts
883) else
884) istart = 1
885) iend = grid%nlmax_node
886) endif
887) do ivertex = istart, iend
888) if (associated(region)) then
889) local_id = region%vertex_ids(ivertex)
890) else
891) local_id = ivertex
892) endif
893) ghosted_id = grid%nL2G(local_id)
894) patch%imat(ghosted_id) = geomech_material_property%id
895) enddo
896) endif
897) strata => strata%next
898) enddo
899)
900) if (update_ghosted_material_ids) then
901) ! update ghosted material ids
902) call GeomechRealizLocalToLocalWithArray(geomech_realization, &
903) MATERIAL_ID_ARRAY)
904) endif
905)
906) ! set cell by cell material properties
907) ! create null material property for inactive cells
908) null_geomech_material_property => GeomechanicsMaterialPropertyCreate()
909) call VecGetArrayF90(field%imech_loc,imech_loc_p,ierr);CHKERRQ(ierr)
910) do local_id = 1, grid%nlmax_node
911) ghosted_id = grid%nL2G(local_id)
912) geomech_material_id = patch%imat(ghosted_id)
913) if (geomech_material_id == 0) then ! accomodate inactive cells
914) geomech_material_property = null_geomech_material_property
915) else if ( geomech_material_id > 0 .and. &
916) geomech_material_id <= &
917) size(geomech_realization%geomech_material_property_array)) then
918) geomech_material_property => &
919) geomech_realization% &
920) geomech_material_property_array(geomech_material_id)%ptr
921) if (.not.associated(geomech_material_property)) then
922) write(dataset_name,*) geomech_material_id
923) option%io_buffer = 'No material property for geomech material id ' // &
924) trim(adjustl(dataset_name)) &
925) // ' defined in input file.'
926) call printErrMsgByRank(option)
927) endif
928) else if (Uninitialized(geomech_material_id)) then
929) write(dataset_name,*) grid%nG2A(ghosted_id)
930) option%io_buffer = 'Uninitialized geomech material id in patch at cell ' // &
931) trim(adjustl(dataset_name))
932) call printErrMsgByRank(option)
933) else if (geomech_material_id > size(geomech_realization% &
934) geomech_material_property_array)) then
935) write(option%io_buffer,*) geomech_material_id
936) option%io_buffer = 'Unmatched geomech material id in patch:' // &
937) adjustl(trim(option%io_buffer))
938) call printErrMsgByRank(option)
939) else
940) option%io_buffer = 'Something messed up with geomech material ids. ' // &
941) ' Possibly material ids not assigned to all grid cells. ' // &
942) ' Contact Glenn/Satish!'
943) call printErrMsgByRank(option)
944) endif
945) imech_loc_p(ghosted_id) = geomech_material_property%id
946) enddo ! local_id - loop
947) call VecRestoreArrayF90(field%imech_loc,imech_loc_p,ierr);CHKERRQ(ierr)
948)
949) call GeomechanicsMaterialPropertyDestroy(null_geomech_material_property)
950) nullify(null_geomech_material_property)
951)
952) call GeomechDiscretizationLocalToLocal(geomech_discretization,field%imech_loc, &
953) field%imech_loc,ONEDOF)
954)
955) end subroutine GeomechInitMatPropToGeomechRegions
956)
957) ! ************************************************************************** !
958)
959) subroutine GeomechInitSetupRealization(simulation)
960) !
961) ! Initializes material property data structres and assign them to the domain.
962) !
963) ! Author: Glenn Hammond
964) ! Date: 12/04/14
965) !
966) use Simulation_Geomechanics_class
967) use Geomechanics_Realization_class
968) use Geomechanics_Global_module
969) use Geomechanics_Force_module
970) use Realization_Subsurface_class
971)
972) use Option_module
973) use Waypoint_module
974)
975) implicit none
976)
977) class(simulation_geomechanics_type) :: simulation
978)
979) class(realization_subsurface_type), pointer :: subsurf_realization
980) class(realization_geomech_type), pointer :: geomech_realization
981) type(option_type), pointer :: option
982)
983) subsurf_realization => simulation%realization
984) geomech_realization => simulation%geomech_realization
985) option => subsurf_realization%option
986)
987) call GeomechRealizCreateDiscretization(geomech_realization)
988)
989) if (option%geomech_subsurf_coupling /= 0) then
990) call GeomechCreateGeomechSubsurfVec(subsurf_realization, &
991) geomech_realization)
992) call GeomechCreateSubsurfStressStrainVec(subsurf_realization, &
993) geomech_realization)
994)
995) call GeomechRealizMapSubsurfGeomechGrid(subsurf_realization, &
996) geomech_realization, &
997) option)
998) endif
999) call GeomechRealizLocalizeRegions(geomech_realization)
1000) call GeomechRealizPassFieldPtrToPatch(geomech_realization)
1001) call GeomechRealizProcessMatProp(geomech_realization)
1002) call GeomechRealizProcessGeomechCouplers(geomech_realization)
1003) call GeomechRealizProcessGeomechConditions(geomech_realization)
1004) call GeomechInitMatPropToGeomechRegions(geomech_realization)
1005) call GeomechRealizInitAllCouplerAuxVars(geomech_realization)
1006) call GeomechRealizPrintCouplers(geomech_realization)
1007) call GeomechGridElemSharedByNodes(geomech_realization,option)
1008) call GeomechForceSetup(geomech_realization)
1009) call GeomechGlobalSetup(geomech_realization)
1010)
1011) ! SK: We are solving quasi-steady state solution for geomechanics.
1012) ! Initial condition is not needed, hence CondControlAssignFlowInitCondGeomech
1013) ! is not needed, at this point.
1014) call GeomechForceUpdateAuxVars(geomech_realization)
1015)
1016) end subroutine GeomechInitSetupRealization
1017)
1018) ! ************************************************************************** !
1019)
1020) subroutine GeomechInitSetupSolvers(geomech_realization,realization, &
1021) convergence_context,solver)
1022) !
1023) ! Initializes material property data structres and assign them to the domain.
1024) !
1025) ! Author: Glenn Hammond
1026) ! Date: 12/04/14
1027) !
1028) use Realization_Subsurface_class
1029) use Geomechanics_Realization_class
1030) use Option_module
1031)
1032) use Solver_module
1033) use Convergence_module
1034) use Discretization_module
1035) use Geomechanics_Force_module
1036) use Geomechanics_Discretization_module
1037)
1038) implicit none
1039)
1040) #include "petsc/finclude/petscvec.h"
1041) #include "petsc/finclude/petscvec.h90"
1042) #include "petsc/finclude/petscmat.h"
1043) #include "petsc/finclude/petscmat.h90"
1044) #include "petsc/finclude/petscsnes.h"
1045) #include "petsc/finclude/petscpc.h"
1046)
1047) class(realization_geomech_type), pointer :: geomech_realization
1048) class(realization_subsurface_type), pointer :: realization
1049) type(convergence_context_type), pointer :: convergence_context
1050) type(solver_type), pointer :: solver
1051)
1052) type(option_type), pointer :: option
1053) SNESLineSearch :: linesearch
1054) character(len=MAXSTRINGLENGTH) :: string
1055) PetscErrorCode :: ierr
1056)
1057) option => realization%option
1058)
1059) call printMsg(option," Beginning setup of GEOMECH SNES ")
1060)
1061) if (solver%J_mat_type == MATAIJ) then
1062) option%io_buffer = 'AIJ matrix not supported for geomechanics.'
1063) call printErrMsg(option)
1064) endif
1065)
1066) call SolverCreateSNES(solver,option%mycomm)
1067) call SNESSetOptionsPrefix(solver%snes, "geomech_", &
1068) ierr);CHKERRQ(ierr)
1069) call SolverCheckCommandLine(solver)
1070)
1071) if (solver%Jpre_mat_type == '') then
1072) solver%Jpre_mat_type = solver%J_mat_type
1073) endif
1074) call GeomechDiscretizationCreateJacobian(geomech_realization% &
1075) geomech_discretization,NGEODOF, &
1076) solver%Jpre_mat_type, &
1077) solver%Jpre,option)
1078)
1079) solver%J = solver%Jpre
1080) call MatSetOptionsPrefix(solver%Jpre,"geomech_", &
1081) ierr);CHKERRQ(ierr)
1082)
1083) #if 0
1084) call SNESSetFunction(solver%snes,geomech_realization%geomech_field%disp_r, &
1085) GeomechForceResidual, &
1086) geomech_realization,ierr);CHKERRQ(ierr)
1087)
1088) call SNESSetJacobian(solver%snes,solver%J, &
1089) solver%Jpre,GeomechForceJacobian, &
1090) geomech_realization,ierr);CHKERRQ(ierr)
1091) #endif
1092)
1093) ! by default turn off line search
1094) call SNESGetLineSearch(solver%snes,linesearch, ierr);CHKERRQ(ierr)
1095) call SNESLineSearchSetType(linesearch,SNESLINESEARCHBASIC, &
1096) ierr);CHKERRQ(ierr)
1097)
1098)
1099) ! Have PETSc do a SNES_View() at the end of each solve if verbosity > 0.
1100) if (option%verbosity >= 1) then
1101) string = '-geomech_snes_view'
1102) call PetscOptionsInsertString(PETSC_NULL_OBJECT, &
1103) string, ierr);CHKERRQ(ierr)
1104) endif
1105)
1106) call SolverSetSNESOptions(solver)
1107)
1108) option%io_buffer = 'Solver: ' // trim(solver%ksp_type)
1109) call printMsg(option)
1110) option%io_buffer = 'Preconditioner: ' // trim(solver%pc_type)
1111) call printMsg(option)
1112)
1113) ! shell for custom convergence test. The default SNES convergence test
1114) ! is call within this function.
1115) !TODO(geh): free this convergence context somewhere!
1116) option%io_buffer = 'DEALLOCATE GEOMECH CONVERGENCE CONTEXT somewhere!!!'
1117) convergence_context => ConvergenceContextCreate(solver,option, &
1118) realization%patch%grid)
1119) call SNESSetConvergenceTest(solver%snes,ConvergenceTest, &
1120) convergence_context, &
1121) PETSC_NULL_FUNCTION,ierr);CHKERRQ(ierr)
1122)
1123) call printMsg(option," Finished setting up GEOMECH SNES ")
1124)
1125) end subroutine GeomechInitSetupSolvers
1126)
1127) end module Factory_Geomechanics_module
1128)