Neko  0.8.99
A portable framework for high-order spectral element flow simulations
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 !
34 module simulation
35  use mpi_f08
36  use case, only : case_t
37  use num_types, only : rp, dp
39  use file, only : file_t
40  use logger, only : log_size, neko_log
41  use jobctrl, only : jobctrl_time_limit
42  use field, only : field_t
43  use profiler, only : profiler_start, profiler_stop, &
48  implicit none
49  private
50 
51  public :: neko_solve
52 
53 contains
54 
56  subroutine neko_solve(C)
57  type(case_t), target, intent(inout) :: c
58  real(kind=rp) :: t, cfl
59  real(kind=dp) :: start_time_org, start_time, end_time, tstep_start_time
60  character(len=LOG_SIZE) :: log_buf
61  integer :: tstep
62  character(len=:), allocatable :: restart_file
63  logical :: output_at_end, found
64  ! for variable_tsteping
65  real(kind=rp) :: cfl_avrg = 0.0_rp
66  type(time_step_controller_t) :: dt_controller
67 
68  t = 0d0
69  tstep = 0
70  call neko_log%section('Starting simulation')
71  write(log_buf, '(A, E15.7,A,E15.7,A)') 'T : [', 0d0, ',', c%end_time, ')'
72  call neko_log%message(log_buf)
73  call dt_controller%init(c%params)
74  if (.not. dt_controller%if_variable_dt) then
75  write(log_buf, '(A, E15.7)') 'dt : ', c%dt
76  call neko_log%message(log_buf)
77  else
78  write(log_buf, '(A, E15.7)') 'CFL : ', dt_controller%set_cfl
79  call neko_log%message(log_buf)
80  end if
81 
82  call c%params%get('case.restart_file', restart_file, found)
83  if (found .and. len_trim(restart_file) .gt. 0) then
84  ! Restart the case
85  call simulation_restart(c, t)
86 
87  ! Restart the simulation components
88  call neko_simcomps%restart(t)
89  end if
90 
92  call neko_log%section('Postprocessing')
93  call c%q%eval(t, c%dt, tstep)
94  call c%s%sample(t, tstep)
95 
96  call c%usr%user_init_modules(t, c%fluid%u, c%fluid%v, c%fluid%w,&
97  c%fluid%p, c%fluid%c_Xh, c%params)
98  call neko_log%end_section()
99  call neko_log%newline()
100 
101  call profiler_start
102  cfl = c%fluid%compute_cfl(c%dt)
103  start_time_org = mpi_wtime()
104 
105  do while (t .lt. c%end_time .and. (.not. jobctrl_time_limit()))
106  call profiler_start_region('Time-Step')
107  tstep = tstep + 1
108  start_time = mpi_wtime()
109  tstep_start_time = start_time
110  if (dt_controller%dt_last_change .eq. 0) then
111  cfl_avrg = cfl
112  end if
113  call dt_controller%set_dt(c%dt, cfl, cfl_avrg, tstep)
114  !calculate the cfl after the possibly varied dt
115  cfl = c%fluid%compute_cfl(c%dt)
116 
117  call neko_log%status(t, c%end_time)
118  write(log_buf, '(A,I6)') 'Time-step: ', tstep
119  call neko_log%message(log_buf)
120  call neko_log%begin()
121 
122  write(log_buf, '(A,E15.7,1x,A,E15.7)') 'CFL:', cfl, 'dt:', c%dt
123  call neko_log%message(log_buf)
124  call simulation_settime(t, c%dt, c%ext_bdf, c%tlag, c%dtlag, tstep)
125 
126  ! Run the preprocessing
127  call neko_log%section('Preprocessing')
128  call neko_simcomps%preprocess(t, tstep)
129  call neko_log%end_section()
130 
131  call neko_log%section('Fluid')
132  call c%fluid%step(t, tstep, c%dt, c%ext_bdf, dt_controller)
133  end_time = mpi_wtime()
134  write(log_buf, '(A,E15.7)') &
135  'Fluid step time (s): ', end_time-start_time
136  call neko_log%message(log_buf)
137  write(log_buf, '(A,E15.7)') &
138  'Total elapsed time (s):', end_time-start_time_org
139  call neko_log%end_section(log_buf)
140 
141  ! Scalar step
142  if (allocated(c%scalar)) then
143  start_time = mpi_wtime()
144  call neko_log%section('Scalar')
145  call c%scalar%step(t, tstep, c%dt, c%ext_bdf, dt_controller)
146  end_time = mpi_wtime()
147  write(log_buf, '(A,E15.7)') &
148  'Scalar step time: ', end_time-start_time
149  call neko_log%message(log_buf)
150  write(log_buf, '(A,E15.7)') &
151  'Total elapsed time (s):', end_time-start_time_org
152  call neko_log%end_section(log_buf)
153  end if
154 
155  call neko_log%section('Postprocessing')
156  ! Execute all simulation components
157  call neko_simcomps%compute(t, tstep)
158 
159  call c%q%eval(t, c%dt, tstep)
160  call c%s%sample(t, tstep)
161 
162  ! Update material properties
163  call c%usr%material_properties(t, tstep, c%material_properties%rho,&
164  c%material_properties%mu, &
165  c%material_properties%cp, &
166  c%material_properties%lambda, &
167  c%params)
168 
169  call c%usr%user_check(t, tstep, c%fluid%u, c%fluid%v, c%fluid%w, &
170  c%fluid%p, c%fluid%c_Xh, c%params)
171 
172  call neko_log%end_section()
173  end_time = mpi_wtime()
174  call neko_log%section('Step summary')
175  write(log_buf, '(A,I8,A,E15.7)') &
176  'Total time for step ', tstep, ' (s): ', end_time-tstep_start_time
177  call neko_log%message(log_buf)
178  write(log_buf, '(A,E15.7)') &
179  'Total elapsed time (s): ', end_time-start_time_org
180  call neko_log%message(log_buf)
181  call neko_log%end_section()
182  call neko_log%end()
184  end do
185  call profiler_stop
186 
187  call json_get_or_default(c%params, 'case.output_at_end',&
188  output_at_end, .true.)
189  call c%s%sample(t, tstep, output_at_end)
190 
191  if (.not. (output_at_end) .and. t .lt. c%end_time) then
192  call simulation_joblimit_chkp(c, t)
193  end if
194 
195  call c%usr%user_finalize_modules(t, c%params)
196 
197  call neko_log%end_section('Normal end.')
198 
199  end subroutine neko_solve
200 
201  subroutine simulation_settime(t, dt, ext_bdf, tlag, dtlag, step)
202  real(kind=rp), intent(inout) :: t
203  real(kind=rp), intent(in) :: dt
204  type(time_scheme_controller_t), intent(inout) :: ext_bdf
205  real(kind=rp), dimension(10) :: tlag
206  real(kind=rp), dimension(10) :: dtlag
207  integer, intent(in) :: step
208  integer :: i
209 
210 
211  do i = 10, 2, -1
212  tlag(i) = tlag(i-1)
213  dtlag(i) = dtlag(i-1)
214  end do
215 
216  dtlag(1) = dt
217  tlag(1) = t
218  if (ext_bdf%ndiff .eq. 0) then
219  dtlag(2) = dt
220  tlag(2) = t
221  end if
222 
223  t = t + dt
224 
225  call ext_bdf%set_coeffs(dtlag)
226 
227  end subroutine simulation_settime
228 
230  subroutine simulation_restart(C, t)
231  implicit none
232  type(case_t), intent(inout) :: C
233  real(kind=rp), intent(inout) :: t
234  integer :: i
235  type(file_t) :: chkpf, previous_meshf
236  character(len=LOG_SIZE) :: log_buf
237  character(len=:), allocatable :: restart_file
238  character(len=:), allocatable :: restart_mesh_file
239  real(kind=rp) :: tol
240  logical :: found
241 
242  call c%params%get('case.restart_file', restart_file, found)
243  call c%params%get('case.restart_mesh_file', restart_mesh_file,&
244  found)
245 
246  if (found) then
247  previous_meshf = file_t(trim(restart_mesh_file))
248  call previous_meshf%read(c%fluid%chkp%previous_mesh)
249  end if
250 
251  call c%params%get('case.mesh2mesh_tolerance', tol,&
252  found)
253 
254  if (found) c%fluid%chkp%mesh2mesh_tol = tol
255 
256  chkpf = file_t(trim(restart_file))
257  call chkpf%read(c%fluid%chkp)
258  c%dtlag = c%fluid%chkp%dtlag
259  c%tlag = c%fluid%chkp%tlag
260 
261  !Free the previous mesh, dont need it anymore
262  call c%fluid%chkp%previous_mesh%free()
263  do i = 1, size(c%dtlag)
264  call c%ext_bdf%set_coeffs(c%dtlag)
265  end do
266 
267  call c%fluid%restart(c%dtlag, c%tlag)
268  if (allocated(c%scalar)) call c%scalar%restart( c%dtlag, c%tlag)
269 
270  t = c%fluid%chkp%restart_time()
271  call neko_log%section('Restarting from checkpoint')
272  write(log_buf, '(A,A)') 'File : ', &
273  trim(restart_file)
274  call neko_log%message(log_buf)
275  write(log_buf, '(A,E15.7)') 'Time : ', t
276  call neko_log%message(log_buf)
277  call neko_log%end_section()
278 
279  call c%s%set_counter(t)
280  end subroutine simulation_restart
281 
283  subroutine simulation_joblimit_chkp(C, t)
284  type(case_t), intent(inout) :: C
285  real(kind=rp), intent(inout) :: t
286  type(file_t) :: chkpf
287  character(len=:), allocatable :: chkp_format
288  character(len=LOG_SIZE) :: log_buf
289  character(len=10) :: format_str
290  logical :: found
291 
292  call c%params%get('case.checkpoint_format', chkp_format, found)
293  call c%fluid%chkp%sync_host()
294  format_str = '.chkp'
295  if (found) then
296  if (chkp_format .eq. 'hdf5') then
297  format_str = '.h5'
298  end if
299  end if
300  chkpf = file_t('joblimit'//trim(format_str))
301  call chkpf%write(c%fluid%chkp, t)
302  write(log_buf, '(A)') '! saving checkpoint >>>'
303  call neko_log%message(log_buf)
304 
305  end subroutine simulation_joblimit_chkp
306 
307 end module simulation
308 
309 
Retrieves a parameter by name or assigns a provided default value. In the latter case also adds the m...
Definition: json_utils.f90:53
Defines a simulation case.
Definition: case.f90:34
Defines a field.
Definition: field.f90:34
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:107
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:61
integer, parameter, public log_size
Definition: log.f90:40
integer, parameter, public dp
Definition: num_types.f90:9
integer, parameter, public rp
Global precision used in computations.
Definition: num_types.f90:12
Profiling interface.
Definition: profiler.F90:34
subroutine, public profiler_start
Start profiling.
Definition: profiler.F90:52
subroutine, public profiler_start_region(name, region_id)
Started a named (name) profiler region.
Definition: profiler.F90:78
subroutine, public profiler_end_region(name, region_id)
End the most recently started profiler region.
Definition: profiler.F90:109
subroutine, public profiler_stop
Stop profiling.
Definition: profiler.F90:65
Contains the simcomp_executor_t type.
type(simcomp_executor_t), target, public neko_simcomps
Global variable for the simulation component driver.
Simulation driver.
Definition: simulation.f90:34
subroutine simulation_settime(t, dt, ext_bdf, tlag, dtlag, step)
Definition: simulation.f90:202
subroutine, public neko_solve(C)
Main driver to solve a case C.
Definition: simulation.f90:57
subroutine simulation_joblimit_chkp(C, t)
Write a checkpoint at joblimit.
Definition: simulation.f90:284
subroutine simulation_restart(C, t)
Restart a case C from a given checkpoint.
Definition: simulation.f90:231
Compound scheme for the advection and diffusion operators in a transport equation.
Implements type time_step_controller.
A wrapper around a polymorphic generic_file_t that handles its init. This is essentially a factory fo...
Definition: file.f90:54
Implements the logic to compute the time coefficients for the advection and diffusion operators in a ...
Provides a tool to set time step dt.