9.2
general documentation
Infinite channel inlet with near-inlet feedback

A second method of defining an inlet condition which converges towards an infinite channel profile is based simply on feedback from values computed at inlet cell centers (combining the inlet boundary conditions and the effect of wall friction on the inlet walls). It assumes the mesh is very regular and orthogonal, at least on the first two inlet cell layers (using a gradient correction in the case of a less regular mesh might work, but has never been tested.

Initialization and finalization

Initialization and finalization is similar to that of the base examples

const cs_lnum_t n_cells_ext = domain->mesh->n_cells_with_ghosts;
const cs_lnum_t n_b_faces = domain->mesh->n_b_faces;
const int n_fields = cs_field_n_fields();
const int keysca = cs_field_key_id("scalar_id");
const int nt_cur = domain->time_step->nt_cur;
const cs_lnum_t *b_face_cells = domain->mesh->b_face_cells;
const cs_nreal_3_t *restrict b_face_u_normal
= domain->mesh_quantities->b_face_u_normal;
const cs_real_t *restrict b_face_surf
= domain->mesh_quantities->b_face_surf;
const auto bpro_rho = CS_F_(rho_b)->get_val_s();
const auto cvar_vel = CS_F_(vel)->get_val_v();
const cs_zone_t *zn = nullptr;
#define restrict
Definition: cs_defs.h:148
double cs_real_t
Floating-point value.
Definition: cs_defs.h:332
cs_nreal_t cs_nreal_3_t[3]
Definition: cs_defs.h:375
int cs_lnum_t
local mesh entity id
Definition: cs_defs.h:325
int cs_field_n_fields(void)
Return the number of defined fields.
Definition: cs_field.cpp:1505
int cs_field_key_id(const char *name)
Return an id associated with a given key name.
Definition: cs_field.cpp:2728
@ vel
Definition: cs_field_pointer.h:66
@ rho_b
Definition: cs_field_pointer.h:97
#define CS_F_(e)
Macro used to return a field pointer by its enumerated value.
Definition: cs_field_pointer.h:47
const cs_fluid_properties_t * cs_glob_fluid_properties
Definition: cs_physical_constants.cpp:462
double viscl0
Definition: cs_physical_constants.h:75
Definition: cs_zone.h:51

Body

Here, we define an inlet boundary condition for a very long channel or duct with a section matching the boundary faces of zone 'INLET'.

We fix a mean inlet velocity, and use a feedback loop assuming a fixed-point type behavior will allow us to reach a state matching that of a very long inlet channel.

Warning
We assume other boundary conditions are defined before this one (ideally, using the GUI).
We also assume that the mesh is orthogonal at the inlet, and we are using a RANS (not LES) computation. to the current inlet.

For EBRSM of V2f models, to avoid laminarization at the inlet, the initial velocity (at the first time step) is divided by 10 on inlet faces adjacent to the boundary, so as to ensure a velocity gradient and turbulent production. Otherwise, the initialization may fail.

zn = cs_boundary_zone_by_name("inlet");
constexpr cs_real_t fmprsc = 1.; // mean prescribed velocity
auto vel_val_ext = CS_F_(vel)->bc_coeffs->get_val_ext_v();
if (nt_cur == 1) {
/* For the Rij-EBRSM model (and possibly V2f), we need a non-flat profile,
* so as to ensure turbulent production, and avoid laminarization;
* here, we simply divide the initial velocity by 10 for inlet
* faces adjacent to the wall.
* The loop below assumes wall conditions have been defined first
* (in the GUI, or in this file, before the current test). */
cs_array<int> mrkcel;
mrkcel.reshape(n_cells_ext);
for (cs_lnum_t i = 0; i < n_cells_ext; i++)
mrkcel[i] = 0;
for (cs_lnum_t f_id = 0; f_id < n_b_faces; f_id++) {
if (bc_type[f_id] == CS_SMOOTHWALL) {
const cs_lnum_t c_id = b_face_cells[f_id];
mrkcel[c_id] = 1;
}
}
}
for (cs_lnum_t e_idx = 0; e_idx < zn->n_elts; e_idx++) {
const cs_lnum_t face_id = zn->elt_ids[e_idx];
const cs_lnum_t c_id = b_face_cells[face_id];
bc_type[face_id] = CS_INLET;
for (int ii = 0; ii < 3; ii++)
vel_val_ext(face_id, ii) = -fmprsc*b_face_u_normal[face_id][ii];
if (mrkcel[c_id] == 1)
vel_val_ext(face_id, 0) = fmprsc/10;
cs_real_t uref2 = 0;
for (int ii = 0; ii< CS_F_(vel)->dim; ii++)
uref2 += cs_math_pow2(vel_val_ext(face_id, ii));
uref2 = cs::max(uref2, 1e-12);
/* Turbulence example computed using equations valid for a pipe.
* We will be careful to specify a hydraulic diameter adapted
* to the current inlet.
* We will also be careful if necessary to use a more precise
* formula for the dynamic viscosity use in the calculation of
* the Reynolds number (especially if it is variable, it may be
* useful to take the law from 'cs_user_physical_properties'
* Here, we use by default the 'viscl0" value.
* Regarding the density, we have access to its value at boundary
* faces (b_rho) so this value is the one used here (specifically,
* it is consistent with the processing in 'cs_user_physical_properties',
* in case of variable density) */
/* Hydraulic diameter */
cs_real_t xdh = 1.0;
/* Calculation of turbulent inlet conditions using
the turbulence intensity and standard laws for a circular pipe
(their initialization is not needed here but is good practice) */
cs_real_t b_rho = bpro_rho[face_id];
uref2,
xdh,
b_rho,
viscl0);
}
/* Initialize user scalars inlet */
for (int f_id = 0; f_id < n_fields; f_id++) {
cs_field_t *fld = cs_field(f_id);
if (! (fld->type & (CS_FIELD_VARIABLE | CS_FIELD_USER)))
continue;
int sc_id = fld->get_key_int(keysca) - 1;
if (sc_id < 0)
continue;
auto val_ext = fld->bc_coeffs->get_val_ext();
for (cs_lnum_t e_idx = 0; e_idx < zn->n_elts; e_idx++) {
const cs_lnum_t face_id = zn->elt_ids[e_idx];
val_ext[face_id] = 1;
}
}
}
else {
/* Subsequent time steps
*----------------------*/
cs_real_2_t acc = {0, 0};
/* Accessors for BC values */
cs_span<cs_real_t> k_val_ext;
cs_span<cs_real_t> eps_val_ext;
cs_span<cs_real_t> alp_bl_val_ext;
cs_span<cs_real_t> phi_val_ext;
cs_span<cs_real_t> f_bar_val_ext;
cs_span<cs_real_t> omg_val_ext;
cs_span<cs_real_t> nusa_val_ext;
cs_span<cs_real_t> cvar_alp_bl;
cs_span<cs_real_t> cvar_f_bar;
cs_span<cs_real_t> cvar_nusa;
k_val_ext = CS_F_(k)->bc_coeffs->get_val_ext();
eps_val_ext = CS_F_(eps)->bc_coeffs->get_val_ext();
cvar_k = CS_F_(k)->get_val_s();
cvar_eps = CS_F_(eps)->get_val_s();
}
else if (cs_glob_turb_model->itytur == 3) {
rij_val_ext = CS_F_(rij)->bc_coeffs->get_val_ext_t();
eps_val_ext = CS_F_(eps)->bc_coeffs->get_val_ext();
cvar_rij = CS_F_(rij)->get_val_t();
cvar_eps = CS_F_(eps)->get_val_s();
alp_bl_val_ext = CS_F_(alp_bl)->bc_coeffs->get_val_ext();
cvar_alp_bl= CS_F_(alp_bl)->get_val_s();
}
}
k_val_ext = CS_F_(k)->bc_coeffs->get_val_ext();
eps_val_ext = CS_F_(eps)->bc_coeffs->get_val_ext();
phi_val_ext = CS_F_(phi)->bc_coeffs->get_val_ext();
cvar_k = CS_F_(k)->get_val_s();
cvar_eps = CS_F_(eps)->get_val_s();
cvar_phi = CS_F_(phi)->get_val_s();
f_bar_val_ext = CS_F_(f_bar)->bc_coeffs->get_val_ext();
cvar_f_bar = CS_F_(f_bar)->get_val_s();
}
alp_bl_val_ext = CS_F_(alp_bl)->bc_coeffs->get_val_ext();
cvar_alp_bl= CS_F_(alp_bl)->get_val_s();
}
}
k_val_ext = CS_F_(k)->bc_coeffs->get_val_ext();
omg_val_ext = CS_F_(omg)->bc_coeffs->get_val_ext();
cvar_k = CS_F_(k)->get_val_s();
cvar_omg = CS_F_(omg)->get_val_s();
}
nusa_val_ext = CS_F_(nusa)->bc_coeffs->get_val_ext();
cvar_nusa = CS_F_(nusa)->get_val_s();
}
/* Estimate multiplier */
for (cs_lnum_t e_idx = 0; e_idx < zn->n_elts; e_idx++) {
const cs_lnum_t face_id = zn->elt_ids[e_idx];
const cs_lnum_t c_id = b_face_cells[face_id];
const cs_real_t vnrm = cs_math_3_norm(cvar_vel.sub_array(c_id));
acc[0] += vnrm*b_face_surf[face_id];
acc[1] += b_face_surf[face_id];
}
cs_real_t fmul = 0; /* zero velocity in bulk domain */
if (acc[0] > cs_math_epzero)
fmul = fmprsc/(acc[0]/acc[1]); /* estimate flow multiplier */
/* Apply BCs */
for (cs_lnum_t e_idx = 0; e_idx < zn->n_elts; e_idx++) {
const cs_lnum_t face_id = zn->elt_ids[e_idx];
const cs_lnum_t c_id = b_face_cells[face_id];
const cs_real_t vnrm = cs_math_3_norm(cvar_vel.sub_array(c_id));
assert(bc_type[face_id] == CS_INLET);
for (cs_lnum_t ii = 0; ii < 3; ii++)
vel_val_ext(face_id, ii) = -fmul*vnrm*b_face_u_normal[face_id][ii];
k_val_ext[face_id] = cvar_k[c_id];
eps_val_ext[face_id] = cvar_eps[c_id];
}
else if (cs_glob_turb_model->itytur == 3) {
for (cs_lnum_t ii = 0; ii< 6; ii++)
rij_val_ext(face_id, ii) = cvar_rij(c_id, ii);
eps_val_ext[face_id] = cvar_eps[c_id];
alp_bl_val_ext[face_id] = cvar_alp_bl[c_id];
}
else if (cs_glob_turb_model->itytur == 5) {
k_val_ext[face_id] = cvar_k[c_id];
eps_val_ext[face_id] = cvar_eps[c_id];
phi_val_ext[face_id] = cvar_phi[c_id];
f_bar_val_ext[face_id] = cvar_f_bar[c_id];
alp_bl_val_ext[face_id] = cvar_alp_bl[c_id];
}
k_val_ext[face_id] = cvar_k[c_id];
omg_val_ext[face_id] = cvar_omg[c_id];
}
nusa_val_ext[face_id] = cvar_nusa[c_id];
}
}
for (int f_id = 0; f_id < n_fields; f_id++) {
cs_field_t *fld = cs_field(f_id);
if (! (fld->type & (CS_FIELD_VARIABLE | CS_FIELD_USER)))
continue;
int sc_id = fld->get_key_int(keysca) - 1;
if (sc_id < 0)
continue;
auto val_ext = fld->bc_coeffs->get_val_ext();
auto cvar = fld->get_val_s();
for (cs_lnum_t e_idx = 0; e_idx < zn->n_elts; e_idx++) {
const cs_lnum_t face_id = zn->elt_ids[e_idx];
const cs_lnum_t c_id = b_face_cells[face_id];
val_ext[face_id] = cvar[c_id];
}
}
}
Define a templated array class (owner of data)
Definition: cs_array.h:1118
CS_F_HOST void reshape(cs_lnum_t new_size, const char *file_name=__FILE__, const int line_number=__LINE__)
Resize data array.
Definition: cs_array.h:1718
Define a templated mdspan class (non owner of data)
Definition: cs_mdspan.h:68
cs_span< cs_real_t > get_val_ext() const
Return a 1D span view of boundary condition external values.
Definition: cs_field.cpp:5826
Field descriptor.
Definition: cs_field.h:275
int get_key_int(int key_id) const
Return a integer value for a given key associated with a field.
Definition: cs_field.cpp:4507
cs_span< cs_real_t > get_val_s(const int time_id=0) const
Return a 1D span view of field values. If the field is not a scalar a fatal error is provoked.
Definition: cs_field.cpp:5080
int type
Definition: cs_field.h:282
cs_field_bc_coeffs_t * bc_coeffs
Definition: cs_field.h:309
const cs_zone_t * cs_boundary_zone_by_name(const char *name)
Return a pointer to a boundary zone based on its name if present.
Definition: cs_boundary_zone.cpp:708
#define CS_REAL_TYPE
Definition: cs_defs.h:476
cs_real_t cs_real_2_t[2]
vector of 2 floating-point values
Definition: cs_defs.h:348
cs_field_t * cs_field(int id)
Return a pointer to a field based on its id. This function requires that a field of the given id is d...
Definition: cs_field.cpp:4295
@ alp_bl
Definition: cs_field_pointer.h:75
@ nusa
Definition: cs_field_pointer.h:79
@ k
Definition: cs_field_pointer.h:68
@ eps
Definition: cs_field_pointer.h:69
@ omg
Definition: cs_field_pointer.h:78
@ rij
Definition: cs_field_pointer.h:71
@ phi
Definition: cs_field_pointer.h:73
@ f_bar
Definition: cs_field_pointer.h:74
static constexpr cs_real_t cs_math_epzero
Definition: cs_math.h:102
CS_F_HOST_DEVICE cs_real_t cs_math_pow2(cs_real_t x)
Compute the square of a real value.
Definition: cs_math.h:902
CS_F_HOST_DEVICE T cs_math_3_norm(const T v[3])
Compute the euclidean norm of a vector of dimension 3.
Definition: cs_math.h:240
static void cs_parall_sum(int n, cs_datatype_t datatype, void *val)
Sum values of a given datatype on all default communicator processes.
Definition: cs_parall.h:139
@ CS_INLET
Definition: cs_parameters.h:83
@ CS_SMOOTHWALL
Definition: cs_parameters.h:87
void cs_turbulence_bc_inlet_hyd_diam(cs_lnum_t face_id, double uref2, double dh, double rho, double mu)
Set inlet boundary condition values for turbulence variables based on a diameter and the reference v...
Definition: cs_turbulence_bc.cpp:745
const cs_turb_model_t * cs_glob_turb_model
@ CS_TURB_SPALART_ALLMARAS
Definition: cs_turbulence_model.h:68
@ CS_TURB_RIJ_EPSILON_EBRSM
Definition: cs_turbulence_model.h:58
@ CS_TURB_V2F_PHI
Definition: cs_turbulence_model.h:65
@ CS_TURB_V2F_BL_V2K
Definition: cs_turbulence_model.h:66
@ CS_TURB_K_OMEGA
Definition: cs_turbulence_model.h:67
#define CS_FIELD_VARIABLE
Definition: cs_field.h:66
#define CS_FIELD_USER
Definition: cs_field.h:78
CS_F_HOST_DEVICE T max(const T a, const T b)
Definition: cs_defs.h:735
DISABLE_WARNING_POP int model
Definition: cs_turbulence_model.h:143
int itytur
Definition: cs_turbulence_model.h:169
const cs_lnum_t * elt_ids
Definition: cs_zone.h:61
cs_lnum_t n_elts
Definition: cs_zone.h:60