timestepper_base.F90 coverage: 56.52 %func 72.13 %block
1) module Timestepper_Base_class
2)
3) use Waypoint_module
4)
5) use PFLOTRAN_Constants_module
6)
7) implicit none
8)
9) private
10)
11) #include "petsc/finclude/petscsys.h"
12)
13) PetscInt, parameter, public :: TS_CONTINUE = 0
14) PetscInt, parameter, public :: TS_STOP_END_SIMULATION = 1
15) PetscInt, parameter, public :: TS_STOP_MAX_TIME_STEP = 2
16) PetscInt, parameter, public :: TS_STOP_WALLCLOCK_EXCEEDED = 3
17) PetscInt, parameter, public :: TS_STOP_FAILURE = 4
18)
19) type, public :: timestepper_base_type
20)
21) character(len=MAXWORDLENGTH) :: name
22) PetscInt :: steps ! The number of time steps taken by the code.
23) PetscInt :: num_constant_time_steps ! number of contiguous time_steps of constant size
24)
25) PetscInt :: max_time_step ! Maximum number of time steps to be taken by the code.
26) PetscInt :: max_time_step_cuts ! Maximum number of timestep cuts within one time step.
27) PetscInt :: constant_time_step_threshold ! Steps needed after cutting to increase time step
28)
29) PetscInt :: cumulative_time_step_cuts ! Total number of cuts in the timestep taken.
30) PetscReal :: cumulative_solver_time
31)
32) PetscReal :: dt
33) PetscReal :: prev_dt
34) PetscReal :: dt_init
35) PetscReal :: dt_min
36) PetscReal :: dt_max
37) PetscBool :: revert_dt
38) PetscInt :: num_contig_revert_due_to_sync
39)
40) PetscBool :: init_to_steady_state
41) PetscBool :: run_as_steady_state
42) PetscReal :: steady_state_rel_tol
43)
44) PetscBool :: time_step_cut_flag ! flag toggled if timestep is cut
45)
46) PetscLogDouble :: start_time
47) PetscInt :: start_time_step ! the first time step of a given run
48) PetscReal :: time_step_tolerance ! scalar used in determining time step size
49) PetscReal :: target_time ! time at end of "synchronized" time step
50) PetscBool :: print_ekg
51)
52) type(waypoint_type), pointer :: cur_waypoint
53) type(waypoint_type), pointer :: prev_waypoint
54)
55) contains
56)
57) procedure, public :: ReadInput => TimestepperBaseRead
58) procedure, public :: Init => TimestepperBaseInit
59) procedure, public :: InitializeRun => TimestepperBaseInitializeRun
60) procedure, public :: SetTargetTime => TimestepperBaseSetTargetTime
61) procedure, public :: StepDT => TimestepperBaseStepDT
62) procedure, public :: UpdateDT => TimestepperBaseUpdateDT
63) procedure, public :: CheckpointBinary => TimestepperBaseCheckpointBinary
64) procedure, public :: CheckpointHDF5 => TimestepperBaseCheckpointHDF5
65) procedure, public :: RestartBinary => TimestepperBaseRestartBinary
66) procedure, public :: RestartHDF5 => TimestepperBaseRestartHDF5
67) procedure, public :: Reset => TimestepperBaseReset
68) procedure, public :: WallClockStop => TimestepperBaseWallClockStop
69) procedure, public :: PrintInfo => TimestepperBasePrintInfo
70) procedure, public :: InputRecord => TimestepperBaseInputRecord
71) procedure, public :: FinalizeRun => TimestepperBaseFinalizeRun
72) procedure, public :: Strip => TimestepperBaseStrip
73) procedure, public :: Destroy => TimestepperBaseDestroy
74)
75) end type timestepper_base_type
76)
77) type, public :: stepper_base_header_type
78) PetscReal :: time
79) PetscReal :: dt
80) PetscReal :: prev_dt
81) PetscInt :: num_steps
82) PetscInt :: cumulative_time_step_cuts
83) PetscInt :: num_constant_time_steps
84) PetscInt :: num_contig_revert_due_to_sync
85) PetscInt :: revert_dt
86) end type stepper_base_header_type
87)
88) public :: TimestepperBaseCreate, &
89) TimestepperBaseProcessKeyword, &
90) TimestepperBaseStrip, &
91) TimestepperBaseInit, &
92) TimestepperBaseSetHeader, &
93) TimestepperBaseGetHeader, &
94) TimestepperBaseReset, &
95) TimestepperBaseRegisterHeader, &
96) TimestepperBasePrintInfo, &
97) TimestepperBaseInputRecord
98)
99) contains
100)
101) ! ************************************************************************** !
102)
103) function TimestepperBaseCreate()
104) !
105) ! Allocates and initializes a new Timestepper object
106) !
107) ! Author: Glenn Hammond
108) ! Date: 10/25/07
109) !
110)
111) implicit none
112)
113) class(timestepper_base_type), pointer :: TimestepperBaseCreate
114)
115) class(timestepper_base_type), pointer :: this
116)
117) allocate(this)
118) call this%Init()
119)
120) TimestepperBaseCreate => this
121)
122) end function TimestepperBaseCreate
123)
124) ! ************************************************************************** !
125)
126) subroutine TimestepperBaseInit(this)
127) !
128) ! Allocates and initializes a new Timestepper object
129) !
130) ! Author: Glenn Hammond
131) ! Date: 07/01/13
132) !
133)
134) implicit none
135)
136) class(timestepper_base_type) :: this
137)
138) this%name = ''
139) this%steps = 0
140) this%num_constant_time_steps = 0
141)
142) this%max_time_step = 999999
143) this%max_time_step_cuts = 16
144) this%constant_time_step_threshold = 5
145)
146) this%cumulative_time_step_cuts = 0
147) this%cumulative_solver_time = 0.d0
148)
149) this%start_time = 0.d0
150) this%start_time_step = 0
151) this%time_step_tolerance = 0.1d0
152) this%target_time = 0.d0
153)
154) this%prev_dt = 0.d0
155) this%dt = 1.d0
156) this%dt_init = 1.d0
157) this%dt_min = 1.d-20 ! Ten zeptoseconds.
158) this%dt_max = 3.1536d6 ! One-tenth of a year.
159)
160) this%time_step_cut_flag = PETSC_FALSE
161)
162) this%init_to_steady_state = PETSC_FALSE
163) this%steady_state_rel_tol = 1.d-8
164) this%run_as_steady_state = PETSC_FALSE
165)
166) nullify(this%cur_waypoint)
167) nullify(this%prev_waypoint)
168) this%revert_dt = PETSC_FALSE
169) this%num_contig_revert_due_to_sync = 0
170) this%print_ekg = PETSC_FALSE
171)
172) end subroutine TimestepperBaseInit
173)
174) ! ************************************************************************** !
175)
176) subroutine TimestepperBaseInitializeRun(this,option)
177) !
178) ! Initializes the timestepper for the simulation. This is more than just
179) ! initializing parameters.
180) !
181) ! Author: Glenn Hammond
182) ! Date: 11/21/14
183) !
184)
185) use Option_module
186)
187) implicit none
188)
189) class(timestepper_base_type) :: this
190) type(option_type) :: option
191)
192) call this%PrintInfo(option)
193) option%time = this%target_time
194) ! For the case where the second waypoint is a printout after the first time
195) ! step, we must increment the waypoint beyond the first (time=0.) waypoint.
196) ! Otherwise the second time step will be zero. - geh
197) if (this%cur_waypoint%time < 1.d-40) then
198) this%cur_waypoint => this%cur_waypoint%next
199) endif
200)
201) end subroutine TimestepperBaseInitializeRun
202)
203) ! ************************************************************************** !
204)
205) subroutine TimestepperBaseRead(this,input,option)
206) !
207) ! Reads parameters associated with time stepper
208) !
209) ! Author: Glenn Hammond
210) ! Date: 02/23/08
211) !
212)
213) use Option_module
214) use Input_Aux_module
215)
216) implicit none
217)
218) class(timestepper_base_type) :: this
219) type(input_type), pointer :: input
220) type(option_type) :: option
221)
222) option%io_buffer = 'TimestepperBaseRead not supported. Requires extension.'
223) call printErrMsg(option)
224)
225) end subroutine TimestepperBaseRead
226)
227) ! ************************************************************************** !
228)
229) subroutine TimestepperBaseProcessKeyword(this,input,option,keyword)
230) !
231) ! Updates time step
232) !
233) ! Author: Glenn Hammond
234) ! Date: 03/20/13
235) !
236)
237) use Option_module
238) use String_module
239) use Input_Aux_module
240)
241) implicit none
242)
243) class(timestepper_base_type) :: this
244) character(len=MAXWORDLENGTH) :: keyword
245) type(input_type) :: input
246) type(option_type) :: option
247)
248) select case(trim(keyword))
249)
250) case('NUM_STEPS_AFTER_TS_CUT')
251) call InputReadInt(input,option,this%constant_time_step_threshold)
252) call InputDefaultMsg(input,option,'num_constant_time_steps_after_ts_cut')
253)
254) case('MAX_STEPS')
255) call InputReadInt(input,option,this%max_time_step)
256) call InputDefaultMsg(input,option,'max_time_step')
257)
258) case('MAX_TS_CUTS')
259) call InputReadInt(input,option,this%max_time_step_cuts)
260) call InputDefaultMsg(input,option,'max_time_step_cuts')
261)
262) case('INITIALIZE_TO_STEADY_STATE')
263) this%init_to_steady_state = PETSC_TRUE
264) call InputReadDouble(input,option,this%steady_state_rel_tol)
265) call InputDefaultMsg(input,option,'steady state convergence relative &
266) &tolerance')
267)
268) case('RUN_AS_STEADY_STATE')
269) this%run_as_steady_state = PETSC_TRUE
270)
271) case('PRINT_EKG')
272) this%print_ekg = PETSC_TRUE
273) option%print_ekg = PETSC_TRUE
274)
275) case('MAX_PRESSURE_CHANGE','MAX_TEMPERATURE_CHANGE', &
276) 'MAX_CONCENTRATION_CHANGE','MAX_SATURATION_CHANGE', &
277) 'PRESSURE_DAMPENING_FACTOR','SATURATION_CHANGE_LIMIT', &
278) 'PRESSURE_CHANGE_LIMIT','TEMPERATURE_CHANGE_LIMIT')
279) option%io_buffer = 'Keyword "' // trim(keyword) // '" has been &
280) &deprecated in TIMESTEPPER and moved to the FLOW PM OPTIONS block.'
281) call printErrMsg(option)
282) case default
283) call InputKeywordUnrecognized(keyword,'TIMESTEPPER',option)
284) end select
285)
286) end subroutine TimestepperBaseProcessKeyword
287)
288) ! ************************************************************************** !
289)
290) subroutine TimestepperBaseUpdateDT(this,process_model)
291) !
292) ! Updates time step
293) !
294) ! Author: Glenn Hammond
295) ! Date: 03/20/13
296) !
297)
298) use PM_Base_class
299) use Option_module
300)
301) implicit none
302)
303) class(timestepper_base_type) :: this
304) class(pm_base_type) :: process_model
305)
306) process_model%option%io_buffer = 'TimestepperBaseStepDT must be extended.'
307) call printErrMsg(process_model%option)
308)
309) end subroutine TimestepperBaseUpdateDT
310)
311) ! ************************************************************************** !
312)
313) subroutine TimestepperBaseSetTargetTime(this,sync_time,option,stop_flag, &
314) snapshot_plot_flag, &
315) observation_plot_flag, &
316) massbal_plot_flag,checkpoint_flag)
317) !
318) ! Sets target time for timestepper
319) !
320) ! Author: Glenn Hammond
321) ! Date: 03/20/13
322) !
323)
324) use Option_module
325)
326) implicit none
327)
328) class(timestepper_base_type) :: this
329) PetscReal :: sync_time
330) type(option_type) :: option
331) PetscInt :: stop_flag
332) PetscBool :: snapshot_plot_flag
333) PetscBool :: observation_plot_flag
334) PetscBool :: massbal_plot_flag
335) PetscBool :: checkpoint_flag
336)
337) PetscReal :: target_time
338) PetscReal :: dt
339) PetscReal :: dt_max
340) PetscInt :: cumulative_time_steps
341) PetscInt :: max_time_step
342) PetscReal :: max_time
343) PetscReal :: tolerance
344) PetscBool :: force_to_match_waypoint
345) PetscBool :: equal_to_or_exceeds_waypoint
346) PetscBool :: equal_to_or_exceeds_sync_time
347) PetscBool :: revert_due_to_waypoint
348) PetscBool :: revert_due_to_sync_time
349) PetscBool :: truncated_due_to_next_dt_max
350) PetscReal :: temp_time
351) type(waypoint_type), pointer :: cur_waypoint, next_waypoint, prev_waypoint
352)
353) !geh: for debugging
354) #ifdef DEBUG
355) option%io_buffer = 'TimestepperBaseSetTargetTime()'
356) call printMsg(option)
357) #endif
358)
359) if (this%time_step_cut_flag) then
360) this%time_step_cut_flag = PETSC_FALSE
361) !geh: pointing the cur_waypoint back may cause problems in the checkpoint
362) ! file. There is no way of knowing whether prev_waypoint is different
363) ! from cur_waypoint as most of the time it will be identical. I believe
364) ! the only way around this is to check associated(cur,prev) to see if
365) ! they differ and set a flag in the checkpoint file. But even this will
366) ! not work if more than one waypoint previous.
367) this%cur_waypoint => this%prev_waypoint
368) else
369) ! If the maximum time step size decreased in the past step, need to set
370) ! the time step size to the minimum of the this%prev_dt and
371) ! this%dt_max. However, if we have to revert twice in a row, throw
372) ! away the old time step and move on.
373) if (this%revert_dt .and. &
374) this%num_contig_revert_due_to_sync < 2) then
375) this%dt = min(this%prev_dt,this%dt_max)
376) endif
377) endif
378) this%revert_dt = PETSC_FALSE ! reset back to false
379) revert_due_to_waypoint = PETSC_FALSE
380) revert_due_to_sync_time = PETSC_FALSE
381)
382) dt = this%dt
383) this%prev_dt = dt
384) cur_waypoint => this%cur_waypoint
385) ! need previous waypoint for reverting back on time step cut
386) this%prev_waypoint => this%cur_waypoint
387) ! dt_max must be lagged. it can be updated below, but it must lag a waypoint.
388) cumulative_time_steps = this%steps
389) max_time_step = this%max_time_step
390) tolerance = this%time_step_tolerance
391) ! target_time = this%target_time + dt
392)
393) do ! we cycle just in case the next waypoint is beyond the target_time
394) dt_max = cur_waypoint%dt_max
395) dt = min(dt,dt_max)
396) ! ensure that the time step does not overstep the next waypoint time +
397) ! dtmax combination.
398) target_time = this%target_time + dt
399)
400) !---! This section of code ensures that no time step over steps the next
401) ! maximum time step (dt_max) if a waypoint is surpassed.
402) force_to_match_waypoint = PETSC_FALSE
403) if (associated(cur_waypoint%next)) then
404) if (dt_max > cur_waypoint%next%dt_max .and. &
405) dt > cur_waypoint%next%dt_max .and. &
406) target_time > cur_waypoint%time) then
407) if (this%target_time + cur_waypoint%next%dt_max < &
408) cur_waypoint%time) then
409) force_to_match_waypoint = PETSC_TRUE
410) else
411) dt = cur_waypoint%next%dt_max
412) target_time = this%target_time + dt
413) endif
414) endif
415) endif
416) !---
417) ! If a waypoint calls for a plot or change in src/sinks, adjust time step
418) ! to match waypoint.
419) force_to_match_waypoint = WaypointForceMatchToTime(cur_waypoint) .or. &
420) force_to_match_waypoint
421) equal_to_or_exceeds_waypoint = target_time + tolerance*dt >= &
422) cur_waypoint%time
423) equal_to_or_exceeds_sync_time = target_time + tolerance*dt >= sync_time
424) if (equal_to_or_exceeds_sync_time .and. sync_time < cur_waypoint%time) then
425) ! flip back if the sync time arrives before the waypoint time.
426) equal_to_or_exceeds_waypoint = PETSC_FALSE
427) endif
428) if (equal_to_or_exceeds_sync_time .or. &
429) (equal_to_or_exceeds_waypoint .and. force_to_match_waypoint)) then
430) if (force_to_match_waypoint) then
431) max_time = min(sync_time,cur_waypoint%time)
432) else
433) max_time = sync_time
434) endif
435) ! decrement by time step size
436) target_time = target_time - dt
437) ! set new time step size based on max time
438) dt = max_time - target_time
439) if (dt > dt_max .and. &
440) ! 1 sec tolerance to avoid cancellation
441) dabs(dt-dt_max) > 1.d0) then
442) dt = dt_max ! error from waypoint%time - time
443) target_time = target_time + dt
444) else
445) target_time = max_time
446) if (equal_to_or_exceeds_waypoint) then
447) ! Since the time step was cut to match the waypoint, we want to set
448) ! the time step back to its prior value after the waypoint is met.
449) ! %revert_dt is a flag that does so above.
450) if (force_to_match_waypoint) revert_due_to_waypoint = PETSC_TRUE
451) if (cur_waypoint%print_snap_output) snapshot_plot_flag = PETSC_TRUE
452) if (cur_waypoint%print_obs_output) observation_plot_flag = PETSC_TRUE
453) if (cur_waypoint%print_msbl_output) massbal_plot_flag = PETSC_TRUE
454) if (cur_waypoint%print_checkpoint) checkpoint_flag = PETSC_TRUE
455) endif
456) if (equal_to_or_exceeds_sync_time) then
457) ! If the time step was cut to match the sync time, we want to set
458) ! the time step back to its prior value. However, if the time step
459) ! is close to its full previous value, this constraint is unnecessary
460) ! and limits the ability of process model couplers "below" to catch up
461) ! with those above. Thus the conditional (dt <= .5 prev_dt) below.
462) !-Also note that if this timestepper is at a depth in the process
463) ! model coupler greater than 1 (not the top process model coupler)
464) ! the timestepper will constantly be reverting to sync due to the
465) ! tolerance applied above without the underlying conditional.
466) ! if (dt < 0.99d0 * this%prev_dt) then
467) if (dt <= 0.5d0 * this%prev_dt) then
468) revert_due_to_sync_time = PETSC_TRUE
469) endif
470) endif
471) if (max_time >= cur_waypoint%time) then
472) cur_waypoint => cur_waypoint%next
473) endif
474) endif
475) exit
476) else if (target_time > cur_waypoint%time) then
477) cur_waypoint => cur_waypoint%next
478) else
479) exit
480) endif
481) enddo
482) ! subtract 1 from max_time_steps since we still have to complete the current
483) ! time step
484)
485) if (revert_due_to_sync_time .or. revert_due_to_waypoint) then
486) this%revert_dt = PETSC_TRUE
487) if (revert_due_to_sync_time) then
488) this%num_contig_revert_due_to_sync = &
489) this%num_contig_revert_due_to_sync + 1
490) endif
491) else
492) this%num_contig_revert_due_to_sync = 0
493) endif
494)
495)
496) if (cumulative_time_steps >= max_time_step-1) then
497) nullify(cur_waypoint)
498) stop_flag = TS_STOP_MAX_TIME_STEP
499) endif
500)
501) ! update maximum time step size to current waypoint value
502) if (associated(cur_waypoint)) then
503) dt_max = cur_waypoint%dt_max
504) else if (stop_flag /= TS_STOP_MAX_TIME_STEP) then
505) stop_flag = TS_STOP_END_SIMULATION ! stop after end of time step
506) endif
507)
508) option%refactor_dt = dt
509) this%dt = dt
510) this%dt_max = dt_max
511) this%target_time = target_time
512) this%cur_waypoint => cur_waypoint
513)
514) end subroutine TimestepperBaseSetTargetTime
515)
516) ! ************************************************************************** !
517)
518) subroutine TimestepperBaseStepDT(this,process_model,stop_flag)
519) !
520) ! Steps forward one step in time
521) !
522) ! Author: Glenn Hammond
523) ! Date: 03/20/13
524) !
525)
526) use PM_Base_class
527) use Option_module
528) use Output_module, only : Output
529)
530) implicit none
531)
532) class(timestepper_base_type) :: this
533) class(pm_base_type) :: process_model
534) PetscInt :: stop_flag
535)
536) type(option_type), pointer :: option
537)
538) option => process_model%option
539)
540) option%io_buffer = 'TimestepperBaseStepDT must be extended.'
541) call printErrMsg(option)
542)
543) end subroutine TimestepperBaseStepDT
544)
545) ! ************************************************************************** !
546)
547) subroutine TimestepperBasePrintInfo(this,option)
548) !
549) ! Prints information about time stepper
550) !
551) ! Author: Glenn Hammond
552) ! Date: 02/23/08
553) !
554)
555) use Option_module
556)
557) implicit none
558)
559) class(timestepper_base_type) :: this
560) type(option_type) :: option
561)
562) character(len=MAXSTRINGLENGTH) :: string
563)
564) if (OptionPrintToScreen(option)) then
565) write(*,*)
566) write(*,'(a)') trim(this%name) // ' Time Stepper'
567) write(string,*) this%max_time_step
568) write(*,'("max steps:",x,a)') trim(adjustl(string))
569) write(string,*) this%constant_time_step_threshold
570) write(*,'("max constant cumulative time steps:",x,a)') &
571) trim(adjustl(string))
572) write(string,*) this%max_time_step_cuts
573) write(*,'("max cuts:",x,a)') trim(adjustl(string))
574) endif
575) if (OptionPrintToFile(option)) then
576) write(option%fid_out,*)
577) write(option%fid_out,'(a)') trim(this%name) // ' Time Stepper'
578) write(string,*) this%max_time_step
579) write(option%fid_out,'("max steps:",x,a)') trim(adjustl(string))
580) write(string,*) this%constant_time_step_threshold
581) write(option%fid_out,'("max constant cumulative time steps:",x,a)') &
582) trim(adjustl(string))
583) write(string,*) this%max_time_step_cuts
584) write(option%fid_out,'("max cuts:",x,a)') trim(adjustl(string))
585) endif
586)
587) end subroutine TimestepperBasePrintInfo
588)
589) ! ************************************************************************** !
590)
591) subroutine TimestepperBaseInputRecord(this)
592) !
593) ! Prints information about the time stepper to the input record.
594) !
595) ! Author: Jenn Frederick, SNL
596) ! Date: 03/17/2016
597) !
598)
599) implicit none
600)
601) class(timestepper_base_type) :: this
602)
603) #ifdef DEBUG
604) call printMsg(this%option,'TimestepperBaseInputRecord()')
605) #endif
606)
607) write(*,*) 'TimestepperBaseInputRecord must be extended for &
608) &each timestepper mode.'
609) stop
610)
611) end subroutine TimestepperBaseInputRecord
612)
613) ! ************************************************************************** !
614)
615) subroutine TimestepperBaseCheckpointBinary(this,viewer,option)
616) !
617) ! Checkpoints parameters/variables associated with
618) ! a time stepper.
619) !
620) ! Author: Glenn Hammond
621) ! Date: 07/25/13
622) !
623)
624) use Option_module
625)
626) implicit none
627)
628) #include "petsc/finclude/petscviewer.h"
629)
630) class(timestepper_base_type) :: this
631) PetscViewer :: viewer
632) type(option_type) :: option
633)
634) option%io_buffer = 'TimestepperBaseCheckpointBinary must be extended.'
635) call printErrMsg(option)
636)
637) end subroutine TimestepperBaseCheckpointBinary
638)
639) ! ************************************************************************** !
640)
641) subroutine TimestepperBaseCheckpointHDF5(this, chk_grp_id, option)
642) !
643) ! Checkpoints parameters/variables associated with a time stepper to a HDF5.
644) !
645) ! Author: Gautam Bisht, LBNL
646) ! Date: 07/30/15
647) !
648)
649) use Option_module
650)
651) implicit none
652)
653) class(timestepper_base_type) :: this
654) PetscInt :: chk_grp_id
655) type(option_type) :: option
656)
657) option%io_buffer = 'TimestepperBaseCheckpointHDF5 must be extended.'
658) call printErrMsg(option)
659)
660) end subroutine TimestepperBaseCheckpointHDF5
661)
662) ! ************************************************************************** !
663)
664) subroutine TimestepperBaseRestartHDF5(this, chk_grp_id, option)
665) !
666) ! Restart parameters/variables associated with a time stepper to a HDF5.
667) !
668) ! Author: Gautam Bisht, LBNL
669) ! Date: 08/16/15
670) !
671)
672) use Option_module
673)
674) implicit none
675)
676) class(timestepper_base_type) :: this
677) PetscInt :: chk_grp_id
678) type(option_type) :: option
679)
680) option%io_buffer = 'TimestepperBaseRestartHDF5 must be extended.'
681) call printErrMsg(option)
682)
683) end subroutine TimestepperBaseRestartHDF5
684)
685) ! ************************************************************************** !
686)
687) subroutine TimestepperBaseRegisterHeader(this,bag,header)
688) !
689) ! Register header entries.
690) !
691) ! Author: Glenn Hammond
692) ! Date: 07/30/13
693) !
694)
695) use Option_module
696)
697) implicit none
698)
699) #include "petsc/finclude/petscbag.h"
700)
701) class(timestepper_base_type) :: this
702) class(stepper_base_header_type) :: header
703) PetscBag :: bag
704)
705) PetscErrorCode :: ierr
706)
707) ! bagsize = 8 * 8 bytes = 64 bytes
708) call PetscBagRegisterReal(bag,header%time,0,"time","",ierr);CHKERRQ(ierr)
709) call PetscBagRegisterReal(bag,header%dt,0,"dt","",ierr);CHKERRQ(ierr)
710) call PetscBagRegisterReal(bag,header%prev_dt,0,"prev_dt","", &
711) ierr);CHKERRQ(ierr)
712) call PetscBagRegisterInt(bag,header%num_steps,0,"num_steps","", &
713) ierr);CHKERRQ(ierr)
714) call PetscBagRegisterInt(bag,header%cumulative_time_step_cuts,0, &
715) "cumulative_time_step_cuts","",ierr);CHKERRQ(ierr)
716) call PetscBagRegisterInt(bag,header%num_constant_time_steps,0, &
717) "num_constant_time_steps","",ierr);CHKERRQ(ierr)
718) call PetscBagRegisterInt(bag,header%num_contig_revert_due_to_sync,0, &
719) "num_contig_revert_due_to_sync","", &
720) ierr);CHKERRQ(ierr)
721) call PetscBagRegisterInt(bag,header%revert_dt,0, &
722) "revert_dt","",ierr);CHKERRQ(ierr)
723)
724) end subroutine TimestepperBaseRegisterHeader
725)
726) ! ************************************************************************** !
727)
728) subroutine TimestepperBaseSetHeader(this,bag,header)
729) !
730) ! Sets values in checkpoint header.
731) !
732) ! Author: Glenn Hammond
733) ! Date: 07/25/13
734) !
735)
736) use Option_module
737)
738) implicit none
739)
740) #include "petsc/finclude/petscbag.h"
741)
742) class(timestepper_base_type) :: this
743) class(stepper_base_header_type) :: header
744) PetscBag :: bag
745)
746) PetscErrorCode :: ierr
747)
748) header%time = this%target_time
749) header%dt = this%dt
750) header%prev_dt = this%prev_dt
751) header%num_steps = this%steps
752) header%cumulative_time_step_cuts = this%cumulative_time_step_cuts
753) header%num_constant_time_steps = this%num_constant_time_steps
754) header%num_contig_revert_due_to_sync = this%num_contig_revert_due_to_sync
755) header%revert_dt = ZERO_INTEGER
756) if (this%revert_dt) then
757) header%revert_dt = ONE_INTEGER
758) endif
759)
760) end subroutine TimestepperBaseSetHeader
761)
762) ! ************************************************************************** !
763)
764) subroutine TimestepperBaseRestartBinary(this,viewer,option)
765) !
766) ! Restarts parameters/variables associated with
767) ! a time stepper.
768) !
769) ! Author: Glenn Hammond
770) ! Date: 07/25/13
771) !
772)
773) use Option_module
774)
775) implicit none
776)
777) #include "petsc/finclude/petscviewer.h"
778)
779) class(timestepper_base_type) :: this
780) PetscViewer :: viewer
781) type(option_type) :: option
782)
783) option%io_buffer = 'TimestepperBaseRestartBinary must be extended.'
784) call printErrMsg(option)
785)
786) end subroutine TimestepperBaseRestartBinary
787)
788) ! ************************************************************************** !
789)
790) subroutine TimestepperBaseGetHeader(this,header)
791) !
792) ! Gets values in checkpoint header.
793) !
794) ! Author: Glenn Hammond
795) ! Date: 07/25/13
796) !
797)
798) use Option_module
799)
800) implicit none
801)
802) #include "petsc/finclude/petscbag.h"
803)
804) class(timestepper_base_type) :: this
805) class(stepper_base_header_type) :: header
806)
807) this%target_time = header%time
808) this%dt = header%dt
809) this%prev_dt = header%prev_dt
810) this%steps = header%num_steps
811) this%cumulative_time_step_cuts = header%cumulative_time_step_cuts
812) this%num_constant_time_steps = header%num_constant_time_steps
813) this%num_contig_revert_due_to_sync = header%num_contig_revert_due_to_sync
814) this%revert_dt = (header%revert_dt == ONE_INTEGER)
815)
816) end subroutine TimestepperBaseGetHeader
817)
818) ! ************************************************************************** !
819)
820) subroutine TimestepperBaseReset(this)
821) !
822) ! Zeros timestepper object members.
823) !
824) ! Author: Glenn Hammond
825) ! Date: 01/20/14
826) !
827)
828) implicit none
829)
830)
831) class(timestepper_base_type) :: this
832)
833) this%target_time = 0.d0
834) this%dt = this%dt_init
835) this%prev_dt = 0.d0
836) this%steps = 0
837) this%cumulative_time_step_cuts = 0
838) this%num_constant_time_steps = 0
839) this%num_contig_revert_due_to_sync = 0
840) this%revert_dt = PETSC_FALSE
841)
842) end subroutine TimestepperBaseReset
843)
844) ! ************************************************************************** !
845)
846) function TimestepperBaseWallClockStop(this,option)
847) !
848) ! Stops time stepping when a prescribed wall clock time has been exceeded.
849) !
850) ! Author: Glenn Hammond
851) ! Date: 08/08/14
852) !
853) use Option_module
854)
855) implicit none
856)
857) class(timestepper_base_type) :: this
858) type(option_type) :: option
859)
860) PetscBool :: TimestepperBaseWallclockStop
861) PetscLogDouble :: current_time, average_step_time
862) PetscErrorCode :: ierr
863)
864) ! if a simulation wallclock duration time is set, check to see that the
865) ! next time step will not exceed that value. If it does, print the
866) ! checkpoint and exit
867) TimestepperBaseWallclockStop = PETSC_FALSE
868) if (option%wallclock_stop_flag) then
869) call PetscTime(current_time, ierr)
870) average_step_time = (current_time-option%start_time)/ &
871) dble(this%steps-this%start_time_step+1) &
872) *2.d0 ! just to be safe, double it
873) if (average_step_time + current_time > option%wallclock_stop_time) then
874) TimestepperBaseWallclockStop = PETSC_TRUE
875) endif
876) endif
877)
878) end function TimestepperBaseWallClockStop
879)
880)
881) ! ************************************************************************** !
882)
883) subroutine TimestepperBasePrintEKG(this)
884) !
885) ! Deallocates members of a time stepper
886) !
887) ! Author: Glenn Hammond
888) ! Date: 07/22/13
889) !
890)
891) implicit none
892)
893) class(timestepper_base_type) :: this
894)
895)
896)
897) end subroutine TimestepperBasePrintEKG
898)
899) ! ************************************************************************** !
900)
901) recursive subroutine TimestepperBaseFinalizeRun(this,option)
902) !
903) ! Finalizes the time stepping
904) !
905) ! Author: Glenn Hammond
906) ! Date: 07/22/13
907) !
908)
909) use Option_module
910)
911) implicit none
912)
913) class(timestepper_base_type) :: this
914) type(option_type) :: option
915)
916) character(len=MAXSTRINGLENGTH) :: string
917)
918) #ifdef DEBUG
919) call printMsg(option,'TimestepperBaseFinalizeRun()')
920) #endif
921)
922) if (OptionPrintToScreen(option)) then
923) write(*,'(/,a," TS Base"," steps = ",i6," cuts = ",i6)') &
924) trim(this%name), &
925) this%steps, &
926) this%cumulative_time_step_cuts
927) write(string,'(f12.1)') this%cumulative_solver_time
928) write(*,'(a)') trim(this%name) // ' TS Base solver time = ' // &
929) trim(adjustl(string)) // ' seconds'
930) endif
931)
932) end subroutine TimestepperBaseFinalizeRun
933)
934) ! ************************************************************************** !
935)
936) subroutine TimestepperBaseStrip(this)
937) !
938) ! Deallocates members of a time stepper
939) !
940) ! Author: Glenn Hammond
941) ! Date: 07/22/13
942) !
943)
944) implicit none
945)
946) class(timestepper_base_type) :: this
947)
948) end subroutine TimestepperBaseStrip
949)
950) ! ************************************************************************** !
951)
952) subroutine TimestepperBaseDestroy(this)
953) !
954) ! Deallocates a time stepper
955) !
956) ! Author: Glenn Hammond
957) ! Date: 11/01/07
958) !
959)
960) implicit none
961)
962) class(timestepper_base_type) :: this
963)
964) call TimestepperBaseStrip(this)
965)
966) ! deallocate(this)
967) ! nullify(this)
968)
969) end subroutine TimestepperBaseDestroy
970)
971) end module Timestepper_Base_class