40 use json_module,
only : json_file
80 real(kind=
rp) :: c_avisc_entropy
82 real(kind=
rp) :: c_avisc_low
84 real(kind=
rp) :: gamma
104 type(
field_t),
pointer :: max_wave_speed => null()
110 type(
gs_t),
pointer :: gs => null()
127 procedure, pass(this) :: compute_entropy => &
130 procedure, pass(this),
private :: compute_residual => &
133 procedure, pass(this),
private :: compute_viscosity => &
136 procedure, pass(this),
private :: smooth_viscosity => &
139 procedure, pass(this),
private :: apply_element_max => &
142 procedure, pass(this),
private :: low_order_viscosity => &
154 type(json_file),
intent(inout) :: json
155 class(
case_t),
intent(inout),
target :: case
156 character(len=:),
allocatable :: reg_coeff_name
160 select type (fluid =>
case%fluid)
162 call this%set_fields(fluid%p, fluid%rho, fluid%u, fluid%v, &
163 fluid%w, fluid%max_wave_speed, fluid%msh, fluid%Xh, fluid%gs_Xh, &
166 call neko_error(
'Entropy viscosity requires a compressible fluid scheme')
170 reg_coeff_name,
"entropy_viscosity")
171 call this%init_base(
case%fluid%dm_Xh,
case%fluid%c_Xh, trim(reg_coeff_name))
172 if (
allocated(reg_coeff_name))
deallocate(reg_coeff_name)
176 this%c_avisc_entropy, 1.0_rp)
178 call this%entropy_residual%init(this%dof,
'entropy_residual')
182 call this%compute_entropy()
183 call this%S_lag%init(this%S, 3)
185 call this%h%init(this%dof,
'h')
186 call this%compute_h()
195 call this%free_base()
196 call this%entropy_residual%free()
197 call this%S_lag%free()
206 nullify(this%max_wave_speed)
220 call this%compute_residual(time%tstep, &
221 real(time%dt, kind=
rp), &
222 real(time%dtlag, kind=
rp))
224 call this%compute_viscosity(time%tstep)
235 integer,
intent(in) :: tstep
236 real(kind=
rp),
intent(in) :: dt
237 real(kind=
rp),
intent(in) :: dt_lag(10)
239 type(
field_t),
pointer :: us_field, vs_field, ws_field, div_field
240 integer :: temp_indices(4)
241 real(kind=
rp) :: bdf_coeffs(4)
243 real(kind=
rp) :: dt_local(10)
245 if (tstep .le. 3)
then
255 call bdf_scheme%compute_coeffs(bdf_coeffs, dt_local, 3)
259 this%entropy_residual%x_d, &
260 this%S%x_d, this%S_lag%lf(1)%x_d, &
261 this%S_lag%lf(2)%x_d, this%S_lag%lf(3)%x_d, &
265 this%entropy_residual%x, &
266 this%S%x, this%S_lag%lf(1)%x, &
267 this%S_lag%lf(2)%x, this%S_lag%lf(3)%x, &
278 call device_col3(us_field%x_d, this%u%x_d, this%S%x_d, n)
279 call device_col3(vs_field%x_d, this%v%x_d, this%S%x_d, n)
280 call device_col3(ws_field%x_d, this%w%x_d, this%S%x_d, n)
283 ws_field%x, this%u%x, this%v%x, this%w%x, this%S%x, n)
286 call div(div_field%x, us_field%x, vs_field%x, ws_field%x, this%coef)
289 call device_memcpy(this%entropy_residual%x, this%entropy_residual%x_d, &
298 call device_memcpy(this%entropy_residual%x, this%entropy_residual%x_d, &
311 integer,
intent(in) :: tstep
312 integer :: n, temp_indices(1)
313 real(kind=
rp) :: s_mean, n_s
314 type(
field_t),
pointer :: temp_field
318 if (tstep .le. 3)
then
337 call absval(temp_field%x, n)
341 n_s =
glmax(temp_field%x, n)
345 if (n_s < 1.0e-12_rp)
then
352 this%reg_coeff%x_d, this%entropy_residual%x_d, &
353 this%h%x_d, this%c_avisc_entropy, n_s, n)
356 this%reg_coeff%x, this%entropy_residual%x, &
357 this%h%x, this%c_avisc_entropy, n_s, n)
363 this%reg_coeff%x_d, this%h%x_d, this%max_wave_speed%x_d, &
367 this%reg_coeff%x, this%h%x, this%max_wave_speed%x, &
371 call this%apply_element_max()
373 call this%smooth_viscosity()
383 type(
field_t),
pointer :: temp_field, mult_field
384 integer :: temp_indices(2)
393 call field_copy(temp_field, this%reg_coeff, n)
401 this%reg_coeff%x_d, temp_field%x_d, mult_field%x_d, n)
404 this%reg_coeff%x, temp_field%x, mult_field%x, n)
421 this%reg_coeff%x_d, lx, this%msh%nelv)
424 this%reg_coeff%x, lx, this%msh%nelv)
442 max_wave_speed, msh, Xh, gs, gamma)
444 type(
field_t),
target,
intent(in) :: p, rho, u, v, w, max_wave_speed
445 type(
mesh_t),
target,
intent(in) :: msh
446 type(
space_t),
target,
intent(in) :: Xh
447 type(
gs_t),
target,
intent(in) :: gs
448 real(kind=
rp),
intent(in) :: gamma
455 this%max_wave_speed => max_wave_speed
476 this%rho%x, this%gamma, n)
488 call this%compute_entropy()
489 call this%S_lag%set(this%S)
500 call this%S_lag%update()
501 call this%compute_entropy()
516 integer,
intent(in) :: n
517 real(kind=
rp),
intent(out) :: us(n), vs(n), ws(n)
518 real(kind=
rp),
intent(in) :: u(n), v(n), w(n), s(n)
539 integer,
intent(in) :: n
540 real(kind=
rp),
intent(inout) :: entropy_residual(n)
541 real(kind=
rp),
intent(in) :: div_field(n)
550 entropy_residual(i) = abs(entropy_residual(i) + div_field(i))
561 integer,
intent(in) :: i
562 real(kind=
rp) :: visc
564 visc = this%c_avisc_low * this%h%x(i,1,1,1) * this%max_wave_speed%x(i,1,1,1)
575 integer :: e, i, j, k
576 integer :: im, ip, jm, jp, km, kp
577 real(kind=
rp) :: di, dj, dk, ndim_inv
578 integer :: lx_half, ly_half, lz_half
580 lx_half = this%coef%Xh%lx / 2
581 ly_half = this%coef%Xh%ly / 2
582 lz_half = this%coef%Xh%lz / 2
584 do concurrent(e = 1:this%coef%msh%nelv)
585 do concurrent(k = 1:this%coef%Xh%lz, &
586 j = 1:this%coef%Xh%ly, i = 1:this%coef%Xh%lx)
588 kp = min(this%coef%Xh%lz, k+1)
591 jp = min(this%coef%Xh%ly, j+1)
594 ip = min(this%coef%Xh%lx, i+1)
596 di = (this%coef%dof%x%x(ip, j, k, e) - &
597 this%coef%dof%x%x(im, j, k, e))**2 &
598 + (this%coef%dof%y%x(ip, j, k, e) - &
599 this%coef%dof%y%x(im, j, k, e))**2 &
600 + (this%coef%dof%z%x(ip, j, k, e) - &
601 this%coef%dof%z%x(im, j, k, e))**2
603 dj = (this%coef%dof%x%x(i, jp, k, e) - &
604 this%coef%dof%x%x(i, jm, k, e))**2 &
605 + (this%coef%dof%y%x(i, jp, k, e) - &
606 this%coef%dof%y%x(i, jm, k, e))**2 &
607 + (this%coef%dof%z%x(i, jp, k, e) - &
608 this%coef%dof%z%x(i, jm, k, e))**2
610 dk = (this%coef%dof%x%x(i, j, kp, e) - &
611 this%coef%dof%x%x(i, j, km, e))**2 &
612 + (this%coef%dof%y%x(i, j, kp, e) - &
613 this%coef%dof%y%x(i, j, km, e))**2 &
614 + (this%coef%dof%z%x(i, j, kp, e) - &
615 this%coef%dof%z%x(i, j, km, e))**2
617 di = sqrt(di) / (ip - im)
618 dj = sqrt(dj) / (jp - jm)
619 dk = sqrt(dk) / (kp - km)
620 this%h%x(i,j,k,e) = (di * dj * dk)**(1.0_rp / 3.0_rp)
629 call device_col2(this%h%x_d, this%coef%mult_d, this%h%dof%size())
632 call col2(this%h%x, this%coef%mult, this%h%dof%size())
Copy data between host and device (or device and device)
Retrieves a parameter by name or assigns a provided default value. In the latter case also adds the m...
Compute the divergence of a vector field.
Backward-differencing scheme for time integration.
Defines a simulation case.
CPU implementation of compressible flow operations.
subroutine, public compressible_ops_cpu_compute_entropy(s, p, rho, gamma, n)
Compute entropy field S = 1/(gamma-1) * rho * (log(p) - gamma * log(rho)) on CPU.
Device implementation of compressible flow operations.
subroutine, public compressible_ops_device_compute_entropy(s, p, rho, gamma, n)
Compute entropy field S = 1/(gamma-1) * rho * (log(p) - gamma * log(rho)) on device.
real(kind=rp) function, public device_glsum(a_d, n, strm)
Sum a vector of length n.
subroutine, public device_col2(a_d, b_d, n, strm)
Vector multiplication .
subroutine, public device_absval(a_d, n, strm)
subroutine, public device_col3(a_d, b_d, c_d, n, strm)
Vector multiplication with 3 vectors .
Device abstraction, common interface for various accelerators.
integer, parameter, public host_to_device
integer, parameter, public device_to_host
Defines a mapping of the degrees of freedom.
subroutine compute_h(h, zgml, gdim, lx)
CPU backend for entropy viscosity regularization.
subroutine, public entropy_viscosity_compute_viscosity_cpu(reg_coeff, entropy_residual, h, c_avisc_entropy, n_s, n)
Compute viscosity from entropy residual on CPU.
subroutine, public entropy_viscosity_compute_residual_cpu(entropy_residual, s, s_lag1, s_lag2, s_lag3, bdf_coeffs, dt, n)
Compute entropy residual on CPU.
subroutine, public entropy_viscosity_smooth_divide_cpu(reg_coeff, temp_field, mult_field, n)
Divide by multiplicity for smoothing on CPU.
subroutine, public entropy_viscosity_clamp_to_low_order_cpu(reg_coeff, h, max_wave_speed, c_avisc_low, n)
Clamp regularization coefficient to low-order viscosity on CPU.
subroutine, public entropy_viscosity_apply_element_max_cpu(reg_coeff, lx, nelv)
Apply element-wise maximum on CPU.
Device backend for entropy viscosity regularization.
subroutine, public entropy_viscosity_smooth_divide_device(reg_coeff_d, temp_field_d, mult_field_d, n)
Divide by gather-scatter multiplicity on a device.
subroutine, public entropy_viscosity_clamp_to_low_order_device(reg_coeff_d, h_d, max_wave_speed_d, c_avisc_low, n)
Clamp the coefficient to low-order viscosity on a device.
subroutine, public entropy_viscosity_apply_element_max_device(reg_coeff_d, lx, nelv)
Apply the element-wise maximum on a device.
subroutine, public entropy_viscosity_compute_residual_device(entropy_residual_d, s_d, s_lag1_d, s_lag2_d, s_lag3_d, bdf_coeffs, dt, n)
Compute entropy residual on a device.
subroutine, public entropy_viscosity_compute_viscosity_device(reg_coeff_d, entropy_residual_d, h_d, c_avisc_entropy, n_s, n)
Compute viscosity from an entropy residual on a device.
Implements the entropy-based artificial viscosity model.
subroutine entropy_viscosity_apply_element_max(this)
Replace nodal viscosity values by the maximum in each element.
subroutine entropy_viscosity_abs_add_cpu(entropy_residual, div_field, n)
Add the flux divergence to the residual and take its absolute value.
subroutine entropy_viscosity_col3_vector_cpu(us, vs, ws, u, v, w, s, n)
Multiply each velocity component by entropy on the CPU.
subroutine entropy_viscosity_compute_h(this)
Compute the characteristic mesh size. Adapted from les_model_compute_delta in les_model....
subroutine entropy_viscosity_smooth_viscosity(this)
Cross-element smoothing via gather-scatter averaging. Averages viscosity values at shared nodes betwe...
subroutine entropy_viscosity_preprocess(this, time)
Compute the artificial viscosity before a time step.
subroutine entropy_viscosity_compute_viscosity(this, tstep)
Compute and limit the entropy viscosity coefficient.
subroutine entropy_viscosity_compute_residual(this, tstep, dt, dt_lag)
Compute the BDF entropy residual.
subroutine entropy_viscosity_update_lag(this, time)
Shift the entropy history and compute the new entropy.
subroutine entropy_viscosity_init(this, case, json)
Initialize the entropy viscosity model from a case and JSON parameters.
subroutine entropy_viscosity_free(this)
Free the entropy viscosity model.
subroutine entropy_viscosity_restart(this, time)
Reinitialize entropy history from a restarted flow state.
subroutine entropy_viscosity_compute_entropy(this)
Compute entropy from the current pressure and density.
pure real(kind=rp) function entropy_viscosity_low_order(this, i)
Compute low-order viscosity at one point.
subroutine entropy_viscosity_set_fields(this, p, rho, u, v, w, max_wave_speed, msh, xh, gs, gamma)
Associate the fields and discretization used by the model.
subroutine, public field_cadd(a, s, n)
Add a scalar to vector .
subroutine, public field_cfill(a, c, n)
Set all elements to a constant c .
real(kind=rp) function, public field_glsum(a, n)
subroutine, public field_copy(a, b, n)
Copy a vector .
Contains the field_serties_t type.
Defines Gather-scatter operations.
integer, parameter, public gs_op_add
Utilities for retrieving parameters from the case files.
subroutine, public absval(a, n)
Take the absolute value of an array.
subroutine, public col2(a, b, n)
Vector multiplication .
real(kind=rp) function, public glmax(a, n)
Max of a vector of length n.
integer, parameter neko_bcknd_device
integer, parameter, public rp
Global precision used in computations.
Defines a registry for storing solution fields.
type(registry_t), target, public neko_registry
Global field registry.
Defines a registry for storing and requesting temporary objects This can be used when you have a func...
type(scratch_registry_t), target, public neko_scratch_registry
Global scratch registry.
Defines a function space.
Module with things related to the simulation time.
Base abstract type for artificial viscosity models.
Implicit backward-differencing scheme for time integration.
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Entropy-based artificial viscosity model for compressible flow.
Stores a series (sequence) of fields, logically connected to a base field, and arranged according to ...
Base type of compressible fluid formulations.
The function space for the SEM solution fields.
A struct that contains all info about the time, expand as needed.