Neko 1.99.9
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
simulation.f90
Go to the documentation of this file.
1! Copyright (c) 2020-2021, 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 mpi_f08, only : mpi_wtime
36 use case, only : case_t
37 use checkpoint, only : chkp_t
38 use num_types, only : rp, dp
40 use file, only : file_t
41 use logger, only : log_size, neko_log
42 use jobctrl, only : jobctrl_time_limit
47 use time_state, only : time_state_t
49 implicit none
50 private
51
55 end interface simulation_restart
56
59
60contains
61
63 subroutine simulation_init(C, dt_controller)
64 type(case_t), intent(inout) :: c
65 type(time_step_controller_t), intent(inout) :: dt_controller
66 character(len=LOG_SIZE) :: log_buf
67 logical :: found
68 character(len=:), allocatable :: restart_file
69
70 ! Restart the case if needed
71 call c%params%get('case.restart_file', restart_file, found)
72 if (found .and. len_trim(restart_file) .gt. 0) then
73 ! Restart the case
74 call simulation_restart(c)
75 end if
76
77 ! Write the initial logging message
78 call neko_log%section('Starting simulation')
79 write(log_buf, '(A, E15.7,A,E15.7,A)') &
80 'T : [', c%time%t, ', ', c%time%end_time, ']'
81 call neko_log%message(log_buf)
82 if (.not. dt_controller%is_variable_dt) then
83 write(log_buf, '(A, E15.7)') 'dt : ', c%time%dt
84 else
85 write(log_buf, '(A, E15.7)') 'CFL : ', dt_controller%cfl_trg
86 end if
87 call neko_log%message(log_buf)
88 if (dt_controller%exact_output_time) then
89 call neko_log%message('dt is fitted to the output times')
90 end if
91
92 ! Execute outputs and user-init before time loop
93 call neko_log%section('Preprocessing')
94 call c%user%initialize(c%time)
95
96 ! With a variable time step, set the first step before the initial
97 ! output.
98 if (dt_controller%is_variable_dt) then
99 c%time%dt = dt_controller%first_dt(c%time, &
100 c%fluid%compute_cfl(c%time%dt))
101 end if
102 call c%output_controller%execute(c%time)
103
104 call neko_log%end_section()
105 call neko_log%newline()
106
107 end subroutine simulation_init
108
111 type(case_t), intent(inout) :: c
112 logical :: output_at_end
113
114 ! Run a final output if specified in the json
115 call json_get_or_default(c%params, 'case.output_at_end', &
116 output_at_end, .true.)
117 call c%output_controller%execute(c%time, output_at_end)
118
119 if (.not. (output_at_end) .and. .not. c%time%is_done()) then
120 call simulation_joblimit_chkp(c, c%time%t)
121 end if
122
123 ! Finalize the user modules
124 call c%user%finalize(c%time)
125
126 call neko_log%end_section('Normal end.')
127
128 end subroutine simulation_finalize
129
131 subroutine simulation_step(C, dt_controller, tstep_loop_start_time)
132 type(case_t), intent(inout) :: c
133 type(time_step_controller_t), intent(inout) :: dt_controller
134 real(kind=dp), optional, intent(in) :: tstep_loop_start_time
135 real(kind=dp) :: start_time, end_time, tstep_start_time
136 real(kind=dp) :: cfl, dt_previous
137 character(len=LOG_SIZE) :: log_buf
138
139 ! Setup the time step, and start time
140 call profiler_start_region('Time-Step')
141 start_time = mpi_wtime()
142 tstep_start_time = start_time
143
144 ! Compute the next time step size
145 dt_previous = c%time%dt
146 cfl = c%fluid%compute_cfl(c%time%dt)
147 call dt_controller%set_dt(c%time, cfl)
148
149 ! Shorten the step to land exactly on the next sampling or output time
150 if (dt_controller%exact_output_time) then
151 call dt_controller%land(c%time, &
152 min(c%output_controller%time_to_next(c%time), &
153 neko_simcomps%time_to_next(c%time)))
154 end if
155
156 ! The CFL number of the step about to be taken, for the log
157 if (c%time%dt .ne. dt_previous) cfl = c%fluid%compute_cfl(c%time%dt)
158
159 ! Advance time step from t to t+dt and print the status
160 call simulation_settime(c%time, c%fluid%ext_bdf)
161 call c%time%status()
162 call neko_log%begin()
163
164 call neko_log%section('Preprocessing')
165
166 write(log_buf, "(A,F8.4,2x,A,1P,E14.7)") 'CFL:', cfl, 'dt:', c%time%dt
167 call neko_log%message(log_buf)
168
169 ! Run the preprocessing
170 call c%user%preprocess(c%time)
171 call neko_simcomps%preprocess(c%time)
172 call neko_log%end_section()
173
174 ! Fluid step
175 call neko_log%section('Fluid')
176 start_time = mpi_wtime()
177 call c%fluid%step(c%time, dt_controller)
178 end_time = mpi_wtime()
179 write(log_buf, '(A,3X,E15.7)') 'Fluid step time (s):', end_time - start_time
180 call neko_log%end_section(log_buf)
181
182 ! Scalar step
183 if (allocated(c%scalars)) then
184 start_time = mpi_wtime()
185 call neko_log%section('Scalar')
186 call c%scalars%step(c%time, c%fluid%ext_bdf, dt_controller)
187 end_time = mpi_wtime()
188 write(log_buf, '(A,6X,E15.7)') 'Scalar step time:', end_time - start_time
189 call neko_log%end_section(log_buf)
190 end if
191
192 ! Postprocessing
193 call neko_log%section('Postprocessing')
194
195 ! Execute all simulation components
196 call neko_simcomps%compute(c%time)
197
198 ! Run the user compute routine
199 call c%user%compute(c%time)
200
201 ! Run any IO needed.
202 call c%output_controller%execute(c%time)
203
204 call neko_log%end_section()
205
206 ! End the step and print summary
207 end_time = mpi_wtime()
208 call neko_log%section('Step summary')
209 write(log_buf, '(A20,I8,A6,E15.7)') &
210 'Total time for step ', c%time%tstep, ' (s): ', &
211 end_time-tstep_start_time
212 call neko_log%message(log_buf)
213
214 if (present(tstep_loop_start_time)) then
215 write(log_buf, '(A34,E15.7)') &
216 'Total elapsed time (s): ', &
217 end_time - tstep_loop_start_time
218 call neko_log%message(log_buf)
219 end if
220
221 call neko_log%end_section()
222 call neko_log%end()
224
225 end subroutine simulation_step
226
227 subroutine simulation_settime(time, ext_bdf)
228 type(time_state_t), intent(inout) :: time
229 type(time_scheme_controller_t), intent(inout), allocatable :: ext_bdf
230 integer :: i
231
232 ! Always shift the time lag arrays (needed by entropy viscosity etc.)
233 do i = 10, 2, -1
234 time%tlag(i) = time%tlag(i-1)
235 time%dtlag(i) = time%dtlag(i-1)
236 end do
237
238 time%dtlag(1) = time%dt
239 time%tlag(1) = time%t
240
241 if (allocated(ext_bdf)) then
242 if (ext_bdf%ndiff .eq. 0) then
243 time%dtlag(2) = time%dt
244 time%tlag(2) = time%t
245 end if
246
247 call ext_bdf%set_coeffs(real(time%dtlag, kind=rp))
248 end if
249
250 time%tstep = time%tstep + 1
251 time%t = time%t + time%dt
252
253 end subroutine simulation_settime
254
257 type(case_t), intent(inout) :: C
258 type(file_t) :: chkpf, previous_meshf
259 character(len=LOG_SIZE) :: log_buf
260 character(len=:), allocatable :: restart_file
261 character(len=:), allocatable :: restart_mesh_file
262 real(kind=rp) :: tol
263 logical :: found, check_cont
264 integer :: i
265
266 call json_get(c%params, 'case.restart_file', restart_file)
267 call json_get_or_default(c%params, 'case.restart_mesh_file', &
268 restart_mesh_file, "")
269
270 if (restart_mesh_file .ne. "") then
271 call previous_meshf%init(trim(restart_mesh_file))
272 call previous_meshf%read(c%chkp%previous_mesh)
273
274 call json_get_or_default(c%params, 'case.mesh2mesh_tolerance', &
275 c%chkp%mesh2mesh_tol, 1e-6_dp)
276 end if
277
278 call neko_log%section('Restarting from checkpoint')
279 write(log_buf, '(A,A)') 'File : ', trim(restart_file)
280 call neko_log%message(log_buf)
281
282 call chkpf%init(trim(restart_file))
283 call chkpf%read(c%chkp)
284
285 call case_restart_from_checkpoint(c, c%chkp)
286
287 ! Free the previous mesh
288 call c%chkp%previous_mesh%free()
289
290 write(log_buf, '(A,E15.7)') 'Time : ', c%time%t
291 call neko_log%message(log_buf)
292 call neko_log%end_section()
293
294 end subroutine case_restart_from_parameters
295
298 type(case_t), intent(inout) :: C
299 type(chkp_t), intent(inout) :: chkp
300 character(len=LOG_SIZE) :: log_buf
301 integer :: i
302
303 ! Restart the time state and BDF coefficients
304 call chkp%set_time_state(c%time)
305 do i = 1, size(c%time%dtlag)
306 call c%fluid%ext_bdf%set_coeffs(real(c%time%dtlag, kind=rp))
307 end do
308
309 ! Restart the fluid and scalars
310 call c%fluid%restart(chkp)
311 if (allocated(c%scalars)) call c%scalars%restart(chkp)
312
313 ! Restart the output controller
314 call c%output_controller%set_counter(c%time)
315
316 ! Restart the simulation components
317 call neko_simcomps%restart(c%time)
318
319 end subroutine case_restart_from_checkpoint
320
323 type(case_t), intent(inout) :: C
324 real(kind=dp), intent(inout) :: t
325 type(file_t) :: chkpf
326 character(len=:), allocatable :: chkp_format
327 character(len=LOG_SIZE) :: log_buf
328 character(len=10) :: format_str
329 logical :: found
330
331 call json_get_or_default(c%params, 'case.checkpoint_format', chkp_format, &
332 'default')
333 call c%chkp%sync_host()
334 if (chkp_format .eq. 'hdf5') then
335 format_str = '.h5'
336 else
337 format_str = '.chkp'
338 end if
339 call chkpf%init(c%output_directory // 'joblimit' // trim(format_str))
340 write(log_buf, '(A)') '! saving checkpoint >>>'
341 call neko_log%message(log_buf)
342 call neko_log%flush()
343 call chkpf%write(c%chkp, t)
344 call neko_log%flush()
345
346 end subroutine simulation_joblimit_chkp
347
348end module simulation
double real
Retrieves a parameter by name or assigns a provided default value. In the latter case also adds the m...
Retrieves a parameter by name or throws an error.
Defines a simulation case.
Definition case.f90:34
Defines format-independent checkpoint registration and restart state.
Module for file I/O operations.
Definition file.f90:34
Job control.
Definition jobctrl.f90:34
logical function, public jobctrl_time_limit()
Check if the job's time limit has been reached.
Definition jobctrl.f90:95
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:92
integer, parameter, public log_size
Definition log.f90:46
integer, parameter, public dp
Definition num_types.f90:10
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:14
Profiling interface.
Definition profiler.F90:34
subroutine, public profiler_start
Start profiling.
Definition profiler.F90:53
subroutine, public profiler_start_region(name, region_id)
Started a named (name) profiler region.
Definition profiler.F90:79
subroutine, public profiler_end_region(name, region_id)
End the most recently started profiler region.
Definition profiler.F90:116
subroutine, public profiler_stop
Stop profiling.
Definition profiler.F90:66
Contains the simcomp_executor_t type.
type(simcomp_executor_t), target, public neko_simcomps
Global variable for the simulation component driver.
Simulation driver.
subroutine, public simulation_step(c, dt_controller, tstep_loop_start_time)
Compute a single time-step of a case.
subroutine simulation_settime(time, ext_bdf)
subroutine, public simulation_finalize(c)
Finalize a simulation of a case.
subroutine case_restart_from_checkpoint(c, chkp)
Restart a case C from a given checkpoint.
subroutine, public simulation_init(c, dt_controller)
Initialise a simulation of a case.
subroutine simulation_joblimit_chkp(c, t)
Write a checkpoint at joblimit.
subroutine case_restart_from_parameters(c)
Restart a case C from a given checkpoint.
Compound scheme for the advection and diffusion operators in a transport equation.
Module with things related to the simulation time.
Implements type time_step_controller.
Collection of live simulation data registered for checkpointing.
A wrapper around a polymorphic generic_file_t that handles its init. This is essentially a factory fo...
Definition file.f90:56
Implements the logic to compute the time coefficients for the advection and diffusion operators in a ...
A struct that contains all info about the time, expand as needed.