Additional post-processing variables
For the mesh parts defined using the GUI or in cs_user_postprocess.c, the cs_user_postprocess_values function of the cs_user_postprocess.c file may be used to specify the variables to post-process (called for each postprocess output mesh, at every active time step of an associated writer).
The output of a given variable is generated by means of a call to the cs_post_write_var for cell or face values, cs_post_write_vertex_var for vertex values, for particle or trajectory values, and cs_post_write_probe_values for probe or profile values.
The examples of post-processing given below use meshes defined in the examples for above.
Output of the turbulent kinetic energy for the Rij-Epsilon model on the volume mesh
One can define, compute and post-process the turbulent kinetic energy for the Rij-Epsilon as shown in the following example:
s_cell[i] = 0.5* ( cvar_r[cell_id][0]
+ cvar_r[cell_id][1]
+ cvar_r[cell_id][2]);
}
}
else {
s_cell[i] = 0.5* ( cvar_r11[cell_id]
+ cvar_r22[cell_id]
+ cvar_r33[cell_id]);
}
}
"Turb energy",
1,
true,
false,
s_cell,
NULL,
NULL,
ts);
}
Output of a variable on a surface mesh
Values can also be output on a surface mesh, possibly containing a mix of boundary and internal faces. In the following example, we simply average or project adjacent cell values on faces, but more precise techniques could be used:
if (strcmp(mesh_name, "pressure_surface") == 0) {
cs_real_t *s_i_faces = NULL, *s_b_faces = NULL;
if (n_i_faces > 0) {
s_i_faces[i] = 0.5 * (cvar_p[
c1] + cvar_p[
c2]);
}
}
if (n_b_faces > 0) {
s_b_faces[i] = cvar_p[cell_id];
}
}
"Pressure",
1,
true,
false,
NULL,
s_i_faces,
s_b_faces,
ts);
}
Simple output of an existing field or array
For fields or arrays already defined on the full mesh, the "use_parent" option of cs_post_write_var may be used to simply reference the values on the parent (i.e. full) mesh when requesting an output. Note that the example below can also be used with probes or profiles:
if (f != NULL)
1,
true,
true,
NULL,
NULL,
ts);
}
Single output of time-independent values
Finally, a minor modification f the above example shows how it is possible to output time-independent values to a writer also used for time-dependent fields without requiring multiple outputs of those values:
if (f != NULL) {
1,
true,
true,
NULL,
NULL,
&ts0);
}
}
}
Additional profile variables
The following examples match the advanced profile definitions given in Advanced profile definitions.
The first section is common to both profile series:
For the profiles along fixed x, the following code is used. Note that this code's complexity is mainly due to extracting Reynolds stresses for different turbulence models and options. Specific values are then computed for each colum, in the switch statement:
if (strncmp(name, "buicesat", strlen("buicesat")) == 0) {
char var_name[64];
x_sum[0] += cell_cen[c_id][0];
}
x_sum[1] = n_cells;
n_cells,
cell_list,
NULL,
rij);
}
else if (turb_mdl->
itytur == 3 && turb_rans_mdl->
irijco == 0) {
}
}
else if (turb_mdl->
itytur == 3) {
rij[i][j] = cvar_rij[c_id][j];
}
}
for (int col = 0; col < 7; col++) {
switch(col) {
case 0:
{
strncpy(var_name, "U*10+x/h", 64);
val[i] = vel[c_id][0]*10 +
xpos;
}
}
break;
case 1:
{
strncpy(var_name, "Y/H", 64);
val[i] = mq->
cell_cen[c_id*3 + 1] / href;
}
}
break;
case 2:
{
strncpy(var_name, "U/Uc", 64);
val[i] = vel[c_id][0] /
uref;
}
}
break;
case 3:
{
strncpy(var_name, "uu/Uc^2", 64);
val[i] = rij[i][0] / uref2;
}
}
break;
case 4:
{
strncpy(var_name, "uv/Uc^2", 64);
val[i] = rij[i][3] / uref2;
}
}
break;
case 5:
{
strncpy(var_name, "vv/Uc^2", 64);
val[i] = rij[i][1] / uref2;
}
}
break;
case 6:
{
strncpy(var_name, "X", 64);
val[i] = cell_cen[c_id][0];
}
}
break;
}
(mesh_id,
var_name,
1,
0,
NULL,
NULL,
val,
ts_post);
}
}
For the profile defined all around a foil, the following code is used to compute the pressure coefficient and output its values:
val[i] = b_face_cog[face_id][0];
}
(mesh_id,
"X",
1,
0,
NULL,
NULL,
val,
ts);
cs_real_t div_half_ro0_uref2 = 1. / (0.5 * ro0 * uref2);
val[i] = (val[i] - p0) * div_half_ro0_uref2;
(mesh_id,
"CP",
1,
0,
NULL,
NULL,
val,
ts);
For the last profiles series, values for each column are also computed, requiring a reference pressure based on the mesh point closest to a given point, and computation of tangential stresses, so as to determine drag coefficients.
else if ( strcmp(name, "buicstr") == 0
|| strcmp(name, "buicinc") == 0) {
cs_real_t div_half_ro0_uref2 = 1. / (0.5 * phys_pro->
ro0 * uref2);
char var_name[64];
int pref_rank;
xyz_ref,
&pref_id,
&pref_rank);
pref = pres[pref_id];
for (int col = 0; col < 5; col++) {
switch(col) {
case 0:
{
strncpy(var_name, "X/H", 64);
val[i] = face_cog[f_id][0] / href;
}
}
break;
case 1:
{
strncpy(var_name, "CP", 64);
val[i] = (pres[c_id] - pref) * div_half_ro0_uref2;
}
}
break;
case 2:
{
strncpy(var_name, "CF", 64);
}
}
break;
case 3:
{
strncpy(var_name, "U/UREF", 64);
val[i] = copysign(val[i], stresses[i][0]);
}
}
break;
case 4:
{
strncpy(var_name, "YPLUS", 64);
val[i] = sqrt(fabs(vel[c_id][0])*
distb[f_id]*phys_pro->
viscl0);
}
}
break;
}
(mesh_id,
var_name,
1,
0,
NULL,
NULL,
val,
ts_post);
}
}