Getting Started
The governing equations for many unsteady systems may be described by the first-order implicit differential equation
\[ 0 = \bm{f}(\bm{\dot{x}}, \bm{x}, \bm{y}, \bm{p}, t)\]
where $\bm{f}$ is a vector-valued residual function, $\dot{()}$ denotes the time derivative, $\bm{x}$ is a vector of state variables, $\bm{y}$ is a vector of time-varying inputs, $\bm{p}$ is a vector of time-invariant parameters, and $t$ is the current time. If we concatenate the governing equations associated with any number of unsteady models described by this equation together, we obtain the concatenated model
\[\bm{0} = \bm{\mathcal{F}}(\bm{\dot{X}}, \bm{X}, \bm{Y}, \bm{P}, t)\]
where
\[\bm{\mathcal{F}} = \begin{bmatrix} \bm{f_1} \\ \bm{f_2} \\ \vdots \\ \bm{f_n} \end{bmatrix} \quad \bm{X} = \begin{bmatrix} \bm{x_1} \\ \bm{x_2} \\ \vdots \\ \bm{x_n} \end{bmatrix} \quad \bm{Y} = \begin{bmatrix} \bm{y_1} \\ \bm{y_2} \\ \vdots \\ \bm{y_n} \end{bmatrix} \quad \bm{P} = \begin{bmatrix} \bm{p_1} \\ \bm{p_2} \\ \vdots \\ \bm{p_n} \end{bmatrix}\]
The concatenated model is a decoupled model, since the states, inputs, and parameters of each submodel are not influenced in any way by the states, inputs, and parameters of the other submodels. To couple these models, we introduce the following coupling function, which defines the inputs of the concatenated model as functions of its rates, states, and parameters, as well as the current time.
\[\bm{y} = \bm{\mathcal{G}}(\bm{\dot{X}}, \bm{X}, \bm{P}, t)\]
Defining this coupling function allows us to define the governing equations for a general monolithic coupled model.
\[\bm{\tilde{\mathcal{F}}}(\bm{\dot{X}}, \bm{X}, \bm{P}, t) = \bm{\mathcal{F}}(\bm{\dot{X}}, \bm{X}, \bm{\mathcal{G}}(\bm{\dot{X}}, \bm{X}, \bm{P}, t), \bm{P}, t) = \bm{0}\]
Implementation
Our coupling methodology is implemented by the following CoupledModel
constructor.
Aeroelasticity.CoupledModel
— MethodCoupledModel(submodels, parameters, nstate=number_of_states.(submodels); kwargs...)
Define a coupled model from a collection of submodels. Each submodel is defined as an in-place implicit differential equation (i.e. submodels[i](residᵢ, dxᵢ, xᵢ, yᵢ, pᵢ, t)
).
General Keyword Arguments
finput = default_coupling(submodels...)
: Coupling function for the combined system. Has the function signature:y₁, y₂, ... yₙ = finput(dxᵢ, xᵢ, pᵢ, t)
. Default coupling functions are defined for various combinations of built-in models.fparam = default_parameter_function(finput)
: Parameter function for the coupled system. Has the function signature:p₁, p₂, ... pₙ, pₐ = fparam(p, t)
Keyword Arguments for Automatically Determining Jacobian Sparsity
neval=3
: Total number of evaluation points (for computing jacobian properties)dx0=[rand(sum(nstate) for ieval = 1:neval]
: Evaluation point ratesx0=[rand(sum(nstate) for ieval = 1:neval]
: Evaluation point statesp0=fill(default_parameters(finput), neval)
: Evaluation point parameterst0=[rand() for ieval=1:neval]
: Evaluation point timessymbolic=true
: Symbolically find jacobian sparsity?autodiff=true
: Use automatic differentiation to evaluate jacobians?fdtype=Val(:forward)
: Finite differencing type to use ifautodiff=false
ztol=nothing
: Tolerance for determining jacobian sparsity (the default includes structural zeros)atol=0.0
: Absolute tolerance for determining rate jacobian properties (seeisapprox
)rtol=0.0
: Relative tolerance for determining rate jacobian properties (seeisapprox
)
Keyword Arguments for Providing Jacobian Sparsity (and other properties)
rate_jacobian_sparsity=nothing
: Coupled system rate jacobian sparsitystate_jacobian_sparsity=nothing
: Coupled system state jacobian sparsityrate_jacobian_colorvec=nothing
: Coupled system rate jacobian color vectorstate_jacobian_colorvec=nothing
: Coupled system state jacobian color vectoridentity_mass_matrix=nothing
: Indicates whether the mass matrix is the identity matrixconstant_mass_matrix=nothing
: Indicates whether the mass matrix does not change. Note that whenneval=1
this property defaults tofalse
unlessidentity_mass_matrix==true
mass_matrix=spzeros(sum(nstate),sum(nstate))
: Storage for the mass matrix. Note that this matrix is only used ifconstant_mass_matrix=true
In addition to constructing a coupled model, this constructor automatically detects the sparsity of the resulting rate and state jacobian matrices. This information is then used when evaluating the following jacobian evaluation functions.
Aeroelasticity.rate_jacobian!
— Functionrate_jacobian!(jacob, coupled_model, dx, x, p, t; kwargs...)
Compute the jacobian of the residual with respect to the state rates.
Aeroelasticity.state_jacobian!
— Functionstate_jacobian!(jacob, coupled_model, dx, x, p, t; kwargs...)
Compute the jacobian of the residual with respect to the state rates.
The residual may be evaluated using the following function
Aeroelasticity.residual!
— Functionresidual!(resid, coupled_model, dx, x, p, t)
Compute the residual for a coupled model.
Alternatively, the residual may be evaluated by calling the coupled model as a function.
(coupled_model::CoupledModel)(resid, dx, x, p, t)
Analyses
Once a coupled model has been constructed, the system may be linearized using the linearize
function.
Aeroelasticity.linearize
— Functionlinearize(model, x, p; autodiff=true, fdtype=Val(:forward))
linearize(model, dx, x, p, t; autodiff=true, fdtype=Val(:forward))
Calculate the jacobian of the residual function for coupled model model
with respect to the state variables and their rates.
Eigenvalues and eigenvectors may then be computed using the dense_eigen
or sparse_eigen
functions.
Aeroelasticity.dense_eigen
— Functiondense_eigen(K, M; kwargs...)
Return the eigenvalues, left eigenvector matrix, and right eigenvector matrix corresponding to the model.
Aeroelasticity.sparse_eigen
— Functionsparse_eigen(K, M; nev=min(20, size(K,1)))
Return the eigenvalues, left eigenvector matrix, and right eigenvector matrix corresponding to the model. nev
is the number of eigenvalues to compute
Correlating eigenmodes with modes from previous iterations may be done using the correlate_eigenmodes
function
Aeroelasticity.correlate_eigenmodes
— Functioncorrelate_eigenmodes(U, M, V; tracked_modes=1:size(U,1), rtol=1e-3, atol=1e-3)
Correlate modes from a current iteration with those from a previous iteration. Returns a permutation that may be used to reorder the new modes and the associated corruption indices.
DifferentialEquations
may be used to find a steady state or time marching solution. To facilitate these analyses, this package provides the following specialized constructors for ODEFunction
and DAEFunction
.
SciMLBase.ODEFunction
— MethodODEFunction(model::Aeroelasticity.CoupledModel, p0)
Construct an ODEFunction
for a coupled model. Note that by using this function you assume that the governing equations may be expressed in the form M(x, p, t)*dx = f(x, p, t)
SciMLBase.DAEFunction
— MethodDAEFunction(model::Aeroelasticity.CoupledModel)
Construct an DAEFunction
for a coupled model.
Aeroelasticity
The primary intended purpose of the coupling methodology presented in this package is to faciltate constructing aeroelastic systems. To this end, a number of aerodynamic and structural models have been implemented in this package which may be used to construct various aeroelastic models. Each model is defined as a callable struct, with a calling signature that matches the format expected by the CoupledModel
constructor. For more details about the theoretical background behind each model, we refer readers to the relevant pages of the documentation. For more details about how to use these models to construct aeroelastic systems, see the examples.