Loading [MathJax]/extensions/tex2jax.js
Neko 0.9.99
A portable framework for high-order spectral element flow simulations
All Classes Namespaces Files Functions Variables Typedefs Enumerator Macros Pages
fluid_scheme_compressible_euler.f90
Go to the documentation of this file.
1! Copyright (c) 2025, 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 use comm
35 use, intrinsic :: iso_fortran_env, only: error_unit
36 use advection, only : advection_t, advection_factory
38 use dofmap, only : dofmap_t
42 use math, only : col2, copy, col3, addcol3, subcol3
43 use device_math, only : device_col2
44 use field, only : field_t
46 use gs_ops, only : gs_op_add
47 use gather_scatter, only : gs_t
48 use num_types, only : rp
49 use mesh, only : mesh_t
50 use checkpoint, only : chkp_t
51 use operators, only: div, grad
52 use json_module, only : json_file, json_core, json_value
55 use user_intf, only : user_t
58 use ax_product, only : ax_t, ax_helm_factory
59 use field_list, only : field_list_t
60 use coefs, only: coef_t
61 use space, only : space_t
62 use euler_residual, only: euler_rhs_t, euler_rhs_factory
67 use bc_list, only: bc_list_t
69 use field_math, only : field_copy
70 use bc, only : bc_t
71 use utils, only : neko_error, neko_warning
72 use logger, only : log_size
73 implicit none
74 private
75
76 type, public, extends(fluid_scheme_compressible_t) &
78 type(field_t) :: rho_res, m_x_res, m_y_res, m_z_res, m_e_res
79 type(field_t) :: drho, dm_x, dm_y, dm_z, de
80 type(field_t) :: h
81 real(kind=rp) :: c_avisc_low
82 class(advection_t), allocatable :: adv
83 class(ax_t), allocatable :: ax
84 class(euler_rhs_t), allocatable :: euler_rhs
85 type(runge_kutta_time_scheme_t) :: rk_scheme
86
87 ! List of boundary conditions for velocity
88 type(bc_list_t) :: bcs_density
89 contains
90 procedure, pass(this) :: init => fluid_scheme_compressible_euler_init
91 procedure, pass(this) :: free => fluid_scheme_compressible_euler_free
92 procedure, pass(this) :: step => fluid_scheme_compressible_euler_step
93 procedure, pass(this) :: restart => fluid_scheme_compressible_euler_restart
95 procedure, pass(this) :: setup_bcs &
97 procedure, pass(this) :: compute_h
99
100 interface
101
108 module subroutine density_bc_factory(object, scheme, json, coef, user)
109 class(bc_t), pointer, intent(inout) :: object
110 type(fluid_scheme_compressible_euler_t), intent(in) :: scheme
111 type(json_file), intent(inout) :: json
112 type(coef_t), intent(in) :: coef
113 type(user_t), intent(in) :: user
114 end subroutine density_bc_factory
115 end interface
116
117 interface
118
125 module subroutine pressure_bc_factory(object, scheme, json, coef, user)
126 class(bc_t), pointer, intent(inout) :: object
127 type(fluid_scheme_compressible_euler_t), intent(in) :: scheme
128 type(json_file), intent(inout) :: json
129 type(coef_t), intent(in) :: coef
130 type(user_t), intent(in) :: user
131 end subroutine pressure_bc_factory
132 end interface
133
134 interface
135
142 module subroutine velocity_bc_factory(object, scheme, json, coef, user)
143 class(bc_t), pointer, intent(inout) :: object
144 type(fluid_scheme_compressible_euler_t), intent(in) :: scheme
145 type(json_file), intent(inout) :: json
146 type(coef_t), intent(in) :: coef
147 type(user_t), intent(in) :: user
148 end subroutine velocity_bc_factory
149 end interface
150
151contains
159 subroutine fluid_scheme_compressible_euler_init(this, msh, lx, params, user, &
160 chkp)
161 class(fluid_scheme_compressible_euler_t), target, intent(inout) :: this
162 type(mesh_t), target, intent(inout) :: msh
163 integer, intent(in) :: lx
164 type(json_file), target, intent(inout) :: params
165 type(user_t), target, intent(in) :: user
166 type(chkp_t), target, intent(inout) :: chkp
167 character(len=12), parameter :: scheme = 'compressible'
168 integer :: rk_order
169
170 call this%free()
171
172 ! Initialize base class
173 call this%scheme_init(msh, lx, params, scheme, user)
174
175 call euler_rhs_factory(this%euler_rhs)
176
177 associate(xh_lx => this%Xh%lx, xh_ly => this%Xh%ly, xh_lz => this%Xh%lz, &
178 dm_xh => this%dm_Xh, nelv => this%msh%nelv)
179
180 call this%drho%init(dm_xh, 'drho')
181 call this%dm_x%init(dm_xh, 'dm_x')
182 call this%dm_y%init(dm_xh, 'dm_y')
183 call this%dm_z%init(dm_xh, 'dm_z')
184 call this%dE%init(dm_xh, 'dE')
185 call this%h%init(dm_xh, 'h')
186
187 end associate
188
189 if (neko_bcknd_device .eq. 1) then
190 associate(p => this%p, rho_field => this%rho_field, &
191 u => this%u, v => this%v, w => this%w, &
192 m_x => this%m_x, m_y => this%m_y, m_z => this%m_z)
193 call device_memcpy(p%x, p%x_d, p%dof%size(), &
194 host_to_device, sync = .false.)
195 call device_memcpy(rho_field%x, rho_field%x_d, rho_field%dof%size(), &
196 host_to_device, sync = .false.)
197 call device_memcpy(u%x, u%x_d, u%dof%size(), &
198 host_to_device, sync = .false.)
199 call device_memcpy(v%x, v%x_d, v%dof%size(), &
200 host_to_device, sync = .false.)
201 call device_memcpy(w%x, w%x_d, w%dof%size(), &
202 host_to_device, sync = .false.)
203 call device_memcpy(m_x%x, m_x%x_d, m_x%dof%size(), &
204 host_to_device, sync = .false.)
205 call device_memcpy(m_y%x, m_y%x_d, m_y%dof%size(), &
206 host_to_device, sync = .false.)
207 call device_memcpy(m_z%x, m_z%x_d, m_z%dof%size(), &
208 host_to_device, sync = .false.)
209 end associate
210 end if
211
212 ! Initialize the diffusion operator
213 call ax_helm_factory(this%Ax, full_formulation = .false.)
214
215 ! Compute h
216 call this%compute_h()
217 call json_get_or_default(params, 'case.numerics.c_avisc_low', &
218 this%c_avisc_low, 0.5_rp)
219
220 ! Initialize Runge-Kutta scheme
221 call json_get_or_default(params, 'case.numerics.time_order', rk_order, 4)
222 call this%rk_scheme%init(rk_order)
223
224 ! Set up boundary conditions
225 call this%setup_bcs(user, params)
226
227 end subroutine fluid_scheme_compressible_euler_init
228
231 subroutine fluid_scheme_compressible_euler_free(this)
232 class(fluid_scheme_compressible_euler_t), intent(inout) :: this
233
234 if (allocated(this%Ax)) then
235 deallocate(this%Ax)
236 end if
237
238 call this%drho%free()
239 call this%dm_x%free()
240 call this%dm_y%free()
241 call this%dm_z%free()
242 call this%dE%free()
243
244 ! call this%scheme_free()
245 end subroutine fluid_scheme_compressible_euler_free
246
254 subroutine fluid_scheme_compressible_euler_step(this, t, tstep, dt, &
255 ext_bdf, dt_controller)
256 class(fluid_scheme_compressible_euler_t), target, intent(inout) :: this
257 real(kind=rp), intent(in) :: t
258 integer, intent(in) :: tstep
259 real(kind=rp), intent(in) :: dt
260 type(time_scheme_controller_t), intent(in) :: ext_bdf
261 type(time_step_controller_t), intent(in) :: dt_controller
262 type(field_t), pointer :: temp
263 integer :: temp_indices(1)
264 ! number of degrees of freedom
265 integer :: n
266
267 n = this%dm_Xh%size()
268 call this%scratch%request_field(temp, temp_indices(1))
269
270 call profiler_start_region('Fluid compressible', 1)
271 associate(u => this%u, v => this%v, w => this%w, p => this%p, &
272 m_x=> this%m_x, m_y => this%m_y, m_z => this%m_z, &
273 xh => this%Xh, msh => this%msh, ax => this%Ax, &
274 c_xh => this%c_Xh, dm_xh => this%dm_Xh, gs_xh => this%gs_Xh, &
275 rho => this%rho, mu => this%mu, e => this%E, &
276 rho_field => this%rho_field, mu_field => this%mu_field, &
277 ulag => this%ulag, vlag => this%vlag, wlag => this%wlag, &
278 f_x => this%f_x, f_y => this%f_y, f_z => this%f_z, &
279 drho => this%drho, dm_x => this%dm_x, dm_y => this%dm_y, &
280 dm_z => this%dm_z, de => this%dE, &
281 euler_rhs => this%euler_rhs, h => this%h, &
282 c_avisc_low => this%c_avisc_low, rk_scheme => this%rk_scheme)
283
284 ! Hack: If m_z is always zero, use it to visualize rho
285 ! call field_cfill(m_z, 0.0_rp, n)
286
287 call euler_rhs%step(rho_field, m_x, m_y, m_z, e, &
288 p, u, v, w, ax, &
289 c_xh, gs_xh, h, c_avisc_low, &
290 rk_scheme, dt)
291
293 call this%bcs_density%apply(rho_field, t, tstep)
294
296 ! Update u, v, w
297 call field_copy(u, m_x, n)
298 call field_invcol2(u, rho_field, n)
299 call field_copy(v, m_y, n)
300 call field_invcol2(v, rho_field, n)
301 call field_copy(w, m_z, n)
302 call field_invcol2(w, rho_field, n)
303
305 call this%bcs_vel%apply_vector(u%x, v%x, w%x, &
306 dm_xh%size(), t, tstep, strong = .true.)
307 call field_copy(m_x, u, n)
308 call field_col2(m_x, rho_field, n)
309 call field_copy(m_y, v, n)
310 call field_col2(m_y, rho_field, n)
311 call field_copy(m_z, w, n)
312 call field_col2(m_z, rho_field, n)
313
315 call field_col3(temp, u, u, n)
316 call field_addcol3(temp, v, v, n)
317 call field_addcol3(temp, w, w, n)
318 call field_col2(temp, rho_field, n)
319 call field_cmult(temp, 0.5_rp, n)
320 call field_copy(p, e, n)
321 call field_sub2(p, temp, n)
322 call field_cmult(p, this%gamma - 1.0_rp, n)
323
325 call this%bcs_prs%apply(p, t, tstep)
326 ! TODO: Make sure pressure is positive
327 ! E = p / (gamma - 1) + 0.5 * rho * (u^2 + v^2 + w^2)
328 call field_copy(e, p, n)
329 call field_cmult(e, 1.0_rp / (this%gamma - 1.0_rp), n)
330 ! temp = 0.5 * rho * (u^2 + v^2 + w^2)
331 call field_add2(e, temp, n)
332
334
335 ! Hack: If m_z is always zero, use it to visualize rho
336 ! call field_copy(w, rho_field, n)
337
338 end associate
339 call profiler_end_region('Fluid compressible', 1)
340
341 call this%scratch%relinquish_field(temp_indices)
342
343 end subroutine fluid_scheme_compressible_euler_step
344
349 subroutine fluid_scheme_compressible_euler_setup_bcs(this, user, params)
350 class(fluid_scheme_compressible_euler_t), intent(inout) :: this
351 type(user_t), target, intent(in) :: user
352 type(json_file), intent(inout) :: params
353 integer :: i, n_bcs, zone_index, j, zone_size, global_zone_size, ierr
354 class(bc_t), pointer :: bc_i
355 type(json_core) :: core
356 type(json_value), pointer :: bc_object
357 type(json_file) :: bc_subdict
358 logical :: found
359 integer, allocatable :: zone_indices(:)
360 character(len=LOG_SIZE) :: log_buf
361
362 ! Process boundary conditions
363 if (params%valid_path('case.fluid.boundary_conditions')) then
364 call params%info('case.fluid.boundary_conditions', n_children = n_bcs)
365 call params%get_core(core)
366 call params%get('case.fluid.boundary_conditions', bc_object, found)
367
368 !
369 ! Velocity bcs
370 !
371 call this%bcs_vel%init(n_bcs)
372
373 do i = 1, n_bcs
374 ! Extract BC configuration
375 call json_extract_item(core, bc_object, i, bc_subdict)
376 call json_get(bc_subdict, "zone_indices", zone_indices)
377
378 ! Validate zones
379 do j = 1, size(zone_indices)
380 zone_size = this%msh%labeled_zones(zone_indices(j))%size
381 call mpi_allreduce(zone_size, global_zone_size, 1, &
382 mpi_integer, mpi_max, neko_comm, ierr)
383
384 if (global_zone_size .eq. 0) then
385 write(error_unit,'(A,I0,A)') "Error: Zone ", zone_indices(j), &
386 " has zero size"
387 error stop
388 end if
389 end do
390
391 ! Create BC
392 bc_i => null()
393 call velocity_bc_factory(bc_i, this, bc_subdict, this%c_Xh, user)
394
395 ! Add to appropriate lists
396 if (associated(bc_i)) then
397 call this%bcs_vel%append(bc_i)
398 end if
399 end do
400
401 !
402 ! Pressure bcs
403 !
404 call this%bcs_prs%init(n_bcs)
405
406 do i = 1, n_bcs
407 ! Create a new json containing just the subdict for this bc
408 call json_extract_item(core, bc_object, i, bc_subdict)
409 bc_i => null()
410 call pressure_bc_factory(bc_i, this, bc_subdict, this%c_Xh, user)
411
412 ! Not all bcs require an allocation for pressure in particular,
413 ! so we check.
414 if (associated(bc_i)) then
415 call this%bcs_prs%append(bc_i)
416 end if
417 end do
418
419 !
420 ! Density bcs
421 !
422 call this%bcs_density%init(n_bcs)
423
424 do i = 1, n_bcs
425 ! Create a new json containing just the subdict for this bc
426 call json_extract_item(core, bc_object, i, bc_subdict)
427 bc_i => null()
428 call density_bc_factory(bc_i, this, bc_subdict, this%c_Xh, user)
429
430 ! Not all bcs require an allocation for pressure in particular,
431 ! so we check.
432 if (associated(bc_i)) then
433 call this%bcs_density%append(bc_i)
434 end if
435 end do
436 end if
437 end subroutine fluid_scheme_compressible_euler_setup_bcs
438
443 subroutine compute_h(this)
444 class(fluid_scheme_compressible_euler_t), intent(inout) :: this
445 integer :: e, i, j, k
446 integer :: im, ip, jm, jp, km, kp
447 real(kind=rp) :: di, dj, dk, ndim_inv
448 integer :: lx_half, ly_half, lz_half
449
450 lx_half = this%c_Xh%Xh%lx / 2
451 ly_half = this%c_Xh%Xh%ly / 2
452 lz_half = this%c_Xh%Xh%lz / 2
453
454 do e = 1, this%c_Xh%msh%nelv
455 do k = 1, this%c_Xh%Xh%lz
456 km = max(1, k-1)
457 kp = min(this%c_Xh%Xh%lz, k+1)
458
459 do j = 1, this%c_Xh%Xh%ly
460 jm = max(1, j-1)
461 jp = min(this%c_Xh%Xh%ly, j+1)
462
463 do i = 1, this%c_Xh%Xh%lx
464 im = max(1, i-1)
465 ip = min(this%c_Xh%Xh%lx, i+1)
466
467 di = (this%c_Xh%dof%x(ip, j, k, e) - &
468 this%c_Xh%dof%x(im, j, k, e))**2 &
469 + (this%c_Xh%dof%y(ip, j, k, e) - &
470 this%c_Xh%dof%y(im, j, k, e))**2 &
471 + (this%c_Xh%dof%z(ip, j, k, e) - &
472 this%c_Xh%dof%z(im, j, k, e))**2
473
474 dj = (this%c_Xh%dof%x(i, jp, k, e) - &
475 this%c_Xh%dof%x(i, jm, k, e))**2 &
476 + (this%c_Xh%dof%y(i, jp, k, e) - &
477 this%c_Xh%dof%y(i, jm, k, e))**2 &
478 + (this%c_Xh%dof%z(i, jp, k, e) - &
479 this%c_Xh%dof%z(i, jm, k, e))**2
480
481 dk = (this%c_Xh%dof%x(i, j, kp, e) - &
482 this%c_Xh%dof%x(i, j, km, e))**2 &
483 + (this%c_Xh%dof%y(i, j, kp, e) - &
484 this%c_Xh%dof%y(i, j, km, e))**2 &
485 + (this%c_Xh%dof%z(i, j, kp, e) - &
486 this%c_Xh%dof%z(i, j, km, e))**2
487
488 di = sqrt(di) / (ip - im)
489 dj = sqrt(dj) / (jp - jm)
490 dk = sqrt(dk) / (kp - km)
491 this%h%x(i,j,k,e) = (di * dj * dk)**(1.0_rp / 3.0_rp)
492
493 end do
494 end do
495 end do
496 end do
497
498 if (neko_bcknd_device .eq. 1) then
499 call device_memcpy(this%h%x, this%h%x_d, this%h%dof%size(),&
500 host_to_device, sync = .false.)
501 call this%gs_Xh%op(this%h, gs_op_add)
502 call device_col2(this%h%x_d, this%c_Xh%mult_d, this%h%dof%size())
503 else
504 call this%gs_Xh%op(this%h, gs_op_add)
505 call col2(this%h%x, this%c_Xh%mult, this%h%dof%size())
506 end if
507
508 end subroutine compute_h
509
514 subroutine fluid_scheme_compressible_euler_restart(this, chkp)
515 class(fluid_scheme_compressible_euler_t), target, intent(inout) :: this
516 type(chkp_t), intent(inout) :: chkp
517 end subroutine fluid_scheme_compressible_euler_restart
518
Copy data between host and device (or device and device)
Definition device.F90:65
Abstract interface to evaluate rhs.
Definition euler_res.f90:54
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 boundary condition.
Definition bc.f90:34
Defines a checkpoint.
Coefficients.
Definition coef.f90:34
Definition comm.F90:1
subroutine, public device_col2(a_d, b_d, n)
Vector multiplication .
Device abstraction, common interface for various accelerators.
Definition device.F90:34
integer, parameter, public host_to_device
Definition device.F90:46
Defines a mapping of the degrees of freedom.
Definition dofmap.f90:35
Defines inflow dirichlet conditions.
Defines user dirichlet condition for a scalar field.
subroutine, public field_invcol2(a, b, n)
Vector division .
subroutine, public field_cadd(a, s, n)
Add a scalar to vector .
subroutine, public field_col2(a, b, n)
Vector multiplication .
subroutine, public field_sub2(a, b, n)
Vector substraction .
subroutine, public field_cfill(a, c, n)
Set all elements to a constant c .
subroutine, public field_addcol3(a, b, c, n)
Returns .
subroutine, public field_add2(a, b, n)
Vector addition .
subroutine, public field_col3(a, b, c, n)
Vector multiplication with 3 vectors .
subroutine, public field_copy(a, b, n)
Copy a vector .
subroutine, public field_cmult(a, c, n)
Multiplication by constant c .
Defines a field.
Definition field.f90:34
subroutine compute_h(this)
Copied from les_model_compute_delta in les_model.f90 TODO: move to a separate module Compute characte...
subroutine fluid_scheme_compressible_euler_init(this, msh, lx, params, user, chkp)
Boundary condition factory for density.
subroutine fluid_scheme_compressible_euler_step(this, t, tstep, dt, ext_bdf, dt_controller)
Advance the fluid simulation one timestep.
subroutine fluid_scheme_compressible_euler_free(this)
Free allocated memory and cleanup.
subroutine fluid_scheme_compressible_euler_restart(this, chkp)
Restart the simulation from saved state.
subroutine fluid_scheme_compressible_euler_setup_bcs(this, user, params)
Set up boundary conditions for the fluid scheme.
Gather-scatter.
Defines Gather-scatter operations.
Definition gs_ops.f90:34
integer, parameter, public gs_op_add
Definition gs_ops.f90:36
Utilities for retrieving parameters from the case files.
Logging routines.
Definition log.f90:34
integer, parameter, public log_size
Definition log.f90:42
Definition math.f90:60
subroutine, public subcol3(a, b, c, n)
Returns .
Definition math.f90:755
subroutine, public addcol3(a, b, c, n)
Returns .
Definition math.f90:800
subroutine, public col2(a, b, n)
Vector multiplication .
Definition math.f90:728
subroutine, public copy(a, b, n)
Copy a vector .
Definition math.f90:238
subroutine, public col3(a, b, c, n)
Vector multiplication with 3 vectors .
Definition math.f90:741
Defines a mesh.
Definition mesh.f90:34
Build configurations.
integer, parameter neko_bcknd_device
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:12
Operators.
Definition operators.f90:34
subroutine, public div(res, ux, uy, uz, coef)
Compute the divergence of a vector field.
subroutine, public grad(ux, uy, uz, u, coef)
Compute the gradient of a scalar field.
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
Defines a function space.
Definition space.f90:34
Compound scheme for the advection and diffusion operators in a transport equation.
Implements type time_step_controller.
Interfaces for user interaction with NEKO.
Definition user_intf.f90:34
Utilities.
Definition utils.f90:35
subroutine, public neko_warning(warning_msg)
Reports a warning to standard output.
Definition utils.f90:266
Defines a zero-valued Dirichlet boundary condition.
Base abstract type for computing the advection operator.
Definition advection.f90:46
Base type for a matrix-vector product providing .
Definition ax.f90:43
Base type for a boundary condition.
Definition bc.f90:57
A list of allocatable `bc_t`. Follows the standard interface of lists.
Definition bc_list.f90:47
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Definition coef.f90:55
Abstract type to compute rhs.
Definition euler_res.f90:47
User defined dirichlet condition, for which the user can work with an entire field....
Extension of the user defined dirichlet condition field_dirichlet
field_list_t, To be able to group fields together
The function space for the SEM solution fields.
Definition space.f90:62
Implements the logic to compute the time coefficients for the advection and diffusion operators in a ...
A type collecting all the overridable user routines.
Zero-valued Dirichlet boundary condition. Used for no-slip walls, but also for various auxillary cond...
#define max(a, b)
Definition tensor.cu:40