Neko 0.9.99
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
scalar_pnpn.f90
Go to the documentation of this file.
1! Copyright (c) 2022-2024, 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
36 use num_types, only: rp
38 rhs_maker_ext_fctry, rhs_maker_bdf_fctry, rhs_maker_oifs_fctry
40 use dirichlet, only : dirichlet_t
41 use neumann, only : neumann_t
42 use field, only : field_t
43 use bc_list, only : bc_list_t
44 use mesh, only : mesh_t
45 use checkpoint, only : chkp_t
46 use coefs, only : coef_t
48 use gather_scatter, only : gs_t, gs_op_add
49 use scalar_residual, only : scalar_residual_t, scalar_residual_factory
50 use ax_product, only : ax_t, ax_helm_factory
53 use krylov, only : ksp_monitor_t
57 use projection, only : projection_t
58 use math, only : glsc2, col2, add2s2
60 use advection, only : advection_t, advection_factory
63 use json_module, only : json_file
64 use user_intf, only : user_t
68 implicit none
69 private
70
71
72 type, public, extends(scalar_scheme_t) :: scalar_pnpn_t
73
75 type(field_t) :: s_res
76
78 type(field_t) :: ds
79
81 class(ax_t), allocatable :: ax
82
84 type(projection_t) :: proj_s
85
89 type(dirichlet_t) :: bc_res
90
93 type(bc_list_t) :: bclst_ds
94
96 class(advection_t), allocatable :: adv
97
98 ! Time interpolation scheme
99 logical :: oifs
100
101 ! Lag arrays for the RHS.
102 type(field_t) :: abx1, abx2
103
104 ! Advection terms for the oifs method
105 type(field_t) :: advs
106
108 class(scalar_residual_t), allocatable :: res
109
111 class(rhs_maker_ext_t), allocatable :: makeext
112
114 class(rhs_maker_bdf_t), allocatable :: makebdf
115
117 class(rhs_maker_oifs_t), allocatable :: makeoifs
118
119 contains
121 procedure, pass(this) :: init => scalar_pnpn_init
123 procedure, pass(this) :: restart => scalar_pnpn_restart
125 procedure, pass(this) :: free => scalar_pnpn_free
127 procedure, pass(this) :: step => scalar_pnpn_step
128 end type scalar_pnpn_t
129
130contains
131
138 subroutine scalar_pnpn_init(this, msh, coef, gs, params, user, &
139 ulag, vlag, wlag, time_scheme, rho)
140 class(scalar_pnpn_t), target, intent(inout) :: this
141 type(mesh_t), target, intent(in) :: msh
142 type(coef_t), target, intent(in) :: coef
143 type(gs_t), target, intent(inout) :: gs
144 type(json_file), target, intent(inout) :: params
145 type(user_t), target, intent(in) :: user
146 type(field_series_t), target, intent(in) :: ulag, vlag, wlag
147 type(time_scheme_controller_t), target, intent(in) :: time_scheme
148 real(kind=rp), intent(in) :: rho
149 integer :: i
150 character(len=15), parameter :: scheme = 'Modular (Pn/Pn)'
151 logical :: advection
152
153 call this%free()
154
155 ! Initiliaze base type.
156 call this%scheme_init(msh, coef, gs, params, scheme, user, rho)
157
158 ! Setup backend dependent Ax routines
159 call ax_helm_factory(this%ax, full_formulation = .false.)
160
161 ! Setup backend dependent scalar residual routines
162 call scalar_residual_factory(this%res)
163
164 ! Setup backend dependent summation of extrapolation scheme
165 call rhs_maker_ext_fctry(this%makeext)
166
167 ! Setup backend depenent contributions to F from lagged BD terms
168 call rhs_maker_bdf_fctry(this%makebdf)
169
170 ! Setup backend dependent contributions of the OIFS scheme
171 call rhs_maker_oifs_fctry(this%makeoifs)
172
173 ! Initialize variables specific to this plan
174 associate(xh_lx => this%Xh%lx, xh_ly => this%Xh%ly, xh_lz => this%Xh%lz, &
175 dm_xh => this%dm_Xh, nelv => this%msh%nelv)
176
177 call this%s_res%init(dm_xh, "s_res")
178
179 call this%abx1%init(dm_xh, "abx1")
180
181 call this%abx2%init(dm_xh, "abx2")
182
183 call this%advs%init(dm_xh, "advs")
184
185 call this%ds%init(dm_xh, 'ds')
186
187 end associate
188
189 ! Initialize dirichlet bcs for scalar residual
190 ! todo: look that this works
191 call this%bc_res%init_base(this%c_Xh)
192 do i = 1, this%n_dir_bcs
193 call this%bc_res%mark_facets(this%dir_bcs(i)%marked_facet)
194 end do
195
196 ! Check for user bcs
197 if (this%user_bc%msk(0) .gt. 0) then
198 call this%bc_res%mark_facets(this%user_bc%marked_facet)
199 end if
200
201 call this%bc_res%mark_zones_from_list(msh%labeled_zones, 'd_s', &
202 this%bc_labels)
203 call this%bc_res%finalize()
204 call this%bc_res%set_g(0.0_rp)
205
206 call this%bclst_ds%init()
207 call this%bclst_ds%append(this%bc_res)
208
209
210 ! Intialize projection space
211 call this%proj_s%init(this%dm_Xh%size(), this%projection_dim, &
212 this%projection_activ_step)
213
214 ! Add lagged term to checkpoint
215 ! @todo Init chkp object, note, adding 3 slags
216 ! call this%chkp%add_lag(this%slag, this%slag, this%slag)
217
218 ! Determine the time-interpolation scheme
219 call json_get_or_default(params, 'case.numerics.oifs', this%oifs, .false.)
220
221 ! Initialize advection factory
222 call json_get_or_default(params, 'case.scalar.advection', advection, .true.)
223 call advection_factory(this%adv, params, this%c_Xh, &
224 ulag, vlag, wlag, this%chkp%dtlag, &
225 this%chkp%tlag, time_scheme, .not. advection, &
226 this%slag)
227 end subroutine scalar_pnpn_init
228
230 subroutine scalar_pnpn_restart(this, dtlag, tlag)
231 class(scalar_pnpn_t), target, intent(inout) :: this
232 real(kind=rp) :: dtlag(10), tlag(10)
233 integer :: n
234
235
236 n = this%s%dof%size()
237
238 call col2(this%s%x, this%c_Xh%mult, n)
239 call col2(this%slag%lf(1)%x, this%c_Xh%mult, n)
240 call col2(this%slag%lf(2)%x, this%c_Xh%mult, n)
241 if (neko_bcknd_device .eq. 1) then
242 call device_memcpy(this%s%x, this%s%x_d, &
243 n, host_to_device, sync = .false.)
244 call device_memcpy(this%slag%lf(1)%x, this%slag%lf(1)%x_d, &
245 n, host_to_device, sync = .false.)
246 call device_memcpy(this%slag%lf(2)%x, this%slag%lf(2)%x_d, &
247 n, host_to_device, sync = .false.)
248 call device_memcpy(this%abx1%x, this%abx1%x_d, &
249 n, host_to_device, sync = .false.)
250 call device_memcpy(this%abx2%x, this%abx2%x_d, &
251 n, host_to_device, sync = .false.)
252 call device_memcpy(this%advs%x, this%advs%x_d, &
253 n, host_to_device, sync = .false.)
254 end if
255
256 call this%gs_Xh%op(this%s, gs_op_add)
257 call this%gs_Xh%op(this%slag%lf(1), gs_op_add)
258 call this%gs_Xh%op(this%slag%lf(2), gs_op_add)
259
260 end subroutine scalar_pnpn_restart
261
262 subroutine scalar_pnpn_free(this)
263 class(scalar_pnpn_t), intent(inout) :: this
264
265 !Deallocate scalar field
266 call this%scheme_free()
267
268 call this%bclst_ds%free()
269 call this%proj_s%free()
270
271 call this%s_res%free()
272
273 call this%ds%free()
274
275 call this%abx1%free()
276 call this%abx2%free()
277
278 call this%advs%free()
279
280 if (allocated(this%Ax)) then
281 deallocate(this%Ax)
282 end if
283
284 if (allocated(this%res)) then
285 deallocate(this%res)
286 end if
287
288 if (allocated(this%makeext)) then
289 deallocate(this%makeext)
290 end if
291
292 if (allocated(this%makebdf)) then
293 deallocate(this%makebdf)
294 end if
295
296 if (allocated(this%makeoifs)) then
297 deallocate(this%makeoifs)
298 end if
299
300 end subroutine scalar_pnpn_free
301
302 subroutine scalar_pnpn_step(this, t, tstep, dt, ext_bdf, dt_controller)
303 class(scalar_pnpn_t), intent(inout) :: this
304 real(kind=rp), intent(in) :: t
305 integer, intent(in) :: tstep
306 real(kind=rp), intent(in) :: dt
307 type(time_scheme_controller_t), intent(in) :: ext_bdf
308 type(time_step_controller_t), intent(in) :: dt_controller
309 ! Number of degrees of freedom
310 integer :: n
311 ! Linear solver results monitor
312 type(ksp_monitor_t) :: ksp_results(1)
313 character(len=LOG_SIZE) :: log_buf
314
315 n = this%dm_Xh%size()
316
317 call profiler_start_region('Scalar', 2)
318 associate(u => this%u, v => this%v, w => this%w, s => this%s, &
319 cp => this%cp, rho => this%rho, &
320 ds => this%ds, &
321 s_res => this%s_res, &
322 ax => this%Ax, f_xh => this%f_Xh, xh => this%Xh, &
323 c_xh => this%c_Xh, dm_xh => this%dm_Xh, gs_xh => this%gs_Xh, &
324 slag => this%slag, oifs => this%oifs, &
325 lambda_field => this%lambda_field, &
326 projection_dim => this%projection_dim, &
327 msh => this%msh, res => this%res, makeoifs => this%makeoifs, &
328 makeext => this%makeext, makebdf => this%makebdf, &
329 if_variable_dt => dt_controller%if_variable_dt, &
330 dt_last_change => dt_controller%dt_last_change)
331
332 if (neko_log%level_ .ge. neko_log_debug) then
333 write(log_buf, '(A,A,E15.7,A,E15.7,A,E15.7)') 'Scalar debug', &
334 ' l2norm s', glsc2(this%s%x, this%s%x, n), &
335 ' slag1', glsc2(this%slag%lf(1)%x, this%slag%lf(1)%x, n), &
336 ' slag2', glsc2(this%slag%lf(2)%x, this%slag%lf(2)%x, n)
337 call neko_log%message(log_buf)
338 write(log_buf, '(A,A,E15.7,A,E15.7)') 'Scalar debug2', &
339 ' l2norm abx1', glsc2(this%abx1%x, this%abx1%x, n), &
340 ' abx2', glsc2(this%abx2%x, this%abx2%x, n)
341 call neko_log%message(log_buf)
342 end if
343
344 ! Compute the source terms
345 call this%source_term%compute(t, tstep)
346
347 ! Compute the grandient jump penalty term
348 if (this%if_gradient_jump_penalty .eqv. .true.) then
349 call this%gradient_jump_penalty%compute(u, v, w, s)
350 call this%gradient_jump_penalty%perform(f_xh)
351 end if
352
353 ! Apply Neumann boundary conditions
354 call this%bclst_neumann%apply_scalar(this%f_Xh%x, dm_xh%size())
355
356 if (oifs) then
357 ! Add the advection operators to the right-hans-side.
358 call this%adv%compute_scalar(u, v, w, s, this%advs, &
359 xh, this%c_Xh, dm_xh%size())
360
361 call makeext%compute_scalar(this%abx1, this%abx2, f_xh%x, rho, &
362 ext_bdf%advection_coeffs, n)
363
364 call makeoifs%compute_scalar(this%advs%x, f_xh%x, rho, dt, n)
365 else
366 ! Add the advection operators to the right-hans-side.
367 call this%adv%compute_scalar(u, v, w, s, f_xh, &
368 xh, this%c_Xh, dm_xh%size())
369
370 ! At this point the RHS contains the sum of the advection operator,
371 ! Neumann boundary sources and additional source terms, evaluated using
372 ! the scalar field from the previous time-step. Now, this value is used in
373 ! the explicit time scheme to advance these terms in time.
374 call makeext%compute_scalar(this%abx1, this%abx2, f_xh%x, rho, &
375 ext_bdf%advection_coeffs, n)
376
377 ! Add the RHS contributions coming from the BDF scheme.
378 call makebdf%compute_scalar(slag, f_xh%x, s, c_xh%B, rho, dt, &
379 ext_bdf%diffusion_coeffs, ext_bdf%ndiff, n)
380 end if
381
382 call slag%update()
383
387 call this%field_dir_bc%update(this%field_dir_bc%field_list, &
388 this%field_dirichlet_bcs, this%c_Xh, t, tstep, "scalar")
389 call this%bclst_dirichlet%apply_scalar(this%s%x, this%dm_Xh%size())
390
391
392 ! Update material properties if necessary
393 call this%update_material_properties()
394
395 ! Compute scalar residual.
396 call profiler_start_region('Scalar_residual', 20)
397 call res%compute(ax, s, s_res, f_xh, c_xh, msh, xh, lambda_field, &
398 rho*cp, ext_bdf%diffusion_coeffs(1), dt, dm_xh%size())
399
400 call gs_xh%op(s_res, gs_op_add)
401
402 ! Apply a 0-valued Dirichlet boundary conditions on the ds.
403 call this%bclst_ds%apply_scalar(s_res%x, dm_xh%size())
404
405 call profiler_end_region('Scalar_residual', 20)
406
407 call this%proj_s%pre_solving(s_res%x, tstep, c_xh, n, dt_controller)
408
409 call this%pc%update()
410 call profiler_start_region('Scalar_solve', 21)
411 ksp_results(1) = this%ksp%solve(ax, ds, s_res%x, n, &
412 c_xh, this%bclst_ds, gs_xh)
413 call profiler_end_region('Scalar_solve', 21)
414
415 call this%proj_s%post_solving(ds%x, ax, c_xh, &
416 this%bclst_ds, gs_xh, n, tstep, dt_controller)
417
418 ! Update the solution
419 if (neko_bcknd_device .eq. 1) then
420 call device_add2s2(s%x_d, ds%x_d, 1.0_rp, n)
421 else
422 call add2s2(s%x, ds%x, 1.0_rp, n)
423 end if
424
425 call scalar_step_info(tstep, t, dt, ksp_results)
426
427 end associate
428 call profiler_end_region('Scalar', 2)
429 end subroutine scalar_pnpn_step
430
431
432end module scalar_pnpn
Copy data between host and device (or device and device)
Definition device.F90:51
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.
Subroutines to add advection terms to the RHS of a transport equation.
Definition advection.f90:34
Defines a Matrix-vector product.
Definition ax.f90:34
Defines a list of bc_t.
Definition bc_list.f90:34
Defines a checkpoint.
Coefficients.
Definition coef.f90:34
subroutine, public device_col2(a_d, b_d, n)
Vector multiplication .
subroutine, public device_add2s2(a_d, b_d, c1, n)
Vector addition with scalar multiplication (multiplication on first argument)
Device abstraction, common interface for various accelerators.
Definition device.F90:34
integer, parameter, public host_to_device
Definition device.F90:47
Defines a dirichlet boundary condition.
Definition dirichlet.f90:34
Dirichlet condition applied in the facet normal direction.
Stores a series fields.
Defines a field.
Definition field.f90:34
Gather-scatter.
Utilities for retrieving parameters from the case files.
Implements the base abstract type for Krylov solvers plus helper types.
Definition krylov.f90:34
Logging routines.
Definition log.f90:34
integer, parameter, public neko_log_debug
Debug log level.
Definition log.f90:73
type(log_t), public neko_log
Global log stream.
Definition log.f90:65
integer, parameter, public log_size
Definition log.f90:42
Definition math.f90:60
real(kind=rp) function, public glsc2(a, b, n)
Weighted inner product .
Definition math.f90:875
subroutine, public col2(a, b, n)
Vector multiplication .
Definition math.f90:728
subroutine, public add2s2(a, b, c1, n)
Vector addition with scalar multiplication (multiplication on second argument)
Definition math.f90:672
Defines a mesh.
Definition mesh.f90:34
Build configurations.
integer, parameter neko_bcknd_device
Defines a Neumann boundary condition.
Definition neumann.f90:34
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:12
Profiling interface.
Definition profiler.F90:34
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
Project x onto X, the space of old solutions and back again.
Routines to generate the right-hand sides for the convection-diffusion equation. Employs the EXT/BDF ...
Definition rhs_maker.f90:38
Auxiliary routines for fluid solvers.
Definition scalar_aux.f90:2
subroutine scalar_step_info(step, t, dt, ksp_results)
Prints for prs, velx, vely, velz the following: Number of iterations, start residual,...
Containts the scalar_pnpn_t type.
subroutine scalar_pnpn_init(this, msh, coef, gs, params, user, ulag, vlag, wlag, time_scheme, rho)
Constructor.
subroutine scalar_pnpn_step(this, t, tstep, dt, ext_bdf, dt_controller)
subroutine scalar_pnpn_restart(this, dtlag, tlag)
I envision the arguments to this func might need to be expanded.
subroutine scalar_pnpn_free(this)
Defines the residual for the scalar transport equation.
Contains the scalar_scheme_t type.
Defines a registry for storing and requesting temporary fields This can be used when you have a funct...
type(scratch_registry_t) function init(dof, size, expansion_size)
Constructor, optionally taking initial registry and expansion size as argument.
type(scratch_registry_t), target, public neko_scratch_registry
Global scratch registry.
Compound scheme for the advection and diffusion operators in a transport equation.
Base class for time integration schemes.
Implements type time_step_controller.
Interfaces for user interaction with NEKO.
Definition user_intf.f90:34
Base abstract type for computing the advection operator.
Definition advection.f90:46
Base type for a matrix-vector product providing .
Definition ax.f90:43
A list of allocatable `bc_t`. Follows the standard interface of lists.
Definition bc_list.f90:46
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Definition coef.f90:55
Generic Dirichlet boundary condition on .
Definition dirichlet.f90:44
Dirichlet condition in facet normal direction.
Type for storing initial and final residuals in a Krylov solver.
Definition krylov.f90:56
A Neumann boundary condition for scalar fields. Sets the flux of the field to the chosen value.
Definition neumann.f90:48
Abstract type to add contributions to F from lagged BD terms.
Definition rhs_maker.f90:59
Abstract type to sum up contributions to kth order extrapolation scheme.
Definition rhs_maker.f90:52
Abstract type to add contributions of kth order OIFS scheme.
Definition rhs_maker.f90:66
Abstract type to compute scalar residual.
Base type for a scalar advection-diffusion solver.
Implements the logic to compute the time coefficients for the advection and diffusion operators in a ...