Neko 1.99.1
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
time_step_controller.f90
Go to the documentation of this file.
1! Copyright (c) 2022, The Neko Authors
2! All rights reserved.
3!
4! Redistribution and use in source and binary forms, with or without
5! modification, are permitted provided that the following conditions
6! are met:
7!
8! * Redistributions of source code must retain the above copyright
9! notice, this list of conditions and the following disclaimer.
10!
11! * Redistributions in binary form must reproduce the above
12! copyright notice, this list of conditions and the following
13! disclaimer in the documentation and/or other materials provided
14! with the distribution.
15!
16! * Neither the name of the authors nor the names of its
17! contributors may be used to endorse or promote products derived
18! from this software without specific prior written permission.
19!
20! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23! FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24! COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25! INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26! BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27! LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30! ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31! POSSIBILITY OF SUCH DAMAGE.
32!
35 use num_types, only : rp
36 use logger, only : neko_log, log_size
37 use json_module, only : json_file
39 use time_state, only : time_state_t
40 implicit none
41 private
42
44 type, public :: time_step_controller_t
45 logical :: is_variable_dt
46 real(kind=rp) :: cfl_trg
47 real(kind=rp) :: cfl_avg
48 real(kind=rp) :: max_dt, min_dt
49 integer :: max_update_frequency, min_update_frequency
50 integer :: dt_last_change
51 real(kind=rp) :: alpha
52 real(kind=rp) :: max_dt_increase_factor, min_dt_decrease_factor
53 real(kind=rp) :: dev_tol
54 contains
56 procedure, pass(this) :: init => time_step_controller_init
58 procedure, pass(this) :: set_dt => time_step_controller_set_dt
59
61
62contains
63
66 subroutine time_step_controller_init(this, params)
67 class(time_step_controller_t), intent(inout) :: this
68 type(json_file), intent(inout) :: params
69
70 this%dt_last_change = -1
71 call json_get_or_default(params, 'variable_timestep', &
72 this%is_variable_dt, .false.)
73 call json_get_or_default(params, 'target_cfl', &
74 this%cfl_trg, 0.4_rp)
75 call json_get_or_default(params, 'max_timestep', &
76 this%max_dt, huge(0.0_rp))
77 call json_get_or_default(params, 'min_timestep', &
78 this%min_dt, 0.0_rp)
79 call json_get_or_default(params, 'max_update_frequency',&
80 this%max_update_frequency, 0)
81 call json_get_or_default(params, 'min_update_frequency',&
82 this%min_update_frequency, huge(0))
83 call json_get_or_default(params, 'cfl_running_avg_coeff', &
84 this%alpha, 0.5_rp)
85 call json_get_or_default(params, 'max_dt_increase_factor', &
86 this%max_dt_increase_factor, 1.2_rp)
87 call json_get_or_default(params, 'min_dt_decrease_factor', &
88 this%min_dt_decrease_factor, 0.5_rp)
89 call json_get_or_default(params, 'cfl_deviation_tolerance', &
90 this%dev_tol, 0.2_rp)
91
92 end subroutine time_step_controller_init
93
101 subroutine time_step_controller_set_dt(this, time, cfl)
102 class(time_step_controller_t), intent(inout) :: this
103 type(time_state_t), intent(inout) :: time
104 real(kind=rp), intent(in) :: cfl
105 real(kind=rp) :: dt_old, scaling_factor
106 character(len=LOG_SIZE) :: log_buf
107
108 ! Check if variable dt is requested
109 if (.not. this%is_variable_dt) return
110
111 ! Reset the average cfl if it is the first time step since the last change
112 if (this%dt_last_change .eq. 0) then
113 this%cfl_avg = cfl
114 end if
115
116 if (this%dt_last_change .eq. -1) then
117
118 ! set the first dt for desired cfl
119 time%dt = max(min(this%cfl_trg / cfl * time%dt, &
120 this%max_dt), this%min_dt)
121 this%dt_last_change = 0
122 this%cfl_avg = cfl
123
124 else
125 ! Calculate the average of cfl over the desired interval
126 this%cfl_avg = this%alpha * cfl + (1 - this%alpha) * this%cfl_avg
127
128 if (abs(this%cfl_avg - this%cfl_trg) .ge. this%dev_tol * this%cfl_trg &
129 .and. this%dt_last_change .ge. this%max_update_frequency &
130 .or. this%dt_last_change .ge. this%min_update_frequency) then
131
132 if (this%cfl_trg/cfl .ge. 1) then
133 ! increase of time step
134 scaling_factor = min(this%max_dt_increase_factor, this%cfl_trg/cfl)
135 else
136 ! reduction of time step
137 scaling_factor = max(this%min_dt_decrease_factor, this%cfl_trg/cfl)
138 end if
139
140 dt_old = time%dt
141 time%dt = scaling_factor * dt_old
142 time%dt = max(min(time%dt, this%max_dt), this%min_dt)
143
144 write(log_buf, '(A,E15.7,1x,A,E15.7)') &
145 'Average CFL:', this%cfl_avg, &
146 'Target CFL:', this%cfl_trg
147 call neko_log%message(log_buf)
148
149 write(log_buf, '(A,E15.7,1x,A,E15.7)') 'Old dt:', dt_old, &
150 'New dt:', time%dt
151 call neko_log%message(log_buf)
152
153 this%dt_last_change = 0
154
155 else
156 this%dt_last_change = this%dt_last_change + 1
157 end if
158 end if
159
160 end subroutine time_step_controller_set_dt
161
162
163
164
165end module time_step_controller
Retrieves a parameter by name or assigns a provided default value. In the latter case also adds the m...
Utilities for retrieving parameters from the case files.
Logging routines.
Definition log.f90:34
type(log_t), public neko_log
Global log stream.
Definition log.f90:70
integer, parameter, public log_size
Definition log.f90:46
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:12
Module with things related to the simulation time.
Implements type time_step_controller.
subroutine time_step_controller_init(this, params)
Constructor.
subroutine time_step_controller_set_dt(this, time, cfl)
Set new dt based on cfl if requested.
A struct that contains all info about the time, expand as needed.
#define max(a, b)
Definition tensor.cu:40