timestepper_steady.F90 coverage: 66.67 %func 78.26 %block
1) module Timestepper_Steady_class
2)
3) use Timestepper_BE_class
4) use Timestepper_Base_class
5) use Convergence_module
6) use Solver_module
7) use Waypoint_module
8) use PFLOTRAN_Constants_module
9)
10) implicit none
11)
12) #include "petsc/finclude/petscsys.h"
13)
14) type, public, extends(timestepper_BE_type) :: timestepper_steady_type
15)
16) ! PetscInt :: num_newton_iterations ! number of Newton iterations in a time step
17) ! PetscInt :: num_linear_iterations ! number of linear solver iterations in a time step
18) ! PetscInt :: cumulative_newton_iterations ! Total number of Newton iterations
19) ! PetscInt :: cumulative_linear_iterations ! Total number of linear iterations
20)
21) ! type(solver_type), pointer :: solver
22) ! type(convergence_context_type), pointer :: convergence_context
23)
24) contains
25)
26) ! procedure, public :: Init => TimestepperSteadyInit
27) procedure, public :: StepDT => TimestepperSteadyStepDT
28) procedure, public :: UpdateDT => TimestepperSteadyUpdateDT
29) procedure, public :: InputRecord => TimestepperSteadyInputRecord
30)
31) end type timestepper_steady_type
32)
33) public :: TimestepperSteadyCreate, &
34) TimestepperSteadyCreateFromBE
35)
36) contains
37)
38) ! ************************************************************************** !
39)
40) function TimestepperSteadyCreate()
41) !
42) ! This routine creates timestepper for steady solve
43) !
44) ! Author: Gautam Bisht, LBNL and Satish Karra, LANL
45) ! Date: 01/01/14, 04/07/2015
46) !
47)
48) implicit none
49)
50) class(timestepper_steady_type), pointer :: TimestepperSteadyCreate
51)
52) class(timestepper_steady_type), pointer :: stepper
53)
54) allocate(stepper)
55) call stepper%Init()
56)
57) stepper%solver => SolverCreate()
58)
59) TimestepperSteadyCreate => stepper
60)
61) end function TimestepperSteadyCreate
62)
63) ! ************************************************************************** !
64)
65) subroutine TimestepperSteadyCreateFromBE(timestepper_BE)
66) !
67) ! This routine creates timestepper for steady solve
68) !
69) ! Author: Gautam Bisht, LBNL and Satish Karra, LANL
70) ! Date: 01/01/14, 04/07/2015
71) !
72)
73) implicit none
74)
75) class(timestepper_BE_type), pointer :: timestepper_BE
76)
77) class(timestepper_steady_type), pointer :: stepper
78)
79) allocate(stepper)
80)
81) stepper%name = timestepper_BE%name
82) stepper%steps = timestepper_BE%steps
83) stepper%num_constant_time_steps = timestepper_BE%num_constant_time_steps
84)
85) stepper%max_time_step = timestepper_BE%max_time_step
86) stepper%max_time_step_cuts = timestepper_BE%max_time_step_cuts
87) stepper%constant_time_step_threshold = timestepper_BE%constant_time_step_threshold
88)
89) stepper%cumulative_time_step_cuts = timestepper_BE%cumulative_time_step_cuts
90) stepper%cumulative_solver_time = timestepper_BE%cumulative_solver_time
91)
92) stepper%start_time = timestepper_BE%start_time
93) stepper%start_time_step = timestepper_BE%start_time_step
94) stepper%time_step_tolerance = timestepper_BE%time_step_tolerance
95) stepper%target_time = timestepper_BE%target_time
96)
97) stepper%prev_dt = timestepper_BE%prev_dt
98) stepper%dt = timestepper_BE%dt
99) stepper%dt_init = timestepper_BE%dt_init
100) stepper%dt_max = timestepper_BE%dt_max
101)
102) stepper%time_step_cut_flag = timestepper_BE%time_step_cut_flag
103)
104) stepper%init_to_steady_state = timestepper_BE%init_to_steady_state
105) stepper%steady_state_rel_tol = timestepper_BE%steady_state_rel_tol
106) stepper%run_as_steady_state = timestepper_BE%run_as_steady_state
107)
108) stepper%cur_waypoint => timestepper_BE%cur_waypoint
109) stepper%prev_waypoint => timestepper_BE%prev_waypoint
110) stepper%revert_dt = timestepper_BE%revert_dt
111) stepper%num_contig_revert_due_to_sync = timestepper_BE%num_contig_revert_due_to_sync
112)
113) stepper%num_newton_iterations = timestepper_BE%num_newton_iterations
114) stepper%num_linear_iterations = timestepper_BE%num_linear_iterations
115)
116) stepper%cumulative_newton_iterations = timestepper_BE%cumulative_newton_iterations
117) stepper%cumulative_linear_iterations = timestepper_BE%cumulative_linear_iterations
118)
119) stepper%iaccel = timestepper_BE%iaccel
120) stepper%ntfac = timestepper_BE%ntfac
121) allocate(stepper%tfac(13))
122) stepper%tfac(1) = timestepper_BE%tfac(1)
123) stepper%tfac(2) = timestepper_BE%tfac(2)
124) stepper%tfac(3) = timestepper_BE%tfac(3)
125) stepper%tfac(4) = timestepper_BE%tfac(4)
126) stepper%tfac(5) = timestepper_BE%tfac(5)
127) stepper%tfac(6) = timestepper_BE%tfac(6)
128) stepper%tfac(7) = timestepper_BE%tfac(7)
129) stepper%tfac(8) = timestepper_BE%tfac(8)
130) stepper%tfac(9) = timestepper_BE%tfac(9)
131) stepper%tfac(10) = timestepper_BE%tfac(10)
132) stepper%tfac(11) = timestepper_BE%tfac(11)
133) stepper%tfac(12) = timestepper_BE%tfac(12)
134) stepper%tfac(13) = timestepper_BE%tfac(13)
135)
136) stepper%solver => timestepper_BE%solver
137) stepper%convergence_context => timestepper_BE%convergence_context
138)
139) timestepper_BE => stepper
140)
141) end subroutine TimestepperSteadyCreateFromBE
142)
143) ! ************************************************************************** !
144)
145) subroutine TimestepperSteadyInit(this)
146) !
147) ! This routine
148) !
149) ! Author: Gautam Bisht, LBNL and Satish Karra, LANL
150) ! Date: 01/01/14, 04/07/2015
151) !
152)
153) implicit none
154)
155) class(timestepper_steady_type) :: this
156)
157) call TimestepperBaseInit(this)
158)
159) end subroutine TimestepperSteadyInit
160)
161)
162) ! ************************************************************************** !
163)
164) subroutine TimestepperSteadyUpdateDT(this,process_model)
165) !
166) ! Updates time step
167) !
168) ! Author: Gautam Bisht, LBNL and Satish Karra, LANL
169) ! Date: 01/01/14, 04/07/2015
170) !
171)
172) use PM_Base_class
173) use Option_module
174)
175) implicit none
176)
177) class(timestepper_steady_type) :: this
178) class(pm_base_type) :: process_model
179)
180)
181) end subroutine TimestepperSteadyUpdateDT
182)
183) ! ************************************************************************** !
184)
185) subroutine TimestepperSteadyStepDT(this, process_model, stop_flag)
186) !
187) ! This routine
188) !
189) ! Author: Gautam Bisht, LBNL and Satish Karra, LANL
190) ! Date: 01/01/14, 04/07/2015
191) !
192)
193) use PM_Base_class
194) use Option_module
195) use PM_Geomechanics_Force_class
196) use Output_module, only : Output
197)
198) use Solver_module
199)
200) implicit none
201)
202) #include "petsc/finclude/petscvec.h"
203) #include "petsc/finclude/petscvec.h90"
204) #include "petsc/finclude/petscmat.h"
205) #include "petsc/finclude/petscviewer.h"
206) #include "petsc/finclude/petscsnes.h"
207)
208) class(timestepper_steady_type) :: this
209) class(pm_base_type) :: process_model
210) PetscInt :: stop_flag
211)
212) PetscBool :: failure
213) PetscLogDouble :: log_start_time
214) PetscLogDouble :: log_end_time
215) PetscErrorCode :: ierr
216) PetscInt :: sum_newton_iterations, sum_linear_iterations
217) PetscInt :: num_newton_iterations, num_linear_iterations
218) PetscInt :: snes_reason
219) PetscInt :: icut
220) PetscReal :: fnorm
221) PetscReal :: inorm
222) PetscReal :: scaled_fnorm
223) Vec :: residual_vec
224)
225) type(option_type), pointer :: option
226) type(solver_type), pointer :: solver
227)
228) solver => this%solver
229) option => process_model%option
230)
231) sum_newton_iterations = 0
232) sum_linear_iterations = 0
233) icut = 0
234)
235) call process_model%InitializeTimestep()
236)
237) call process_model%PreSolve()
238)
239) call PetscTime(log_start_time, ierr);CHKERRQ(ierr)
240)
241) call SNESSolve(solver%snes, PETSC_NULL_OBJECT, &
242) process_model%solution_vec, ierr);CHKERRQ(ierr)
243)
244) call PetscTime(log_end_time, ierr);CHKERRQ(ierr)
245)
246) this%cumulative_solver_time = &
247) this%cumulative_solver_time + &
248) (log_end_time - log_start_time)
249)
250) call SNESGetIterationNumber(solver%snes, num_newton_iterations, &
251) ierr);CHKERRQ(ierr)
252) call SNESGetLinearSolveIterations(solver%snes, num_linear_iterations, &
253) ierr);CHKERRQ(ierr)
254) call SNESGetConvergedReason(solver%snes, snes_reason, ierr);CHKERRQ(ierr)
255)
256) sum_newton_iterations = sum_newton_iterations + num_newton_iterations
257) sum_linear_iterations = sum_linear_iterations + num_linear_iterations
258)
259) if (snes_reason <= 0) then
260) if (option%print_screen_flag) then
261) print *, 'Newton solver failed to converge in steady-solve, reason: ', &
262) snes_reason
263) endif
264) failure = PETSC_TRUE
265) stop_flag = TS_STOP_END_SIMULATION
266) return
267) endif
268)
269) this%steps = this%steps + 1
270) this%cumulative_newton_iterations = &
271) this%cumulative_newton_iterations + sum_newton_iterations
272) this%cumulative_linear_iterations = &
273) this%cumulative_linear_iterations + sum_linear_iterations
274) this%cumulative_time_step_cuts = &
275) this%cumulative_time_step_cuts + icut
276)
277) this%num_newton_iterations = num_newton_iterations
278) this%num_linear_iterations = num_linear_iterations
279)
280) ! print screen output
281) call SNESGetFunction(solver%snes,residual_vec,PETSC_NULL_OBJECT, &
282) PETSC_NULL_INTEGER,ierr);CHKERRQ(ierr)
283) call VecNorm(residual_vec,NORM_2,fnorm,ierr);CHKERRQ(ierr)
284) call VecNorm(residual_vec,NORM_INFINITY,inorm,ierr);CHKERRQ(ierr)
285) if (option%print_screen_flag) then
286) select type(pm => process_model)
287) class is(pm_geomech_force_type)
288) if (associated(pm%geomech_realization%geomech_discretization%grid)) then
289) scaled_fnorm = fnorm/pm%geomech_realization%geomech_discretization% &
290) grid%nmax_node
291) else
292) scaled_fnorm = fnorm
293) endif
294) end select
295) write(*,*) ''
296) print *,' --> SNES Linear/Non-Linear Iterations = ', &
297) num_linear_iterations,' / ',num_newton_iterations
298) write(*,'(" --> SNES Residual: ",1p3e14.6)') fnorm, scaled_fnorm, inorm
299) endif
300)
301) if (option%print_screen_flag) print *, ""
302)
303) if (option%print_file_flag) then
304) write(option%fid_out, '(" STEADY-SOLVE ",i6," snes_conv_reason: ",i4,/, &
305) &" newton = ",i3," [",i8,"]", &
306) & " linear = ",i5," [",i10,"]")') &
307) this%steps, &
308) snes_reason,sum_newton_iterations, &
309) this%cumulative_newton_iterations,sum_linear_iterations, &
310) this%cumulative_linear_iterations
311) endif
312)
313) option%time = this%target_time
314) call process_model%FinalizeTimestep()
315)
316) if (option%print_screen_flag) print *, ""
317) ! check if the steady state option is selected in input deck
318) ! if yes then end simulation
319) if (option%steady_state) stop_flag = TS_STOP_END_SIMULATION
320)
321) end subroutine TimestepperSteadyStepDT
322)
323) ! ************************************************************************** !
324)
325) subroutine TimestepperSteadyInputRecord(this)
326) !
327) ! Prints information about the time stepper to the input record.
328) ! To get a## format, must match that in simulation types.
329) !
330) ! Author: Jenn Frederick, SNL
331) ! Date: 03/17/2016
332) !
333)
334) implicit none
335)
336) class(timestepper_steady_type) :: this
337)
338) PetscInt :: id
339) character(len=MAXWORDLENGTH) :: word
340)
341) id = INPUT_RECORD_UNIT
342)
343) write(id,'(a29)',advance='no') 'pmc timestepper: '
344) write(id,'(a)') this%name
345)
346) end subroutine TimestepperSteadyInputRecord
347)
348) end module Timestepper_Steady_class