My Project
programmer's documentation
Loading...
Searching...
No Matches
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;
cs_real_3_t *grad;
BFT_MALLOC(grad, m->n_cells_with_ghosts, cs_real_3_t);
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;
}
BFT_FREE(grad);
}
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;
cs_real_33_t *grad;
BFT_MALLOC(grad, m->n_cells_with_ghosts, cs_real_33_t);
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;
}
}
BFT_FREE(grad);
}
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;
cs_real_63_t *grad;
BFT_MALLOC(grad, m->n_cells_with_ghosts, cs_real_63_t);
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;
}
}
BFT_FREE(grad);
}
break;
default:
assert(0);
}
}
#define BFT_MALLOC(_ptr, _ni, _type)
Allocate memory for _ni elements of type _type.
Definition bft_mem.h:62
#define BFT_FREE(_ptr)
Free allocated memory.
Definition bft_mem.h:101
cs_datatype_t
Definition cs_defs.h:260
double cs_real_t
Floating-point value.
Definition cs_defs.h:302
#define CS_REAL_TYPE
Definition cs_defs.h:407
cs_real_t cs_real_3_t[3]
vector of 3 floating-point values
Definition cs_defs.h:315
cs_real_t cs_real_6_t[6]
vector of 6 floating-point values
Definition cs_defs.h:317
cs_real_t cs_real_33_t[3][3]
3x3 matrix of floating-point values
Definition cs_defs.h:321
int cs_lnum_t
local mesh entity id
Definition cs_defs.h:298
cs_real_t cs_real_63_t[6][3]
Definition cs_defs.h:327
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
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
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
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
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
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
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
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_gradient_type_t
Definition cs_gradient.h:54
@ CS_GRADIENT_ITER
Definition cs_gradient.h:56
cs_halo_type_t
Definition cs_halo.h:50
@ CS_HALO_STANDARD
Definition cs_halo.h:52
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_mesh_t * cs_glob_mesh
cs_mesh_quantities_t * cs_glob_mesh_quantities
const cs_space_disc_t * cs_glob_space_disc
static int input(void)
Field descriptor.
Definition cs_field.h:124
cs_real_t * cell_cen
Definition cs_mesh_quantities.h:92
Definition cs_mesh.h:63
int imrgra
Definition cs_parameters.h:179

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);
}
}
}
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
#define CS_POST_WRITER_ALL_ASSOCIATED
Definition cs_post.h:63
@ CS_POST_TYPE_cs_real_t
Definition cs_post.h:93
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
const char * name
Definition cs_field.h:126
cs_real_t * val
Definition cs_field.h:145
int dim
Definition cs_field.h:131

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.