4.2.5. Linearization
OpenFAST can linearise the full multi-physics system about a periodic (or static) operating point to produce continuous-time, first-order state-space matrices of the form
together with the coupling matrices dUdu (input-to-input feed-through) and
dUdy (output-to-input coupling). The linearization engine lives in
modules/openfast-library/src/FAST_ModGlue.f90.
4.2.5.1. User inputs for linearization
The following parameters appear in the main OpenFAST input file (*.fst)
under the Linearization section.
Parameter |
Type |
Description |
|---|---|---|
|
logical |
Master switch. Set to |
|
logical |
When |
|
integer |
Controller degree of freedom trimmed during
|
|
real |
RMS convergence tolerance on normalised output error across one
rotor revolution. Trimming stops when the error falls below this
value. Typical value: |
|
real |
Proportional gain used by the built-in trim controller. Units are rad/(rad/s) for yaw/pitch cases and N·m/(rad/s) for the torque case. |
|
real |
Artificial tower damping coefficient (N/(m/s)) added during the
|
|
real |
Artificial blade damping coefficient (N/(m/s)) during |
|
integer |
Number of linearization time points per rotor revolution (or number of
equally spaced absolute time instants when |
|
real array |
Absolute simulation times (seconds) at which to linearise when
|
|
integer |
Controls which input variables appear in the B and D matrices.
|
|
integer |
Controls which output variables appear in the C and D matrices.
|
|
logical |
When |
|
logical |
When |
4.2.5.2. Module support for linearization
Modules that appear in the linearization variable ordering (set in
ModGlue_Init) are:
InflowWind → SeaState → ServoDyn → ElastoDyn → BeamDyn → AeroDyn → HydroDyn → SubDyn → MAP++ → MoorDyn
A module that is not in this ordered list causes a fatal error if
Linearize=True.
4.2.5.3. Variable selection
During ModGlue_Init, the VF_Linearize flag is applied to variables
according to the LinInputs and LinOutputs settings:
States (x): the
VF_Linearizeflag is always set on all continuous state variables of every participating module.Inputs (u):
LIN_NONE→ flag cleared on all input variables.LIN_STANDARD→ keeps whateverVF_Linearizeflag was set in the module’sInitVars; module developers choose the standard input set.LIN_ALL→ flag set on all input variables.Variables with
VF_NoLinalways haveVF_Linearizecleared, regardless of the above setting.
Outputs (y):
LIN_NONE→ flag cleared on all output variables.LIN_STANDARD→ flag set only on outputs that also carryVF_WriteOut.LIN_ALL→ flag set on all output variables.Variables with
VF_NoLinare always excluded.
The combined variable set is assembled into a ModGlueType named Lin
via ModGlue_CombineModules.
4.2.5.4. Steady-state trimming (CalcSteady)
When CalcSteady=True, ModGlue_CalcSteady is called at each time step
to detect periodicity:
The module outputs tagged
VF_Linearize(excludingVF_WriteOut) are collected into a buffer indexed by azimuth angle.After each complete revolution the outputs at each of the
NLinTimesazimuth targets are compared against the previous revolution via the normalised RMS error:\[\varepsilon = \sqrt{\frac{1}{N} \sum_{i=1}^{N} \left(\frac{y_i^{\rm current} - y_i^{\rm previous}}{r_i}\right)^2}\]where \(r_i = \max(y_{i,\rm max} - y_{i,\rm min},\, 0.01)\) is the output range from the current revolution (with a floor to avoid division by near-zero).
When \(\varepsilon < \texttt{TrimTol}\),
FoundSteady=Trueand linearization at allNLinTimesazimuths proceeds automatically.If the simulation reaches within approximately two revolutions of
TMaxwithout converging, a warning is issued and linearization is forced.
The azimuth interpolation between buffer samples uses the extrapolation
routines from MV_ExtrapInterp (supports constant, linear, and quadratic
schemes depending on the number of available samples).
4.2.5.5. linearization at an operating point
ModGlue_Linearize_OP assembles the full-system matrices at a single
operating point (time / azimuth):
Module Jacobians: for each module,
FAST_JacobianPInputandFAST_JacobianPContStateare called to compute the per-module sub-matrices dYdu, dXdu, dYdx, dXdx by central-difference finite differentiation. The perturbation magnitudes are taken from each variable’sPerturbfield (see Module Variables (ModVar)).Operating point extraction:
FAST_GetOPpacks the current states, inputs, and outputs into the linearization arrays (ModGlue%Lin%x,%u,%y).Coupling matrices: the input-output coupling matrices dUdu and dUdy are assembled from the mesh-mapping Jacobians to account for the fact that some module inputs are functions of other modules’ outputs.
Full-system assembly: the per-module sub-matrices are placed into the combined glue-level matrices using the
iGluindex ranges stored in eachModVarType.Output:
ModGlue_CalcWriteLinearMatriceswrites the.linfile containing:Operating point values (x_op, u_op, y_op)
linearization channel names (from
LinNames)Derivative order indicators (
VF_DerivOrder1,VF_DerivOrder2)Rotating-frame flags (
VF_RotFrame)Full-system matrices A, B, C, D, dUdu, dUdy
Per-module matrices (if
LinOutMod=True)Full Jacobians (if
LinOutJac=True)
4.2.5.6. Output file format
Each linearization call produces a file named
<RootName>.<N>.lin where N is the linearization index (1 … NLinTimes).
The file is a plain-text ASCII file that can be read by the
openfast_io Python library or the
pyFAST post-processing tools.
Key fields in the file header:
Rotor_Speed– rotor speed at linearization time (RPM)Azimuth– blade-1 azimuth at linearization time (deg)
4.2.5.7. Variable naming conventions
In linearization output files each channel label follows the pattern:
<ModAbbr> <MeshName> <Field> [, component [, node [, unit]]]
Examples:
ED BlPitch1, rad– ElastoDyn individual blade-1 pitch stateAD B1N001Fx force, node 1, N– AeroDyn blade 1 node 1 X-force inputBD_1 B1TipTDxr translation displacement, node 10, m– BeamDyn instance 1
Module developers should ensure that the Name argument to MV_AddVar /
MV_AddMeshVar and the entries in LinNames follow this convention for
consistency with post-processing tools.
4.2.5.8. Module developer responsibilities
To participate in linearization a module must:
Call
MV_AddVar/MV_AddMeshVarwith appropriateVF_Linearizeflags and supplyLinNamesfor all variables that may appear in the standard linearization set.Implement
<Mod>_JacobianPInputand<Mod>_JacobianPContStatesubroutines (or supply analytical Jacobians through the registry). The glue code calls these via theFAST_JacobianPInput/FAST_JacobianPContStatewrappers inFAST_Funcs.f90.Implement
<Mod>_GetOP(via the registry) to extract the operating-point values of states, inputs, and outputs.Mark variables that should not participate in linearization with
VF_NoLin.Mark variables in the rotating reference frame with
VF_RotFrameso that multi-blade coordinate (MBC) transformations applied by post-processing tools are aware of these variables.