My Project
programmer's documentation
Interpolation

By default, probes and profile values are "P0" interpolated, that is their value is that of the containing cell or face, or closest vertex.

For cell-based values, a "P1" piecewise linear interpolation may be defined, using gradient reconstruction..

The following example shows how intepolation may be used in the cs_user_postprocess_values function.

First, we define an interpolation function:

/*----------------------------------------------------------------------------
* Interpolate values defined on a mesh location at a given set of
* points using a P0 interpolation.
*
* This function assumes the input is a field name. If no field matches
* the name, a "generic" interpolation (assuming homogeneous Neumann boundary
* conditions) is used).
*
* \param[in, out] input pointer to optional (untyped) value
* or structure.
* \param[in] datatype associated datatype
* \param[in] val_dim dimension of data values
* \param[in] n_points number of interpolation points
* \param[in] point_location location of points in mesh elements
* \param[in] point_coords point coordinates
* \param[in] location_vals values at mesh location
* \param[out] point_vals interpolated values at points
*----------------------------------------------------------------------------*/
static void
_cs_interpolate_from_location_p1(void *input,
cs_datatype_t datatype,
int val_dim,
cs_lnum_t n_points,
const cs_lnum_t point_location[],
const cs_real_3_t point_coords[],
const void *location_vals,
void *point_vals)
{
/* If used with a non-real argument type, use P0 interpolation */
if ( datatype != CS_REAL_TYPE
|| (val_dim != 1 && val_dim != 3 && val_dim != 6)) {
datatype,
val_dim,
n_points,
point_location,
point_coords,
location_vals,
point_vals);
return;
}
/* Main usage */
const cs_real_3_t *cell_cen
&gradient_type,
&halo_type);
cs_field_t *f = NULL;
if (input != NULL) {
const char *name = input;
}
switch(val_dim) {
case 1:
{
const cs_real_t *c_vals = (const cs_real_t *)location_vals;
cs_real_t *p_vals = (cs_real_t *)point_vals;
if (f != NULL)
false, /* use_previous_t */
1, /* inc */
true, /* _recompute_cocg */
grad);
else
gradient_type,
halo_type,
1, /* inc */
true, /* recompute_cocg */
100, /* n_r_sweeps */
0, /* tr_dim */
0, /* hyd_p_flag */
0, /* w_stride */
0, /* verbosity */
-1, /* clip_mode */
1e-5, /* epsilon */
0, /* extrap */
1.5, /* clip_coeff */
NULL, /* f_ext[] */
NULL, /* bc_coeff_a */
NULL, /* bc_coeff_b */
c_vals,
NULL, /* c_weight */
NULL, /* cpl */
grad);
for (cs_lnum_t i = 0; i < n_points; i++) {
cs_lnum_t c_id = point_location[i];
if (c_id > -1) {
cs_real_t d[3] = {point_coords[i][0] - cell_cen[c_id][0],
point_coords[i][1] - cell_cen[c_id][1],
point_coords[i][2] - cell_cen[c_id][2]};
p_vals[i] = c_vals[c_id] + grad[c_id][0]*d[0]
+ grad[c_id][1]*d[1]
+ grad[c_id][2]*d[2];
}
else
p_vals[i] = 0;
}
}
break;
case 3:
{
const cs_real_3_t *c_vals = (const cs_real_3_t *)location_vals;
cs_real_3_t *p_vals = (cs_real_3_t *)point_vals;
if (f != NULL)
false, /* use_previous_t */
1, /* inc */
grad);
else
gradient_type,
halo_type,
1, /* inc */
100, /* n_r_sweeps */
0, /* verbosity */
-1, /* clip_mode */
1e-5, /* epsilon */
1.5, /* clip_coeff */
NULL, /* bc_coeff_a */
NULL, /* bc_coeff_b */
c_vals,
NULL, /* c_weight */
NULL, /* cpl */
grad);
for (cs_lnum_t i = 0; i < n_points; i++) {
cs_lnum_t c_id = point_location[i];
if (c_id > -1) {
cs_real_t d[3] = {point_coords[i][0] - cell_cen[c_id][0],
point_coords[i][1] - cell_cen[c_id][1],
point_coords[i][2] - cell_cen[c_id][2]};
for (cs_lnum_t j = 0; j < 3; j++) {
p_vals[i][j] = c_vals[c_id][j] + grad[c_id][j][0]*d[0]
+ grad[c_id][j][1]*d[1]
+ grad[c_id][j][2]*d[2];
}
}
else {
for (cs_lnum_t j = 0; j < 6; j++)
p_vals[i][j] = 0;
}
}
}
break;
case 6:
{
const cs_real_6_t *c_vals = (const cs_real_6_t *)location_vals;
cs_real_6_t *p_vals = (cs_real_6_t *)point_vals;
if (f != NULL)
false, /* use_previous_t */
1, /* inc */
grad);
else
gradient_type,
halo_type,
1, /* inc */
100, /* n_r_sweeps */
0, /* verbosity */
-1, /* clip_mode */
1e-5, /* epsilon */
1.5, /* clip_coeff */
NULL, /* bc_coeff_a */
NULL, /* bc_coeff_b */
c_vals,
grad);
for (cs_lnum_t i = 0; i < n_points; i++) {
cs_lnum_t c_id = point_location[i];
if (c_id > -1) {
cs_real_t d[3] = {point_coords[i][0] - cell_cen[c_id][0],
point_coords[i][1] - cell_cen[c_id][1],
point_coords[i][2] - cell_cen[c_id][2]};
for (cs_lnum_t j = 0; j < 6; j++) {
p_vals[i][j] = c_vals[c_id][j] + grad[c_id][j][0]*d[0]
+ grad[c_id][j][1]*d[1]
+ grad[c_id][j][2]*d[2];
}
}
else {
for (cs_lnum_t j = 0; j < 6; j++)
p_vals[i][j] = 0;
}
}
}
break;
default:
assert(0);
}
}

