## Constraints: Curvilinear coordinates |

Curvilinear constraints allow a wide class of generalised constraint problems to be modelled in OrcaFlex, such as restricting the motion of the out-frame to lie on an arbitrary curve or surface, mixed calculated and imposed motion, and dynamic release of the out-frame based upon user-specified criteria.

Note: | It is necessary to have both Python and the Python SymPy module installed in order to use curvilinear constraints. See Python Interface: Installation for more information on installing Python, and on the embedded Python distribution that can be automatically installed as part of the OrcaFlex installation process. |

The utility of curvilinear constraints comes from the ability to define a bespoke set of coordinates in which to model the motion of the out-frame relative to the in-frame. The number of user-specified coordinates corresponds to the number of degrees of freedom in which motion of the out-frame is possible: one user-specified coordinate corresponds to motion along a curve, two to motion on a surface, etc. We will illustrate this shortly with an example, but for now let us recall the six basic degrees of freedom of the constraint: $x$, $y$, $z$, $Rx$, $Ry$ and $Rz$. These are defined in the same way as for a simple Cartesian constraint: $x$, $y$ and $z$ are the translational coordinates of the out-frame origin relative and with respect to the axes of the in-frame; $Rx$, $Ry$ and $Rz$ are the components of a rotation vector, again expressed relative and with respect to the axes of the in-frame. The magnitude of this rotation vector is the angle of rotation necessary to rotate the in-frame to the out-frame; its direction gives the axis of rotation.

As an example, consider constraining the motion of the out-frame to lie on the straight line $X{=}Z$, where $X$ and $Z$ are the usual coordinates with repect to *global axes*. This is straightforward to achieve via a Cartesian constraint: simply place the constraint at the global origin, set the declination of the in-frame to $45$° and the $z$ DOF to be free. Using a curvilinear constraint, we could instead define a single free coordinate, $q$ say, and then define the mappings $x=q$ and $z=q$, which are parametric equations of a straight line. How such mappings are set up will be described below, but for now the aim is to present the general concept. Similarly, the constraint $z=5x$ can be implemented by specifying $x=q$, $z=5q$. In fact, we can do better than this, and simply define $x$ itself as a free coordinate, so that we merely need to specify $z=5x$. It may seem trivial, but try doing this with a Cartesian constraint!

Figure: | $\boldsymbol{z=5x}$ |

So far, $q$ (or $x$), is our only free coordinate, so the motion of the out-frame relative to the in-frame will be one-dimensional. A straight line is a relatively uninteresting constraint though, so let us consider the curve $z=x^2$: a *parabola*. To implement this, we define $x$ as our free coordinate and then specify $z=x^2$.

Figure: | $\boldsymbol{z=x^2}$ |

A two-dimensional surface can be defined in an analogous fashion: consider two coordinates $r$ and $\phi$, together with the mappings $x=r \cos \phi$, $y=r \sin \phi$ and $z=r^2$. These mappings define a *parabolic well* in polar coordinates, with $r$ the horizontal distance between the the out-frame and the in-frame (i.e. in the $x$-$y$ plane) and $\phi$ the azimuth angle measured from the $x$-axis.

Figure: | $\boldsymbol{x=r \cos \phi, \quad y=r \sin \phi, \quad z=r^2}$ |

Mappings, and free coordinates, are defined on the **coordinates** page of the constraint data form.

Free coordinates are defined, one per row, in this table. The following data are associated with each free coordinate:

**Name**is used to refer to the coordinate in mappings or when viewing results. It may be a new coordinate, or one of the basic DOFs, $x$, $y$, $z$, $Rx$, $Ry$ and $Rz$. Some reserved names may not be used, such as $t$ which is reserved for simulation time.**Initial value**is the value of the coordinate when the model is in reset state. It is used to determine the position of the out-frame at the start of the first iteration of the static analysis. Often, this can be left at the default of zero, but there are situations where static convergence can only be achieved if the initial value is specified appropriately. The use calculated positions menu item can be used to capture this value after a successful statics analysis. If the constraint has a double-sided connection, then the out-frame's reset position is instead determined by its initial position and orientation data. In this case, the initial value is only used to influence convergence.**Characteristic value**and**characteristic load**are used analogously to a model object's characteristic scales, as a measure of convergence during a solve. A value of ~ instructs OrcaFlex to determine, if possible, the characteristic value/load associated with that coordinate from the properties of any other objects that are coupled to the constraint during the analysis.

In the same way as for Cartesian constraints, the out-frame can be released from the in-frame at the start of any stage of the simulation, such that all of its six DOFs become free.

The mapping between the free coordinates and the six basic DOFs ($x$, $y$, $z$, $Rx$, $Ry$ and $Rz$) is defined via a series of Python commands entered as free-form text. It is essential that all six basic DOFs are defined on the coordinates page, either as free coordinates or as a mapping. For instance, the default mapping is

