Neko 1.99.1
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
time_based_controller.f90
Go to the documentation of this file.
1! Copyright (c) 2023, 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 utils, only : neko_error
37 use time_state, only : time_state_t
38 implicit none
39 private
40
50 real(kind=rp) :: frequency = 0.0_rp
52 real(kind=rp) :: time_interval = 0.0_rp
54 integer :: nsteps = 0
56 real(kind=rp) :: start_time = 0.0_rp
58 real(kind=rp) :: end_time = 0.0_rp
60 integer :: nexecutions = 0
62 logical :: never = .false.
65 character(len=:), allocatable :: control_mode
67 real(kind=rp) :: control_value
68
69 contains
71 procedure, pass(this) :: init => time_based_controller_init
73 procedure, pass(this) :: check => time_based_controller_check
75 procedure, pass(this) :: register_execution => &
78 procedure, pass(this) :: set_counter => &
80
82
83 interface assignment(=)
85 end interface assignment(=)
86
87contains
88
93 subroutine time_based_controller_init(this, start_time, end_time, &
94 control_mode, control_value)
95 class(time_based_controller_t), intent(inout) :: this
96 real(kind=rp), intent(in) :: start_time
97 real(kind=rp), intent(in) :: end_time
98 character(len=*), intent(in) :: control_mode
99 real(kind=rp), intent(in) :: control_value
100
101 this%start_time = start_time
102 this%end_time = end_time
103 this%control_mode = control_mode
104 this%control_value = control_value
105
106 if (trim(control_mode) .eq. 'simulationtime') then
107 this%time_interval = control_value
108 this%frequency = 1/this%time_interval
109 this%nsteps = 0
110 else if (trim(control_mode) .eq. 'nsamples') then
111 if (control_value .le. 0) then
112 call neko_error("nsamples must be positive")
113 end if
114
115 this%frequency = control_value / (end_time - start_time)
116 this%time_interval = 1.0_rp / this%frequency
117 this%nsteps = 0
118 else if (trim(control_mode) .eq. 'tsteps') then
119 this%nsteps = control_value
120 ! if the timestep will be variable, we cannot compute these.
121 this%frequency = 0
122 this%time_interval = 0
123 else if (trim(control_mode) .eq. 'never') then
124 this%never = .true.
125 else
126 call neko_error("The control parameter must be simulationtime, nsamples&
127 & tsteps, or never, but received "//trim(control_mode))
128 end if
129 end subroutine time_based_controller_init
130
140 function time_based_controller_check(this, time, force) result(check)
141 class(time_based_controller_t), intent(inout) :: this
142 type(time_state_t), intent(in) :: time
143 logical, intent(in), optional :: force
144 real(kind=rp) :: t
145 integer :: tstep
146 real(kind=rp) :: dt
147 logical :: check
148 logical :: ifforce
149
150 t = time%t - time%start_time
151 dt = time%dt
152 tstep = time%tstep
153
154 if (present(force)) then
155 ifforce = force
156 else
157 ifforce = .false.
158 end if
159
160 check = .false.
161 if (ifforce) then
162 check = .true.
163 else if (this%never) then
164 check = .false.
165 else if (time%t - this%start_time .gt. this%end_time - this%start_time) then
166 check = .false.
167 else if ( (this%nsteps .eq. 0) .and. &
168 (t .ge. this%nexecutions * this%time_interval - 0.1_rp * dt) ) then
169 check = .true.
170 else if (this%nsteps .gt. 0) then
171 if (mod(tstep, this%nsteps) .eq. 0) then
172 check = .true.
173 end if
174 end if
175 end function time_based_controller_check
176
180 subroutine time_based_controller_assignment(ctrl1, ctrl2)
181 type(time_based_controller_t), intent(inout) :: ctrl1
182 type(time_based_controller_t), intent(in) :: ctrl2
183
184 ctrl1%end_time = ctrl2%end_time
185 ctrl1%frequency = ctrl2%frequency
186 ctrl1%nsteps = ctrl2%nsteps
187 ctrl1%time_interval = ctrl2%time_interval
188 ctrl1%nexecutions = ctrl2%nexecutions
189
191
194 class(time_based_controller_t), intent(inout) :: this
195
196 this%nexecutions = this%nexecutions + 1
197
199
203 class(time_based_controller_t), intent(inout) :: this
204 type(time_state_t) :: time
205
206 if (this%nsteps .eq. 0) then
207 this%nexecutions = int(((time%t - time%start_time) + 0.1_rp*time%dt) &
208 / this%time_interval) + 1
209 end if
210
212
213
214end module time_based_controller
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:12
Contains the time_based_controller_t type.
subroutine time_based_controller_set_counter(this, time)
Set the counter based on a time (for restarts)
subroutine time_based_controller_assignment(ctrl1, ctrl2)
Assignment operator. Simply copies attribute values.
subroutine time_based_controller_init(this, start_time, end_time, control_mode, control_value)
Constructor.
logical function time_based_controller_check(this, time, force)
Check if the execution should be performed.
subroutine time_based_controller_register_execution(this)
Increment nexectutions.
Module with things related to the simulation time.
Utilities.
Definition utils.f90:35
A utility type for determining whether an action should be executed based on the current time value....
A struct that contains all info about the time, expand as needed.