# NODAL_BOUNDARY_CONDITION

Specifies boundary conditions for a solution field on a set of nodes.

AcuSolve Command

## Syntax

NODAL_BOUNDARY_CONDITION("name") {parameters...}

User-given name.

## Parameters

variable or var (enumerated) [no default]
Boundary condition variable.
x_velocity or xvel
X-component of velocity.
y_velocity or yvel
U-component of velocity.
z_velocity or zvel
Z-component of velocity.
direction_velocity or dvel
A velocity component in an arbitrary direction. Requires direction_type.
pressure or pres
Pressure.
temperature or temp
Temperature.
relative_humidity or relHum
Relative humidity.
dewpoint_temperature or dewPoint
Dewpoint temperature.
species_1 or spec1
Species 1.
species_2 or spec2
Species 2.
species_3 or spec3
Species 3.
species_4 or spec4
Species 4.
species_5 or spec5
Species 5.
species_6 or spec6
Species 6.
species_7 or spec7
Species 7.
species_8 or spec8
Species 8.
species_9 or spec9
Species 9.
eddy_viscosity or eddy
Turbulence kinematic eddy viscosity.
kinetic_energy or tke
Turbulence kinetic energy.
eddy_frequency or tomega
Turbulence eddy frequency.
eddy_time or ttau
Turbulence eddy time.
dissipation_rate or teps
Turbulence dissipation rate.
intermittency or tintc
Transition intermittency.
transition_re_theta or treth
Transition Re-Theta
viscoelastic_xx_stress or xxvest
x-x component of the viscoelastic stress.
viscoelastic_yy_stress or yyvest
y-y component of the viscoelastic stress.
viscoelastic_zz_stress or zzvest
z-z component of the viscoelastic stress.
viscoelastic_xy_stress or xyvest
x-y component of the viscoelastic stress.
viscoelastic_yz_stress or yzvest
y-z component of the viscoelastic stress.
viscoelastic_zx_stress or zxvest
z-x component of the viscoelastic stress.
field
Volume fraction of field in multi field for levelset and algebraic Eulerian problems or mass fraction of field in multi field for the humid air model.
mesh_x_displacement or mesh_xdisp
X-component of mesh displacement.
mesh_y_displacement or mesh_ydisp
Y-component of mesh displacement.
mesh_z_displacement or mesh_zdisp
Z-component of mesh displacement.
mesh_direction_displacement or mesh_ddisp
A mesh displacement component in an arbitrary direction. Requires direction_type.
mesh_x_velocity or mesh_xvel
X-component of mesh velocity.
mesh_y_velocity or mesh_yvel
Y-component of mesh velocity.
mesh_z_velocity or mesh_zvel
Z-component of mesh velocity.
mesh_direction_velocity or mesh_dvel
A mesh velocity component in an arbitrary direction. Requires direction_type.
precedence (integer) [=1]
Precedence of this boundary condition set with respect to other sets. The set with the highest value has precedence.
type (enumerated) [=zero]
Type of the boundary condition.
zero
Zero for the set.
constant or const
Constant value. Requires constant_value.
nodal
Nodal values. Requires nodal_values.
nodal_time_series
Time series for each node. Requires nodal_values and times_series.
piecewise_linear or linear
Piecewise linear curve fit. Requires curve_fit_values and curve_fit_variable.
cubic_spline or spline
Cubic spline curve fit. Requires curve_fit_values and curve_fit_variable.
user_function or user scattered_data
Spatially interpolate from data. Requires scattered_data, scattered_data_origin and scattered_data_axes.
scattered_data_time_series
Spatially and temporally interpolate from data. Requires scattered_data, scattered_data_origin, scattered_data_axes, and times_series.
external_file
Read values dynamically from an external file. Requires external_file, external_file_evaluation and external_file_nodal_offset.
match_mesh_velocity
Set equal to the corresponding component of mesh velocity. Used with x_velocity, y_velocity, z_velocity and direction_velocity variables.
mesh_motion
Mesh displacement given by MESH_MOTION command. Requires mesh_motion. Used with mesh_x_displacement, mesh_y_displacement and mesh_z_displacement variables.
flexible_body
Mesh displacement or velocity given by FLEXIBLE_BODY command. Requires flexible_body and nodal_modes. Used with mesh displacement and velocity variables.
design_variables
User-given name of the design optimization variable.
guide_surface
Allows mesh to slip on a given surface. Requires guide_surface. Used with x_velocity, y_velocity, z_velocity, direction_velocity and mesh_direction_displacement variables.
external_code
Mesh displacement given by an external solid/structural code. Used with mesh_x_displacement, mesh_y_displacement, mesh_z_displacement and mesh_direction_displacement variables.
nodes (array) [no default]
List of nodal points in this set.
constant_value or value (real) [=0]
Constant value of the boundary condition. Used with constant type.
field (real) [no default]
Value of the boundary condition for field. Used with variable field.
nodal_values or values (array) [no default]
Array of nodes (first column) and data values. Used with nodal and nodal_time_series types.
curve_fit_values or curve_values (array) [={0,0}]
A two-column array of independent-variable/boundary-condition data values. Used with piecewise_linear and cubic_spline types.
curve_fit_variable or curve_var (enumerated) [=temperature]
Independent variable of the curve fit. Used with piecewise_linear and cubic_spline types.
x_coordinate or xcrd
X-component of coordinates.
y_coordinate or ycrd
Y-component of coordinates.
z_coordinate or zcrd
Z-component of coordinates.
x_reference_coordinate or xrefcrd
X-component of reference coordinates.
y_reference_coordinate or yrefcrd
Y-component of reference coordinates.
z_reference_coordinate or zrefcrd
Z-component of reference coordinates.
x_velocity or xvel
X-component of velocity.
y_velocity or yvel
U-component of velocity.
z_velocity or zvel
Z-component of velocity.
velocity_magnitude or vel_mag
Velocity magnitude.
pressure or pres
Pressure.
temperature or temp
Temperature.
relative_humidity
Relative humidity.
dewpoint_temperature
Dewpoint temperature.
eddy_viscosity or eddy
Turbulence kinematic eddy viscosity.
kinetic_energy or tke
Turbulence kinetic energy.
eddy_frequency
Turbulence eddy frequency.
species_1 or spec1
Species 1.
species_2 or spec2
Species 2.
species_3 or spec3
Species 3.
species_4 or spec4
Species 4.
species_5 or spec5
Species 5.
species_6 or spec6
Species 6.
species_7 or spec7
Species 7.
species_8 or spec8
Species 8.
species_9 or spec9
Species 9.
mesh_x_displacement or mesh_xdisp
X-component of mesh displacement.
mesh_y_displacement or mesh_ydisp
Y-component of mesh displacement.
mesh_z_displacement or mesh_zdisp
Z-component of mesh displacement.
mesh_displacement_magnitude or mesh_disp_mag
Mesh displacement magnitude.
mesh_x_velocity or mesh_xvel
X-component of mesh velocity.
mesh_y_velocity or mesh_yvel
Y-component of mesh velocity.
mesh_z_velocity or mesh_zvel
Z-component of mesh velocity.
mesh_velocity_magnitude or mesh_vel_mag
Mesh velocity magnitude.
user_function or user (string) [no default]
Name of the user-defined function. Used with user_function type.
user_values (array) [={}]
Array of values to be passed to the user-defined function. Used with user_function type.
user_strings (list) [={}]
Array of strings to be passed to the user-defined function. Used with user_function type.
user_nodal_values (array) [={}]
Array of data values (starting with second column) for each node (first column) to be passed to the user-defined function. Used with user_function type.
scattered_data (array) [no default]
Array of xyz coordinates (first three columns] and data values. Used with scattered_data and scattered_data_time_series types.
scattered_data_origin (array) [={0,0,0}]
Origin for transformation of scattered_data coordinates to global coordinates. Used with scattered_data and scattered_data_time_series types.
scattered_data_axes (array) [={1,0,0;0,1,0;0,0,1}]
Axes for transformation of scattered_data coordinates to global coordinates. Used with scattered_data and scattered_data_time_series types.
external_file (string) [no default]
User-given file name referencing the file containing boundary condition data. The file is in local binary format. Used with external_file type.
external_file_evaluation (enumerated) [=once_per_timestep]
Frequency of reading the external file. Used with external_file type.
once_per_timestep or step
Once per time step.
external_file_nodal_offset (array) [no default]
Two-column array giving the node and the byte offset of the datum of each node for reading the external file. Used with external_file type.
auxiliary_nodes (array) [no default]
Array of auxiliary nodes (starting with second column) for each node (first column) to be passed to the user defined function. Used with user_function type.
reference_frame (string) [=none]
User-given name of the reference frame for transforming a velocity boundary condition. If none, or if variable is not a velocity component, no transformation takes place.
multiplier_function (string) [=none]
User-given name of the multiplier function for scaling the boundary condition. If none, no scaling is performed.
mesh_motion (string) [=none]
User-given name of the MESH_MOTION command for specifying (mesh_motion type) or scaling (other types) a mesh displacement boundary condition. If none, or if variable is not a mesh displacement component, no scaling is performed. none is not supported with mesh_motion type.
flexible_body (string) [no default]
User-given name of the FLEXIBLE_BODY command for specifying a mesh displacement or velocity boundary condition. Used with flexible_body type.
guide_surface (string) [no default]
User-given name of the GUIDE_SURFACE command for specifying a velocity or mesh displacement boundary condition. Used with guide_surface type.
nodal_modes (array) [no default]
Array of node number (first column) and eigenvector values (last num_modes columns, where num_modes is given by the FLEXIBLE_BODY command referenced by flexible_body). Used with flexible_body type.
time_series (array) [={0}]
Array of time values. Used with nodal_time_series and scattered_data_time_series types.
time_series_variable (enumerated) [=time]
Independent variable for time series. Used with nodal_time_series and scattered_data_time_series types.
time
Time
cyclic_time
Time cycled over a period. Requires time_series_cyclic_period.
multiplier_function
User-given name of the multiplier function that replaces time. Requires time_series_variable_multiplier_function.
time_series_cyclic_period (real) >=0 [=1]
Value of the time period. Zero denotes an infinite period. Used with cyclic_time time series variable.
time_series_variable_multiplier_function (string) [=none]
User-given name of the multiplier function for the independent variable of the time series. If none, the independent variable is zero. Used with multiplier_function time series variable.
coupling_type (enumerated) [=structural]
Manner in which the nodes are coupled to an external code. Used with type=external_code.
structural
Nodes are coupled with either a line or surface element set in the external.
line
Nodes are coupled with a line element set in the external code.
surface
Nodes are coupled with a surface element set in the external code.
rigid_body
Nodes are coupled with a rigid body in the external code.
rigid_body_name (array) [no default]
Name of the rigid body the nodal boundary condition is coupled with. Used with mesh displacement and velocity variables, type=external_code and coupling_type=rigid_body.
external_code_tags (list) [={}]
Array of strings to be passed to the external code for identifying surface associations for the purpose of boundary condition assignment. Used with mesh displacement and velocity variables and when type=external_code. Used with coupling_type of structural, line, or surface. When this option is specified, the associativity of a given node in the AcuSolve model is restricted based on this mapping and not a simple projection of the external code coordinates onto the AcuSolve surfaces.
direction_type or dir_type (enumerated) [=constant]
Type of the direction vector. Used with direction_velocity variable.
constant or const
Constant direction. Requires constant_direction.
nodal
Nodal direction. Requires nodal_directions.
normal
Direction is normal to the boundary. Direction is computed automatically.
constant_direction (array) [={1,0,0}]
Constant direction vector specified in the global xyz coordinate system. Direction is normalized before use. Used with constant direction type.
nodal_directions (array) [no default]
Nodal direction vector. Directions are normalized before use. Used with nodal direction type.
active_type (enumerated) [=all]
Type of the active flag. Determines which nodes in this set will have this boundary condition imposed.
all
All nodes in this set are active.
none
No node in this set is active.
inflow or in
Only nodes where the flow is into the fluid domain are active.
user_function or user
Active nodes determined by a user-defined function. Requires active_user_function, active_user_values and active_user_strings.
no_outflow
Only nodes that where there is no outflow are active.
no_interface
Only nodes that are not on an interface surface or do not find a contact surface of an appropriate medium are active.
far_field
Only nodes that have a velocity boundary condition vector that is entering into the volume are active.
active_user_function (string) [no default]
Name of the user-defined function for the active flag. Used with user_function active type.
active_user_values (array) [={}]
Array of values to be passed to the active flag user-defined function. Used with user_function active type.
active_user_strings (list) [={}]
Array of strings to be passed to the active flag user-defined function. Used with user_function active type.
synthetic_turbulence (boolean) (=off)
Flag specifying whether to activate the synthetic turbulence feature at inflow, with velocity or atmospheric inflow type. This command is only activated when synthetic_turbulence_input_type in turbulence_model_parameters is set to k_omega (or k_epsilon).

