Assemblers
The assembly module contains two important pieces for assembly: the weak formulation and the assembly routine itself. The weak formulation contains all the terms that need to be assembled, the assembler creates the final system matrix.
Weak Formulations
A weak formulation describes the problem in detail, see The Finite Element Method (FEM) for more information. It consists of a few key ingredients: the given data (forcings, boundary conditions, etc.), the trial spaces, the test spaces, and the equations. In Mantis, there are two structures that are used to represent all this data: WeakFormInputs and WeakForm.
Representing problem data using WeakFormInputs
The data, trial spaces, and test spaces are represented by the following object.
Mantis.Assemblers.WeakFormInputs Type
WeakFormInputs{manifold_dim, TeF, TrF, F} <: AbstractInputsContainer for test and trial spaces, and forcing terms to be used in a WeakForm.
Constructors
WeakFormInputs(test_forms::TeF, trial_forms::TrF, forcings::F): Creates a newWeakFormInputsinstance with the given test forms, trial forms, and forcing terms.WeakFormInputs(test_forms::TeF, trial_forms::TrF): Creates a newWeakFormInputsinstance with the given test forms and trial forms. The forcing terms are set to nothing.WeakFormInputs(test_forms::TeF, trial_forms::TrF, forcing::F): Creates a newWeakFormInputsinstance from a single test and trial space and a forcing term.WeakFormInputs(test_forms::TeF, trial_forms::TrF): Creates a newWeakFormInputsinstance from a single test and trial space. The forcing terms are set to nothing.WeakFormInputs(forms::TrF, forcing::F): Creates a newWeakFormInputsinstance with the given trial spaces and forcing terms. The test spaces are set to the same as the trial spaces.WeakFormInputs(forms::TrF): Creates a newWeakFormInputsinstance with the given trial spaces. The test spaces are set to the same as the trial spaces and the forcing terms are set to nothing.WeakFormInputs(forms::TrF, forcing::F): Creates a newWeakFormInputsinstance with a single trial space and forcing term. The test space is set to the same as the trial space.WeakFormInputs(forms::TrF): Creates a newWeakFormInputsinstance with a single trial space. The test space is set to the same as the trial space and the forcing term is set to nothing.
Example
julia> using Mantis
julia> V0, V1, V2, V3 = Forms.create_tensor_product_bspline_de_rham_complex((0.0, 0.0, 0.0), (1.0, 1.0, 1.0), (4, 4, 4), (3, 3, 3), (2, 2, 2));
julia> geometry = Forms.get_geometry(V2);
julia> forcing_function(x) = [ones(size(x))];
julia> f = Forms.AnalyticalFormField(3, forcing_function, geometry, "f");
julia> weak_form_inputs = Assemblers.WeakFormInputs((V2, V3), (f,));
julia> isa(weak_form_inputs, Assemblers.WeakFormInputs{3})
trueFields
test_forms::TeF: The test forms for the weak-formulation.trial_forms::TrF: The trial forms for the weak-formulation.forcings::F: The forcing terms for the weak-formulation, possibly nothing.
Type parameters
manifold_dim::Int: The dimension of the manifold where the weak-formulation is defined.TeF: The type of the tuple of test forms. Each entry should be a subtype ofForms.AbstractFormSpace.TrF: The type of the tuple of trial forms. Each entry should be a subtype ofForms.AbstractFormSpace.F: The type of the tuple of forcing terms. Each entry should be a subtype ofForms.AbstractFormField.
The following getters are defined to obtain the data from a WeakFormInputs object.
Mantis.Assemblers.get_trial_forms Method
get_trial_forms(wfi::WeakFormInputs)Return a tuple of Forms.AbstractFormSpace that are used as trial spaces.
Mantis.Assemblers.get_test_forms Method
get_test_forms(wfi::WeakFormInputs)Return a tuple of Forms.AbstractFormSpace that are used as test spaces.
Mantis.Assemblers.get_forcings Method
get_forcings(wfi::WeakFormInputs)Return a tuple of Forms.AbstractFormField that are used as test spaces.
Mantis.Assemblers.get_trial_form Function
get_trial_form(wfi::WeakFormInputs, i::Int=1)Return the i-th trial Forms.AbstractFormSpace.
Mantis.Assemblers.get_test_form Function
get_test_form(wfi::WeakFormInputs, i::Int=1)Return the i-th test Forms.AbstractFormSpace.
Mantis.Assemblers.get_forcing Function
get_forcing(wfi::WeakFormInputs, i::Int=1)Return the i-th forcing Forms.AbstractFormField.
Mantis.Assemblers.get_num_trial Method
get_num_trial(wfi::WeakFormInputs)Return the number of trial spaces.
sourceMantis.Assemblers.get_num_test Method
get_num_test(wfi::WeakFormInputs)Return the number of test spaces.
sourceMantis.Assemblers.get_num_forcings Method
get_num_forcings(wfi::WeakFormInputs)Return the number of forcing functions.
sourceRepresenting weak formulations using WeakForm
The complete weak formulation is represented by the following object, that takes a WeakFormInputs and the left-hand and right-hand sides of the equations as inputs.
Mantis.Assemblers.WeakForm Type
WeakForm{manifold_dim, LHS, RHS, I}Structure representing the weak-formulation of a continuous Petrov-Galerking method. Both the left and right-hand sides of the formulation are given as blocks of real-valued operators; these are defined from a set of inputs holding the test, trial and forcing terms, and a constructor method that defines where the blocks are placed.
Constructors
WeakForm( lhs_expressions::LHS, rhs_expressions::RHS, inputs::I ) where { manifold_dim, lhs_num_rows, lhs_num_cols, rhs_num_rows, rhs_num_cols, LHS <: NTuple{ lhs_num_rows, NTuple{lhs_num_cols, Union{Int, Forms.AbstractRealValuedOperator}} }, RHS <: NTuple{ rhs_num_rows, NTuple{rhs_num_cols, Union{Int, Forms.AbstractRealValuedOperator}} }, I <: WeakFormInputs{manifold_dim}, }: Creates a newWeakForminstance with the given inputs (the problem data and spaces, seeWeakFormInputsfor more details), and the left- and right-hand side expressions.
Example
julia> using Mantis
julia> V0, V1, V2, V3 = Forms.create_tensor_product_bspline_de_rham_complex((0.0, 0.0, 0.0), (1.0, 1.0, 1.0), (4, 4, 4), (3, 3, 3), (2, 2, 2));
julia> geometry = Forms.get_geometry(V2);
julia> forcing_function(x) = [ones(size(x))];
julia> f = Forms.AnalyticalFormField(3, forcing_function, geometry, "f");
julia> weak_form_inputs = Assemblers.WeakFormInputs((V2, V3), (f,));
julia> canonical_qrule = Quadrature.tensor_product_rule((4, 4, 4), Quadrature.gauss_legendre);
julia> dΩ = Quadrature.StandardQuadrature(canonical_qrule, Geometry.get_num_elements(geometry));
julia> tau_h, v_h = Assemblers.get_test_forms(weak_form_inputs);
julia> sigma_h, u_h = Assemblers.get_trial_forms(weak_form_inputs);
julia> f = Assemblers.get_forcing(weak_form_inputs);
julia> A_11 = ∫(tau_h ∧ ★(sigma_h), dΩ);
julia> A_12 = -∫(d(tau_h) ∧ ★(u_h), dΩ);
julia> A_21 = ∫(v_h ∧ ★(d(sigma_h)), dΩ);
julia> lhs_expressions = ((A_11, A_12), (A_21, 0));
julia> b_21 = ∫(v_h ∧ ★(f), dΩ);
julia> rhs_expressions = ((0,), (b_21,));
julia> weak_form = Assemblers.WeakForm(lhs_expressions, rhs_expressions, weak_form_inputs);
julia> isa(weak_form, Assemblers.WeakForm{3})
trueFields
lhs_expressions::LHS: The left-hand side blocks of the weak-formulation.rhs_expressions::RHS: The right-hand side blocks of the weak-formulation.inputs::I: The inputs for the weak-formulation, which include the test and trial spaces, and forcing terms.
Type parameters
manifold_dim::Int: The dimension of the manifold where the weak-formulation is defined.LHS: The type of the left-hand side expressions. Each row-column entry should be a subtype ofAbstractRealValuedOperatoror0.RHS: The type of the right-hand side expressions. Each row-column entry should be a subtype ofAbstractRealValuedOperatoror0.I: The type of the inputs. It should be a subtype ofWeakFormInputs{manifold_dim}.
For this object, the following getters are defined.
Mantis.Assemblers.get_lhs_expressions Function
get_lhs_expressions(wf::WeakForm)Return a tuple of Forms.AbstractRealValuedOperator representing the left-hand sides of the weak formulation.
Mantis.Assemblers.get_rhs_expressions Function
get_rhs_expressions(wf::WeakForm)Return a tuple of Forms.AbstractRealValuedOperator representing the right-hand sides of the weak formulation.
Mantis.Assemblers.get_inputs Function
get_inputs(wf::WeakForm)Return the WeakFormInputs object used in the weak form.
Mantis.Assemblers.get_test_forms Method
get_test_forms(wf::WeakForm)Return a tuple of Forms.AbstractFormSpace that are used as test spaces.
Mantis.Assemblers.get_trial_forms Method
get_trial_forms(wf::WeakForm)Return a tuple of Forms.AbstractFormSpace that are used as trial spaces.
Mantis.Assemblers.get_forcings Method
get_forcings(wf::WeakForm)Return a tuple of Forms.AbstractFormField that are used as test spaces.
Mantis.Assemblers.get_forcing Function
get_forcing(wf::WeakForm, id::Int=1)Return the id-th forcing Forms.AbstractFormField.
Mantis.Assemblers.get_test_sizes Function
get_test_sizes(wf::WeakForm)Return the number of degrees of freedom for each test form. Uses Forms.get_num_basis.
Mantis.Assemblers.get_trial_sizes Function
get_trial_sizes(wf::WeakForm)Return the number of degrees of freedom for each trial form. Uses Forms.get_num_basis.
Mantis.Assemblers.get_test_size Function
get_test_size(wf::WeakForm)Return the total number of degrees of freedom for all test forms combined.
sourceMantis.Assemblers.get_trial_size Function
get_trial_size(wf::WeakForm)Return the total number of degrees of freedom for all trial forms combined.
sourceMantis.Assemblers.get_lhs_size Function
get_lhs_size(wf::WeakForm)Return the size of the left-hand-side matrix. Does not require assembly.
sourceMantis.Assemblers.get_rhs_size Function
get_rhs_size(wf::WeakForm)Return the size of the right-hand-side matrix (or vector). Does not require assembly.
sourceMantis.Assemblers.get_test_offsets Function
get_test_offsets(
wf::WeakForm{manifold_dim, LHS, RHS, I}
) where {
manifold_dim,
num_rows,
lhs_num_cols,
rhs_num_cols,
LHS <:
NTuple{
num_rows, NTuple{lhs_num_cols, Union{Int, Forms.AbstractRealValuedOperator}}
},
RHS <:
NTuple{
num_rows, NTuple{rhs_num_cols, Union{Int, Forms.AbstractRealValuedOperator}}
},
I,
}Returns the offsets of the test function spaces used in the weak form.
Arguments
wf::WeakForm{manifold_dim, LHS, RHS, I}: The weak form being used.
Returns
NTuple{num_rows, Int}: The offsets of the test function spaces.
Mantis.Assemblers.get_trial_offsets Function
get_trial_offsets(
wf::WeakForm{manifold_dim, LHS, RHS, I}
) where {
manifold_dim,
num_rows,
lhs_num_cols,
rhs_num_cols,
LHS <:
NTuple{
num_rows, NTuple{lhs_num_cols, Union{Int, Forms.AbstractRealValuedOperator}}
},
RHS <:
NTuple{
num_rows, NTuple{rhs_num_cols, Union{Int, Forms.AbstractRealValuedOperator}}
},
I,
}Returns the offsets of the trial function spaces used in the weak form.
Arguments
wf::WeakForm{manifold_dim, LHS, RHS, I}: The weak form being used.
Returns
NTuple{lhs_num_cols, lhs_num_cols}: The offsets of the trial function spaces.
Mantis.Assemblers.get_estimated_nnz_per_elem Function
get_estimated_nnz_per_elem(wf::WeakForm)Returns the estimated number of non-zero entries per element for the left- and right-hand sides of the weak-formulation.
Arguments
wf::WeakForm: The weak-formulation for which the estimated number of non-zero entries is to be determined.
Returns
Tuple(Int, Int): The estimated number of non-zero entries per element for the left-hand side and right-hand side of the weak-formulation, respectively.
Mantis.Assemblers.get_num_elements Function
get_num_elements(wf::WeakForm)Returns the number of elements over which the discrete weak-formulation is defined.
Arguments
wf::WeakForm: The weak-formulation for which the number of elements is to be determined.
Returns
::Int: The number of elements.
Mantis.Assemblers.get_num_evaluation_elements Function
get_num_evaluation_elements(wf::WeakForm)Returns the maximum number of elements over which the weak form blocks are evaluated. This is the max over all lhs and rhs expression blocks.
Arguments
wf::WeakForm: The weak-formulation for which the number of quadrature elements is to be determined.
Returns
::Int: The number of quadrature elements.
Example: setting up a weak form.
As an example, consider the mixed
We first create a WeakFormInputs object containing the test and trial spaces (which are the same in this case, so we only have to include them once), and the forcing (which we set to return one here for simplicity).
julia> using Mantis
julia> V0, V1, V2, V3 = Forms.create_tensor_product_bspline_de_rham_complex(
(0.0, 0.0, 0.0), (1.0, 1.0, 1.0), (4, 4, 4), (3, 3, 3), (2, 2, 2)
);
julia> geometry = Forms.get_geometry(V2);
julia> forcing_function(x) = [ones(size(x, 1))]
forcing_function (generic function with 1 method)
julia> f = Forms.AnalyticalFormField(3, forcing_function, geometry, "f");
julia> weak_form_inputs = Assemblers.WeakFormInputs((V2, V3), (f,));With the WeakFormInputs object ready, we can create the complete WeakForm object. Note that the lhs_expressions and rhs_expressions contain the integer 0 where we don't need a term.
julia> canonical_qrule = Quadrature.tensor_product_rule((4, 4, 4), Quadrature.gauss_legendre);
julia> dΩ = Quadrature.StandardQuadrature(canonical_qrule, Geometry.get_num_elements(geometry));
julia> τ_h, v_h = Assemblers.get_test_forms(weak_form_inputs);
julia> σ_h, u_h = Assemblers.get_trial_forms(weak_form_inputs);
julia> f = Assemblers.get_forcing(weak_form_inputs);
julia> A_11 = ∫(τ_h ∧ ★(σ_h), dΩ);
julia> A_12 = -∫(d(τ_h) ∧ ★(u_h), dΩ);
julia> A_21 = ∫(v_h ∧ ★(d(σ_h)), dΩ);
julia> lhs_expressions = ((A_11, A_12), (A_21, 0));
julia> b_21 = ∫(v_h ∧ ★(f), dΩ);
julia> rhs_expressions = ((0,), (b_21,));
julia> weak_form = Assemblers.WeakForm(lhs_expressions, rhs_expressions, weak_form_inputs);The weak form object can now be assembled using the assemble function.
Pre-implemented weak formulations
While you can always write your own weak formulation, Mantis does provide a few common pre-made weak formulations. The pre-implemented weak formulations require input spaces, forcings, and quadrature, but simplify the remaining steps. Most pre-implemented weak formulations consist of two parts: one that encodes the equations, another that also performs the remaining setup and solve steps.
-projection
Mantis.Assemblers.L2_projection Function
L2_projection(inputs::AbstractInputs, dΩ::Quadrature.AbstractGlobalQuadratureRule)Set up the L2 projection equations of projecting a function onto a discrete form space.
Weak form: for given
Arguments
inputs::AbstractInputs: The inputs for the weak form assembly. SeeWeakFormInputsfor the details.dΩ::Quadrature.AbstractGlobalQuadratureRule: The quadrature rule to use for the integral evaluation.
Returns
lhs_expression<:NTuple{1, NTuple{1, AbstractRealValuedOperator}}: The left-hand side of the weak form.rhs_expression<:NTuple{1, NTuple{1, AbstractRealValuedOperator}}: The right-hand side of the weak form.
Mantis.Assemblers.solve_L2_projection Function
solve_L2_projection(Xᵏ, fₑ, dΩ)Returns the solution of the weak form of the L2 projection.
Weak form: for given
Arguments
Xᵏ: The k-form space to use as trial and test space.fₑ: The forcing term to use for the right-hand side of the weak formulation.dΩ: The quadrature rule to use for the assembly.
Returns
fₕ::FormField: The projection offₑontoXᵏ.
Hodge-Laplacians
Mantis.Assemblers.zero_form_hodge_laplacian Function
zero_form_hodge_laplacian(
inputs::AbstractInputs, dΩ::Quadrature.AbstractGlobalQuadratureRule
)Set up the equations for the
Weak form: for given
Arguments
inputs::AbstractInputs: The inputs for the weak form assembly. SeeWeakFormInputsfor the details.dΩ::Quadrature.AbstractGlobalQuadratureRule: The quadrature rule to use for the integral evaluation.
Returns
lhs_expression<:NTuple{1, NTuple{1, AbstractRealValuedOperator}}: The left-hand side of the weak form.rhs_expression<:NTuple{1, NTuple{1, AbstractRealValuedOperator}}: The right-hand side of the weak form.
Mantis.Assemblers.solve_zero_form_hodge_laplacian Function
solve_zero_form_hodge_laplacian(X⁰, fₑ, dΩ)Returns the solution of the weak form of the 0-form Hodge Laplacian using homogeneous Dirichlet boundary conditions.
Weak form: for given
Arguments
X⁰: The 0-form space to use as trial and test space.fₑ: The forcing term to use for the right-hand side of the weak formulation.dΩ: The quadrature rule to use for the assembly.
Returns
uₕ::Forms.FormField: The solution of the weak-formulation.
Mantis.Assemblers.one_form_hodge_laplacian Function
one_form_hodge_laplacian(
inputs::AbstractInputs, dΩ::Quadrature.AbstractGlobalQuadratureRule
)Set up the equations for the
Weak form: for given
Arguments
inputs::AbstractInputs: The inputs for the weak form assembly. SeeWeakFormInputsfor the details.dΩ::Quadrature.AbstractGlobalQuadratureRule: The quadrature rule to use for the integral evaluation.
Returns
lhs_expression<:NTuple{2, NTuple{2, Union{Int, AbstractRealValuedOperator}}}: The left-hand side of the weak form.rhs_expression<:NTuple{2, NTuple{1, Union{Int, AbstractRealValuedOperator}}}: The right-hand side of the weak form.
Function for assembling the weak form of the 1-form Hodge Laplacian problem.
sourceMantis.Assemblers.solve_one_form_hodge_laplacian Function
solve_one_form_hodge_laplacian(X⁰, X¹, f¹, dΩ)Returns the solution of the weak form of the 1-form Hodge Laplacian.
Weak form: for given
Arguments
X⁰: The 0-form space to use as trial and test space.X¹: The 1-form space to use as trial and test space.f¹: The forcing term to use for the right-hand side of the weak formulation.dΩ: The quadrature rule to use for the assembly.
Returns
σ⁰ₕ::Forms.FormField: The 0-form solution of the weak-formulation.u¹ₕ::Forms.FormField: The 1-form solution of the weak-formulation.
solve_one_form_hodge_laplacian(
complex::C,
forcing_function::Function,
dΩₐ::Quadrature.AbstractGlobalQuadratureRule{manifold_dim},
num_steps::Int,
dorfler_parameter::Float64,
dΩₑ::Quadrature.AbstractGlobalQuadratureRule{manifold_dim},
Lchains::Bool;
verbose::Bool=false
) where {manifold_dim, num_forms, C <: NTuple{num_forms, Forms.AbstractFormSpace}}Returns the solution of the weak form of the 1-form Hodge Laplacian from an adaptive loop.
Arguments
complex::C: The initial de Rham complex to use for the problem.forcing_function::Function: The function to use for the forcing term.dΩₐ::Quadrature.AbstractGlobalQuadratureRule{manifold_dim}: The quadrature rule to use for the assembly.num_steps::Int: The number of steps to use for the adaptive loop.dorfler_parameter::Float64: The parameter to use for the Dörfler marking.dΩₑ::Quadrature.AbstractGlobalQuadratureRule{manifold_dim}: The quadrature rule to use for the error estimation.Lchains::Bool: Whether to use L-chains for the refinement.verbose::Bool=false: Whether to print the progress of the adaptive loop.
Mantis.Assemblers.n_form_hodge_laplacian Function
n_form_hodge_laplacian(
inputs::WeakFormInputs, dΩ::Quadrature.AbstractGlobalQuadratureRule
)Set up the equations for the
Weak form: for given
Arguments
inputs::AbstractInputs: The inputs for the weak form assembly. SeeWeakFormInputsfor the details.dΩ::Quadrature.AbstractGlobalQuadratureRule: The quadrature rule to use for the integral evaluation.
Returns
lhs_expression<:NTuple{2, NTuple{2, Union{Int, AbstractRealValuedOperator}}}: The left-hand side of the weak form.rhs_expression<:NTuple{2, NTuple{1, Union{Int, AbstractRealValuedOperator}}}: The right-hand side of the weak form.
Mantis.Assemblers.solve_volume_form_hodge_laplacian Function
solve_volume_form_hodge_laplacian(Xⁿ⁻¹, Xⁿ, fₑ, dΩ)Returns the solution of the weak form of the n-form Hodge Laplacian.
Weak form: for given
Arguments
Xⁿ⁻¹: The (n-1)-form space to use as trial and test space.Xⁿ: The n-form space to use as trial and test space.fₑ: The forcing term to use for the right-hand side of the weak formulation.dΩ: The quadrature rule to use for the assembly.
Returns
uⁿ⁻¹ₕ: The (n-1)-form solution of the weak-formulation.ϕⁿₕ: The n-form solution of the weak-formulation.
Maxwell Eigenvalue Problems
In this case, next to the functions maxwell_eigenvalue and solve_maxwell_eig, Mantis also provides two functions to obtain the analytical eigenvalues.
Mantis.Assemblers.maxwell_eigenvalue Function
maxwell_eigenvalue(inputs::WeakFormInputs, dΩ::Quadrature.AbstractGlobalQuadratureRule)Set up the equations for Maxwell's eigenvalue problem.
Weak form: find
Arguments
inputs::AbstractInputs: The inputs for the weak form assembly. SeeWeakFormInputsfor the details.dΩ::Quadrature.AbstractGlobalQuadratureRule: The quadrature rule to use for the integral evaluation.
Returns
lhs_expression<:NTuple{1, NTuple{1, AbstractRealValuedOperator}}: The left-hand side of the weak form.rhs_expression<:NTuple{1, NTuple{1, AbstractRealValuedOperator}}: The right-hand side of the weak form.
Mantis.Assemblers.analytical_maxwell_eigenfunction Function
analytical_maxwell_eigenfunction(
m::Int, n::Int, scale_factors::NTuple{2, Float64}, x::Matrix{Float64}
)Evaluates the analytical Maxwell eigenfunction for the eigenmode (m, n) at points x.
Arguments
m::Int: Eigenmode component x.n::Int: Eigenmode component y.scale_factors::NTuple{2, Int}: Scaling factors based on the size of the domain.x::Matrix{Float64}: Evaluation points.
Returns
NTuple{2, Vector{Float64}}: The evaluated Maxwell eigenfunction at pointsx.
Mantis.Assemblers.get_analytical_maxwell_eig Function
get_maxwell_eig(num_eig::Int, geom::G) where {G <: Geometry.AbstractGeometry{2}}Returns the first num_eig eigenvalues and 1-form eigenfunctions on the geometry geom.
Arguments
num_eig::Int: Number of eigenvalues and eigenfunctions to compute.geom::Geometry.AbstractGeometry{2}: The two-dimensional geometry.
Returns
Vector{Float64}: The firstnum_eiganalytical eigenvalues.Vector{Forms.AnalyticalFormField{2, 1, G}: The firstnum_eiganalytical eigenfunctions.
Mantis.Assemblers.solve_maxwell_eig Function
solve_maxwell_eig(
X⁰::Forms.AbstractFormSpace{2, 0},
X¹::Forms.AbstractFormSpace{2, 1},
dΩ::Quadrature.AbstractGlobalQuadratureRule{2},
num_eig::Int;
verbose::Bool=false,
)Returns the first num_eig eigenvalues and 1-form eigenfunctions of the Maxwell eigenvalue problem.
Weak form: find
Arguments
X⁰::Forms.AbstractFormSpace{2, 0}: The 0-form space to compute the nullspace offset with.X¹::Forms.AbstractFormSpace{2, 1}: The 1-form space to use as trial and test space.dΩ::Quadrature.AbstractGlobalQuadratureRule{2}: The quadrature rule to use for the assembly.num_eig::Int: The number of eigenvalues and eigenfunctions to compute.verbose::Bool=false: Whether to print the nullspace offset.
Returns
ω²ₕ::Vector{Float64}: The firstnum_eigeigenvalues.u¹ₕ::Vector{Forms.FormField{2, 1}}: The firstnum_eigeigenfunctions.
solve_maxwell_eig(
complex::C,
dΩₐ::Quadrature.StandardQuadrature{manifold_dim},
num_steps::Int,
dorfler_parameter::Float64,
dΩₑ::Quadrature.StandardQuadrature{manifold_dim},
Lchains::Bool,
eigenfunction::Int,
num_eig::Int,
scale_factors::NTuple{manifold_dim, Float64};
verbose::Bool=false,
) where {manifold_dim, num_forms, C <: NTuple{num_forms, Forms.AbstractFormSpace}}Returns the first num_eig eigenvalues and 1-form eigenfunctions of the Maxwell eigenvalue problem for an adaptive loop.
Arguments
complex::C: The initial de Rham complex to use for the problem.dΩₐ::Quadrature.StandardQuadrature{manifold_dim}: The quadrature rule to use for the assembly.num_steps::Int: The number of adaptive steps to perform.dorfler_parameter::Float64: The Dörfler marking parameter.dΩₑ::Quadrature.StandardQuadrature{manifold_dim}: The quadrature rule to use for the error estimation.Lchains::Bool: Whether to use L-chains for the refinement.eigenfunction::Int: The index of the eigenfunction to use for the error estimation.num_eig::Int: The number of eigenvalues and eigenfunctions to compute.scale_factors::NTuple{manifold_dim, Float64}: The scaling factors for the geometry.verbose::Bool=false: Whether to print the progress of the adaptive loop.
Returns
ω²ₕ::Vector{Float64}: The firstnum_eigeigenvalues.u¹ₕ::Vector{Forms.FormField{manifold_dim, 1, G}}: The firstnum_eigeigenfunctions.
Assembling a weak formulation
In Mantis, the actual assembly routine can be used by simply calling the following function.
Mantis.Assemblers.assemble Function
assemble(
weak_form::WeakForm{manifold_dim, LHS, RHS, I},
dirichlet_bcs::Dict{Int, Float64}=Dict{Int, Float64}();
lhs_type::Type=spa.SparseMatrixCSC{Float64, Int},
rhs_type::Type=Vector{Float64},
) where {
manifold_dim,
num_rows,
lhs_num_cols,
rhs_num_cols,
LHS <: NTuple{
num_rows, NTuple{lhs_num_cols, Union{Int, Forms.AbstractRealValuedOperator}}
},
RHS <: NTuple{
num_rows, NTuple{rhs_num_cols, Union{Int, Forms.AbstractRealValuedOperator}}
},
I,
}Assemble the left- and right-hand sides of a discrete Petrov-Galerkin problem for the given weak-formulation and Dirichlet boundary conditions.
Arguments
weak_form::WeakForm{manifold_dim, LHS, RHS, I}: The weak form to assemble.dirichlet_bcs::Dict{Int, Float64}: A dictionary containing the Dirichlet boundary conditions, where the key is the index of the boundary condition and the value is the boundary condition value.lhs_type::Type: The type of the left-hand side array. Default isSparseMatrixCSC{Float64, Int}.rhs_type::Type: The type of the right-hand side array. Default isVector{Float64}.
Returns
lhs::lhs_type: The assembled left-hand side array.rhs::rhs_type: The assembled right-hand side vector.
So, continuing the previous example, we can assemble our problem by simply calling
julia> A, b = Assemblers.assemble(weak_form);This gives us the left-hand side matrix A and right-hand side vector b. You can solve this with a solver of your choosing. Here we pick Julia's backslash operator. We can obtain the final solution as a FormField using the build_form_fields helper. This helper takes the trial spaces and full solution vector as inputs, and combines the spaces and coefficients into the final solution objects.
julia> sol = A \ b;
julia> sigma_h, u_h = Forms.build_form_fields((V2, V3), sol);Helpers used within assemble
The assembly module also provides the following helper functions that are used within the assembly routine.
Mantis.Assemblers.get_pre_allocation Function
get_pre_allocation(
weak_form::WeakForm, side::String, ::Type{A}
) where {T, A <: AbstractArray{T}}Returns pre-allocated row, column, and value vectors for the left-hand side (lhs) or right-hand side (rhs) array.
Arguments
weak_form::WeakForm: The weak form to use for the pre-allocation.side::String: The side of the array to pre-allocate. Must be either "lhs" or "rhs".
Returns
rows::Vector{Int}: The pre-allocated row indices.cols::Vector{Int}: The pre-allocated column indices.vals::Vector{T}: The pre-allocated values.
Mantis.Assemblers.add_expression_contributions! Function
add_expression_contributions!(
rows::Vector{Int},
cols::Vector{Int},
vals::AbstractVector,
counts::Int,
expression,
element_id::Int,
test_offset::Int,
trial_offset::Int,
)Updates the row, column, and value vectors with contributions from the specified real-valued expression at the element given by element_id.
Arguments
rows::Vector{Int}: The row indices of the array.cols::Vector{Int}: The column indices of the array.vals::AbstractVector: The values of the array.counts::Int: The current count of non-zero entries in the array.expressions: The expression to evaluate.element_id::Int: The identifier of the element.test_offsets::Int: The offset for the test function.trial_offsets::Int: The offset for the trial function.
Returns
rows::Vector{Int}: The updated row indices of the array.cols::Vector{Int}: The updated column indices of the array.vals::AbstractVector: The updated values of the array.counts::Int: The updated count of non-zero entries in the array.
Mantis.Assemblers.zero_rows! Function
zero_rows!(
lhs_vals::AbstractVector{T},
rhs_vals::AbstractVector{T},
lhs_rows::Vector{Int},
rhs_rows::Vector{Int},
dirichlet_bcs::Dict{Int, T},
) where {T}For each index i that is a key of dirichlet_bcs, set the corresponding values from that row to zero, both in lhs_vals and rhs_vals.
Examples
using Mantis
Assemblers.zero_rows!([1., 1., 1.], [1., 2., 3.], [1, 2, 3], [1, 3, 2], Dict(2 => 42.0))
# output
([1.0, 0.0, 1.0], [1.0, 2.0, 0.0])Mantis.Assemblers.add_bc! Function
add_bc!(
lhs::AbstractMatrix{T}, rhs::AbstractVector{T}, dirichlet_bcs::Dict{Int, T}
) where {T}Set the rows to 0 and diagonals to 1 in lhs, and rows of rhs to a value, as specified by the row indices (keys) and values of dirichlet_bcs.
Examples
using Mantis
Assemblers.add_bc!([2.0 2.0 2.0; 2.0 2. 2.0; 2.0 2.0 2.0], zeros(3), Dict(2 => 42.0))
# output
([2.0 2.0 2.0; 0.0 1.0 0.0; 2.0 2.0 2.0], [0.0, 42.0, 0.0])add_bc!(lhs::AbstractMatrix, rhs::AbstractMatrix, dirichlet_bcs::Dict)Remove the rows and columns of lhs and rhs as specified by the keys of dirichlet_bcs. See also set_diagonal!.
Mantis.Assemblers.set_diagonal! Function
set_diagonal!(
lhs::AbstractMatrix{T}, rhs::AbstractVector{T}, dirichlet_bcs::Dict{Int, T}
) where {T}Set the diagonals of lhs to 1 and rows of rhs to a value, as specified by the row indices (keys) and values of dirichlet_bcs. See also add_bc!.
Examples
using Mantis
Assemblers.set_diagonal!([2.0 2.0 2.0; 2.0 2. 2.0; 2.0 2.0 2.0], zeros(3), Dict(2 => 42.0))
# output
([2.0 2.0 2.0; 2.0 1.0 2.0; 2.0 2.0 2.0], [0.0, 42.0, 0.0])set_diagonal!(lhs::AbstractMatrix, rhs::AbstractMatrix, dirichlet_bcs::Dict)Remove the rows and columns of lhs and rhs as specified by the keys of dirichlet_bcs.
Examples
using Mantis
Assemblers.set_diagonal!(
[2. 0. 0.; 0. 2. 0.; 0. 0. 2.], [2. 0. 0.; 0. 2. 0.; 0. 0. 2.], Dict(2 => 42.0)
)
# output
([2.0 0.0; 0.0 2.0], [2.0 0.0; 0.0 2.0])Mantis.Assemblers.build_array Function
build_array(
array_type::Type{A},
rows::Vector{Int},
cols::Vector{Int},
vals::AbstractVector,
size::Tuple{Int, Int},
) where {A <: AbstractArray}Returns a array of the specified type with the given row and column indices and values.
Arguments
array_type::Type{AbstractArray}: The type of array to build.rows::Vector{Int}: The row indices of the array.cols::Vector{Int}: The column indices of the array.vals::AbstractVector: The values of the array.size::Tuple{Int, Int}: The size of the array.
Returns
::array_type: The constructed array of the specified type.