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.CoupledModelMethod
CoupledModel(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 rates
  • x0=[rand(sum(nstate) for ieval = 1:neval]: Evaluation point states
  • p0=fill(default_parameters(finput), neval): Evaluation point parameters
  • t0=[rand() for ieval=1:neval]: Evaluation point times
  • symbolic=true: Symbolically find jacobian sparsity?
  • autodiff=true: Use automatic differentiation to evaluate jacobians?
  • fdtype=Val(:forward): Finite differencing type to use if autodiff=false
  • ztol=nothing: Tolerance for determining jacobian sparsity (the default includes structural zeros)
  • atol=0.0: Absolute tolerance for determining rate jacobian properties (see isapprox)
  • rtol=0.0: Relative tolerance for determining rate jacobian properties (see isapprox)

Keyword Arguments for Providing Jacobian Sparsity (and other properties)

  • rate_jacobian_sparsity=nothing: Coupled system rate jacobian sparsity
  • state_jacobian_sparsity=nothing: Coupled system state jacobian sparsity
  • rate_jacobian_colorvec=nothing: Coupled system rate jacobian color vector
  • state_jacobian_colorvec=nothing: Coupled system state jacobian color vector
  • identity_mass_matrix=nothing: Indicates whether the mass matrix is the identity matrix
  • constant_mass_matrix=nothing: Indicates whether the mass matrix does not change. Note that when neval=1 this property defaults to false unless identity_mass_matrix==true
  • mass_matrix=spzeros(sum(nstate),sum(nstate)): Storage for the mass matrix. Note that this matrix is only used if constant_mass_matrix=true
source

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!Function
rate_jacobian!(jacob, coupled_model, dx, x, p, t; kwargs...)

Compute the jacobian of the residual with respect to the state rates.

source

The residual may be evaluated using the following function

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.linearizeFunction
linearize(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.

source

Eigenvalues and eigenvectors may then be computed using the dense_eigen or sparse_eigen functions.

Aeroelasticity.dense_eigenFunction
dense_eigen(K, M; kwargs...)

Return the eigenvalues, left eigenvector matrix, and right eigenvector matrix corresponding to the model.

source
Aeroelasticity.sparse_eigenFunction
sparse_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

source

Correlating eigenmodes with modes from previous iterations may be done using the correlate_eigenmodes function

Aeroelasticity.correlate_eigenmodesFunction
correlate_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.

source

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.ODEFunctionMethod
ODEFunction(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)

source

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.