## Description

This command specifies nodal boundary conditions for a solution variable on a set of nodes. For example,
NODAL_BOUNDARY_CONDITION( "constant BC on inflow x-velocity" ) {
variable        = x_velocity
type            = constant
nodes           = { 1 ;
3 ;
6 ; }
constant_value  = 12.5
}

defines nodal boundary conditions on the x-component of velocity for global nodes one, three and six. The boundary condition is a constant value of 12.5 for all three nodes.

The variable and nodes parameters are mandatory. variable specifies the solution field to which the boundary condition applies. If the problem does not solve for such a variable (see the STAGGER command), the boundary condition is ignored. nodes is a single-column array containing a list of node numbers. Node numbers must be valid numbers, as given by the COORDINATE command. Duplicate nodes are not allowed in a single set. This means that to specify two or more boundary conditions on the same variable (such as direction_velocity) and on the same node, multiple NODAL_BOUNDARY_CONDITION commands must be used.

The nodal numbers may be read from a file. For the above example the nodes may be placed in a file, such as inflow.nbc:
1
3
6
NODAL_BOUDARY_CONDITION( "constant BC on inflow x-velocity" ) {
variable        = x_velocity
type            = constant
nodes           = Read( "inflow.nbc" )
constant_value  = 12.5
}
The field variable may be specified through the NODAL_BOUNDARY_CONDITION command by assigning the associated FIELD as defined according to the material model selected.
NODAL_BOUNDARY_CONDITION( "Inflow field" ) {
variable       = "field"
field          = "Air"
type           = constant
precedence     = 2
constant_value = 1
active_type    = all
}
For the above example the field attribute has been previously defined with the FIELD specifier, as follows:
FIELD( "Air" ) {
material_model  = "Air"
}

