8.3
general documentation
Calculation of a local Nusselt number

This is an example of cs_user_extra_operations function which computes a local Nusselt number.

Local variables

Faces can be selected either using a selector (as is done here) or directly using boundary zone element ids if an appropriate zone has been defined.

const cs_lnum_t n_cells = domain->mesh->n_cells;
const cs_lnum_t n_b_faces = domain->mesh->n_b_faces;
const cs_lnum_t *b_face_cells = domain->mesh->b_face_cells;
const cs_real_3_t *cell_cen
= (const cs_real_3_t *)domain->mesh_quantities->cell_cen;
= (const cs_real_3_t *)domain->mesh_quantities->b_face_cog;
const cs_real_t *volume = domain->mesh_quantities->cell_vol;
FILE *file = nullptr;
/* Parameters, case dependant */
const cs_real_t prandtl = 0.71, height = 1., qwall = 1.;
const cs_field_t *f = CS_F_(t);
const cs_field_t *mu = CS_F_(mu);
cs_lnum_t nlelt;
cs_lnum_t *lstelt;
BFT_MALLOC(lstelt, n_b_faces, cs_lnum_t);
("normal[0, -1, 0, 0.1] and box[-1000, -1000, -1000, 1000, 0.01, 1000]",
&nlelt, lstelt);
#define BFT_MALLOC(_ptr, _ni, _type)
Definition: bft_mem.h:58
double cs_real_t
Floating-point value.
Definition: cs_defs.h:342
cs_real_t cs_real_3_t[3]
vector of 3 floating-point values
Definition: cs_defs.h:359
int cs_lnum_t
local mesh entity id
Definition: cs_defs.h:335
@ t
Definition: cs_field_pointer.h:94
@ mu
Definition: cs_field_pointer.h:105
@ vel
Definition: cs_field_pointer.h:70
#define CS_F_(e)
Macro used to return a field pointer by its enumerated value.
Definition: cs_field_pointer.h:51
const cs_fluid_properties_t * cs_glob_fluid_properties
Definition: cs_physical_constants.cpp:465
void cs_selector_get_b_face_list(const char *criteria, cs_lnum_t *n_b_faces, cs_lnum_t b_face_list[])
Fill a list of boundary faces verifying a given selection criteria.
Definition: cs_selector.cpp:213
double precision, dimension(:), pointer volume
volume of each cell
Definition: mesh.f90:100
double precision, dimension(:,:), pointer cdgfbo
coordinates of the centers of the boundary faces
Definition: mesh.f90:96
Field descriptor.
Definition: cs_field.h:131
Fluid properties descriptor.
Definition: cs_physical_constants.h:61

Reconstruct value at selected boundary faces

Allocate a local array for the selected boundary faces.

cs_real_t *treloc;
BFT_MALLOC(treloc, nlelt, cs_real_t);
int iortho = 0;

General case (for non-orthogonal meshes)

if (iortho == 0) {
cs_post_field_cell_to_b_face_values(f, nlelt, lstelt, treloc);
}
void cs_post_field_cell_to_b_face_values(const cs_field_t *f, cs_lnum_t n_loc_b_faces, const cs_lnum_t b_face_ids[], cs_real_t *b_val)
Compute values at a selection of boundary faces of a given field located on cells.
Definition: cs_post_util.cpp:899

Case of orthogonal meshes

Compute boundary value without reconstruction

const cs_real_t *coefap = CS_F_(t)->bc_coeffs->a;
const cs_real_t *coefbp = CS_F_(t)->bc_coeffs->b;
for (cs_lnum_t ielt = 0; ielt < nlelt; ielt++) {
cs_lnum_t face_id = lstelt[ielt];
cs_lnum_t c_id = b_face_cells[face_id];
treloc[ielt] = coefap[face_id] + coefbp[face_id] * f->val[c_id];
}
cs_real_t * val
Definition: cs_field.h:152
Note
Here, we assign the non-reconstructed value.

Open file to print values and broadcast values to all parallel ranks. Values are ordered by the xabs array values provided to the cs_parall_allgather_ordered_r, so this function is needed even when not running in parallel.