x = 0

y = 0

z = 0

Rx = 0

Ry = 0

Rz = 0

which means that no DOFs are free: the in-frame and the out-frame are rigidly connected and, since all the values are zero, coincident. The earlier example of $z=5x$ can be implemented in one of two ways: you can either define a free coordinate $q$ and the mapping

x = q

y = 0

z = 5*q

Rx = 0

Ry = 0

Rz = 0

or define $x$ itself to be a free coordinate and define the mapping

y = 0

z = 5*x

Rx = 0

Ry = 0

Rz = 0

Similarly, the following mapping defines the earlier parabolic well example with $r$ and $\phi$ (phi) as free coordinates:

x = r*cos(phi)

y = r*sin(phi)

z = r**2

Rx = 0

Ry = 0

Rz = 0

In all cases, all six DOFs are defined, with the definitions being shared between the **free coordinates** and **mappings**.

As you edit the mappings, OrcaFlex will try to evaluate them dynamically. Text in the bottom-left corner of the coordinates page indicates whether or not the current mapping text is valid and, if it is not, will provide details of any problems.

The preceding example has one free translational DOF and is fixed in rotation. To have the same translational mapping but with free rotational motion in all directions, define $Rx$, $Ry$ and $Rz$ as additional free coordinates, and specify the remaining DOF, $y$, as a mapping along with $z$:

Figure: | Free DOFs $\boldsymbol{x}$, $\boldsymbol{Rx}$, $\boldsymbol{Ry}$ and $\boldsymbol{Rz}$ |

Many common mathematical functions are available to mappings, including $\sin$, $\cos$, $\tan$ and $\exp$. It is important to note that these functions are defined within SymPy and act *symbolically*, rather than numerically. Some common constants, such as pi, are also pre-defined. A (non-comprehensive) list of functions available via SymPy is available on the SymPy help pages.

OrcaFlex also has certain reserved symbols available for use in mappings. These are

- t, the current simulation time.
- t0, the simulation time at the start of the simulation.
- rampStartTime, the simulation time at which the ramp becomes non-zero.
- rampFinishTime, the simulation time at which the ramp becomes equal to one.
- ramp, the current value of the ramping factor.
- rampDot, the first time derivative of the ramping factor.
- rampDotDot, the second time derivative of the ramping factor.
- intRamp, the time integral of the ramping factor.

Further examples of mappings, illustrating the use of mathematical functions and time-varying quantities, can be found on the curvilinear constraints examples page.

As well as the ability to release the out-frame from the in-frame based on the simulation stage, you can also arrange that the out-frame is released if a user-defined condition is satisfied. Once again, this condition is specified using a free-form Python script, which this time sets a Python boolean variable named releaseCondition. For example,

releaseCondition = x > 10

will release the out-frame if and when the $x$ coordinate becomes greater than 10. Unlike mappings, the release condition is evaluated numerically, *not* symbolically, so it is necessary to import modules such as NumPy to gain access to common mathematical operators. Several pre-defined variables can be accessed in the release condition script:

- q, the current value of the q coordinate (either a user-defined coordinate or of one of the six basic DOFs).
- qDot, the current value of the rate of change of the q coordinate (the q velocity). This variable is not available when using the indirect solution method.
- qDotDot, the current value of the rate of change of the q velocity (the q acceleration). This variable is not available when using the indirect solution method.
- qHatT, a unit-vector (tuple), expressed with respect to the axes of the in-frame, representing the direction in which the out-frame will translate if the q coordinate is
*increased*by an infinitesimal amount. If a change in q does not translate the out-frame, then this vector is zero. - qHatR, a unit-vector (tuple), expressed with respect to the axes of the in-frame, representing the direction about which the out-frame will rotate if the q coordinate is
*increased*infinitesimally. If a change in q does not produce a rotation of the out-frame, then this vector is zero. - F, the
*connection force*, a vector (tuple) expressed with respect to the axes of the in-frame. This is the force that the in-frame must provide to the out-frame in order to maintain the constraint - M, the
*connection moment*, a vector (tuple) expressed with respect to the axes of the in-frame. The moment that the in-frame must provide to the out-frame in order to maintain the constraint.

t, t0 and ramp, as available to mappings, are also available to the release condition. As an example, consider the case in which the out-frame is rigidly attached to the in-frame via the default mapping, and define the following release condition:

from numpy.linalg import norm

releaseCondition = norm(F) > 1000

This release condition means that the out-frame will be released once the magnitude of the connection force becomes greater than $1000$ force units (the units used in the Python script must be consistent with those prevailing in the OrcaFlex model). This may be useful for modelling the failure of a rigid connection when some maximum tension (or compression) has been exceeded.

Further examples of release conditions are given on the curvilinear constraints examples page.