If more than one nodal boundary condition is specified for a given variable on a given node, then the precedence parameter is used to determine which boundary condition to satisfy. The boundary condition set with the highest value of precedence takes precedence. If two or more boundary conditions have the same highest value, then the one with value of zero takes precedence. For the purpose of this evaluation, boundary conditions of types piecewise_linear, cubic_spline, user_function, and mesh_motion are assumed nonzero. Finally, if the zero condition is ambiguous, the last boundary condition set specified is used. For vector variables, such as velocity, the precedence is determined collectively on all components of the variable. For example, if the direction of a direction_velocity boundary condition coincides with the x-axis and there is also an x_velocity boundary condition on the same node, the above precedence rule is used to determine which boundary condition to satisfy.

A constant boundary condition type applies the same boundary condition on all nodes in the set, as in the above example.

A zero type is a short-hand form of the constant type, with a constant value of zero. For example,
NODAL_BOUNDARY_CONDITION( "zero BC on inflow y-velocity" ) {
variable  = y_velocity
type      = zero
nodes     = Read( "inflow.nbc" )
}
A nodal type specifies a different value for each node. For example,
NODAL_BOUNDARY_CONDITION( "nodal BC on inflow x-velocity" ) {
variable      = x_velocity
type          = nodal
nodes         = { 1 ;
3 ;
6 ; }
nodal_values  = { 1, 0 ;
3, 1 ;
6, 2 ; }
}

The nodal_values parameter is a two-column array corresponding to the node number and boundary condition value. The node numbers must match those given by the nodes parameter. No node may be missing.

The nodal values may be read from a file. For the above example, the boundary conditions may be placed in a file, such as inflow.bcu:
1      0
3      1
6      2
NODAL_BOUNDARY_CONDITION( "nodal BC on inflow x-velocity" ) {
variable     = x_velocity
type         = nodal
nodes        = Read( "inflow.nbc" )
nodal_values = Read( "inflow.bcu" )
}
The preceding can be generalized to a function of time at each node with the nodal_time_series type. The time points are given by time_series and must be in ascending order. If the number of points in time_series is N, then the number of columns in nodal_values must be N+1. Piecewise linear interpolation of the nodal_values data is used for times within the time series, and the limit point values are used for times outside the range of the time series. For example,
NODAL_BOUNDARY_CONDITION( "time-dependent nodal BC on inflow x-velocity" ) {
variable     = x_velocity
type         = nodal_time_series
nodes        = Read( "inflow.nbc" )
nodal_values = { 1, 0., 0.1, 0.2, 0.5 ;
3, 1., 1.2, 1.5, 1.8 ;
6, 2., 2.3, 2.6, 2.9 ; }
time_series  = { 0., 0.5, 1.0, 1.5 }
}
The data may be read from files. inflow.bcu becomes
1 0. 0.1 0.2 0.5
3 1. 1.2 1.5 1.8
6 2. 2.3 2.6 2.9
and the time series may placed in inflow.time:
0. 0.5 1.0 1.5
These files are then read by:
NODAL_BOUNDARY_CONDITION( "time-dependent nodal BC on inflow x-velocity" ) {
variable     = x_velocity
type         = nodal_time_series
nodes        = Read( "inflow.nbc" )
nodal_values = Read( "inflow.bcu" )
time_series  = Read( "inflow.time" )
}
If the boundary condition is periodic in time time_series_variable may be set to cyclic_time with the period given by time_series_cyclic_period. In this case time is replaced by mod(time, time_series_cyclic_period) before the temporal interpolation is done. Data in nodal_values outside of the first period in time are ignored. An infinite period is denoted by time_series_cyclic_period = 0, which is equivalent to time_series_variable = time. For example,
NODAL_BOUNDARY_CONDITION( "time-periodic nodal BC on inflow x-velocity" ) {
variable                  = x_velocity
type                      = nodal_time_series
nodes                     = Read( "inflow.nbc" )
nodal_values              = Read( "inflow.bcu" )
time_series               = Read( "inflow.time" )
time_series_variable      = cyclic_time
time_series_cyclic_period = 2
}
Time in the above temporal interpolation may also be replaced by a multiplier function:
NODAL_BOUNDARY_CONDITION( "time-periodic nodal BC on inflow x-velocity" ) {
variable                                  = x_velocity
type                                      = nodal_time_series
nodes                                     = Read( "inflow.nbc" )
nodal_values                              = Read( "inflow.bcu" )
time_series                               = Read( "inflow.time" )
time_series_variable                      = multiplier_function
time_series_variable_multiplier_function  = "ramped time"
}
MULTIPLIER_FUNCTION( "ramped time" ) {
type               = piecewise_linear
curve_fit_values   {  0, 0 ;
0.1, 0.01 ;
0.2, 0.04 ;
0.3, 0.09 ;
0.4, 0.16 ;
0.5, 0.25 ;
10.5, 10.25 ; }
curve_fit_variable = time
}