if (cs_glob_rank_id < 1) {
file = fopen("Nusselt.dat", "w");
}
cs_gnum_t neltg = nlelt;
cs_parall_counter(&neltg, 1);
cs_real_t *xabs = nullptr, *xabsg = nullptr, *xnusselt = nullptr;
cs_real_t *treglo = nullptr;
BFT_MALLOC(xabs, nlelt, cs_real_t);
BFT_MALLOC(xnusselt, neltg, cs_real_t);
BFT_MALLOC(xabsg, neltg, cs_real_t);
BFT_MALLOC(treglo, neltg, cs_real_t);
for (cs_lnum_t ilelt = 0; ilelt < nlelt; ilelt ++) {
cs_lnum_t face_id = lstelt[ilelt];
xabs[ilelt] = cdgfbo[face_id][0];
}
cs_parall_allgather_ordered_r(nlelt, neltg, 1, xabs, xabs, xabsg);
cs_parall_allgather_ordered_r(nlelt, neltg, 1, xabs, treloc, treglo);
BFT_FREE(xabs);
BFT_FREE(treloc);
BFT_FREE(lstelt);
#define BFT_FREE(_ptr)
Definition: bft_mem.h:90
int cs_glob_rank_id
Definition: cs_defs.cpp:174
uint64_t cs_gnum_t
global mesh entity number
Definition: cs_defs.h:325
void cs_parall_allgather_ordered_r(int n_elts, int n_g_elts, int stride, cs_real_t o_key[], cs_real_t array[], cs_real_t g_array[])
Build an ordered global array from each local array in each domain.
Definition: cs_parall.cpp:986
static void cs_parall_counter(cs_gnum_t cpt[], const int n)
Sum values of a counter on all default communicator processes.
Definition: cs_parall.h:88

Compute the bulk temperature, finalize the Nusselt number, print it and free memory not already freed before:

for (cs_gnum_t ilelt = 0; ilelt < neltg; ilelt ++) {
cs_real_t xtbulk = 0;
cs_real_t xubulk = 0;
int npoint = 200;
cs_lnum_t c_id_prev = -1;
int irang1 = -1;
int irangv;
for (int ii = 0; ii < npoint; ii++) {
cs_lnum_t c_id;
cs_real_t xyz[3] = {xabsg[ilelt],
(cs_real_t)ii/(cs_real_t)(npoint-1),
0.};
cell_cen,
xyz,
&c_id, &irangv);
if (c_id != c_id_prev || irangv != irang1) {
c_id_prev = c_id;
irang1 = irangv;
if (cs_glob_rank_id == irangv) {
cs_real_t xtb = volume[c_id]*f->val[c_id]*vel[c_id][0];
cs_real_t xub = volume[c_id]*vel[c_id][0];
xtbulk += xtb;
xubulk += xub;
lambda = phys_pro->cp0*mu->val[c_id] / prandtl;
}
}
}
/* Note: only last location used for lambda.
Would be more appropriate (but still not general at all)
with visls0 in definition of lambda and from the derivation
of Nusselt number; use of lambda at the wall (ii = 0)
would seem better */
cs_real_t xbulk[2] = {xtbulk, xubulk};
xtbulk = xbulk[0] / xbulk[1];
xubulk = xbulk[1];
cs_real_t tfac = treglo[ilelt];
xnusselt[ilelt] = qwall * 2. * height / lambda / (tfac - xtbulk);
}
for (cs_gnum_t ii = 0; ii < neltg; ii++)
fprintf(file,
"%17.9e %17.9e\n",
xabsg[ii]*10.,
xnusselt[ii]/(0.023*pow(30000., 0.8)*pow(0.71, 0.4)));
if (file != nullptr)
fclose(file);
BFT_FREE(xnusselt);
BFT_FREE(xabsg);
BFT_FREE(treglo);
#define CS_REAL_TYPE
Definition: cs_defs.h:486
@ lambda
Definition: cs_field_pointer.h:108
void cs_geom_closest_point(cs_lnum_t n_points, const cs_real_t point_coords[][3], const cs_real_t query_coords[3], cs_lnum_t *point_id, int *rank_id)
find the closest point of a set to a given point in space.
Definition: cs_geom.cpp:162
static void cs_parall_bcast(int root_rank, int n, cs_datatype_t datatype, void *val)
Broadcast values of a given datatype to all default communicator processes.
Definition: cs_parall.h:248
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:147
double cp0
Definition: cs_physical_constants.h:83