Note the the gradient reconstruction used here assumes ghost cell values are synchronized, which should be the case for field values at this calling stage.

This interpolation function may the be passed to the probe values output function (in cs_user_postprocess_values):

const char *name = cs_probe_set_get_name(probes);
int n_p_fields = 2;
const char *p_field_names[] = {"velocity", "temperature"};
for (int i = 0; i < n_p_fields; i++) {
cs_field_t *f = cs_field_by_name_try(p_field_names[i]);
if (f != NULL) {
/* use different name to avoid conflict with field name in case already
present in probe set through default output */
char p_name[64];
snprintf(p_name, 63, "%s_p", f->name); p_name[63] = '\0';
(mesh_id,
CS_POST_WRITER_ALL_ASSOCIATED, /* writer id filter */
p_name, /* var_name */
f->dim, /* var_dim */
1, /* parent location id */
_cs_interpolate_from_location_p1, /* P1 interpolation */
f->name, /* interpolation input */
f->val,
ts);
}
}
}

In this case, selected outputs are named by appending "_p" to the field name to allow combining default probe outputs with interpolated outputs of specific fields.

For simplicity here, values are output to the main probe set and writer, which is assumed to be defined using the GUI in this example.

Note also that interpolation could be also used in some cs_user_extra_operations cases.