This multiplier function has the effect of "slowing down" time during the first 0.5 units of time. Such functions are often used to prevent poor physical or numerical behavior caused by the sudden imposition of a boundary condition. Note that the multiplier function specified by time_series_variable_multiplier_function is independent of the one specified by multiplier_function, which may be given as well.

Nodal boundary conditions of types piecewise_linear and cubic_spline may be used to define boundary condition values as a function of a single independent variable. For example,
NODAL_BOUNDARY_CONDITION( "curve fit BC on inflow x-velocity" ) {
variable            = x_velocity
type                = cubic_spline
nodes               = { 1 ; 3 ; 6 ; }
curve_fit_values    = { -1, 0.0 ;  0, 2.5 ;  1, 0.0 ; }
curve_fit_variable  = y_coordinate
}

defines an x-velocity boundary condition as a function of the y-coordinate. Note that in this example you get a parabolic velocity profile centered at y = 0, with a width of 2 and a center-line magnitude of 2.5. The curve_fit_values parameter is a two-column array corresponding to the independent variable and the boundary condition values. The independent variable values must be in ascending order. The limit point values of the curve fit are used when curve_fit_variable falls outside of the curve fit limits.

The curve_fit_values data may be read from a file. For the above example, the curve fit values may be placed in a file, such as inflow.bcu.fit:
-1 0.0
0 2.5
1 0.0
NODAL_BOUNDARY_CONDITION( "curve fit BC on inflow x-velocity" ) {
variable           = x_velocity
type               = cubic_spline
nodes              = { 1 ; 3 ; 6 ; }
curve_fit_values   = Read( "inflow.bcu.fit" )
curve_fit_variable = y_coordinate
}

A nodal boundary condition of user_function type may be used to model more complex behaviors; see the AcuSolve User-Defined Functions Guide for a detailed description of user-defined functions.

