The preferred method for defining boundary conditions (besides using the GUI) is to assign zone-based definitions in the cs_user_boundary_conditions_setup function (cs_user_boundary_conditions.c).
As an alternative, the same definitions may be defined in cs_user_finalize_setup_wrapper (cs_user_parameters), which is called immediately after cs_user_boundary_conditions_setup. Choosing one or the other should be based on the best balance for reability and maintainability,
The following examples illustrate how different types of boundary conditions can be assigned to given variables at specified zones. In each case, an input array is provided. Values are copied internally, so the array does not need to continue existing after the boundary condition is defined.
Imposed values (Dirichlet conditions) can be defined using an array of the same dimension as the variable, as shown here for a velocity vector (1.5, 0, 0) at a zone named "inlet":
Simple Neuman conditions can be defined in a simular manner, replacing CS_PARAM_BC_DIRICHLET with CS_PARAM_BC_NEUMANN.
For exchange-condition-type boundary conditions, where a given exchange coefficient and exterior value are provided, a Robin boundary condition can be used. In this case, a boundary condition of the form: can be used by providing the values
, where
is the exchange coefficient mulitiplied by -1 (contribution from boundary to domain sign convention), and
is the external value.
In the following example, and exchange coefficient of value 10.5 and an external value of 0.1 is appplied to a scalar (named "scalar1") on a zone named "exchanger_wall":
The following examples illustrate how slightly more advanced boundary conditions can be assigned with user-defined callback functions. Here, we use "static" (i.e. local) functions that must be defined in the same file (i.e. cs_user_boundary_conditions.c) prior to being referenced in cs_user_boundary_conditions_define. It is of course possible to use functions with global linkage, which can be defined in any file, as log as the matching function prototypes are defined or included at the calling point.
Note the as many callback functions as required may be used, and can be named in any manner chosen by the user (though of course using a consistent naming scheme is recommended for readability and maintainability).
Analytic functions of type cs_analytic_func_t are one of several callback function types that may be used to define boundary conditions. For each zone, they are called for a set of quadrature points at which values are evaluated. For legacy schemes, the associated quadrature points are the face centers of the selected zone. For CDO-based solvers, the set of points depends on the quadrature type.
In this example, analytic functions are used to define the velocity and a scalar. Here, the following functions are first defined, for the velocity:
And for the scalar:
They are then associated to the matching zone in cs_user_boundary_conditions_define:
and
Degree-of-freedom-based callbacks of type cs_dof_func_t can be used to define boundary conditions at known locations, such as boundary faces for a given zone, independently of the quadrature actually used. For legacy schemes, boundary faces represent the natural boundary value locations, so using analytic or dof-base functions is equivalent (though point coordinates are not provided in dof-function arguments, so must be accessed through the mesh quantities if needed). For CDO schemes, values are automatically interpolated from the provided boundary face centers to the actual quadrature points.
In the following example, a function based on boundary face values of type cs_dof_func_t is used to define a Robin boundary condition based on an exchange coefficient and external value. As Robin conditions are expressed in the form: for each location pont, a tuple of values (alpha, u0, g) is provided with interleaved storage. This can be seen in the definition of the associated function:
As usual, the function is then used as a callback for for Robin condition:
To define even a constant boundary value using a scaling variable not yet known at setup time, an appropriate callback function must be used. This is the case, for division by a zone's surface, which is unknown when calling cs_user_boundary_conditions_setup (where the mesh has not yet been read or built).
As an example, to define a unit flux such that the total flux over a zone has value 1, we can simply divide it by a zone's measure, such as in the following function for a zone named "wall_top":
which we associate to the given zone and variable:
A similar definition is done for zone "wall_side", with a slightly improved function definition:
This function is similar to the one used for "wall_top", but assumes the associated input pointer is a pointer to the associated zone, which can thus be obtained directly using a pointer cast.
In this case, the matching zone pointer must be passed as the associated input when assigning the condition:
Note that a structure passed as a callback input must still point to valid data when the callback is executed. This is the case for zone pointers, even for time-varying zones (whose data may change, but base structure pointer is unvarying).