cs_field_t::dim
int dim
Definition: cs_field.h:131
input
static int input(void)
cs_post_write_probe_values
void cs_post_write_probe_values(int mesh_id, int writer_id, const char *var_name, int var_dim, cs_post_type_t var_type, int parent_location_id, cs_interpolate_from_location_t *interpolate_func, void *interpolate_input, const void *vals, const cs_time_step_t *ts)
Output a variable defined at cells or faces of a post-processing mesh using associated writers.
Definition: cs_post.c:5619
cs_glob_mesh_quantities
cs_mesh_quantities_t * cs_glob_mesh_quantities
cs_gradient_tensor_synced_input
void cs_gradient_tensor_synced_input(const char *var_name, cs_gradient_type_t gradient_type, cs_halo_type_t halo_type, int inc, int n_r_sweeps, int verbosity, int clip_mode, double epsilon, double clip_coeff, const cs_real_t bc_coeff_a[][6], const cs_real_t bc_coeff_b[][6][6], const cs_real_t var[restrict][6], cs_real_63_t *restrict grad)
Compute cell gradient of tensor.
Definition: cs_gradient.c:7936
cs_real_3_t
cs_real_t cs_real_3_t[3]
vector of 3 floating-point values
Definition: cs_defs.h:315
cs_field_gradient_tensor
void cs_field_gradient_tensor(const cs_field_t *f, bool use_previous_t, int inc, cs_real_63_t *restrict grad)
Compute cell gradient of tensor field.
Definition: cs_field_operator.c:791
cs_glob_space_disc
const cs_space_disc_t * cs_glob_space_disc
cs_space_disc_t::imrgra
int imrgra
Definition: cs_parameters.h:179
grad
void const cs_int_t *const const cs_int_t *const const cs_int_t *const const cs_int_t *const const cs_int_t *const const cs_int_t *const const cs_int_t *const const cs_int_t *const const cs_int_t *const const cs_real_t *const const cs_real_t *const const cs_real_t *const cs_real_3_t const cs_real_t const cs_real_t cs_real_t cs_real_t cs_real_3_t grad[]
Definition: cs_gradient.h:93
CS_REAL_TYPE
#define CS_REAL_TYPE
Definition: cs_defs.h:407
cs_field_t::name
const char * name
Definition: cs_field.h:126
CS_POST_TYPE_cs_real_t
Definition: cs_post.h:97
cs_real_t
double cs_real_t
Floating-point value.
Definition: cs_defs.h:302
CS_POST_WRITER_ALL_ASSOCIATED
#define CS_POST_WRITER_ALL_ASSOCIATED
Definition: cs_post.h:66
cs_field_by_name_try
cs_field_t * cs_field_by_name_try(const char *name)
Return a pointer to a field based on its name if present.
Definition: cs_field.c:2357
cs_gradient_scalar_synced_input
void cs_gradient_scalar_synced_input(const char *var_name, cs_gradient_type_t gradient_type, cs_halo_type_t halo_type, int inc, bool recompute_cocg, int n_r_sweeps, int tr_dim, int hyd_p_flag, int w_stride, int verbosity, int clip_mode, double epsilon, double extrap, double clip_coeff, cs_real_t f_ext[][3], const cs_real_t bc_coeff_a[], const cs_real_t bc_coeff_b[], const cs_real_t var[restrict], const cs_real_t c_weight[restrict], const cs_internal_coupling_t *cpl, cs_real_t grad[restrict][3])
Compute cell gradient of scalar field or component of vector or tensor field.
Definition: cs_gradient.c:7748
cs_field_gradient_scalar
void cs_field_gradient_scalar(const cs_field_t *f, bool use_previous_t, int inc, bool recompute_cocg, cs_real_3_t *restrict grad)
Compute cell gradient of scalar field or component of vector or tensor field.
Definition: cs_field_operator.c:529
CS_GRADIENT_ITER
Definition: cs_gradient.h:56
cs_glob_mesh
cs_mesh_t * cs_glob_mesh
cs_mesh_t::n_cells_with_ghosts
cs_lnum_t n_cells_with_ghosts
Definition: cs_mesh.h:127
cs_datatype_t
cs_datatype_t
Definition: cs_defs.h:260
cs_field_t::val
cs_real_t * val
Definition: cs_field.h:145
cs_gradient_vector_synced_input
void cs_gradient_vector_synced_input(const char *var_name, cs_gradient_type_t gradient_type, cs_halo_type_t halo_type, int inc, int n_r_sweeps, int verbosity, int clip_mode, double epsilon, double clip_coeff, const cs_real_t bc_coeff_a[][3], const cs_real_t bc_coeff_b[][3][3], const cs_real_t var[restrict][3], const cs_real_t c_weight[restrict], const cs_internal_coupling_t *cpl, cs_real_33_t *restrict grad)
Compute cell gradient of vector field.
Definition: cs_gradient.c:7856
cs_mesh_quantities_t::cell_cen
cs_real_t * cell_cen
Definition: cs_mesh_quantities.h:92
BFT_MALLOC
#define BFT_MALLOC(_ptr, _ni, _type)
Allocate memory for _ni elements of type _type.
Definition: bft_mem.h:62
BFT_FREE
#define BFT_FREE(_ptr)
Free allocated memory.
Definition: bft_mem.h:101
cs_real_6_t
cs_real_t cs_real_6_t[6]
vector of 6 floating-point values
Definition: cs_defs.h:317
cs_gradient_type_by_imrgra
void cs_gradient_type_by_imrgra(int imrgra, cs_gradient_type_t *gradient_type, cs_halo_type_t *halo_type)
Definition: cs_gradient.c:8000
ts
void cs_int_t cs_int_t cs_int_t cs_real_t * ts
Definition: cs_at_plugin.h:63
CS_HALO_STANDARD
Definition: cs_halo.h:52
cs_lnum_t
int cs_lnum_t
local mesh entity id
Definition: cs_defs.h:298
cs_real_33_t
cs_real_t cs_real_33_t[3][3]
3x3 matrix of floating-point values
Definition: cs_defs.h:321
cs_interpolate_from_location_p0
void cs_interpolate_from_location_p0(void *input, cs_datatype_t datatype, int val_dim, cs_lnum_t n_points, const cs_lnum_t point_location[], const cs_real_3_t point_coords[], const void *location_vals, void *point_vals)
Interpolate values defined on a mesh location at a given set of points using a P0 interpolation.
Definition: cs_interpolate.c:119
cs_halo_type_t
cs_halo_type_t
Definition: cs_halo.h:50
cs_field_t
Field descriptor.
Definition: cs_field.h:124
cs_real_63_t
cs_real_t cs_real_63_t[6][3]
Definition: cs_defs.h:327
cs_field_gradient_vector
void cs_field_gradient_vector(const cs_field_t *f, bool use_previous_t, int inc, cs_real_33_t *restrict grad)
Compute cell gradient of vector field.
Definition: cs_field_operator.c:713
cs_mesh_t
Definition: cs_mesh.h:63
cs_probe_set_get_name
const char * cs_probe_set_get_name(cs_probe_set_t *pset)
Retrieve the name related to a cs_probe_set_t structure.
Definition: cs_probe.c:538
cs_gradient_type_t
cs_gradient_type_t
Definition: cs_gradient.h:54