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.SimpleIntegrator — TypeSimpleIntegrator(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 face 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 face domains, n is the face normal vector.
It is the user's responsibility that fun(args...)::typeof(val). Additionally, the type of val must support
val + valval * x(wherex::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]/areaIf the buffer is setup to be threaded, this calculation will also be threaded.
Integrator
FerriteAssembly.Integrator — TypeIntegrator(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
Functions to overload
Using the Integrator requires the following functions to be overloaded, depending on the type of domain
FerriteAssembly.integrate_cell! — Functionintegrate_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
FerriteAssembly.integrate_face! — Functionintegrate_face!(val, ae, material, fv, facebuffer)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