Neko 1.99.2
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) :: free => time_based_controller_free
75 procedure, pass(this) :: check => time_based_controller_check
77 procedure, pass(this) :: register_execution => &
80 procedure, pass(this) :: set_counter => &
82
84
85 interface assignment(=)
87 end interface assignment(=)
88
89contains
90
95 subroutine time_based_controller_init(this, start_time, end_time, &
96 control_mode, control_value)
97 class(time_based_controller_t), intent(inout) :: this
98 real(kind=rp), intent(in) :: start_time
99 real(kind=rp), intent(in) :: end_time
100 character(len=*), intent(in) :: control_mode
101 real(kind=rp), intent(in) :: control_value
102
103 this%start_time = start_time
104 this%end_time = end_time
105 this%control_mode = control_mode
106 this%control_value = control_value
107
108 if (trim(control_mode) .eq. 'simulationtime') then
109 this%time_interval = control_value
110 this%frequency = 1/this%time_interval
111 this%nsteps = 0
112 else if (trim(control_mode) .eq. 'nsamples') then
113 if (control_value .le. 0) then
114 call neko_error("nsamples must be positive")
115 end if
116
117 this%frequency = control_value / (end_time - start_time)
118 this%time_interval = 1.0_rp / this%frequency
119 this%nsteps = 0
120 else if (trim(control_mode) .eq. 'tsteps') then
121 this%nsteps = control_value
122 ! if the timestep will be variable, we cannot compute these.
123 this%frequency = 0
124 this%time_interval = 0
125 else if (trim(control_mode) .eq. 'never') then
126 this%never = .true.
127 else
128 call neko_error("The control parameter must be simulationtime, nsamples&
129 & tsteps, or never, but received "//trim(control_mode))
130 end if
131 end subroutine time_based_controller_init
132
135 class(time_based_controller_t), intent(inout) :: this
136
137 if (allocated(this%control_mode)) then
138 deallocate(this%control_mode)
139 end if
140
141 this%frequency = 0.0_rp
142 this%time_interval = 0.0_rp
143 this%nsteps = 0
144 this%start_time = 0.0_rp
145 this%end_time = 0.0_rp
146 this%nexecutions = 0
147 this%never = .false.
148 end subroutine time_based_controller_free
149
159 function time_based_controller_check(this, time, force) result(check)
160 class(time_based_controller_t), intent(inout) :: this
161 type(time_state_t), intent(in) :: time
162 logical, intent(in), optional :: force
163 real(kind=rp) :: t
164 integer :: tstep
165 real(kind=rp) :: dt
166 logical :: check
167 logical :: ifforce
168
169 t = time%t - time%start_time
170 dt = time%dt
171 tstep = time%tstep
172
173 if (present(force)) then
174 ifforce = force
175 else
176 ifforce = .false.
177 end if
178
179 check = .false.
180 if (ifforce) then
181 check = .true.
182 else if (this%never) then
183 check = .false.
184 else if (time%t - this%start_time .gt. this%end_time - this%start_time) then
185 check = .false.
186 else if ( (this%nsteps .eq. 0) .and. &
187 (t .ge. this%nexecutions * this%time_interval - 0.1_rp * dt) ) then
188 check = .true.
189 else if (this%nsteps .gt. 0) then
190 if (mod(tstep, this%nsteps) .eq. 0) then
191 check = .true.
192 end if
193 end if
194 end function time_based_controller_check
195
199 subroutine time_based_controller_assignment(ctrl1, ctrl2)
200 type(time_based_controller_t), intent(inout) :: ctrl1
201 type(time_based_controller_t), intent(in) :: ctrl2
202
203 ctrl1%end_time = ctrl2%end_time
204 ctrl1%frequency = ctrl2%frequency
205 ctrl1%nsteps = ctrl2%nsteps
206 ctrl1%time_interval = ctrl2%time_interval
207 ctrl1%nexecutions = ctrl2%nexecutions
208
210
213 class(time_based_controller_t), intent(inout) :: this
214
215 this%nexecutions = this%nexecutions + 1
216
218
222 class(time_based_controller_t), intent(inout) :: this
223 type(time_state_t) :: time
224
225 if (this%nsteps .eq. 0) then
226 this%nexecutions = int(((time%t - time%start_time) + 0.1_rp*time%dt) &
227 / this%time_interval) + 1
228 end if
229
231
232
233end 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_free(this)
Destructor.
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.