Forces
Different forces (or forcings, linear operators in general) are included in Limace.jl. For the high-level interface, they are implemented as abstract types Limace.Forcing{1} or Limace.Forcing{2}, for on one or two bases dependencies respectively.
Currently, the implemented forces are:
Some details for each of these forces is given in the following.
Inertial
\[\int \mathbf{u}_i^* \cdot \mathbf{u}_j\,\mathrm{d}V,\]
The linear operator is simply the inner product of the basis elements. For the momentum equation, this is essentially the projection of the inertial term $\partial_t \mathbf{u} \rightarrow \lambda \mathbf{u}$, hence the name.
Limace.Inertial — Type
mutable struct Inertial{TB, T} <: Limace.Forcing{1}basis::Basis{TB}: The basis for the inertial operator.factor::T: A scalar factor that multiplies the inertial operator, defaulting to1.0.mat::SparseMatrixCSC{ComplexF64}: A sparse matrix representation of the inertial operator.preassembled::Bool: A flag indicating whether the inertial operator has been preassembled.
Example usage
u = Inviscid(10)
f = Limace.Inertial(u)
Limace.assemble!(f)
r.mat # sparse matrix representation of the inertial operatorLimace.inertial — Function
inertial(
b::Basis;
threads,
external
) -> LinearAlgebra.SymTridiagonal
Compute the Galerkin projection matrix of basis b onto itself, i.e. the inner products. Also known as the mass matrix.
Advection
\[\int \mathbf{u}_i^* \cdot \left(\left(\boldsymbol{\nabla}\times\mathbf{u}_j\right)\times\mathbf{U}_0 + \left(\boldsymbol{\nabla}\times\mathbf{U}_0\right)\times\mathbf{u}_j \right)\,\mathrm{d}V\]
This equivalent to the projection of the operator $\left(\mathbf{u}\cdot\boldsymbol{\nabla}\right)\mathbf{U}_0+\left(\mathbf{U}_0\cdot\boldsymbol{\nabla}\right)\mathbf{u}$, when $\boldsymbol{\nabla}\cdot\mathbf{u} = \boldsymbol{\nabla}\cdot\mathbf{U}_0 = 0$.
Limace.Advection — Type
mutable struct Advection{TU, T} <: Limace.Forcing{1}basis::Basis{TU}: The basis for the advection operator.U0: The background flow, which can be a singleBasisElementor a collection of them.factor::T: A scalar factor that multiplies the advection operator, defaulting to1.0.mat::SparseMatrixCSC{ComplexF64}: A sparse matrix representation of the advection operator.preassembled::Bool: A flag indicating whether the advection operator has been preassembled.
Example usage
u = Inviscid(10)
U0 = BasisElement(u, Toroidal, (1,0,0))
a = Limace.Advection(u, U0)
Limace.assemble!(a)
a.mat # sparse matrix representation of the advection operatorLimace.advection — Function
advection(
u::Basis,
U0::BasisElement{T0<:Basis, TH<:Helmholtz, T};
threads
) -> Any
Computes the advection term for a poloidal/toroidal background flow U0, a velocity basis u. Equivalent to -lorentz(u,u,U0).
Buoyancy
\[\int \mathbf{u}_i^* \cdot \left(T_j\mathbf{r} \right)\,\mathrm{d}V\]
Limace.Buoyancy — Type
mutable struct Buoyancy{TU, TT, T} <: Limace.Forcing{2}ubasis::Basis{TU}: The velocity basis for the buoyancy operator.tbasis: The temperature basis for the buoyancy operator.factor::T: : A scalar factor that multiplies the operator, defaulting to1.0.mat::SparseMatrixCSC{ComplexF64}: A sparse matrix representation of the operator.preassembled::Bool: A flag indicating whether the operator has been preassembled.
Example usage
u = Inviscid(10)
T = Temperature(10)
f = Limace.Buoyancy(u,T)
Limace.assemble!(f)
f.mat = # sparse matrix representation of the buoyancy operatorLimace.buoyancy — Function
buoyancy(
ub::Basis,
tb::Basis;
kwargs...
) -> Union{SparseArrays.SparseMatrixCSC{Missing, Int64}, SparseArrays.SparseMatrixCSC{Tv, Int64} where Tv<:(Complex)}
Computes the advection term for a spherically symmetric gravity acceleration (eq. (115) in Ivers & Phillips (2008)) for a velocity basis ub and Temperature basis tb.
Coriolis
\[\int \mathbf{u}_i^* \cdot 2\mathbf{e}_z\times\mathbf{u}_j\,\mathrm{d}V,\]
Limace.Coriolis — Type
mutable struct Coriolis{TB, T} <: Limace.Forcing{1}basis::Basisfactor::Anymat::SparseArrays.SparseMatrixCSC{ComplexF64}preassembled::Bool
This defines the Coriolis force operator for a given basis. The factor is a scalar that multiplies the operator, e.g. the rotation rate $\Omega$ or a nondimensional parameter (e.g. $1/\mathrm{Le}$). The mat is a sparse matrix representation of the operator, and preassembled indicates whether the matrix has been preassembled.
Example usage
u = Inviscid(10)
Ω = 1.0
c = Limace.Coriolis(u, Ω)
Limace.assemble!(c)
c.mat # sparse matrix representation of the Coriolis operatorLimace.coriolis — Function
coriolis(
b::Basis;
threads,
Ω
) -> SparseArrays.SparseMatrixCSC{Tv, Int64} where Tv
Compute the sparse Galerkin projection matrix, by projecting the basis b onto the Coriolis operator.
Diffusion
\[\int \mathbf{u}_i^* \cdot \boldsymbol{\nabla}^2\mathbf{u}_j\,\mathrm{d}V\]
Limace.Diffusion — Type
mutable struct Diffusion{TB, T} <: Limace.Forcing{1}basis::Basis{TB}: The basis for the diffusion operator.factor::T: : A scalar factor that multiplies the diffusion operator, defaulting to1.0.mat::SparseMatrixCSC{ComplexF64}: A sparse matrix representation of the diffusion operator.preassembled::Bool: A flag indicating whether the diffusion operator has been preassembled.
Limace.diffusion — Function
diffusion(
b::Basis;
threads,
external
) -> SparseArrays.SparseMatrixCSC{Float64, Int64}
Compute the Galerkin projection matrix of the basis b onto the vector Laplacian. When keyword external=true, the integral is computed over all space, assuming continuity of the poloidal field and a scalar potential in the exterior domain.
Induction
\[\int \mathbf{b}_i^* \cdot \boldsymbol{\nabla}\times\left(\mathbf{u}_j\times\mathbf{B}_0\right)\,\mathrm{d}V\]
Limace.InductionB0 — Type
mutable struct InductionB0{TB, TU, T} <: Limace.Forcing{2}bbasis::Basis{TB}: The magnetic field basis for the induction operator.ubasis::Basis{TB}: The velocity basis for the induction operator.B0: The background magnetic field, which can be a singleBasisElementor a collection of them.factor::T: : A scalar factor that multiplies the induction operator, defaulting to1.0.mat::SparseMatrixCSC{ComplexF64}: A sparse matrix representation of the induction operator.preassembled::Bool: A flag indicating whether the induction operator has been preassembled.
u = Inviscid(10)
b = Insulating(10)
B0 = BasisElement(b, Poloidal, (2,0,1))
f = Limace.InductionB0(b, u, B0)
Limace.assemble!(f)
f.mat # sparse matrix representation of the induction operator\[\int \mathbf{b}_i^* \cdot \boldsymbol{\nabla}\times\left(\mathbf{U}_0\times\mathbf{b}_j\right)\,\mathrm{d}V\]
Limace.InductionU0 — Type
mutable struct InductionU0{TB, T} <: Limace.Forcing{1}basis::Basis{TB}: The basis for the induction operator.U0: The background flow, which can be a singleBasisElementor a collection of them.factor::T: : A scalar factor that multiplies the induction operator, defaulting to1.0.mat::SparseMatrixCSC{ComplexF64}: A sparse matrix representation of the induction operator.preassembled::Bool: A flag indicating whether the induction operator has been preassembled.
Example usage
u = Inviscid(10)
b = Insulating(10)
U0 = BasisElement(u, Toroidal, (2,0,1))
f = Limace.InductionU0(b, U0)
Limace.assemble!(f)
f.mat # sparse matrix representation of the induction operatorLimace.induction — Function
induction(
bbi::Basis,
buj::Basis,
B0::BasisElement{T0<:Basis, TH<:Helmholtz, T};
threads,
external
) -> Any
Computes the induction term for a poloidal/toroidal background magnetic field B0, a magnetic field basis bbi and a velocity basis buj.
induction(
bbi::Basis,
U0::BasisElement{T0<:Basis, TH<:Helmholtz, T},
bbj::Basis;
threads,
external
) -> Any
Computes the induction term for a poloidal/toroidal background velocity U0, a magnetic field basis bbi and a magnetic field basis bbj.
Lorentz
\[\int \mathbf{u}_i^* \cdot \left(\left(\boldsymbol{\nabla}\times\mathbf{b}_j\right)\times\mathbf{B}_0+\left(\boldsymbol{\nabla}\times\mathbf{B}_0\right)\times\mathbf{b}_j\right)\,\mathrm{d}V\]
Limace.Lorentz — Type
mutable struct Lorentz{TU, TB, T} <: Limace.Forcing{2}ubasis::Basis{TU}: The velocity basis for the Lorentz operator.bbasis::Basis{TB}: The basis for the Lorentz operator.B0: The background magnetic field, which can be a singleBasisElementor a collection of them.factor::T: : A scalar factor that multiplies the Lorentz operator, defaulting to1.0.mat::SparseMatrixCSC{ComplexF64}: A sparse matrix representation of the Lorentz operator.preassembled::Bool: A flag indicating whether the Lorentz operator has been preassembled.
Example usage
u = Inviscid(10)
b = Insulating(10)
B0 = BasisElement(b, Toroidal, (1,0,1))
f = Limace.Lorentz(u,b,B0)
Limace.assemble!(f)
f.mat = # sparse matrix representation of the Lorentz operatorLimace.lorentz — Function
lorentz(
bui::Basis,
bbj::Basis,
B0::BasisElement{T0<:Basis, TH<:Helmholtz, T};
threads
) -> Any
Computes the Lorentz term for a poloidal/toroidal background magnetic field B0, a velocity basis bui and a magnetic field basis bbj.
Scalar advection
\[\int T_i^* \left(\mathbf{u}_j\boldsymbol{\cdot}\nabla T_0\right)\,\mathrm{d}V\]
Limace.ScalarAdvectionT0 — Type
mutable struct ScalarAdvectionT0{TT, TU, T} <: Limace.Forcing{2}tbasis::Basis{TT}: The temperature basis for the scalar advection operator.ubasis::Basis{TU}: The basis for the scalar advection operator.T0: The background temperature, which can be a singleBasisElementor a collection of them.factor::T: : A scalar factor that multiplies the operator, defaulting to1.0.mat::SparseMatrixCSC{ComplexF64}: A sparse matrix representation of the operator.preassembled::Bool: A flag indicating whether the operator has been preassembled.
Example usage
u = Limace.Inviscid(10)
T = Limace.Temperature(10)
T0 = BasisElement(t, Toroidal, (1,0,1))
f = Limace.ScalarAdvectionT0(T,u,T0)
Limace.assemble!(f)
f.mat # sparse matrix representation of the scalar advection operator\[\int T_i^* \left(\mathbf{U}_0\boldsymbol{\cdot}\nabla T_j\right)\,\mathrm{d}V\]
Limace.ScalarAdvectionU0 — Type
mutable struct ScalarAdvectionU0{TT, T} <: Limace.Forcing{1}tbasis::Basis{TT}: The temperature basis for the scalar advection operator.U0: The background flow field, which can be a singleBasisElementor a collection of them.factor::T: : A scalar factor that multiplies the operator, defaulting to1.0.mat::SparseMatrixCSC{ComplexF64}: A sparse matrix representation of the operator.preassembled::Bool: A flag indicating whether the operator has been preassembled.
Example usage
u = Limace.Inviscid(10)
T = Limace.Temperature(10)
U0 = BasisElement(u, Toroidal, (1,0,1))
f = Limace.ScalarAdvectionU0(T,U0)
Limace.assemble!(f)
f.mat # sparse matrix representation of the scalar advection operatorLimace.scalaradvection — Function
scalaradvection(
bti::Basis,
buj::Basis,
t0::BasisElement{T0<:Basis, Toroidal, T};
threads,
external
) -> SparseArrays.SparseMatrixCSC{Tv, Int64} where Tv
Computes the scalar advection term for a background temperature t0, a temperature basis bti and a velocity basis buj. Currently, scalar fields are implemented as being Toroidal scalars (may change in the future).
scalaradvection(
bti::Basis,
U0::BasisElement{T0<:Basis, TH<:Helmholtz, T},
btj::Basis;
threads,
external
) -> Any
Computes the scalar advection term for a poloidal/toroidal background flow U0, a temperature basis bti and a temperature basis btj.
Explicit boundary condition operator
Limace.boundarycondition! — Method
boundarycondition!(A, b::TB, ::Type{T}=Float64) where {TB<:Basis,T<:Number}Add the explicit boundary condition lines to a preassembled matrix A.
Limace.boundarycondition — Method
boundarycondition(b::TB, ::Type{T}=Float64) where {TB<:Basis,T<:Number}Construct a sparse matrix representing the boundary conditions for the basis b.
Limace.zero_boundarycondition! — Method
zero_boundarycondition!(A, b::TB, ::Type{T}=Float64) where {TB<:Basis,T<:Number}Zero out lines in a preassembled matrix (useful, when preassembling matrices at large resolution and then using them at lower resolution).
Assembly
All forcings are constructed without being assembled (i.e. the projections of each forcing onto the relevant basis are not done at the definition of the forcing).
The projections are done explicitly through Limace.assemble!, that saves the assembled sparse matrix in the forcing structure (f).
N = 10
u = Inviscid(N)
b = Insulating(N)
B0 = BasisElement(b, Poloidal, (1,0,1))
f = Limace.Lorentz(u,b,B0)
Limace.assemble!(f)495×375 SparseArrays.SparseMatrixCSC{ComplexF64, Int64} with 2051 stored entries:
⎡⣀⠘⠦⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠣⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⎤
⎢⠉⢧⠀⠈⠓⢤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠳⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⎥
⎢⠀⠀⠙⣀⠀⠀⠹⢤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢦⡀⠀⠀⠀⠀⠀⠀⠀⎥
⎢⠀⠀⠀⠈⠓⣆⠀⠀⠙⠦⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⠀⠀⠀⠀⠀⠀⎥
⎢⠀⠀⠀⠀⠀⠈⠳⡄⠀⠀⠙⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢳⡀⠀⠀⠀⠀⎥
⎢⠀⠀⠀⠀⠀⠀⠀⠙⠢⣄⠀⠈⠙⢦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⎥
⎢⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠳⣄⠀⠀⠹⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢳⡀⠀⎥
⎢⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠲⢤⡀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠳⣄⎥
⎢⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠦⠀⠀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⎥
⎢⠀⠳⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢤⡈⠓⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⎥
⎢⠀⠀⠘⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢧⡀⠈⠳⣄⠀⠀⠀⠀⠀⠀⠀⎥
⎢⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢩⡀⠀⠈⢲⡀⠀⠀⠀⠀⠀⎥
⎢⠀⠀⠀⠀⠀⠀⠳⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⡆⠀⠀⢳⣀⠀⠀⠀⠀⎥
⎢⠀⠀⠀⠀⠀⠀⠀⠈⠣⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠘⢦⠀⠀⠀⎥
⎢⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠱⡄⠀⠈⢳⠀⠀⎥
⎢⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠳⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣆⠀⠈⢇⠀⎥
⎢⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢷⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢳⡄⠈⢧⎥
⎢⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠱⡀⠀⎥
⎢⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢆⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠳⣄⎥
⎣⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⎦This can also be done in parallel, by using the keyword argument threads=true.
Limace.assemble!(f; threads=true)When the forcings are wrapped into a LimaceProblem, it is not necessary to call Limace.assembly! on each forcing by hand, but one can simply call Limace.assembly!(problem), as outlined in the Quickstart.