7.2
general documentation
Volume and boundary zone definitions (cs_user_zones.c)

Volume and boundary zones may be defined using the GUI, or through the cs_user_zones (in cs_user_zones.c).

Simple volume zone example

Most zones may be defined in a simple manner using the general selection criteria, such as in the following example:

{
cs_volume_zone_define("head_loss_1",
"box[4.0, 6.0, -1e6, 2.0, 8.0, 1e6]",
}

Or you can define 3 spherical source term zones based on geometrical criteria described by a rule.

{
char name[128], criteria[128];
for (int i = 0; i < 3; i++) {
double s_coords[] = {0, 0, 2.0*i};
snprintf(name, 127, "source_%d", i);
snprintf(criteria, 127, "sphere[%f, %f, %f, 0.5]",
s_coords[0], s_coords[1], s_coords[2]);
}
}

Advanced volume zone examples

More complex selections can be done by defining an appropriate selection function. For example, to select cells adjacent to boundary faces belonging to a group named "G3", the following selection function must first be defined:

static void
_g3_boundary_cells(void *input,
const cs_mesh_t *m,
int location_id,
cs_lnum_t *n_elts,
cs_lnum_t **elt_ids)
{
CS_UNUSED(input);
CS_UNUSED(location_id);
/* Allocate selection list */
cs_lnum_t n_b_faces = 0;
cs_lnum_t *b_face_ids = NULL;
BFT_MALLOC(b_face_ids, m->n_b_faces, cs_lnum_t);
cs_selector_get_b_face_list("G3", &n_b_faces, b_face_ids);
char *cell_flag;
BFT_MALLOC(cell_flag, m->n_cells, char);
for (cs_lnum_t i = 0; i < m->n_cells; i++)
cell_flag[i] = 0;
/* Now that flag is built, test for adjacency */
for (cs_lnum_t i= 0; i < n_b_faces; i++) {
cs_lnum_t face_id = b_face_ids[i];
cs_lnum_t c_id = m->b_face_cells[face_id];
cell_flag[c_id] = 1;
}
/* Now build list from flag */
cs_lnum_t _n_elts = 0;
for (cs_lnum_t i = 0; i < m->n_cells; i++) {
if (cell_flag[i] != 0)
_n_elts++;
}
cs_lnum_t *_elt_ids;
BFT_MALLOC(_elt_ids, _n_elts, cs_lnum_t);
_n_elts = 0;
for (cs_lnum_t i = 0; i < m->n_cells; i++) {
if (cell_flag[i] != 0) {
_elt_ids[_n_elts] = i;
_n_elts++;
}
}
/* Free memory */
BFT_FREE(b_face_ids);
BFT_FREE(cell_flag);
/* Set return values */
*n_elts = _n_elts;
*elt_ids = _elt_ids;
}

It can then simply be used in a zone definition:

{
char name[128], criteria[128];
for (int i = 0; i < 3; i++) {
double s_coords[] = {0, 0, 2.0*i};
snprintf(name, 127, "source_%d", i);
snprintf(criteria, 127, "sphere[%f, %f, %f, 0.5]",
s_coords[0], s_coords[1], s_coords[2]);
cs_volume_zone_define_by_func("G3_B", _g3_boundary_cells, NULL, 0);
}
}
Remarks
If defined as "static", as in this example, an with no function prototype, the selection function must be defined in the same file (i.e. cs_user_zones.c), and appear before the definition of cs_user_zones. If a appropriate selection function is available in another source file, it must have non-static linkage an a function prototype must be provided (usually through an associated .h file).

Advanced boundary zone examples

You can define simple boundary zones, allowing all faces not in the "INLET" or "OUTLET" groups to be considered as walls

{
int z_id = cs_boundary_zone_define("wall", "all[]", 0);
cs_boundary_zone_define("inlet", "INLET", 0);
cs_boundary_zone_define("outlet", "OUTLET", 0);
}

Or simply allow overlapping for an existing zone:

{
int z_id = cs_boundary_zone_by_name("wall")->id;
}