8.0
general documentation
Setting porosity values from a CAD file

Using an appropriate CAD representation, it may be possible to compute the porosity fields using "common" or "cut" boolean operations between cells in the porous zones and the CAD volume. If the CAD shape represents the actual fluid volume, the common volume between the shape and the porous mesh section's cells will be used. If the CAD shape represents the solid volume, it should be cut from the pourous mesh section's cells.

The following example uses functions from the OpenCascade Technology (OCCT) libraries (https://dev.opencascade.org/doc/overview/html/index.html), and assumes they are installed on the user's machine. As these libraries form the backbone of the SALOME platform's CAD features, they are present with any generic or common SALOME install, and are available as a package in many Linux distributions.

Libraries to compile and link.

As the OCCT libraries provide a C++ API, interfacing them with code_saturne requires a file written in C++, so the following example uses a separate C++ file, cs_cad_intersect.cxx to to most of the work. This file is also a user example, and may be improved or modified.

To compile and link, additional compiler flags must be passed to code_saturne. They may be defined in <_ref cs_user_scripts.py, and the following values are recommended (adapting the paths to the local environment):

occ_include_path = "/opt/occ/7.4.0/include/opencascade"
occ_lib_paths = ("/opt/occ/7.4.0/lib", "/opt/gl2ps/1.4.0.1/lib")
occ_libs "-lTKMesh -lTKernel -lTKG2d -lTKG3d -lTKMath -lTKIGES -lTKXSBase -lTKBin -lTKBool -lTKBO -lTKCDF -lTKBRep -lTKTopAlgo -lTKGeomAlgo -lTKGeomBase -lTKOffset -lTKPrim -lTKSTEP -lTKSTEPBase -lTKSTEPAttr -lTKHLR -lTKFeat"
domain.compile_cxxflags = "-std=c++11 -I" + occ_include_path;
domain.compile_libs = ""
for p in occ_lib_paths:
domain.compile_libs += "-L" + p + " -Wl,-rpath -Wl," + p + " "
domain.compile_libs += occ_libs

Function prototypes.

As the prototypes for the cs_cad_intersect.cxx are not part of the defaul code_saturne installation, do not forget to include the cs_cad_intersect.h header in the Local headers section of the cs_user_porosity.c file:

#include "cs_cad_intersect.h"

Zone selection

It is recommended to use the standard zone selection mechanism to select cells which may be intersected by the CAD shape, for example:

const cs_zone_t *z_poro = cs_volume_zone_by_name("Zone_1");
const cs_zone_t * cs_volume_zone_by_name(const char *name)
Return a pointer to a volume zone based on its name if present.
Definition: cs_volume_zone.c:680
Definition: cs_zone.h:55

Local variables and initialization

A few local variables may allow a more concise syntax, and optional face porosity arrays may be declared as temporary work arrays if face factors are required::

const cs_lnum_t n_i_faces = m->n_i_faces;
const cs_lnum_t n_b_faces = m->n_b_faces;
/* Temporary arrays for face porosity */
cs_real_t *cell_porosity = cs_field_by_name("porosity")->val;
cs_real_t *i_face_porosity, *b_face_porosity;
BFT_MALLOC(i_face_porosity, m->n_i_faces, cs_real_t);
BFT_MALLOC(b_face_porosity, m->n_b_faces, cs_real_t);
for (cs_lnum_t i = 0; i < m->n_i_faces; i++)
i_face_porosity[i] = 1;
for (cs_lnum_t i = 0; i < m->n_b_faces; i++)
b_face_porosity[i] = 1;
#define BFT_MALLOC(_ptr, _ni, _type)
Allocate memory for _ni elements of type _type.
Definition: bft_mem.h:62
double cs_real_t
Floating-point value.
Definition: cs_defs.h:319
int cs_lnum_t
local mesh entity id
Definition: cs_defs.h:313
cs_field_t * cs_field_by_name(const char *name)
Return a pointer to a field based on its name.
Definition: cs_field.c:2340
cs_mesh_t * cs_glob_mesh
cs_mesh_quantities_t * cs_glob_mesh_quantities
cs_real_t * val
Definition: cs_field.h:151
Definition: cs_mesh_quantities.h:92
Definition: cs_mesh.h:85
cs_lnum_t n_i_faces
Definition: cs_mesh.h:98
cs_lnum_t n_b_faces
Definition: cs_mesh.h:99

CAD intersection operation

The actual CAD intersection is done using the following call (adapting the file path to the actual file):

cs_cad_intersect(m,
"Compound_1.step",
CS_CAD_INTERSECT_CUT,
z_poro->n_elts,
z_poro->elt_ids,
cell_porosity,
NULL, /* modified cell centers */
i_face_porosity,
NULL, /* modified interior face centers */
b_face_porosity,
NULL); /* modified boundary face centers */
const cs_lnum_t * elt_ids
Definition: cs_zone.h:65
cs_lnum_t n_elts
Definition: cs_zone.h:64

Computing porous quantities

Though the cell porosity is directly set by the call above, face quantities may be computed from the face porosities. The following code also handles the cleanup op local arrays.

/* synchronize ghost cells */
if (m->halo != NULL)
cs_halo_sync_var(m->halo, CS_HALO_EXTENDED, cell_porosity);
/* Set interior and boundary face values */
if (mq->i_f_face_surf != mq->i_face_surf) {
const cs_real_3_t *restrict i_face_normal
cs_real_3_t *restrict i_f_face_normal
cs_real_t *i_f_face_surf = mq->i_f_face_surf;
for (cs_lnum_t f_id = 0; f_id < n_i_faces; f_id++) {
cs_real_t f_porosity = i_face_porosity[f_id];
for (cs_lnum_t i = 0; i < 3; i++)
i_f_face_normal[f_id][i] = f_porosity * i_face_normal[f_id][i];
i_f_face_surf[f_id] = cs_math_3_norm(i_f_face_normal[f_id]);
}
}
if (mq->b_f_face_surf != mq->b_face_surf) {
const cs_real_3_t *restrict b_face_normal
cs_real_3_t *restrict b_f_face_normal
cs_real_t *b_f_face_surf = mq->b_f_face_surf;
for (cs_lnum_t f_id = 0; f_id < n_b_faces; f_id++) {
cs_real_t f_porosity = b_face_porosity[f_id];
for (cs_lnum_t i = 0; i < 3; i++)
b_f_face_normal[f_id][i] = f_porosity * b_face_normal[f_id][i];
b_f_face_surf[f_id] = cs_math_3_norm(b_f_face_normal[f_id]);
}
}
BFT_FREE(i_face_porosity);
BFT_FREE(b_face_porosity);
/* Four set face factor */
if (mq->i_f_face_factor != NULL) {
const cs_lnum_2_t *i_face_cells
= (const cs_lnum_2_t *)m->i_face_cells;
const cs_real_t *i_face_surf = mq->i_face_surf;
const cs_real_t *i_f_face_surf = mq->i_f_face_surf;
for (cs_lnum_t f_id = 0; f_id < m->n_i_faces; f_id++) {
cs_lnum_t ii = i_face_cells[f_id][0];
cs_lnum_t jj = i_face_cells[f_id][1];
cs_real_t face_porosity
= CS_MAX(i_f_face_surf[f_id] / i_face_surf[f_id],
mq->i_f_face_factor[f_id][0] = cell_porosity[ii] / face_porosity;
mq->i_f_face_factor[f_id][1] = cell_porosity[jj] / face_porosity;
}
}
#define BFT_FREE(_ptr)
Free allocated memory.
Definition: bft_mem.h:101
#define restrict
Definition: cs_defs.h:139
cs_lnum_t cs_lnum_2_t[2]
vector of 2 local mesh-entity ids
Definition: cs_defs.h:325
#define CS_MAX(a, b)
Definition: cs_defs.h:473
cs_real_t cs_real_3_t[3]
vector of 3 floating-point values
Definition: cs_defs.h:332
void cs_halo_sync_var(const cs_halo_t *halo, cs_halo_type_t sync_mode, cs_real_t var[])
Definition: cs_halo.c:1957
@ CS_HALO_EXTENDED
Definition: cs_halo.h:59
static cs_real_t cs_math_3_norm(const cs_real_t v[3])
Compute the euclidean norm of a vector of dimension 3.
Definition: cs_math.h:424
const cs_real_t cs_math_epzero
cs_real_t * i_face_surf
Definition: cs_mesh_quantities.h:122
cs_real_2_t * i_f_face_factor
Definition: cs_mesh_quantities.h:129
cs_real_t * b_face_surf
Definition: cs_mesh_quantities.h:123
cs_real_t * i_f_face_surf
Definition: cs_mesh_quantities.h:125
cs_real_t * b_face_normal
Definition: cs_mesh_quantities.h:102
cs_real_t * i_f_face_normal
Definition: cs_mesh_quantities.h:104
cs_real_t * b_f_face_surf
Definition: cs_mesh_quantities.h:126
cs_real_t * b_f_face_normal
Definition: cs_mesh_quantities.h:106
cs_real_t * i_face_normal
Definition: cs_mesh_quantities.h:100
cs_halo_t * halo
Definition: cs_mesh.h:156
cs_lnum_2_t * i_face_cells
Definition: cs_mesh.h:111