For example, consider the case where the x-velocity has a parabolic profile at the inflow of a circular pipe. Then the input command may be given by:
NODAL_BOUNDARY_CONDITION( "UDF BC on inflow x-velocity" ) {
variable       = x_velocity
type           = user_funtion
nodes          = Read( "inflow.nbc" )
user_function  = "usrNodalBcExample"
user_values    = { 0,  # y-center 0,  # z-center 1,  # radius 1 } # max velocity
}
where the user-defined function "usrNodalBcExample" may be implemented as follows.
#include "acusim.h"
#include "udf.h"
UDF_PROTOTYPE( usrNodalBcExample ) ; /* function prototype*/
Void usrNodalBcExample (
UdfHd           udfHd,                       /* Opaque handle for accessing data  */
Real*           outVec,                      /* Output vector                     */
Integer         nItems,                      /* Number of BC nodes                */
Integer         vecDim                       /* = 1                               */
) {
Integer         node ;                       /* a node counter                    */
Real            radius ;                     /* pipe radius                       */
Real            scale ;                      /* scaling factor                    */
Real            ve10 ;                       /* velocity at center line           */
Real            y ;                          /* y-location                        */
Real            yCenter ;                    /* y-coordinates of inflow center    */
Real            z ;                          /* z-location                        */
Real            zCenter ;                    /* y-coordinates of inflow center    */
Real            crd ;                        /* coordinates                       */
Real            usrVals ;                    /* user values                       */
Real            xCrd ;                       /* x-coordinates                     */
Real            yCrd ;                       /* y-coordinates                     */
Real            zCrd ;                       /* z-coordinates                     */
udfCheckNumUsrVals( udfHd, 4 ) ;                /* check for error                   */
usrVals         = udfGetUsrVals( udfHd ) ;   /* get the user vals                 */
yCenter         = usrVals[0] ;               /* get y-center                      */
zCenter         = usrVals[1] ;               /* get z-center                      */
radius          = usrVals[2] ;               /* get pipe radius                   */
vel0            = usrVals[3] ;               /* get max velocity                  */
scale           = 1 / ( radius * radius )    /* for convenience                   */
crd             = udfGetNbcCrd( udfHd ) ;    /* get the coord.                    */
xCrd            = &crd[0*nItems] ;           /* localize x-coord.                 */
yCrd            = &crd[1*nItems] ;           /* localize y-coord.                 */
zCrd            = &crd[2*nItems] ;           /* localize z-coord.                 */
for ( node = 0 ; node < nItems ; node++ ) {
y           = yCrd[node] - yCenter ;
z           = zCrd[node] - zCenter ;
outVec[node] = vel0 * ( 1 - scale * ( y*y + z*z ) ) ;
}
} /* end of usrNodalBcExample() */

The dimension of the returned boundary condition vector, outVec, is the number of nodes.

The auxiliary_nodes parameter provides a mechanism to access data from other nodes in a user-defined function. The format of the input array is two dimensional where the first column contains the boundary condition nodes and the second and successive columns contain the auxiliary nodes which must be valid node numbers. Then for each node the user-defined function can obtain data from any of its auxiliary nodes through the use of functions such as udfGetNbcAuxCrd and udfGetNbcAuxData. For example,
NODAL_BOUNDARY_CONDITION( "BC based on other nodes" ) {
...
type            = user_funtion
auxiliary_nodes = { 1, 101, 201, 301 ;... }
...
}

In the above example, the auxiliary nodes of node one are 101, 201 and 301.

The user_nodal_values parameter extends user_values to each node. The format of the input array is the same as for auxiliary_nodes except the auxiliary nodes are replaced with user values. For example,
NODAL_BOUNDARY_CONDITION( "BC with individual coefs" ) {
...
type               = user_funtion
user_values        = { 1.0, 2.0, 3.0 }
user_nodal_values  = { 1, 4.0, 5.0 ;... }
}

Using both auxiliary_nodes and user_nodal_values enables the computation of interpolated and projected data inside of user functions.

The scattered_data type allows direct use of experimental or other sources of data specified at coordinates that do not coincide with nodes. The data is specified in scattered_data where the first three columns give the xyz coordinates in an orthonormal xyz coordinate system defined by you, and the last column contains the boundary condition data. The origin of the user coordinate system in the global system is given by scattered_data_origin. The three rows in scattered_data_axes gives the direction of the x, y, and z axes in the global system. If the user coordinate system is the same as the global coordinate system then these last two parameters do not need to be specified. For example, experimental temperature data may be used for inflow boundary conditions as follows:
NODAL_BOUNDARY_CONDITION( "experimental data for inflow temperature" ) {
nodes                  = Read( "channel.inflow.nbc" )
variable               = temperature
type                   = scattered_data
scattered_data         = { 0.0, 0.0,
0.0, 100.0 ;
2.0, 0.0, 0.0, 102.0 ;
0.0, 1.0, 0.0, 105.0 ;
1.0, 1.5, 0.0, 107.0 ;
2.0, 1.0, 0.0, 110.0 ; }
scattered_data_origin  = { 0, -10, 0 }
scattered_data_axes    = { 0, 1, 0 ;
0, 0, 1 ;
1, 0, 0 ; }
}

This command defines a temperature boundary condition from a set of scattered data. Here, the data was measured in the xy-plane, while the inflow plane of the model is parallel to the yz-plane and shifted by -10 in the y axis.

The scattered_data data may be read from a file. For the above example, the experimental data may be placed in a file, such as measured.temp.dat:
0.0 0.0 0.0 100.0
2.0 0.0 0.0 102.0
0.0 1.0 0.0 105.0
1.0 1.5 0.0 107.0
2.0 1.0 0.0 110.0
NODAL_BOUNDARY_CONDITION( "experimental data for inflow temperature" ) {
nodes                 = Read( "channel.inflow.nbc" )
variable              = temperature
type                  = scattered_data
scattered_data        = Read( "measured.temp.dat" )
scattered_data_origin = { 0, -10, 0 }
scattered_data_axes   = { 0, 1, 0 ;
0, 0, 1 ;
1, 0, 0 ; }
}

In general, the user coordinates are first transformed to the global coordinate system. Then a plane is fitted to these points and all the points are projected to this plane. In the present example the data is already planar so there is no approximation. The points are triangulated and a 2D mesh is constructed. Each boundary condition node is then projected to this mesh and the data linearly interpolated to produce the boundary condition value. If the projection falls outside of the constructed mesh, the closest edge of the mesh is found and linear interpolation is performed along the edge. This algorithm works well for planar or nearly planar user data. If the data are far from planar, the results may be unpredictable. The algorithm also guarantees all boundary condition values are bounded by the user data. The disadvantage is that the interpolation is faceted and not smooth.

The scattered_data_time_series type is a generalization of the scattered_data type to include a piecewise linear function of time at each spatial data point. This generalization is completely analogous to the generalization from nodal to nodal_time_series type described above. The time points are given by time_series and must be in ascending order. If the number of points in time_series is N, then the number of columns in scattered_data must be N+3, where the first three columns give the xyz user coordinates, and the last N columns contain the time series data. Piecewise linear interpolation of the scattered_data data is used for times within the time series, and the limit point values are used for times outside the range of the time series. This time interpolation is done first for all the rows in scattered_data and then the spatial interpolation described in the previous paragraph is performed. For example,
NODAL_BOUNDARY_CONDITION( "time series experimental data for inflow temp" ) {
nodes                  = Read( "channel.inflow.nbc" )
variable               = temperature
type                   = scattered_data_time_series
scattered_data         = { 0.0, 0.0, 0.0, 100.0, 110.0, 120.0 ;
2.0, 0.0, 0.0, 102.0, 112.0, 122.0 ;
0.0, 1.0, 0.0, 105.0, 115.0, 125.0 ;
1.0, 1.5, 0.0, 107.0, 117.0, 127.0 ;
2.0, 1.0, 0.0, 110.0, 120.0, 130.0 ; }
time_series            = { 0.0, 0.5, 1.0 }
scattered_data_origin  = { 0, -10, 0 }
scattered_data_axes    = { 0, 1, 0 ;
0, 0, 1 ;
1, 0, 0 ; }
}

The parameters time_series_variable, time_series_cyclic_period, and time_series_variable_multiplier_function may be used with scattered_data_time_series type in exactly the same way as they are used with nodal_time_series type above.

The external_file type allows the boundary conditions to be modified each time step during the run. This is normally used in conjunction with another program that monitors the AcuSolve solution and creates new boundary conditions in response. For example,
NODAL_BOUNDARY_CONDITION( "inflow x-vel" ) {
variable                   = x_velocity
type                       = external_file
external_file              = "inflow.exf"
external_file_evaluation   = once_per_time_step
}

At the beginning of each time step, the boundary condition values for nodes in "inflow.nbc" and variable x_velocity are read from "inflow.exf". The file is deleted after it is read by all nodal boundary condition commands referencing this file. This deletion may be used as a signal that the next file may be written. The appearance of the file signals AcuSolve that the data is ready for reading. An error is issued and AcuSolve exits if the file does not appear within 600 seconds. In order to avoid reading incomplete data, it is recommended that a temporary file be used to hold the data which is then renamed appropriately after it is closed. The values are read as native 8-byte binary floating point numbers. The byte offset for each node (from the beginning of the file) is specified in the "inflow.loc" file. This is a 2-column file, where the first column contains the nodes given in nodes parameter ("inflow.nbc" in this case) and the second column specifies the byte offset, typically set to 0, 8, 16, 24, and so on.

By default, all boundary conditions are specified with respect to the fixed (or "laboratory") reference frame. If the REFERENCE_FRAME command is used to define the rotational body forces (this is recommended, as opposed to using the ROTATION_FORCE command), then the velocity boundary conditions on a rotating wall are non-trivial. However, the reference_frame parameter provides a convenient way of specifying these conditions. Instead of the fixed frame, velocity boundary conditions are applied in the given frame. In many cases, a zero type can then be used. See the REFERENCE_FRAME command for more details and an example. The reference_frame parameter has no effect on variables other than velocity components.

The multiplier_function parameter may be used to uniformly scale the nodal boundary condition values. The value of this parameter refers to the user-given name of a MULTIPLIER_FUNCTION command in the input file. For example, to linearly increase the inflow parabolic x-velocity from zero at time zero to the full amount at time one, the above boundary condition may be changed to:
NODAL_BOUNDARY_CONDITION( "UDF BC on inflow x-velocity" ) {
variable            = x_velocity
type                = user_function
nodes               = Read( "inflow.nbc"
user_function       = "usrNodalBcExample"
user_values         = { 0,   # y-center
0,   # z-center
1 }  # max velocity
multiplier_funtion  = "ramped"
}
MULTIPLIER_FUNCTION( "ramped" ) {
type               = piecewise_linear
curve-fit_values   = { 0, 0 ; 10, 1 }
curve_fit_variable = time
}
A nodal boundary condition of match_mesh_velocity type is used to ensure conservation of mass in moving mesh problems. On a solid wall conservation requires that the normal component of flow velocity equals the normal velocity of the wall itself (that is, the normal velocity of the mesh). If the mesh velocity is specified, then it is a trivial matter to use the same boundary condition for the flow velocity. However, if the mesh displacement is specified (this is usually the best strategy), the mesh velocity is determined internally (it is not the analytic time derivative of the displacement) and a match_mesh_velocity type is needed. This type will cause the given component of flow velocity to match the corresponding component of mesh velocity. You are responsible for ensuring the normal component of flow velocity has the appropriate boundary condition on it. For example, on a wall parallel to the x-z plane moving in the y direction, you may have:
NODAL_BOUNDARY_CONDITION( "accelerating wall" ) {
variable             = y_mesh_displacement
type                 = constant
constant_value       = 5.
nodes                = { 1 ; 3 ; 6 ; }
multiplier_function  = "accelerate"
}
MULTIPLIER_FUNCTION( "accelerate" ) {
type                 = cubic_spine
curve_fit_values     = { 0, .0 ;
1, .1 ;
2, .4 ;
3, .9 ; }
curve_fit_variable   = time
}
NODAL_BOUNDARY_CONDITION( "match y velocity" ) {
variable             = y_velocity
type                 = match_mesh_velocity
nodes                = { 1 ; 3 ; 6 ; }
}

Note that the match_mesh_velocity type may only be used with velocity-component variables and may not be combined with a multiplier function.

Mesh displacement boundary conditions may be scaled with mesh_motion. The value of this parameter refers to the user-given name of a MESH_MOTION command in the input file. This command is evaluated and the appropriate component of the resulting mesh displacement vector is used to scale the boundary condition. The mesh_motion type is shorthand for type = constant constant_value = 1, except that it is not compatible with mesh_motion = none. It is possible to specify both mesh_motion and multiplier_function; they are simply multiplied together and the result used to scale the boundary condition. For example,
NODAL_BOUNDARY_CONDITION( "buffer region for mesh displacement" ) {
variable            = mesh_x_displacement
type                = piecewise_linear
nodes               = Read( "buffer.nbc" ) # all nodes in -10 < x <10
curve_fit_values    = { -10, 0.0 ; -1, 1.0 ;  1, 1.0 ; 10, 0.0 }
curve_fit_variable  = x_reference_coordinate
mesh_motion         = "moving body"
}
MESH_MOTION( "moving body" ) {
type                = rigid_body
...
}

If the rigid body is originally within -1 < x < 1 then the mesh in this area follows the rigid body without distortion. The distortion takes place in the larger buffer area away from the body and smoothly ramps down to zero at x = ±10. Note that this strategy also allows the use of mesh=specified in the EQUATION command and thus avoids solving an ALE equation.

Fluid-structure interaction (FSI) problems use the flexible_body type in a manner similar to the rigid_body type. The flexible_body parameter references a FLEXIBLE_BODY command that is used to drive either a mesh displacement or velocity boundary condition here, depending on the modeling type specified by the equation parameter of FLEXIBLE_BODY. The eigenvectors required by a FSI calculation are given by nodal_modes here. See the FLEXIBLE_BODY command for a detailed description of FSI modeling and an example.

The guide_surface type is used along with a velocity variable or mesh_direction_displacement variable to allow mesh nodes to slip along a surface specified by the guide_surface parameter. For flat surfaces this can be accomplished by specifying a constant direction type. But for curved surfaces the appropriate direction may change every step as the fluid node moves along the surface. The guide_surface type overcomes this difficulty by continuously recomputing which guide surface facet each node is in (or closest to) and then using the normal to that facet. See the GUIDE_SURFACE command for more details. The boundary conditions on velocity are more subtle. Consider a case similar to the moving surface example given in SIMPLE_BOUNDARY_CONDITION, but with a no-slip wall. The NODAL_BOUNDARY_CONDITION command would be used as follows:
MESH_MOTION( "boat motion" ) {
type                        = rigid_body_dynamic
rigid_body_mass             = 100
...
rigid_body_surface_outputs  = { "ocean: boat hull" }
}
SURFACE_OUTPUT( "ocean: boat hull" ) {
surfaces                    = Read( "ocean.hull.ebc" )
shape                       = three_node_triangle
element_set                 = "ocean"
}
GUIDE_SURFACE( "moving boat surface" ) {
...
element_set                 = "boat"
...
mesh_motion                 = "boat motion"
}
NODAL_BOUNDARY_CONDITION( "slip condition for mesh" ) {
variable                    = mesh_direction_displacement
type                        = guide_surface
nodes                       = Read( "boat.wall.nbc" )
guide_surface               = "moving boat surface"
}
NODAL_BOUNDARY_CONDITION( "no-slip condition for x-velocity" ) {
variable                    = x_velocity
type                        = guide_surface
nodes                       = Read( "boat.wall.nbc" )
guide_surface               = "moving boat surface"
}
NODAL_BOUNDARY_CONDITION( "no-slip condition for y-velocity" ) {
variable                    = y_velocity
type                        = guide_surface
nodes                       = Read( "boat.wall.nbc" )
guide_surface               = "moving boat surface"
}
NODAL_BOUNDARY_CONDITION( "no-slip condition for z-velocity" ) {
variable                    = z_velocity
type                        = guide_surface
nodes                       = Read( "boat.wall.nbc" )
guide_surface               = "moving boat surface"
}
NODAL_BOUNDARY_CONDITION( "match normal velocity to mesh" ) {
variable                    = direction_velocity
type                        = match_mesh_velocity
nodes                       = Read( "boat.wall.nbc" )
}

Note that four boundary conditions are given for the velocity. The direction_velocity condition is necessary to conserve mass, but using a match_mesh_velocity type for the velocity vector would be wrong since the mesh slips and the velocity does not. This apparent over-specification is resolved internally by giving the direction_velocity condition a higher precedence. Effectively, the velocity produced by the x, y, and z conditions is projected to the nearest velocity that satisfies conservation of mass. A slip velocity condition is obtained by removing the three commands for the x, y, and z velocity components.

The external_code type is only used in Direct Coupling Fluid Structure Interaction (DC-FSI) problems. It is not necessary even then, since mesh displacement boundary conditions are set in the EXTERNAL_CODE_SURFACE command for nodes on the corresponding surface. However, it is sometimes desirable to have nodes not on such surfaces to also follow the solid deformation. For example, this may be accomplished by:
NODAL_BOUNDARY_CONDITION( "match normal mesh displacement to solid" ) {
variable            = mesh_direction_displacement
type                = external_code
nodes               = Read( "external.nbc" )
external_code_tags  = { "Surface 1"; }
coupling_type       = surface
}

Assuming the specified nodes are not on the external surface, this command constrains the nodes to remain a constant distance away from the deforming solid, but allows them to slide relative to the solid. In this case, the external_code_tags option was used to tell the external code to force these nodes to move with a surface tagged as "Surface 1". Note that this parameter is optional and is only necessary when the standard mapping procedure between fluid and solid codes produces an ambiguous surface association for the nodes of the fluid. If all three components of the mesh displacement are specified (in three commands) then the nodes will move with the solid. In both cases the point on the solid surface closest to the given node is used to determine the mesh motion and the normal direction.

The boundary condition variables direction_velocity, mesh_direction_displacement and mesh_direction_velocity require specification of a direction type, except when the type is match_mesh_velocity, guide_surface, or external_code. For example,
NODAL_BOUNDARY_CONDITION( "slip velocity -- constant direction" ) {
variable             = direction_velocity
type                 = zero
nodes                = Read( "wall.nbc" )
direction_type       = constant
constant_direction   = { 1, 1, 0 }
}

imposes a zero boundary condition on the (1,1,0) component of velocity of all nodes given in the "wall.nbc" file. The vector constant_direction specifies the direction in the global xyz coordinate system. The direction vector is normalized before use.

The direction type of constant_direction specifies the same direction vector for all nodes in the boundary condition set, as in the above example.

The direction type of nodal specifies a different direction for each node in the set. For example,
NODAL_BOUNDARY_CONDITION( "slip velocity -- nodal direction" ) {
variable         = direction_velocity
type             = zero
nodes            = { 1 ; 3 ; 6 ; }
direction_type   = nodal
nodal_directions = { 1, 1, 1, 1 ;
3, 1, 1, 0 ;
6, 1, 1,-1 ; }
}

The nodal_directions parameter is a four-column array corresponding to node numbers and the x, y, and z components of the direction vectors. The node numbers must match those given by the nodes parameter. No node may be missing. All direction vectors are normalized before use.

The nodal directions may be read from a file. For the above example, the directions may be placed in a file, such as slip.dir:
1    1    1   1
3    1    1   0
6    1    1  -1
NODAL_BOUNDARY_CONDITION( "slip velocity -- nodal direction" ) {
variable          = direction_velocity
type              = zero
nodes             = { 1 ; 3 ; 6 ; }
direction_type    = nodal
nodal_directions  = Read( "slip.dir" )
}
The direction type of normal specifies that the normal direction to the boundary of the mesh is to be used for the direction vector of the boundary condition. The normal direction is computed as the area-weighted average of the neighboring element surface outward normals. Note that the normal direction of each node must be unambiguous; however this algorithm does not guarantee such an outcome. For example,
NODAL_BOUNDARY_CONDITION( "slip velocity -- normal direction" ) {
variable       = direction_velocity
type           = zero
nodes          = { 1 ;
3 ;
6 ; }
direction_type = normal
}

computes the normal direction to nodes one, three, and six, and imposes a zero velocity in that normal direction.

In some circumstances it is necessary to "turn off" or "deactivate" a previously-defined nodal boundary condition. This is accomplished by setting the active flag through active_type. A value of all is the default and means that all nodes in the set are active (active flag = 1) and will have the boundary condition imposed on them. A value of none means that no node is active (active flag = 0). For example, assume that one run was made with the following commands to model a no-slip wall:
NODAL_BOUNDARY_CONDITION( "wall x-velocity" ) {
variable       = x_velocity
nodes          = Read( "wall.nbc" )
}
NODAL_BOUNDARY_CONDITION( "wall y-velocity" ) {
variable       = y_velocity
nodes          = Read( "wall.nbc" )
}
NODAL_BOUNDARY_CONDITION( "wall z-velocity" ) {
variable       = z_velocity
nodes          = Read( "wall.nbc" )
}
Then the entire input file to convert this wall to a slip wall on restart may be given by (assuming the normal to the wall is in the y direction):
RESTART {}
NODAL_BOUNDARY_CONDITION( "wall x-velocity" ) {
active_type       = none
}
NODAL_BOUNDARY_CONDITION( "wall z-velocity" ) {
active_type       = none
}
RUN {}

An inflow active type is typically used to stabilize outflow boundary conditions. For those nodes in the set where the normal velocity is out of the fluid domain (that is, the desired situation for outflow boundaries) then the boundary condition is turned off. However, for nodes with reverse flow (normal velocity into the fluid domain), the boundary condition is activated. This is particularly useful for scalar variables and both components of the tangential velocity, which would otherwise be undefined at reverse flow nodes and be potential sources of instability. A no_outflow active type is the same as inflow except nodes with zero normal velocity are also activated.

A user_function active type may be used to model more complex behaviors; see the AcuSolve User-Defined Functions Guide for a detailed description of user-defined functions. Values of the active flag between zero and one are allowed; such values are used to linearly interpolate between the previous value of the variable and its given boundary condition, with the result imposed as the actual boundary condition.

For example, consider the case where the velocity boundary conditions are to be turned on in a wave-like manner in order to (crudely) model a wall moving in the positive x direction through the mesh at speed c:(1)
where xw=x0-ct is the position of the wall at time t, x0 is the initial position and ε is a small positive parameter (the "mushy interval") used to smooth the transition between no boundary condition and an active one. The input command for the x-velocity may be given by:
NODAL_BOUNDARY_CONDITION( "UDF moving wall for x-velocity" ) {
variable              = x_velocity
type                  = constant
constant_value        = 5
nodes                 = Read( "moving_wall.nbc" )
active_type           = user_function
active_user_function  = "usrActiveFlagExample"
active_user_values    = { -100,   # initial wall location
5,   # wall speed
0.1 } # mushy interval
}
with similar commands for the y- and z-velocities. The user-defined function "usrActiveFlagExample" may be implemented as follows.
#include "acusim.h"
#include "udf.h"
UDF_PROTOTYPE( usrActiveFlagExample ) ;    /* function prototype               */
Void usrActiveFlagExample (
UdfHd        udfHd,                     /* Opaque handle for accessing data */
Real*        outVec,                    /* Output vector                    */
Integer      nItems,                    /* Number of BC nodes               */
Integer      vecDim                     /* = 1                              */
) {
Integer      node ;                     /* a node counter                   */
Real         x0 ;                       /* initial location of wall         */
Real         speed ;                    /* speed of wall                    */
Real         mushy ;                    /* mushy interval                   */
Real         xWall ;                    /* location of wall                 */
Real         time ;                     /* time                             */
Real         delta_x ;                  /* distance from wall               */
Real*        crd ;                      /* coordinates                      */
Real*        usrVals ;                  /* user values                      */
Real*        xCrd ;                     /* x-coordinates                    */
udfCheckNumUsrVals( udfHd, 3 ) ;           /* check for error                  */
time         = udfGetTime( udfHd ) ;    /* get the time                     */
usrVals      = udfGetUsrVals( udfHd ) ; /* get the user vals                */
x0           = usrVals[0] ;             /* get initial loc                  */
speed        = usrVals[1] ;             /* get speed                        */
mushy        = usrVals[2] ;             /* get mushy interval               */
crd          = udfGetNbcCrd( udfHd ) ;  /* get the coord.                   */
xCrd         = &crd[0*nItems] ;         /* localize x-coord.                */
xWall        = x0 + speed * time ;      /* location of wall                 */
for ( node = 0 ; node < nItems ; node++ ) {
delta_x = xCrd[node] - xWall ;
if ( delta_x >= mushy ) {
outVec[node] = 0 ;
} else if ( delta_x <= 0 ) {
outVec[node] = 1 ;
} else {
outVec[node] = 1. - delta_x / mushy ;
}
}
} /* end of usrActiveFlagExample() */

The dimension of the returned active flag vector, outVec, is the number of nodes.

A no_interface active type is used to automatically turn on and off boundary conditions in the presence of interfaces. The boundary condition is applied (active flag = 1) if the node is not part of any surface of an INTERFACE_SURFACE set or if it does not find a contact surface of the appropriate medium. That is, each node will fall into one of five possible cases:
• The node is not in any INTERFACE_SURFACE set; active flag = 1.
• The node is a part of an INTERFACE_SURFACE set, but it does not find a contact surface; active flag = 1.
• The node finds a contact surface of fluid medium; active flag = 0.
• The node finds a contact surface of solid/shell medium, and variable is defined on the solid/shell side (currently only temperature); active flag = 0.
• The node finds a contact surface of solid/shell medium, and variable is not defined on the solid/shell side (that is, it is not temperature; active flag = 1.

The pressure may be imposed either strongly via the NODAL_BOUNDARY_CONDITION command or weakly via the ELEMENT_BOUNDARY_CONDITION command. The latter command should be used in all cases, except when a boundary condition is imposed on the normal component of velocity on all boundary nodes (this includes defining boundary conditions on all three velocity components). In this case pressure is defined up to a constant, and it is advisable to specify pressure at one and only one nodal point to define that constant.

Below is an example to setup synthetic turbulence for a large eddy simulation inflow condition:
NODAL_BOUNDARY_CONDITION( "some x-velocity" ) {
Synthetic_turbulence 	= on
}

Note that synthetic_turbulence is normally set to on for all three velocity components and two turbulence profiles corresponding to the synthetic_turbulence_input_type defined in turbulence_model_parameters.