programmer's documentation
Turbomachinery module usage

Introduction

Two classical models are available in Code_Saturne for rotor/stator interactions modelling in turbomachinery computations: the steady approach which is based on the so-called Frozen Rotor modelling and the transient rotor/stator approach which is based on a sliding mesh technique.

Warning
This page describes these functionalities based on a single Code_Saturne computation. An alternative rotor/stator coupling based on the code/code coupling of Code_Saturne with itself is still possible (and briefly described in this page) but it is not recommended (will be highly modified soon).

Mesh requirements

Periodicity

The rotational periodicity treatment is possible only in Frozen Rotor. However, the interface plane between rotor and stator must match in the azimutal $\theta$ direction: $\theta_{\text{min}}^{\text{rotor}}(z)=\theta_{\text{min}}^{\text{stator}}(z),\quad\theta_{\text{max}}^{\text{rotor}}(z)=\theta_{\text{max}}^{\text{stator}}(z)$ for all z through the rotation axis direction.

Rotor/stator interface

Data setting

The data setting is made through the GUI or through the cs_user_turbomachinery.c source file. In that case, the type of turbomachinery model is first set in cs_user_turbomachinery subroutine:

as in the following example:

/* Set turbomachinery model type:
CS_TURBOMACHINERY_NONE, No turbomachinery modeling
CS_TURBOMACHINERY_FROZEN, Frozen rotor model
CS_TURBOMACHINERY_TRANSIENT Full transient simulation
*/

Then, the rotor region and the rotor/stator interface boundaries must be specified in the cs_user_turbomachinery_rotor subroutine. The rotor region is first specified, like in this example:

{
/* Define cells belonging to rotor and associated axis */
double rotation_velocity = 2.;
double rotation_axis[3] = {0., 0., 1.};
double rotation_invariant[3] = {0., 0., 0.};
const char cell_criteria[] = "cylinder[0.0, 0.0, 0.0,"
" 0.0, 0.0, 1.0,"
" 2.0]";
rotation_velocity,
rotation_axis,
rotation_invariant);
}

In this example, rotation_velocity refers to the rotation angular velocity of the rotor, in rad/s. The rotation axis might be normilized (elsewhere it is normalized afterward by the code). Note that from the code point of view, adding a rotor results in the addition of an internal cs_rotation_t structure in the global corresponding list (see Basic operations section in the following).

Then the rotor/stator interface boundary is specified. This step is mandatory only for the CS_TURBOMACHINERY_TRANSIENT model. For the CS_TURBOMACHINERY_FROZEN model, this step is required only if the interface is made of boundary faces (see Rotor/stator interface subsection above).

{
/* Define joining associated with rotor/stator interface */
const char faces_criteria[] = "rotor_interface or stator_interface";
int verbosity = 0; /* per-task dump if > 1, debug level if >= 3 */
int visualization = 0; /* debug level if >= 3 */
float fraction = 0.10, plane = 25.;
int join_num = cs_turbomachinery_join_add(faces_criteria,
fraction,
plane,
verbosity,
visualization);
/* Note that advanced parameters may be defined
using cs_join_set_advanced_param(),
just as for regular joinings or periodicities. */
}

User recomandations

Meshing recomandations at interface

As mentioned above, when a rotor/stator inteface boundary exists (in particular for the CS_TURBOMACHINERY_TRANSIENT model), it is then joined by the solver during the computation. It is thus important to be aware that the success of a joining operation is strongly dependant on the quality of the mesh at the interface. More precisely, the refinement must be as similar as possible on both sides of the interface. Moreover, it is reminded that the tolerance parameter of a joining is a fraction of the shortest edge linked with a vertex to join. Consequently, cells where the refinement in the azimutal $\theta$ direction is much coarser than those in one of the two others can also lead to a joining failure. In particular, the user should be wary of boundary layers.

Remarks
  • The tolerance parameter of a joining should always be lower than 0.5.
  • If the meshes at both sides of the interface are very different such that the joining fails, advanced joining parameters are available. However, modifying the mesh is more likely to succeed. The introduction of some kind of buffer cells layer on both sides of the interface is strongly recommended. Ideally, each of the two layers should have the same refinement and a constant azimutal step (this latter recommandation is relevant only for CS_TURBOMACHINERY_TRANSIENT model).

Alternative rotor/stator coupling

If the meshes on both sides of the interface are very different and can not be modified, the user should turn to a rotor/stator coupling based on the code/code coupling of Code_Saturne with itself. This simply requires replacing the definition of a face joining for an interface (using the GUI or a call to cs_turbomachinery_join_add by a call to cs_turbomachinery_coupling_add, as in the following example:

If a coupling is defined and the rotation is not null in at least one of the cases, icorio determines the type of rotor/stator coupling: icorio = 1 for a Frozen Rotor computation and icorio = 0 for a sliding mesh approach.

Warning
Contrary to the mesh joining approach, the code/code coupling approach is not fully conservative.

User operations

Basic operations

A specific rotor is identified by an integer value. The "default rotor" is actually the stator that is the fixed part of the domain, with identifier 0. Then the identifiers of the rotors are incremented as the user add rotors (cs_turbomachinery_add_rotor, see above).

Once the rotor identifier is known, one can acces to its parameters:

/* Access to a specific rotation zone (the first one) */
cs_lnum_t rotor_id = 1;
const cs_rotation_t *ref_rot = cs_glob_rotation + rotor_id;
/* Rotation zone parameters */
double omega = ref_rot->omega; /* angular velocity [rad/s] */
cs_real_3_t axis = {ref_rot->axis[0], /* rotation axis (normalized vector) */
ref_rot->axis[1], ref_rot->axis[2]};

Importantly, one access to the rotor associated to each cell of the domain thanks to a rotor identifier list, like in this example:

const cs_lnum_t *rotor_num = NULL;
for (cs_lnum_t cell_id = 0; cell_id < n_cells; cell_id++) {
cs_rotation_t *rot = cs_glob_rotation + rotor_num[cell_id];
/* ... */

Turbomachinery dedicated postprocessing functions

Useful postprocessing functions relative to the machinery characteristics are available: postprocessing of the couple on the rotor walls (cs_post_moment_of_force) and postprocessing of the head generated by the machinery (cs_post_turbomachinery_head). In the latter one, the mesh locations (CS_MESH_LOCATION_CELLS, CS_MESH_LOCATION_BOUNDARY_FACES or CS_MESH_LOCATION_INTERNAL_FACES) associated with the given selection criteria must be specified.

/* Postprocessing of the couple: axial moment resulting from the stresses */
/* on the rotor blades */
cs_lnum_t n_elts;
cs_lnum_t *elt_list;
BFT_MALLOC(elt_list, n_b_faces, cs_lnum_t);
cs_selector_get_b_face_list("rotor_blades", &n_elts, elt_list);
cs_real_t c = cs_post_moment_of_force(n_elts, elt_list, axis);
BFT_FREE(elt_list);
/* Postprocessing of the head: total pressure increase through the machinery */
cs_real_t turbomachinery_head
("inlet", /* selection criteria at suction */
CS_MESH_LOCATION_BOUNDARY_FACES, /* associated mesh location */
"z > 2.725 and z < 2.775", /* selection criteria at discharge */
CS_MESH_LOCATION_CELLS); /* associated mesh location */

Fortran naming

Useful fortran variables and/or functions specific to turbomachinery computations are contained int the fortran module turbomachinery and rotation.