Integrators

In addition to assembling system matrices and vectors, much of the internal code can be reused to create quite efficient integration of values, given a solution vector (and potentially state variables). This feature can also be used to calculate per-cell (or per-integration point) quantities, simply by defining an integrator containing a vector that is indexed by the global cell id.

Available integrators

SimpleIntegrator

FerriteAssembly.SimpleIntegratorType
SimpleIntegrator(fun::Function, val; domains=nothing)

Calculate the integrals

\[\int_\Omega f(u, \nabla u, s)\, \mathrm{d}\Omega \int_\Gamma f(u, \nabla u, n)\, \mathrm{d}\Gamma \]

for cell and facet domains respectively. For single-field problems, u is the current function value, ∇u the current function gradient. For multi-field problem, u and ∇u are NamedTuples, where the keys in u and ∇u are the fieldnames.

For cell domains, qp_state the current state in the current quadrature point. This assumes that cell_state::AbstractVector, otherwise, qp_state = cell_state. For facet domains, n is the facet normal vector.

It is the user's responsibility that fun(args...)::typeof(val). Additionally, the type of val must support

  • val + val
  • val * x (where x::Real)
  • zero(val)

One exception to these requirements; val::Tuple, if the elements of the tuple fulfills those requirements.

Specify domains to only integrate over a part of the grid. It should contain a subset of the keys provided to setup_domainbuffers. Single, String, or collections; Set{String}, AbstractVector{String}, or NTuple{N,String} inputs are supported. If domains=nothing, all domains are integrated.

Example: Calculate the average value and gradient
We assume that we have done the setup: buffer = setup_domainbuffer(...),
assembled K and r, and solved a=K\r

integrator = SimpleIntegrator((u, ∇u, state)->(1.0, u, ∇u), (0.0, 0.0, zero(Vec{dim})))
work!(integrator, buffer; a=a)
area = integrator.val[1]
u_avg = integrator.val[2]/area 
∇u_avg = integrator.val[3]/area

If the buffer is setup to be threaded, this calculation will also be threaded.

source

Integrator

FerriteAssembly.IntegratorType
Integrator(val::V; domains=nothing)

Integrate over the domain by modifying the value val for each cell in the function integrate_cell, which should be overloaded for the specific combination of val::V and the material for that cell. V must be a mutable type.

Specify domains to only integrate over a part of the grid. It should contain the names of the domains to integrate over. Single, String, or collections; Set{String}, AbstractVector{String}, or NTuple{N,String} inputs are supported. If domains=nothing, all domains are integrated.

Note: This integrator will currently only run sequentially even if a threaded assembly is setup with setup_domainbuffer

source

Functions to overload

Using the Integrator requires the following functions to be overloaded, depending on the type of domain

FerriteAssembly.integrate_cell!Function
integrate_cell!(val, cell_state, ae, material, cv, cellbuffer)

Function to be overloaded for val (potentially in combination with material), and will be called when using Integrator. Mutate val to add to the result.

The order of the inputs is chosen to follow the element routines

source
FerriteAssembly.integrate_facet!Function
integrate_facet!(val, ae, material, fv, facetbuffer)

Function to be overloaded for val (potentially in combination with material), and will be called when using Integrator. Mutate val to add to the result.

The order of the inputs is chosen to follow the element routines

source