Neko  0.9.99
A portable framework for high-order spectral element flow simulations
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  implicit none
40  private
41 
43  type, public :: time_step_controller_t
45  logical :: if_variable_dt
46  real(kind=rp) :: set_cfl
47  real(kind=rp) :: max_dt
48  integer :: max_update_frequency
49  integer :: dt_last_change
50  real(kind=rp) :: alpha !coefficient of running average
51  real(kind=rp) :: max_dt_increase_factor, min_dt_decrease_factor
52  real(kind=rp) :: dev_tol
53  contains
55  procedure, pass(this) :: init => time_step_controller_init
57  procedure, pass(this) :: set_dt => time_step_controller_set_dt
58 
59  end type time_step_controller_t
60 
61 contains
62 
65  subroutine time_step_controller_init(this, params)
66  class(time_step_controller_t), intent(inout) :: this
67  type(json_file), intent(inout) :: params
68 
69  this%dt_last_change = 0
70  call json_get_or_default(params, 'case.variable_timestep',&
71  this%if_variable_dt, .false.)
72  call json_get_or_default(params, 'case.target_cfl',&
73  this%set_cfl, 0.4_rp)
74  call json_get_or_default(params, 'case.max_timestep',&
75  this%max_dt, huge(0.0_rp))
76  call json_get_or_default(params, 'case.cfl_max_update_frequency',&
77  this%max_update_frequency, 0)
78  call json_get_or_default(params, 'case.cfl_running_avg_coeff',&
79  this%alpha, 0.5_rp)
80  call json_get_or_default(params, 'case.max_dt_increase_factor',&
81  this%max_dt_increase_factor, 1.2_rp)
82  call json_get_or_default(params, 'case.min_dt_decrease_factor',&
83  this%min_dt_decrease_factor, 0.5_rp)
84  call json_get_or_default(params, 'case.cfl_deviation_tolerance',&
85  this%dev_tol, 0.2_rp)
86 
87  end subroutine time_step_controller_init
88 
97  subroutine time_step_controller_set_dt(this, dt, cfl, cfl_avrg, tstep)
98  implicit none
99  class(time_step_controller_t), intent(inout) :: this
100  real(kind=rp), intent(inout) :: dt
101  real(kind=rp), intent(in) :: cfl
102  real(kind=rp), intent(inout) :: cfl_avrg
103  real(kind=rp) :: dt_old, scaling_factor
104  character(len=LOG_SIZE) :: log_buf
105  integer, intent(in):: tstep
106 
107  if (this%if_variable_dt .eqv. .true.) then
108  if (tstep .eq. 1) then
109  ! set the first dt for desired cfl
110  dt = min(this%set_cfl/cfl*dt, this%max_dt)
111  else
112  ! Calculate the average of cfl over the desired interval
113  cfl_avrg = this%alpha * cfl + (1-this%alpha) * cfl_avrg
114 
115  if (abs(cfl_avrg - this%set_cfl) .ge. &
116  this%dev_tol * this%set_cfl .and. &
117  this%dt_last_change .ge. this%max_update_frequency) then
118 
119  if (this%set_cfl/cfl .ge. 1) then
120  ! increase of time step
121  scaling_factor = min(this%max_dt_increase_factor, this%set_cfl/cfl)
122  else
123  ! reduction of time step
124  scaling_factor = max(this%min_dt_decrease_factor, this%set_cfl/cfl)
125  end if
126 
127  dt_old = dt
128  dt = scaling_factor * dt_old
129  dt = min(dt, this%max_dt)
130 
131  write(log_buf, '(A,E15.7,1x,A,E15.7)') 'Avrg CFL:', cfl_avrg, &
132  'set_cfl:', this%set_cfl
133  call neko_log%message(log_buf)
134 
135  write(log_buf, '(A,E15.7,1x,A,E15.7)') 'old dt:', dt_old, &
136  'new dt:', dt
137  call neko_log%message(log_buf)
138 
139  this%dt_last_change = 0
140 
141  else
142  this%dt_last_change = this%dt_last_change + 1
143  end if
144  end if
145 
146  end if
147 
148  end subroutine time_step_controller_set_dt
149 
150 
151 
152 
153 end module time_step_controller
Retrieves a parameter by name or assigns a provided default value. In the latter case also adds the m...
Definition: json_utils.f90:54
Utilities for retrieving parameters from the case files.
Definition: json_utils.f90:34
Logging routines.
Definition: log.f90:34
type(log_t), public neko_log
Global log stream.
Definition: log.f90:65
integer, parameter, public log_size
Definition: log.f90:42
integer, parameter, public rp
Global precision used in computations.
Definition: num_types.f90:12
Implements type time_step_controller.
subroutine time_step_controller_init(this, params)
Constructor.
subroutine time_step_controller_set_dt(this, dt, cfl, cfl_avrg, tstep)
Set new dt based on cfl if requested.
Provides a tool to set time step dt.
#define max(a, b)
Definition: tensor.cu:40