diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index 0145042..0ee5c1e 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.10.4","generation_timestamp":"2024-07-18T14:10:01","documenter_version":"1.5.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.10.5","generation_timestamp":"2024-08-28T15:35:31","documenter_version":"1.6.0"}} \ No newline at end of file diff --git a/dev/assets/documenter.js b/dev/assets/documenter.js index b2bdd43..82252a1 100644 --- a/dev/assets/documenter.js +++ b/dev/assets/documenter.js @@ -77,30 +77,35 @@ require(['jquery'], function($) { let timer = 0; var isExpanded = true; -$(document).on("click", ".docstring header", function () { - let articleToggleTitle = "Expand docstring"; - - debounce(() => { - if ($(this).siblings("section").is(":visible")) { - $(this) - .find(".docstring-article-toggle-button") - .removeClass("fa-chevron-down") - .addClass("fa-chevron-right"); - } else { - $(this) - .find(".docstring-article-toggle-button") - .removeClass("fa-chevron-right") - .addClass("fa-chevron-down"); +$(document).on( + "click", + ".docstring .docstring-article-toggle-button", + function () { + let articleToggleTitle = "Expand docstring"; + const parent = $(this).parent(); + + debounce(() => { + if (parent.siblings("section").is(":visible")) { + parent + .find("a.docstring-article-toggle-button") + .removeClass("fa-chevron-down") + .addClass("fa-chevron-right"); + } else { + parent + .find("a.docstring-article-toggle-button") + .removeClass("fa-chevron-right") + .addClass("fa-chevron-down"); - articleToggleTitle = "Collapse docstring"; - } + articleToggleTitle = "Collapse docstring"; + } - $(this) - .find(".docstring-article-toggle-button") - .prop("title", articleToggleTitle); - $(this).siblings("section").slideToggle(); - }); -}); + parent + .children(".docstring-article-toggle-button") + .prop("title", articleToggleTitle); + parent.siblings("section").slideToggle(); + }); + } +); $(document).on("click", ".docs-article-toggle-button", function (event) { let articleToggleTitle = "Expand docstring"; @@ -110,7 +115,7 @@ $(document).on("click", ".docs-article-toggle-button", function (event) { debounce(() => { if (isExpanded) { $(this).removeClass("fa-chevron-up").addClass("fa-chevron-down"); - $(".docstring-article-toggle-button") + $("a.docstring-article-toggle-button") .removeClass("fa-chevron-down") .addClass("fa-chevron-right"); @@ -119,7 +124,7 @@ $(document).on("click", ".docs-article-toggle-button", function (event) { $(".docstring section").slideUp(animationSpeed); } else { $(this).removeClass("fa-chevron-down").addClass("fa-chevron-up"); - $(".docstring-article-toggle-button") + $("a.docstring-article-toggle-button") .removeClass("fa-chevron-right") .addClass("fa-chevron-down"); diff --git a/dev/examples_intro/index.html b/dev/examples_intro/index.html index b1242ce..873c3c2 100644 --- a/dev/examples_intro/index.html +++ b/dev/examples_intro/index.html @@ -1,4 +1,4 @@ Introduction · ExtendableFEMBase.jl

About the examples

The examples have been designed with the following issues in mind:

  • they run from the Julia REPL
  • each example is a Julia module named similar to the basename of the example file.
  • an example can be used as the starting point for a project
  • some examples define test cases for the test suite
  • ExampleXYZ with X = A can be considered advanced and uses low-level structures and/or demonstrates customisation features or experimental features
  • the default output of the main function is printed on the website and can be used to check if the code runs as expected (unfortunately REPL messages are not recorded)
  • printed assembly and solving times (especially in a first iteration) can be much larger due to first-run compilation times

Running the examples

In order to run ExampleXXX, peform the following steps:

  • Download the example file (e.g. via the source code link at the top)
  • Make sure all used packages are installed in your Julia environment
  • In the REPL:
julia> include("ExampleXXX.jl")`
 
-julia> ExampleXXX.main()
  • Some examples offer visual output via the optional argument Plotter = PyPlot or Plotter = GLMakie

(provided the package PyPlot/GLMakie is installed and loaded)

+julia> ExampleXXX.main()

(provided the package PyPlot/GLMakie is installed and loaded)

diff --git a/dev/feevaluator/index.html b/dev/feevaluator/index.html index 3cf8f43..5a4ff99 100644 --- a/dev/feevaluator/index.html +++ b/dev/feevaluator/index.html @@ -1,2 +1,2 @@ -FEEvaluator · ExtendableFEMBase.jl

FEEvaluator

FEEvaluators provide a structure that handles the evaluation of finite element basis functions for a given function operator, quadrature rule and item geometry. It stores the evaluations on the reference geometry (where derivatives are computed by automatic differentiation) and on the current mesh item. The current mesh item can be changed via the update! call.

ExtendableFEMBase.FEEvaluatorMethod
function FEEvaluator(FE::FESpace, operator::AbstractFunctionOperator, qrule::QuadratureRule; T = Float64, AT = ON_CELLS, L2G = nothing)

Constructs a FEEvaluator that handles evaluations of finite element basis function evaluation for the given FESpace, operator at the quadrature points of the given QuadratureRule. It has an update! function to update the evaluation upon entry to a new cell. Evaluations can be accessed via FEEvaluator.cvals[j,k,i] where i is the quadrature point id, k is the local dof number and j is the component.

Note that matrix-valued operators evaluations, e.g. for Gradient, are given as a long vector (in component-wise order).

source
ExtendableFEMBase.eval_febe!Function
	eval_febe!(result, FEBE::FEBasisEvaluator, j::Int, i::Int, offset::Int = 0, factor = 1)

Evaluates the linear combination of the basisfunction with given coefficients at the i-th quadrature point and writes the (possibly vector-valued) evaluation into result (beginning at offset and with the specified factor).

source
ExtendableFEMBase.eval_febe!Function
	eval_febe!(result, FEBE::FEBasisEvaluator, j::Int, i::Int, offset::Int = 0, factor = 1)

Evaluate the j-th basis function of the FEBasisEvaluator at the i-th quadrature point and writes the (possibly vector-valued) evaluation into result (beginning at offset and with the specified factor).

source
+FEEvaluator · ExtendableFEMBase.jl

FEEvaluator

FEEvaluators provide a structure that handles the evaluation of finite element basis functions for a given function operator, quadrature rule and item geometry. It stores the evaluations on the reference geometry (where derivatives are computed by automatic differentiation) and on the current mesh item. The current mesh item can be changed via the update! call.

ExtendableFEMBase.FEEvaluatorMethod
function FEEvaluator(FE::FESpace, operator::AbstractFunctionOperator, qrule::QuadratureRule; T = Float64, AT = ON_CELLS, L2G = nothing)

Constructs a FEEvaluator that handles evaluations of finite element basis function evaluation for the given FESpace, operator at the quadrature points of the given QuadratureRule. It has an update! function to update the evaluation upon entry to a new cell. Evaluations can be accessed via FEEvaluator.cvals[j,k,i] where i is the quadrature point id, k is the local dof number and j is the component.

Note that matrix-valued operators evaluations, e.g. for Gradient, are given as a long vector (in component-wise order).

source
ExtendableFEMBase.eval_febe!Function
	eval_febe!(result, FEBE::FEBasisEvaluator, j::Int, i::Int, offset::Int = 0, factor = 1)

Evaluate the j-th basis function of the FEBasisEvaluator at the i-th quadrature point and writes the (possibly vector-valued) evaluation into result (beginning at offset and with the specified factor).

source
ExtendableFEMBase.eval_febe!Function
	eval_febe!(result, FEBE::FEBasisEvaluator, j::Int, i::Int, offset::Int = 0, factor = 1)

Evaluates the linear combination of the basisfunction with given coefficients at the i-th quadrature point and writes the (possibly vector-valued) evaluation into result (beginning at offset and with the specified factor).

source
diff --git a/dev/fematrix/index.html b/dev/fematrix/index.html index 77fb23c..78ef61b 100644 --- a/dev/fematrix/index.html +++ b/dev/fematrix/index.html @@ -1,63 +1,63 @@ -FEMatrix · ExtendableFEMBase.jl

FEMatrix

A FEMatrix consists of FEMatrixBlocks that share a common ExtendableSparseMatrix. Each block is associated to two FESpaces and can only write into a submatrix of the common sparse matrix specified by offsets.

ExtendableFEMBase.FEMatrixType
struct FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal} <: SparseArrays.AbstractSparseArray{TvM, TiM, 2}

an AbstractMatrix (e.g. an ExtendableSparseMatrix) with an additional layer of several FEMatrixBlock subdivisions each carrying coefficients for their associated pair of FESpaces

source
ExtendableFEMBase.FEMatrixMethod
FEMatrix{TvM,TiM}(FESX, FESY; name = "auto")

Creates FEMatrix with one rectangular block (FESX,FESY) if FESX and FESY are single FESpaces, or a rectangular block matrix with blocks corresponding to the entries of the FESpace vectors FESX and FESY. Optionally a name for the matrix can be given.

source
ExtendableFEMBase.FEMatrixMethod
FEMatrix{TvM,TiM}(name::String, FES::FESpace{TvG,TiG,FETypeX,APTX}) where {TvG,TiG,FETypeX,APTX}

Creates FEMatrix with one square block (FES,FES).

source
ExtendableFEMBase.FEMatrixMethod
FEMatrix{TvM,TiM}(FESX, FESY; name = "auto")

Creates an FEMatrix with blocks coressponding to the ndofs of FESX (rows) and FESY (columns).

source
ExtendableFEMBase.FEMatrixBlockType
struct FEMatrixBlock{TvM, TiM, TvG, TiG, FETypeX, FETypeY, APTX, APTY} <: AbstractArray{TvM, 2}

block of an FEMatrix that carries coefficients for an associated pair of FESpaces and can be assigned as an two-dimensional AbstractArray (getindex, setindex, size)

source
Base.fill!Method
fill!(B::FEMatrixBlock{Tv, Ti}, value)
-

Custom fill function for FEMatrixBlock (only fills the already present nzval in the block, not the complete FEMatrix).

source
Base.lengthMethod
length(
+FEMatrix · ExtendableFEMBase.jl

FEMatrix

A FEMatrix consists of FEMatrixBlocks that share a common ExtendableSparseMatrix. Each block is associated to two FESpaces and can only write into a submatrix of the common sparse matrix specified by offsets.

ExtendableFEMBase.FEMatrixType
struct FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal} <: SparseArrays.AbstractSparseArray{TvM, TiM, 2}

an AbstractMatrix (e.g. an ExtendableSparseMatrix) with an additional layer of several FEMatrixBlock subdivisions each carrying coefficients for their associated pair of FESpaces

source
ExtendableFEMBase.FEMatrixMethod
FEMatrix{TvM,TiM}(FESX, FESY; name = "auto")

Creates FEMatrix with one rectangular block (FESX,FESY) if FESX and FESY are single FESpaces, or a rectangular block matrix with blocks corresponding to the entries of the FESpace vectors FESX and FESY. Optionally a name for the matrix can be given.

source
ExtendableFEMBase.FEMatrixMethod
FEMatrix{TvM,TiM}(name::String, FES::FESpace{TvG,TiG,FETypeX,APTX}) where {TvG,TiG,FETypeX,APTX}

Creates FEMatrix with one square block (FES,FES).

source
ExtendableFEMBase.FEMatrixMethod
FEMatrix{TvM,TiM}(FESX, FESY; name = "auto")

Creates an FEMatrix with blocks coressponding to the ndofs of FESX (rows) and FESY (columns).

source
ExtendableFEMBase.FEMatrixBlockType
struct FEMatrixBlock{TvM, TiM, TvG, TiG, FETypeX, FETypeY, APTX, APTY} <: AbstractArray{TvM, 2}

block of an FEMatrix that carries coefficients for an associated pair of FESpaces and can be assigned as an two-dimensional AbstractArray (getindex, setindex, size)

source
Base.fill!Method
fill!(B::FEMatrixBlock{Tv, Ti}, value)
+

Custom fill function for FEMatrixBlock (only fills the already present nzval in the block, not the complete FEMatrix).

source
Base.lengthMethod
length(
     _::FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}
 ) -> Any
-

Custom length function for FEMatrix that gives the total number of defined FEMatrixBlocks in it

source
Base.showMethod
show(
+

Custom length function for FEMatrix that gives the total number of defined FEMatrixBlocks in it

source
Base.showMethod
show(
     io::IO,
     FEM::FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}
 )
-

Custom show function for FEMatrix that prints some information on its blocks.

source
Base.sizeMethod
size(FEB::FEMatrixBlock) -> Tuple{Int64, Int64}
-

Custom size function for FEMatrixBlock that gives a tuple with the size of the block (that coressponds to the number of degrees of freedoms in X and Y)

source
Base.sizeMethod
size(
+

Custom show function for FEMatrix that prints some information on its blocks.

source
Base.sizeMethod
size(FEB::FEMatrixBlock) -> Tuple{Int64, Int64}
+

Custom size function for FEMatrixBlock that gives a tuple with the size of the block (that coressponds to the number of degrees of freedoms in X and Y)

source
Base.sizeMethod
size(
     _::FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}
 ) -> Tuple{Any, Any}
-

Custom size function for FEMatrix that gives a tuple with the number of rows and columns of the FEBlock overlay

source
ExtendableFEMBase.add!Method
add!(A::FEMatrix{Tv, Ti}, B::FEMatrix{Tv, Ti}; kwargs...)
-

Adds FEMatrix/ExtendableSparseMatrix/CSCMatrix B to FEMatrix A.

source
ExtendableFEMBase.addblock!Method
addblock!(
+

Custom size function for FEMatrix that gives a tuple with the number of rows and columns of the FEBlock overlay

source
ExtendableFEMBase.add!Method
add!(A::FEMatrix{Tv, Ti}, B::FEMatrix{Tv, Ti}; kwargs...)
+

Adds FEMatrix/ExtendableSparseMatrix/CSCMatrix B to FEMatrix A.

source
ExtendableFEMBase.addblock!Method
addblock!(
     A::FEMatrixBlock{Tv, Ti},
     B::FEMatrixBlock{Tv, Ti};
     factor,
     transpose
 )
-

Adds FEMatrixBlock B to FEMatrixBlock A.

source
ExtendableFEMBase.addblock!Method
addblock!(
     A::FEMatrixBlock{Tv},
     B::ExtendableSparse.ExtendableSparseMatrixCSC{Tv, Ti<:Integer};
     factor,
     transpose
 )
-

Adds ExtendableSparseMatrix B to FEMatrixBlock A.

source
ExtendableFEMBase.addblock!Method
addblock!(
     A::FEMatrixBlock{Tv},
     cscmat::SparseArrays.SparseMatrixCSC{Tv, Ti<:Integer};
     factor,
     transpose
 )
-

Adds SparseMatrixCSC B to FEMatrixBlock A.

source
ExtendableFEMBase.addblock_matmul!Method
addblock_matmul!(
     a::AbstractArray{Tv, 1},
     B::FEMatrixBlock{Tv, Ti},
     b::AbstractArray{Tv, 1};
     factor,
     transposed
 )
-

Adds matrix-vector product B times b to FEVectorBlock a.

source
ExtendableFEMBase.addblock_matmul!Method
addblock_matmul!(
     A::FEMatrixBlock{Tv},
     cscmatB::SparseArrays.SparseMatrixCSC{Tv, Ti},
     cscmatC::SparseArrays.SparseMatrixCSC{Tv, Ti};
     factor,
     transposed
 )
-

Adds matrix-matrix product B times C to FEMatrixBlock A.

source
ExtendableFEMBase.addblock_matmul!Method
addblock_matmul!(
     a::FEVectorBlock{Tv},
     B::ExtendableSparse.ExtendableSparseMatrixCSC{Tv, Ti<:Integer},
     b::FEVectorBlock{Tv};
     factor
 )
-

Adds matrix-vector product B times b to FEVectorBlock a.

source
ExtendableFEMBase.addblock_matmul!Method
addblock_matmul!(
     a::FEVectorBlock{Tv},
     B::FEMatrixBlock{Tv, Ti},
     b::FEVectorBlock{Tv};
     factor,
     transposed
 )
-

Adds matrix-vector product B times b (or B' times b if transposed = true) to FEVectorBlock a.

source
ExtendableFEMBase.ldrdmatmulMethod
ldrdmatmul(
     a1::AbstractArray{Tv, 1},
     a2::AbstractArray{Tv, 1},
     B::ExtendableSparse.ExtendableSparseMatrixCSC{Tv, Ti<:Integer},
@@ -65,16 +65,16 @@
     b2::AbstractArray{Tv, 1};
     factor
 ) -> Any
-

Computes vector'-matrix-vector product (a1-a2)'B(b1-b2).

source
ExtendableFEMBase.lrmatmulMethod
lrmatmul(
     a::AbstractArray{Tv, 1},
     B::ExtendableSparse.ExtendableSparseMatrixCSC{Tv, Ti<:Integer},
     b::AbstractArray{Tv, 1};
     factor
 ) -> Any
-

Computes vector'-matrix-vector product a'Bb.

source
ExtendableFEMBase.nbcolsMethod
nbcols(
     _::FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}
 ) -> Any
-

Gives the number of FEMatrixBlocks in each row.

source
ExtendableFEMBase.nbrowsMethod
nbrows(
     _::FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}
 ) -> Any
-

Gives the number of FEMatrixBlocks in each column.

source
+

Gives the number of FEMatrixBlocks in each column.

source
diff --git a/dev/fems/index.html b/dev/fems/index.html index a091a33..57c3d8b 100644 --- a/dev/fems/index.html +++ b/dev/fems/index.html @@ -24,4 +24,4 @@ ├─ HDIVRT0 ├─ HDIVRT1 ├─ HDIVRTk - └─ HDIVRTkENRICH

Remarks

List of implemented Finite Elements

The following table lists all curently implemented finite elements and on which geometries they are available (in brackets a dofmap pattern for CellDofs is shown and the number of local degrees of freedom for a vector-valued realisation). Click on the FEType to find out more details.

FETypeTriangle2DParallelogram2DTetrahedron3DParallelepiped3D
AbstractH1FiniteElementWithCoefficients
H1BR✓ (N1f1, 9)✓ (N1f1, 12)✓ (N1f1, 16)
H1P1TEB✓ (N1f1, 9)✓ (N1e1, 18)
AbstractH1FiniteElement
H1BUBBLE✓ (I1, 2)✓ (I1, 2)✓ (I1, 3)
H1CR✓ (F1, 6)✓ (F1, 8)✓ (F1, 12)
H1MINI✓ (N1I1, 8)✓ (N1I1, 10)✓ (N1I1, 15)
L2P0✓ (I1, 2)✓ (I1, 2)✓ (I1, 3)✓ (I1, 3)
L2P1✓ (I3, 6)✓ (I3, 6)✓ (I4, 12)✓ (I4, 12)
H1P1✓ (N1, 6)✓ (N1, 12)
H1P2✓ (N1F1, 12)✓ (N1E1, 30)
H1P2B✓ (N1F1I1, 14)
H1P3✓ (N1F2I1, 20)✓ (N1E2F1, 60)
H1Pk✓ (order-dep)
H1Q1✓ (N1, 6)✓ (N1, 8)✓ (N1, 12)✓ (N1, 24)
H1Q2✓ (N1F1, 12)✓ (N1F1I1, 18)✓ (N1E1, 30)
AbstractHcurlFiniteElement
HCURLN0✓ (f1, 3)✓ (f1, 4)✓ (e1, 6)
HCURLN1✓ (f1, 6)
AbstractHdivFiniteElement
HDIVBDM1✓ (f2, 6)✓ (f2, 8)✓ (f3, 12)
HDIVBDM2✓ (f3i3, 12)
HDIVRT0✓ (f1, 3)✓ (f1, 4)✓ (f1, 4)✓ (f1, 6)
HDIVRT1✓ (f2i2, 8)✓ (f3i3, 15)
HDIVRTk✓ (order-dep)
HDIVRTkENRICH✓ (order-dep)✓ (order-dep)

Note: the dofmap pattern describes the connection of the local degrees of freedom to entities of the grid and also hints to the continuity. Here, "N" or "n" means nodes, "F" or "f" means faces, "E" or "e" means edges and "I" means interior (dofs without any continuity across elements). Capital letters cause that every component has its own degree of freedom, while small letters signalize that only one dof is associated to the entity. As an example "N1f1" (for the Bernardi-Raugel element) means that at each node sits one dof per component and at each face sits a single dof. Usually finite elements that involve small letters are only defined vector-valued (i.e. the number of components has to match the element dimension), while finite elements that only involve capital letters are available for any number of components.

H1-conforming finite elements

P0 finite element

Piecewise constant finite element that has one degree of freedom on each cell of the grid. (It is masked as a H1-conforming finite element, because it uses the same operator evaulations.)

The interpolation of a given function into this space preserves the cell integrals.

ExtendableFEMBase.L2P0Type
abstract type L2P0{ncomponents} <: AbstractH1FiniteElement where {ncomponents<:Int}

Piecewise constant polynomials on cells.

allowed ElementGeometries:

  • any
source

P1 finite element

The lowest-order Courant finite element that has a degree of freedom on each vertex of the grid. On simplices the basis functions coincide with the linear barycentric coordinates. Only the L2P1 element is also defined on quads.

The interpolation of a given function into this space performs point evaluations at the nodes.

ExtendableFEMBase.L2P1Type
abstract type L2P1{ncomponents} <: AbstractH1FiniteElement where {ncomponents<:Int}

Discontinuous piecewise first-order linear polynomials.

allowed ElementGeometries:

  • any
source
ExtendableFEMBase.H1P1Type
abstract type H1P1{ncomponents} <: AbstractH1FiniteElement where {ncomponents<:Int}

Continuous piecewise first-order linear polynomials.

allowed ElementGeometries:

  • Edge1D
  • Triangle2D
  • Tetrahedron3D
source

Q1 finite element

The lowest-order finite element that has a degree of freedom on each vertex of the grid. On simplices the basis functions coincide with the linear barycentric coordinates. This element is also defined on quads.

The interpolation of a given function into this space performs point evaluations at the nodes.

ExtendableFEMBase.H1Q1Type
abstract type Q1P1{ncomponents} <: AbstractH1FiniteElement where {ncomponents<:Int}

Continuous piecewise first-order polynomials on simplices and quads, can be used for mixed geometries.

allowed ElementGeometries:

  • Edge1D (P1 space)
  • Triangle2D (P1 space)
  • Quadrilateral2D (Q1 space)
  • Tetrahedron3D (P1 space)
  • Hexahedron3D (Q1 space)
source

MINI finite element

The mini finite element adds cell bubles to the P1 element that are e.g. beneficial to define inf-sup stable finite element pairs for the Stokes problem.

The interpolation of a given function into this space performs point evaluations at the nodes and preserves its cell integral.

ExtendableFEMBase.H1MINIType
abstract type H1MINI{ncomponents,edim} <: AbstractH1FiniteElement where {ncomponents<:Int,edim<:Int}

Mini finite element.

allowed element geometries:

  • Triangle2D (linear polynomials + cubic cell bubble)
  • Quadrilateral2D (Q1 space + quartic cell bubble)
  • Tetrahedron3D (linear polynomials + cubic cell bubble)
source

P1TEB finite element

This element adds tangent-weighted edge bubbles to the P1 finite element and therefore is only available as a vector-valued element.

The interpolation of a given function into this space performs point evaluations at the nodes and preserves face integrals of its tangential flux.

ExtendableFEMBase.H1P1TEBType
abstract type H1P1TEB{edim} <: AbstractH1FiniteElementWithCoefficients where {edim<:Int}

vector-valued (ncomponents = edim) element that uses P1 functions + tangential-weighted edge bubbles as suggested by [Diening, L., Storn, J. & Tscherpel, T., "Fortin operator for the Taylor–Hood element", Numer. Math. 150, 671–689 (2022)]

(is inf-sup stable for Stokes if paired with continuous P1 pressure space, less degrees of freedom than MINI)

allowed ElementGeometries:

  • Triangle2D
  • Tetrahedron3D
source

Bernardi-Raugel (BR) finite element

The Bernardi-Raugel adds normal-weighted face bubbles to the P1 finite element and therefore is only available as a vector-valued element.

The interpolation of a given function into this space performs point evaluations at the nodes and preserves face integrals of its normal flux.

ExtendableFEMBase.H1BRType
abstract type H1BR{edim} <: AbstractH1FiniteElementWithCoefficients where {edim<:Int}

vector-valued (ncomponents = edim) Bernardi–Raugel element (first-order polynomials + normal-weighted face bubbles)

allowed ElementGeometries:

  • Triangle2D (piecewise linear + normal-weighted face bubbles)
  • Quadrilateral2D (Q1 space + normal-weighted face bubbles)
  • Tetrahedron3D (piecewise linear + normal-weighted face bubbles)
source

P2 finite element

The P2 finite element method on simplices equals quadratic polynomials. On the Triangle2D shape the degrees of freedom are associated with the three vertices and the three faces of the triangle. On the Tetrahedron3D shape the degrees of freedom are associated with the four verties and the six edges.

The interpolation of a given function into this space performs point evaluations at the nodes and preserves its face/edge integrals in 2D/3D.

ExtendableFEMBase.H1P2Type
abstract type H1P2{ncomponents,edim} <: AbstractH1FiniteElement where {ncomponents<:Int,edim<:Int}

Continuous piecewise second-order polynomials.

allowed ElementGeometries:

  • Edge1D
  • Triangle2D
  • Tetrahedron3D
source

Q2 finite element

A second order finite element. On simplices it equals the P2 finite element, and on Quadrilateral2D it has 9 degrees of freedom (vertices, faces and one cell bubble).

The interpolation of a given function into this space performs point evaluations at the nodes and preserves lowest order face moments and (only on quads) also the cell integreal mean.

ExtendableFEMBase.H1Q2Type
abstract type H1Q2{ncomponents,edim} <: AbstractH1FiniteElement where {ncomponents<:Int,edim<:Int}

Continuous piecewise second-order polynomials on simplices and quads. Can be used with mixed geometries (in 2D).

allowed ElementGeometries:

  • Edge1D (P2 space)
  • Triangle2D (P2 space)
  • Quadrilateral2D (Q2 space with cell bubble)
  • Tetrahedron3D (P2 space)
source

P2B finite element

The P2B finite element adds additional cell bubles (in 2D and 3D) and face bubbles (only in 3D) that are e.g. used to define inf-sup stable finite element pairs for the Stokes problem.

The interpolation of a given function into this space performs point evaluations at the nodes and preserves its cell and face integrals in 2D and also edge integrals in 3D.

ExtendableFEMBase.H1P2BType
abstract type H1P2B{ncomponents,edim} <: AbstractH1FiniteElement where {ncomponents<:Int,edim<:Int}

Continuous piecewise second-order polynomials.

allowed ElementGeometries:

  • Triangle2D
source

P3 finite element

The P3 finite element method on simplices equals cubic polynomials. On the Triangle2D shape the degrees of freedom are associated with the three vertices, the three faces (double dof) of the triangle and the cell itself (one cell bubble).

The interpolation of a given function into this space performs point evaluations at the nodes and preserves cell and face integrals in 2D.

ExtendableFEMBase.H1P3Type
abstract type H1P3{ncomponents,edim} <: AbstractH1FiniteElement where {ncomponents<:Int,edim<:Int}

Continuous piecewise third-order polynomials.

allowed ElementGeometries:

  • Edge1D
  • Triangle2D
  • Tetrahedron3D
source

Pk finite element (experimental)

The Pk finite element method generically generates polynomials of abitrary order k on simplices (Edge1D, Triangle2D so far).

The interpolation of a given function into this space performs point evaluations at the nodes and preserves cell and face integrals in 2D (moment order depends on the order and the element dimension).

ExtendableFEMBase.H1PkType
abstract type H1PK{ncomponents,edim,order} <: AbstractH1FiniteElement where {ncomponents<:Int,edim<:Int,order<:Int}

Continuous piecewise polynomials of arbitrary order >= 1 with ncomponents components in edim space dimensions.

allowed ElementGeometries:

  • Edge1D
  • Triangle2D
source

Crouzeix-Raviart (CR) finite element

The Crouzeix-Raviart element associates one lowest-order function with each face. On the Triangle2D shape, the basis function of a face is one minus two times the nodal basis function of the opposite node.

The interpolation of a given function into this space preserves its face integrals.

ExtendableFEMBase.H1CRType
abstract type H1CR{ncomponents} <: AbstractH1FiniteElement where {ncomponents<:Int}

Crouzeix-Raviart element (only continuous at face centers).

allowed ElementGeometries:

  • Triangle2D (piecewise linear, similar to P1)
  • Quadrilateral2D (similar to Q1 space)
  • Tetrahedron3D (piecewise linear, similar to P1)
source

Hdiv-conforming finite elements

These Raviart-Thomas and Brezzi-Douglas-Marini finite elements of lower order and their standard interpolations are available:

ExtendableFEMBase.HDIVRT0Type
abstract type HDIVRT0{edim} <: AbstractHdivFiniteElement where {edim<:Int}

Hdiv-conforming vector-valued (ncomponents = edim) lowest-order Raviart-Thomas space.

allowed ElementGeometries:

  • Triangle2D
  • Quadrilateral2D
  • Tetrahedron3D
  • Hexahedron3D
source
ExtendableFEMBase.HDIVBDM1Type
abstract type HDIVBDM1{edim} <: AbstractHdivFiniteElement where {edim<:Int}

Hdiv-conforming vector-valued (ncomponents = edim) lowest-order Brezzi-Douglas-Marini space

allowed ElementGeometries:

  • Triangle2D
  • Quadrilateral2D
  • Tetrahedron3D
source
ExtendableFEMBase.HDIVRT1Type
abstract type HDIVRT1{edim} <: AbstractHdivFiniteElement where {edim<:Int}

Hdiv-conforming vector-valued (ncomponents = edim) Raviart-Thomas space of order 1.

allowed ElementGeometries:

  • Triangle2D
  • Tetrahedron3D
source
ExtendableFEMBase.HDIVBDM2Type
abstract type HDIVBDM2{edim} <: AbstractHdivFiniteElement where {edim<:Int}

Hdiv-conforming vector-valued (ncomponents = edim) Brezzi-Douglas-Marini space of order 2

allowed ElementGeometries:

  • Triangle2D
source
ExtendableFEMBase.HDIVRTkType
abstract type HDIVRTk{edim, order} <: AbstractHdivFiniteElement where {edim<:Int}

Hdiv-conforming vector-valued (ncomponents = edim) Raviart-Thomas space of arbitrary order.

allowed ElementGeometries:

  • Triangle2D
source
ExtendableFEMBase.HDIVRTkENRICHType
abstract type HDIVRTkENRICH{k,edim} <: AbstractHdivFiniteElement where {edim<:Int}

Internal (normal-zero) Hdiv-conforming vector-valued (ncomponents = edim) Raviart-Thomas space of order k ≥ 1 with the additional orthogonality property that their divergences are L2-orthogonal on P_{k-edim+1}. Example: HDIVRTkENRICH{1,2} gives the edim interior RT1 bubbles (= normal-trace-free) on a triangle, their divergences have integral mean zero; HDIVRTkENRICH{2,2} gives three RT2 bubbles on a triangle whose divergences are L2-orthogonal onto all P1 functions. The maximal order for k is 4 on a Triangle2D (edim = 2) and 3 on Tetrahedron3D (edim = 3). These spaces have no approximation power on their own, but can be used as enrichment spaces in divergence-free schemes for incompressible Stokes problems.

allowed ElementGeometries:

  • Triangle2D
  • Tetrahedron3D
source

Hcurl-conforming finite elements

So far only the lowest order Nedelec element is available in 2D and 3D. On Triangle2D it has one degree of freedom for each face (i.e. the rotated RT0 element), on Tetrahedron3D it has one degree of freedom associated to each of the six edges.

Its standard interpolation of a given functions preserves its tangential face/edge integrals.

ExtendableFEMBase.HCURLN0Type
abstract type HCURLN0{edim} <: AbstractHcurlFiniteElement where {edim<:Int}

Hcurl-conforming vector-valued (ncomponents = edim) lowest-order Nedelec space of first kind.

allowed ElementGeometries:

  • Triangle2D
  • Quadrilateral2D
  • Tetrahedron3D
source
ExtendableFEMBase.HCURLN1Type
abstract type HCURLN1{edim} <: AbstractHcurlFiniteElement where {edim<:Int}

Hcurl-conforming vector-valued (ncomponents = edim) Nedelec space of first kind and order 1.

allowed ElementGeometries:

  • Triangle2D
source

Incomplete finite elements without approximation power

ExtendableFEMBase.H1BUBBLEType
abstract type H1BUBBLE{ncomponents} <: AbstractH1FiniteElement where {ncomponents<:Int}

Piecewise bubbles (=zero at boundary)

allowed element geometries:

  • Edge1D (one quadratic bubble)
  • Triangle2D (one cubic bubble)
  • Quadrilateral2D (one quartic bubble)
  • Tetrahedron3D (one cubic bubble)
source
+ └─ HDIVRTkENRICH

Remarks

List of implemented Finite Elements

The following table lists all curently implemented finite elements and on which geometries they are available (in brackets a dofmap pattern for CellDofs is shown and the number of local degrees of freedom for a vector-valued realisation). Click on the FEType to find out more details.

FETypeTriangle2DParallelogram2DTetrahedron3DParallelepiped3D
AbstractH1FiniteElementWithCoefficients
H1BR✓ (N1f1, 9)✓ (N1f1, 12)✓ (N1f1, 16)
H1P1TEB✓ (N1f1, 9)✓ (N1e1, 18)
AbstractH1FiniteElement
H1BUBBLE✓ (I1, 2)✓ (I1, 2)✓ (I1, 3)
H1CR✓ (F1, 6)✓ (F1, 8)✓ (F1, 12)
H1MINI✓ (N1I1, 8)✓ (N1I1, 10)✓ (N1I1, 15)
L2P0✓ (I1, 2)✓ (I1, 2)✓ (I1, 3)✓ (I1, 3)
L2P1✓ (I3, 6)✓ (I3, 6)✓ (I4, 12)✓ (I4, 12)
H1P1✓ (N1, 6)✓ (N1, 12)
H1P2✓ (N1F1, 12)✓ (N1E1, 30)
H1P2B✓ (N1F1I1, 14)
H1P3✓ (N1F2I1, 20)✓ (N1E2F1, 60)
H1Pk✓ (order-dep)
H1Q1✓ (N1, 6)✓ (N1, 8)✓ (N1, 12)✓ (N1, 24)
H1Q2✓ (N1F1, 12)✓ (N1F1I1, 18)✓ (N1E1, 30)
AbstractHcurlFiniteElement
HCURLN0✓ (f1, 3)✓ (f1, 4)✓ (e1, 6)
HCURLN1✓ (f1, 6)
AbstractHdivFiniteElement
HDIVBDM1✓ (f2, 6)✓ (f2, 8)✓ (f3, 12)
HDIVBDM2✓ (f3i3, 12)
HDIVRT0✓ (f1, 3)✓ (f1, 4)✓ (f1, 4)✓ (f1, 6)
HDIVRT1✓ (f2i2, 8)✓ (f3i3, 15)
HDIVRTk✓ (order-dep)
HDIVRTkENRICH✓ (order-dep)✓ (order-dep)

Note: the dofmap pattern describes the connection of the local degrees of freedom to entities of the grid and also hints to the continuity. Here, "N" or "n" means nodes, "F" or "f" means faces, "E" or "e" means edges and "I" means interior (dofs without any continuity across elements). Capital letters cause that every component has its own degree of freedom, while small letters signalize that only one dof is associated to the entity. As an example "N1f1" (for the Bernardi-Raugel element) means that at each node sits one dof per component and at each face sits a single dof. Usually finite elements that involve small letters are only defined vector-valued (i.e. the number of components has to match the element dimension), while finite elements that only involve capital letters are available for any number of components.

H1-conforming finite elements

P0 finite element

Piecewise constant finite element that has one degree of freedom on each cell of the grid. (It is masked as a H1-conforming finite element, because it uses the same operator evaulations.)

The interpolation of a given function into this space preserves the cell integrals.

ExtendableFEMBase.L2P0Type
abstract type L2P0{ncomponents} <: AbstractH1FiniteElement where {ncomponents<:Int}

Piecewise constant polynomials on cells.

allowed ElementGeometries:

  • any
source

P1 finite element

The lowest-order Courant finite element that has a degree of freedom on each vertex of the grid. On simplices the basis functions coincide with the linear barycentric coordinates. Only the L2P1 element is also defined on quads.

The interpolation of a given function into this space performs point evaluations at the nodes.

ExtendableFEMBase.L2P1Type
abstract type L2P1{ncomponents} <: AbstractH1FiniteElement where {ncomponents<:Int}

Discontinuous piecewise first-order linear polynomials.

allowed ElementGeometries:

  • any
source
ExtendableFEMBase.H1P1Type
abstract type H1P1{ncomponents} <: AbstractH1FiniteElement where {ncomponents<:Int}

Continuous piecewise first-order linear polynomials.

allowed ElementGeometries:

  • Edge1D
  • Triangle2D
  • Tetrahedron3D
source

Q1 finite element

The lowest-order finite element that has a degree of freedom on each vertex of the grid. On simplices the basis functions coincide with the linear barycentric coordinates. This element is also defined on quads.

The interpolation of a given function into this space performs point evaluations at the nodes.

ExtendableFEMBase.H1Q1Type
abstract type Q1P1{ncomponents} <: AbstractH1FiniteElement where {ncomponents<:Int}

Continuous piecewise first-order polynomials on simplices and quads, can be used for mixed geometries.

allowed ElementGeometries:

  • Edge1D (P1 space)
  • Triangle2D (P1 space)
  • Quadrilateral2D (Q1 space)
  • Tetrahedron3D (P1 space)
  • Hexahedron3D (Q1 space)
source

MINI finite element

The mini finite element adds cell bubles to the P1 element that are e.g. beneficial to define inf-sup stable finite element pairs for the Stokes problem.

The interpolation of a given function into this space performs point evaluations at the nodes and preserves its cell integral.

ExtendableFEMBase.H1MINIType
abstract type H1MINI{ncomponents,edim} <: AbstractH1FiniteElement where {ncomponents<:Int,edim<:Int}

Mini finite element.

allowed element geometries:

  • Triangle2D (linear polynomials + cubic cell bubble)
  • Quadrilateral2D (Q1 space + quartic cell bubble)
  • Tetrahedron3D (linear polynomials + cubic cell bubble)
source

P1TEB finite element

This element adds tangent-weighted edge bubbles to the P1 finite element and therefore is only available as a vector-valued element.

The interpolation of a given function into this space performs point evaluations at the nodes and preserves face integrals of its tangential flux.

ExtendableFEMBase.H1P1TEBType
abstract type H1P1TEB{edim} <: AbstractH1FiniteElementWithCoefficients where {edim<:Int}

vector-valued (ncomponents = edim) element that uses P1 functions + tangential-weighted edge bubbles as suggested by [Diening, L., Storn, J. & Tscherpel, T., "Fortin operator for the Taylor–Hood element", Numer. Math. 150, 671–689 (2022)]

(is inf-sup stable for Stokes if paired with continuous P1 pressure space, less degrees of freedom than MINI)

allowed ElementGeometries:

  • Triangle2D
  • Tetrahedron3D
source

Bernardi-Raugel (BR) finite element

The Bernardi-Raugel adds normal-weighted face bubbles to the P1 finite element and therefore is only available as a vector-valued element.

The interpolation of a given function into this space performs point evaluations at the nodes and preserves face integrals of its normal flux.

ExtendableFEMBase.H1BRType
abstract type H1BR{edim} <: AbstractH1FiniteElementWithCoefficients where {edim<:Int}

vector-valued (ncomponents = edim) Bernardi–Raugel element (first-order polynomials + normal-weighted face bubbles)

allowed ElementGeometries:

  • Triangle2D (piecewise linear + normal-weighted face bubbles)
  • Quadrilateral2D (Q1 space + normal-weighted face bubbles)
  • Tetrahedron3D (piecewise linear + normal-weighted face bubbles)
source

P2 finite element

The P2 finite element method on simplices equals quadratic polynomials. On the Triangle2D shape the degrees of freedom are associated with the three vertices and the three faces of the triangle. On the Tetrahedron3D shape the degrees of freedom are associated with the four verties and the six edges.

The interpolation of a given function into this space performs point evaluations at the nodes and preserves its face/edge integrals in 2D/3D.

ExtendableFEMBase.H1P2Type
abstract type H1P2{ncomponents,edim} <: AbstractH1FiniteElement where {ncomponents<:Int,edim<:Int}

Continuous piecewise second-order polynomials.

allowed ElementGeometries:

  • Edge1D
  • Triangle2D
  • Tetrahedron3D
source

Q2 finite element

A second order finite element. On simplices it equals the P2 finite element, and on Quadrilateral2D it has 9 degrees of freedom (vertices, faces and one cell bubble).

The interpolation of a given function into this space performs point evaluations at the nodes and preserves lowest order face moments and (only on quads) also the cell integreal mean.

ExtendableFEMBase.H1Q2Type
abstract type H1Q2{ncomponents,edim} <: AbstractH1FiniteElement where {ncomponents<:Int,edim<:Int}

Continuous piecewise second-order polynomials on simplices and quads. Can be used with mixed geometries (in 2D).

allowed ElementGeometries:

  • Edge1D (P2 space)
  • Triangle2D (P2 space)
  • Quadrilateral2D (Q2 space with cell bubble)
  • Tetrahedron3D (P2 space)
source

P2B finite element

The P2B finite element adds additional cell bubles (in 2D and 3D) and face bubbles (only in 3D) that are e.g. used to define inf-sup stable finite element pairs for the Stokes problem.

The interpolation of a given function into this space performs point evaluations at the nodes and preserves its cell and face integrals in 2D and also edge integrals in 3D.

ExtendableFEMBase.H1P2BType
abstract type H1P2B{ncomponents,edim} <: AbstractH1FiniteElement where {ncomponents<:Int,edim<:Int}

Continuous piecewise second-order polynomials.

allowed ElementGeometries:

  • Triangle2D
source

P3 finite element

The P3 finite element method on simplices equals cubic polynomials. On the Triangle2D shape the degrees of freedom are associated with the three vertices, the three faces (double dof) of the triangle and the cell itself (one cell bubble).

The interpolation of a given function into this space performs point evaluations at the nodes and preserves cell and face integrals in 2D.

ExtendableFEMBase.H1P3Type
abstract type H1P3{ncomponents,edim} <: AbstractH1FiniteElement where {ncomponents<:Int,edim<:Int}

Continuous piecewise third-order polynomials.

allowed ElementGeometries:

  • Edge1D
  • Triangle2D
  • Tetrahedron3D
source

Pk finite element (experimental)

The Pk finite element method generically generates polynomials of abitrary order k on simplices (Edge1D, Triangle2D so far).

The interpolation of a given function into this space performs point evaluations at the nodes and preserves cell and face integrals in 2D (moment order depends on the order and the element dimension).

ExtendableFEMBase.H1PkType
abstract type H1PK{ncomponents,edim,order} <: AbstractH1FiniteElement where {ncomponents<:Int,edim<:Int,order<:Int}

Continuous piecewise polynomials of arbitrary order >= 1 with ncomponents components in edim space dimensions.

allowed ElementGeometries:

  • Edge1D
  • Triangle2D
source

Crouzeix-Raviart (CR) finite element

The Crouzeix-Raviart element associates one lowest-order function with each face. On the Triangle2D shape, the basis function of a face is one minus two times the nodal basis function of the opposite node.

The interpolation of a given function into this space preserves its face integrals.

ExtendableFEMBase.H1CRType
abstract type H1CR{ncomponents} <: AbstractH1FiniteElement where {ncomponents<:Int}

Crouzeix-Raviart element (only continuous at face centers).

allowed ElementGeometries:

  • Triangle2D (piecewise linear, similar to P1)
  • Quadrilateral2D (similar to Q1 space)
  • Tetrahedron3D (piecewise linear, similar to P1)
source

Hdiv-conforming finite elements

These Raviart-Thomas and Brezzi-Douglas-Marini finite elements of lower order and their standard interpolations are available:

ExtendableFEMBase.HDIVRT0Type
abstract type HDIVRT0{edim} <: AbstractHdivFiniteElement where {edim<:Int}

Hdiv-conforming vector-valued (ncomponents = edim) lowest-order Raviart-Thomas space.

allowed ElementGeometries:

  • Triangle2D
  • Quadrilateral2D
  • Tetrahedron3D
  • Hexahedron3D
source
ExtendableFEMBase.HDIVBDM1Type
abstract type HDIVBDM1{edim} <: AbstractHdivFiniteElement where {edim<:Int}

Hdiv-conforming vector-valued (ncomponents = edim) lowest-order Brezzi-Douglas-Marini space

allowed ElementGeometries:

  • Triangle2D
  • Quadrilateral2D
  • Tetrahedron3D
source
ExtendableFEMBase.HDIVRT1Type
abstract type HDIVRT1{edim} <: AbstractHdivFiniteElement where {edim<:Int}

Hdiv-conforming vector-valued (ncomponents = edim) Raviart-Thomas space of order 1.

allowed ElementGeometries:

  • Triangle2D
  • Tetrahedron3D
source
ExtendableFEMBase.HDIVBDM2Type
abstract type HDIVBDM2{edim} <: AbstractHdivFiniteElement where {edim<:Int}

Hdiv-conforming vector-valued (ncomponents = edim) Brezzi-Douglas-Marini space of order 2

allowed ElementGeometries:

  • Triangle2D
source
ExtendableFEMBase.HDIVRTkType
abstract type HDIVRTk{edim, order} <: AbstractHdivFiniteElement where {edim<:Int}

Hdiv-conforming vector-valued (ncomponents = edim) Raviart-Thomas space of arbitrary order.

allowed ElementGeometries:

  • Triangle2D
source
ExtendableFEMBase.HDIVRTkENRICHType
abstract type HDIVRTkENRICH{k,edim} <: AbstractHdivFiniteElement where {edim<:Int}

Internal (normal-zero) Hdiv-conforming vector-valued (ncomponents = edim) Raviart-Thomas space of order k ≥ 1 with the additional orthogonality property that their divergences are L2-orthogonal on P_{k-edim+1}. Example: HDIVRTkENRICH{1,2} gives the edim interior RT1 bubbles (= normal-trace-free) on a triangle, their divergences have integral mean zero; HDIVRTkENRICH{2,2} gives three RT2 bubbles on a triangle whose divergences are L2-orthogonal onto all P1 functions. The maximal order for k is 4 on a Triangle2D (edim = 2) and 3 on Tetrahedron3D (edim = 3). These spaces have no approximation power on their own, but can be used as enrichment spaces in divergence-free schemes for incompressible Stokes problems.

allowed ElementGeometries:

  • Triangle2D
  • Tetrahedron3D
source

Hcurl-conforming finite elements

So far only the lowest order Nedelec element is available in 2D and 3D. On Triangle2D it has one degree of freedom for each face (i.e. the rotated RT0 element), on Tetrahedron3D it has one degree of freedom associated to each of the six edges.

Its standard interpolation of a given functions preserves its tangential face/edge integrals.

ExtendableFEMBase.HCURLN0Type
abstract type HCURLN0{edim} <: AbstractHcurlFiniteElement where {edim<:Int}

Hcurl-conforming vector-valued (ncomponents = edim) lowest-order Nedelec space of first kind.

allowed ElementGeometries:

  • Triangle2D
  • Quadrilateral2D
  • Tetrahedron3D
source
ExtendableFEMBase.HCURLN1Type
abstract type HCURLN1{edim} <: AbstractHcurlFiniteElement where {edim<:Int}

Hcurl-conforming vector-valued (ncomponents = edim) Nedelec space of first kind and order 1.

allowed ElementGeometries:

  • Triangle2D
source

Incomplete finite elements without approximation power

ExtendableFEMBase.H1BUBBLEType
abstract type H1BUBBLE{ncomponents} <: AbstractH1FiniteElement where {ncomponents<:Int}

Piecewise bubbles (=zero at boundary)

allowed element geometries:

  • Edge1D (one quadratic bubble)
  • Triangle2D (one cubic bubble)
  • Quadrilateral2D (one quartic bubble)
  • Tetrahedron3D (one cubic bubble)
source
diff --git a/dev/fespace/index.html b/dev/fespace/index.html index 8baeaa3..21cc695 100644 --- a/dev/fespace/index.html +++ b/dev/fespace/index.html @@ -1,5 +1,5 @@ -FESpace · ExtendableFEMBase.jl

FESpace

To generate a finite element space only a finite element type and a grid is needed, dofmaps are generated automatically on their first demand.

ExtendableFEMBase.FESpaceType
struct FESpace{Tv, Ti, FEType<:AbstractFiniteElement,AT<:AssemblyType}
+FESpace · ExtendableFEMBase.jl

FESpace

To generate a finite element space only a finite element type and a grid is needed, dofmaps are generated automatically on their first demand.

ExtendableFEMBase.FESpaceType
struct FESpace{Tv, Ti, FEType<:AbstractFiniteElement,AT<:AssemblyType}
 	name::String                          # full name of finite element space (used in messages)
 	broken::Bool                          # if true, broken dofmaps are generated
 	ndofs::Int                            # total number of dofs
@@ -7,23 +7,23 @@
 	xgrid::ExtendableGrid[Tv,Ti}          # link to xgrid 
 	dofgrid::ExtendableGrid{Tv,Ti}	      # link to (sub) grid used for dof numbering (expected to be equal to or child grid of xgrid)
 	dofmaps::Dict{Type{<:AbstractGridComponent},Any} # backpack with dofmaps
-end

A struct that has a finite element type as parameter and carries dofmaps (CellDofs, FaceDofs, BFaceDofs) plus additional grid information and access to arrays holding coefficients if needed.

source
ExtendableFEMBase.FESpaceMethod
function FESpace{FEType<:AbstractFiniteElement,AT<:AssemblyType}(
+end

A struct that has a finite element type as parameter and carries dofmaps (CellDofs, FaceDofs, BFaceDofs) plus additional grid information and access to arrays holding coefficients if needed.

source
ExtendableFEMBase.FESpaceMethod
function FESpace{FEType<:AbstractFiniteElement,AT<:AssemblyType}(
 	xgrid::ExtendableGrid{Tv,Ti};
 	name = "",
-	broken::Bool = false)

Constructor for FESpace of the given FEType, AT = ONCELLS/ONFACES/ONEDGES generates a finite elements space on the cells/faces/edges of the provided xgrid (if omitted ONCELLS is used as default). The broken switch allows to generate a broken finite element space (that is piecewise H1/Hdiv/HCurl). If no name is provided it is generated automatically from FEType. If no AT is provided, the space is generated ON_CELLS.

source
Base.eltypeMethod
eltype(
+	broken::Bool = false)

Constructor for FESpace of the given FEType, AT = ONCELLS/ONFACES/ONEDGES generates a finite elements space on the cells/faces/edges of the provided xgrid (if omitted ONCELLS is used as default). The broken switch allows to generate a broken finite element space (that is piecewise H1/Hdiv/HCurl). If no name is provided it is generated automatically from FEType. If no AT is provided, the space is generated ON_CELLS.

source
Base.eltypeMethod
eltype(
     _::FESpace{Tv, Ti, FEType<:AbstractFiniteElement, APT}
 ) -> Type{FEType} where FEType<:AbstractFiniteElement
-

Custom eltype function for FESpace returns the finite element type parameter of the finite element space.

source
Base.get!Method
get!(FES::FESpace, DM::Type{<:DofMap}) -> Any
-

To be called by getindex. This triggers lazy creation of non-existing dofmaps

source
Base.getindexMethod
Base.getindex(FES::FESpace,DM::Type{<:DofMap})

Generic method for obtaining dofmap. This method is mutating in the sense that non-existing dofmaps are created on demand. Due to the fact that components are stored as Any the return value triggers type instability.

source
Base.setindex!Method
setindex!(FES::FESpace, v, DM::Type{<:DofMap}) -> Any
-

Set new dofmap

source
Base.showMethod
show(
+

Custom eltype function for FESpace returns the finite element type parameter of the finite element space.

source
Base.get!Method
get!(FES::FESpace, DM::Type{<:DofMap}) -> Any
+

To be called by getindex. This triggers lazy creation of non-existing dofmaps

source
Base.getindexMethod
Base.getindex(FES::FESpace,DM::Type{<:DofMap})

Generic method for obtaining dofmap. This method is mutating in the sense that non-existing dofmaps are created on demand. Due to the fact that components are stored as Any the return value triggers type instability.

source
Base.setindex!Method
setindex!(FES::FESpace, v, DM::Type{<:DofMap}) -> Any
+

Set new dofmap

source
Base.showMethod
show(
     io::IO,
     FES::FESpace{Tv, Ti, FEType<:AbstractFiniteElement, APT}
 )
-

Custom show function for FESpace that prints some information and all available dofmaps.

source
ExtendableFEMBase.assemblytypeMethod
assemblytype(
     _::FESpace{Tv, Ti, FEType<:AbstractFiniteElement, APT}
 ) -> Any
-

returns the assembly type parameter of the finite element space, i.e. on which entities of the grid the finite element is defined.

source
ExtendableFEMBase.ndofsMethod
ndofs(FES::FESpace) -> Int64
-

returns the total number of degrees of freedom of the finite element space.

source

DofMaps

ExtendableFEMBase.DofMapType
abstract type DofMap <: ExtendableGrids.AbstractGridAdjacency

Dofmaps are stored as an ExtendableGrids.AbstractGridAdjacency in the finite element space and collect information with respect to different AssemblyTypes. They are generated automatically on demand and the dofmaps associated to each subtype can be accessed via FESpace[DofMap].

source

The following DofMap subtypes are available and are used as keys to access the dofmap via FESpace[DofMap] (which is equivalent to FESpace.dofmaps[DofMap]).

DofMapExplanation
CellDofsdegrees of freedom for on each cell
FaceDofsdegrees of freedom for each face
EdgeDofsdegrees of freedom for each edge (in 3D)
BFaceDofsdegrees of freedom for each boundary face
BEdgeDofsdegrees of freedom for each boundary edge (in 3D)
+

returns the assembly type parameter of the finite element space, i.e. on which entities of the grid the finite element is defined.

source
ExtendableFEMBase.ndofsMethod
ndofs(FES::FESpace) -> Int64
+

returns the total number of degrees of freedom of the finite element space.

source

DofMaps

ExtendableFEMBase.DofMapType
abstract type DofMap <: ExtendableGrids.AbstractGridAdjacency

Dofmaps are stored as an ExtendableGrids.AbstractGridAdjacency in the finite element space and collect information with respect to different AssemblyTypes. They are generated automatically on demand and the dofmaps associated to each subtype can be accessed via FESpace[DofMap].

source

The following DofMap subtypes are available and are used as keys to access the dofmap via FESpace[DofMap] (which is equivalent to FESpace.dofmaps[DofMap]).

DofMapExplanation
CellDofsdegrees of freedom for on each cell
FaceDofsdegrees of freedom for each face
EdgeDofsdegrees of freedom for each edge (in 3D)
BFaceDofsdegrees of freedom for each boundary face
BEdgeDofsdegrees of freedom for each boundary edge (in 3D)
diff --git a/dev/fevector/index.html b/dev/fevector/index.html index 6493bec..4262eb9 100644 --- a/dev/fevector/index.html +++ b/dev/fevector/index.html @@ -1,23 +1,23 @@ -FEVector · ExtendableFEMBase.jl

FEVector

A FEVector consists of FEVectorBlocks that share a common one-dimensional array. Each block is associated to a FESpace and can only write into a region of the common array specified by offsets that stores the degrees of freedom of that FEspace.

ExtendableFEMBase.FEVectorType
struct FEVector{T, Tv, Ti}

a plain array but with an additional layer of several FEVectorBlock subdivisions each carrying coefficients for their associated FESpace. The j-th block can be accessed by getindex(::FEVector, j) or by getindex(::FEVector, tag) if tags are associated. The full vector can be accessed via FEVector.entries

source
ExtendableFEMBase.FEVectorMethod
FEVector{T}(FES; name = nothing, tags = nothing, kwargs...) where T <: Real

Creates FEVector that has one block if FES is a single FESpace, and a blockwise FEVector if FES is a vector of FESpaces. Optionally a name for the vector (as a String) or each of the blocks (as a vector of Strings), or tags (as an Array{Any}) for the blocks can be specified.

source
ExtendableFEMBase.FEVectorBlockType
struct FEVectorBlock{T, Tv, Ti, FEType, APT} <: AbstractArray{T, 1}

block of an FEVector that carries coefficients for an associated FESpace and can be assigned as an AbstractArray (getindex, setindex, size, length)

source
Base.append!Method
append!(
+FEVector · ExtendableFEMBase.jl

FEVector

A FEVector consists of FEVectorBlocks that share a common one-dimensional array. Each block is associated to a FESpace and can only write into a region of the common array specified by offsets that stores the degrees of freedom of that FEspace.

ExtendableFEMBase.FEVectorType
struct FEVector{T, Tv, Ti}

a plain array but with an additional layer of several FEVectorBlock subdivisions each carrying coefficients for their associated FESpace. The j-th block can be accessed by getindex(::FEVector, j) or by getindex(::FEVector, tag) if tags are associated. The full vector can be accessed via FEVector.entries

source
ExtendableFEMBase.FEVectorMethod
FEVector{T}(FES; name = nothing, tags = nothing, kwargs...) where T <: Real

Creates FEVector that has one block if FES is a single FESpace, and a blockwise FEVector if FES is a vector of FESpaces. Optionally a name for the vector (as a String) or each of the blocks (as a vector of Strings), or tags (as an Array{Any}) for the blocks can be specified.

source
ExtendableFEMBase.FEVectorBlockType
struct FEVectorBlock{T, Tv, Ti, FEType, APT} <: AbstractArray{T, 1}

block of an FEVector that carries coefficients for an associated FESpace and can be assigned as an AbstractArray (getindex, setindex, size, length)

source
Base.append!Method
append!(
     FEF::FEVector{T},
     FES::FESpace{Tv, Ti, FEType, APT};
     name,
     tag
 ) -> Int64
-

Overloaded append function for FEVector that adds a FEVectorBlock at the end.

source
Base.fill!Method
fill!(b::FEVectorBlock, value)
-

Overloaded fill function for FEVectorBlock (only fills the block, not the complete FEVector).

source
Base.lengthMethod
length(FEB::FEVectorBlock) -> Int64
-

Custom length function for FEVectorBlock that gives the coressponding number of degrees of freedoms of the associated FESpace

source
Base.lengthMethod
length(FEF::FEVector) -> Int64
-

Custom length function for FEVector that gives the number of defined FEMatrixBlocks in it

source
Base.showMethod
show(io::IO, FEF::FEVector)
-

Custom show function for FEVector that prints some information on its blocks.

source
Base.viewMethod

returns a view of the part of the full FEVector that coressponds to the block.

source
Base.fill!Method
fill!(b::FEVectorBlock, value)
+

Overloaded fill function for FEVectorBlock (only fills the block, not the complete FEVector).

source
Base.lengthMethod
length(FEB::FEVectorBlock) -> Int64
+

Custom length function for FEVectorBlock that gives the coressponding number of degrees of freedoms of the associated FESpace

source
Base.lengthMethod
length(FEF::FEVector) -> Int64
+

Custom length function for FEVector that gives the number of defined FEMatrixBlocks in it

source
Base.showMethod
show(io::IO, FEF::FEVector)
+

Custom show function for FEVector that prints some information on its blocks.

source
Base.viewMethod

returns a view of the part of the full FEVector that coressponds to the block.

source
ExtendableFEMBase.FESpacesMethod
FESpaces(
     FEV::FEVector{T, Tv, Ti}
 ) -> Vector{T} where T<:FESpace
-

Returns the vector of FEspaces for the blocks of the given FEVector.

source
LinearAlgebra.dotMethod
dot(a::FEVectorBlock{T}, b::FEVectorBlock{T}) -> Any
-

Scalar product between two FEVEctorBlocks

source
+

Adds Array b to FEVectorBlock a.

source
LinearAlgebra.dotMethod
dot(a::FEVectorBlock{T}, b::FEVectorBlock{T}) -> Any
+

Scalar product between two FEVEctorBlocks

source
diff --git a/dev/functionoperators/index.html b/dev/functionoperators/index.html index b6f2e9d..bc1698e 100644 --- a/dev/functionoperators/index.html +++ b/dev/functionoperators/index.html @@ -1,2 +1,2 @@ -Function Operators · ExtendableFEMBase.jl

Function Operators

StandardFunctionOperators

StandardFunctionOperators are abstract types that encode primitive (linear) operators (like Identity, Gradient etc.) used to dispatch different evaluations of finite element basis functions.

List of primitive operators

StandardFunctionOperatorDescriptionMathematically
Identityidentity$v \rightarrow v$
IdentityComponent{c}identity of c-th component$v \rightarrow v_c$
NormalFluxnormal flux (function times normal)$v \rightarrow v \cdot \vec{n}$ (only ON_FACES)
TangentFluxtangent flux (function times tangent)$v \rightarrow v \cdot \vec{t}$ (only ON_EDGES)
Gradientgradient/Jacobian (as a vector)$v \rightarrow \nabla v$
SymmetricGradientsymmetric part of the gradient$v \rightarrow Voigt(\mathrm{sym}(\nabla v))$
Divergencedivergence$v \rightarrow \mathrm{div}(v) = \nabla \cdot v$
CurlScalarcurl operator 1D to 2D (rotated gradient)$v \rightarrow [-dv/dx_2,dv/dx_1]$
Curl2Dcurl operator 2D to 1D$v \rightarrow dv_1/dx_2 - dv_2/dx_1$
Curl3Dcurl operator 3D to 3D$v \rightarrow \nabla \times v$
HessianHesse matrix = all 2nd order derivatives (as a vector)$v \rightarrow D^2 v$ (e.g. in 2D: xx,xy,yx,yy for each component)
SymmetricHessian{a}symmetric part of Hesse matrix, offdiagonals scaled by a$v \rightarrow sym(D^2 v)$ (e.g. in 2D: xx,yy,a*xy for each component)
LaplacianLaplace Operator (diagonal of Hessian)$v \rightarrow \Delta v$ (e.g. in 2D: xx,yy for each component)
Note

As each finite element type is transformed differently from the reference domain to the general domain, the evaluation of each function operator has to be implemented for each finite element class. Currently, not every function operator works in any dimension and for any finite element. More evaluations are added as soon as they are needed (and possibly upon request). Also, the function operators can be combined with user-defined actions to evaluate other operators that can be build from the ones available (e.g. the deviator).

ReconstructionOperators

There are special operators that allow to evaluate a primitive operator of some discrete reconstructed version of a testfunction.

ExtendableFEMBase.ReconstructType
abstract type Reconstruct{FETypeR, O} <: ExtendableFEMBase.ReconstructionOperator

reconstruction operator: evaluates a reconstructed version of the finite element function.

FETypeR specifies the reconstruction space (needs to be defined for the finite element that it is applied to). O specifies the StandardFunctionOperator that shall be evaluated.

source

Divergence-free reconstruction operators

For gradient-robust discretisations of certain classical non divergence-conforming ansatz spaces, reconstruction operators are available that map a discretely divergence-free H1 function to a pointwise divergence-free Hdiv function. So far such operators are available for the vector-valued Crouzeix-Raviart (H1CR) and Bernardi–Raugel (H1BR) finite element types, as well as for the P2-bubble (H1P2B) finite element type in two dimensions.

Example: Reconst{HDIVRT0{d}, Identity} gives the reconstruction of the Identity operator into HDIVRT0 (and is available for H1BR{d} and H1CR{d} for d = 1,2)

Operator Pairs (experimental)

Two function operators can be put into an OperatorPair so that one can provide effectively two operators in each argument of an assembly pattern. However, the user should make sure that both operators can be evaluated together reasonably (meaning both should be well-defined on the element geometries and the finite element space where the argument will be evaluated, and the action of the operator has to operate with coressponding input and result fields). This feature is still experimental and might have issues in some cases. OperatorTriple for a combination of three operators is also available.

ExtendableFEMBase.OperatorPairType
abstract type OperatorPair{<:StandardFunctionOperator,<:StandardFunctionOperator} <: StandardFunctionOperator

allows to evaluate two operators in place of one, e.g. OperatorPair{Identity,Gradient}.

source
ExtendableFEMBase.OperatorTripleType
abstract type OperatorTriple{<:StandardFunctionOperator,<:StandardFunctionOperator} <: StandardFunctionOperator

allows to evaluate three operators in place of one, e.g. OperatorTriple{Identity,Gradient,Hessian}.

source
+Function Operators · ExtendableFEMBase.jl

Function Operators

StandardFunctionOperators

StandardFunctionOperators are abstract types that encode primitive (linear) operators (like Identity, Gradient etc.) used to dispatch different evaluations of finite element basis functions.

List of primitive operators

StandardFunctionOperatorDescriptionMathematically
Identityidentity$v \rightarrow v$
IdentityComponent{c}identity of c-th component$v \rightarrow v_c$
NormalFluxnormal flux (function times normal)$v \rightarrow v \cdot \vec{n}$ (only ON_FACES)
TangentFluxtangent flux (function times tangent)$v \rightarrow v \cdot \vec{t}$ (only ON_EDGES)
Gradientgradient/Jacobian (as a vector)$v \rightarrow \nabla v$
SymmetricGradientsymmetric part of the gradient$v \rightarrow Voigt(\mathrm{sym}(\nabla v))$
Divergencedivergence$v \rightarrow \mathrm{div}(v) = \nabla \cdot v$
CurlScalarcurl operator 1D to 2D (rotated gradient)$v \rightarrow [-dv/dx_2,dv/dx_1]$
Curl2Dcurl operator 2D to 1D$v \rightarrow dv_1/dx_2 - dv_2/dx_1$
Curl3Dcurl operator 3D to 3D$v \rightarrow \nabla \times v$
HessianHesse matrix = all 2nd order derivatives (as a vector)$v \rightarrow D^2 v$ (e.g. in 2D: xx,xy,yx,yy for each component)
SymmetricHessian{a}symmetric part of Hesse matrix, offdiagonals scaled by a$v \rightarrow sym(D^2 v)$ (e.g. in 2D: xx,yy,a*xy for each component)
LaplacianLaplace Operator (diagonal of Hessian)$v \rightarrow \Delta v$ (e.g. in 2D: xx,yy for each component)
Note

As each finite element type is transformed differently from the reference domain to the general domain, the evaluation of each function operator has to be implemented for each finite element class. Currently, not every function operator works in any dimension and for any finite element. More evaluations are added as soon as they are needed (and possibly upon request). Also, the function operators can be combined with user-defined actions to evaluate other operators that can be build from the ones available (e.g. the deviator).

ReconstructionOperators

There are special operators that allow to evaluate a primitive operator of some discrete reconstructed version of a testfunction.

ExtendableFEMBase.ReconstructType
abstract type Reconstruct{FETypeR, O} <: ExtendableFEMBase.ReconstructionOperator

reconstruction operator: evaluates a reconstructed version of the finite element function.

FETypeR specifies the reconstruction space (needs to be defined for the finite element that it is applied to). O specifies the StandardFunctionOperator that shall be evaluated.

source

Divergence-free reconstruction operators

For gradient-robust discretisations of certain classical non divergence-conforming ansatz spaces, reconstruction operators are available that map a discretely divergence-free H1 function to a pointwise divergence-free Hdiv function. So far such operators are available for the vector-valued Crouzeix-Raviart (H1CR) and Bernardi–Raugel (H1BR) finite element types, as well as for the P2-bubble (H1P2B) finite element type in two dimensions.

Example: Reconst{HDIVRT0{d}, Identity} gives the reconstruction of the Identity operator into HDIVRT0 (and is available for H1BR{d} and H1CR{d} for d = 1,2)

Operator Pairs (experimental)

Two function operators can be put into an OperatorPair so that one can provide effectively two operators in each argument of an assembly pattern. However, the user should make sure that both operators can be evaluated together reasonably (meaning both should be well-defined on the element geometries and the finite element space where the argument will be evaluated, and the action of the operator has to operate with coressponding input and result fields). This feature is still experimental and might have issues in some cases. OperatorTriple for a combination of three operators is also available.

ExtendableFEMBase.OperatorPairType
abstract type OperatorPair{<:StandardFunctionOperator,<:StandardFunctionOperator} <: StandardFunctionOperator

allows to evaluate two operators in place of one, e.g. OperatorPair{Identity,Gradient}.

source
ExtendableFEMBase.OperatorTripleType
abstract type OperatorTriple{<:StandardFunctionOperator,<:StandardFunctionOperator} <: StandardFunctionOperator

allows to evaluate three operators in place of one, e.g. OperatorTriple{Identity,Gradient,Hessian}.

source
diff --git a/dev/index.html b/dev/index.html index 31203dd..30e75ad 100644 --- a/dev/index.html +++ b/dev/index.html @@ -1,2 +1,2 @@ -Home · ExtendableFEMBase.jl
+Home · ExtendableFEMBase.jl
diff --git a/dev/interpolations/index.html b/dev/interpolations/index.html index 4dbf366..2366a44 100644 --- a/dev/interpolations/index.html +++ b/dev/interpolations/index.html @@ -1,5 +1,5 @@ -Finite Element Interpolations · ExtendableFEMBase.jl

Finite Element Interpolations

Source functions and QPInfo

The functions that can be interpolated with the methods below are expected to have a certain interface, i.e.:

function f!(result, qpinfo) end

The qpinfo argument communicates vast information of the current quadrature point:

qpinfo childTypeDescription
qpinfo.xVector{Real}space coordinates of quadrature point
qpinfo.timeRealcurrent time
qpinfo.itemIntegercurrent item that contains qpinfo.x
qpinfo.regionIntegerregion number of item
qpinfo.xrefVector{Real}reference coordinates within item of qpinfo.x
qpinfo.volumeRealvolume of item
qpinfo.paramsVector{Any}parameters that can be transfered via keyword arguments

Standard Interpolations

Each finite element has its standard interpolator that can be applied to some user-defined DataFunction. Instead of interpolating on the full cells, the interpolation can be restricted to faces or edges.

It is also possible to interpolate finite element functions on one grid onto a finite element function on another grid (experimental feature, does not work for all finite elements yet and shall be extended to interpolations of operator evaluations as well in future).

ExtendableGrids.interpolate!Function
function ExtendableGrids.interpolate!(target::FEVectorBlock,
+Finite Element Interpolations · ExtendableFEMBase.jl

Finite Element Interpolations

Source functions and QPInfo

The functions that can be interpolated with the methods below are expected to have a certain interface, i.e.:

function f!(result, qpinfo) end

The qpinfo argument communicates vast information of the current quadrature point:

qpinfo childTypeDescription
qpinfo.xVector{Real}space coordinates of quadrature point
qpinfo.timeRealcurrent time
qpinfo.itemIntegercurrent item that contains qpinfo.x
qpinfo.regionIntegerregion number of item
qpinfo.xrefVector{Real}reference coordinates within item of qpinfo.x
qpinfo.volumeRealvolume of item
qpinfo.paramsVector{Any}parameters that can be transfered via keyword arguments

Standard Interpolations

Each finite element has its standard interpolator that can be applied to some user-defined DataFunction. Instead of interpolating on the full cells, the interpolation can be restricted to faces or edges.

It is also possible to interpolate finite element functions on one grid onto a finite element function on another grid (experimental feature, does not work for all finite elements yet and shall be extended to interpolations of operator evaluations as well in future).

ExtendableGrids.interpolate!Function
function ExtendableGrids.interpolate!(target::FEVectorBlock,
 	 AT::Type{<:AssemblyType},
 	 source!::Function;
 	 items = [],
@@ -10,7 +10,7 @@
 	 items = [],
 	 bonus_quadorder = 0,
 	 time = 0,
-	 kwargs...)

Interpolates the given source function into the finite element space assigned to the target FEVectorBlock.

The source functions should adhere to the interface

	source!(result, qpinfo)

The qpinfo argument communicates vast information of the current quadrature/evaluation point.

The bonus_quadorder argument can be used to steer the quadrature order of integrals that needs to be computed for the interpolation (the default quadrature order corressponds to the polynomial order of the finite element).

source

Nodal Evaluations

Usually, Plotters need nodal values, so there is a gengeric function that evaluates any finite element function at the nodes of the grids (possibly by averaging if discontinuous). In case of Identity evaluations of an H1-conforming finite element, the function nodevalues_view can generate a view into the coefficient field that avoids further allocations.

ExtendableFEMBase.nodevalues!Function
function nodevalues!(
+	 kwargs...)

Interpolates the given source function into the finite element space assigned to the target FEVectorBlock.

The source functions should adhere to the interface

	source!(result, qpinfo)

The qpinfo argument communicates vast information of the current quadrature/evaluation point.

The bonus_quadorder argument can be used to steer the quadrature order of integrals that needs to be computed for the interpolation (the default quadrature order corressponds to the polynomial order of the finite element).

source

Nodal Evaluations

Usually, Plotters need nodal values, so there is a gengeric function that evaluates any finite element function at the nodes of the grids (possibly by averaging if discontinuous). In case of Identity evaluations of an H1-conforming finite element, the function nodevalues_view can generate a view into the coefficient field that avoids further allocations.

ExtendableFEMBase.nodevalues!Function
function nodevalues!(
 	target::AbstractArray{<:Real,2},
 	source::AbstractArray{T,1},
 	FE::FESpace{Tv,Ti,FEType,AT},
@@ -30,7 +30,7 @@
 	cellwise = false,		  # return cellwise nodevalues ncells x nnodes_on_cell
 	target_offset::Int = 0,   # start to write into target after offset
 	zero_target::Bool = true, # target vector is zeroed
-	continuous::Bool = false)

Evaluates the finite element function with the coefficient vector source and the specified FunctionOperator at all the nodes of the (specified regions of the) grid and writes the values into target. Discontinuous (continuous = false) quantities are evaluated in all neighbouring cells of each node and then averaged. Continuous (continuous = true) quantities are only evaluated once at each node.

source
ExtendableFEMBase.nodevaluesFunction
function nodevalues(
+	continuous::Bool = false)

Evaluates the finite element function with the coefficient vector source and the specified FunctionOperator at all the nodes of the (specified regions of the) grid and writes the values into target. Discontinuous (continuous = false) quantities are evaluated in all neighbouring cells of each node and then averaged. Continuous (continuous = true) quantities are only evaluated once at each node.

source
ExtendableFEMBase.nodevaluesFunction
function nodevalues(
 	source::FEVectorBlock,
 	operator::Type{<:AbstractFunctionOperator} = Identity;
 	regions::Array{Int,1} = [0],
@@ -40,9 +40,9 @@
 	cellwise = false,		  # return cellwise nodevalues ncells x nnodes_on_cell (only if nodes == [])
 	target_offset::Int = 0,   # start to write into target after offset
 	zero_target::Bool = true, # target vector is zeroed
-	continuous::Bool = false)

Evaluates the finite element function with the coefficient vector source and the specified FunctionOperator at the specified list of nodes of the grid (default = all nodes) and writes the values in that order into target. Nodes that are not part of the specified regions (default = all regions) are set to zero. Discontinuous (continuous = false) quantities are evaluated in all neighbouring cells of each node and then averaged. Continuous (continuous = true) quantities are only evaluated once at each node.

source
ExtendableFEMBase.nodevalues_viewFunction
function nodevalues_view(
+	continuous::Bool = false)

Evaluates the finite element function with the coefficient vector source and the specified FunctionOperator at the specified list of nodes of the grid (default = all nodes) and writes the values in that order into target. Nodes that are not part of the specified regions (default = all regions) are set to zero. Discontinuous (continuous = false) quantities are evaluated in all neighbouring cells of each node and then averaged. Continuous (continuous = true) quantities are only evaluated once at each node.

source
ExtendableFEMBase.nodevalues_viewFunction
function nodevalues_view(
 	source::FEVectorBlock,
-	operator::Type{<:AbstractFunctionOperator} = Identity)

Returns a vector of views of the nodal values of the source block (currently works for unbroken H1-conforming elements) that directly accesses the coefficients.

source

Lazy Interpolation

To interpolate between different finite element spaces and meshes, there is a lazy interpolation routine that works in all cases (but is not very efficient as it involves a PointeEvaluator and CellFinder):

ExtendableFEMBase.lazy_interpolate!Function
function lazy_interpolate!(
+	operator::Type{<:AbstractFunctionOperator} = Identity)

Returns a vector of views of the nodal values of the source block (currently works for unbroken H1-conforming elements) that directly accesses the coefficients.

source

Lazy Interpolation

To interpolate between different finite element spaces and meshes, there is a lazy interpolation routine that works in all cases (but is not very efficient as it involves a PointeEvaluator and CellFinder):

ExtendableFEMBase.lazy_interpolate!Function
function lazy_interpolate!(
 	target::FEVectorBlock{T1,Tv,Ti},
 	source::FEVectorBlock{T2,Tv,Ti};
 	operator = Identity,
@@ -51,4 +51,4 @@
 	items = [],
 	not_in_domain_value = 1e30,
 	eps = 1e-13,
-	use_cellparents::Bool = false) where {T1,T2,Tv,Ti}

Interpolates (operator-evaluations of) the given finite element function into the finite element space assigned to the target FEVectorBlock. (Currently not the most efficient way as it is based on the PointEvaluation pattern and cell search. If CellParents are available in the grid components of the target grid, these parent cell information can be used to improve the search. To activate this put 'use_cellparents' = true). By some given kernel function that is conforming to the interface

kernel!(result, input, qpinfo)

the operator evaluation (=input) can be further postprocessed. The qpinfo argument allows to access information at the current quadrature point.

Note: discontinuous quantities at vertices of the target grid will be evaluted in the first found cell of the source grid. No averaging is performed. With eps the tolerances of the cell search via ExtendableGrids.CellFinder can be steered.

source
+ use_cellparents::Bool = false) where {T1,T2,Tv,Ti}

Interpolates (operator-evaluations of) the given finite element function into the finite element space assigned to the target FEVectorBlock. (Currently not the most efficient way as it is based on the PointEvaluation pattern and cell search. If CellParents are available in the grid components of the target grid, these parent cell information can be used to improve the search. To activate this put 'use_cellparents' = true). By some given kernel function that is conforming to the interface

kernel!(result, input, qpinfo)

the operator evaluation (=input) can be further postprocessed. The qpinfo argument allows to access information at the current quadrature point.

Note: discontinuous quantities at vertices of the target grid will be evaluted in the first found cell of the source grid. No averaging is performed. With eps the tolerances of the cell search via ExtendableGrids.CellFinder can be steered.

source
diff --git a/dev/meshing/index.html b/dev/meshing/index.html index 18fbe87..a6fd9ba 100644 --- a/dev/meshing/index.html +++ b/dev/meshing/index.html @@ -30,4 +30,4 @@ [1]--------[2] [8] = [0,1,1] Note: most finite elements only work as intended on Parallelepiped3D - since the local<>global map stays affine in this case + since the local<>global map stays affine in this case diff --git a/dev/module_examples/Example200_LowLevelPoisson/index.html b/dev/module_examples/Example200_LowLevelPoisson/index.html index 11e1c8b..a29c71d 100644 --- a/dev/module_examples/Example200_LowLevelPoisson/index.html +++ b/dev/module_examples/Example200_LowLevelPoisson/index.html @@ -181,4 +181,4 @@ loop_allocations = assemble!(A.entries, b.entries, FES, f, μ) @info "allocations in 2nd assembly: $loop_allocations" @test loop_allocations == 0 -end #module

This page was generated using Literate.jl.

+end #module

This page was generated using Literate.jl.

diff --git a/dev/module_examples/Example205_LowLevelSpaceTimePoisson/index.html b/dev/module_examples/Example205_LowLevelSpaceTimePoisson/index.html index 5bac112..1a55f45 100644 --- a/dev/module_examples/Example205_LowLevelSpaceTimePoisson/index.html +++ b/dev/module_examples/Example205_LowLevelSpaceTimePoisson/index.html @@ -290,4 +290,4 @@ GridVisualize.save(joinpath(dir, "example205.png"), scene; Plotter = Plotter) end -end #module

This page was generated using Literate.jl.

+end #module

This page was generated using Literate.jl.

diff --git a/dev/module_examples/Example210_LowLevelNavierStokes/index.html b/dev/module_examples/Example210_LowLevelNavierStokes/index.html index a65ef96..f167f7e 100644 --- a/dev/module_examples/Example210_LowLevelNavierStokes/index.html +++ b/dev/module_examples/Example210_LowLevelNavierStokes/index.html @@ -369,4 +369,4 @@ scene = GridVisualize.reveal(plt) GridVisualize.save(joinpath(dir, "example210.png"), scene; Plotter = Plotter) end -end #module

This page was generated using Literate.jl.

+end #module

This page was generated using Literate.jl.

diff --git a/dev/module_examples/Example280_BasisPlotter/index.html b/dev/module_examples/Example280_BasisPlotter/index.html index 209d370..0524375 100644 --- a/dev/module_examples/Example280_BasisPlotter/index.html +++ b/dev/module_examples/Example280_BasisPlotter/index.html @@ -28,4 +28,4 @@ # plot println(stdout, unicode_scalarplot(FEFunc[1]; title = "φ", ylim = (-0.5, 1), resolution = dim == 1 ? (40, 10) : (20, 15), nrows = order)) end -end

This page was generated using Literate.jl.

+end

This page was generated using Literate.jl.

diff --git a/dev/module_examples/Example281_DiscontinuousPlot/index.html b/dev/module_examples/Example281_DiscontinuousPlot/index.html index f94b847..1afe5a0 100644 --- a/dev/module_examples/Example281_DiscontinuousPlot/index.html +++ b/dev/module_examples/Example281_DiscontinuousPlot/index.html @@ -61,4 +61,4 @@ scene = GridVisualize.reveal(plt) GridVisualize.save(joinpath(dir, "example281.png"), scene; Plotter = Plotter) end -end

This page was generated using Literate.jl.

+end

This page was generated using Literate.jl.

diff --git a/dev/module_examples/Example290_InterpolationBetweenMeshes/index.html b/dev/module_examples/Example290_InterpolationBetweenMeshes/index.html index fa3defc..dd01b40 100644 --- a/dev/module_examples/Example290_InterpolationBetweenMeshes/index.html +++ b/dev/module_examples/Example290_InterpolationBetweenMeshes/index.html @@ -53,4 +53,4 @@ GridVisualize.save(joinpath(dir, "example290.png"), scene; Plotter = Plotter) end -end

This page was generated using Literate.jl.

+end

This page was generated using Literate.jl.

diff --git a/dev/module_examples/example200.png b/dev/module_examples/example200.png index ab59d51..e9ed326 100644 Binary files a/dev/module_examples/example200.png and b/dev/module_examples/example200.png differ diff --git a/dev/module_examples/example205.png b/dev/module_examples/example205.png index 5990b7d..1f67509 100644 Binary files a/dev/module_examples/example205.png and b/dev/module_examples/example205.png differ diff --git a/dev/module_examples/example210.png b/dev/module_examples/example210.png index 8c3e563..e28ed29 100644 Binary files a/dev/module_examples/example210.png and b/dev/module_examples/example210.png differ diff --git a/dev/module_examples/example290.png b/dev/module_examples/example290.png index 6a4d9a3..ee2636a 100644 Binary files a/dev/module_examples/example290.png and b/dev/module_examples/example290.png differ diff --git a/dev/notebooks_intro/index.html b/dev/notebooks_intro/index.html index 7f38750..f04c2cb 100644 --- a/dev/notebooks_intro/index.html +++ b/dev/notebooks_intro/index.html @@ -1,2 +1,2 @@ -About the notebooks · ExtendableFEMBase.jl

About the notebooks

This sections contains Pluto.jl notebooks.

Plese note, that in the html version, interactive elements like sliders are disabled. Navigation via the table of contents does work, though.

+About the notebooks · ExtendableFEMBase.jl

About the notebooks

This sections contains Pluto.jl notebooks.

Plese note, that in the html version, interactive elements like sliders are disabled. Navigation via the table of contents does work, though.

diff --git a/dev/objects.inv b/dev/objects.inv index f787177..c2b6c6d 100644 Binary files a/dev/objects.inv and b/dev/objects.inv differ diff --git a/dev/package_index/index.html b/dev/package_index/index.html index f7416a6..951d431 100644 --- a/dev/package_index/index.html +++ b/dev/package_index/index.html @@ -1,2 +1,2 @@ -Index · ExtendableFEMBase.jl
+Index · ExtendableFEMBase.jl
diff --git a/dev/plots/index.html b/dev/plots/index.html index adc62ca..8a9275f 100644 --- a/dev/plots/index.html +++ b/dev/plots/index.html @@ -1,5 +1,5 @@ -Plots · ExtendableFEMBase.jl

Plots

GridVisualize/PlutoVista

Plotting is possible e.g. via Nodal Evaluations and the plot routines from ExtendableGrids.jl. In Pluto notebooks it is recommended to use PlutoVista.jl as an backend.

UnicodePlots

For a fast and rough peak several UnicodePlots plotters are available:

ExtendableFEMBase.unicode_gridplotMethod
function unicode_gridplot(
+Plots · ExtendableFEMBase.jl

Plots

GridVisualize/PlutoVista

Plotting is possible e.g. via Nodal Evaluations and the plot routines from ExtendableGrids.jl. In Pluto notebooks it is recommended to use PlutoVista.jl as an backend.

UnicodePlots

For a fast and rough peak several UnicodePlots plotters are available:

ExtendableFEMBase.unicode_gridplotMethod
function unicode_gridplot(
 	xgrid::ExtendableGrid;
 	title = "gridplot",
 	resolution = (40,20),
@@ -7,11 +7,11 @@
 	bface_color = (255,0,0),
 	CanvasType = BrailleCanvas,
 	plot_based = ON_CELLS,   # or ON_FACES/ON_EDGES
-	kwargs...

Plots the grid on a UnicodePlots canvas (default: BrailleCanvas) by drawing all edges in the triangulation.

source
ExtendableFEMBase.unicode_scalarplotMethod
function unicode_scalarplot(
 	u::FEVectorBlock; 
 	components = 1:get_ncomponents(u),
 	abs = false,
 	resolution = (30,30),
 	colormap = :viridis,
 	title = u.name,
-	kwargs...)

Plots components of the finite element function in the FEVectorBlock u by using a lazy_interpolate! onto a coarse uniform mesh and UnicodePlots.jl lineplot or heatmap for 1D or 2D, respectively.

In 1D all components all plotted in the same lineplot, while in 2D all components are plotted in a separate heatmap.

If abs = true, only the absolute value over the components is plotted.

source
+ kwargs...)

Plots components of the finite element function in the FEVectorBlock u by using a lazy_interpolate! onto a coarse uniform mesh and UnicodePlots.jl lineplot or heatmap for 1D or 2D, respectively.

In 1D all components all plotted in the same lineplot, while in 2D all components are plotted in a separate heatmap.

If abs = true, only the absolute value over the components is plotted.

source
diff --git a/dev/plutostatichtml_examples/LowLevelNavierStokes/index.html b/dev/plutostatichtml_examples/LowLevelNavierStokes/index.html index d664534..be45b7c 100644 --- a/dev/plutostatichtml_examples/LowLevelNavierStokes/index.html +++ b/dev/plutostatichtml_examples/LowLevelNavierStokes/index.html @@ -26,7 +26,7 @@ # This information is used for caching. [PlutoStaticHTML.State] input_sha = "44e10cb25a2dfe16db3f33fcdafb073f2ad5f97414ef4849a953f3686d5cf52a" - julia_version = "1.10.4" + julia_version = "1.10.5" --> @@ -47,8 +47,8 @@
2-element Vector{PlutoVTKPlot}:
- PlutoVTKPlot(Dict{String, Any}("2axisfontsize" => 10, "1" => "tricontour", "2ylabel" => "y", "2" => "axis", "cbar_levels" => [6.123233995736766e-17, 0.16667347690578882, 0.3333469538115776, 0.5000204307173663, 0.6666939076231551, 0.833367384528944, 1.0000408614347327], "cbar" => 1, "2xlabel" => "x", "2zlabel" => "z", "cbar_stops" => [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09  …  0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1.0], "2zoom" => 1.0…), 300.0, 300.0, false, (title = "", titlefontsize = 12, axisfontsize = 10, tickfontsize = 10, xlabel = "x", ylabel = "y", zlabel = "z", aspect = 1.0, zoom = 1.0, legendfontsize = 10, colorbarticks = :default, clear = false, levels = 5), "61bbfc1e-450f-11ef-0eb4-058c3656a96b")
- PlutoVTKPlot(Dict{String, Any}("2axisfontsize" => 10, "1" => "tricontour", "2ylabel" => "y", "2" => "axis", "cbar_levels" => [-0.5064542228750328, -0.33763730567358835, -0.1688203884721439, -3.4712706993289544e-6, 0.16881344593074513, 0.3376303631321897, 0.5064472803336342], "cbar" => 1, "2xlabel" => "x", "2zlabel" => "z", "cbar_stops" => [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09  …  0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1.0], "2zoom" => 1.0…), 300.0, 300.0, false, (title = "", titlefontsize = 12, axisfontsize = 10, tickfontsize = 10, xlabel = "x", ylabel = "y", zlabel = "z", aspect = 1.0, zoom = 1.0, legendfontsize = 10, colorbarticks = :default, clear = false, levels = 5), "62531eb4-450f-11ef-28c5-f1b0eece2468")
+ PlutoVTKPlot(Dict{String, Any}("2axisfontsize" => 10, "1" => "tricontour", "2ylabel" => "y", "2" => "axis", "cbar_levels" => [6.123233995736766e-17, 0.16667347690578882, 0.3333469538115776, 0.5000204307173663, 0.6666939076231551, 0.833367384528944, 1.0000408614347327], "cbar" => 1, "2xlabel" => "x", "2zlabel" => "z", "cbar_stops" => [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09 … 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1.0], "2zoom" => 1.0…), 300.0, 300.0, false, (title = "", titlefontsize = 12, axisfontsize = 10, tickfontsize = 10, xlabel = "x", ylabel = "y", zlabel = "z", aspect = 1.0, zoom = 1.0, legendfontsize = 10, colorbarticks = :default, clear = false, levels = 5), "1c7481ee-6553-11ef-08b1-e3de6e2c0746") + PlutoVTKPlot(Dict{String, Any}("2axisfontsize" => 10, "1" => "tricontour", "2ylabel" => "y", "2" => "axis", "cbar_levels" => [-0.5064542228750328, -0.33763730567358835, -0.1688203884721439, -3.4712706993289544e-6, 0.16881344593074513, 0.3376303631321897, 0.5064472803336342], "cbar" => 1, "2xlabel" => "x", "2zlabel" => "z", "cbar_stops" => [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09 … 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1.0], "2zoom" => 1.0…), 300.0, 300.0, false, (title = "", titlefontsize = 12, axisfontsize = 10, tickfontsize = 10, xlabel = "x", ylabel = "y", zlabel = "z", aspect = 1.0, zoom = 1.0, legendfontsize = 10, colorbarticks = :default, clear = false, levels = 5), "1d1f385a-6553-11ef-1eb7-41d0c8b897c4")
begin
     ## PDE data
@@ -396,14 +396,14 @@
 end
prepare_assembly! (generic function with 2 methods)
-

Built with Julia 1.10.4 and

+

Built with Julia 1.10.5 and

DiffResults 1.1.0
ExtendableFEMBase 0.6.0
-ExtendableGrids 1.9.0
-ExtendableSparse 1.5.0
+ExtendableGrids 1.9.2
+ExtendableSparse 1.5.1
ForwardDiff 0.10.36
GridVisualize 1.7.0
PlutoVista 1.0.1
- + diff --git a/dev/plutostatichtml_examples/LowLevelPoisson/index.html b/dev/plutostatichtml_examples/LowLevelPoisson/index.html index 1ceee83..36da6ff 100644 --- a/dev/plutostatichtml_examples/LowLevelPoisson/index.html +++ b/dev/plutostatichtml_examples/LowLevelPoisson/index.html @@ -26,7 +26,7 @@ # This information is used for caching. [PlutoStaticHTML.State] input_sha = "a04f122e47b606372f0ac49624a33733f0e8789f0a60c3bbf6fda0948d17bfd1" - julia_version = "1.10.4" + julia_version = "1.10.5" -->
begin
     using ExtendableFEMBase
@@ -58,7 +58,7 @@
 
1
tricontour(xgrid[Coordinates],xgrid[CellNodes],sol.entries[1:num_nodes(xgrid)]; levels = 5, resolution = (500,500))
-
+
begin
@@ -896,12 +896,12 @@
 end
assemble! (generic function with 2 methods)
-

Built with Julia 1.10.4 and

+

Built with Julia 1.10.5 and

ExtendableFEMBase 0.6.0
-ExtendableGrids 1.9.0
-ExtendableSparse 1.5.0
+ExtendableGrids 1.9.2
+ExtendableSparse 1.5.1
GridVisualize 1.7.0
PlutoVista 1.0.1
- + diff --git a/dev/pointevaluators/index.html b/dev/pointevaluators/index.html index f8b2681..072e879 100644 --- a/dev/pointevaluators/index.html +++ b/dev/pointevaluators/index.html @@ -1,18 +1,18 @@ -PointEvaluator · ExtendableFEMBase.jl

PointEvaluator

Point evaluators allow to evaluate a finite element function (FEVector) at arbitrary points.

ExtendableFEMBase.PointEvaluatorType
function Pointevaluator(
+PointEvaluator · ExtendableFEMBase.jl

PointEvaluator

Point evaluators allow to evaluate a finite element function (FEVector) at arbitrary points.

ExtendableFEMBase.PointEvaluatorType
function Pointevaluator(
 	[kernel!::Function],
 	oa_args::Array{<:Tuple{<:Any, DataType},1};
-	kwargs...)

Generates a PointEvaluator that can evaluate the specified operator evaluations at arbitrary points. If no kernel function is given, the arguments are given directly. If a kernel is provided, the arguments are postprocessed accordingly and the kernel has to be conform to the interface

kernel!(result, eval_args, qpinfo)

where qpinfo allows to access information at the current evaluation point. Additionally the length of the result needs to be specified via the kwargs.

Evaluation can be triggered via the evaluate function after an initialize! call.

Operator evaluations are tuples that pair a tag (to identify an unknown or the position in the vector) with a FunctionOperator.

Keyword arguments:

  • resultdim: dimension of result field (default = length of operators). Default: 0

  • params: array of parameters that should be made available in qpinfo argument of kernel function. Default: nothing

  • name: name for operator used in printouts. Default: ''PointEvaluator''

  • verbosity: verbosity level. Default: 0

source
ExtendableFEMBase.evaluate!Method
function evaluate!(
+	kwargs...)

Generates a PointEvaluator that can evaluate the specified operator evaluations at arbitrary points. If no kernel function is given, the arguments are given directly. If a kernel is provided, the arguments are postprocessed accordingly and the kernel has to be conform to the interface

kernel!(result, eval_args, qpinfo)

where qpinfo allows to access information at the current evaluation point. Additionally the length of the result needs to be specified via the kwargs.

Evaluation can be triggered via the evaluate function after an initialize! call.

Operator evaluations are tuples that pair a tag (to identify an unknown or the position in the vector) with a FunctionOperator.

Keyword arguments:

  • resultdim: dimension of result field (default = length of operators). Default: 0

  • params: array of parameters that should be made available in qpinfo argument of kernel function. Default: nothing

  • name: name for operator used in printouts. Default: ''PointEvaluator''

  • verbosity: verbosity level. Default: 0

source
ExtendableFEMBase.evaluate!Method
function evaluate!(
 	result,
 	PE::PointEvaluator,
 	x
-	)

Evaluates the PointEvaluator at the specified coordinates x. (To do so it internally calls CellFinder to find the cell and the barycentric coordinates of x and calls evaluate_bary!.)

source
ExtendableFEMBase.evaluate_bary!Method
function evaluate_bary!(
+	)

Evaluates the PointEvaluator at the specified coordinates x. (To do so it internally calls CellFinder to find the cell and the barycentric coordinates of x and calls evaluate_bary!.)

source
ExtendableFEMBase.evaluate_bary!Method
function evaluate_bary!(
 	result,
 	PE::PointEvaluator,
 	xref, 
 	item
-	)

Evaluates the PointEvaluator at the specified reference coordinates in the cell with the specified item number.

source
ExtendableFEMBase.initialize!Method
function initialize!(
+	)

Evaluates the PointEvaluator at the specified reference coordinates in the cell with the specified item number.

source
+ kwargs...)

Initializes the PointEvaluator for the specified solution.

source
diff --git a/dev/quadrature/index.html b/dev/quadrature/index.html index 0837b24..1120277 100644 --- a/dev/quadrature/index.html +++ b/dev/quadrature/index.html @@ -1,9 +1,9 @@ -Quadrature · ExtendableFEMBase.jl

Quadrature

Usually quadrature is a hidden layer as quadrature rules are chosen automatically based on the polynomial degree of the ansatz functions and the specified quadorder of the user data.

Hence, quadrature rules are only needed if the user wants write his own low-level assembly.

Quadrature rules consist of points (coordinates of evaluation points with respect to reference geometry) and weights. There are constructors for several AbstractElementGeometries (from ExtendableGrids) and different order (some have generic formulas for arbitrary order), see below for a detailed list.

ExtendableFEMBase.QuadratureRuleType
abstract type QuadratureRule{T<:Real, ET<:ExtendableGrids.AbstractElementGeometry}

A struct that contains the name of the quadrature rule, the reference points and the weights for the parameter-determined element geometry.

source
ExtendableFEMBase.QuadratureRuleMethod
function QuadratureRule{T,ET}(order::Int) where {T<:Real, ET <: AbstractElementGeometry0D}

Constructs 0D quadrature rule of specified order (always point evaluation).

source
ExtendableFEMBase.QuadratureRuleMethod
function QuadratureRule{T,ET}(order::Int) where {T<:Real, ET <: Parallelepiped3D}

Constructs quadrature rule on Parallelepiped3D of specified order.

source
ExtendableFEMBase.QuadratureRuleMethod
function QuadratureRule{T,ET}(order::Int) where {T<:Real, ET <: Parallelogram2D}

Constructs quadrature rule on Parallelogram2D of specified order.

source
ExtendableFEMBase.QuadratureRuleMethod
function QuadratureRule{T,ET}(order::Int) where {T<:Real, ET <: Tetrahedron3D}

Constructs quadrature rule on Tetrahedron3D of specified order.

source
Base.eltypeMethod
eltype(
+Quadrature · ExtendableFEMBase.jl

Quadrature

Usually quadrature is a hidden layer as quadrature rules are chosen automatically based on the polynomial degree of the ansatz functions and the specified quadorder of the user data.

Hence, quadrature rules are only needed if the user wants write his own low-level assembly.

Quadrature rules consist of points (coordinates of evaluation points with respect to reference geometry) and weights. There are constructors for several AbstractElementGeometries (from ExtendableGrids) and different order (some have generic formulas for arbitrary order), see below for a detailed list.

ExtendableFEMBase.QuadratureRuleType
abstract type QuadratureRule{T<:Real, ET<:ExtendableGrids.AbstractElementGeometry}

A struct that contains the name of the quadrature rule, the reference points and the weights for the parameter-determined element geometry.

source
ExtendableFEMBase.QuadratureRuleMethod
function QuadratureRule{T,ET}(order::Int) where {T<:Real, ET <: AbstractElementGeometry0D}

Constructs 0D quadrature rule of specified order (always point evaluation).

source
ExtendableFEMBase.QuadratureRuleMethod
function QuadratureRule{T,ET}(order::Int) where {T<:Real, ET <: Parallelepiped3D}

Constructs quadrature rule on Parallelepiped3D of specified order.

source
ExtendableFEMBase.QuadratureRuleMethod
function QuadratureRule{T,ET}(order::Int) where {T<:Real, ET <: Parallelogram2D}

Constructs quadrature rule on Parallelogram2D of specified order.

source
ExtendableFEMBase.QuadratureRuleMethod
function QuadratureRule{T,ET}(order::Int) where {T<:Real, ET <: Tetrahedron3D}

Constructs quadrature rule on Tetrahedron3D of specified order.

source
Base.eltypeMethod
eltype(
     _::QuadratureRule{T<:Real, ET<:ExtendableGrids.AbstractElementGeometry}
 ) -> Any
-

Custom eltype function for QuadratureRule{T,ET}.

source
Base.showMethod
show(io::IO, Q::QuadratureRule)
-

Custom show function for QuadratureRule{T,ET} that prints some information.

source
Base.showMethod
show(io::IO, Q::QuadratureRule)
+

Custom show function for QuadratureRule{T,ET} that prints some information.

source
ExtendableFEMBase.integrate!Method
integrate!(
     integral4items::AbstractArray{T},
     grid::ExtendableGrids.ExtendableGrid{Tv, Ti},
     AT::Type{<:ExtendableGrids.AssemblyType},
@@ -16,7 +16,7 @@
     force_quadrature_rule,
     kwargs...
 )
-

Integration that writes result on every item into integral4items.

source
ExtendableFEMBase.integrateMethod
integrate(
     grid::ExtendableGrids.ExtendableGrid,
     AT::Type{<:ExtendableGrids.AssemblyType},
     integrand!,
@@ -24,10 +24,10 @@
     T,
     kwargs...
 ) -> Union{Float64, Vector{Float64}}
-

Integration that returns total integral.

source
ExtendableFEMBase.ref_integrate!Method
ref_integrate!(
     integral::AbstractArray,
     EG::Type{<:ExtendableGrids.AbstractElementGeometry},
     order::Int64,
     integrand::Function
 )
-

Integration for reference basis functions on reference domains (merely for testing stuff).

Note: area of reference geometry is not multiplied

source
+

Integration for reference basis functions on reference domains (merely for testing stuff).

Note: area of reference geometry is not multiplied

source
diff --git a/dev/search_index.js b/dev/search_index.js index f499c3d..5eddc3f 100644 --- a/dev/search_index.js +++ b/dev/search_index.js @@ -1,3 +1,3 @@ var documenterSearchIndex = {"docs": -[{"location":"fematrix/#FEMatrix","page":"FEMatrix","title":"FEMatrix","text":"","category":"section"},{"location":"fematrix/","page":"FEMatrix","title":"FEMatrix","text":"A FEMatrix consists of FEMatrixBlocks that share a common ExtendableSparseMatrix. Each block is associated to two FESpaces and can only write into a submatrix of the common sparse matrix specified by offsets.","category":"page"},{"location":"fematrix/","page":"FEMatrix","title":"FEMatrix","text":"Modules = [ExtendableFEMBase]\nPages = [\"fematrix.jl\"]\nOrder = [:type, :function]","category":"page"},{"location":"fematrix/#ExtendableFEMBase.FEMatrix","page":"FEMatrix","title":"ExtendableFEMBase.FEMatrix","text":"struct FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal} <: SparseArrays.AbstractSparseArray{TvM, TiM, 2}\n\nan AbstractMatrix (e.g. an ExtendableSparseMatrix) with an additional layer of several FEMatrixBlock subdivisions each carrying coefficients for their associated pair of FESpaces\n\n\n\n\n\n","category":"type"},{"location":"fematrix/#ExtendableFEMBase.FEMatrix-Tuple{FESpace, FESpace}","page":"FEMatrix","title":"ExtendableFEMBase.FEMatrix","text":"FEMatrix{TvM,TiM}(FESX, FESY; name = \"auto\")\n\nCreates FEMatrix with one rectangular block (FESX,FESY) if FESX and FESY are single FESpaces, or a rectangular block matrix with blocks corresponding to the entries of the FESpace vectors FESX and FESY. Optionally a name for the matrix can be given.\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.FEMatrix-Tuple{FESpace}","page":"FEMatrix","title":"ExtendableFEMBase.FEMatrix","text":"FEMatrix{TvM,TiM}(name::String, FES::FESpace{TvG,TiG,FETypeX,APTX}) where {TvG,TiG,FETypeX,APTX}\n\nCreates FEMatrix with one square block (FES,FES).\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.FEMatrix-Union{Tuple{TiG}, Tuple{TvG}, Tuple{TiM}, Tuple{TvM}, Tuple{Vector{<:FESpace{TvG, TiG}}, Vector{<:FESpace{TvG, TiG}}}} where {TvM, TiM, TvG, TiG}","page":"FEMatrix","title":"ExtendableFEMBase.FEMatrix","text":"FEMatrix{TvM,TiM}(FESX, FESY; name = \"auto\")\n\nCreates an FEMatrix with blocks coressponding to the ndofs of FESX (rows) and FESY (columns).\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.FEMatrixBlock","page":"FEMatrix","title":"ExtendableFEMBase.FEMatrixBlock","text":"struct FEMatrixBlock{TvM, TiM, TvG, TiG, FETypeX, FETypeY, APTX, APTY} <: AbstractArray{TvM, 2}\n\nblock of an FEMatrix that carries coefficients for an associated pair of FESpaces and can be assigned as an two-dimensional AbstractArray (getindex, setindex, size)\n\n\n\n\n\n","category":"type"},{"location":"fematrix/#Base.fill!-Union{Tuple{Ti}, Tuple{Tv}, Tuple{FEMatrixBlock{Tv, Ti}, Any}} where {Tv, Ti}","page":"FEMatrix","title":"Base.fill!","text":"fill!(B::FEMatrixBlock{Tv, Ti}, value)\n\n\nCustom fill function for FEMatrixBlock (only fills the already present nzval in the block, not the complete FEMatrix).\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#Base.length-Union{Tuple{FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}}, Tuple{nbtotal}, Tuple{nbcol}, Tuple{nbrow}, Tuple{TiG}, Tuple{TvG}, Tuple{TiM}, Tuple{TvM}} where {TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}","page":"FEMatrix","title":"Base.length","text":"length(\n _::FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}\n) -> Any\n\n\nCustom length function for FEMatrix that gives the total number of defined FEMatrixBlocks in it\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#Base.show-Union{Tuple{nbtotal}, Tuple{nbcol}, Tuple{nbrow}, Tuple{TiG}, Tuple{TvG}, Tuple{TiM}, Tuple{TvM}, Tuple{IO, FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}}} where {TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}","page":"FEMatrix","title":"Base.show","text":"show(\n io::IO,\n FEM::FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}\n)\n\n\nCustom show function for FEMatrix that prints some information on its blocks.\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#Base.size-Tuple{FEMatrixBlock}","page":"FEMatrix","title":"Base.size","text":"size(FEB::FEMatrixBlock) -> Tuple{Int64, Int64}\n\n\nCustom size function for FEMatrixBlock that gives a tuple with the size of the block (that coressponds to the number of degrees of freedoms in X and Y)\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#Base.size-Union{Tuple{FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}}, Tuple{nbtotal}, Tuple{nbcol}, Tuple{nbrow}, Tuple{TiG}, Tuple{TvG}, Tuple{TiM}, Tuple{TvM}} where {TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}","page":"FEMatrix","title":"Base.size","text":"size(\n _::FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}\n) -> Tuple{Any, Any}\n\n\nCustom size function for FEMatrix that gives a tuple with the number of rows and columns of the FEBlock overlay\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.add!-Union{Tuple{Ti}, Tuple{Tv}, Tuple{FEMatrix{Tv, Ti}, FEMatrix{Tv, Ti}}} where {Tv, Ti}","page":"FEMatrix","title":"ExtendableFEMBase.add!","text":"add!(A::FEMatrix{Tv, Ti}, B::FEMatrix{Tv, Ti}; kwargs...)\n\n\nAdds FEMatrix/ExtendableSparseMatrix/CSCMatrix B to FEMatrix A.\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.addblock!-Union{Tuple{Ti}, Tuple{Tv}, Tuple{FEMatrixBlock{Tv, Ti}, FEMatrixBlock{Tv, Ti}}} where {Tv, Ti}","page":"FEMatrix","title":"ExtendableFEMBase.addblock!","text":"addblock!(\n A::FEMatrixBlock{Tv, Ti},\n B::FEMatrixBlock{Tv, Ti};\n factor,\n transpose\n)\n\n\nAdds FEMatrixBlock B to FEMatrixBlock A.\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.addblock!-Union{Tuple{Ti}, Tuple{Tv}, Tuple{FEMatrixBlock{Tv}, ExtendableSparse.ExtendableSparseMatrixCSC{Tv, Ti}}} where {Tv, Ti<:Integer}","page":"FEMatrix","title":"ExtendableFEMBase.addblock!","text":"addblock!(\n A::FEMatrixBlock{Tv},\n B::ExtendableSparse.ExtendableSparseMatrixCSC{Tv, Ti<:Integer};\n factor,\n transpose\n)\n\n\nAdds ExtendableSparseMatrix B to FEMatrixBlock A.\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.addblock!-Union{Tuple{Ti}, Tuple{Tv}, Tuple{FEMatrixBlock{Tv}, SparseArrays.SparseMatrixCSC{Tv, Ti}}} where {Tv, Ti<:Integer}","page":"FEMatrix","title":"ExtendableFEMBase.addblock!","text":"addblock!(\n A::FEMatrixBlock{Tv},\n cscmat::SparseArrays.SparseMatrixCSC{Tv, Ti<:Integer};\n factor,\n transpose\n)\n\n\nAdds SparseMatrixCSC B to FEMatrixBlock A.\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.addblock_matmul!-Union{Tuple{Ti}, Tuple{Tv}, Tuple{AbstractVector{Tv}, FEMatrixBlock{Tv, Ti}, AbstractVector{Tv}}} where {Tv, Ti}","page":"FEMatrix","title":"ExtendableFEMBase.addblock_matmul!","text":"addblock_matmul!(\n a::AbstractArray{Tv, 1},\n B::FEMatrixBlock{Tv, Ti},\n b::AbstractArray{Tv, 1};\n factor,\n transposed\n)\n\n\nAdds matrix-vector product B times b to FEVectorBlock a.\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.addblock_matmul!-Union{Tuple{Ti}, Tuple{Tv}, Tuple{FEMatrixBlock{Tv}, SparseArrays.SparseMatrixCSC{Tv, Ti}, SparseArrays.SparseMatrixCSC{Tv, Ti}}} where {Tv, Ti}","page":"FEMatrix","title":"ExtendableFEMBase.addblock_matmul!","text":"addblock_matmul!(\n A::FEMatrixBlock{Tv},\n cscmatB::SparseArrays.SparseMatrixCSC{Tv, Ti},\n cscmatC::SparseArrays.SparseMatrixCSC{Tv, Ti};\n factor,\n transposed\n)\n\n\nAdds matrix-matrix product B times C to FEMatrixBlock A.\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.addblock_matmul!-Union{Tuple{Ti}, Tuple{Tv}, Tuple{FEVectorBlock{Tv}, ExtendableSparse.ExtendableSparseMatrixCSC{Tv, Ti}, FEVectorBlock{Tv}}} where {Tv, Ti<:Integer}","page":"FEMatrix","title":"ExtendableFEMBase.addblock_matmul!","text":"addblock_matmul!(\n a::FEVectorBlock{Tv},\n B::ExtendableSparse.ExtendableSparseMatrixCSC{Tv, Ti<:Integer},\n b::FEVectorBlock{Tv};\n factor\n)\n\n\nAdds matrix-vector product B times b to FEVectorBlock a.\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.addblock_matmul!-Union{Tuple{Ti}, Tuple{Tv}, Tuple{FEVectorBlock{Tv}, FEMatrixBlock{Tv, Ti}, FEVectorBlock{Tv}}} where {Tv, Ti}","page":"FEMatrix","title":"ExtendableFEMBase.addblock_matmul!","text":"addblock_matmul!(\n a::FEVectorBlock{Tv},\n B::FEMatrixBlock{Tv, Ti},\n b::FEVectorBlock{Tv};\n factor,\n transposed\n)\n\n\nAdds matrix-vector product B times b (or B' times b if transposed = true) to FEVectorBlock a.\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.ldrdmatmul-Union{Tuple{Ti}, Tuple{Tv}, Tuple{AbstractVector{Tv}, AbstractVector{Tv}, ExtendableSparse.ExtendableSparseMatrixCSC{Tv, Ti}, AbstractVector{Tv}, AbstractVector{Tv}}} where {Tv, Ti<:Integer}","page":"FEMatrix","title":"ExtendableFEMBase.ldrdmatmul","text":"ldrdmatmul(\n a1::AbstractArray{Tv, 1},\n a2::AbstractArray{Tv, 1},\n B::ExtendableSparse.ExtendableSparseMatrixCSC{Tv, Ti<:Integer},\n b1::AbstractArray{Tv, 1},\n b2::AbstractArray{Tv, 1};\n factor\n) -> Any\n\n\nComputes vector'-matrix-vector product (a1-a2)'B(b1-b2).\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.lrmatmul-Union{Tuple{Ti}, Tuple{Tv}, Tuple{AbstractVector{Tv}, ExtendableSparse.ExtendableSparseMatrixCSC{Tv, Ti}, AbstractVector{Tv}}} where {Tv, Ti<:Integer}","page":"FEMatrix","title":"ExtendableFEMBase.lrmatmul","text":"lrmatmul(\n a::AbstractArray{Tv, 1},\n B::ExtendableSparse.ExtendableSparseMatrixCSC{Tv, Ti<:Integer},\n b::AbstractArray{Tv, 1};\n factor\n) -> Any\n\n\nComputes vector'-matrix-vector product a'Bb.\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.nbcols-Union{Tuple{FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}}, Tuple{nbtotal}, Tuple{nbcol}, Tuple{nbrow}, Tuple{TiG}, Tuple{TvG}, Tuple{TiM}, Tuple{TvM}} where {TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}","page":"FEMatrix","title":"ExtendableFEMBase.nbcols","text":"nbcols(\n _::FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}\n) -> Any\n\n\nGives the number of FEMatrixBlocks in each row.\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.nbrows-Union{Tuple{FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}}, Tuple{nbtotal}, Tuple{nbcol}, Tuple{nbrow}, Tuple{TiG}, Tuple{TvG}, Tuple{TiM}, Tuple{TvM}} where {TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}","page":"FEMatrix","title":"ExtendableFEMBase.nbrows","text":"nbrows(\n _::FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}\n) -> Any\n\n\nGives the number of FEMatrixBlocks in each column.\n\n\n\n\n\n","category":"method"},{"location":"module_examples/Example281_DiscontinuousPlot/#281-:-Discontinuous-Plot","page":"Example281_DiscontinuousPlot","title":"281 : Discontinuous Plot","text":"","category":"section"},{"location":"module_examples/Example281_DiscontinuousPlot/","page":"Example281_DiscontinuousPlot","title":"Example281_DiscontinuousPlot","text":"(source code)","category":"page"},{"location":"module_examples/Example281_DiscontinuousPlot/","page":"Example281_DiscontinuousPlot","title":"Example281_DiscontinuousPlot","text":"This example demonstrates how to plot a discontinuous function on a grid with two regions by region-wise nodal values and plotting.","category":"page"},{"location":"module_examples/Example281_DiscontinuousPlot/","page":"Example281_DiscontinuousPlot","title":"Example281_DiscontinuousPlot","text":"The computed solution for the default parameters looks like this:","category":"page"},{"location":"module_examples/Example281_DiscontinuousPlot/","page":"Example281_DiscontinuousPlot","title":"Example281_DiscontinuousPlot","text":"(Image: )","category":"page"},{"location":"module_examples/Example281_DiscontinuousPlot/","page":"Example281_DiscontinuousPlot","title":"Example281_DiscontinuousPlot","text":"module Example281_DiscontinuousPlot\n\nusing ExtendableFEMBase\nusing ExtendableGrids\nusing GridVisualize\n\n# function to interpolate\nfunction u!(result, qpinfo)\n\tx = qpinfo.x\n if qpinfo.region == 1\n result[1] = 2*x[1]*x[2]\n elseif qpinfo.region == 2\n result[1] = -1*x[2]*x[1] + 0.5\n else\n @error \"function was evaluated without region information\"\n end\nend\n\n# everything is wrapped in a main function\nfunction main(; broken = false, nrefs = 3, abs = false, Plotter = nothing)\n\n\t# generate two grids\n\txgrid = grid_unitsquare(Triangle2D)\n\n # mark first two triangles to be in second region\n xgrid[CellRegions][1:2] .= 2\n\n # refine\n\txgrid = uniform_refine(xgrid, nrefs)\n\n\t# generate coressponding finite element spaces and FEVectors\n\tFES = FESpace{L2P1{1}}(xgrid; broken = broken)\n\tFEFunction = FEVector(FES)\n\n\t# interpolate function onto first grid\n\tinterpolate!(FEFunction[1], u!; bonus_quadorder = 2)\n\n # get subgrid for each region\n subgrid1 = subgrid(xgrid, [1])\n subgrid2 = subgrid(xgrid, [2])\n\n # get parent nodes for each subgrid\n subnodes1 = subgrid1[NodeParents]\n subnodes2 = subgrid2[NodeParents]\n\n # compute nodevalues for nodes of each subgrid\n nodevals4nodes1 = nodevalues(FEFunction[1], Identity; abs = abs, regions = [1], nodes = subnodes1)\n nodevals4nodes2 = nodevalues(FEFunction[1], Identity; abs = abs, regions = [2], nodes = subnodes2)\n\n\t# plot\n\tp = GridVisualizer(; Plotter = Plotter, layout = (2, 2), clear = true, resolution = (1000, 500))\n gridplot!(p[1,1], xgrid)\n\tscalarplot!(p[1, 2], [subgrid1, subgrid2], xgrid, [view(nodevals4nodes1,:), view(nodevals4nodes2,:)], cellwise = false, levels = 11, title = \"u\")\n\n return p\nend\n\nfunction generateplots(dir = pwd(); Plotter = nothing, kwargs...)\n\tplt = main(; Plotter = Plotter, kwargs...)\n\tscene = GridVisualize.reveal(plt)\n\tGridVisualize.save(joinpath(dir, \"example281.png\"), scene; Plotter = Plotter)\nend\nend","category":"page"},{"location":"module_examples/Example281_DiscontinuousPlot/","page":"Example281_DiscontinuousPlot","title":"Example281_DiscontinuousPlot","text":"","category":"page"},{"location":"module_examples/Example281_DiscontinuousPlot/","page":"Example281_DiscontinuousPlot","title":"Example281_DiscontinuousPlot","text":"This page was generated using Literate.jl.","category":"page"},{"location":"interpolations/#Finite-Element-Interpolations","page":"Finite Element Interpolations","title":"Finite Element Interpolations","text":"","category":"section"},{"location":"interpolations/#Source-functions-and-QPInfo","page":"Finite Element Interpolations","title":"Source functions and QPInfo","text":"","category":"section"},{"location":"interpolations/","page":"Finite Element Interpolations","title":"Finite Element Interpolations","text":"The functions that can be interpolated with the methods below are expected to have a certain interface, i.e.:","category":"page"},{"location":"interpolations/","page":"Finite Element Interpolations","title":"Finite Element Interpolations","text":"function f!(result, qpinfo) end","category":"page"},{"location":"interpolations/","page":"Finite Element Interpolations","title":"Finite Element Interpolations","text":"The qpinfo argument communicates vast information of the current quadrature point:","category":"page"},{"location":"interpolations/","page":"Finite Element Interpolations","title":"Finite Element Interpolations","text":"qpinfo child Type Description\nqpinfo.x Vector{Real} space coordinates of quadrature point\nqpinfo.time Real current time\nqpinfo.item Integer current item that contains qpinfo.x\nqpinfo.region Integer region number of item\nqpinfo.xref Vector{Real} reference coordinates within item of qpinfo.x\nqpinfo.volume Real volume of item\nqpinfo.params Vector{Any} parameters that can be transfered via keyword arguments","category":"page"},{"location":"interpolations/#Standard-Interpolations","page":"Finite Element Interpolations","title":"Standard Interpolations","text":"","category":"section"},{"location":"interpolations/","page":"Finite Element Interpolations","title":"Finite Element Interpolations","text":"Each finite element has its standard interpolator that can be applied to some user-defined DataFunction. Instead of interpolating on the full cells, the interpolation can be restricted to faces or edges. ","category":"page"},{"location":"interpolations/","page":"Finite Element Interpolations","title":"Finite Element Interpolations","text":"It is also possible to interpolate finite element functions on one grid onto a finite element function on another grid (experimental feature, does not work for all finite elements yet and shall be extended to interpolations of operator evaluations as well in future).","category":"page"},{"location":"interpolations/","page":"Finite Element Interpolations","title":"Finite Element Interpolations","text":"interpolate!","category":"page"},{"location":"interpolations/#ExtendableGrids.interpolate!","page":"Finite Element Interpolations","title":"ExtendableGrids.interpolate!","text":"function ExtendableGrids.interpolate!(target::FEVectorBlock,\n\t AT::Type{<:AssemblyType},\n\t source!::Function;\n\t items = [],\n\t bonus_quadorder = 0,\n\t time = 0,\n\t kwargs...)\n\nInterpolates the given source into the finite elements space assigned to the target FEVectorBlock with the specified AssemblyType (usualy ON_CELLS). \n\nThe source functions should adhere to the interface\n\n\tsource!(result, qpinfo)\n\nThe qpinfo argument communicates vast information of the current quadrature/evaluation point.\n\nThe bonus_quadorder argument can be used to steer the quadrature order of integrals that needs to be computed for the interpolation (the default quadrature order corressponds to the polynomial order of the finite element).\n\n\n\n\n\nfunction ExtendableGrids.interpolate!(target::FEVectorBlock,\n\t source::Function;\n\t items = [],\n\t bonus_quadorder = 0,\n\t time = 0,\n\t kwargs...)\n\nInterpolates the given source function into the finite element space assigned to the target FEVectorBlock. \n\nThe source functions should adhere to the interface\n\n\tsource!(result, qpinfo)\n\nThe qpinfo argument communicates vast information of the current quadrature/evaluation point.\n\nThe bonus_quadorder argument can be used to steer the quadrature order of integrals that needs to be computed for the interpolation (the default quadrature order corressponds to the polynomial order of the finite element).\n\n\n\n\n\n","category":"function"},{"location":"interpolations/#Nodal-Evaluations","page":"Finite Element Interpolations","title":"Nodal Evaluations","text":"","category":"section"},{"location":"interpolations/","page":"Finite Element Interpolations","title":"Finite Element Interpolations","text":"Usually, Plotters need nodal values, so there is a gengeric function that evaluates any finite element function at the nodes of the grids (possibly by averaging if discontinuous). In case of Identity evaluations of an H1-conforming finite element, the function nodevalues_view can generate a view into the coefficient field that avoids further allocations.","category":"page"},{"location":"interpolations/","page":"Finite Element Interpolations","title":"Finite Element Interpolations","text":"nodevalues!\nnodevalues\nnodevalues_view","category":"page"},{"location":"interpolations/#ExtendableFEMBase.nodevalues!","page":"Finite Element Interpolations","title":"ExtendableFEMBase.nodevalues!","text":"function nodevalues!(\n\ttarget::AbstractArray{<:Real,2},\n\tsource::AbstractArray{T,1},\n\tFE::FESpace{Tv,Ti,FEType,AT},\n\toperator::Type{<:AbstractFunctionOperator} = Identity;\n\tregions::Array{Int,1} = [0],\n\tabs::Bool = false,\n\tfactor = 1,\n\ttarget_offset::Int = 0, # start to write into target after offset\n\tzero_target::Bool = true, # target vector is zeroed\n\tcontinuous::Bool = false)\n\nEvaluates the finite element function with the coefficient vector source (interpreted as a coefficient vector for the FESpace FE) and the specified FunctionOperator at all the nodes of the (specified regions of the) grid and writes the values into target. Discontinuous (continuous = false) quantities are evaluated in all neighbouring cells of each node and then averaged. Continuous (continuous = true) quantities are only evaluated once at each node.\n\n\n\n\n\nfunction nodevalues!(\n\ttarget::AbstractArray{<:Real,2},\n\tsource::FEVectorBlock,\n\toperator::Type{<:AbstractFunctionOperator} = Identity;\n\tregions::Array{Int,1} = [0],\n\tabs::Bool = false,\n\tfactor = 1,\n\tcellwise = false,\t\t # return cellwise nodevalues ncells x nnodes_on_cell\n\ttarget_offset::Int = 0, # start to write into target after offset\n\tzero_target::Bool = true, # target vector is zeroed\n\tcontinuous::Bool = false)\n\nEvaluates the finite element function with the coefficient vector source and the specified FunctionOperator at all the nodes of the (specified regions of the) grid and writes the values into target. Discontinuous (continuous = false) quantities are evaluated in all neighbouring cells of each node and then averaged. Continuous (continuous = true) quantities are only evaluated once at each node.\n\n\n\n\n\n","category":"function"},{"location":"interpolations/#ExtendableFEMBase.nodevalues","page":"Finite Element Interpolations","title":"ExtendableFEMBase.nodevalues","text":"function nodevalues(\n\tsource::FEVectorBlock,\n\toperator::Type{<:AbstractFunctionOperator} = Identity;\n\tregions::Array{Int,1} = [0],\n\tabs::Bool = false,\n\tfactor = 1,\n\tnodes = [],\t\t\t\t \n\tcellwise = false,\t\t # return cellwise nodevalues ncells x nnodes_on_cell (only if nodes == [])\n\ttarget_offset::Int = 0, # start to write into target after offset\n\tzero_target::Bool = true, # target vector is zeroed\n\tcontinuous::Bool = false)\n\nEvaluates the finite element function with the coefficient vector source and the specified FunctionOperator at the specified list of nodes of the grid (default = all nodes) and writes the values in that order into target. Nodes that are not part of the specified regions (default = all regions) are set to zero. Discontinuous (continuous = false) quantities are evaluated in all neighbouring cells of each node and then averaged. Continuous (continuous = true) quantities are only evaluated once at each node.\n\n\n\n\n\n","category":"function"},{"location":"interpolations/#ExtendableFEMBase.nodevalues_view","page":"Finite Element Interpolations","title":"ExtendableFEMBase.nodevalues_view","text":"function nodevalues_view(\n\tsource::FEVectorBlock,\n\toperator::Type{<:AbstractFunctionOperator} = Identity)\n\nReturns a vector of views of the nodal values of the source block (currently works for unbroken H1-conforming elements) that directly accesses the coefficients.\n\n\n\n\n\n","category":"function"},{"location":"interpolations/#Lazy-Interpolation","page":"Finite Element Interpolations","title":"Lazy Interpolation","text":"","category":"section"},{"location":"interpolations/","page":"Finite Element Interpolations","title":"Finite Element Interpolations","text":"To interpolate between different finite element spaces and meshes, there is a lazy interpolation routine that works in all cases (but is not very efficient as it involves a PointeEvaluator and CellFinder):","category":"page"},{"location":"interpolations/","page":"Finite Element Interpolations","title":"Finite Element Interpolations","text":"lazy_interpolate!","category":"page"},{"location":"interpolations/#ExtendableFEMBase.lazy_interpolate!","page":"Finite Element Interpolations","title":"ExtendableFEMBase.lazy_interpolate!","text":"function lazy_interpolate!(\n\ttarget::FEVectorBlock{T1,Tv,Ti},\n\tsource::FEVectorBlock{T2,Tv,Ti};\n\toperator = Identity,\n\tpostprocess = nothing,\n\txtrafo = nothing,\n\titems = [],\n\tnot_in_domain_value = 1e30,\n\teps = 1e-13,\n\tuse_cellparents::Bool = false) where {T1,T2,Tv,Ti}\n\nInterpolates (operator-evaluations of) the given finite element function into the finite element space assigned to the target FEVectorBlock. (Currently not the most efficient way as it is based on the PointEvaluation pattern and cell search. If CellParents are available in the grid components of the target grid, these parent cell information can be used to improve the search. To activate this put 'use_cellparents' = true). By some given kernel function that is conforming to the interface\n\nkernel!(result, input, qpinfo)\n\nthe operator evaluation (=input) can be further postprocessed. The qpinfo argument allows to access information at the current quadrature point.\n\nNote: discontinuous quantities at vertices of the target grid will be evaluted in the first found cell of the source grid. No averaging is performed. With eps the tolerances of the cell search via ExtendableGrids.CellFinder can be steered.\n\n\n\n\n\n","category":"function"},{"location":"package_index/","page":"Index","title":"Index","text":"Modules = [ExtendableFEMBase]\nOrder = [:function, :type]","category":"page"},{"location":"fevector/#FEVector","page":"FEVector","title":"FEVector","text":"","category":"section"},{"location":"fevector/","page":"FEVector","title":"FEVector","text":"A FEVector consists of FEVectorBlocks that share a common one-dimensional array. Each block is associated to a FESpace and can only write into a region of the common array specified by offsets that stores the degrees of freedom of that FEspace.","category":"page"},{"location":"fevector/","page":"FEVector","title":"FEVector","text":"Modules = [ExtendableFEMBase]\nPages = [\"fevector.jl\"]\nOrder = [:type, :function]","category":"page"},{"location":"fevector/#ExtendableFEMBase.FEVector","page":"FEVector","title":"ExtendableFEMBase.FEVector","text":"struct FEVector{T, Tv, Ti}\n\na plain array but with an additional layer of several FEVectorBlock subdivisions each carrying coefficients for their associated FESpace. The j-th block can be accessed by getindex(::FEVector, j) or by getindex(::FEVector, tag) if tags are associated. The full vector can be accessed via FEVector.entries \n\n\n\n\n\n","category":"type"},{"location":"fevector/#ExtendableFEMBase.FEVector-Union{Tuple{FESpace{Tv, Ti, FEType, APT}}, Tuple{APT}, Tuple{FEType}, Tuple{Ti}, Tuple{Tv}} where {Tv, Ti, FEType, APT}","page":"FEVector","title":"ExtendableFEMBase.FEVector","text":"FEVector{T}(FES; name = nothing, tags = nothing, kwargs...) where T <: Real\n\nCreates FEVector that has one block if FES is a single FESpace, and a blockwise FEVector if FES is a vector of FESpaces. Optionally a name for the vector (as a String) or each of the blocks (as a vector of Strings), or tags (as an Array{Any}) for the blocks can be specified.\n\n\n\n\n\n","category":"method"},{"location":"fevector/#ExtendableFEMBase.FEVectorBlock","page":"FEVector","title":"ExtendableFEMBase.FEVectorBlock","text":"struct FEVectorBlock{T, Tv, Ti, FEType, APT} <: AbstractArray{T, 1}\n\nblock of an FEVector that carries coefficients for an associated FESpace and can be assigned as an AbstractArray (getindex, setindex, size, length)\n\n\n\n\n\n","category":"type"},{"location":"fevector/#Base.append!-Union{Tuple{APT}, Tuple{FEType}, Tuple{Ti}, Tuple{Tv}, Tuple{T}, Tuple{FEVector{T}, FESpace{Tv, Ti, FEType, APT}}} where {T, Tv, Ti, FEType, APT}","page":"FEVector","title":"Base.append!","text":"append!(\n FEF::FEVector{T},\n FES::FESpace{Tv, Ti, FEType, APT};\n name,\n tag\n) -> Int64\n\n\nOverloaded append function for FEVector that adds a FEVectorBlock at the end.\n\n\n\n\n\n","category":"method"},{"location":"fevector/#Base.fill!-Tuple{FEVectorBlock, Any}","page":"FEVector","title":"Base.fill!","text":"fill!(b::FEVectorBlock, value)\n\n\nOverloaded fill function for FEVectorBlock (only fills the block, not the complete FEVector).\n\n\n\n\n\n","category":"method"},{"location":"fevector/#Base.length-Tuple{FEVectorBlock}","page":"FEVector","title":"Base.length","text":"length(FEB::FEVectorBlock) -> Int64\n\n\nCustom length function for FEVectorBlock that gives the coressponding number of degrees of freedoms of the associated FESpace\n\n\n\n\n\n","category":"method"},{"location":"fevector/#Base.length-Tuple{FEVector}","page":"FEVector","title":"Base.length","text":"length(FEF::FEVector) -> Int64\n\n\nCustom length function for FEVector that gives the number of defined FEMatrixBlocks in it\n\n\n\n\n\n","category":"method"},{"location":"fevector/#Base.show-Tuple{IO, FEVector}","page":"FEVector","title":"Base.show","text":"show(io::IO, FEF::FEVector)\n\n\nCustom show function for FEVector that prints some information on its blocks.\n\n\n\n\n\n","category":"method"},{"location":"fevector/#Base.view-Tuple{FEVectorBlock}","page":"FEVector","title":"Base.view","text":"returns a view of the part of the full FEVector that coressponds to the block. \n\n\n\n\n\n","category":"method"},{"location":"fevector/#ExtendableFEMBase.FESpaces-Union{Tuple{FEVector{T, Tv, Ti}}, Tuple{Ti}, Tuple{Tv}, Tuple{T}} where {T, Tv, Ti}","page":"FEVector","title":"ExtendableFEMBase.FESpaces","text":"FESpaces(\n FEV::FEVector{T, Tv, Ti}\n) -> Vector{T} where T<:FESpace\n\n\nReturns the vector of FEspaces for the blocks of the given FEVector.\n\n\n\n\n\n","category":"method"},{"location":"fevector/#ExtendableFEMBase.addblock!-Tuple{FEVectorBlock, AbstractVector}","page":"FEVector","title":"ExtendableFEMBase.addblock!","text":"addblock!(\n a::FEVectorBlock,\n b::AbstractVector;\n factor,\n offset\n)\n\n\nAdds Array b to FEVectorBlock a.\n\n\n\n\n\n","category":"method"},{"location":"fevector/#ExtendableFEMBase.addblock!-Tuple{FEVectorBlock, FEVectorBlock}","page":"FEVector","title":"ExtendableFEMBase.addblock!","text":"addblock!(a::FEVectorBlock, b::FEVectorBlock; factor)\n\n\nAdds FEVectorBlock b to FEVectorBlock a.\n\n\n\n\n\n","category":"method"},{"location":"fevector/#LinearAlgebra.dot-Union{Tuple{T}, Tuple{FEVectorBlock{T}, FEVectorBlock{T}}} where T","page":"FEVector","title":"LinearAlgebra.dot","text":"dot(a::FEVectorBlock{T}, b::FEVectorBlock{T}) -> Any\n\n\nScalar product between two FEVEctorBlocks\n\n\n\n\n\n","category":"method"},{"location":"pointevaluators/#PointEvaluator","page":"PointEvaluator","title":"PointEvaluator","text":"","category":"section"},{"location":"pointevaluators/","page":"PointEvaluator","title":"PointEvaluator","text":"Point evaluators allow to evaluate a finite element function (FEVector) at arbitrary points.","category":"page"},{"location":"pointevaluators/","page":"PointEvaluator","title":"PointEvaluator","text":"Modules = [ExtendableFEMBase]\nPages = [\"point_evaluator.jl\"]\nOrder = [:type, :function]","category":"page"},{"location":"pointevaluators/#ExtendableFEMBase.PointEvaluator","page":"PointEvaluator","title":"ExtendableFEMBase.PointEvaluator","text":"function Pointevaluator(\n\t[kernel!::Function],\n\toa_args::Array{<:Tuple{<:Any, DataType},1};\n\tkwargs...)\n\nGenerates a PointEvaluator that can evaluate the specified operator evaluations at arbitrary points. If no kernel function is given, the arguments are given directly. If a kernel is provided, the arguments are postprocessed accordingly and the kernel has to be conform to the interface\n\nkernel!(result, eval_args, qpinfo)\n\nwhere qpinfo allows to access information at the current evaluation point. Additionally the length of the result needs to be specified via the kwargs.\n\nEvaluation can be triggered via the evaluate function after an initialize! call.\n\nOperator evaluations are tuples that pair a tag (to identify an unknown or the position in the vector) with a FunctionOperator.\n\nKeyword arguments:\n\nresultdim: dimension of result field (default = length of operators). Default: 0\nparams: array of parameters that should be made available in qpinfo argument of kernel function. Default: nothing\nname: name for operator used in printouts. Default: ''PointEvaluator''\nverbosity: verbosity level. Default: 0\n\n\n\n\n\n","category":"type"},{"location":"pointevaluators/#ExtendableFEMBase.eval_func-Tuple{PointEvaluator}","page":"PointEvaluator","title":"ExtendableFEMBase.eval_func","text":"function eval_func(PE::PointEvaluator)\n\nYields the function (result, x) -> evaluate!(result,PE,x).\n\n\n\n\n\n","category":"method"},{"location":"pointevaluators/#ExtendableFEMBase.eval_func_bary-Tuple{PointEvaluator}","page":"PointEvaluator","title":"ExtendableFEMBase.eval_func_bary","text":"function eval_func_bary(PE::PointEvaluator)\n\nYields the function (result, xref, item) -> evaluate_bary!(result,PE,xref,item).\n\n\n\n\n\n","category":"method"},{"location":"pointevaluators/#ExtendableFEMBase.evaluate!-Tuple{Any, PointEvaluator, Any}","page":"PointEvaluator","title":"ExtendableFEMBase.evaluate!","text":"function evaluate!(\n\tresult,\n\tPE::PointEvaluator,\n\tx\n\t)\n\nEvaluates the PointEvaluator at the specified coordinates x. (To do so it internally calls CellFinder to find the cell and the barycentric coordinates of x and calls evaluate_bary!.)\n\n\n\n\n\n","category":"method"},{"location":"pointevaluators/#ExtendableFEMBase.evaluate_bary!-Tuple{Any, PointEvaluator, Any, Any}","page":"PointEvaluator","title":"ExtendableFEMBase.evaluate_bary!","text":"function evaluate_bary!(\n\tresult,\n\tPE::PointEvaluator,\n\txref, \n\titem\n\t)\n\nEvaluates the PointEvaluator at the specified reference coordinates in the cell with the specified item number.\n\n\n\n\n\n","category":"method"},{"location":"pointevaluators/#ExtendableFEMBase.initialize!-Union{Tuple{UT}, Tuple{T}, Tuple{PointEvaluator{T, UT}, Any}} where {T, UT}","page":"PointEvaluator","title":"ExtendableFEMBase.initialize!","text":"function initialize!(\n\tO::PointEvaluator,\n\tsol;\n\ttime = 0,\n\tkwargs...)\n\nInitializes the PointEvaluator for the specified solution.\n\n\n\n\n\n","category":"method"},{"location":"module_examples/Example210_LowLevelNavierStokes/#210-:-Navier-Stokes-Problem","page":"Example210_LowLevelNavierStokes","title":"210 : Navier-Stokes Problem","text":"","category":"section"},{"location":"module_examples/Example210_LowLevelNavierStokes/","page":"Example210_LowLevelNavierStokes","title":"Example210_LowLevelNavierStokes","text":"(source code)","category":"page"},{"location":"module_examples/Example210_LowLevelNavierStokes/","page":"Example210_LowLevelNavierStokes","title":"Example210_LowLevelNavierStokes","text":"Consider the Navier-Stokes problem that seeks u and p such that","category":"page"},{"location":"module_examples/Example210_LowLevelNavierStokes/","page":"Example210_LowLevelNavierStokes","title":"Example210_LowLevelNavierStokes","text":"beginaligned\n\t- mu Delta u + (u cdot nabla) u + nabla p = f\n\t\t\tmathrmdiv(u) = 0\nendaligned","category":"page"},{"location":"module_examples/Example210_LowLevelNavierStokes/","page":"Example210_LowLevelNavierStokes","title":"Example210_LowLevelNavierStokes","text":"The weak formulation seeks u in V = H^1_0(Omega) and p in Q = L^2_0(Omega) such that","category":"page"},{"location":"module_examples/Example210_LowLevelNavierStokes/","page":"Example210_LowLevelNavierStokes","title":"Example210_LowLevelNavierStokes","text":"beginaligned\n\tmu (nabla u nabla v) + ((u cdot nabla) u v) - (p mathrmdiv(v)) = (f v)\n\t textfor all v in V\n\t(q mathrmdiv(u)) = 0\n\t textfor all q in Q\nendaligned","category":"page"},{"location":"module_examples/Example210_LowLevelNavierStokes/","page":"Example210_LowLevelNavierStokes","title":"Example210_LowLevelNavierStokes","text":"This example computes a planar lattice flow with inhomogeneous Dirichlet boundary conditions (which requires some modification above). Newton's method with automatic differentation is used to handle the nonlinear convection term.","category":"page"},{"location":"module_examples/Example210_LowLevelNavierStokes/","page":"Example210_LowLevelNavierStokes","title":"Example210_LowLevelNavierStokes","text":"The computed solution for the default parameters looks like this:","category":"page"},{"location":"module_examples/Example210_LowLevelNavierStokes/","page":"Example210_LowLevelNavierStokes","title":"Example210_LowLevelNavierStokes","text":"(Image: )","category":"page"},{"location":"module_examples/Example210_LowLevelNavierStokes/","page":"Example210_LowLevelNavierStokes","title":"Example210_LowLevelNavierStokes","text":"module Example210_LowLevelNavierStokes\n\nusing ExtendableFEMBase\nusing ExtendableGrids\nusing ExtendableSparse\nusing GridVisualize\nusing ForwardDiff\nusing DiffResults\n\n# data for Poisson problem\nconst μ = 1e-2\nfunction f!(fval, x, t) # right-hand side\n\tfval[1] = 8.0 * π * π * μ * exp(-8.0 * π * π * μ * t) * sin(2.0 * π * x[1]) * sin(2.0 * π * x[2])\n\tfval[2] = 8.0 * π * π * μ * exp(-8.0 * π * π * μ * t) * cos(2.0 * π * x[1]) * cos(2.0 * π * x[2])\n\treturn nothing\nend\n\n# exact velocity (for boundary data and error calculation)\nfunction u!(uval, qpinfo)\n\tx = qpinfo.x\n\tt = qpinfo.time\n\tuval[1] = exp(-8.0 * π * π * μ * t) * sin(2.0 * π * x[1]) * sin(2.0 * π * x[2])\n\tuval[2] = exp(-8.0 * π * π * μ * t) * cos(2.0 * π * x[1]) * cos(2.0 * π * x[2])\n\treturn nothing\nend\n\n# exact pressure (for error calculation)\nfunction p!(pval, qpinfo)\n\tx = qpinfo.x\n\tt = qpinfo.time\n\tpval[1] = exp(-16 * pi * pi * μ * t) * (cos(4 * pi * x[1]) - cos(4 * pi * x[2])) / 4\n\treturn nothing\nend\n\nfunction main(; nref = 5, teval = 0, order = 2, Plotter = nothing)\n\n\t@assert order >= 2\n\n\t# create grid\n\tX = LinRange(0, 1, 2^nref + 1)\n\tY = LinRange(0, 1, 2^nref + 1)\n\tprintln(\"Creating grid...\")\n\t@time xgrid = simplexgrid(X, Y)\n\n\t# create FESpace\n\tprintln(\"Creating FESpace...\")\n\tFETypes = [H1Pk{2, 2, order}, H1Pk{1, 2, order - 1}]\n\t@time FES = [FESpace{FETypes[1]}(xgrid; name = \"velocity space\"),\n\t\tFESpace{FETypes[2]}(xgrid; name = \"pressure space\")]\n\tFES\n\n\t# solve\n\tsol = solve_stokes_lowlevel(FES; teval = teval)\n\n\t# move integral mean of pressure\n\tpmean = sum(compute_error(sol[2], nothing, order, 1))\n\tfor j ∈ 1:sol[2].FES.ndofs\n\t\tsol[2][j] -= pmean\n\tend\n\n\t# calculate l2 error\n\terror_u = sqrt(sum(compute_error(sol[1], u!, 2)))\n\terror_p = sqrt(sum(compute_error(sol[2], p!, 2)))\n\tprintln(\"\\nl2 error velo = $(error_u)\")\n\tprintln(\"l2 error pressure = $(error_p)\")\n\n\t# plot\n\tplt = GridVisualizer(; Plotter = Plotter, layout = (1, 1), clear = true, resolution = (500, 500))\n\tscalarplot!(plt[1, 1], xgrid, nodevalues(sol[1]; abs = true)[1, :]; title = \"|u| + quiver\", Plotter = Plotter)\n\tvectorplot!(plt[1, 1], xgrid, eval_func_bary(PointEvaluator([(1, Identity)], sol)), clear = false)\n\n\treturn sol, plt\nend\n\n# computes error and integrals\nfunction compute_error(uh::FEVectorBlock, u, order = get_polynomialorder(get_FEType(uh), uh.FES.xgrid[CellGeometries][1]), p = 2)\n\txgrid = uh.FES.xgrid\n\tFES = uh.FES\n\tEG = xgrid[UniqueCellGeometries][1]\n\tncomponents = get_ncomponents(uh)\n\tcellvolumes = xgrid[CellVolumes]\n\tcelldofs = FES[CellDofs]\n\terror = zeros(Float64, ncomponents, num_cells(xgrid))\n\tuhval = zeros(Float64, ncomponents)\n\tuval = zeros(Float64, ncomponents)\n\tL2G = L2GTransformer(EG, xgrid, ON_CELLS)\n\tQP = QPInfos(xgrid)\n\tqf = VertexRule(EG, order)\n\tFEB = FEEvaluator(FES, Identity, qf)\n\n\tfunction barrier(L2G::L2GTransformer)\n\t\tfor cell in 1:num_cells(xgrid)\n\t\t\tupdate_trafo!(L2G, cell)\n\t\t\tupdate_basis!(FEB, cell)\n\t\t\tfor (qp, weight) in enumerate(qf.w)\n\t\t\t\t# evaluate uh\n\t\t\t\tfill!(uhval, 0)\n\t\t\t\teval_febe!(uhval, FEB, view(view(uh), view(celldofs, :, cell)), qp)\n\n\t\t\t\t# evaluate u\n\t\t\t\tif u !== nothing\n\t\t\t\t\tfill!(uval, 0)\n\t\t\t\t\teval_trafo!(QP.x, L2G, qf.xref[qp])\n\t\t\t\t\tu(uval, QP)\n\t\t\t\tend\n\n\t\t\t\t# evaluate error\n\t\t\t\tfor d ∈ 1:ncomponents\n\t\t\t\t\terror[d, cell] += (uhval[d] - uval[d]) .^ p * cellvolumes[cell] * weight\n\t\t\t\tend\n\t\t\tend\n\t\tend\n\tend\n\n\tbarrier(L2G)\n\treturn error\nend\n\nfunction solve_stokes_lowlevel(FES; teval = 0)\n\n\tprintln(\"Initializing system...\")\n\tsol = FEVector(FES)\n\tA = FEMatrix(FES)\n\tb = FEVector(FES)\n\t@time update_system! = prepare_assembly!(A, b, FES[1], FES[2], sol)\n\t@time update_system!(true, false)\n\tAlin = deepcopy(A) ## = keep linear part of system matrix\n\tblin = deepcopy(b) ## = keep linear part of right-hand side\n\n\tprintln(\"Prepare boundary conditions...\")\n\t@time begin\n\t\tu_init = FEVector(FES)\n\t\tinterpolate!(u_init[1], u!; time = teval)\n\t\tfixed_dofs = boundarydofs(FES[1])\n\t\tpush!(fixed_dofs, FES[1].ndofs + 1) ## fix one pressure dof\n\tend\n\n\tfor it ∈ 1:20\n\t\t# solve\n\t\tprintln(\"\\nITERATION $it\\n=============\")\n\t\tprintln(\"Solving linear system...\")\n\t\t@time copyto!(sol.entries, A.entries \\ b.entries)\n\t\tres = A.entries.cscmatrix * sol.entries .- b.entries\n\t\tfor dof in fixed_dofs\n\t\t\tres[dof] = 0\n\t\tend\n\t\tlinres = norm(res)\n\t\tprintln(\"linear residual = $linres\")\n\n\t\tfill!(A.entries.cscmatrix.nzval, 0)\n\t\tfill!(b.entries, 0)\n\t\tprintln(\"Updating linear system...\")\n\t\t@time begin\n\t\t\tupdate_system!(false, true)\n\t\t\tA.entries.cscmatrix += Alin.entries.cscmatrix\n\t\t\tb.entries .+= blin.entries\n\t\tend\n\n\t\t# fix boundary dofs\n\t\tfor dof in fixed_dofs\n\t\t\tA.entries[dof, dof] = 1e60\n\t\t\tb.entries[dof] = 1e60 * u_init.entries[dof]\n\t\tend\n\t\tExtendableSparse.flush!(A.entries)\n\n\t\t# calculate nonlinear residual\n\t\tres = A.entries.cscmatrix * sol.entries .- b.entries\n\t\tfor dof in fixed_dofs\n\t\t\tres[dof] = 0\n\t\tend\n\t\tnlres = norm(res)\n\t\tprintln(\"nonlinear residual = $nlres\")\n\t\tif nlres < max(1e-12, 20 * linres)\n\t\t\tbreak\n\t\tend\n\tend\n\n\treturn sol\nend\n\nfunction prepare_assembly!(A, b, FESu, FESp, sol; teval = 0)\n\n\tA = A.entries\n\tb = b.entries\n\tsol = sol.entries\n\txgrid = FESu.xgrid\n\tEG = xgrid[UniqueCellGeometries][1]\n\tFEType_u = eltype(FESu)\n\tFEType_p = eltype(FESp)\n\tL2G = L2GTransformer(EG, xgrid, ON_CELLS)\n\tcellvolumes = xgrid[CellVolumes]\n\tncells::Int = num_cells(xgrid)\n\n\t# dofmap\n\tCellDofs_u = FESu[ExtendableFEMBase.CellDofs]\n\tCellDofs_p = FESp[ExtendableFEMBase.CellDofs]\n\toffset_p = FESu.ndofs\n\n\t# quadrature formula\n\tqf = QuadratureRule{Float64, EG}(3 * get_polynomialorder(FEType_u, EG) - 1)\n\tweights::Vector{Float64} = qf.w\n\txref::Vector{Vector{Float64}} = qf.xref\n\tnweights::Int = length(weights)\n\n\t# FE basis evaluator\n\tFEBasis_∇u = FEEvaluator(FESu, Gradient, qf)\n\t∇uvals = FEBasis_∇u.cvals\n\tFEBasis_idu = FEEvaluator(FESu, Identity, qf)\n\tiduvals = FEBasis_idu.cvals\n\tFEBasis_idp = FEEvaluator(FESp, Identity, qf)\n\tidpvals = FEBasis_idp.cvals\n\n\t# prepare automatic differentation of convection operator\n\tfunction operator!(result, input)\n\t\t# result = (u ⋅ ∇)u\n\t\tresult[1] = input[1] * input[3] + input[2] * input[4]\n\t\tresult[2] = input[1] * input[5] + input[2] * input[6]\n\tend\n\tresult = Vector{Float64}(undef, 2)\n\tinput = Vector{Float64}(undef, 6)\n\ttempV = zeros(Float64, 2)\n\tDresult = DiffResults.JacobianResult(result, input)\n\tcfg = ForwardDiff.JacobianConfig(operator!, result, input, ForwardDiff.Chunk{6}())\n\tjac = DiffResults.jacobian(Dresult)\n\tvalue = DiffResults.value(Dresult)\n\n\t# ASSEMBLY LOOP\n\tfunction barrier(EG, L2G::L2GTransformer, linear::Bool, nonlinear::Bool)\n\t\t# barrier function to avoid allocations caused by L2G\n\n\t\tndofs4cell_u::Int = get_ndofs(ON_CELLS, FEType_u, EG)\n\t\tndofs4cell_p::Int = get_ndofs(ON_CELLS, FEType_p, EG)\n\t\tAloc = zeros(Float64, ndofs4cell_u, ndofs4cell_u)\n\t\tBloc = zeros(Float64, ndofs4cell_u, ndofs4cell_p)\n\t\tdof_j::Int, dof_k::Int = 0, 0\n\t\tfval::Vector{Float64} = zeros(Float64, 2)\n\t\tx::Vector{Float64} = zeros(Float64, 2)\n\n\t\tfor cell ∈ 1:ncells\n\t\t\t# update FE basis evaluators\n\t\t\tupdate_basis!(FEBasis_∇u, cell)\n\t\t\tupdate_basis!(FEBasis_idu, cell)\n\t\t\tupdate_basis!(FEBasis_idp, cell)\n\n\t\t\t# assemble local stiffness matrix (symmetric)\n\t\t\tif (linear)\n\t\t\t\tfor j ∈ 1:ndofs4cell_u, k ∈ 1:ndofs4cell_u\n\t\t\t\t\ttemp = 0\n\t\t\t\t\tfor qp ∈ 1:nweights\n\t\t\t\t\t\ttemp += weights[qp] * dot(view(∇uvals, :, j, qp), view(∇uvals, :, k, qp))\n\t\t\t\t\tend\n\t\t\t\t\tAloc[k, j] = μ * temp\n\t\t\t\tend\n\n\t\t\t\t# assemble div-pressure coupling\n\t\t\t\tfor j ∈ 1:ndofs4cell_u, k ∈ 1:ndofs4cell_p\n\t\t\t\t\ttemp = 0\n\t\t\t\t\tfor qp ∈ 1:nweights\n\t\t\t\t\t\ttemp -= weights[qp] * (∇uvals[1, j, qp] + ∇uvals[4, j, qp]) *\n\t\t\t\t\t\t\t\tidpvals[1, k, qp]\n\t\t\t\t\tend\n\t\t\t\t\tBloc[j, k] = temp\n\t\t\t\tend\n\t\t\t\tBloc .*= cellvolumes[cell]\n\n\t\t\t\t# assemble right-hand side\n\t\t\t\tupdate_trafo!(L2G, cell)\n\t\t\t\tfor j ∈ 1:ndofs4cell_u\n\t\t\t\t\t# right-hand side\n\t\t\t\t\ttemp = 0\n\t\t\t\t\tfor qp ∈ 1:nweights\n\t\t\t\t\t\t# get global x for quadrature point\n\t\t\t\t\t\teval_trafo!(x, L2G, xref[qp])\n\t\t\t\t\t\t# evaluate (f(x), v_j(x))\n\t\t\t\t\t\tf!(fval, x, teval)\n\t\t\t\t\t\ttemp += weights[qp] * dot(view(iduvals, :, j, qp), fval)\n\t\t\t\t\tend\n\t\t\t\t\t# write into global vector\n\t\t\t\t\tdof_j = CellDofs_u[j, cell]\n\t\t\t\t\tb[dof_j] += temp * cellvolumes[cell]\n\t\t\t\tend\n\t\t\tend\n\n\t\t\t# assemble nonlinear term\n\t\t\tif (nonlinear)\n\t\t\t\tfor qp ∈ 1:nweights\n\t\t\t\t\tfill!(input, 0)\n\t\t\t\t\tfor j ∈ 1:ndofs4cell_u\n\t\t\t\t\t\tdof_j = CellDofs_u[j, cell]\n\t\t\t\t\t\tfor d ∈ 1:2\n\t\t\t\t\t\t\tinput[d] += sol[dof_j] * iduvals[d, j, qp]\n\t\t\t\t\t\tend\n\t\t\t\t\t\tfor d ∈ 1:4\n\t\t\t\t\t\t\tinput[2+d] += sol[dof_j] * ∇uvals[d, j, qp]\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\n\t\t\t\t\t# evaluate jacobian\n\t\t\t\t\tForwardDiff.chunk_mode_jacobian!(Dresult, operator!, result, input, cfg)\n\n\t\t\t\t\t# update matrix\n\t\t\t\t\tfor j ∈ 1:ndofs4cell_u\n\t\t\t\t\t\t# multiply ansatz function with local jacobian\n\t\t\t\t\t\tfill!(tempV, 0)\n\t\t\t\t\t\tfor d ∈ 1:2\n\t\t\t\t\t\t\ttempV[1] += jac[1, d] * iduvals[d, j, qp]\n\t\t\t\t\t\t\ttempV[2] += jac[2, d] * iduvals[d, j, qp]\n\t\t\t\t\t\tend\n\t\t\t\t\t\tfor d ∈ 1:4\n\t\t\t\t\t\t\ttempV[1] += jac[1, 2+d] * ∇uvals[d, j, qp]\n\t\t\t\t\t\t\ttempV[2] += jac[2, 2+d] * ∇uvals[d, j, qp]\n\t\t\t\t\t\tend\n\n\t\t\t\t\t\t# multiply test function operator evaluation\n\t\t\t\t\t\tfor k ∈ 1:ndofs4cell_u\n\t\t\t\t\t\t\tAloc[k, j] += dot(tempV, view(iduvals, :, k, qp)) * weights[qp]\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\n\t\t\t\t\t# update rhs\n\t\t\t\t\tmul!(tempV, jac, input)\n\t\t\t\t\ttempV .-= value\n\t\t\t\t\tfor j ∈ 1:ndofs4cell_u\n\t\t\t\t\t\tdof_j = CellDofs_u[j, cell]\n\t\t\t\t\t\tb[dof_j] += dot(tempV, view(iduvals, :, j, qp)) * weights[qp] * cellvolumes[cell]\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\tend\n\n\t\t\t# add local matrices to global matrix\n\t\t\tAloc .*= cellvolumes[cell]\n\t\t\tfor j ∈ 1:ndofs4cell_u\n\t\t\t\tdof_j = CellDofs_u[j, cell]\n\t\t\t\tfor k ∈ 1:ndofs4cell_u\n\t\t\t\t\tdof_k = CellDofs_u[k, cell]\n\t\t\t\t\trawupdateindex!(A, +, Aloc[j, k], dof_j, dof_k)\n\t\t\t\tend\n\t\t\t\tif (linear)\n\t\t\t\t\tfor k ∈ 1:ndofs4cell_p\n\t\t\t\t\t\tdof_k = CellDofs_p[k, cell] + offset_p\n\t\t\t\t\t\trawupdateindex!(A, +, Bloc[j, k], dof_j, dof_k)\n\t\t\t\t\t\trawupdateindex!(A, +, Bloc[j, k], dof_k, dof_j)\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\tend\n\t\t\tfill!(Aloc, 0)\n\t\t\tfill!(Bloc, 0)\n\t\tend\n\tend\n\n\tfunction update_system!(linear::Bool, nonlinear::Bool)\n\t\tbarrier(EG, L2G, linear, nonlinear)\n\t\tflush!(A)\n\tend\n\tupdate_system!\nend\n\nfunction generateplots(dir = pwd(); Plotter = nothing, kwargs...)\n\t~, plt = main(; Plotter = Plotter, kwargs...)\n\tscene = GridVisualize.reveal(plt)\n\tGridVisualize.save(joinpath(dir, \"example210.png\"), scene; Plotter = Plotter)\nend\nend #module","category":"page"},{"location":"module_examples/Example210_LowLevelNavierStokes/","page":"Example210_LowLevelNavierStokes","title":"Example210_LowLevelNavierStokes","text":"","category":"page"},{"location":"module_examples/Example210_LowLevelNavierStokes/","page":"Example210_LowLevelNavierStokes","title":"Example210_LowLevelNavierStokes","text":"This page was generated using Literate.jl.","category":"page"},{"location":"segmentintegrators/#SegmentIntegrator","page":"SegmentIntegrator","title":"SegmentIntegrator","text":"","category":"section"},{"location":"segmentintegrators/","page":"SegmentIntegrator","title":"SegmentIntegrator","text":"Segment integrators allow to integrate a finite element function (FEVector) along arbitrary lines through mesh cells.","category":"page"},{"location":"segmentintegrators/","page":"SegmentIntegrator","title":"SegmentIntegrator","text":"Modules = [ExtendableFEMBase]\nPages = [\"segment_integrator.jl\"]\nOrder = [:type, :function]","category":"page"},{"location":"segmentintegrators/#ExtendableFEMBase.SegmentIntegrator-Tuple{Any, Any, Vector{<:Tuple{Any, DataType}}}","page":"SegmentIntegrator","title":"ExtendableFEMBase.SegmentIntegrator","text":"function SegmentIntegrator(\n\tEG::ElementGeometry,\n\t[kernel!::Function],\n\toa_args::Array{<:Tuple{<:Any, DataType},1};\n\tkwargs...)\n\nGenerates an SegmentIntegrator that can intgrate over segments of the specified geometry EG. To do so, it evaluates, at each quadrature point, the specified operator evaluations, postprocesses them with the kernel function (if provided) and accumulates the results with the quadrature weights. If no kernel is given, the arguments are integrated directly. If a kernel is provided it has be conform to the interface\n\nkernel!(result, eval_args, qpinfo)\n\nwhere qpinfo allows to access information at the current quadrature point. Additionally the length of the result needs to be specified via the kwargs.\n\nEvaluation can be triggered via the integrate_segment! function after an initialize!\n\nOperator evaluations are tuples that pair a tag (to identify an unknown or the position in the vector) with a FunctionOperator.\n\nKeyword arguments:\n\nfactor: factor that should be multiplied during assembly. Default: 1\nresultdim: dimension of result field (default = length of arguments). Default: 0\nmatrix_mode: integrator integrates basis functions of FEspace seperately to assembly a matrix that maps solution to segment integrations (requires that kernel is linear). Default: false\nname: name for operator used in printouts. Default: ''SegmentIntegrator''\nparams: array of parameters that should be made available in qpinfo argument of kernel function. Default: nothing\nquadorder: quadrature order. Default: ''auto''\nbonus_quadorder: additional quadrature order added to quadorder. Default: 0\nentrytolerance: threshold to add entry to sparse matrix (only in matrixmode). Default: 0\nverbosity: verbosity level. Default: 0\n\n\n\n\n\n","category":"method"},{"location":"segmentintegrators/#ExtendableFEMBase.initialize!-Union{Tuple{UT}, Tuple{T}, Tuple{SegmentIntegrator{T, UT}, Any}} where {T, UT}","page":"SegmentIntegrator","title":"ExtendableFEMBase.initialize!","text":"function initialize!(\n\tO::SegmentIntegrator{T, UT},\n\tsol;\n\ttime = 0,\n\tkwargs...)\n\nInitializes the SegmentIntegrator for the specified solution.\n\n\n\n\n\n","category":"method"},{"location":"segmentintegrators/#ExtendableFEMBase.integrate_segment!-Union{Tuple{T}, Tuple{Vector{T}, SegmentIntegrator, Array{Vector{T}, 1}, Array{Vector{T}, 1}, Any}} where T","page":"SegmentIntegrator","title":"ExtendableFEMBase.integrate_segment!","text":"function integrate_segment!(\n\tresult::Array{T,1},\n\tSI::SegmentIntegrator,\n\tw::Array{Array{T,1},1},\n\tb::Array{Array{T,1},1},\n\titem\n\t) where {T}\n\nIntegrate a segment with world coordinates w and barycentric coordinates b in the cell with the given item number.\n\n\n\n\n\n","category":"method"},{"location":"plots/#Plots","page":"Plots","title":"Plots","text":"","category":"section"},{"location":"plots/#GridVisualize/PlutoVista","page":"Plots","title":"GridVisualize/PlutoVista","text":"","category":"section"},{"location":"plots/","page":"Plots","title":"Plots","text":"Plotting is possible e.g. via Nodal Evaluations and the plot routines from ExtendableGrids.jl. In Pluto notebooks it is recommended to use PlutoVista.jl as an backend.","category":"page"},{"location":"plots/#UnicodePlots","page":"Plots","title":"UnicodePlots","text":"","category":"section"},{"location":"plots/","page":"Plots","title":"Plots","text":"For a fast and rough peak several UnicodePlots plotters are available:","category":"page"},{"location":"plots/","page":"Plots","title":"Plots","text":"Modules = [ExtendableFEMBase]\nPages = [\"plots.jl\"]\nOrder = [:type, :function]","category":"page"},{"location":"plots/#ExtendableFEMBase.unicode_gridplot-Tuple{ExtendableGrids.ExtendableGrid}","page":"Plots","title":"ExtendableFEMBase.unicode_gridplot","text":"function unicode_gridplot(\n\txgrid::ExtendableGrid;\n\ttitle = \"gridplot\",\n\tresolution = (40,20),\n\tcolor = (200,200,200),\n\tbface_color = (255,0,0),\n\tCanvasType = BrailleCanvas,\n\tplot_based = ON_CELLS, # or ON_FACES/ON_EDGES\n\tkwargs...\n\nPlots the grid on a UnicodePlots canvas (default: BrailleCanvas) by drawing all edges in the triangulation.\n\n\n\n\n\n","category":"method"},{"location":"plots/#ExtendableFEMBase.unicode_scalarplot-Tuple{FEVectorBlock}","page":"Plots","title":"ExtendableFEMBase.unicode_scalarplot","text":"function unicode_scalarplot(\n\tu::FEVectorBlock; \n\tcomponents = 1:get_ncomponents(u),\n\tabs = false,\n\tresolution = (30,30),\n\tcolormap = :viridis,\n\ttitle = u.name,\n\tkwargs...)\n\nPlots components of the finite element function in the FEVectorBlock u by using a lazy_interpolate! onto a coarse uniform mesh and UnicodePlots.jl lineplot or heatmap for 1D or 2D, respectively.\n\nIn 1D all components all plotted in the same lineplot, while in 2D all components are plotted in a separate heatmap.\n\nIf abs = true, only the absolute value over the components is plotted.\n\n\n\n\n\n","category":"method"},{"location":"functionoperators/#Function-Operators","page":"Function Operators","title":"Function Operators","text":"","category":"section"},{"location":"functionoperators/#StandardFunctionOperators","page":"Function Operators","title":"StandardFunctionOperators","text":"","category":"section"},{"location":"functionoperators/","page":"Function Operators","title":"Function Operators","text":"StandardFunctionOperators are abstract types that encode primitive (linear) operators (like Identity, Gradient etc.) used to dispatch different evaluations of finite element basis functions.","category":"page"},{"location":"functionoperators/#List-of-primitive-operators","page":"Function Operators","title":"List of primitive operators","text":"","category":"section"},{"location":"functionoperators/","page":"Function Operators","title":"Function Operators","text":"StandardFunctionOperator Description Mathematically\nIdentity identity v rightarrow v\nIdentityComponent{c} identity of c-th component v rightarrow v_c\nNormalFlux normal flux (function times normal) v rightarrow v cdot vecn (only ON_FACES)\nTangentFlux tangent flux (function times tangent) v rightarrow v cdot vect (only ON_EDGES)\nGradient gradient/Jacobian (as a vector) v rightarrow nabla v\nSymmetricGradient symmetric part of the gradient v rightarrow Voigt(mathrmsym(nabla v))\nDivergence divergence v rightarrow mathrmdiv(v) = nabla cdot v\nCurlScalar curl operator 1D to 2D (rotated gradient) v rightarrow -dvdx_2dvdx_1\nCurl2D curl operator 2D to 1D v rightarrow dv_1dx_2 - dv_2dx_1\nCurl3D curl operator 3D to 3D v rightarrow nabla times v\nHessian Hesse matrix = all 2nd order derivatives (as a vector) v rightarrow D^2 v (e.g. in 2D: xx,xy,yx,yy for each component)\nSymmetricHessian{a} symmetric part of Hesse matrix, offdiagonals scaled by a v rightarrow sym(D^2 v) (e.g. in 2D: xx,yy,a*xy for each component)\nLaplacian Laplace Operator (diagonal of Hessian) v rightarrow Delta v (e.g. in 2D: xx,yy for each component)","category":"page"},{"location":"functionoperators/","page":"Function Operators","title":"Function Operators","text":"note: Note\nAs each finite element type is transformed differently from the reference domain to the general domain, the evaluation of each function operator has to be implemented for each finite element class. Currently, not every function operator works in any dimension and for any finite element. More evaluations are added as soon as they are needed (and possibly upon request). Also, the function operators can be combined with user-defined actions to evaluate other operators that can be build from the ones available (e.g. the deviator).","category":"page"},{"location":"functionoperators/#ReconstructionOperators","page":"Function Operators","title":"ReconstructionOperators","text":"","category":"section"},{"location":"functionoperators/","page":"Function Operators","title":"Function Operators","text":"There are special operators that allow to evaluate a primitive operator of some discrete reconstructed version of a testfunction. ","category":"page"},{"location":"functionoperators/","page":"Function Operators","title":"Function Operators","text":"Modules = [ExtendableFEMBase]\nPages = [\"reconstructionoperators.jl\"]\nOrder = [:type, :function]","category":"page"},{"location":"functionoperators/#ExtendableFEMBase.Reconstruct","page":"Function Operators","title":"ExtendableFEMBase.Reconstruct","text":"abstract type Reconstruct{FETypeR, O} <: ExtendableFEMBase.ReconstructionOperator\n\nreconstruction operator: evaluates a reconstructed version of the finite element function.\n\nFETypeR specifies the reconstruction space (needs to be defined for the finite element that it is applied to). O specifies the StandardFunctionOperator that shall be evaluated.\n\n\n\n\n\n","category":"type"},{"location":"functionoperators/#Divergence-free-reconstruction-operators","page":"Function Operators","title":"Divergence-free reconstruction operators","text":"","category":"section"},{"location":"functionoperators/","page":"Function Operators","title":"Function Operators","text":"For gradient-robust discretisations of certain classical non divergence-conforming ansatz spaces, reconstruction operators are available that map a discretely divergence-free H1 function to a pointwise divergence-free Hdiv function. So far such operators are available for the vector-valued Crouzeix-Raviart (H1CR) and Bernardi–Raugel (H1BR) finite element types, as well as for the P2-bubble (H1P2B) finite element type in two dimensions.","category":"page"},{"location":"functionoperators/","page":"Function Operators","title":"Function Operators","text":"Example: Reconst{HDIVRT0{d}, Identity} gives the reconstruction of the Identity operator into HDIVRT0 (and is available for H1BR{d} and H1CR{d} for d = 1,2)","category":"page"},{"location":"functionoperators/#Operator-Pairs-(experimental)","page":"Function Operators","title":"Operator Pairs (experimental)","text":"","category":"section"},{"location":"functionoperators/","page":"Function Operators","title":"Function Operators","text":"Two function operators can be put into an OperatorPair so that one can provide effectively two operators in each argument of an assembly pattern. However, the user should make sure that both operators can be evaluated together reasonably (meaning both should be well-defined on the element geometries and the finite element space where the argument will be evaluated, and the action of the operator has to operate with coressponding input and result fields). This feature is still experimental and might have issues in some cases. OperatorTriple for a combination of three operators is also available.","category":"page"},{"location":"functionoperators/","page":"Function Operators","title":"Function Operators","text":"OperatorPair\nOperatorTriple","category":"page"},{"location":"functionoperators/#ExtendableFEMBase.OperatorPair","page":"Function Operators","title":"ExtendableFEMBase.OperatorPair","text":"abstract type OperatorPair{<:StandardFunctionOperator,<:StandardFunctionOperator} <: StandardFunctionOperator\n\nallows to evaluate two operators in place of one, e.g. OperatorPair{Identity,Gradient}.\n\n\n\n\n\n","category":"type"},{"location":"functionoperators/#ExtendableFEMBase.OperatorTriple","page":"Function Operators","title":"ExtendableFEMBase.OperatorTriple","text":"abstract type OperatorTriple{<:StandardFunctionOperator,<:StandardFunctionOperator} <: StandardFunctionOperator\n\nallows to evaluate three operators in place of one, e.g. OperatorTriple{Identity,Gradient,Hessian}.\n\n\n\n\n\n","category":"type"},{"location":"quadrature/#Quadrature","page":"Quadrature","title":"Quadrature","text":"","category":"section"},{"location":"quadrature/","page":"Quadrature","title":"Quadrature","text":"Usually quadrature is a hidden layer as quadrature rules are chosen automatically based on the polynomial degree of the ansatz functions and the specified quadorder of the user data.","category":"page"},{"location":"quadrature/","page":"Quadrature","title":"Quadrature","text":"Hence, quadrature rules are only needed if the user wants write his own low-level assembly.","category":"page"},{"location":"quadrature/","page":"Quadrature","title":"Quadrature","text":"Quadrature rules consist of points (coordinates of evaluation points with respect to reference geometry) and weights. There are constructors for several AbstractElementGeometries (from ExtendableGrids) and different order (some have generic formulas for arbitrary order), see below for a detailed list.","category":"page"},{"location":"quadrature/","page":"Quadrature","title":"Quadrature","text":"Modules = [ExtendableFEMBase]\nPages = [\"quadrature.jl\"]\nOrder = [:type, :function]","category":"page"},{"location":"quadrature/#ExtendableFEMBase.QuadratureRule","page":"Quadrature","title":"ExtendableFEMBase.QuadratureRule","text":"abstract type QuadratureRule{T<:Real, ET<:ExtendableGrids.AbstractElementGeometry}\n\nA struct that contains the name of the quadrature rule, the reference points and the weights for the parameter-determined element geometry.\n\n\n\n\n\n","category":"type"},{"location":"quadrature/#ExtendableFEMBase.QuadratureRule-Union{Tuple{Int64}, Tuple{ET}, Tuple{T}} where {T<:Real, ET<:ExtendableGrids.AbstractElementGeometry0D}","page":"Quadrature","title":"ExtendableFEMBase.QuadratureRule","text":"function QuadratureRule{T,ET}(order::Int) where {T<:Real, ET <: AbstractElementGeometry0D}\n\nConstructs 0D quadrature rule of specified order (always point evaluation).\n\n\n\n\n\n","category":"method"},{"location":"quadrature/#ExtendableFEMBase.QuadratureRule-Union{Tuple{Int64}, Tuple{ET}, Tuple{T}} where {T<:Real, ET<:ExtendableGrids.AbstractElementGeometry1D}","page":"Quadrature","title":"ExtendableFEMBase.QuadratureRule","text":"function QuadratureRule{T,ET}(order::Int) where {T<:Real, ET <: AbstractElementGeometry1D}\n\nConstructs 1D quadrature rule of specified order.\n\n\n\n\n\n","category":"method"},{"location":"quadrature/#ExtendableFEMBase.QuadratureRule-Union{Tuple{Int64}, Tuple{ET}, Tuple{T}} where {T<:Real, ET<:Parallelepiped3D}","page":"Quadrature","title":"ExtendableFEMBase.QuadratureRule","text":"function QuadratureRule{T,ET}(order::Int) where {T<:Real, ET <: Parallelepiped3D}\n\nConstructs quadrature rule on Parallelepiped3D of specified order.\n\n\n\n\n\n","category":"method"},{"location":"quadrature/#ExtendableFEMBase.QuadratureRule-Union{Tuple{Int64}, Tuple{ET}, Tuple{T}} where {T<:Real, ET<:Parallelogram2D}","page":"Quadrature","title":"ExtendableFEMBase.QuadratureRule","text":"function QuadratureRule{T,ET}(order::Int) where {T<:Real, ET <: Parallelogram2D}\n\nConstructs quadrature rule on Parallelogram2D of specified order.\n\n\n\n\n\n","category":"method"},{"location":"quadrature/#ExtendableFEMBase.QuadratureRule-Union{Tuple{Int64}, Tuple{ET}, Tuple{T}} where {T<:Real, ET<:Tetrahedron3D}","page":"Quadrature","title":"ExtendableFEMBase.QuadratureRule","text":"function QuadratureRule{T,ET}(order::Int) where {T<:Real, ET <: Tetrahedron3D}\n\nConstructs quadrature rule on Tetrahedron3D of specified order.\n\n\n\n\n\n","category":"method"},{"location":"quadrature/#ExtendableFEMBase.QuadratureRule-Union{Tuple{Int64}, Tuple{ET}, Tuple{T}} where {T<:Real, ET<:Triangle2D}","page":"Quadrature","title":"ExtendableFEMBase.QuadratureRule","text":"function QuadratureRule{T,ET}(order::Int) where {T<:Real, ET <: Triangle2D}\n\nConstructs quadrature rule on Triangle2D of specified order.\n\n\n\n\n\n","category":"method"},{"location":"quadrature/#Base.eltype-Union{Tuple{QuadratureRule{T, ET}}, Tuple{ET}, Tuple{T}} where {T<:Real, ET<:ExtendableGrids.AbstractElementGeometry}","page":"Quadrature","title":"Base.eltype","text":"eltype(\n _::QuadratureRule{T<:Real, ET<:ExtendableGrids.AbstractElementGeometry}\n) -> Any\n\n\nCustom eltype function for QuadratureRule{T,ET}.\n\n\n\n\n\n","category":"method"},{"location":"quadrature/#Base.show-Tuple{IO, QuadratureRule}","page":"Quadrature","title":"Base.show","text":"show(io::IO, Q::QuadratureRule)\n\n\nCustom show function for QuadratureRule{T,ET} that prints some information.\n\n\n\n\n\n","category":"method"},{"location":"quadrature/#ExtendableFEMBase.integrate!-Union{Tuple{Ti}, Tuple{Tv}, Tuple{T}, Tuple{AbstractArray{T}, ExtendableGrids.ExtendableGrid{Tv, Ti}, Type{<:ExtendableGrids.AssemblyType}, Any}} where {T, Tv, Ti}","page":"Quadrature","title":"ExtendableFEMBase.integrate!","text":"integrate!(\n integral4items::AbstractArray{T},\n grid::ExtendableGrids.ExtendableGrid{Tv, Ti},\n AT::Type{<:ExtendableGrids.AssemblyType},\n integrand;\n offset,\n bonus_quadorder,\n quadorder,\n time,\n items,\n force_quadrature_rule,\n kwargs...\n)\n\n\nIntegration that writes result on every item into integral4items.\n\n\n\n\n\n","category":"method"},{"location":"quadrature/#ExtendableFEMBase.integrate-Tuple{ExtendableGrids.ExtendableGrid, Type{<:ExtendableGrids.AssemblyType}, Any, Int64}","page":"Quadrature","title":"ExtendableFEMBase.integrate","text":"integrate(\n grid::ExtendableGrids.ExtendableGrid,\n AT::Type{<:ExtendableGrids.AssemblyType},\n integrand!,\n resultdim::Int64;\n T,\n kwargs...\n) -> Union{Float64, Vector{Float64}}\n\n\nIntegration that returns total integral.\n\n\n\n\n\n","category":"method"},{"location":"quadrature/#ExtendableFEMBase.ref_integrate!-Tuple{AbstractArray, Type{<:ExtendableGrids.AbstractElementGeometry}, Int64, Function}","page":"Quadrature","title":"ExtendableFEMBase.ref_integrate!","text":"ref_integrate!(\n integral::AbstractArray,\n EG::Type{<:ExtendableGrids.AbstractElementGeometry},\n order::Int64,\n integrand::Function\n)\n\n\nIntegration for reference basis functions on reference domains (merely for testing stuff).\n\nNote: area of reference geometry is not multiplied\n\n\n\n\n\n","category":"method"},{"location":"fespace/#FESpace","page":"FESpace","title":"FESpace","text":"","category":"section"},{"location":"fespace/","page":"FESpace","title":"FESpace","text":"To generate a finite element space only a finite element type and a grid is needed, dofmaps are generated automatically on their first demand.","category":"page"},{"location":"fespace/","page":"FESpace","title":"FESpace","text":"Modules = [ExtendableFEMBase]\nPages = [\"finiteelements.jl\"]\nOrder = [:type, :function]","category":"page"},{"location":"fespace/#ExtendableFEMBase.FESpace","page":"FESpace","title":"ExtendableFEMBase.FESpace","text":"struct FESpace{Tv, Ti, FEType<:AbstractFiniteElement,AT<:AssemblyType}\n\tname::String # full name of finite element space (used in messages)\n\tbroken::Bool # if true, broken dofmaps are generated\n\tndofs::Int # total number of dofs\n\tcoffset::Int # offset for component dofs\n\txgrid::ExtendableGrid[Tv,Ti} # link to xgrid \n\tdofgrid::ExtendableGrid{Tv,Ti}\t # link to (sub) grid used for dof numbering (expected to be equal to or child grid of xgrid)\n\tdofmaps::Dict{Type{<:AbstractGridComponent},Any} # backpack with dofmaps\nend\n\nA struct that has a finite element type as parameter and carries dofmaps (CellDofs, FaceDofs, BFaceDofs) plus additional grid information and access to arrays holding coefficients if needed.\n\n\n\n\n\n","category":"type"},{"location":"fespace/#ExtendableFEMBase.FESpace-Union{Tuple{ExtendableGrids.ExtendableGrid{Tv, Ti}}, Tuple{AT}, Tuple{FEType}, Tuple{Ti}, Tuple{Tv}} where {Tv, Ti, FEType<:AbstractFiniteElement, AT<:ExtendableGrids.AssemblyType}","page":"FESpace","title":"ExtendableFEMBase.FESpace","text":"function FESpace{FEType<:AbstractFiniteElement,AT<:AssemblyType}(\n\txgrid::ExtendableGrid{Tv,Ti};\n\tname = \"\",\n\tbroken::Bool = false)\n\nConstructor for FESpace of the given FEType, AT = ONCELLS/ONFACES/ONEDGES generates a finite elements space on the cells/faces/edges of the provided xgrid (if omitted ONCELLS is used as default). The broken switch allows to generate a broken finite element space (that is piecewise H1/Hdiv/HCurl). If no name is provided it is generated automatically from FEType. If no AT is provided, the space is generated ON_CELLS.\n\n\n\n\n\n","category":"method"},{"location":"fespace/#Base.eltype-Union{Tuple{FESpace{Tv, Ti, FEType, APT}}, Tuple{APT}, Tuple{FEType}, Tuple{Ti}, Tuple{Tv}} where {Tv, Ti, FEType<:AbstractFiniteElement, APT}","page":"FESpace","title":"Base.eltype","text":"eltype(\n _::FESpace{Tv, Ti, FEType<:AbstractFiniteElement, APT}\n) -> Type{FEType} where FEType<:AbstractFiniteElement\n\n\nCustom eltype function for FESpace returns the finite element type parameter of the finite element space.\n\n\n\n\n\n","category":"method"},{"location":"fespace/#Base.get!-Tuple{FESpace, Type{<:DofMap}}","page":"FESpace","title":"Base.get!","text":"get!(FES::FESpace, DM::Type{<:DofMap}) -> Any\n\n\nTo be called by getindex. This triggers lazy creation of non-existing dofmaps\n\n\n\n\n\n","category":"method"},{"location":"fespace/#Base.getindex-Tuple{FESpace, Type{<:DofMap}}","page":"FESpace","title":"Base.getindex","text":"Base.getindex(FES::FESpace,DM::Type{<:DofMap})\n\nGeneric method for obtaining dofmap. This method is mutating in the sense that non-existing dofmaps are created on demand. Due to the fact that components are stored as Any the return value triggers type instability.\n\n\n\n\n\n","category":"method"},{"location":"fespace/#Base.setindex!-Tuple{FESpace, Any, Type{<:DofMap}}","page":"FESpace","title":"Base.setindex!","text":"setindex!(FES::FESpace, v, DM::Type{<:DofMap}) -> Any\n\n\nSet new dofmap\n\n\n\n\n\n","category":"method"},{"location":"fespace/#Base.show-Union{Tuple{APT}, Tuple{FEType}, Tuple{Ti}, Tuple{Tv}, Tuple{IO, FESpace{Tv, Ti, FEType, APT}}} where {Tv, Ti, FEType<:AbstractFiniteElement, APT}","page":"FESpace","title":"Base.show","text":"show(\n io::IO,\n FES::FESpace{Tv, Ti, FEType<:AbstractFiniteElement, APT}\n)\n\n\nCustom show function for FESpace that prints some information and all available dofmaps.\n\n\n\n\n\n","category":"method"},{"location":"fespace/#ExtendableFEMBase.assemblytype-Union{Tuple{FESpace{Tv, Ti, FEType, APT}}, Tuple{APT}, Tuple{FEType}, Tuple{Ti}, Tuple{Tv}} where {Tv, Ti, FEType<:AbstractFiniteElement, APT}","page":"FESpace","title":"ExtendableFEMBase.assemblytype","text":"assemblytype(\n _::FESpace{Tv, Ti, FEType<:AbstractFiniteElement, APT}\n) -> Any\n\n\nreturns the assembly type parameter of the finite element space, i.e. on which entities of the grid the finite element is defined.\n\n\n\n\n\n","category":"method"},{"location":"fespace/#ExtendableFEMBase.broken-Tuple{FESpace}","page":"FESpace","title":"ExtendableFEMBase.broken","text":"broken(FES::FESpace) -> Bool\n\n\nreturns true if the finite element space is broken, false if not\n\n\n\n\n\n","category":"method"},{"location":"fespace/#ExtendableFEMBase.get_AT-Union{Tuple{FESpace{Tv, Ti, FEType, AT}}, Tuple{AT}, Tuple{FEType}, Tuple{Ti}, Tuple{Tv}} where {Tv, Ti, FEType, AT}","page":"FESpace","title":"ExtendableFEMBase.get_AT","text":"get_AT(_::FESpace{Tv, Ti, FEType, AT}) -> Any\n\n\nreturns the support of the finite element space\n\n\n\n\n\n","category":"method"},{"location":"fespace/#ExtendableFEMBase.get_FEType-Union{Tuple{FESpace{Tv, Ti, FEType, AT}}, Tuple{AT}, Tuple{FEType}, Tuple{Ti}, Tuple{Tv}} where {Tv, Ti, FEType, AT}","page":"FESpace","title":"ExtendableFEMBase.get_FEType","text":"get_FEType(_::FESpace{Tv, Ti, FEType, AT}) -> Any\n\n\nreturns the finite element type of the finite element space\n\n\n\n\n\n","category":"method"},{"location":"fespace/#ExtendableFEMBase.ndofs-Tuple{FESpace}","page":"FESpace","title":"ExtendableFEMBase.ndofs","text":"ndofs(FES::FESpace) -> Int64\n\n\nreturns the total number of degrees of freedom of the finite element space.\n\n\n\n\n\n","category":"method"},{"location":"fespace/#DofMaps","page":"FESpace","title":"DofMaps","text":"","category":"section"},{"location":"fespace/","page":"FESpace","title":"FESpace","text":"Modules = [ExtendableFEMBase]\nPages = [\"dofmaps.jl\"]\nOrder = [:type, :function]","category":"page"},{"location":"fespace/#ExtendableFEMBase.BEdgeDofs","page":"FESpace","title":"ExtendableFEMBase.BEdgeDofs","text":"abstract type BEdgeDofs <: DofMap\n\nKey type describing the dofs for each boundary edge of the dofgrid\n\n\n\n\n\n","category":"type"},{"location":"fespace/#ExtendableFEMBase.BEdgeDofsParent","page":"FESpace","title":"ExtendableFEMBase.BEdgeDofsParent","text":"abstract type BEdgeDofsParent <: DofMap\n\nKey type describing the dofs for each boundary edge of the parentgrid\n\n\n\n\n\n","category":"type"},{"location":"fespace/#ExtendableFEMBase.BFaceDofs","page":"FESpace","title":"ExtendableFEMBase.BFaceDofs","text":"abstract type BFaceDofs <: DofMap\n\nKey type describing the dofs for each boundary face of the dofgrid\n\n\n\n\n\n","category":"type"},{"location":"fespace/#ExtendableFEMBase.BFaceDofsParent","page":"FESpace","title":"ExtendableFEMBase.BFaceDofsParent","text":"abstract type BFaceDofsParent <: DofMap\n\nKey type describing the dofs for each boundary face of the parentgrid\n\n\n\n\n\n","category":"type"},{"location":"fespace/#ExtendableFEMBase.CellDofs","page":"FESpace","title":"ExtendableFEMBase.CellDofs","text":"abstract type CellDofs <: DofMap\n\nKey type describing the dofs for each cell of the dofgrid\n\n\n\n\n\n","category":"type"},{"location":"fespace/#ExtendableFEMBase.CellDofsParent","page":"FESpace","title":"ExtendableFEMBase.CellDofsParent","text":"abstract type CellDofsParent <: DofMap\n\nKey type describing the dofs for each cell of the parentgrid\n\n\n\n\n\n","category":"type"},{"location":"fespace/#ExtendableFEMBase.DofMap","page":"FESpace","title":"ExtendableFEMBase.DofMap","text":"abstract type DofMap <: ExtendableGrids.AbstractGridAdjacency\n\nDofmaps are stored as an ExtendableGrids.AbstractGridAdjacency in the finite element space and collect information with respect to different AssemblyTypes. They are generated automatically on demand and the dofmaps associated to each subtype can be accessed via FESpace[DofMap].\n\n\n\n\n\n","category":"type"},{"location":"fespace/#ExtendableFEMBase.EdgeDofs","page":"FESpace","title":"ExtendableFEMBase.EdgeDofs","text":"abstract type EdgeDofs <: DofMap\n\nKey type describing the dofs for each edge of the dofgrid\n\n\n\n\n\n","category":"type"},{"location":"fespace/#ExtendableFEMBase.EdgeDofsParent","page":"FESpace","title":"ExtendableFEMBase.EdgeDofsParent","text":"abstract type EdgeDofsParent <: DofMap\n\nKey type describing the dofs for each edge of the parentgrid\n\n\n\n\n\n","category":"type"},{"location":"fespace/#ExtendableFEMBase.FaceDofs","page":"FESpace","title":"ExtendableFEMBase.FaceDofs","text":"abstract type FaceDofs <: DofMap\n\nKey type describing the dofs for each face of the dofgrid\n\n\n\n\n\n","category":"type"},{"location":"fespace/#ExtendableFEMBase.FaceDofsParent","page":"FESpace","title":"ExtendableFEMBase.FaceDofsParent","text":"abstract type FaceDofsParent <: DofMap\n\nKey type describing the dofs for each face of the parentgrid\n\n\n\n\n\n","category":"type"},{"location":"fespace/","page":"FESpace","title":"FESpace","text":"The following DofMap subtypes are available and are used as keys to access the dofmap via FESpace[DofMap] (which is equivalent to FESpace.dofmaps[DofMap]).","category":"page"},{"location":"fespace/","page":"FESpace","title":"FESpace","text":"DofMap Explanation\nCellDofs degrees of freedom for on each cell\nFaceDofs degrees of freedom for each face\nEdgeDofs degrees of freedom for each edge (in 3D)\nBFaceDofs degrees of freedom for each boundary face\nBEdgeDofs degrees of freedom for each boundary edge (in 3D)","category":"page"},{"location":"feevaluator/#FEEvaluator","page":"FEEvaluator","title":"FEEvaluator","text":"","category":"section"},{"location":"feevaluator/","page":"FEEvaluator","title":"FEEvaluator","text":"FEEvaluators provide a structure that handles the evaluation of finite element basis functions for a given function operator, quadrature rule and item geometry. It stores the evaluations on the reference geometry (where derivatives are computed by automatic differentiation) and on the current mesh item. The current mesh item can be changed via the update! call.","category":"page"},{"location":"feevaluator/","page":"FEEvaluator","title":"FEEvaluator","text":"Modules = [ExtendableFEMBase]\nPages = [\"feevaluator.jl\"]\nOrder = [:type, :function]","category":"page"},{"location":"feevaluator/#ExtendableFEMBase.FEEvaluator-Union{Tuple{FEAPT}, Tuple{EG}, Tuple{FEType}, Tuple{TvR}, Tuple{TiG}, Tuple{TvG}, Tuple{FESpace{TvG, TiG, FEType, FEAPT}, Type{<:??}, QuadratureRule{TvR, EG}}} where {TvG, TiG, TvR, FEType<:AbstractFiniteElement, EG<:ExtendableGrids.AbstractElementGeometry, FEAPT<:ExtendableGrids.AssemblyType}","page":"FEEvaluator","title":"ExtendableFEMBase.FEEvaluator","text":"function FEEvaluator(FE::FESpace, operator::AbstractFunctionOperator, qrule::QuadratureRule; T = Float64, AT = ON_CELLS, L2G = nothing)\n\nConstructs a FEEvaluator that handles evaluations of finite element basis function evaluation for the given FESpace, operator at the quadrature points of the given QuadratureRule. It has an update! function to update the evaluation upon entry to a new cell. Evaluations can be accessed via FEEvaluator.cvals[j,k,i] where i is the quadrature point id, k is the local dof number and j is the component. \n\nNote that matrix-valued operators evaluations, e.g. for Gradient, are given as a long vector (in component-wise order).\n\n\n\n\n\n","category":"method"},{"location":"feevaluator/#ExtendableFEMBase.eval_febe!","page":"FEEvaluator","title":"ExtendableFEMBase.eval_febe!","text":"\teval_febe!(result, FEBE::FEBasisEvaluator, j::Int, i::Int, offset::Int = 0, factor = 1)\n\nEvaluates the linear combination of the basisfunction with given coefficients at the i-th quadrature point and writes the (possibly vector-valued) evaluation into result (beginning at offset and with the specified factor).\n\n\n\n\n\n","category":"function"},{"location":"feevaluator/#ExtendableFEMBase.eval_febe!-2","page":"FEEvaluator","title":"ExtendableFEMBase.eval_febe!","text":"\teval_febe!(result, FEBE::FEBasisEvaluator, j::Int, i::Int, offset::Int = 0, factor = 1)\n\nEvaluate the j-th basis function of the FEBasisEvaluator at the i-th quadrature point and writes the (possibly vector-valued) evaluation into result (beginning at offset and with the specified factor).\n\n\n\n\n\n","category":"function"},{"location":"feevaluator/#ExtendableFEMBase.update_basis!-Tuple{FEEvaluator, Any}","page":"FEEvaluator","title":"ExtendableFEMBase.update_basis!","text":"function update_basis!(FEBE::FEEvaluator, item::Integer)\n\nSets FEBE.citem[] = item and updates the basis.\n\n\n\n\n\n","category":"method"},{"location":"feevaluator/#ExtendableFEMBase.update_basis!-Union{Tuple{ExtendableFEMBase.SingleFEEvaluator{<:Real, <:Real, <:Integer, operator, FEType}}, Tuple{FEType}, Tuple{operator}} where {operator, FEType}","page":"FEEvaluator","title":"ExtendableFEMBase.update_basis!","text":"function update_basis!(FEBE::SingleFEEvaluator)\n\nUpdates the basis for the current item FEBE.citem[].\n\n\n\n\n\n","category":"method"},{"location":"plutostatichtml_examples/LowLevelPoisson/","page":"Low level Poisson","title":"Low level Poisson","text":"\n\n\n\n
begin\n    using ExtendableFEMBase\n    using ExtendableGrids\n    using ExtendableSparse\n    using GridVisualize\n    using PlutoVista\n    GridVisualize.default_plotter!(PlutoVista)\nend
\n
PlutoVista
\n\n\n

Tutorial notebook: Poisson problem

This notebook demonstrates how to implement the Poisson problem with the low level structures provided by ExtendableFEMBase. The Poisson problem with homogeneous Dirichlet boundary data seeks \\(u\\) such that

$$\\begin{aligned}\n\t- \\mu \\Delta u = f.\n\\end{aligned}$$

The weak formulation seeks \\(u \\in V := H^1_0(\\Omega)\\) such that

$$\\begin{aligned}\n\t\\mu (\\nabla u, \\nabla v) = (f, v)\n\t\\quad \\text{for all } v \\in V\n\\end{aligned}$$

\n\n
begin\n    ## PDE data\n    μ = 1.0\n    f = x -> x[1] - x[2]\n\n    ## discretization parameters\n    nref = 9\n    order = 1\nend
\n
1
\n\n
tricontour(xgrid[Coordinates],xgrid[CellNodes],sol.entries[1:num_nodes(xgrid)]; levels = 5, resolution = (500,500))
\n
\n\n\n
begin\n    ## call low level solver\n    sol = solve_poisson_lowlevel(FES, μ, f)\nend
\n
FEVector information\n====================\n   block  |  ndofs \t|     min  /  max    \t| FEType \t\t (name/tag)\n [    1]  |  263169\t| -1.21e-02/1.21e-02  \t| H1Pk{1,2,1}  \t (#1)
\n\n
function solve_poisson_lowlevel(FES, μ, f)\n    \n    Solution = FEVector(FES)\n    FES = Solution[1].FES\n    A = FEMatrix(FES, FES)\n    b = FEVector(FES)\n    println(\"Assembling operators...\")\n    @time assemble!(A.entries, b.entries, FES, f, μ)\n\n    ## fix boundary dofs\n    println(\"Assembling boundary data...\")\n    @time begin\n        BFaceDofs::Adjacency{Int32} = FES[ExtendableFEMBase.BFaceDofs]\n        nbfaces::Int = num_sources(BFaceDofs)\n        AM::ExtendableSparseMatrix{Float64,Int64} = A.entries\n        dof_j::Int = 0\n        for bface = 1 : nbfaces\n            for j = 1 : num_targets(BFaceDofs,1)\n                dof_j = BFaceDofs[j, bface]\n                AM[dof_j,dof_j] = 1e60\n                b.entries[dof_j] = 0\n            end\n        end\n    end\n    ExtendableSparse.flush!(A.entries)\n\n    ## solve\n    println(\"Solving linear system...\")\n    @time copyto!(Solution.entries, A.entries \\ b.entries)\n\n    return Solution\nend
\n
solve_poisson_lowlevel (generic function with 1 method)
\n\n
begin\n    ## create finite element space\n    FEType = H1Pk{1,2,order}\n\n    ## prepare finite element space and dofmaps\n    println(\"Creating FESpace...\")\n    @time FES = FESpace{FEType}(xgrid)\n    FES\nend
\n
FESpace information\n===================\n     name = H1Pk{1,2,1}\n   FEType = H1Pk{1,2,1}\n  FEClass = ExtendableFEMBase.AbstractH1FiniteElement\n    ndofs = 263169\n\n\nDofMaps\n==========\n
\n\n
begin\n    ## create grid\n    X = LinRange(0,1,2^nref+1)\n    Y = LinRange(0,1,2^nref+1)\n    println(\"Creating grid...\")\n    @time xgrid = simplexgrid(X,Y)\n    println(\"Preparing FaceNodes...\")\n    @time xgrid[FaceNodes]\n    println(\"Preparing CellVolumes...\")\n    @time xgrid[CellVolumes]\n    xgrid\nend
\n
ExtendableGrids.ExtendableGrid{Float64, Int32};\ndim: 2 nodes: 263169 cells: 524288 bfaces: 2048\n
\n\n
function assemble!(A::ExtendableSparseMatrix, b::Vector, FES, f, μ = 1)\n\n    xgrid = FES.xgrid\n    EG = xgrid[UniqueCellGeometries][1]\n    FEType = eltype(FES)\n    L2G = L2GTransformer(EG, xgrid, ON_CELLS)\n\n    ## dofmap\n    CellDofs = FES[ExtendableFEMBase.CellDofs]\n    \n    ## quadrature formula\n    qf = QuadratureRule{Float64, EG}(2*(get_polynomialorder(FEType, EG)-1))\n    weights::Vector{Float64} = qf.w\n    xref::Vector{Vector{Float64}} = qf.xref\n    nweights::Int = length(weights)\n    \n    ## FE basis evaluator\n    FEBasis_∇ = FEEvaluator(FES, Gradient, qf)\n    ∇vals = FEBasis_∇.cvals\n    FEBasis_id = FEEvaluator(FES, Identity, qf)\n    idvals = FEBasis_id.cvals\n\n    \n    cellvolumes = xgrid[CellVolumes]\n   \n    ## ASSEMBLY LOOP\n    function barrier(EG, L2G::L2GTransformer)\n        ## barrier function to avoid allocations by EG dispatch\n        \n    \tndofs4cell::Int = get_ndofs(ON_CELLS, FEType, EG)\n    \tAloc = zeros(Float64, ndofs4cell, ndofs4cell)\n        ncells::Int = num_cells(xgrid)\n    \tdof_j::Int, dof_k::Int = 0, 0\n        x::Vector{Float64} = zeros(Float64, 2)\n        \n        for cell = 1 : ncells\n            ## update FE basis evaluators\n            FEBasis_∇.citem[] = cell\n            update_basis!(FEBasis_∇) \n    \n            ## assemble local stiffness matrix\n            for j = 1 : ndofs4cell, k = j : ndofs4cell\n                temp = 0\n                for qp = 1 : nweights\n                    temp += weights[qp] * dot(view(∇vals,:,j,qp), view(∇vals,:,k,qp))\n                end\n                Aloc[j,k] = temp\n            end\n            Aloc .*= μ * cellvolumes[cell]\n    \n            ## add local matrix to global matrix\n            for j = 1 : ndofs4cell\n                dof_j = CellDofs[j, cell]\n                for k = j : ndofs4cell\n                    dof_k = CellDofs[k, cell]\n                    if abs(Aloc[j,k]) > 1e-15\n                        # write into sparse matrix, only lines with allocations\n                        rawupdateindex!(A, +, Aloc[j,k], dof_j, dof_k) \n                        if k > j\n                            rawupdateindex!(A, +, Aloc[j,k], dof_k, dof_j)\n                        end\n                    end\n                end\n            end\n            fill!(Aloc, 0)\n\n            ## assemble right-hand side\n            update_trafo!(L2G, cell)\n            for j = 1 : ndofs4cell\n                ## right-hand side\n                temp = 0\n                for qp = 1 : nweights\n                    ## get global x for quadrature point\n                    eval_trafo!(x, L2G, xref[qp])\n                    ## evaluate (f(x), v_j(x))\n                    temp += weights[qp] * idvals[1, j, qp] * f(x)\n                end\n                ## write into global vector\n                dof_j = CellDofs[j, cell]\n                b[dof_j] += temp * cellvolumes[cell]\n            end\n        end\n    end\n    barrier(EG, L2G)\n    flush!(A)\nend
\n
assemble! (generic function with 2 methods)
\n
\n

Built with Julia 1.10.4 and

\nExtendableFEMBase 0.6.0
\nExtendableGrids 1.9.0
\nExtendableSparse 1.5.0
\nGridVisualize 1.7.0
\nPlutoVista 1.0.1\n
\n\n","category":"page"},{"location":"plutostatichtml_examples/LowLevelPoisson/","page":"Low level Poisson","title":"Low level Poisson","text":"EditURL = \"https://github.com/chmerdon/ExtendableFEMBase.jl/blob/master/nothing\"","category":"page"},{"location":"module_examples/Example280_BasisPlotter/#280-:-Basis-Plotter","page":"Example280_BasisPlotter","title":"280 : Basis-Plotter","text":"","category":"section"},{"location":"module_examples/Example280_BasisPlotter/","page":"Example280_BasisPlotter","title":"Example280_BasisPlotter","text":"(source code)","category":"page"},{"location":"module_examples/Example280_BasisPlotter/","page":"Example280_BasisPlotter","title":"Example280_BasisPlotter","text":"This example plots all the basis functions of a H1 finite element on Edge1D or Triangle2D as unicode plots. This is the result with the default parameters (dim = 1, order = 3):","category":"page"},{"location":"module_examples/Example280_BasisPlotter/","page":"Example280_BasisPlotter","title":"Example280_BasisPlotter","text":"(Image: )","category":"page"},{"location":"module_examples/Example280_BasisPlotter/","page":"Example280_BasisPlotter","title":"Example280_BasisPlotter","text":"module Example280_BasisPlotter\n\nusing ExtendableFEMBase\nusing ExtendableGrids\n\n# everything is wrapped in a main function\nfunction main(; dim = 1, order = 3)\n\n\t# generate two grids\n\t@assert dim in [1, 2] \"dim must be 1 or 2\"\n\trefgeom = dim == 1 ? Edge1D : Triangle2D\n\txgrid = reference_domain(refgeom)\n\n\t# set finite element type and get some information\n\tFEType = H1Pk{1, dim, order}\n\tndofs = get_ndofs(ON_CELLS, FEType, refgeom)\n\tFEType = H1Pk{ndofs, dim, order}\n\n\t# generate FEVector with ncomponents = ndofs\n\t# that will carry one basis function in each component\n\tFEFunc = FEVector(FESpace{FEType}(xgrid))\n\tcoffsets = ExtendableFEMBase.get_local_coffsets(FEType, ON_CELLS, refgeom)\n\tfor j ∈ 1:ndofs\n\t\tFEFunc[1][j+coffsets[j]] = 1\n\tend\n\n # plot\n\tprintln(stdout, unicode_scalarplot(FEFunc[1]; title = \"φ\", ylim = (-0.5, 1), resolution = dim == 1 ? (40, 10) : (20, 15), nrows = order))\nend\nend","category":"page"},{"location":"module_examples/Example280_BasisPlotter/","page":"Example280_BasisPlotter","title":"Example280_BasisPlotter","text":"","category":"page"},{"location":"module_examples/Example280_BasisPlotter/","page":"Example280_BasisPlotter","title":"Example280_BasisPlotter","text":"This page was generated using Literate.jl.","category":"page"},{"location":"examples_intro/#About-the-examples","page":"Introduction","title":"About the examples","text":"","category":"section"},{"location":"examples_intro/","page":"Introduction","title":"Introduction","text":"The examples have been designed with the following issues in mind:","category":"page"},{"location":"examples_intro/","page":"Introduction","title":"Introduction","text":"they run from the Julia REPL\neach example is a Julia module named similar to the basename of the example file.\nan example can be used as the starting point for a project \nsome examples define test cases for the test suite\nExampleXYZ with X = A can be considered advanced and uses low-level structures and/or demonstrates customisation features or experimental features\nthe default output of the main function is printed on the website and can be used to check if the code runs as expected (unfortunately REPL messages are not recorded)\nprinted assembly and solving times (especially in a first iteration) can be much larger due to first-run compilation times","category":"page"},{"location":"examples_intro/#Running-the-examples","page":"Introduction","title":"Running the examples","text":"","category":"section"},{"location":"examples_intro/","page":"Introduction","title":"Introduction","text":"In order to run ExampleXXX, peform the following steps:","category":"page"},{"location":"examples_intro/","page":"Introduction","title":"Introduction","text":"Download the example file (e.g. via the source code link at the top)\nMake sure all used packages are installed in your Julia environment\nIn the REPL: ","category":"page"},{"location":"examples_intro/","page":"Introduction","title":"Introduction","text":"julia> include(\"ExampleXXX.jl\")`\n\njulia> ExampleXXX.main()","category":"page"},{"location":"examples_intro/","page":"Introduction","title":"Introduction","text":"Some examples offer visual output via the optional argument Plotter = PyPlot or Plotter = GLMakie","category":"page"},{"location":"examples_intro/","page":"Introduction","title":"Introduction","text":"(provided the package PyPlot/GLMakie is installed and loaded)","category":"page"},{"location":"meshing/#Meshing","page":"Meshing","title":"Meshing","text":"","category":"section"},{"location":"meshing/","page":"Meshing","title":"Meshing","text":"Meshes are stored as an ExtendableGrid, see ExtendableGrids.jl for details and constructors. Grid generators for simplex grids can be found e.g. in the external module SimplexGridFactory.jl","category":"page"},{"location":"meshing/","page":"Meshing","title":"Meshing","text":"Cells, faces and edges of the mesh are associated to AbstractElementGeometries (defined by ExtendableGrids.jl) that are used to dispatch functionality (local/global transformation, enumeration rules, set of basis functions, volume calculation, refinements etc.). See further below for a list of recognized element geometries.","category":"page"},{"location":"meshing/#Recognized-Geometries-and-Reference-Domains","page":"Meshing","title":"Recognized Geometries and Reference Domains","text":"","category":"section"},{"location":"meshing/","page":"Meshing","title":"Meshing","text":"The following list contains all subtypes of ExtendableGrids.AbstractElementGeometries and their reference domains for which the package offers finite elements on them.","category":"page"},{"location":"meshing/","page":"Meshing","title":"Meshing","text":"","category":"page"},{"location":"meshing/#Edge1D-:-AbstractElementGeometry1D","page":"Meshing","title":"Edge1D <: AbstractElementGeometry1D","text":"","category":"section"},{"location":"meshing/","page":"Meshing","title":"Meshing","text":"[1]-----[2] [1] = [0]\n [2] = [1]","category":"page"},{"location":"meshing/","page":"Meshing","title":"Meshing","text":"","category":"page"},{"location":"meshing/#Triangle2D","page":"Meshing","title":"Triangle2D","text":"","category":"section"},{"location":"meshing/","page":"Meshing","title":"Meshing","text":"[3] \n | \\ \n | \\ [1] = [0,0]\n | \\ [2] = [1,0]\n | \\ [3] = [0,1]\n | \\ \n[1]--------[2]","category":"page"},{"location":"meshing/","page":"Meshing","title":"Meshing","text":"","category":"page"},{"location":"meshing/#Parallelogram2D-:-Quadrilateral2D","page":"Meshing","title":"Parallelogram2D <: Quadrilateral2D","text":"","category":"section"},{"location":"meshing/","page":"Meshing","title":"Meshing","text":"[4]--------[3] \n | | [1] = [0,0]\n | | [2] = [1,0]\n | | [3] = [1,1]\n | | [4] = [0,1]\n[1]--------[2]\n\nNote: most finite elements only work as intended on Parallelogram2D\n since the local<>global map stays affine in this case","category":"page"},{"location":"meshing/","page":"Meshing","title":"Meshing","text":"","category":"page"},{"location":"meshing/#Tetrahedron3D","page":"Meshing","title":"Tetrahedron3D","text":"","category":"section"},{"location":"meshing/","page":"Meshing","title":"Meshing","text":"[4] \n |\\\\ \n | \\ \\ [1] = [0,0,0]\n | \\ \\ [2] = [1,0,0]\n | \\ \\ [3] = [0,1,0]\n | _-[3]-_ \\ [4] = [0,0,1]\n[1]--------[2]","category":"page"},{"location":"meshing/","page":"Meshing","title":"Meshing","text":"","category":"page"},{"location":"meshing/#Parallelepiped3D-:-Hexahedron3D","page":"Meshing","title":"Parallelepiped3D <: Hexahedron3D","text":"","category":"section"},{"location":"meshing/","page":"Meshing","title":"Meshing","text":" [8]--------[7] [1] = [0,0,0]\n / | / | [2] = [1,0,0]\n[5]--------[6] | [3] = [1,1,0]\n | | | | [4] = [0,1,0]\n | | | | [5] = [0,0,1]\n | [4]-----|--[3] [6] = [1,0,1]\n | / | / [7] = [1,1,1]\n[1]--------[2] [8] = [0,1,1]\n\nNote: most finite elements only work as intended on Parallelepiped3D\n since the local<>global map stays affine in this case","category":"page"},{"location":"module_examples/Example200_LowLevelPoisson/#200-:-Poisson-Problem","page":"Example200_LowLevelPoisson","title":"200 : Poisson Problem","text":"","category":"section"},{"location":"module_examples/Example200_LowLevelPoisson/","page":"Example200_LowLevelPoisson","title":"Example200_LowLevelPoisson","text":"(source code)","category":"page"},{"location":"module_examples/Example200_LowLevelPoisson/","page":"Example200_LowLevelPoisson","title":"Example200_LowLevelPoisson","text":"This example computes the solution u of the two-dimensional Poisson problem","category":"page"},{"location":"module_examples/Example200_LowLevelPoisson/","page":"Example200_LowLevelPoisson","title":"Example200_LowLevelPoisson","text":"beginaligned\n-Delta u = f quad textin Omega\nendaligned","category":"page"},{"location":"module_examples/Example200_LowLevelPoisson/","page":"Example200_LowLevelPoisson","title":"Example200_LowLevelPoisson","text":"with right-hand side f(xy) equiv xy and homogeneous Dirichlet boundary conditions on the unit square domain Omega on a given grid.","category":"page"},{"location":"module_examples/Example200_LowLevelPoisson/","page":"Example200_LowLevelPoisson","title":"Example200_LowLevelPoisson","text":"When run, this script also measures runtimes for grid generation, assembly and solving (direct/UMFPACK) for different refinement levels.","category":"page"},{"location":"module_examples/Example200_LowLevelPoisson/","page":"Example200_LowLevelPoisson","title":"Example200_LowLevelPoisson","text":"The computed solution for the default parameters looks like this:","category":"page"},{"location":"module_examples/Example200_LowLevelPoisson/","page":"Example200_LowLevelPoisson","title":"Example200_LowLevelPoisson","text":"(Image: )","category":"page"},{"location":"module_examples/Example200_LowLevelPoisson/","page":"Example200_LowLevelPoisson","title":"Example200_LowLevelPoisson","text":"module Example200_LowLevelPoisson\n\nusing ExtendableFEMBase\nusing ExtendableGrids\nusing ExtendableSparse\nusing GridVisualize\nusing UnicodePlots\nusing Test #\n\n# data for Poisson problem\nconst μ = 1.0\nconst f = x -> x[1] - x[2]\n\nfunction main(; maxnref = 8, order = 2, Plotter = nothing)\n\n\t# Finite element type\n\tFEType = H1Pk{1, 2, order}\n\n\t# run once on a tiny mesh for compiling\n\tX = LinRange(0, 1, 4)\n\txgrid = simplexgrid(X, X)\n\tFES = FESpace{FEType}(xgrid)\n\tsol, time_assembly, time_solve = solve_poisson_lowlevel(FES, μ, f)\n\n\t# loop over uniform refinements + timings\n\tplt = GridVisualizer(; Plotter = Plotter, layout = (1, 1), clear = true, resolution = (500, 500))\n\tloop_allocations = 0\n\tfor level ∈ 1:maxnref\n\t\tX = LinRange(0, 1, 2^level + 1)\n\t\ttime_grid = @elapsed xgrid = simplexgrid(X, X)\n\t\ttime_facenodes = @elapsed xgrid[FaceNodes]\n\t\tFES = FESpace{FEType}(xgrid)\n\t\tprintln(\"\\nLEVEL = $level, ndofs = $(FES.ndofs)\\n\")\n\t\tif level < 4\n\t\t\tprintln(stdout, unicode_gridplot(xgrid))\n\t\tend\n\t\ttime_dofmap = @elapsed FES[CellDofs]\n\t\tsol, time_assembly, time_solve = solve_poisson_lowlevel(FES, μ, f)\n\n\t\t# plot statistics\n\t\tprintln(stdout, barplot([\"Grid\", \"FaceNodes\", \"celldofs\", \"Assembly\", \"Solve\"], [time_grid, time_facenodes, time_dofmap, time_assembly, time_solve], title = \"Runtimes\"))\n\n\t\t# plot\n\t\tscalarplot!(plt[1,1], xgrid, view(sol.entries, 1:num_nodes(xgrid)), limits = (-0.0125,0.0125))\n\tend\n\n\treturn sol, plt\nend\n\n\nfunction solve_poisson_lowlevel(FES, μ, f)\n\tSolution = FEVector(FES)\n\tFES = Solution[1].FES\n\tA = FEMatrix(FES, FES)\n\tb = FEVector(FES)\n\tprintln(\"Assembling...\")\n\ttime_assembly = @elapsed @time begin\n\t\tloop_allocations = assemble!(A.entries, b.entries, FES, f, μ)\n\n\t\t# fix boundary dofs\n\t\tbegin\n\t\t\tbdofs = boundarydofs(FES)\n\t\t\tfor dof in bdofs\n\t\t\t\tA.entries[dof, dof] = 1e60\n\t\t\t\tb.entries[dof] = 0\n\t\t\tend\n\t\tend\n\t\tExtendableSparse.flush!(A.entries)\n\tend\n\n\t# solve\n\tprintln(\"Solving linear system...\")\n\ttime_solve = @elapsed @time copyto!(Solution.entries, A.entries \\ b.entries)\n\n\treturn Solution, time_assembly, time_solve\nend\n\nfunction assemble!(A::ExtendableSparseMatrix, b::Vector, FES, f, μ = 1)\n\txgrid = FES.xgrid\n\tEG = xgrid[UniqueCellGeometries][1]\n\tFEType = eltype(FES)\n\tL2G = L2GTransformer(EG, xgrid, ON_CELLS)\n\n\t# quadrature formula\n\tqf = QuadratureRule{Float64, EG}(2 * (get_polynomialorder(FEType, EG) - 1))\n\tweights::Vector{Float64} = qf.w\n\txref::Vector{Vector{Float64}} = qf.xref\n\tnweights::Int = length(weights)\n\tcellvolumes = xgrid[CellVolumes]\n\n\t# FE basis evaluator and dofmap\n\tFEBasis_∇ = FEEvaluator(FES, Gradient, qf)\n\t∇vals = FEBasis_∇.cvals\n\tFEBasis_id = FEEvaluator(FES, Identity, qf)\n\tidvals = FEBasis_id.cvals\n\tcelldofs = FES[CellDofs]\n\n\t# ASSEMBLY LOOP\n\tloop_allocations = 0\n\tfunction barrier(EG, L2G::L2GTransformer)\n\t\t# barrier function to avoid allocations by type dispatch\n\t\tndofs4cell::Int = get_ndofs(ON_CELLS, FEType, EG)\n\t\tAloc = zeros(Float64, ndofs4cell, ndofs4cell)\n\t\tncells::Int = num_cells(xgrid)\n\t\tdof_j::Int, dof_k::Int = 0, 0\n\t\tx::Vector{Float64} = zeros(Float64, 2)\n\n\t\tloop_allocations += @allocated for cell ∈ 1:ncells\n\t\t\t# update FE basis evaluators\n\t\t\tFEBasis_∇.citem[] = cell\n\t\t\tupdate_basis!(FEBasis_∇)\n\n\t\t\t# assemble local stiffness matrix\n\t\t\tfor j ∈ 1:ndofs4cell, k ∈ j:ndofs4cell\n\t\t\t\ttemp = 0\n\t\t\t\tfor qp ∈ 1:nweights\n\t\t\t\t\ttemp += weights[qp] * dot(view(∇vals, :, j, qp), view(∇vals, :, k, qp))\n\t\t\t\tend\n\t\t\t\tAloc[j, k] = temp\n\t\t\tend\n\t\t\tAloc .*= μ * cellvolumes[cell]\n\n\t\t\t# add local matrix to global matrix\n\t\t\tfor j ∈ 1:ndofs4cell\n\t\t\t\tdof_j = celldofs[j, cell]\n\t\t\t\tfor k ∈ j:ndofs4cell\n\t\t\t\t\tdof_k = celldofs[k, cell]\n\t\t\t\t\tif abs(Aloc[j, k]) > 1e-15\n\t\t\t\t\t\t# write into sparse matrix, only lines with allocations\n\t\t\t\t\t\trawupdateindex!(A, +, Aloc[j, k], dof_j, dof_k)\n\t\t\t\t\t\tif k > j\n\t\t\t\t\t\t\trawupdateindex!(A, +, Aloc[j, k], dof_k, dof_j)\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\tend\n\t\t\tfill!(Aloc, 0)\n\n\t\t\t# assemble right-hand side\n\t\t\tupdate_trafo!(L2G, cell)\n\t\t\tfor j ∈ 1:ndofs4cell\n\t\t\t\t# right-hand side\n\t\t\t\ttemp = 0\n\t\t\t\tfor qp ∈ 1:nweights\n\t\t\t\t\t# get global x for quadrature point\n\t\t\t\t\teval_trafo!(x, L2G, xref[qp])\n\t\t\t\t\t# evaluate (f(x), v_j(x))\n\t\t\t\t\ttemp += weights[qp] * idvals[1, j, qp] * f(x)\n\t\t\t\tend\n\t\t\t\t# write into global vector\n\t\t\t\tdof_j = celldofs[j, cell]\n\t\t\t\tb[dof_j] += temp * cellvolumes[cell]\n\t\t\tend\n\t\tend\n\tend\n\tbarrier(EG, L2G)\n\tflush!(A)\n\treturn loop_allocations\nend\n\nfunction generateplots(dir = pwd(); Plotter = nothing, kwargs...)\n\t~, plt = main(; Plotter = Plotter, kwargs...)\n\tscene = GridVisualize.reveal(plt)\n\tGridVisualize.save(joinpath(dir, \"example200.png\"), scene; Plotter = Plotter)\nend\n\n\tFEType = H1Pk{1, 2, order}\n\tX = LinRange(0, 1, 64)\n\txgrid = simplexgrid(X, X)\n\tFES = FESpace{FEType}(xgrid)\n\tA = FEMatrix(FES, FES)\n\tb = FEVector(FES)\n\t@info \"ndofs = $(FES.ndofs)\"\n\t# first assembly causes allocations when filling sparse matrix\n\tloop_allocations = assemble!(A.entries, b.entries, FES, f, μ)\n\t@info \"allocations in 1st assembly: $loop_allocations\"\n\t# second assebly in same matrix should have allocation-free inner loop\n\tloop_allocations = assemble!(A.entries, b.entries, FES, f, μ)\n\t@info \"allocations in 2nd assembly: $loop_allocations\"\n\t@test loop_allocations == 0\nend #module","category":"page"},{"location":"module_examples/Example200_LowLevelPoisson/","page":"Example200_LowLevelPoisson","title":"Example200_LowLevelPoisson","text":"","category":"page"},{"location":"module_examples/Example200_LowLevelPoisson/","page":"Example200_LowLevelPoisson","title":"Example200_LowLevelPoisson","text":"This page was generated using Literate.jl.","category":"page"},{"location":"plutostatichtml_examples/LowLevelNavierStokes/","page":"Low level Navier-Stokes","title":"Low level Navier-Stokes","text":"\n\n\n\n\n\n\n\n

Tutorial notebook: Navier–Stokes problem

Consider the Navier-Stokes problem that seeks \\(u\\) and \\(p\\) such that

$$\\begin{aligned}\n\t- \\mu \\Delta u + (u \\cdot \\nabla) u + \\nabla p &= f\\\\\n\t\t\t\\mathrm{div}(u) & = 0.\n\\end{aligned}$$

The weak formulation seeks \\(u \\in V := H^1_0(\\Omega)\\) and \\(p \\in Q := L^2_0(\\Omega)\\) such that

$$\\begin{aligned}\n\t\\mu (\\nabla u, \\nabla v) + ((u \\cdot \\nabla) u, v) - (p, \\mathrm{div}(v)) & = (f, v)\n\t& \\text{for all } v \\in V\\\\\n\t(q, \\mathrm{div}(u)) & = 0\n\t& \\text{for all } q \\in Q\\\\\n\\end{aligned}$$

This tutorial notebook compute a planar lattice flow with inhomogeneous Dirichlet boundary conditions (which requires some modification above). Newton's method with automatic differentation is used to handle the nonlinear convection term.

\n\n\n

This is a plot of the computed velocity and pressure:

\n\n\n
2-element Vector{PlutoVTKPlot}:\n PlutoVTKPlot(Dict{String, Any}(\"2axisfontsize\" => 10, \"1\" => \"tricontour\", \"2ylabel\" => \"y\", \"2\" => \"axis\", \"cbar_levels\" => [6.123233995736766e-17, 0.16667347690578882, 0.3333469538115776, 0.5000204307173663, 0.6666939076231551, 0.833367384528944, 1.0000408614347327], \"cbar\" => 1, \"2xlabel\" => \"x\", \"2zlabel\" => \"z\", \"cbar_stops\" => [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09  …  0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1.0], \"2zoom\" => 1.0…), 300.0, 300.0, false, (title = \"\", titlefontsize = 12, axisfontsize = 10, tickfontsize = 10, xlabel = \"x\", ylabel = \"y\", zlabel = \"z\", aspect = 1.0, zoom = 1.0, legendfontsize = 10, colorbarticks = :default, clear = false, levels = 5), \"61bbfc1e-450f-11ef-0eb4-058c3656a96b\")\n PlutoVTKPlot(Dict{String, Any}(\"2axisfontsize\" => 10, \"1\" => \"tricontour\", \"2ylabel\" => \"y\", \"2\" => \"axis\", \"cbar_levels\" => [-0.5064542228750328, -0.33763730567358835, -0.1688203884721439, -3.4712706993289544e-6, 0.16881344593074513, 0.3376303631321897, 0.5064472803336342], \"cbar\" => 1, \"2xlabel\" => \"x\", \"2zlabel\" => \"z\", \"cbar_stops\" => [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09  …  0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1.0], \"2zoom\" => 1.0…), 300.0, 300.0, false, (title = \"\", titlefontsize = 12, axisfontsize = 10, tickfontsize = 10, xlabel = \"x\", ylabel = \"y\", zlabel = \"z\", aspect = 1.0, zoom = 1.0, legendfontsize = 10, colorbarticks = :default, clear = false, levels = 5), \"62531eb4-450f-11ef-28c5-f1b0eece2468\")
\n\n
begin\n    ## PDE data\n    const μ = 1e-2\n    function f!(fval, x, t) # right-hand side\n        fval[1] = 8.0*π*π*μ * exp(-8.0*π*π*μ*t) * sin(2.0*π*x[1])*sin(2.0*π*x[2])\n        fval[2] = 8.0*π*π*μ * exp(-8.0*π*π*μ*t) * cos(2.0*π*x[1])*cos(2.0*π*x[2])\n        return nothing\n    end\n\n    # exact velocity (for boundary data and error calculation)\n    function u!(uval, qpinfo) \n        x = qpinfo.x\n        t = qpinfo.time\n        uval[1] = exp(-8.0*π*π*μ*t) * sin(2.0*π*x[1])*sin(2.0*π*x[2])\n        uval[2] = exp(-8.0*π*π*μ*t) * cos(2.0*π*x[1])*cos(2.0*π*x[2])\n        return nothing\n    end\n    \n    ## discretization parameters\n    const nref = 5\n    const teval = 0\n    const order = 2\n    \n    ## prepare error calculation\n    function p!(pval,x,t) # exact pressure (for error calculation)\n        pval[1] = exp(-16*pi*pi*μ*t)*(cos(4*pi*x[1])-cos(4*pi*x[2]))/4\n        return nothing\n    end\nend
\n
p! (generic function with 1 method)
\n\n
begin\n    ## create grid\n    X = LinRange(0,1,2^nref+1)\n    Y = LinRange(0,1,2^nref+1)\n    println(\"Creating grid...\")\n    @time xgrid = simplexgrid(X,Y)\n    println(\"Preparing FaceNodes...\")\n    @time xgrid[FaceNodes]\n    println(\"Preparing CellVolumes...\")\n    @time xgrid[CellVolumes]\n    xgrid\nend
\n
ExtendableGrids.ExtendableGrid{Float64, Int32};\ndim: 2 nodes: 1089 cells: 2048 bfaces: 128\n
\n\n
begin\n    ## create finite element space (Taylor--Hood)\n    FETypes = [H1Pk{2,2,order}, H1Pk{1,2,order-1}]\n\n    ## prepare finite element space and dofmaps\n    println(\"Creating FESpace...\")\n    @time FES = [FESpace{FETypes[1]}(xgrid; name = \"velocity space\"),                  \t             FESpace{FETypes[2]}(xgrid; name = \"pressure space\")]\n    FES\nend
\n
2-element Vector{FESpace{Float64, Int32, FEType, ON_CELLS} where FEType<:AbstractFiniteElement}:\n \nFESpace information\n===================\n     name = velocity space\n   FEType = H1Pk{2,2,2}\n  FEClass = ExtendableFEMBase.AbstractH1FiniteElement\n    ndofs = 8450\n\n\nDofMaps\n==========\n\n \nFESpace information\n===================\n     name = pressure space\n   FEType = H1Pk{1,2,1}\n  FEClass = ExtendableFEMBase.AbstractH1FiniteElement\n    ndofs = 1089\n\n\nDofMaps\n==========\n
\n\n
begin\n    ## call low level solver\n    sol, u_init = solve_stokes_lowlevel(FES, μ, f!)\n    sol\nend
\n
FEVector information\n====================\n   block  |  ndofs \t|     min  /  max    \t| FEType \t\t (name/tag)\n [    1]  |    8450\t| -1.00e+00/1.00e+00  \t| velocity space  \t (#1)\n [    2]  |    1089\t| -5.06e-01/5.06e-01  \t| pressure space  \t (#2)
\n\n
function solve_stokes_lowlevel(FES, μ, f!)\n    \n    println(\"Initializing system...\")\n    Solution = FEVector(FES)\n    A = FEMatrix(FES)\n    b = FEVector(FES)\n    @time update_system! = prepare_assembly!(A, b, FES[1], FES[2], Solution, f!, μ)\n    @time update_system!(true, false)\n    Alin = deepcopy(A) # = keep linear part of system matrix\n    blin = deepcopy(b) # = keep linear part of right-hand side\n    \n    println(\"Pepare boundary conditions...\")\n    @time begin\n        u_init = FEVector(FES)\n        interpolate!(u_init[1], u!; time = teval)\n        \n        fixed_dofs = [size(A.entries,1)] # fix one pressure dof = last dof\n        BFaceDofs::Adjacency{Int32} = FES[1][ExtendableFEMBase.BFaceDofs]\n        nbfaces::Int = num_sources(BFaceDofs)\n        AM::ExtendableSparseMatrix{Float64,Int64} = A.entries\n        dof_j::Int = 0\n        for bface = 1 : nbfaces\n            for j = 1 : num_targets(BFaceDofs,1)\n                dof_j = BFaceDofs[j, bface]\n                push!(fixed_dofs, dof_j)\n            end\n        end\n    end\n\n    \n    for it = 1 : 20\n        ## solve\n        println(\"\\nITERATION $it\\n=============\")\n        println(\"Solving linear system...\")\n        @time copyto!(Solution.entries, A.entries \\ b.entries)\n        res = A.entries.cscmatrix * Solution.entries .- b.entries\n        for dof in fixed_dofs\n            res[dof] = 0\n        end\n        linres = norm(res)\n        println(\"linear residual = $linres\")\n        \n        fill!(A.entries.cscmatrix.nzval,0)\n        fill!(b.entries,0)\n        println(\"Updating linear system...\")\n        @time begin\n            update_system!(false,true)\n            A.entries.cscmatrix += Alin.entries.cscmatrix\n            b.entries .+= blin.entries\n        end\n        \n        ## fix boundary dofs\n        for dof in fixed_dofs\n            AM[dof,dof] = 1e60\n            b.entries[dof] = 1e60 * u_init.entries[dof]\n        end\n        ExtendableSparse.flush!(A.entries)\n\n        ## calculate nonlinear residual\n        res = A.entries.cscmatrix * Solution.entries .- b.entries\n        for dof in fixed_dofs\n            res[dof] = 0\n        end\n        nlres = norm(res)\n        println(\"nonlinear residual = $nlres\")\n        if nlres < max(1e-12, 20*linres)\n            break\n        end\n    end\n\n    return Solution, u_init\nend
\n
solve_stokes_lowlevel (generic function with 1 method)
\n\n
function prepare_assembly!(A, b, FESu, FESp, Solution, f, μ = 1)\n\n    A = A.entries\n    b = b.entries\n    Solution = Solution.entries\n    xgrid = FESu.xgrid\n    EG = xgrid[UniqueCellGeometries][1]\n    FEType_u = eltype(FESu)\n    FEType_p = eltype(FESp)\n    L2G = L2GTransformer(EG, xgrid, ON_CELLS)\n    cellvolumes = xgrid[CellVolumes]\n    ncells::Int = num_cells(xgrid)\n\n    ## dofmap\n    CellDofs_u = FESu[ExtendableFEMBase.CellDofs]\n    CellDofs_p = FESp[ExtendableFEMBase.CellDofs]\n    offset_p = FESu.ndofs\n    \n    ## quadrature formula\n    qf = QuadratureRule{Float64, EG}(3*get_polynomialorder(FEType_u, EG)-1)\n    weights::Vector{Float64} = qf.w\n    xref::Vector{Vector{Float64}} = qf.xref\n    nweights::Int = length(weights)\n    \n    ## FE basis evaluator\n    FEBasis_∇u = FEEvaluator(FESu, Gradient, qf)\n    ∇uvals = FEBasis_∇u.cvals\n    FEBasis_idu = FEEvaluator(FESu, Identity, qf)\n    iduvals = FEBasis_idu.cvals\n    FEBasis_idp = FEEvaluator(FESp, Identity, qf)\n    idpvals = FEBasis_idp.cvals\n\n    ## prepare automatic differentation of convection operator\n    function operator!(result, input)\n        # result = (u ⋅ ∇)u\n        result[1] = input[1]*input[3]+input[2]*input[4]\n        result[2] = input[1]*input[5]+input[2]*input[6]\n    end\n    result = Vector{Float64}(undef,2)\n    input = Vector{Float64}(undef,6)\n    tempV = zeros(Float64, 2)\n    Dresult = DiffResults.JacobianResult(result, input)\n    cfg = ForwardDiff.JacobianConfig(operator!, result, input, ForwardDiff.Chunk{6}())\n    jac = DiffResults.jacobian(Dresult)\n    value = DiffResults.value(Dresult)\n    \n   \n    ## ASSEMBLY LOOP\n    function barrier(EG, L2G::L2GTransformer, linear::Bool, nonlinear::Bool)\n        ## barrier function to avoid allocations caused by L2G\n        \n    \tndofs4cell_u::Int = get_ndofs(ON_CELLS, FEType_u, EG)\n    \tndofs4cell_p::Int = get_ndofs(ON_CELLS, FEType_p, EG)\n    \tAloc = zeros(Float64, ndofs4cell_u, ndofs4cell_u)\n    \tBloc = zeros(Float64, ndofs4cell_u, ndofs4cell_p)\n    \tdof_j::Int, dof_k::Int = 0, 0\n        fval::Vector{Float64} = zeros(Float64,2)\n        x::Vector{Float64} = zeros(Float64, 2)\n        \n        for cell = 1 : ncells\n            ## update FE basis evaluators\n            update_basis!(FEBasis_∇u, cell)\n            update_basis!(FEBasis_idu, cell)\n            update_basis!(FEBasis_idp, cell) \n    \n            ## assemble local stiffness matrix (symmetric)\n            if (linear)\n                for j = 1 : ndofs4cell_u, k = 1 : ndofs4cell_u\n                    temp = 0\n                    for qp = 1 : nweights\n                        temp += weights[qp] * dot(view(∇uvals,:,j,qp), view(∇uvals,:,k,qp))\n                    end\n                    Aloc[k,j] = μ * temp\n                end\n\n                ## assemble div-pressure coupling\n                for j = 1 : ndofs4cell_u, k = 1 : ndofs4cell_p\n                    temp = 0\n                    for qp = 1 : nweights\n                        temp -= weights[qp] * (∇uvals[1,j,qp] + ∇uvals[4,j,qp]) * \n                        idpvals[1,k,qp]\n                    end\n                    Bloc[j,k] = temp\n                end\n                Bloc .*= cellvolumes[cell]\n                \n                ## assemble right-hand side\n                update_trafo!(L2G, cell)\n                for j = 1 : ndofs4cell_u\n                    ## right-hand side\n                    temp = 0\n                    for qp = 1 : nweights\n                        ## get global x for quadrature point\n                        eval_trafo!(x, L2G, xref[qp])\n                        ## evaluate (f(x), v_j(x))\n                        f!(fval, x, teval)\n                        temp += weights[qp] * dot(view(iduvals,: , j, qp), fval)\n                    end\n                    ## write into global vector\n                    dof_j = CellDofs_u[j, cell]\n                    b[dof_j] += temp * cellvolumes[cell]\n                end\n            end\n\n            ## assemble nonlinear term\n            if (nonlinear)\n                for qp = 1 : nweights\n                    fill!(input,0)\n                    for j = 1 : ndofs4cell_u\n                        dof_j = CellDofs_u[j, cell]\n                        for d = 1 : 2\n                            input[d] += Solution[dof_j] * iduvals[d,j,qp]\n                        end\n                        for d = 1 : 4\n                            input[2+d] += Solution[dof_j] * ∇uvals[d,j,qp]\n                        end\n                    end\n                    \n                \t## evaluate jacobian\n                    ForwardDiff.chunk_mode_jacobian!(Dresult, operator!, result, input, cfg)\n                    \n                    # update matrix\n                    for j = 1 : ndofs4cell_u\n                        # multiply ansatz function with local jacobian\n                        fill!(tempV,0)\n                        for d = 1 : 2\n                            tempV[1] += jac[1,d] * iduvals[d,j,qp]\n                            tempV[2] += jac[2,d] * iduvals[d,j,qp]\n                        end\n                        for d = 1 : 4\n                            tempV[1] += jac[1,2+d] * ∇uvals[d,j,qp]\n                            tempV[2] += jac[2,2+d] * ∇uvals[d,j,qp]\n                        end\n    \n                        # multiply test function operator evaluation\n                        for k = 1 : ndofs4cell_u\n                            Aloc[k,j] += dot(tempV,view(iduvals,:,k,qp)) * weights[qp]\n                        end\n                    end \n    \n                    # update rhs\n                    mul!(tempV, jac, input)\n                    tempV .-= value\n                    for j = 1 : ndofs4cell_u\n                \t\tdof_j = CellDofs_u[j, cell]\n                \t\tb[dof_j] += dot(tempV, view(iduvals,:,j,qp)) * weights[qp] * cellvolumes[cell]\n                    end\n                end\n            end\n            \n            ## add local matrices to global matrix\n            Aloc .*= cellvolumes[cell]\n            for j = 1 : ndofs4cell_u\n                dof_j = CellDofs_u[j, cell]\n                for k = 1 : ndofs4cell_u\n                    dof_k = CellDofs_u[k, cell]\n                    rawupdateindex!(A, +, Aloc[j,k], dof_j, dof_k)\n                end\n                if (linear)\n                    for k = 1 : ndofs4cell_p\n                        dof_k = CellDofs_p[k, cell] + offset_p\n                        rawupdateindex!(A, +, Bloc[j,k], dof_j, dof_k) \n                        rawupdateindex!(A, +, Bloc[j,k], dof_k, dof_j)\n                    end\n                end\n            end\n            fill!(Aloc, 0)\n            fill!(Bloc, 0)\n        end\n    end\n\n    function update_system!(linear::Bool, nonlinear::Bool)\n        barrier(EG, L2G, linear, nonlinear)\n        flush!(A)\n    end\n    update_system!\nend
\n
prepare_assembly! (generic function with 2 methods)
\n
\n

Built with Julia 1.10.4 and

\nDiffResults 1.1.0
\nExtendableFEMBase 0.6.0
\nExtendableGrids 1.9.0
\nExtendableSparse 1.5.0
\nForwardDiff 0.10.36
\nGridVisualize 1.7.0
\nPlutoVista 1.0.1\n
\n\n","category":"page"},{"location":"plutostatichtml_examples/LowLevelNavierStokes/","page":"Low level Navier-Stokes","title":"Low level Navier-Stokes","text":"EditURL = \"https://github.com/chmerdon/ExtendableFEMBase.jl/blob/master/nothing\"","category":"page"},{"location":"module_examples/Example290_InterpolationBetweenMeshes/#290-:-Interpolation-Between-Meshes","page":"Example290_InterpolationBetweenMeshes","title":"290 : Interpolation Between Meshes","text":"","category":"section"},{"location":"module_examples/Example290_InterpolationBetweenMeshes/","page":"Example290_InterpolationBetweenMeshes","title":"Example290_InterpolationBetweenMeshes","text":"(source code)","category":"page"},{"location":"module_examples/Example290_InterpolationBetweenMeshes/","page":"Example290_InterpolationBetweenMeshes","title":"Example290_InterpolationBetweenMeshes","text":"This example demonstrates the interpolation between meshes feature. Here, we interpolate a function with the P2 element of a coarse triangulation and then interpolate this P2 function on two uniform refinements into some P1 function. Then, both finite element functions are plotted.","category":"page"},{"location":"module_examples/Example290_InterpolationBetweenMeshes/","page":"Example290_InterpolationBetweenMeshes","title":"Example290_InterpolationBetweenMeshes","text":"The computed solution for the default parameters looks like this:","category":"page"},{"location":"module_examples/Example290_InterpolationBetweenMeshes/","page":"Example290_InterpolationBetweenMeshes","title":"Example290_InterpolationBetweenMeshes","text":"(Image: )","category":"page"},{"location":"module_examples/Example290_InterpolationBetweenMeshes/","page":"Example290_InterpolationBetweenMeshes","title":"Example290_InterpolationBetweenMeshes","text":"module Example290_InterpolationBetweenMeshes\n\nusing ExtendableFEMBase\nusing ExtendableGrids\nusing GridVisualize\n\n# function to interpolate\nfunction u!(result, qpinfo)\n\tx = qpinfo.x\n\tresult[1] = sin(4 * pi * x[1]) * sin(4 * pi * x[2])\n\tresult[2] = cos(4 * pi * x[1]) * cos(4 * pi * x[2])\nend\n\n# everything is wrapped in a main function\nfunction main(; ν = 1e-3, nrefs = 4, Plotter = nothing)\n\n\t# generate two grids\n\txgrid1 = uniform_refine(grid_unitsquare(Triangle2D), nrefs)\n\txgrid2 = uniform_refine(xgrid1, 3; store_parents = true)\n\n\t@show xgrid1 xgrid2\n\n\t# set finite element types for the two grids\n\tFEType1 = H1Pk{2, 2, 2}\n\tFEType2 = H1Pk{2, 2, 1}\n\n\t# generate coressponding finite element spaces and FEVectors\n\tFES1 = FESpace{FEType1}(xgrid1)\n\tFES2 = FESpace{FEType2}(xgrid2)\n\tFEFunction1 = FEVector(FES1)\n\tFEFunction2 = FEVector(FES2)\n\n\t# interpolate function onto first grid\n\t@time interpolate!(FEFunction1[1], u!)\n\t@time interpolate!(FEFunction2[1], u!)\n\n\t# interpolate onto other grid\n\t@time lazy_interpolate!(FEFunction2[1], FEFunction1)\n\t@time lazy_interpolate!(FEFunction2[1], FEFunction1; use_cellparents = true)\n\n\t# plot\n\tp = GridVisualizer(; Plotter = Plotter, layout = (1, 2), clear = true, resolution = (800, 400))\n\tscalarplot!(p[1, 1], xgrid1, view(nodevalues(FEFunction1[1]), 1, :), levels = 11, title = \"u_h ($FEType1, coarse grid)\")\n\tscalarplot!(p[1, 2], xgrid2, view(nodevalues(FEFunction2[1]), 1, :), levels = 11, title = \"u_h ($FEType2, fine grid)\")\n\n\treturn p\nend\n\nfunction generateplots(dir = pwd(); Plotter = nothing, kwargs...)\n\tplt = main(; Plotter = Plotter, kwargs...)\n\tscene = GridVisualize.reveal(plt)\n\tGridVisualize.save(joinpath(dir, \"example290.png\"), scene; Plotter = Plotter)\nend\n\nend","category":"page"},{"location":"module_examples/Example290_InterpolationBetweenMeshes/","page":"Example290_InterpolationBetweenMeshes","title":"Example290_InterpolationBetweenMeshes","text":"","category":"page"},{"location":"module_examples/Example290_InterpolationBetweenMeshes/","page":"Example290_InterpolationBetweenMeshes","title":"Example290_InterpolationBetweenMeshes","text":"This page was generated using Literate.jl.","category":"page"},{"location":"fems/#Implemented-Finite-Elements","page":"List of Finite Elements","title":"Implemented Finite Elements","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"This page describes the finite element type-tree and lists all implemented finite elements.","category":"page"},{"location":"fems/#The-Finite-Element-Type-Tree","page":"List of Finite Elements","title":"The Finite Element Type-Tree","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"Finite elements are abstract type leaves in a type-tree. The complete tree looks like this:","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"AbstractFiniteElement\n├─ AbstractH1FiniteElement\n│ ├─ AbstractH1FiniteElementWithCoefficients\n│ │ ├─ H1P1TEB\n│ │ └─ H1BR\n│ ├─ H1CR\n│ ├─ H1MINI\n│ ├─ L2P0\n│ ├─ L2P1\n│ ├─ H1P1\n│ ├─ H1P2\n│ ├─ H1P2B\n│ ├─ H1P3\n│ ├─ H1Pk\n│ ├─ H1Q1\n│ └─ H1Q2\n├─ AbstractHcurlFiniteElement\n│ ├─ HCURLN0\n│ └─ HCURLN1\n└─ AbstractHdivFiniteElement\n ├─ HDIVBDM1\n ├─ HDIVBDM2\n ├─ HDIVRT0\n ├─ HDIVRT1\n ├─ HDIVRTk\n └─ HDIVRTkENRICH","category":"page"},{"location":"fems/#Remarks","page":"List of Finite Elements","title":"Remarks","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"each type depends on one/two or three parameters, the first one is always the number of components (ncomponents) that determines if the finite element is scalar- or veector-valued; some elements additionaly require the parameter edim <: Int if they are structurally different in different space dimensions; arbitrary order elements require a third parameter that determines the order\neach finite elements mainly comes with a set of basis functions in reference coordinates for each applicable AbstractElementGeometry and degrees of freedom maps for each mesh entity\nbroken finite elements are possible via the broken switch in the FESpace constructor\nthe type steers how the basis functions are transformed from local to global coordinates and how FunctionOperators are evaluated\ndepending on additional continuity properties of the element types more basis function sets are defined:\nAbstractH1FiniteElements additionally have evaluations of nonzero basisfunctions on faces/bfaces\nAbstractHdivFiniteElements additionally have evaluations of nonzero normalfluxes of basisfunctions on faces/bfaces\nAbstractHcurlFiniteElements additionally have evaluations of nonzero tangentfluxes of basisfunctions on edges/bedges\neach finite element has its own implemented standard interpolation interpolate! (see Finite Element Interpolations) that can be applied to a function with header function(result, qpinfo), below it is shortly described what this means for each finite element","category":"page"},{"location":"fems/#List-of-implemented-Finite-Elements","page":"List of Finite Elements","title":"List of implemented Finite Elements","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The following table lists all curently implemented finite elements and on which geometries they are available (in brackets a dofmap pattern for CellDofs is shown and the number of local degrees of freedom for a vector-valued realisation). Click on the FEType to find out more details.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"FEType Triangle2D Parallelogram2D Tetrahedron3D Parallelepiped3D\nAbstractH1FiniteElementWithCoefficients \nH1BR ✓ (N1f1, 9) ✓ (N1f1, 12) ✓ (N1f1, 16) \nH1P1TEB ✓ (N1f1, 9) ✓ (N1e1, 18) \nAbstractH1FiniteElement \nH1BUBBLE ✓ (I1, 2) ✓ (I1, 2) ✓ (I1, 3) \nH1CR ✓ (F1, 6) ✓ (F1, 8) ✓ (F1, 12) \nH1MINI ✓ (N1I1, 8) ✓ (N1I1, 10) ✓ (N1I1, 15) \nL2P0 ✓ (I1, 2) ✓ (I1, 2) ✓ (I1, 3) ✓ (I1, 3)\nL2P1 ✓ (I3, 6) ✓ (I3, 6) ✓ (I4, 12) ✓ (I4, 12)\nH1P1 ✓ (N1, 6) ✓ (N1, 12) \nH1P2 ✓ (N1F1, 12) ✓ (N1E1, 30) \nH1P2B ✓ (N1F1I1, 14) \nH1P3 ✓ (N1F2I1, 20) ✓ (N1E2F1, 60) \nH1Pk ✓ (order-dep) \nH1Q1 ✓ (N1, 6) ✓ (N1, 8) ✓ (N1, 12) ✓ (N1, 24)\nH1Q2 ✓ (N1F1, 12) ✓ (N1F1I1, 18) ✓ (N1E1, 30) \nAbstractHcurlFiniteElement \nHCURLN0 ✓ (f1, 3) ✓ (f1, 4) ✓ (e1, 6) \nHCURLN1 ✓ (f1, 6) \nAbstractHdivFiniteElement \nHDIVBDM1 ✓ (f2, 6) ✓ (f2, 8) ✓ (f3, 12) \nHDIVBDM2 ✓ (f3i3, 12) \nHDIVRT0 ✓ (f1, 3) ✓ (f1, 4) ✓ (f1, 4) ✓ (f1, 6)\nHDIVRT1 ✓ (f2i2, 8) ✓ (f3i3, 15) \nHDIVRTk ✓ (order-dep) \nHDIVRTkENRICH ✓ (order-dep) ✓ (order-dep) ","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"Note: the dofmap pattern describes the connection of the local degrees of freedom to entities of the grid and also hints to the continuity. Here, \"N\" or \"n\" means nodes, \"F\" or \"f\" means faces, \"E\" or \"e\" means edges and \"I\" means interior (dofs without any continuity across elements). Capital letters cause that every component has its own degree of freedom, while small letters signalize that only one dof is associated to the entity. As an example \"N1f1\" (for the Bernardi-Raugel element) means that at each node sits one dof per component and at each face sits a single dof. Usually finite elements that involve small letters are only defined vector-valued (i.e. the number of components has to match the element dimension), while finite elements that only involve capital letters are available for any number of components.","category":"page"},{"location":"fems/#H1-conforming-finite-elements","page":"List of Finite Elements","title":"H1-conforming finite elements","text":"","category":"section"},{"location":"fems/#P0-finite-element","page":"List of Finite Elements","title":"P0 finite element","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"Piecewise constant finite element that has one degree of freedom on each cell of the grid. (It is masked as a H1-conforming finite element, because it uses the same operator evaulations.)","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The interpolation of a given function into this space preserves the cell integrals.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"L2P0","category":"page"},{"location":"fems/#ExtendableFEMBase.L2P0","page":"List of Finite Elements","title":"ExtendableFEMBase.L2P0","text":"abstract type L2P0{ncomponents} <: AbstractH1FiniteElement where {ncomponents<:Int}\n\nPiecewise constant polynomials on cells.\n\nallowed ElementGeometries:\n\nany\n\n\n\n\n\n","category":"type"},{"location":"fems/#P1-finite-element","page":"List of Finite Elements","title":"P1 finite element","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The lowest-order Courant finite element that has a degree of freedom on each vertex of the grid. On simplices the basis functions coincide with the linear barycentric coordinates. Only the L2P1 element is also defined on quads.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The interpolation of a given function into this space performs point evaluations at the nodes.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"L2P1\nH1P1","category":"page"},{"location":"fems/#ExtendableFEMBase.L2P1","page":"List of Finite Elements","title":"ExtendableFEMBase.L2P1","text":"abstract type L2P1{ncomponents} <: AbstractH1FiniteElement where {ncomponents<:Int}\n\nDiscontinuous piecewise first-order linear polynomials.\n\nallowed ElementGeometries:\n\nany\n\n\n\n\n\n","category":"type"},{"location":"fems/#ExtendableFEMBase.H1P1","page":"List of Finite Elements","title":"ExtendableFEMBase.H1P1","text":"abstract type H1P1{ncomponents} <: AbstractH1FiniteElement where {ncomponents<:Int}\n\nContinuous piecewise first-order linear polynomials.\n\nallowed ElementGeometries:\n\nEdge1D\nTriangle2D\nTetrahedron3D\n\n\n\n\n\n","category":"type"},{"location":"fems/#Q1-finite-element","page":"List of Finite Elements","title":"Q1 finite element","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The lowest-order finite element that has a degree of freedom on each vertex of the grid. On simplices the basis functions coincide with the linear barycentric coordinates. This element is also defined on quads.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The interpolation of a given function into this space performs point evaluations at the nodes.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"H1Q1","category":"page"},{"location":"fems/#ExtendableFEMBase.H1Q1","page":"List of Finite Elements","title":"ExtendableFEMBase.H1Q1","text":"abstract type Q1P1{ncomponents} <: AbstractH1FiniteElement where {ncomponents<:Int}\n\nContinuous piecewise first-order polynomials on simplices and quads, can be used for mixed geometries.\n\nallowed ElementGeometries:\n\nEdge1D (P1 space)\nTriangle2D (P1 space)\nQuadrilateral2D (Q1 space)\nTetrahedron3D (P1 space)\nHexahedron3D (Q1 space)\n\n\n\n\n\n","category":"type"},{"location":"fems/#MINI-finite-element","page":"List of Finite Elements","title":"MINI finite element","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The mini finite element adds cell bubles to the P1 element that are e.g. beneficial to define inf-sup stable finite element pairs for the Stokes problem.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The interpolation of a given function into this space performs point evaluations at the nodes and preserves its cell integral.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"H1MINI","category":"page"},{"location":"fems/#ExtendableFEMBase.H1MINI","page":"List of Finite Elements","title":"ExtendableFEMBase.H1MINI","text":"abstract type H1MINI{ncomponents,edim} <: AbstractH1FiniteElement where {ncomponents<:Int,edim<:Int}\n\nMini finite element.\n\nallowed element geometries:\n\nTriangle2D (linear polynomials + cubic cell bubble)\nQuadrilateral2D (Q1 space + quartic cell bubble)\nTetrahedron3D (linear polynomials + cubic cell bubble)\n\n\n\n\n\n","category":"type"},{"location":"fems/#P1TEB-finite-element","page":"List of Finite Elements","title":"P1TEB finite element","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"This element adds tangent-weighted edge bubbles to the P1 finite element and therefore is only available as a vector-valued element.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The interpolation of a given function into this space performs point evaluations at the nodes and preserves face integrals of its tangential flux.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"H1P1TEB","category":"page"},{"location":"fems/#ExtendableFEMBase.H1P1TEB","page":"List of Finite Elements","title":"ExtendableFEMBase.H1P1TEB","text":"abstract type H1P1TEB{edim} <: AbstractH1FiniteElementWithCoefficients where {edim<:Int}\n\nvector-valued (ncomponents = edim) element that uses P1 functions + tangential-weighted edge bubbles as suggested by [Diening, L., Storn, J. & Tscherpel, T., \"Fortin operator for the Taylor–Hood element\", Numer. Math. 150, 671–689 (2022)]\n\n(is inf-sup stable for Stokes if paired with continuous P1 pressure space, less degrees of freedom than MINI)\n\nallowed ElementGeometries:\n\nTriangle2D\nTetrahedron3D\n\n\n\n\n\n","category":"type"},{"location":"fems/#Bernardi-Raugel-(BR)-finite-element","page":"List of Finite Elements","title":"Bernardi-Raugel (BR) finite element","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The Bernardi-Raugel adds normal-weighted face bubbles to the P1 finite element and therefore is only available as a vector-valued element.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The interpolation of a given function into this space performs point evaluations at the nodes and preserves face integrals of its normal flux.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"H1BR","category":"page"},{"location":"fems/#ExtendableFEMBase.H1BR","page":"List of Finite Elements","title":"ExtendableFEMBase.H1BR","text":"abstract type H1BR{edim} <: AbstractH1FiniteElementWithCoefficients where {edim<:Int}\n\nvector-valued (ncomponents = edim) Bernardi–Raugel element (first-order polynomials + normal-weighted face bubbles)\n\nallowed ElementGeometries:\n\nTriangle2D (piecewise linear + normal-weighted face bubbles)\nQuadrilateral2D (Q1 space + normal-weighted face bubbles)\nTetrahedron3D (piecewise linear + normal-weighted face bubbles)\n\n\n\n\n\n","category":"type"},{"location":"fems/#P2-finite-element","page":"List of Finite Elements","title":"P2 finite element","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The P2 finite element method on simplices equals quadratic polynomials. On the Triangle2D shape the degrees of freedom are associated with the three vertices and the three faces of the triangle. On the Tetrahedron3D shape the degrees of freedom are associated with the four verties and the six edges.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The interpolation of a given function into this space performs point evaluations at the nodes and preserves its face/edge integrals in 2D/3D.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"H1P2","category":"page"},{"location":"fems/#ExtendableFEMBase.H1P2","page":"List of Finite Elements","title":"ExtendableFEMBase.H1P2","text":"abstract type H1P2{ncomponents,edim} <: AbstractH1FiniteElement where {ncomponents<:Int,edim<:Int}\n\nContinuous piecewise second-order polynomials.\n\nallowed ElementGeometries:\n\nEdge1D\nTriangle2D\nTetrahedron3D\n\n\n\n\n\n","category":"type"},{"location":"fems/#Q2-finite-element","page":"List of Finite Elements","title":"Q2 finite element","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"A second order finite element. On simplices it equals the P2 finite element, and on Quadrilateral2D it has 9 degrees of freedom (vertices, faces and one cell bubble).","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The interpolation of a given function into this space performs point evaluations at the nodes and preserves lowest order face moments and (only on quads) also the cell integreal mean.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"H1Q2","category":"page"},{"location":"fems/#ExtendableFEMBase.H1Q2","page":"List of Finite Elements","title":"ExtendableFEMBase.H1Q2","text":"abstract type H1Q2{ncomponents,edim} <: AbstractH1FiniteElement where {ncomponents<:Int,edim<:Int}\n\nContinuous piecewise second-order polynomials on simplices and quads. Can be used with mixed geometries (in 2D).\n\nallowed ElementGeometries:\n\nEdge1D (P2 space)\nTriangle2D (P2 space)\nQuadrilateral2D (Q2 space with cell bubble)\nTetrahedron3D (P2 space)\n\n\n\n\n\n","category":"type"},{"location":"fems/#P2B-finite-element","page":"List of Finite Elements","title":"P2B finite element","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The P2B finite element adds additional cell bubles (in 2D and 3D) and face bubbles (only in 3D) that are e.g. used to define inf-sup stable finite element pairs for the Stokes problem.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The interpolation of a given function into this space performs point evaluations at the nodes and preserves its cell and face integrals in 2D and also edge integrals in 3D.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"H1P2B","category":"page"},{"location":"fems/#ExtendableFEMBase.H1P2B","page":"List of Finite Elements","title":"ExtendableFEMBase.H1P2B","text":"abstract type H1P2B{ncomponents,edim} <: AbstractH1FiniteElement where {ncomponents<:Int,edim<:Int}\n\nContinuous piecewise second-order polynomials.\n\nallowed ElementGeometries:\n\nTriangle2D\n\n\n\n\n\n","category":"type"},{"location":"fems/#P3-finite-element","page":"List of Finite Elements","title":"P3 finite element","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The P3 finite element method on simplices equals cubic polynomials. On the Triangle2D shape the degrees of freedom are associated with the three vertices, the three faces (double dof) of the triangle and the cell itself (one cell bubble).","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The interpolation of a given function into this space performs point evaluations at the nodes and preserves cell and face integrals in 2D.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"H1P3","category":"page"},{"location":"fems/#ExtendableFEMBase.H1P3","page":"List of Finite Elements","title":"ExtendableFEMBase.H1P3","text":"abstract type H1P3{ncomponents,edim} <: AbstractH1FiniteElement where {ncomponents<:Int,edim<:Int}\n\nContinuous piecewise third-order polynomials.\n\nallowed ElementGeometries:\n\nEdge1D\nTriangle2D\nTetrahedron3D\n\n\n\n\n\n","category":"type"},{"location":"fems/#Pk-finite-element-(experimental)","page":"List of Finite Elements","title":"Pk finite element (experimental)","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The Pk finite element method generically generates polynomials of abitrary order k on simplices (Edge1D, Triangle2D so far).","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The interpolation of a given function into this space performs point evaluations at the nodes and preserves cell and face integrals in 2D (moment order depends on the order and the element dimension).","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"H1Pk","category":"page"},{"location":"fems/#ExtendableFEMBase.H1Pk","page":"List of Finite Elements","title":"ExtendableFEMBase.H1Pk","text":"abstract type H1PK{ncomponents,edim,order} <: AbstractH1FiniteElement where {ncomponents<:Int,edim<:Int,order<:Int}\n\nContinuous piecewise polynomials of arbitrary order >= 1 with ncomponents components in edim space dimensions.\n\nallowed ElementGeometries:\n\nEdge1D\nTriangle2D\n\n\n\n\n\n","category":"type"},{"location":"fems/#Crouzeix-Raviart-(CR)-finite-element","page":"List of Finite Elements","title":"Crouzeix-Raviart (CR) finite element","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The Crouzeix-Raviart element associates one lowest-order function with each face. On the Triangle2D shape, the basis function of a face is one minus two times the nodal basis function of the opposite node. ","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The interpolation of a given function into this space preserves its face integrals.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"H1CR","category":"page"},{"location":"fems/#ExtendableFEMBase.H1CR","page":"List of Finite Elements","title":"ExtendableFEMBase.H1CR","text":"abstract type H1CR{ncomponents} <: AbstractH1FiniteElement where {ncomponents<:Int}\n\nCrouzeix-Raviart element (only continuous at face centers).\n\nallowed ElementGeometries:\n\nTriangle2D (piecewise linear, similar to P1)\nQuadrilateral2D (similar to Q1 space)\nTetrahedron3D (piecewise linear, similar to P1)\n\n\n\n\n\n","category":"type"},{"location":"fems/#Hdiv-conforming-finite-elements","page":"List of Finite Elements","title":"Hdiv-conforming finite elements","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"These Raviart-Thomas and Brezzi-Douglas-Marini finite elements of lower order and their standard interpolations are available:","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"HDIVRT0\nHDIVBDM1\nHDIVRT1\nHDIVBDM2\nHDIVRTk\nHDIVRTkENRICH","category":"page"},{"location":"fems/#ExtendableFEMBase.HDIVRT0","page":"List of Finite Elements","title":"ExtendableFEMBase.HDIVRT0","text":"abstract type HDIVRT0{edim} <: AbstractHdivFiniteElement where {edim<:Int}\n\nHdiv-conforming vector-valued (ncomponents = edim) lowest-order Raviart-Thomas space.\n\nallowed ElementGeometries:\n\nTriangle2D\nQuadrilateral2D\nTetrahedron3D\nHexahedron3D\n\n\n\n\n\n","category":"type"},{"location":"fems/#ExtendableFEMBase.HDIVBDM1","page":"List of Finite Elements","title":"ExtendableFEMBase.HDIVBDM1","text":"abstract type HDIVBDM1{edim} <: AbstractHdivFiniteElement where {edim<:Int}\n\nHdiv-conforming vector-valued (ncomponents = edim) lowest-order Brezzi-Douglas-Marini space\n\nallowed ElementGeometries:\n\nTriangle2D\nQuadrilateral2D\nTetrahedron3D\n\n\n\n\n\n","category":"type"},{"location":"fems/#ExtendableFEMBase.HDIVRT1","page":"List of Finite Elements","title":"ExtendableFEMBase.HDIVRT1","text":"abstract type HDIVRT1{edim} <: AbstractHdivFiniteElement where {edim<:Int}\n\nHdiv-conforming vector-valued (ncomponents = edim) Raviart-Thomas space of order 1.\n\nallowed ElementGeometries:\n\nTriangle2D\nTetrahedron3D\n\n\n\n\n\n","category":"type"},{"location":"fems/#ExtendableFEMBase.HDIVBDM2","page":"List of Finite Elements","title":"ExtendableFEMBase.HDIVBDM2","text":"abstract type HDIVBDM2{edim} <: AbstractHdivFiniteElement where {edim<:Int}\n\nHdiv-conforming vector-valued (ncomponents = edim) Brezzi-Douglas-Marini space of order 2\n\nallowed ElementGeometries:\n\nTriangle2D\n\n\n\n\n\n","category":"type"},{"location":"fems/#ExtendableFEMBase.HDIVRTk","page":"List of Finite Elements","title":"ExtendableFEMBase.HDIVRTk","text":"abstract type HDIVRTk{edim, order} <: AbstractHdivFiniteElement where {edim<:Int}\n\nHdiv-conforming vector-valued (ncomponents = edim) Raviart-Thomas space of arbitrary order.\n\nallowed ElementGeometries:\n\nTriangle2D\n\n\n\n\n\n","category":"type"},{"location":"fems/#ExtendableFEMBase.HDIVRTkENRICH","page":"List of Finite Elements","title":"ExtendableFEMBase.HDIVRTkENRICH","text":"abstract type HDIVRTkENRICH{k,edim} <: AbstractHdivFiniteElement where {edim<:Int}\n\nInternal (normal-zero) Hdiv-conforming vector-valued (ncomponents = edim) Raviart-Thomas space of order k ≥ 1 with the additional orthogonality property that their divergences are L2-orthogonal on P_{k-edim+1}. Example: HDIVRTkENRICH{1,2} gives the edim interior RT1 bubbles (= normal-trace-free) on a triangle, their divergences have integral mean zero; HDIVRTkENRICH{2,2} gives three RT2 bubbles on a triangle whose divergences are L2-orthogonal onto all P1 functions. The maximal order for k is 4 on a Triangle2D (edim = 2) and 3 on Tetrahedron3D (edim = 3). These spaces have no approximation power on their own, but can be used as enrichment spaces in divergence-free schemes for incompressible Stokes problems.\n\nallowed ElementGeometries:\n\nTriangle2D\nTetrahedron3D\n\n\n\n\n\n","category":"type"},{"location":"fems/#Hcurl-conforming-finite-elements","page":"List of Finite Elements","title":"Hcurl-conforming finite elements","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"So far only the lowest order Nedelec element is available in 2D and 3D. On Triangle2D it has one degree of freedom for each face (i.e. the rotated RT0 element), on Tetrahedron3D it has one degree of freedom associated to each of the six edges.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"Its standard interpolation of a given functions preserves its tangential face/edge integrals.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"HCURLN0\nHCURLN1","category":"page"},{"location":"fems/#ExtendableFEMBase.HCURLN0","page":"List of Finite Elements","title":"ExtendableFEMBase.HCURLN0","text":"abstract type HCURLN0{edim} <: AbstractHcurlFiniteElement where {edim<:Int}\n\nHcurl-conforming vector-valued (ncomponents = edim) lowest-order Nedelec space of first kind.\n\nallowed ElementGeometries:\n\nTriangle2D\nQuadrilateral2D\nTetrahedron3D\n\n\n\n\n\n","category":"type"},{"location":"fems/#ExtendableFEMBase.HCURLN1","page":"List of Finite Elements","title":"ExtendableFEMBase.HCURLN1","text":"abstract type HCURLN1{edim} <: AbstractHcurlFiniteElement where {edim<:Int}\n\nHcurl-conforming vector-valued (ncomponents = edim) Nedelec space of first kind and order 1.\n\nallowed ElementGeometries:\n\nTriangle2D\n\n\n\n\n\n","category":"type"},{"location":"fems/#Incomplete-finite-elements-without-approximation-power","page":"List of Finite Elements","title":"Incomplete finite elements without approximation power","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"H1BUBBLE","category":"page"},{"location":"fems/#ExtendableFEMBase.H1BUBBLE","page":"List of Finite Elements","title":"ExtendableFEMBase.H1BUBBLE","text":"abstract type H1BUBBLE{ncomponents} <: AbstractH1FiniteElement where {ncomponents<:Int}\n\nPiecewise bubbles (=zero at boundary)\n\nallowed element geometries:\n\nEdge1D (one quadratic bubble)\nTriangle2D (one cubic bubble)\nQuadrilateral2D (one quartic bubble)\nTetrahedron3D (one cubic bubble)\n\n\n\n\n\n","category":"type"},{"location":"notebooks_intro/#About-the-notebooks","page":"About the notebooks","title":"About the notebooks","text":"","category":"section"},{"location":"notebooks_intro/","page":"About the notebooks","title":"About the notebooks","text":"This sections contains Pluto.jl notebooks.","category":"page"},{"location":"notebooks_intro/","page":"About the notebooks","title":"About the notebooks","text":"Plese note, that in the html version, interactive elements like sliders are disabled. Navigation via the table of contents does work, though.","category":"page"},{"location":"module_examples/Example205_LowLevelSpaceTimePoisson/#205-:-Space-Time-FEM-for-Poisson-Problem","page":"Example205_LowLevelSpaceTimePoisson","title":"205 : Space-Time FEM for Poisson Problem","text":"","category":"section"},{"location":"module_examples/Example205_LowLevelSpaceTimePoisson/","page":"Example205_LowLevelSpaceTimePoisson","title":"Example205_LowLevelSpaceTimePoisson","text":"(source code)","category":"page"},{"location":"module_examples/Example205_LowLevelSpaceTimePoisson/","page":"Example205_LowLevelSpaceTimePoisson","title":"Example205_LowLevelSpaceTimePoisson","text":"This example computes the solution u of the two-dimensional heat equation","category":"page"},{"location":"module_examples/Example205_LowLevelSpaceTimePoisson/","page":"Example205_LowLevelSpaceTimePoisson","title":"Example205_LowLevelSpaceTimePoisson","text":"beginaligned\nu_t - Delta u = f quad textin Omega\nendaligned","category":"page"},{"location":"module_examples/Example205_LowLevelSpaceTimePoisson/","page":"Example205_LowLevelSpaceTimePoisson","title":"Example205_LowLevelSpaceTimePoisson","text":"with a (possibly space- and time-depepdent) right-hand side f and homogeneous Dirichlet boundary and initial conditions on the unit square domain Omega on a given grid with space-time finite element methods based on tensorized ansatz functions.","category":"page"},{"location":"module_examples/Example205_LowLevelSpaceTimePoisson/","page":"Example205_LowLevelSpaceTimePoisson","title":"Example205_LowLevelSpaceTimePoisson","text":"(Image: )","category":"page"},{"location":"module_examples/Example205_LowLevelSpaceTimePoisson/","page":"Example205_LowLevelSpaceTimePoisson","title":"Example205_LowLevelSpaceTimePoisson","text":"module Example205_LowLevelSpaceTimePoisson\n\nusing ExtendableFEMBase\nusing ExtendableGrids\nusing ExtendableSparse\nusing GridVisualize\nusing UnicodePlots\nusing Test #\n\n# data for Poisson problem\nconst μ = (t) -> 1e-1*t + 1*max(0,(1-2*t))\nconst f = (x, t) -> sin(3*pi*x[1])*4*t - cos(3*pi*x[2])*4*(1-t)\n\nfunction main(; dt = 0.01, Tfinal = 1, level = 5, order = 1, Plotter = nothing, produce_movie = false )\n\n\t# Finite element type\n\tFEType_time = H1Pk{1, 1, order}\n\tFEType_space = H1Pk{1, 2, order}\n\n # time grid\n T = LinRange(0, Tfinal, round(Int, Tfinal/dt + 1))\n grid_time = simplexgrid(T)\n\n # space grid\n\tX = LinRange(0, 1, 2^level + 1)\n\tgrid_space = simplexgrid(X, X)\n\n # FESpaces for time and space\n FES_time = FESpace{FEType_time}(grid_time)\n FES_space = FESpace{FEType_space}(grid_space)\n\n\t# solve\n sol = solve_poisson_lowlevel(FES_time, FES_space, μ, f)\n\n\t# visualize\n\tif produce_movie\n\t\t@info \"Producing movie...\"\n\t\tvis=GridVisualizer(Plotter=Plotter)\n\t\tmovie(vis, file=\"example205_video.mp4\") do vis\n\t\t\tfor tj = 2 : length(T)\n\t\t\t\tt = T[tj]\n\t\t\t\tfirst = (tj-1)*FES_space.ndofs+1\n\t\t\t\tlast = tj*FES_space.ndofs\n\t\t\t\tscalarplot!(vis, grid_space, view(sol,first:last), title = \"t = $(Float16(t))\")\n\t\t\t\treveal(vis)\n\t\t\tend\n\t\tend\n\t\treturn sol, vis\n\telse\n\t\t@info \"Plotting at five times...\"\n\t\tplot_timesteps = [2,round(Int,length(T)/4+0.25),round(Int,length(T)/2+0.5),round(Int,length(T)-length(T)/4),FES_time.ndofs]\n\t\tplt = GridVisualizer(; Plotter = Plotter, layout = (1, length(plot_timesteps)), clear = true, resolution = (200*length(plot_timesteps), 200))\n\t\tfor tj = 1 : length(plot_timesteps)\n\t\t\tt = plot_timesteps[tj]\n\t\t\tfirst = (t-1)*FES_space.ndofs+1\n\t\t\tlast = t*FES_space.ndofs\n\t\t\tscalarplot!(plt[1,tj], grid_space, view(sol,first:last), title = \"t = $(T[t])\")\n\t\tend\n\t\treturn sol, plt\n\tend\n\nend\n\n\nfunction solve_poisson_lowlevel(FES_time, FES_space, μ, f)\n ndofs_time = FES_time.ndofs\n ndofs_space = FES_space.ndofs\n ndofs_total = ndofs_time * ndofs_space\n\tsol = zeros(Float64, ndofs_total)\n\n\tA = ExtendableSparseMatrix{Float64, Int64}(ndofs_total, ndofs_total)\n\tb = zeros(Float64, ndofs_total)\n\n\tprintln(\"Assembling...\")\n\ttime_assembly = @elapsed @time begin\n\t\tloop_allocations = assemble!(A, b, FES_time, FES_space, f, μ)\n\n\t\t# fix homogeneous boundary dofs\n\t\tbdofs = boundarydofs(FES_space)\n\t\tfor sdof in bdofs\n\t\t\tfor dof_t = 1 : ndofs_time\n\t\t\t\tdof = (dof_t-1)*ndofs_space + sdof\n\t\t\t\tA[dof, dof] = 1e60\n\t\t\t\tb[dof] = 0\n\t\t\tend\n\t\tend\n\n # fix initial value by zero\n\t\tfor j=1:ndofs_space\n\t\t\tA[j,j] = 1e60\n\t\t\tb[j] = 0\n\t\tend\n\t\tExtendableSparse.flush!(A)\n\tend\n\n @info \".... spy plot of system matrix:\\n$(UnicodePlots.spy(sparse(A.cscmatrix)))\"\n\n\t# solve\n\tprintln(\"Solving linear system...\")\n\ttime_solve = @elapsed @time copyto!(sol, A \\ b)\n\n\t# compute linear residual\n @show norm(A*sol - b)\n\n\treturn sol\nend\n\nfunction assemble!(A::ExtendableSparseMatrix, b::Vector, FES_time, FES_space, f, μ = 1)\n\n\t# get space and time grids\n\tgrid_time = FES_time.xgrid\n\tgrid_space = FES_space.xgrid\n\n\t# get number of degrees of freedom\n ndofs_time = FES_time.ndofs\n ndofs_space = FES_space.ndofs\n\n\t# get local to global maps\n\tEG_time = grid_time[UniqueCellGeometries][1]\n\tEG_space = grid_space[UniqueCellGeometries][1]\n\tL2G_time = L2GTransformer(EG_time, grid_time, ON_CELLS)\n\tL2G_space = L2GTransformer(EG_space, grid_space, ON_CELLS)\n\n\t# get finite element types\n\tFEType_time = eltype(FES_time)\n\tFEType_space = eltype(FES_space)\n\n\t# quadrature formula in space\n\tqf_space = QuadratureRule{Float64, EG_space}(2 * (get_polynomialorder(FEType_space, EG_space) - 1))\n\tweights_space::Vector{Float64} = qf_space.w\n\txref_space::Vector{Vector{Float64}} = qf_space.xref\n\tnweights_space::Int = length(weights_space)\n\tcellvolumes_space = grid_space[CellVolumes]\n\n\t# quadrature formula in time\n\tqf_time = QuadratureRule{Float64, EG_time}(2 * (get_polynomialorder(FEType_time, EG_time) - 1))\n\tweights_time::Vector{Float64} = qf_time.w\n\txref_time::Vector{Vector{Float64}} = qf_time.xref\n\tnweights_time::Int = length(weights_time)\n\tcellvolumes_time = grid_time[CellVolumes]\n\n\t# FE basis evaluators and dofmap for space elements\n\tFEBasis_space_∇ = FEEvaluator(FES_space, Gradient, qf_space)\n\t∇vals_space = FEBasis_space_∇.cvals\n\tFEBasis_space_id = FEEvaluator(FES_space, Identity, qf_space)\n\tidvals_space = FEBasis_space_id.cvals\n\tcelldofs_space = FES_space[ExtendableFEMBase.CellDofs]\n\n\t# FE basis evaluators and dofmap for time elements\n\tFEBasis_time_∇ = FEEvaluator(FES_time, Gradient, qf_time)\n\t∇vals_time = FEBasis_time_∇.cvals\n\tFEBasis_time_id = FEEvaluator(FES_time, Identity, qf_time)\n\tidvals_time = FEBasis_time_id.cvals\n\tcelldofs_time = FES_time[ExtendableFEMBase.CellDofs]\n\n\t# ASSEMBLY LOOP\n\tloop_allocations = 0\n\tfunction barrier(EG_time, EG_space, L2G_time::L2GTransformer, L2G_space::L2GTransformer)\n\t\t# barrier function to avoid allocations by type dispatch\n\n\t\tndofs4cell_time::Int = get_ndofs(ON_CELLS, FEType_time, EG_time)\n\t\tndofs4cell_space::Int = get_ndofs(ON_CELLS, FEType_space, EG_space)\n\t\tAloc = zeros(Float64, ndofs4cell_space, ndofs4cell_space)\n Mloc = zeros(Float64, ndofs4cell_time, ndofs4cell_time)\n\t\tncells_space::Int = num_cells(grid_space)\n ncells_time::Int = num_cells(grid_time)\n\t\tx::Vector{Float64} = zeros(Float64, 2)\n\t\tt::Vector{Float64} = zeros(Float64, 1)\n\n # assemble Laplacian\n\t\tloop_allocations += @allocated for cell ∈ 1:ncells_space\n\t\t\t# update FE basis evaluators for space\n\t\t\tFEBasis_space_∇.citem[] = cell\n\t\t\tupdate_basis!(FEBasis_space_∇)\n\n\t\t\t# assemble local stiffness matrix in space\n\t\t\tfor j ∈ 1:ndofs4cell_space, k ∈ 1:ndofs4cell_space\n\t\t\t\ttemp = 0\n\t\t\t\tfor qp ∈ 1:nweights_space\n\t\t\t\t\ttemp += weights_space[qp] * dot(view(∇vals_space, :, j, qp), view(∇vals_space, :, k, qp))\n\t\t\t\tend\n\t\t\t\tAloc[j, k] = temp\n\t\t\tend\n\t\t\tAloc .*= cellvolumes_space[cell]\n\n\t\t\t# add local matrix to global matrix\n for time_cell ∈ 1:ncells_time\n\t\t\t\tupdate_trafo!(L2G_time, time_cell)\n for jT ∈ 1:ndofs4cell_time, kT ∈ 1:ndofs4cell_time\n dofTj = celldofs_time[jT, time_cell]\n dofTk = celldofs_time[kT, time_cell]\n\t\t\t\t for qpT ∈ 1:nweights_time\n\t\t\t\t\t\t# evaluate time coordinate and μ\n\t\t\t\t\t\teval_trafo!(t, L2G_time, xref_time[qpT])\n factor = μ(t[1]) * weights_time[qpT] * idvals_time[1,jT,qpT] * idvals_time[1,kT,qpT] * cellvolumes_time[time_cell]\n for j ∈ 1:ndofs4cell_space\n dof_j = celldofs_space[j, cell] + (dofTj - 1) * ndofs_space\n for k ∈ 1:ndofs4cell_space\n dof_k = celldofs_space[k, cell] + (dofTk - 1) * ndofs_space\n if abs(Aloc[j, k]) > 1e-15\n # write into sparse matrix, only lines with allocations\n rawupdateindex!(A, +, Aloc[j, k]*factor, dof_j, dof_k)\n end\n end\n end\n end\n end\n end\n\t\t\tfill!(Aloc, 0)\n\n\t\t\t# assemble right-hand side\n\t\t\tupdate_trafo!(L2G_space, cell)\n\t\t\tfor qp ∈ 1:nweights_space\n\t\t\t\t# evaluate coordinates of quadrature point in space\n\t\t\t\teval_trafo!(x, L2G_space, xref_space[qp])\n for time_cell ∈ 1:ncells_time\n\t\t\t\t\tupdate_trafo!(L2G_time, time_cell)\n\t\t\t\t\tfor qpT ∈ 1:nweights_time\n\t\t\t\t\t\t# evaluate time coordinate\n\t\t\t\t\t\teval_trafo!(t, L2G_time, xref_time[qpT])\n\n\t\t\t\t\t\t# evaluate right-hand side in x and t\n\t\t\t\t\t\tfval = f(x, t[1])\n\n\t\t\t\t\t\t# multiply with test function and add to right-hand side\n\t\t\t\t\t\tfor j ∈ 1:ndofs4cell_space\n\t\t\t\t\t\t\ttemp = weights_time[qpT] * weights_space[qp] * idvals_space[1, j, qp] * fval * cellvolumes_space[cell] * cellvolumes_time[time_cell]\n\n\t\t\t\t\t\t\t# write into global vector\n\t\t\t\t\t\t\tfor jT ∈ 1:ndofs4cell_time\n\t\t\t\t\t\t\t\tdof_j = celldofs_space[j, cell] + (celldofs_time[jT, time_cell] - 1) * ndofs_space\n\t\t\t\t\t\t\t\tb[dof_j] += temp * idvals_time[1, jT, qpT]\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n end\n\t\t\tend\n\t\tend\n\n # assemble time derivative\n\t\tloop_allocations += @allocated for time_cell ∈ 1:ncells_time\n\t\t\t# update FE basis evaluators for time derivative\n\t\t\tFEBasis_time_∇.citem[] = time_cell\n\t\t\tupdate_basis!(FEBasis_time_∇)\n\n\t\t\t# assemble local convection term in time\n\t\t\tfor j ∈ 1:ndofs4cell_time, k ∈ 1:ndofs4cell_time\n\t\t\t\ttemp = 0\n\t\t\t\tfor qpT ∈ 1:nweights_time\n\t\t\t\t\ttemp += weights_time[qpT] * dot(view(∇vals_time, :, j, qpT), view(∇vals_time, :, k, qpT))\n\t\t\t\tend\n\t\t\t\tMloc[j, k] = temp\n\t\t\tend\n\t\t\tMloc .*= cellvolumes_time[time_cell]\n\n\t\t\t# add local matrix to global matrix\n for cell ∈ 1:ncells_space\n for jX ∈ 1:ndofs4cell_space, kX ∈ 1:ndofs4cell_space\n dofXj = celldofs_space[jX, cell]\n dofXk = celldofs_space[kX, cell]\n\t\t\t\t for qpX ∈ 1:nweights_space\n factor = weights_space[qpX] * idvals_space[1, jX, qpX] * idvals_space[1, kX, qpX] * cellvolumes_space[cell]\n for j ∈ 1:ndofs4cell_time\n dof_j = dofXj + (celldofs_time[j, time_cell] - 1) * ndofs_space\n for k ∈ 1:ndofs4cell_time\n dof_k = dofXk + (celldofs_time[k, time_cell] - 1) * ndofs_space\n if abs(Mloc[j, k]) > 1e-15\n # write into sparse matrix, only lines with allocations\n rawupdateindex!(A, +, Mloc[j, k]*factor, dof_j, dof_k)\n end\n end\n end\n end\n end\n end\n\t\t\tfill!(Mloc, 0)\n\t\tend\n\tend\n\tbarrier(EG_time, EG_space, L2G_time, L2G_space)\n\tflush!(A)\n\treturn loop_allocations\nend\n\nfunction generateplots(dir = pwd(); Plotter = nothing, kwargs...)\n\t~, plt = main(; Plotter = Plotter, kwargs...)\n\tscene = GridVisualize.reveal(plt)\n\tGridVisualize.save(joinpath(dir, \"example205.png\"), scene; Plotter = Plotter)\nend\n\nend #module","category":"page"},{"location":"module_examples/Example205_LowLevelSpaceTimePoisson/","page":"Example205_LowLevelSpaceTimePoisson","title":"Example205_LowLevelSpaceTimePoisson","text":"","category":"page"},{"location":"module_examples/Example205_LowLevelSpaceTimePoisson/","page":"Example205_LowLevelSpaceTimePoisson","title":"Example205_LowLevelSpaceTimePoisson","text":"This page was generated using Literate.jl.","category":"page"},{"location":"","page":"Home","title":"Home","text":"(Image: Build status) (Image: ) (Image: ) (Image: DOI)","category":"page"},{"location":"#ExtendableFEMBase.jl","page":"Home","title":"ExtendableFEMBase.jl","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"This package provides some low level structures like finite element spaces, interpolors, matrices and vectors to assemble custom finite element solvers based on ExtendableGrids.jl infrastructure.","category":"page"},{"location":"#Dependencies-on-other-Julia-packages","page":"Home","title":"Dependencies on other Julia packages","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"ExtendableGrids.jl\nExtendableSparse.jl\nForwardDiff.jl\nDiffResults.jl\nUnicodePlots.jl\nDocStringExtensions.jl","category":"page"}] +[{"location":"fematrix/#FEMatrix","page":"FEMatrix","title":"FEMatrix","text":"","category":"section"},{"location":"fematrix/","page":"FEMatrix","title":"FEMatrix","text":"A FEMatrix consists of FEMatrixBlocks that share a common ExtendableSparseMatrix. Each block is associated to two FESpaces and can only write into a submatrix of the common sparse matrix specified by offsets.","category":"page"},{"location":"fematrix/","page":"FEMatrix","title":"FEMatrix","text":"Modules = [ExtendableFEMBase]\nPages = [\"fematrix.jl\"]\nOrder = [:type, :function]","category":"page"},{"location":"fematrix/#ExtendableFEMBase.FEMatrix","page":"FEMatrix","title":"ExtendableFEMBase.FEMatrix","text":"struct FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal} <: SparseArrays.AbstractSparseArray{TvM, TiM, 2}\n\nan AbstractMatrix (e.g. an ExtendableSparseMatrix) with an additional layer of several FEMatrixBlock subdivisions each carrying coefficients for their associated pair of FESpaces\n\n\n\n\n\n","category":"type"},{"location":"fematrix/#ExtendableFEMBase.FEMatrix-Tuple{FESpace, FESpace}","page":"FEMatrix","title":"ExtendableFEMBase.FEMatrix","text":"FEMatrix{TvM,TiM}(FESX, FESY; name = \"auto\")\n\nCreates FEMatrix with one rectangular block (FESX,FESY) if FESX and FESY are single FESpaces, or a rectangular block matrix with blocks corresponding to the entries of the FESpace vectors FESX and FESY. Optionally a name for the matrix can be given.\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.FEMatrix-Tuple{FESpace}","page":"FEMatrix","title":"ExtendableFEMBase.FEMatrix","text":"FEMatrix{TvM,TiM}(name::String, FES::FESpace{TvG,TiG,FETypeX,APTX}) where {TvG,TiG,FETypeX,APTX}\n\nCreates FEMatrix with one square block (FES,FES).\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.FEMatrix-Union{Tuple{TiG}, Tuple{TvG}, Tuple{TiM}, Tuple{TvM}, Tuple{Vector{<:FESpace{TvG, TiG}}, Vector{<:FESpace{TvG, TiG}}}} where {TvM, TiM, TvG, TiG}","page":"FEMatrix","title":"ExtendableFEMBase.FEMatrix","text":"FEMatrix{TvM,TiM}(FESX, FESY; name = \"auto\")\n\nCreates an FEMatrix with blocks coressponding to the ndofs of FESX (rows) and FESY (columns).\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.FEMatrixBlock","page":"FEMatrix","title":"ExtendableFEMBase.FEMatrixBlock","text":"struct FEMatrixBlock{TvM, TiM, TvG, TiG, FETypeX, FETypeY, APTX, APTY} <: AbstractArray{TvM, 2}\n\nblock of an FEMatrix that carries coefficients for an associated pair of FESpaces and can be assigned as an two-dimensional AbstractArray (getindex, setindex, size)\n\n\n\n\n\n","category":"type"},{"location":"fematrix/#Base.fill!-Union{Tuple{Ti}, Tuple{Tv}, Tuple{FEMatrixBlock{Tv, Ti}, Any}} where {Tv, Ti}","page":"FEMatrix","title":"Base.fill!","text":"fill!(B::FEMatrixBlock{Tv, Ti}, value)\n\n\nCustom fill function for FEMatrixBlock (only fills the already present nzval in the block, not the complete FEMatrix).\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#Base.length-Union{Tuple{FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}}, Tuple{nbtotal}, Tuple{nbcol}, Tuple{nbrow}, Tuple{TiG}, Tuple{TvG}, Tuple{TiM}, Tuple{TvM}} where {TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}","page":"FEMatrix","title":"Base.length","text":"length(\n _::FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}\n) -> Any\n\n\nCustom length function for FEMatrix that gives the total number of defined FEMatrixBlocks in it\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#Base.show-Union{Tuple{nbtotal}, Tuple{nbcol}, Tuple{nbrow}, Tuple{TiG}, Tuple{TvG}, Tuple{TiM}, Tuple{TvM}, Tuple{IO, FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}}} where {TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}","page":"FEMatrix","title":"Base.show","text":"show(\n io::IO,\n FEM::FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}\n)\n\n\nCustom show function for FEMatrix that prints some information on its blocks.\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#Base.size-Tuple{FEMatrixBlock}","page":"FEMatrix","title":"Base.size","text":"size(FEB::FEMatrixBlock) -> Tuple{Int64, Int64}\n\n\nCustom size function for FEMatrixBlock that gives a tuple with the size of the block (that coressponds to the number of degrees of freedoms in X and Y)\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#Base.size-Union{Tuple{FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}}, Tuple{nbtotal}, Tuple{nbcol}, Tuple{nbrow}, Tuple{TiG}, Tuple{TvG}, Tuple{TiM}, Tuple{TvM}} where {TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}","page":"FEMatrix","title":"Base.size","text":"size(\n _::FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}\n) -> Tuple{Any, Any}\n\n\nCustom size function for FEMatrix that gives a tuple with the number of rows and columns of the FEBlock overlay\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.add!-Union{Tuple{Ti}, Tuple{Tv}, Tuple{FEMatrix{Tv, Ti}, FEMatrix{Tv, Ti}}} where {Tv, Ti}","page":"FEMatrix","title":"ExtendableFEMBase.add!","text":"add!(A::FEMatrix{Tv, Ti}, B::FEMatrix{Tv, Ti}; kwargs...)\n\n\nAdds FEMatrix/ExtendableSparseMatrix/CSCMatrix B to FEMatrix A.\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.addblock!-Union{Tuple{Ti}, Tuple{Tv}, Tuple{FEMatrixBlock{Tv, Ti}, FEMatrixBlock{Tv, Ti}}} where {Tv, Ti}","page":"FEMatrix","title":"ExtendableFEMBase.addblock!","text":"addblock!(\n A::FEMatrixBlock{Tv, Ti},\n B::FEMatrixBlock{Tv, Ti};\n factor,\n transpose\n)\n\n\nAdds FEMatrixBlock B to FEMatrixBlock A.\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.addblock!-Union{Tuple{Ti}, Tuple{Tv}, Tuple{FEMatrixBlock{Tv}, ExtendableSparse.ExtendableSparseMatrixCSC{Tv, Ti}}} where {Tv, Ti<:Integer}","page":"FEMatrix","title":"ExtendableFEMBase.addblock!","text":"addblock!(\n A::FEMatrixBlock{Tv},\n B::ExtendableSparse.ExtendableSparseMatrixCSC{Tv, Ti<:Integer};\n factor,\n transpose\n)\n\n\nAdds ExtendableSparseMatrix B to FEMatrixBlock A.\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.addblock!-Union{Tuple{Ti}, Tuple{Tv}, Tuple{FEMatrixBlock{Tv}, SparseArrays.SparseMatrixCSC{Tv, Ti}}} where {Tv, Ti<:Integer}","page":"FEMatrix","title":"ExtendableFEMBase.addblock!","text":"addblock!(\n A::FEMatrixBlock{Tv},\n cscmat::SparseArrays.SparseMatrixCSC{Tv, Ti<:Integer};\n factor,\n transpose\n)\n\n\nAdds SparseMatrixCSC B to FEMatrixBlock A.\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.addblock_matmul!-Union{Tuple{Ti}, Tuple{Tv}, Tuple{AbstractVector{Tv}, FEMatrixBlock{Tv, Ti}, AbstractVector{Tv}}} where {Tv, Ti}","page":"FEMatrix","title":"ExtendableFEMBase.addblock_matmul!","text":"addblock_matmul!(\n a::AbstractArray{Tv, 1},\n B::FEMatrixBlock{Tv, Ti},\n b::AbstractArray{Tv, 1};\n factor,\n transposed\n)\n\n\nAdds matrix-vector product B times b to FEVectorBlock a.\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.addblock_matmul!-Union{Tuple{Ti}, Tuple{Tv}, Tuple{FEMatrixBlock{Tv}, SparseArrays.SparseMatrixCSC{Tv, Ti}, SparseArrays.SparseMatrixCSC{Tv, Ti}}} where {Tv, Ti}","page":"FEMatrix","title":"ExtendableFEMBase.addblock_matmul!","text":"addblock_matmul!(\n A::FEMatrixBlock{Tv},\n cscmatB::SparseArrays.SparseMatrixCSC{Tv, Ti},\n cscmatC::SparseArrays.SparseMatrixCSC{Tv, Ti};\n factor,\n transposed\n)\n\n\nAdds matrix-matrix product B times C to FEMatrixBlock A.\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.addblock_matmul!-Union{Tuple{Ti}, Tuple{Tv}, Tuple{FEVectorBlock{Tv}, ExtendableSparse.ExtendableSparseMatrixCSC{Tv, Ti}, FEVectorBlock{Tv}}} where {Tv, Ti<:Integer}","page":"FEMatrix","title":"ExtendableFEMBase.addblock_matmul!","text":"addblock_matmul!(\n a::FEVectorBlock{Tv},\n B::ExtendableSparse.ExtendableSparseMatrixCSC{Tv, Ti<:Integer},\n b::FEVectorBlock{Tv};\n factor\n)\n\n\nAdds matrix-vector product B times b to FEVectorBlock a.\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.addblock_matmul!-Union{Tuple{Ti}, Tuple{Tv}, Tuple{FEVectorBlock{Tv}, FEMatrixBlock{Tv, Ti}, FEVectorBlock{Tv}}} where {Tv, Ti}","page":"FEMatrix","title":"ExtendableFEMBase.addblock_matmul!","text":"addblock_matmul!(\n a::FEVectorBlock{Tv},\n B::FEMatrixBlock{Tv, Ti},\n b::FEVectorBlock{Tv};\n factor,\n transposed\n)\n\n\nAdds matrix-vector product B times b (or B' times b if transposed = true) to FEVectorBlock a.\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.ldrdmatmul-Union{Tuple{Ti}, Tuple{Tv}, Tuple{AbstractVector{Tv}, AbstractVector{Tv}, ExtendableSparse.ExtendableSparseMatrixCSC{Tv, Ti}, AbstractVector{Tv}, AbstractVector{Tv}}} where {Tv, Ti<:Integer}","page":"FEMatrix","title":"ExtendableFEMBase.ldrdmatmul","text":"ldrdmatmul(\n a1::AbstractArray{Tv, 1},\n a2::AbstractArray{Tv, 1},\n B::ExtendableSparse.ExtendableSparseMatrixCSC{Tv, Ti<:Integer},\n b1::AbstractArray{Tv, 1},\n b2::AbstractArray{Tv, 1};\n factor\n) -> Any\n\n\nComputes vector'-matrix-vector product (a1-a2)'B(b1-b2).\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.lrmatmul-Union{Tuple{Ti}, Tuple{Tv}, Tuple{AbstractVector{Tv}, ExtendableSparse.ExtendableSparseMatrixCSC{Tv, Ti}, AbstractVector{Tv}}} where {Tv, Ti<:Integer}","page":"FEMatrix","title":"ExtendableFEMBase.lrmatmul","text":"lrmatmul(\n a::AbstractArray{Tv, 1},\n B::ExtendableSparse.ExtendableSparseMatrixCSC{Tv, Ti<:Integer},\n b::AbstractArray{Tv, 1};\n factor\n) -> Any\n\n\nComputes vector'-matrix-vector product a'Bb.\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.nbcols-Union{Tuple{FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}}, Tuple{nbtotal}, Tuple{nbcol}, Tuple{nbrow}, Tuple{TiG}, Tuple{TvG}, Tuple{TiM}, Tuple{TvM}} where {TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}","page":"FEMatrix","title":"ExtendableFEMBase.nbcols","text":"nbcols(\n _::FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}\n) -> Any\n\n\nGives the number of FEMatrixBlocks in each row.\n\n\n\n\n\n","category":"method"},{"location":"fematrix/#ExtendableFEMBase.nbrows-Union{Tuple{FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}}, Tuple{nbtotal}, Tuple{nbcol}, Tuple{nbrow}, Tuple{TiG}, Tuple{TvG}, Tuple{TiM}, Tuple{TvM}} where {TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}","page":"FEMatrix","title":"ExtendableFEMBase.nbrows","text":"nbrows(\n _::FEMatrix{TvM, TiM, TvG, TiG, nbrow, nbcol, nbtotal}\n) -> Any\n\n\nGives the number of FEMatrixBlocks in each column.\n\n\n\n\n\n","category":"method"},{"location":"module_examples/Example281_DiscontinuousPlot/#281-:-Discontinuous-Plot","page":"Example281_DiscontinuousPlot","title":"281 : Discontinuous Plot","text":"","category":"section"},{"location":"module_examples/Example281_DiscontinuousPlot/","page":"Example281_DiscontinuousPlot","title":"Example281_DiscontinuousPlot","text":"(source code)","category":"page"},{"location":"module_examples/Example281_DiscontinuousPlot/","page":"Example281_DiscontinuousPlot","title":"Example281_DiscontinuousPlot","text":"This example demonstrates how to plot a discontinuous function on a grid with two regions by region-wise nodal values and plotting.","category":"page"},{"location":"module_examples/Example281_DiscontinuousPlot/","page":"Example281_DiscontinuousPlot","title":"Example281_DiscontinuousPlot","text":"The computed solution for the default parameters looks like this:","category":"page"},{"location":"module_examples/Example281_DiscontinuousPlot/","page":"Example281_DiscontinuousPlot","title":"Example281_DiscontinuousPlot","text":"(Image: )","category":"page"},{"location":"module_examples/Example281_DiscontinuousPlot/","page":"Example281_DiscontinuousPlot","title":"Example281_DiscontinuousPlot","text":"module Example281_DiscontinuousPlot\n\nusing ExtendableFEMBase\nusing ExtendableGrids\nusing GridVisualize\n\n# function to interpolate\nfunction u!(result, qpinfo)\n\tx = qpinfo.x\n if qpinfo.region == 1\n result[1] = 2*x[1]*x[2]\n elseif qpinfo.region == 2\n result[1] = -1*x[2]*x[1] + 0.5\n else\n @error \"function was evaluated without region information\"\n end\nend\n\n# everything is wrapped in a main function\nfunction main(; broken = false, nrefs = 3, abs = false, Plotter = nothing)\n\n\t# generate two grids\n\txgrid = grid_unitsquare(Triangle2D)\n\n # mark first two triangles to be in second region\n xgrid[CellRegions][1:2] .= 2\n\n # refine\n\txgrid = uniform_refine(xgrid, nrefs)\n\n\t# generate coressponding finite element spaces and FEVectors\n\tFES = FESpace{L2P1{1}}(xgrid; broken = broken)\n\tFEFunction = FEVector(FES)\n\n\t# interpolate function onto first grid\n\tinterpolate!(FEFunction[1], u!; bonus_quadorder = 2)\n\n # get subgrid for each region\n subgrid1 = subgrid(xgrid, [1])\n subgrid2 = subgrid(xgrid, [2])\n\n # get parent nodes for each subgrid\n subnodes1 = subgrid1[NodeParents]\n subnodes2 = subgrid2[NodeParents]\n\n # compute nodevalues for nodes of each subgrid\n nodevals4nodes1 = nodevalues(FEFunction[1], Identity; abs = abs, regions = [1], nodes = subnodes1)\n nodevals4nodes2 = nodevalues(FEFunction[1], Identity; abs = abs, regions = [2], nodes = subnodes2)\n\n\t# plot\n\tp = GridVisualizer(; Plotter = Plotter, layout = (2, 2), clear = true, resolution = (1000, 500))\n gridplot!(p[1,1], xgrid)\n\tscalarplot!(p[1, 2], [subgrid1, subgrid2], xgrid, [view(nodevals4nodes1,:), view(nodevals4nodes2,:)], cellwise = false, levels = 11, title = \"u\")\n\n return p\nend\n\nfunction generateplots(dir = pwd(); Plotter = nothing, kwargs...)\n\tplt = main(; Plotter = Plotter, kwargs...)\n\tscene = GridVisualize.reveal(plt)\n\tGridVisualize.save(joinpath(dir, \"example281.png\"), scene; Plotter = Plotter)\nend\nend","category":"page"},{"location":"module_examples/Example281_DiscontinuousPlot/","page":"Example281_DiscontinuousPlot","title":"Example281_DiscontinuousPlot","text":"","category":"page"},{"location":"module_examples/Example281_DiscontinuousPlot/","page":"Example281_DiscontinuousPlot","title":"Example281_DiscontinuousPlot","text":"This page was generated using Literate.jl.","category":"page"},{"location":"interpolations/#Finite-Element-Interpolations","page":"Finite Element Interpolations","title":"Finite Element Interpolations","text":"","category":"section"},{"location":"interpolations/#Source-functions-and-QPInfo","page":"Finite Element Interpolations","title":"Source functions and QPInfo","text":"","category":"section"},{"location":"interpolations/","page":"Finite Element Interpolations","title":"Finite Element Interpolations","text":"The functions that can be interpolated with the methods below are expected to have a certain interface, i.e.:","category":"page"},{"location":"interpolations/","page":"Finite Element Interpolations","title":"Finite Element Interpolations","text":"function f!(result, qpinfo) end","category":"page"},{"location":"interpolations/","page":"Finite Element Interpolations","title":"Finite Element Interpolations","text":"The qpinfo argument communicates vast information of the current quadrature point:","category":"page"},{"location":"interpolations/","page":"Finite Element Interpolations","title":"Finite Element Interpolations","text":"qpinfo child Type Description\nqpinfo.x Vector{Real} space coordinates of quadrature point\nqpinfo.time Real current time\nqpinfo.item Integer current item that contains qpinfo.x\nqpinfo.region Integer region number of item\nqpinfo.xref Vector{Real} reference coordinates within item of qpinfo.x\nqpinfo.volume Real volume of item\nqpinfo.params Vector{Any} parameters that can be transfered via keyword arguments","category":"page"},{"location":"interpolations/#Standard-Interpolations","page":"Finite Element Interpolations","title":"Standard Interpolations","text":"","category":"section"},{"location":"interpolations/","page":"Finite Element Interpolations","title":"Finite Element Interpolations","text":"Each finite element has its standard interpolator that can be applied to some user-defined DataFunction. Instead of interpolating on the full cells, the interpolation can be restricted to faces or edges. ","category":"page"},{"location":"interpolations/","page":"Finite Element Interpolations","title":"Finite Element Interpolations","text":"It is also possible to interpolate finite element functions on one grid onto a finite element function on another grid (experimental feature, does not work for all finite elements yet and shall be extended to interpolations of operator evaluations as well in future).","category":"page"},{"location":"interpolations/","page":"Finite Element Interpolations","title":"Finite Element Interpolations","text":"interpolate!","category":"page"},{"location":"interpolations/#ExtendableGrids.interpolate!","page":"Finite Element Interpolations","title":"ExtendableGrids.interpolate!","text":"function ExtendableGrids.interpolate!(target::FEVectorBlock,\n\t AT::Type{<:AssemblyType},\n\t source!::Function;\n\t items = [],\n\t bonus_quadorder = 0,\n\t time = 0,\n\t kwargs...)\n\nInterpolates the given source into the finite elements space assigned to the target FEVectorBlock with the specified AssemblyType (usualy ON_CELLS). \n\nThe source functions should adhere to the interface\n\n\tsource!(result, qpinfo)\n\nThe qpinfo argument communicates vast information of the current quadrature/evaluation point.\n\nThe bonus_quadorder argument can be used to steer the quadrature order of integrals that needs to be computed for the interpolation (the default quadrature order corressponds to the polynomial order of the finite element).\n\n\n\n\n\nfunction ExtendableGrids.interpolate!(target::FEVectorBlock,\n\t source::Function;\n\t items = [],\n\t bonus_quadorder = 0,\n\t time = 0,\n\t kwargs...)\n\nInterpolates the given source function into the finite element space assigned to the target FEVectorBlock. \n\nThe source functions should adhere to the interface\n\n\tsource!(result, qpinfo)\n\nThe qpinfo argument communicates vast information of the current quadrature/evaluation point.\n\nThe bonus_quadorder argument can be used to steer the quadrature order of integrals that needs to be computed for the interpolation (the default quadrature order corressponds to the polynomial order of the finite element).\n\n\n\n\n\n","category":"function"},{"location":"interpolations/#Nodal-Evaluations","page":"Finite Element Interpolations","title":"Nodal Evaluations","text":"","category":"section"},{"location":"interpolations/","page":"Finite Element Interpolations","title":"Finite Element Interpolations","text":"Usually, Plotters need nodal values, so there is a gengeric function that evaluates any finite element function at the nodes of the grids (possibly by averaging if discontinuous). In case of Identity evaluations of an H1-conforming finite element, the function nodevalues_view can generate a view into the coefficient field that avoids further allocations.","category":"page"},{"location":"interpolations/","page":"Finite Element Interpolations","title":"Finite Element Interpolations","text":"nodevalues!\nnodevalues\nnodevalues_view","category":"page"},{"location":"interpolations/#ExtendableFEMBase.nodevalues!","page":"Finite Element Interpolations","title":"ExtendableFEMBase.nodevalues!","text":"function nodevalues!(\n\ttarget::AbstractArray{<:Real,2},\n\tsource::AbstractArray{T,1},\n\tFE::FESpace{Tv,Ti,FEType,AT},\n\toperator::Type{<:AbstractFunctionOperator} = Identity;\n\tregions::Array{Int,1} = [0],\n\tabs::Bool = false,\n\tfactor = 1,\n\ttarget_offset::Int = 0, # start to write into target after offset\n\tzero_target::Bool = true, # target vector is zeroed\n\tcontinuous::Bool = false)\n\nEvaluates the finite element function with the coefficient vector source (interpreted as a coefficient vector for the FESpace FE) and the specified FunctionOperator at all the nodes of the (specified regions of the) grid and writes the values into target. Discontinuous (continuous = false) quantities are evaluated in all neighbouring cells of each node and then averaged. Continuous (continuous = true) quantities are only evaluated once at each node.\n\n\n\n\n\nfunction nodevalues!(\n\ttarget::AbstractArray{<:Real,2},\n\tsource::FEVectorBlock,\n\toperator::Type{<:AbstractFunctionOperator} = Identity;\n\tregions::Array{Int,1} = [0],\n\tabs::Bool = false,\n\tfactor = 1,\n\tcellwise = false,\t\t # return cellwise nodevalues ncells x nnodes_on_cell\n\ttarget_offset::Int = 0, # start to write into target after offset\n\tzero_target::Bool = true, # target vector is zeroed\n\tcontinuous::Bool = false)\n\nEvaluates the finite element function with the coefficient vector source and the specified FunctionOperator at all the nodes of the (specified regions of the) grid and writes the values into target. Discontinuous (continuous = false) quantities are evaluated in all neighbouring cells of each node and then averaged. Continuous (continuous = true) quantities are only evaluated once at each node.\n\n\n\n\n\n","category":"function"},{"location":"interpolations/#ExtendableFEMBase.nodevalues","page":"Finite Element Interpolations","title":"ExtendableFEMBase.nodevalues","text":"function nodevalues(\n\tsource::FEVectorBlock,\n\toperator::Type{<:AbstractFunctionOperator} = Identity;\n\tregions::Array{Int,1} = [0],\n\tabs::Bool = false,\n\tfactor = 1,\n\tnodes = [],\t\t\t\t \n\tcellwise = false,\t\t # return cellwise nodevalues ncells x nnodes_on_cell (only if nodes == [])\n\ttarget_offset::Int = 0, # start to write into target after offset\n\tzero_target::Bool = true, # target vector is zeroed\n\tcontinuous::Bool = false)\n\nEvaluates the finite element function with the coefficient vector source and the specified FunctionOperator at the specified list of nodes of the grid (default = all nodes) and writes the values in that order into target. Nodes that are not part of the specified regions (default = all regions) are set to zero. Discontinuous (continuous = false) quantities are evaluated in all neighbouring cells of each node and then averaged. Continuous (continuous = true) quantities are only evaluated once at each node.\n\n\n\n\n\n","category":"function"},{"location":"interpolations/#ExtendableFEMBase.nodevalues_view","page":"Finite Element Interpolations","title":"ExtendableFEMBase.nodevalues_view","text":"function nodevalues_view(\n\tsource::FEVectorBlock,\n\toperator::Type{<:AbstractFunctionOperator} = Identity)\n\nReturns a vector of views of the nodal values of the source block (currently works for unbroken H1-conforming elements) that directly accesses the coefficients.\n\n\n\n\n\n","category":"function"},{"location":"interpolations/#Lazy-Interpolation","page":"Finite Element Interpolations","title":"Lazy Interpolation","text":"","category":"section"},{"location":"interpolations/","page":"Finite Element Interpolations","title":"Finite Element Interpolations","text":"To interpolate between different finite element spaces and meshes, there is a lazy interpolation routine that works in all cases (but is not very efficient as it involves a PointeEvaluator and CellFinder):","category":"page"},{"location":"interpolations/","page":"Finite Element Interpolations","title":"Finite Element Interpolations","text":"lazy_interpolate!","category":"page"},{"location":"interpolations/#ExtendableFEMBase.lazy_interpolate!","page":"Finite Element Interpolations","title":"ExtendableFEMBase.lazy_interpolate!","text":"function lazy_interpolate!(\n\ttarget::FEVectorBlock{T1,Tv,Ti},\n\tsource::FEVectorBlock{T2,Tv,Ti};\n\toperator = Identity,\n\tpostprocess = nothing,\n\txtrafo = nothing,\n\titems = [],\n\tnot_in_domain_value = 1e30,\n\teps = 1e-13,\n\tuse_cellparents::Bool = false) where {T1,T2,Tv,Ti}\n\nInterpolates (operator-evaluations of) the given finite element function into the finite element space assigned to the target FEVectorBlock. (Currently not the most efficient way as it is based on the PointEvaluation pattern and cell search. If CellParents are available in the grid components of the target grid, these parent cell information can be used to improve the search. To activate this put 'use_cellparents' = true). By some given kernel function that is conforming to the interface\n\nkernel!(result, input, qpinfo)\n\nthe operator evaluation (=input) can be further postprocessed. The qpinfo argument allows to access information at the current quadrature point.\n\nNote: discontinuous quantities at vertices of the target grid will be evaluted in the first found cell of the source grid. No averaging is performed. With eps the tolerances of the cell search via ExtendableGrids.CellFinder can be steered.\n\n\n\n\n\n","category":"function"},{"location":"package_index/","page":"Index","title":"Index","text":"Modules = [ExtendableFEMBase]\nOrder = [:function, :type]","category":"page"},{"location":"fevector/#FEVector","page":"FEVector","title":"FEVector","text":"","category":"section"},{"location":"fevector/","page":"FEVector","title":"FEVector","text":"A FEVector consists of FEVectorBlocks that share a common one-dimensional array. Each block is associated to a FESpace and can only write into a region of the common array specified by offsets that stores the degrees of freedom of that FEspace.","category":"page"},{"location":"fevector/","page":"FEVector","title":"FEVector","text":"Modules = [ExtendableFEMBase]\nPages = [\"fevector.jl\"]\nOrder = [:type, :function]","category":"page"},{"location":"fevector/#ExtendableFEMBase.FEVector","page":"FEVector","title":"ExtendableFEMBase.FEVector","text":"struct FEVector{T, Tv, Ti}\n\na plain array but with an additional layer of several FEVectorBlock subdivisions each carrying coefficients for their associated FESpace. The j-th block can be accessed by getindex(::FEVector, j) or by getindex(::FEVector, tag) if tags are associated. The full vector can be accessed via FEVector.entries \n\n\n\n\n\n","category":"type"},{"location":"fevector/#ExtendableFEMBase.FEVector-Union{Tuple{FESpace{Tv, Ti, FEType, APT}}, Tuple{APT}, Tuple{FEType}, Tuple{Ti}, Tuple{Tv}} where {Tv, Ti, FEType, APT}","page":"FEVector","title":"ExtendableFEMBase.FEVector","text":"FEVector{T}(FES; name = nothing, tags = nothing, kwargs...) where T <: Real\n\nCreates FEVector that has one block if FES is a single FESpace, and a blockwise FEVector if FES is a vector of FESpaces. Optionally a name for the vector (as a String) or each of the blocks (as a vector of Strings), or tags (as an Array{Any}) for the blocks can be specified.\n\n\n\n\n\n","category":"method"},{"location":"fevector/#ExtendableFEMBase.FEVectorBlock","page":"FEVector","title":"ExtendableFEMBase.FEVectorBlock","text":"struct FEVectorBlock{T, Tv, Ti, FEType, APT} <: AbstractArray{T, 1}\n\nblock of an FEVector that carries coefficients for an associated FESpace and can be assigned as an AbstractArray (getindex, setindex, size, length)\n\n\n\n\n\n","category":"type"},{"location":"fevector/#Base.append!-Union{Tuple{APT}, Tuple{FEType}, Tuple{Ti}, Tuple{Tv}, Tuple{T}, Tuple{FEVector{T}, FESpace{Tv, Ti, FEType, APT}}} where {T, Tv, Ti, FEType, APT}","page":"FEVector","title":"Base.append!","text":"append!(\n FEF::FEVector{T},\n FES::FESpace{Tv, Ti, FEType, APT};\n name,\n tag\n) -> Int64\n\n\nOverloaded append function for FEVector that adds a FEVectorBlock at the end.\n\n\n\n\n\n","category":"method"},{"location":"fevector/#Base.fill!-Tuple{FEVectorBlock, Any}","page":"FEVector","title":"Base.fill!","text":"fill!(b::FEVectorBlock, value)\n\n\nOverloaded fill function for FEVectorBlock (only fills the block, not the complete FEVector).\n\n\n\n\n\n","category":"method"},{"location":"fevector/#Base.length-Tuple{FEVectorBlock}","page":"FEVector","title":"Base.length","text":"length(FEB::FEVectorBlock) -> Int64\n\n\nCustom length function for FEVectorBlock that gives the coressponding number of degrees of freedoms of the associated FESpace\n\n\n\n\n\n","category":"method"},{"location":"fevector/#Base.length-Tuple{FEVector}","page":"FEVector","title":"Base.length","text":"length(FEF::FEVector) -> Int64\n\n\nCustom length function for FEVector that gives the number of defined FEMatrixBlocks in it\n\n\n\n\n\n","category":"method"},{"location":"fevector/#Base.show-Tuple{IO, FEVector}","page":"FEVector","title":"Base.show","text":"show(io::IO, FEF::FEVector)\n\n\nCustom show function for FEVector that prints some information on its blocks.\n\n\n\n\n\n","category":"method"},{"location":"fevector/#Base.view-Tuple{FEVectorBlock}","page":"FEVector","title":"Base.view","text":"returns a view of the part of the full FEVector that coressponds to the block. \n\n\n\n\n\n","category":"method"},{"location":"fevector/#ExtendableFEMBase.FESpaces-Union{Tuple{FEVector{T, Tv, Ti}}, Tuple{Ti}, Tuple{Tv}, Tuple{T}} where {T, Tv, Ti}","page":"FEVector","title":"ExtendableFEMBase.FESpaces","text":"FESpaces(\n FEV::FEVector{T, Tv, Ti}\n) -> Vector{T} where T<:FESpace\n\n\nReturns the vector of FEspaces for the blocks of the given FEVector.\n\n\n\n\n\n","category":"method"},{"location":"fevector/#ExtendableFEMBase.addblock!-Tuple{FEVectorBlock, AbstractVector}","page":"FEVector","title":"ExtendableFEMBase.addblock!","text":"addblock!(\n a::FEVectorBlock,\n b::AbstractVector;\n factor,\n offset\n)\n\n\nAdds Array b to FEVectorBlock a.\n\n\n\n\n\n","category":"method"},{"location":"fevector/#ExtendableFEMBase.addblock!-Tuple{FEVectorBlock, FEVectorBlock}","page":"FEVector","title":"ExtendableFEMBase.addblock!","text":"addblock!(a::FEVectorBlock, b::FEVectorBlock; factor)\n\n\nAdds FEVectorBlock b to FEVectorBlock a.\n\n\n\n\n\n","category":"method"},{"location":"fevector/#LinearAlgebra.dot-Union{Tuple{T}, Tuple{FEVectorBlock{T}, FEVectorBlock{T}}} where T","page":"FEVector","title":"LinearAlgebra.dot","text":"dot(a::FEVectorBlock{T}, b::FEVectorBlock{T}) -> Any\n\n\nScalar product between two FEVEctorBlocks\n\n\n\n\n\n","category":"method"},{"location":"pointevaluators/#PointEvaluator","page":"PointEvaluator","title":"PointEvaluator","text":"","category":"section"},{"location":"pointevaluators/","page":"PointEvaluator","title":"PointEvaluator","text":"Point evaluators allow to evaluate a finite element function (FEVector) at arbitrary points.","category":"page"},{"location":"pointevaluators/","page":"PointEvaluator","title":"PointEvaluator","text":"Modules = [ExtendableFEMBase]\nPages = [\"point_evaluator.jl\"]\nOrder = [:type, :function]","category":"page"},{"location":"pointevaluators/#ExtendableFEMBase.PointEvaluator","page":"PointEvaluator","title":"ExtendableFEMBase.PointEvaluator","text":"function Pointevaluator(\n\t[kernel!::Function],\n\toa_args::Array{<:Tuple{<:Any, DataType},1};\n\tkwargs...)\n\nGenerates a PointEvaluator that can evaluate the specified operator evaluations at arbitrary points. If no kernel function is given, the arguments are given directly. If a kernel is provided, the arguments are postprocessed accordingly and the kernel has to be conform to the interface\n\nkernel!(result, eval_args, qpinfo)\n\nwhere qpinfo allows to access information at the current evaluation point. Additionally the length of the result needs to be specified via the kwargs.\n\nEvaluation can be triggered via the evaluate function after an initialize! call.\n\nOperator evaluations are tuples that pair a tag (to identify an unknown or the position in the vector) with a FunctionOperator.\n\nKeyword arguments:\n\nresultdim: dimension of result field (default = length of operators). Default: 0\nparams: array of parameters that should be made available in qpinfo argument of kernel function. Default: nothing\nname: name for operator used in printouts. Default: ''PointEvaluator''\nverbosity: verbosity level. Default: 0\n\n\n\n\n\n","category":"type"},{"location":"pointevaluators/#ExtendableFEMBase.eval_func-Tuple{PointEvaluator}","page":"PointEvaluator","title":"ExtendableFEMBase.eval_func","text":"function eval_func(PE::PointEvaluator)\n\nYields the function (result, x) -> evaluate!(result,PE,x).\n\n\n\n\n\n","category":"method"},{"location":"pointevaluators/#ExtendableFEMBase.eval_func_bary-Tuple{PointEvaluator}","page":"PointEvaluator","title":"ExtendableFEMBase.eval_func_bary","text":"function eval_func_bary(PE::PointEvaluator)\n\nYields the function (result, xref, item) -> evaluate_bary!(result,PE,xref,item).\n\n\n\n\n\n","category":"method"},{"location":"pointevaluators/#ExtendableFEMBase.evaluate!-Tuple{Any, PointEvaluator, Any}","page":"PointEvaluator","title":"ExtendableFEMBase.evaluate!","text":"function evaluate!(\n\tresult,\n\tPE::PointEvaluator,\n\tx\n\t)\n\nEvaluates the PointEvaluator at the specified coordinates x. (To do so it internally calls CellFinder to find the cell and the barycentric coordinates of x and calls evaluate_bary!.)\n\n\n\n\n\n","category":"method"},{"location":"pointevaluators/#ExtendableFEMBase.evaluate_bary!-Tuple{Any, PointEvaluator, Any, Any}","page":"PointEvaluator","title":"ExtendableFEMBase.evaluate_bary!","text":"function evaluate_bary!(\n\tresult,\n\tPE::PointEvaluator,\n\txref, \n\titem\n\t)\n\nEvaluates the PointEvaluator at the specified reference coordinates in the cell with the specified item number.\n\n\n\n\n\n","category":"method"},{"location":"pointevaluators/#ExtendableFEMBase.initialize!-Union{Tuple{UT}, Tuple{T}, Tuple{PointEvaluator{T, UT}, Any}} where {T, UT}","page":"PointEvaluator","title":"ExtendableFEMBase.initialize!","text":"function initialize!(\n\tO::PointEvaluator,\n\tsol;\n\ttime = 0,\n\tkwargs...)\n\nInitializes the PointEvaluator for the specified solution.\n\n\n\n\n\n","category":"method"},{"location":"module_examples/Example210_LowLevelNavierStokes/#210-:-Navier-Stokes-Problem","page":"Example210_LowLevelNavierStokes","title":"210 : Navier-Stokes Problem","text":"","category":"section"},{"location":"module_examples/Example210_LowLevelNavierStokes/","page":"Example210_LowLevelNavierStokes","title":"Example210_LowLevelNavierStokes","text":"(source code)","category":"page"},{"location":"module_examples/Example210_LowLevelNavierStokes/","page":"Example210_LowLevelNavierStokes","title":"Example210_LowLevelNavierStokes","text":"Consider the Navier-Stokes problem that seeks u and p such that","category":"page"},{"location":"module_examples/Example210_LowLevelNavierStokes/","page":"Example210_LowLevelNavierStokes","title":"Example210_LowLevelNavierStokes","text":"beginaligned\n\t- mu Delta u + (u cdot nabla) u + nabla p = f\n\t\t\tmathrmdiv(u) = 0\nendaligned","category":"page"},{"location":"module_examples/Example210_LowLevelNavierStokes/","page":"Example210_LowLevelNavierStokes","title":"Example210_LowLevelNavierStokes","text":"The weak formulation seeks u in V = H^1_0(Omega) and p in Q = L^2_0(Omega) such that","category":"page"},{"location":"module_examples/Example210_LowLevelNavierStokes/","page":"Example210_LowLevelNavierStokes","title":"Example210_LowLevelNavierStokes","text":"beginaligned\n\tmu (nabla u nabla v) + ((u cdot nabla) u v) - (p mathrmdiv(v)) = (f v)\n\t textfor all v in V\n\t(q mathrmdiv(u)) = 0\n\t textfor all q in Q\nendaligned","category":"page"},{"location":"module_examples/Example210_LowLevelNavierStokes/","page":"Example210_LowLevelNavierStokes","title":"Example210_LowLevelNavierStokes","text":"This example computes a planar lattice flow with inhomogeneous Dirichlet boundary conditions (which requires some modification above). Newton's method with automatic differentation is used to handle the nonlinear convection term.","category":"page"},{"location":"module_examples/Example210_LowLevelNavierStokes/","page":"Example210_LowLevelNavierStokes","title":"Example210_LowLevelNavierStokes","text":"The computed solution for the default parameters looks like this:","category":"page"},{"location":"module_examples/Example210_LowLevelNavierStokes/","page":"Example210_LowLevelNavierStokes","title":"Example210_LowLevelNavierStokes","text":"(Image: )","category":"page"},{"location":"module_examples/Example210_LowLevelNavierStokes/","page":"Example210_LowLevelNavierStokes","title":"Example210_LowLevelNavierStokes","text":"module Example210_LowLevelNavierStokes\n\nusing ExtendableFEMBase\nusing ExtendableGrids\nusing ExtendableSparse\nusing GridVisualize\nusing ForwardDiff\nusing DiffResults\n\n# data for Poisson problem\nconst μ = 1e-2\nfunction f!(fval, x, t) # right-hand side\n\tfval[1] = 8.0 * π * π * μ * exp(-8.0 * π * π * μ * t) * sin(2.0 * π * x[1]) * sin(2.0 * π * x[2])\n\tfval[2] = 8.0 * π * π * μ * exp(-8.0 * π * π * μ * t) * cos(2.0 * π * x[1]) * cos(2.0 * π * x[2])\n\treturn nothing\nend\n\n# exact velocity (for boundary data and error calculation)\nfunction u!(uval, qpinfo)\n\tx = qpinfo.x\n\tt = qpinfo.time\n\tuval[1] = exp(-8.0 * π * π * μ * t) * sin(2.0 * π * x[1]) * sin(2.0 * π * x[2])\n\tuval[2] = exp(-8.0 * π * π * μ * t) * cos(2.0 * π * x[1]) * cos(2.0 * π * x[2])\n\treturn nothing\nend\n\n# exact pressure (for error calculation)\nfunction p!(pval, qpinfo)\n\tx = qpinfo.x\n\tt = qpinfo.time\n\tpval[1] = exp(-16 * pi * pi * μ * t) * (cos(4 * pi * x[1]) - cos(4 * pi * x[2])) / 4\n\treturn nothing\nend\n\nfunction main(; nref = 5, teval = 0, order = 2, Plotter = nothing)\n\n\t@assert order >= 2\n\n\t# create grid\n\tX = LinRange(0, 1, 2^nref + 1)\n\tY = LinRange(0, 1, 2^nref + 1)\n\tprintln(\"Creating grid...\")\n\t@time xgrid = simplexgrid(X, Y)\n\n\t# create FESpace\n\tprintln(\"Creating FESpace...\")\n\tFETypes = [H1Pk{2, 2, order}, H1Pk{1, 2, order - 1}]\n\t@time FES = [FESpace{FETypes[1]}(xgrid; name = \"velocity space\"),\n\t\tFESpace{FETypes[2]}(xgrid; name = \"pressure space\")]\n\tFES\n\n\t# solve\n\tsol = solve_stokes_lowlevel(FES; teval = teval)\n\n\t# move integral mean of pressure\n\tpmean = sum(compute_error(sol[2], nothing, order, 1))\n\tfor j ∈ 1:sol[2].FES.ndofs\n\t\tsol[2][j] -= pmean\n\tend\n\n\t# calculate l2 error\n\terror_u = sqrt(sum(compute_error(sol[1], u!, 2)))\n\terror_p = sqrt(sum(compute_error(sol[2], p!, 2)))\n\tprintln(\"\\nl2 error velo = $(error_u)\")\n\tprintln(\"l2 error pressure = $(error_p)\")\n\n\t# plot\n\tplt = GridVisualizer(; Plotter = Plotter, layout = (1, 1), clear = true, resolution = (500, 500))\n\tscalarplot!(plt[1, 1], xgrid, nodevalues(sol[1]; abs = true)[1, :]; title = \"|u| + quiver\", Plotter = Plotter)\n\tvectorplot!(plt[1, 1], xgrid, eval_func_bary(PointEvaluator([(1, Identity)], sol)), clear = false)\n\n\treturn sol, plt\nend\n\n# computes error and integrals\nfunction compute_error(uh::FEVectorBlock, u, order = get_polynomialorder(get_FEType(uh), uh.FES.xgrid[CellGeometries][1]), p = 2)\n\txgrid = uh.FES.xgrid\n\tFES = uh.FES\n\tEG = xgrid[UniqueCellGeometries][1]\n\tncomponents = get_ncomponents(uh)\n\tcellvolumes = xgrid[CellVolumes]\n\tcelldofs = FES[CellDofs]\n\terror = zeros(Float64, ncomponents, num_cells(xgrid))\n\tuhval = zeros(Float64, ncomponents)\n\tuval = zeros(Float64, ncomponents)\n\tL2G = L2GTransformer(EG, xgrid, ON_CELLS)\n\tQP = QPInfos(xgrid)\n\tqf = VertexRule(EG, order)\n\tFEB = FEEvaluator(FES, Identity, qf)\n\n\tfunction barrier(L2G::L2GTransformer)\n\t\tfor cell in 1:num_cells(xgrid)\n\t\t\tupdate_trafo!(L2G, cell)\n\t\t\tupdate_basis!(FEB, cell)\n\t\t\tfor (qp, weight) in enumerate(qf.w)\n\t\t\t\t# evaluate uh\n\t\t\t\tfill!(uhval, 0)\n\t\t\t\teval_febe!(uhval, FEB, view(view(uh), view(celldofs, :, cell)), qp)\n\n\t\t\t\t# evaluate u\n\t\t\t\tif u !== nothing\n\t\t\t\t\tfill!(uval, 0)\n\t\t\t\t\teval_trafo!(QP.x, L2G, qf.xref[qp])\n\t\t\t\t\tu(uval, QP)\n\t\t\t\tend\n\n\t\t\t\t# evaluate error\n\t\t\t\tfor d ∈ 1:ncomponents\n\t\t\t\t\terror[d, cell] += (uhval[d] - uval[d]) .^ p * cellvolumes[cell] * weight\n\t\t\t\tend\n\t\t\tend\n\t\tend\n\tend\n\n\tbarrier(L2G)\n\treturn error\nend\n\nfunction solve_stokes_lowlevel(FES; teval = 0)\n\n\tprintln(\"Initializing system...\")\n\tsol = FEVector(FES)\n\tA = FEMatrix(FES)\n\tb = FEVector(FES)\n\t@time update_system! = prepare_assembly!(A, b, FES[1], FES[2], sol)\n\t@time update_system!(true, false)\n\tAlin = deepcopy(A) ## = keep linear part of system matrix\n\tblin = deepcopy(b) ## = keep linear part of right-hand side\n\n\tprintln(\"Prepare boundary conditions...\")\n\t@time begin\n\t\tu_init = FEVector(FES)\n\t\tinterpolate!(u_init[1], u!; time = teval)\n\t\tfixed_dofs = boundarydofs(FES[1])\n\t\tpush!(fixed_dofs, FES[1].ndofs + 1) ## fix one pressure dof\n\tend\n\n\tfor it ∈ 1:20\n\t\t# solve\n\t\tprintln(\"\\nITERATION $it\\n=============\")\n\t\tprintln(\"Solving linear system...\")\n\t\t@time copyto!(sol.entries, A.entries \\ b.entries)\n\t\tres = A.entries.cscmatrix * sol.entries .- b.entries\n\t\tfor dof in fixed_dofs\n\t\t\tres[dof] = 0\n\t\tend\n\t\tlinres = norm(res)\n\t\tprintln(\"linear residual = $linres\")\n\n\t\tfill!(A.entries.cscmatrix.nzval, 0)\n\t\tfill!(b.entries, 0)\n\t\tprintln(\"Updating linear system...\")\n\t\t@time begin\n\t\t\tupdate_system!(false, true)\n\t\t\tA.entries.cscmatrix += Alin.entries.cscmatrix\n\t\t\tb.entries .+= blin.entries\n\t\tend\n\n\t\t# fix boundary dofs\n\t\tfor dof in fixed_dofs\n\t\t\tA.entries[dof, dof] = 1e60\n\t\t\tb.entries[dof] = 1e60 * u_init.entries[dof]\n\t\tend\n\t\tExtendableSparse.flush!(A.entries)\n\n\t\t# calculate nonlinear residual\n\t\tres = A.entries.cscmatrix * sol.entries .- b.entries\n\t\tfor dof in fixed_dofs\n\t\t\tres[dof] = 0\n\t\tend\n\t\tnlres = norm(res)\n\t\tprintln(\"nonlinear residual = $nlres\")\n\t\tif nlres < max(1e-12, 20 * linres)\n\t\t\tbreak\n\t\tend\n\tend\n\n\treturn sol\nend\n\nfunction prepare_assembly!(A, b, FESu, FESp, sol; teval = 0)\n\n\tA = A.entries\n\tb = b.entries\n\tsol = sol.entries\n\txgrid = FESu.xgrid\n\tEG = xgrid[UniqueCellGeometries][1]\n\tFEType_u = eltype(FESu)\n\tFEType_p = eltype(FESp)\n\tL2G = L2GTransformer(EG, xgrid, ON_CELLS)\n\tcellvolumes = xgrid[CellVolumes]\n\tncells::Int = num_cells(xgrid)\n\n\t# dofmap\n\tCellDofs_u = FESu[ExtendableFEMBase.CellDofs]\n\tCellDofs_p = FESp[ExtendableFEMBase.CellDofs]\n\toffset_p = FESu.ndofs\n\n\t# quadrature formula\n\tqf = QuadratureRule{Float64, EG}(3 * get_polynomialorder(FEType_u, EG) - 1)\n\tweights::Vector{Float64} = qf.w\n\txref::Vector{Vector{Float64}} = qf.xref\n\tnweights::Int = length(weights)\n\n\t# FE basis evaluator\n\tFEBasis_∇u = FEEvaluator(FESu, Gradient, qf)\n\t∇uvals = FEBasis_∇u.cvals\n\tFEBasis_idu = FEEvaluator(FESu, Identity, qf)\n\tiduvals = FEBasis_idu.cvals\n\tFEBasis_idp = FEEvaluator(FESp, Identity, qf)\n\tidpvals = FEBasis_idp.cvals\n\n\t# prepare automatic differentation of convection operator\n\tfunction operator!(result, input)\n\t\t# result = (u ⋅ ∇)u\n\t\tresult[1] = input[1] * input[3] + input[2] * input[4]\n\t\tresult[2] = input[1] * input[5] + input[2] * input[6]\n\tend\n\tresult = Vector{Float64}(undef, 2)\n\tinput = Vector{Float64}(undef, 6)\n\ttempV = zeros(Float64, 2)\n\tDresult = DiffResults.JacobianResult(result, input)\n\tcfg = ForwardDiff.JacobianConfig(operator!, result, input, ForwardDiff.Chunk{6}())\n\tjac = DiffResults.jacobian(Dresult)\n\tvalue = DiffResults.value(Dresult)\n\n\t# ASSEMBLY LOOP\n\tfunction barrier(EG, L2G::L2GTransformer, linear::Bool, nonlinear::Bool)\n\t\t# barrier function to avoid allocations caused by L2G\n\n\t\tndofs4cell_u::Int = get_ndofs(ON_CELLS, FEType_u, EG)\n\t\tndofs4cell_p::Int = get_ndofs(ON_CELLS, FEType_p, EG)\n\t\tAloc = zeros(Float64, ndofs4cell_u, ndofs4cell_u)\n\t\tBloc = zeros(Float64, ndofs4cell_u, ndofs4cell_p)\n\t\tdof_j::Int, dof_k::Int = 0, 0\n\t\tfval::Vector{Float64} = zeros(Float64, 2)\n\t\tx::Vector{Float64} = zeros(Float64, 2)\n\n\t\tfor cell ∈ 1:ncells\n\t\t\t# update FE basis evaluators\n\t\t\tupdate_basis!(FEBasis_∇u, cell)\n\t\t\tupdate_basis!(FEBasis_idu, cell)\n\t\t\tupdate_basis!(FEBasis_idp, cell)\n\n\t\t\t# assemble local stiffness matrix (symmetric)\n\t\t\tif (linear)\n\t\t\t\tfor j ∈ 1:ndofs4cell_u, k ∈ 1:ndofs4cell_u\n\t\t\t\t\ttemp = 0\n\t\t\t\t\tfor qp ∈ 1:nweights\n\t\t\t\t\t\ttemp += weights[qp] * dot(view(∇uvals, :, j, qp), view(∇uvals, :, k, qp))\n\t\t\t\t\tend\n\t\t\t\t\tAloc[k, j] = μ * temp\n\t\t\t\tend\n\n\t\t\t\t# assemble div-pressure coupling\n\t\t\t\tfor j ∈ 1:ndofs4cell_u, k ∈ 1:ndofs4cell_p\n\t\t\t\t\ttemp = 0\n\t\t\t\t\tfor qp ∈ 1:nweights\n\t\t\t\t\t\ttemp -= weights[qp] * (∇uvals[1, j, qp] + ∇uvals[4, j, qp]) *\n\t\t\t\t\t\t\t\tidpvals[1, k, qp]\n\t\t\t\t\tend\n\t\t\t\t\tBloc[j, k] = temp\n\t\t\t\tend\n\t\t\t\tBloc .*= cellvolumes[cell]\n\n\t\t\t\t# assemble right-hand side\n\t\t\t\tupdate_trafo!(L2G, cell)\n\t\t\t\tfor j ∈ 1:ndofs4cell_u\n\t\t\t\t\t# right-hand side\n\t\t\t\t\ttemp = 0\n\t\t\t\t\tfor qp ∈ 1:nweights\n\t\t\t\t\t\t# get global x for quadrature point\n\t\t\t\t\t\teval_trafo!(x, L2G, xref[qp])\n\t\t\t\t\t\t# evaluate (f(x), v_j(x))\n\t\t\t\t\t\tf!(fval, x, teval)\n\t\t\t\t\t\ttemp += weights[qp] * dot(view(iduvals, :, j, qp), fval)\n\t\t\t\t\tend\n\t\t\t\t\t# write into global vector\n\t\t\t\t\tdof_j = CellDofs_u[j, cell]\n\t\t\t\t\tb[dof_j] += temp * cellvolumes[cell]\n\t\t\t\tend\n\t\t\tend\n\n\t\t\t# assemble nonlinear term\n\t\t\tif (nonlinear)\n\t\t\t\tfor qp ∈ 1:nweights\n\t\t\t\t\tfill!(input, 0)\n\t\t\t\t\tfor j ∈ 1:ndofs4cell_u\n\t\t\t\t\t\tdof_j = CellDofs_u[j, cell]\n\t\t\t\t\t\tfor d ∈ 1:2\n\t\t\t\t\t\t\tinput[d] += sol[dof_j] * iduvals[d, j, qp]\n\t\t\t\t\t\tend\n\t\t\t\t\t\tfor d ∈ 1:4\n\t\t\t\t\t\t\tinput[2+d] += sol[dof_j] * ∇uvals[d, j, qp]\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\n\t\t\t\t\t# evaluate jacobian\n\t\t\t\t\tForwardDiff.chunk_mode_jacobian!(Dresult, operator!, result, input, cfg)\n\n\t\t\t\t\t# update matrix\n\t\t\t\t\tfor j ∈ 1:ndofs4cell_u\n\t\t\t\t\t\t# multiply ansatz function with local jacobian\n\t\t\t\t\t\tfill!(tempV, 0)\n\t\t\t\t\t\tfor d ∈ 1:2\n\t\t\t\t\t\t\ttempV[1] += jac[1, d] * iduvals[d, j, qp]\n\t\t\t\t\t\t\ttempV[2] += jac[2, d] * iduvals[d, j, qp]\n\t\t\t\t\t\tend\n\t\t\t\t\t\tfor d ∈ 1:4\n\t\t\t\t\t\t\ttempV[1] += jac[1, 2+d] * ∇uvals[d, j, qp]\n\t\t\t\t\t\t\ttempV[2] += jac[2, 2+d] * ∇uvals[d, j, qp]\n\t\t\t\t\t\tend\n\n\t\t\t\t\t\t# multiply test function operator evaluation\n\t\t\t\t\t\tfor k ∈ 1:ndofs4cell_u\n\t\t\t\t\t\t\tAloc[k, j] += dot(tempV, view(iduvals, :, k, qp)) * weights[qp]\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\n\t\t\t\t\t# update rhs\n\t\t\t\t\tmul!(tempV, jac, input)\n\t\t\t\t\ttempV .-= value\n\t\t\t\t\tfor j ∈ 1:ndofs4cell_u\n\t\t\t\t\t\tdof_j = CellDofs_u[j, cell]\n\t\t\t\t\t\tb[dof_j] += dot(tempV, view(iduvals, :, j, qp)) * weights[qp] * cellvolumes[cell]\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\tend\n\n\t\t\t# add local matrices to global matrix\n\t\t\tAloc .*= cellvolumes[cell]\n\t\t\tfor j ∈ 1:ndofs4cell_u\n\t\t\t\tdof_j = CellDofs_u[j, cell]\n\t\t\t\tfor k ∈ 1:ndofs4cell_u\n\t\t\t\t\tdof_k = CellDofs_u[k, cell]\n\t\t\t\t\trawupdateindex!(A, +, Aloc[j, k], dof_j, dof_k)\n\t\t\t\tend\n\t\t\t\tif (linear)\n\t\t\t\t\tfor k ∈ 1:ndofs4cell_p\n\t\t\t\t\t\tdof_k = CellDofs_p[k, cell] + offset_p\n\t\t\t\t\t\trawupdateindex!(A, +, Bloc[j, k], dof_j, dof_k)\n\t\t\t\t\t\trawupdateindex!(A, +, Bloc[j, k], dof_k, dof_j)\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\tend\n\t\t\tfill!(Aloc, 0)\n\t\t\tfill!(Bloc, 0)\n\t\tend\n\tend\n\n\tfunction update_system!(linear::Bool, nonlinear::Bool)\n\t\tbarrier(EG, L2G, linear, nonlinear)\n\t\tflush!(A)\n\tend\n\tupdate_system!\nend\n\nfunction generateplots(dir = pwd(); Plotter = nothing, kwargs...)\n\t~, plt = main(; Plotter = Plotter, kwargs...)\n\tscene = GridVisualize.reveal(plt)\n\tGridVisualize.save(joinpath(dir, \"example210.png\"), scene; Plotter = Plotter)\nend\nend #module","category":"page"},{"location":"module_examples/Example210_LowLevelNavierStokes/","page":"Example210_LowLevelNavierStokes","title":"Example210_LowLevelNavierStokes","text":"","category":"page"},{"location":"module_examples/Example210_LowLevelNavierStokes/","page":"Example210_LowLevelNavierStokes","title":"Example210_LowLevelNavierStokes","text":"This page was generated using Literate.jl.","category":"page"},{"location":"segmentintegrators/#SegmentIntegrator","page":"SegmentIntegrator","title":"SegmentIntegrator","text":"","category":"section"},{"location":"segmentintegrators/","page":"SegmentIntegrator","title":"SegmentIntegrator","text":"Segment integrators allow to integrate a finite element function (FEVector) along arbitrary lines through mesh cells.","category":"page"},{"location":"segmentintegrators/","page":"SegmentIntegrator","title":"SegmentIntegrator","text":"Modules = [ExtendableFEMBase]\nPages = [\"segment_integrator.jl\"]\nOrder = [:type, :function]","category":"page"},{"location":"segmentintegrators/#ExtendableFEMBase.SegmentIntegrator-Tuple{Any, Any, Vector{<:Tuple{Any, DataType}}}","page":"SegmentIntegrator","title":"ExtendableFEMBase.SegmentIntegrator","text":"function SegmentIntegrator(\n\tEG::ElementGeometry,\n\t[kernel!::Function],\n\toa_args::Array{<:Tuple{<:Any, DataType},1};\n\tkwargs...)\n\nGenerates an SegmentIntegrator that can intgrate over segments of the specified geometry EG. To do so, it evaluates, at each quadrature point, the specified operator evaluations, postprocesses them with the kernel function (if provided) and accumulates the results with the quadrature weights. If no kernel is given, the arguments are integrated directly. If a kernel is provided it has be conform to the interface\n\nkernel!(result, eval_args, qpinfo)\n\nwhere qpinfo allows to access information at the current quadrature point. Additionally the length of the result needs to be specified via the kwargs.\n\nEvaluation can be triggered via the integrate_segment! function after an initialize!\n\nOperator evaluations are tuples that pair a tag (to identify an unknown or the position in the vector) with a FunctionOperator.\n\nKeyword arguments:\n\nfactor: factor that should be multiplied during assembly. Default: 1\nresultdim: dimension of result field (default = length of arguments). Default: 0\nmatrix_mode: integrator integrates basis functions of FEspace seperately to assembly a matrix that maps solution to segment integrations (requires that kernel is linear). Default: false\nname: name for operator used in printouts. Default: ''SegmentIntegrator''\nparams: array of parameters that should be made available in qpinfo argument of kernel function. Default: nothing\nquadorder: quadrature order. Default: ''auto''\nbonus_quadorder: additional quadrature order added to quadorder. Default: 0\nentrytolerance: threshold to add entry to sparse matrix (only in matrixmode). Default: 0\nverbosity: verbosity level. Default: 0\n\n\n\n\n\n","category":"method"},{"location":"segmentintegrators/#ExtendableFEMBase.initialize!-Union{Tuple{UT}, Tuple{T}, Tuple{SegmentIntegrator{T, UT}, Any}} where {T, UT}","page":"SegmentIntegrator","title":"ExtendableFEMBase.initialize!","text":"function initialize!(\n\tO::SegmentIntegrator{T, UT},\n\tsol;\n\ttime = 0,\n\tkwargs...)\n\nInitializes the SegmentIntegrator for the specified solution.\n\n\n\n\n\n","category":"method"},{"location":"segmentintegrators/#ExtendableFEMBase.integrate_segment!-Union{Tuple{T}, Tuple{Vector{T}, SegmentIntegrator, Array{Vector{T}, 1}, Array{Vector{T}, 1}, Any}} where T","page":"SegmentIntegrator","title":"ExtendableFEMBase.integrate_segment!","text":"function integrate_segment!(\n\tresult::Array{T,1},\n\tSI::SegmentIntegrator,\n\tw::Array{Array{T,1},1},\n\tb::Array{Array{T,1},1},\n\titem\n\t) where {T}\n\nIntegrate a segment with world coordinates w and barycentric coordinates b in the cell with the given item number.\n\n\n\n\n\n","category":"method"},{"location":"plots/#Plots","page":"Plots","title":"Plots","text":"","category":"section"},{"location":"plots/#GridVisualize/PlutoVista","page":"Plots","title":"GridVisualize/PlutoVista","text":"","category":"section"},{"location":"plots/","page":"Plots","title":"Plots","text":"Plotting is possible e.g. via Nodal Evaluations and the plot routines from ExtendableGrids.jl. In Pluto notebooks it is recommended to use PlutoVista.jl as an backend.","category":"page"},{"location":"plots/#UnicodePlots","page":"Plots","title":"UnicodePlots","text":"","category":"section"},{"location":"plots/","page":"Plots","title":"Plots","text":"For a fast and rough peak several UnicodePlots plotters are available:","category":"page"},{"location":"plots/","page":"Plots","title":"Plots","text":"Modules = [ExtendableFEMBase]\nPages = [\"plots.jl\"]\nOrder = [:type, :function]","category":"page"},{"location":"plots/#ExtendableFEMBase.unicode_gridplot-Tuple{ExtendableGrids.ExtendableGrid}","page":"Plots","title":"ExtendableFEMBase.unicode_gridplot","text":"function unicode_gridplot(\n\txgrid::ExtendableGrid;\n\ttitle = \"gridplot\",\n\tresolution = (40,20),\n\tcolor = (200,200,200),\n\tbface_color = (255,0,0),\n\tCanvasType = BrailleCanvas,\n\tplot_based = ON_CELLS, # or ON_FACES/ON_EDGES\n\tkwargs...\n\nPlots the grid on a UnicodePlots canvas (default: BrailleCanvas) by drawing all edges in the triangulation.\n\n\n\n\n\n","category":"method"},{"location":"plots/#ExtendableFEMBase.unicode_scalarplot-Tuple{FEVectorBlock}","page":"Plots","title":"ExtendableFEMBase.unicode_scalarplot","text":"function unicode_scalarplot(\n\tu::FEVectorBlock; \n\tcomponents = 1:get_ncomponents(u),\n\tabs = false,\n\tresolution = (30,30),\n\tcolormap = :viridis,\n\ttitle = u.name,\n\tkwargs...)\n\nPlots components of the finite element function in the FEVectorBlock u by using a lazy_interpolate! onto a coarse uniform mesh and UnicodePlots.jl lineplot or heatmap for 1D or 2D, respectively.\n\nIn 1D all components all plotted in the same lineplot, while in 2D all components are plotted in a separate heatmap.\n\nIf abs = true, only the absolute value over the components is plotted.\n\n\n\n\n\n","category":"method"},{"location":"functionoperators/#Function-Operators","page":"Function Operators","title":"Function Operators","text":"","category":"section"},{"location":"functionoperators/#StandardFunctionOperators","page":"Function Operators","title":"StandardFunctionOperators","text":"","category":"section"},{"location":"functionoperators/","page":"Function Operators","title":"Function Operators","text":"StandardFunctionOperators are abstract types that encode primitive (linear) operators (like Identity, Gradient etc.) used to dispatch different evaluations of finite element basis functions.","category":"page"},{"location":"functionoperators/#List-of-primitive-operators","page":"Function Operators","title":"List of primitive operators","text":"","category":"section"},{"location":"functionoperators/","page":"Function Operators","title":"Function Operators","text":"StandardFunctionOperator Description Mathematically\nIdentity identity v rightarrow v\nIdentityComponent{c} identity of c-th component v rightarrow v_c\nNormalFlux normal flux (function times normal) v rightarrow v cdot vecn (only ON_FACES)\nTangentFlux tangent flux (function times tangent) v rightarrow v cdot vect (only ON_EDGES)\nGradient gradient/Jacobian (as a vector) v rightarrow nabla v\nSymmetricGradient symmetric part of the gradient v rightarrow Voigt(mathrmsym(nabla v))\nDivergence divergence v rightarrow mathrmdiv(v) = nabla cdot v\nCurlScalar curl operator 1D to 2D (rotated gradient) v rightarrow -dvdx_2dvdx_1\nCurl2D curl operator 2D to 1D v rightarrow dv_1dx_2 - dv_2dx_1\nCurl3D curl operator 3D to 3D v rightarrow nabla times v\nHessian Hesse matrix = all 2nd order derivatives (as a vector) v rightarrow D^2 v (e.g. in 2D: xx,xy,yx,yy for each component)\nSymmetricHessian{a} symmetric part of Hesse matrix, offdiagonals scaled by a v rightarrow sym(D^2 v) (e.g. in 2D: xx,yy,a*xy for each component)\nLaplacian Laplace Operator (diagonal of Hessian) v rightarrow Delta v (e.g. in 2D: xx,yy for each component)","category":"page"},{"location":"functionoperators/","page":"Function Operators","title":"Function Operators","text":"note: Note\nAs each finite element type is transformed differently from the reference domain to the general domain, the evaluation of each function operator has to be implemented for each finite element class. Currently, not every function operator works in any dimension and for any finite element. More evaluations are added as soon as they are needed (and possibly upon request). Also, the function operators can be combined with user-defined actions to evaluate other operators that can be build from the ones available (e.g. the deviator).","category":"page"},{"location":"functionoperators/#ReconstructionOperators","page":"Function Operators","title":"ReconstructionOperators","text":"","category":"section"},{"location":"functionoperators/","page":"Function Operators","title":"Function Operators","text":"There are special operators that allow to evaluate a primitive operator of some discrete reconstructed version of a testfunction. ","category":"page"},{"location":"functionoperators/","page":"Function Operators","title":"Function Operators","text":"Modules = [ExtendableFEMBase]\nPages = [\"reconstructionoperators.jl\"]\nOrder = [:type, :function]","category":"page"},{"location":"functionoperators/#ExtendableFEMBase.Reconstruct","page":"Function Operators","title":"ExtendableFEMBase.Reconstruct","text":"abstract type Reconstruct{FETypeR, O} <: ExtendableFEMBase.ReconstructionOperator\n\nreconstruction operator: evaluates a reconstructed version of the finite element function.\n\nFETypeR specifies the reconstruction space (needs to be defined for the finite element that it is applied to). O specifies the StandardFunctionOperator that shall be evaluated.\n\n\n\n\n\n","category":"type"},{"location":"functionoperators/#Divergence-free-reconstruction-operators","page":"Function Operators","title":"Divergence-free reconstruction operators","text":"","category":"section"},{"location":"functionoperators/","page":"Function Operators","title":"Function Operators","text":"For gradient-robust discretisations of certain classical non divergence-conforming ansatz spaces, reconstruction operators are available that map a discretely divergence-free H1 function to a pointwise divergence-free Hdiv function. So far such operators are available for the vector-valued Crouzeix-Raviart (H1CR) and Bernardi–Raugel (H1BR) finite element types, as well as for the P2-bubble (H1P2B) finite element type in two dimensions.","category":"page"},{"location":"functionoperators/","page":"Function Operators","title":"Function Operators","text":"Example: Reconst{HDIVRT0{d}, Identity} gives the reconstruction of the Identity operator into HDIVRT0 (and is available for H1BR{d} and H1CR{d} for d = 1,2)","category":"page"},{"location":"functionoperators/#Operator-Pairs-(experimental)","page":"Function Operators","title":"Operator Pairs (experimental)","text":"","category":"section"},{"location":"functionoperators/","page":"Function Operators","title":"Function Operators","text":"Two function operators can be put into an OperatorPair so that one can provide effectively two operators in each argument of an assembly pattern. However, the user should make sure that both operators can be evaluated together reasonably (meaning both should be well-defined on the element geometries and the finite element space where the argument will be evaluated, and the action of the operator has to operate with coressponding input and result fields). This feature is still experimental and might have issues in some cases. OperatorTriple for a combination of three operators is also available.","category":"page"},{"location":"functionoperators/","page":"Function Operators","title":"Function Operators","text":"OperatorPair\nOperatorTriple","category":"page"},{"location":"functionoperators/#ExtendableFEMBase.OperatorPair","page":"Function Operators","title":"ExtendableFEMBase.OperatorPair","text":"abstract type OperatorPair{<:StandardFunctionOperator,<:StandardFunctionOperator} <: StandardFunctionOperator\n\nallows to evaluate two operators in place of one, e.g. OperatorPair{Identity,Gradient}.\n\n\n\n\n\n","category":"type"},{"location":"functionoperators/#ExtendableFEMBase.OperatorTriple","page":"Function Operators","title":"ExtendableFEMBase.OperatorTriple","text":"abstract type OperatorTriple{<:StandardFunctionOperator,<:StandardFunctionOperator} <: StandardFunctionOperator\n\nallows to evaluate three operators in place of one, e.g. OperatorTriple{Identity,Gradient,Hessian}.\n\n\n\n\n\n","category":"type"},{"location":"quadrature/#Quadrature","page":"Quadrature","title":"Quadrature","text":"","category":"section"},{"location":"quadrature/","page":"Quadrature","title":"Quadrature","text":"Usually quadrature is a hidden layer as quadrature rules are chosen automatically based on the polynomial degree of the ansatz functions and the specified quadorder of the user data.","category":"page"},{"location":"quadrature/","page":"Quadrature","title":"Quadrature","text":"Hence, quadrature rules are only needed if the user wants write his own low-level assembly.","category":"page"},{"location":"quadrature/","page":"Quadrature","title":"Quadrature","text":"Quadrature rules consist of points (coordinates of evaluation points with respect to reference geometry) and weights. There are constructors for several AbstractElementGeometries (from ExtendableGrids) and different order (some have generic formulas for arbitrary order), see below for a detailed list.","category":"page"},{"location":"quadrature/","page":"Quadrature","title":"Quadrature","text":"Modules = [ExtendableFEMBase]\nPages = [\"quadrature.jl\"]\nOrder = [:type, :function]","category":"page"},{"location":"quadrature/#ExtendableFEMBase.QuadratureRule","page":"Quadrature","title":"ExtendableFEMBase.QuadratureRule","text":"abstract type QuadratureRule{T<:Real, ET<:ExtendableGrids.AbstractElementGeometry}\n\nA struct that contains the name of the quadrature rule, the reference points and the weights for the parameter-determined element geometry.\n\n\n\n\n\n","category":"type"},{"location":"quadrature/#ExtendableFEMBase.QuadratureRule-Union{Tuple{Int64}, Tuple{ET}, Tuple{T}} where {T<:Real, ET<:ExtendableGrids.AbstractElementGeometry0D}","page":"Quadrature","title":"ExtendableFEMBase.QuadratureRule","text":"function QuadratureRule{T,ET}(order::Int) where {T<:Real, ET <: AbstractElementGeometry0D}\n\nConstructs 0D quadrature rule of specified order (always point evaluation).\n\n\n\n\n\n","category":"method"},{"location":"quadrature/#ExtendableFEMBase.QuadratureRule-Union{Tuple{Int64}, Tuple{ET}, Tuple{T}} where {T<:Real, ET<:ExtendableGrids.AbstractElementGeometry1D}","page":"Quadrature","title":"ExtendableFEMBase.QuadratureRule","text":"function QuadratureRule{T,ET}(order::Int) where {T<:Real, ET <: AbstractElementGeometry1D}\n\nConstructs 1D quadrature rule of specified order.\n\n\n\n\n\n","category":"method"},{"location":"quadrature/#ExtendableFEMBase.QuadratureRule-Union{Tuple{Int64}, Tuple{ET}, Tuple{T}} where {T<:Real, ET<:ExtendableGrids.Parallelepiped3D}","page":"Quadrature","title":"ExtendableFEMBase.QuadratureRule","text":"function QuadratureRule{T,ET}(order::Int) where {T<:Real, ET <: Parallelepiped3D}\n\nConstructs quadrature rule on Parallelepiped3D of specified order.\n\n\n\n\n\n","category":"method"},{"location":"quadrature/#ExtendableFEMBase.QuadratureRule-Union{Tuple{Int64}, Tuple{ET}, Tuple{T}} where {T<:Real, ET<:ExtendableGrids.Parallelogram2D}","page":"Quadrature","title":"ExtendableFEMBase.QuadratureRule","text":"function QuadratureRule{T,ET}(order::Int) where {T<:Real, ET <: Parallelogram2D}\n\nConstructs quadrature rule on Parallelogram2D of specified order.\n\n\n\n\n\n","category":"method"},{"location":"quadrature/#ExtendableFEMBase.QuadratureRule-Union{Tuple{Int64}, Tuple{ET}, Tuple{T}} where {T<:Real, ET<:ExtendableGrids.Tetrahedron3D}","page":"Quadrature","title":"ExtendableFEMBase.QuadratureRule","text":"function QuadratureRule{T,ET}(order::Int) where {T<:Real, ET <: Tetrahedron3D}\n\nConstructs quadrature rule on Tetrahedron3D of specified order.\n\n\n\n\n\n","category":"method"},{"location":"quadrature/#ExtendableFEMBase.QuadratureRule-Union{Tuple{Int64}, Tuple{ET}, Tuple{T}} where {T<:Real, ET<:ExtendableGrids.Triangle2D}","page":"Quadrature","title":"ExtendableFEMBase.QuadratureRule","text":"function QuadratureRule{T,ET}(order::Int) where {T<:Real, ET <: Triangle2D}\n\nConstructs quadrature rule on Triangle2D of specified order.\n\n\n\n\n\n","category":"method"},{"location":"quadrature/#Base.eltype-Union{Tuple{QuadratureRule{T, ET}}, Tuple{ET}, Tuple{T}} where {T<:Real, ET<:ExtendableGrids.AbstractElementGeometry}","page":"Quadrature","title":"Base.eltype","text":"eltype(\n _::QuadratureRule{T<:Real, ET<:ExtendableGrids.AbstractElementGeometry}\n) -> Any\n\n\nCustom eltype function for QuadratureRule{T,ET}.\n\n\n\n\n\n","category":"method"},{"location":"quadrature/#Base.show-Tuple{IO, QuadratureRule}","page":"Quadrature","title":"Base.show","text":"show(io::IO, Q::QuadratureRule)\n\n\nCustom show function for QuadratureRule{T,ET} that prints some information.\n\n\n\n\n\n","category":"method"},{"location":"quadrature/#ExtendableFEMBase.integrate!-Union{Tuple{Ti}, Tuple{Tv}, Tuple{T}, Tuple{AbstractArray{T}, ExtendableGrids.ExtendableGrid{Tv, Ti}, Type{<:ExtendableGrids.AssemblyType}, Any}} where {T, Tv, Ti}","page":"Quadrature","title":"ExtendableFEMBase.integrate!","text":"integrate!(\n integral4items::AbstractArray{T},\n grid::ExtendableGrids.ExtendableGrid{Tv, Ti},\n AT::Type{<:ExtendableGrids.AssemblyType},\n integrand;\n offset,\n bonus_quadorder,\n quadorder,\n time,\n items,\n force_quadrature_rule,\n kwargs...\n)\n\n\nIntegration that writes result on every item into integral4items.\n\n\n\n\n\n","category":"method"},{"location":"quadrature/#ExtendableFEMBase.integrate-Tuple{ExtendableGrids.ExtendableGrid, Type{<:ExtendableGrids.AssemblyType}, Any, Int64}","page":"Quadrature","title":"ExtendableFEMBase.integrate","text":"integrate(\n grid::ExtendableGrids.ExtendableGrid,\n AT::Type{<:ExtendableGrids.AssemblyType},\n integrand!,\n resultdim::Int64;\n T,\n kwargs...\n) -> Union{Float64, Vector{Float64}}\n\n\nIntegration that returns total integral.\n\n\n\n\n\n","category":"method"},{"location":"quadrature/#ExtendableFEMBase.ref_integrate!-Tuple{AbstractArray, Type{<:ExtendableGrids.AbstractElementGeometry}, Int64, Function}","page":"Quadrature","title":"ExtendableFEMBase.ref_integrate!","text":"ref_integrate!(\n integral::AbstractArray,\n EG::Type{<:ExtendableGrids.AbstractElementGeometry},\n order::Int64,\n integrand::Function\n)\n\n\nIntegration for reference basis functions on reference domains (merely for testing stuff).\n\nNote: area of reference geometry is not multiplied\n\n\n\n\n\n","category":"method"},{"location":"fespace/#FESpace","page":"FESpace","title":"FESpace","text":"","category":"section"},{"location":"fespace/","page":"FESpace","title":"FESpace","text":"To generate a finite element space only a finite element type and a grid is needed, dofmaps are generated automatically on their first demand.","category":"page"},{"location":"fespace/","page":"FESpace","title":"FESpace","text":"Modules = [ExtendableFEMBase]\nPages = [\"finiteelements.jl\"]\nOrder = [:type, :function]","category":"page"},{"location":"fespace/#ExtendableFEMBase.FESpace","page":"FESpace","title":"ExtendableFEMBase.FESpace","text":"struct FESpace{Tv, Ti, FEType<:AbstractFiniteElement,AT<:AssemblyType}\n\tname::String # full name of finite element space (used in messages)\n\tbroken::Bool # if true, broken dofmaps are generated\n\tndofs::Int # total number of dofs\n\tcoffset::Int # offset for component dofs\n\txgrid::ExtendableGrid[Tv,Ti} # link to xgrid \n\tdofgrid::ExtendableGrid{Tv,Ti}\t # link to (sub) grid used for dof numbering (expected to be equal to or child grid of xgrid)\n\tdofmaps::Dict{Type{<:AbstractGridComponent},Any} # backpack with dofmaps\nend\n\nA struct that has a finite element type as parameter and carries dofmaps (CellDofs, FaceDofs, BFaceDofs) plus additional grid information and access to arrays holding coefficients if needed.\n\n\n\n\n\n","category":"type"},{"location":"fespace/#ExtendableFEMBase.FESpace-Union{Tuple{ExtendableGrids.ExtendableGrid{Tv, Ti}}, Tuple{AT}, Tuple{FEType}, Tuple{Ti}, Tuple{Tv}} where {Tv, Ti, FEType<:AbstractFiniteElement, AT<:ExtendableGrids.AssemblyType}","page":"FESpace","title":"ExtendableFEMBase.FESpace","text":"function FESpace{FEType<:AbstractFiniteElement,AT<:AssemblyType}(\n\txgrid::ExtendableGrid{Tv,Ti};\n\tname = \"\",\n\tbroken::Bool = false)\n\nConstructor for FESpace of the given FEType, AT = ONCELLS/ONFACES/ONEDGES generates a finite elements space on the cells/faces/edges of the provided xgrid (if omitted ONCELLS is used as default). The broken switch allows to generate a broken finite element space (that is piecewise H1/Hdiv/HCurl). If no name is provided it is generated automatically from FEType. If no AT is provided, the space is generated ON_CELLS.\n\n\n\n\n\n","category":"method"},{"location":"fespace/#Base.eltype-Union{Tuple{FESpace{Tv, Ti, FEType, APT}}, Tuple{APT}, Tuple{FEType}, Tuple{Ti}, Tuple{Tv}} where {Tv, Ti, FEType<:AbstractFiniteElement, APT}","page":"FESpace","title":"Base.eltype","text":"eltype(\n _::FESpace{Tv, Ti, FEType<:AbstractFiniteElement, APT}\n) -> Type{FEType} where FEType<:AbstractFiniteElement\n\n\nCustom eltype function for FESpace returns the finite element type parameter of the finite element space.\n\n\n\n\n\n","category":"method"},{"location":"fespace/#Base.get!-Tuple{FESpace, Type{<:DofMap}}","page":"FESpace","title":"Base.get!","text":"get!(FES::FESpace, DM::Type{<:DofMap}) -> Any\n\n\nTo be called by getindex. This triggers lazy creation of non-existing dofmaps\n\n\n\n\n\n","category":"method"},{"location":"fespace/#Base.getindex-Tuple{FESpace, Type{<:DofMap}}","page":"FESpace","title":"Base.getindex","text":"Base.getindex(FES::FESpace,DM::Type{<:DofMap})\n\nGeneric method for obtaining dofmap. This method is mutating in the sense that non-existing dofmaps are created on demand. Due to the fact that components are stored as Any the return value triggers type instability.\n\n\n\n\n\n","category":"method"},{"location":"fespace/#Base.setindex!-Tuple{FESpace, Any, Type{<:DofMap}}","page":"FESpace","title":"Base.setindex!","text":"setindex!(FES::FESpace, v, DM::Type{<:DofMap}) -> Any\n\n\nSet new dofmap\n\n\n\n\n\n","category":"method"},{"location":"fespace/#Base.show-Union{Tuple{APT}, Tuple{FEType}, Tuple{Ti}, Tuple{Tv}, Tuple{IO, FESpace{Tv, Ti, FEType, APT}}} where {Tv, Ti, FEType<:AbstractFiniteElement, APT}","page":"FESpace","title":"Base.show","text":"show(\n io::IO,\n FES::FESpace{Tv, Ti, FEType<:AbstractFiniteElement, APT}\n)\n\n\nCustom show function for FESpace that prints some information and all available dofmaps.\n\n\n\n\n\n","category":"method"},{"location":"fespace/#ExtendableFEMBase.assemblytype-Union{Tuple{FESpace{Tv, Ti, FEType, APT}}, Tuple{APT}, Tuple{FEType}, Tuple{Ti}, Tuple{Tv}} where {Tv, Ti, FEType<:AbstractFiniteElement, APT}","page":"FESpace","title":"ExtendableFEMBase.assemblytype","text":"assemblytype(\n _::FESpace{Tv, Ti, FEType<:AbstractFiniteElement, APT}\n) -> Any\n\n\nreturns the assembly type parameter of the finite element space, i.e. on which entities of the grid the finite element is defined.\n\n\n\n\n\n","category":"method"},{"location":"fespace/#ExtendableFEMBase.broken-Tuple{FESpace}","page":"FESpace","title":"ExtendableFEMBase.broken","text":"broken(FES::FESpace) -> Bool\n\n\nreturns true if the finite element space is broken, false if not\n\n\n\n\n\n","category":"method"},{"location":"fespace/#ExtendableFEMBase.get_AT-Union{Tuple{FESpace{Tv, Ti, FEType, AT}}, Tuple{AT}, Tuple{FEType}, Tuple{Ti}, Tuple{Tv}} where {Tv, Ti, FEType, AT}","page":"FESpace","title":"ExtendableFEMBase.get_AT","text":"get_AT(_::FESpace{Tv, Ti, FEType, AT}) -> Any\n\n\nreturns the support of the finite element space\n\n\n\n\n\n","category":"method"},{"location":"fespace/#ExtendableFEMBase.get_FEType-Union{Tuple{FESpace{Tv, Ti, FEType, AT}}, Tuple{AT}, Tuple{FEType}, Tuple{Ti}, Tuple{Tv}} where {Tv, Ti, FEType, AT}","page":"FESpace","title":"ExtendableFEMBase.get_FEType","text":"get_FEType(_::FESpace{Tv, Ti, FEType, AT}) -> Any\n\n\nreturns the finite element type of the finite element space\n\n\n\n\n\n","category":"method"},{"location":"fespace/#ExtendableFEMBase.ndofs-Tuple{FESpace}","page":"FESpace","title":"ExtendableFEMBase.ndofs","text":"ndofs(FES::FESpace) -> Int64\n\n\nreturns the total number of degrees of freedom of the finite element space.\n\n\n\n\n\n","category":"method"},{"location":"fespace/#DofMaps","page":"FESpace","title":"DofMaps","text":"","category":"section"},{"location":"fespace/","page":"FESpace","title":"FESpace","text":"Modules = [ExtendableFEMBase]\nPages = [\"dofmaps.jl\"]\nOrder = [:type, :function]","category":"page"},{"location":"fespace/#ExtendableFEMBase.BEdgeDofs","page":"FESpace","title":"ExtendableFEMBase.BEdgeDofs","text":"abstract type BEdgeDofs <: DofMap\n\nKey type describing the dofs for each boundary edge of the dofgrid\n\n\n\n\n\n","category":"type"},{"location":"fespace/#ExtendableFEMBase.BEdgeDofsParent","page":"FESpace","title":"ExtendableFEMBase.BEdgeDofsParent","text":"abstract type BEdgeDofsParent <: DofMap\n\nKey type describing the dofs for each boundary edge of the parentgrid\n\n\n\n\n\n","category":"type"},{"location":"fespace/#ExtendableFEMBase.BFaceDofs","page":"FESpace","title":"ExtendableFEMBase.BFaceDofs","text":"abstract type BFaceDofs <: DofMap\n\nKey type describing the dofs for each boundary face of the dofgrid\n\n\n\n\n\n","category":"type"},{"location":"fespace/#ExtendableFEMBase.BFaceDofsParent","page":"FESpace","title":"ExtendableFEMBase.BFaceDofsParent","text":"abstract type BFaceDofsParent <: DofMap\n\nKey type describing the dofs for each boundary face of the parentgrid\n\n\n\n\n\n","category":"type"},{"location":"fespace/#ExtendableFEMBase.CellDofs","page":"FESpace","title":"ExtendableFEMBase.CellDofs","text":"abstract type CellDofs <: DofMap\n\nKey type describing the dofs for each cell of the dofgrid\n\n\n\n\n\n","category":"type"},{"location":"fespace/#ExtendableFEMBase.CellDofsParent","page":"FESpace","title":"ExtendableFEMBase.CellDofsParent","text":"abstract type CellDofsParent <: DofMap\n\nKey type describing the dofs for each cell of the parentgrid\n\n\n\n\n\n","category":"type"},{"location":"fespace/#ExtendableFEMBase.DofMap","page":"FESpace","title":"ExtendableFEMBase.DofMap","text":"abstract type DofMap <: ExtendableGrids.AbstractGridAdjacency\n\nDofmaps are stored as an ExtendableGrids.AbstractGridAdjacency in the finite element space and collect information with respect to different AssemblyTypes. They are generated automatically on demand and the dofmaps associated to each subtype can be accessed via FESpace[DofMap].\n\n\n\n\n\n","category":"type"},{"location":"fespace/#ExtendableFEMBase.EdgeDofs","page":"FESpace","title":"ExtendableFEMBase.EdgeDofs","text":"abstract type EdgeDofs <: DofMap\n\nKey type describing the dofs for each edge of the dofgrid\n\n\n\n\n\n","category":"type"},{"location":"fespace/#ExtendableFEMBase.EdgeDofsParent","page":"FESpace","title":"ExtendableFEMBase.EdgeDofsParent","text":"abstract type EdgeDofsParent <: DofMap\n\nKey type describing the dofs for each edge of the parentgrid\n\n\n\n\n\n","category":"type"},{"location":"fespace/#ExtendableFEMBase.FaceDofs","page":"FESpace","title":"ExtendableFEMBase.FaceDofs","text":"abstract type FaceDofs <: DofMap\n\nKey type describing the dofs for each face of the dofgrid\n\n\n\n\n\n","category":"type"},{"location":"fespace/#ExtendableFEMBase.FaceDofsParent","page":"FESpace","title":"ExtendableFEMBase.FaceDofsParent","text":"abstract type FaceDofsParent <: DofMap\n\nKey type describing the dofs for each face of the parentgrid\n\n\n\n\n\n","category":"type"},{"location":"fespace/","page":"FESpace","title":"FESpace","text":"The following DofMap subtypes are available and are used as keys to access the dofmap via FESpace[DofMap] (which is equivalent to FESpace.dofmaps[DofMap]).","category":"page"},{"location":"fespace/","page":"FESpace","title":"FESpace","text":"DofMap Explanation\nCellDofs degrees of freedom for on each cell\nFaceDofs degrees of freedom for each face\nEdgeDofs degrees of freedom for each edge (in 3D)\nBFaceDofs degrees of freedom for each boundary face\nBEdgeDofs degrees of freedom for each boundary edge (in 3D)","category":"page"},{"location":"feevaluator/#FEEvaluator","page":"FEEvaluator","title":"FEEvaluator","text":"","category":"section"},{"location":"feevaluator/","page":"FEEvaluator","title":"FEEvaluator","text":"FEEvaluators provide a structure that handles the evaluation of finite element basis functions for a given function operator, quadrature rule and item geometry. It stores the evaluations on the reference geometry (where derivatives are computed by automatic differentiation) and on the current mesh item. The current mesh item can be changed via the update! call.","category":"page"},{"location":"feevaluator/","page":"FEEvaluator","title":"FEEvaluator","text":"Modules = [ExtendableFEMBase]\nPages = [\"feevaluator.jl\"]\nOrder = [:type, :function]","category":"page"},{"location":"feevaluator/#ExtendableFEMBase.FEEvaluator-Union{Tuple{FEAPT}, Tuple{EG}, Tuple{FEType}, Tuple{TvR}, Tuple{TiG}, Tuple{TvG}, Tuple{FESpace{TvG, TiG, FEType, FEAPT}, Type{<:??}, QuadratureRule{TvR, EG}}} where {TvG, TiG, TvR, FEType<:AbstractFiniteElement, EG<:ExtendableGrids.AbstractElementGeometry, FEAPT<:ExtendableGrids.AssemblyType}","page":"FEEvaluator","title":"ExtendableFEMBase.FEEvaluator","text":"function FEEvaluator(FE::FESpace, operator::AbstractFunctionOperator, qrule::QuadratureRule; T = Float64, AT = ON_CELLS, L2G = nothing)\n\nConstructs a FEEvaluator that handles evaluations of finite element basis function evaluation for the given FESpace, operator at the quadrature points of the given QuadratureRule. It has an update! function to update the evaluation upon entry to a new cell. Evaluations can be accessed via FEEvaluator.cvals[j,k,i] where i is the quadrature point id, k is the local dof number and j is the component. \n\nNote that matrix-valued operators evaluations, e.g. for Gradient, are given as a long vector (in component-wise order).\n\n\n\n\n\n","category":"method"},{"location":"feevaluator/#ExtendableFEMBase.eval_febe!","page":"FEEvaluator","title":"ExtendableFEMBase.eval_febe!","text":"\teval_febe!(result, FEBE::FEBasisEvaluator, j::Int, i::Int, offset::Int = 0, factor = 1)\n\nEvaluate the j-th basis function of the FEBasisEvaluator at the i-th quadrature point and writes the (possibly vector-valued) evaluation into result (beginning at offset and with the specified factor).\n\n\n\n\n\n","category":"function"},{"location":"feevaluator/#ExtendableFEMBase.eval_febe!-2","page":"FEEvaluator","title":"ExtendableFEMBase.eval_febe!","text":"\teval_febe!(result, FEBE::FEBasisEvaluator, j::Int, i::Int, offset::Int = 0, factor = 1)\n\nEvaluates the linear combination of the basisfunction with given coefficients at the i-th quadrature point and writes the (possibly vector-valued) evaluation into result (beginning at offset and with the specified factor).\n\n\n\n\n\n","category":"function"},{"location":"feevaluator/#ExtendableFEMBase.update_basis!-Tuple{FEEvaluator, Any}","page":"FEEvaluator","title":"ExtendableFEMBase.update_basis!","text":"function update_basis!(FEBE::FEEvaluator, item::Integer)\n\nSets FEBE.citem[] = item and updates the basis.\n\n\n\n\n\n","category":"method"},{"location":"feevaluator/#ExtendableFEMBase.update_basis!-Union{Tuple{ExtendableFEMBase.SingleFEEvaluator{<:Real, <:Real, <:Integer, operator, FEType}}, Tuple{FEType}, Tuple{operator}} where {operator, FEType}","page":"FEEvaluator","title":"ExtendableFEMBase.update_basis!","text":"function update_basis!(FEBE::SingleFEEvaluator)\n\nUpdates the basis for the current item FEBE.citem[].\n\n\n\n\n\n","category":"method"},{"location":"plutostatichtml_examples/LowLevelPoisson/","page":"Low level Poisson","title":"Low level Poisson","text":"\n\n\n\n
begin\n    using ExtendableFEMBase\n    using ExtendableGrids\n    using ExtendableSparse\n    using GridVisualize\n    using PlutoVista\n    GridVisualize.default_plotter!(PlutoVista)\nend
\n
PlutoVista
\n\n\n

Tutorial notebook: Poisson problem

This notebook demonstrates how to implement the Poisson problem with the low level structures provided by ExtendableFEMBase. The Poisson problem with homogeneous Dirichlet boundary data seeks \\(u\\) such that

$$\\begin{aligned}\n\t- \\mu \\Delta u = f.\n\\end{aligned}$$

The weak formulation seeks \\(u \\in V := H^1_0(\\Omega)\\) such that

$$\\begin{aligned}\n\t\\mu (\\nabla u, \\nabla v) = (f, v)\n\t\\quad \\text{for all } v \\in V\n\\end{aligned}$$

\n\n
begin\n    ## PDE data\n    μ = 1.0\n    f = x -> x[1] - x[2]\n\n    ## discretization parameters\n    nref = 9\n    order = 1\nend
\n
1
\n\n
tricontour(xgrid[Coordinates],xgrid[CellNodes],sol.entries[1:num_nodes(xgrid)]; levels = 5, resolution = (500,500))
\n
\n\n\n
begin\n    ## call low level solver\n    sol = solve_poisson_lowlevel(FES, μ, f)\nend
\n
FEVector information\n====================\n   block  |  ndofs \t|     min  /  max    \t| FEType \t\t (name/tag)\n [    1]  |  263169\t| -1.21e-02/1.21e-02  \t| H1Pk{1,2,1}  \t (#1)
\n\n
function solve_poisson_lowlevel(FES, μ, f)\n    \n    Solution = FEVector(FES)\n    FES = Solution[1].FES\n    A = FEMatrix(FES, FES)\n    b = FEVector(FES)\n    println(\"Assembling operators...\")\n    @time assemble!(A.entries, b.entries, FES, f, μ)\n\n    ## fix boundary dofs\n    println(\"Assembling boundary data...\")\n    @time begin\n        BFaceDofs::Adjacency{Int32} = FES[ExtendableFEMBase.BFaceDofs]\n        nbfaces::Int = num_sources(BFaceDofs)\n        AM::ExtendableSparseMatrix{Float64,Int64} = A.entries\n        dof_j::Int = 0\n        for bface = 1 : nbfaces\n            for j = 1 : num_targets(BFaceDofs,1)\n                dof_j = BFaceDofs[j, bface]\n                AM[dof_j,dof_j] = 1e60\n                b.entries[dof_j] = 0\n            end\n        end\n    end\n    ExtendableSparse.flush!(A.entries)\n\n    ## solve\n    println(\"Solving linear system...\")\n    @time copyto!(Solution.entries, A.entries \\ b.entries)\n\n    return Solution\nend
\n
solve_poisson_lowlevel (generic function with 1 method)
\n\n
begin\n    ## create finite element space\n    FEType = H1Pk{1,2,order}\n\n    ## prepare finite element space and dofmaps\n    println(\"Creating FESpace...\")\n    @time FES = FESpace{FEType}(xgrid)\n    FES\nend
\n
FESpace information\n===================\n     name = H1Pk{1,2,1}\n   FEType = H1Pk{1,2,1}\n  FEClass = ExtendableFEMBase.AbstractH1FiniteElement\n    ndofs = 263169\n\n\nDofMaps\n==========\n
\n\n
begin\n    ## create grid\n    X = LinRange(0,1,2^nref+1)\n    Y = LinRange(0,1,2^nref+1)\n    println(\"Creating grid...\")\n    @time xgrid = simplexgrid(X,Y)\n    println(\"Preparing FaceNodes...\")\n    @time xgrid[FaceNodes]\n    println(\"Preparing CellVolumes...\")\n    @time xgrid[CellVolumes]\n    xgrid\nend
\n
ExtendableGrids.ExtendableGrid{Float64, Int32};\ndim: 2 nodes: 263169 cells: 524288 bfaces: 2048\n
\n\n
function assemble!(A::ExtendableSparseMatrix, b::Vector, FES, f, μ = 1)\n\n    xgrid = FES.xgrid\n    EG = xgrid[UniqueCellGeometries][1]\n    FEType = eltype(FES)\n    L2G = L2GTransformer(EG, xgrid, ON_CELLS)\n\n    ## dofmap\n    CellDofs = FES[ExtendableFEMBase.CellDofs]\n    \n    ## quadrature formula\n    qf = QuadratureRule{Float64, EG}(2*(get_polynomialorder(FEType, EG)-1))\n    weights::Vector{Float64} = qf.w\n    xref::Vector{Vector{Float64}} = qf.xref\n    nweights::Int = length(weights)\n    \n    ## FE basis evaluator\n    FEBasis_∇ = FEEvaluator(FES, Gradient, qf)\n    ∇vals = FEBasis_∇.cvals\n    FEBasis_id = FEEvaluator(FES, Identity, qf)\n    idvals = FEBasis_id.cvals\n\n    \n    cellvolumes = xgrid[CellVolumes]\n   \n    ## ASSEMBLY LOOP\n    function barrier(EG, L2G::L2GTransformer)\n        ## barrier function to avoid allocations by EG dispatch\n        \n    \tndofs4cell::Int = get_ndofs(ON_CELLS, FEType, EG)\n    \tAloc = zeros(Float64, ndofs4cell, ndofs4cell)\n        ncells::Int = num_cells(xgrid)\n    \tdof_j::Int, dof_k::Int = 0, 0\n        x::Vector{Float64} = zeros(Float64, 2)\n        \n        for cell = 1 : ncells\n            ## update FE basis evaluators\n            FEBasis_∇.citem[] = cell\n            update_basis!(FEBasis_∇) \n    \n            ## assemble local stiffness matrix\n            for j = 1 : ndofs4cell, k = j : ndofs4cell\n                temp = 0\n                for qp = 1 : nweights\n                    temp += weights[qp] * dot(view(∇vals,:,j,qp), view(∇vals,:,k,qp))\n                end\n                Aloc[j,k] = temp\n            end\n            Aloc .*= μ * cellvolumes[cell]\n    \n            ## add local matrix to global matrix\n            for j = 1 : ndofs4cell\n                dof_j = CellDofs[j, cell]\n                for k = j : ndofs4cell\n                    dof_k = CellDofs[k, cell]\n                    if abs(Aloc[j,k]) > 1e-15\n                        # write into sparse matrix, only lines with allocations\n                        rawupdateindex!(A, +, Aloc[j,k], dof_j, dof_k) \n                        if k > j\n                            rawupdateindex!(A, +, Aloc[j,k], dof_k, dof_j)\n                        end\n                    end\n                end\n            end\n            fill!(Aloc, 0)\n\n            ## assemble right-hand side\n            update_trafo!(L2G, cell)\n            for j = 1 : ndofs4cell\n                ## right-hand side\n                temp = 0\n                for qp = 1 : nweights\n                    ## get global x for quadrature point\n                    eval_trafo!(x, L2G, xref[qp])\n                    ## evaluate (f(x), v_j(x))\n                    temp += weights[qp] * idvals[1, j, qp] * f(x)\n                end\n                ## write into global vector\n                dof_j = CellDofs[j, cell]\n                b[dof_j] += temp * cellvolumes[cell]\n            end\n        end\n    end\n    barrier(EG, L2G)\n    flush!(A)\nend
\n
assemble! (generic function with 2 methods)
\n
\n

Built with Julia 1.10.5 and

\nExtendableFEMBase 0.6.0
\nExtendableGrids 1.9.2
\nExtendableSparse 1.5.1
\nGridVisualize 1.7.0
\nPlutoVista 1.0.1\n
\n\n","category":"page"},{"location":"plutostatichtml_examples/LowLevelPoisson/","page":"Low level Poisson","title":"Low level Poisson","text":"EditURL = \"https://github.com/chmerdon/ExtendableFEMBase.jl/blob/master/nothing\"","category":"page"},{"location":"module_examples/Example280_BasisPlotter/#280-:-Basis-Plotter","page":"Example280_BasisPlotter","title":"280 : Basis-Plotter","text":"","category":"section"},{"location":"module_examples/Example280_BasisPlotter/","page":"Example280_BasisPlotter","title":"Example280_BasisPlotter","text":"(source code)","category":"page"},{"location":"module_examples/Example280_BasisPlotter/","page":"Example280_BasisPlotter","title":"Example280_BasisPlotter","text":"This example plots all the basis functions of a H1 finite element on Edge1D or Triangle2D as unicode plots. This is the result with the default parameters (dim = 1, order = 3):","category":"page"},{"location":"module_examples/Example280_BasisPlotter/","page":"Example280_BasisPlotter","title":"Example280_BasisPlotter","text":"(Image: )","category":"page"},{"location":"module_examples/Example280_BasisPlotter/","page":"Example280_BasisPlotter","title":"Example280_BasisPlotter","text":"module Example280_BasisPlotter\n\nusing ExtendableFEMBase\nusing ExtendableGrids\n\n# everything is wrapped in a main function\nfunction main(; dim = 1, order = 3)\n\n\t# generate two grids\n\t@assert dim in [1, 2] \"dim must be 1 or 2\"\n\trefgeom = dim == 1 ? Edge1D : Triangle2D\n\txgrid = reference_domain(refgeom)\n\n\t# set finite element type and get some information\n\tFEType = H1Pk{1, dim, order}\n\tndofs = get_ndofs(ON_CELLS, FEType, refgeom)\n\tFEType = H1Pk{ndofs, dim, order}\n\n\t# generate FEVector with ncomponents = ndofs\n\t# that will carry one basis function in each component\n\tFEFunc = FEVector(FESpace{FEType}(xgrid))\n\tcoffsets = ExtendableFEMBase.get_local_coffsets(FEType, ON_CELLS, refgeom)\n\tfor j ∈ 1:ndofs\n\t\tFEFunc[1][j+coffsets[j]] = 1\n\tend\n\n # plot\n\tprintln(stdout, unicode_scalarplot(FEFunc[1]; title = \"φ\", ylim = (-0.5, 1), resolution = dim == 1 ? (40, 10) : (20, 15), nrows = order))\nend\nend","category":"page"},{"location":"module_examples/Example280_BasisPlotter/","page":"Example280_BasisPlotter","title":"Example280_BasisPlotter","text":"","category":"page"},{"location":"module_examples/Example280_BasisPlotter/","page":"Example280_BasisPlotter","title":"Example280_BasisPlotter","text":"This page was generated using Literate.jl.","category":"page"},{"location":"examples_intro/#About-the-examples","page":"Introduction","title":"About the examples","text":"","category":"section"},{"location":"examples_intro/","page":"Introduction","title":"Introduction","text":"The examples have been designed with the following issues in mind:","category":"page"},{"location":"examples_intro/","page":"Introduction","title":"Introduction","text":"they run from the Julia REPL\neach example is a Julia module named similar to the basename of the example file.\nan example can be used as the starting point for a project \nsome examples define test cases for the test suite\nExampleXYZ with X = A can be considered advanced and uses low-level structures and/or demonstrates customisation features or experimental features\nthe default output of the main function is printed on the website and can be used to check if the code runs as expected (unfortunately REPL messages are not recorded)\nprinted assembly and solving times (especially in a first iteration) can be much larger due to first-run compilation times","category":"page"},{"location":"examples_intro/#Running-the-examples","page":"Introduction","title":"Running the examples","text":"","category":"section"},{"location":"examples_intro/","page":"Introduction","title":"Introduction","text":"In order to run ExampleXXX, peform the following steps:","category":"page"},{"location":"examples_intro/","page":"Introduction","title":"Introduction","text":"Download the example file (e.g. via the source code link at the top)\nMake sure all used packages are installed in your Julia environment\nIn the REPL: ","category":"page"},{"location":"examples_intro/","page":"Introduction","title":"Introduction","text":"julia> include(\"ExampleXXX.jl\")`\n\njulia> ExampleXXX.main()","category":"page"},{"location":"examples_intro/","page":"Introduction","title":"Introduction","text":"Some examples offer visual output via the optional argument Plotter = PyPlot or Plotter = GLMakie","category":"page"},{"location":"examples_intro/","page":"Introduction","title":"Introduction","text":"(provided the package PyPlot/GLMakie is installed and loaded)","category":"page"},{"location":"meshing/#Meshing","page":"Meshing","title":"Meshing","text":"","category":"section"},{"location":"meshing/","page":"Meshing","title":"Meshing","text":"Meshes are stored as an ExtendableGrid, see ExtendableGrids.jl for details and constructors. Grid generators for simplex grids can be found e.g. in the external module SimplexGridFactory.jl","category":"page"},{"location":"meshing/","page":"Meshing","title":"Meshing","text":"Cells, faces and edges of the mesh are associated to AbstractElementGeometries (defined by ExtendableGrids.jl) that are used to dispatch functionality (local/global transformation, enumeration rules, set of basis functions, volume calculation, refinements etc.). See further below for a list of recognized element geometries.","category":"page"},{"location":"meshing/#Recognized-Geometries-and-Reference-Domains","page":"Meshing","title":"Recognized Geometries and Reference Domains","text":"","category":"section"},{"location":"meshing/","page":"Meshing","title":"Meshing","text":"The following list contains all subtypes of ExtendableGrids.AbstractElementGeometries and their reference domains for which the package offers finite elements on them.","category":"page"},{"location":"meshing/","page":"Meshing","title":"Meshing","text":"","category":"page"},{"location":"meshing/#Edge1D-:-AbstractElementGeometry1D","page":"Meshing","title":"Edge1D <: AbstractElementGeometry1D","text":"","category":"section"},{"location":"meshing/","page":"Meshing","title":"Meshing","text":"[1]-----[2] [1] = [0]\n [2] = [1]","category":"page"},{"location":"meshing/","page":"Meshing","title":"Meshing","text":"","category":"page"},{"location":"meshing/#Triangle2D","page":"Meshing","title":"Triangle2D","text":"","category":"section"},{"location":"meshing/","page":"Meshing","title":"Meshing","text":"[3] \n | \\ \n | \\ [1] = [0,0]\n | \\ [2] = [1,0]\n | \\ [3] = [0,1]\n | \\ \n[1]--------[2]","category":"page"},{"location":"meshing/","page":"Meshing","title":"Meshing","text":"","category":"page"},{"location":"meshing/#Parallelogram2D-:-Quadrilateral2D","page":"Meshing","title":"Parallelogram2D <: Quadrilateral2D","text":"","category":"section"},{"location":"meshing/","page":"Meshing","title":"Meshing","text":"[4]--------[3] \n | | [1] = [0,0]\n | | [2] = [1,0]\n | | [3] = [1,1]\n | | [4] = [0,1]\n[1]--------[2]\n\nNote: most finite elements only work as intended on Parallelogram2D\n since the local<>global map stays affine in this case","category":"page"},{"location":"meshing/","page":"Meshing","title":"Meshing","text":"","category":"page"},{"location":"meshing/#Tetrahedron3D","page":"Meshing","title":"Tetrahedron3D","text":"","category":"section"},{"location":"meshing/","page":"Meshing","title":"Meshing","text":"[4] \n |\\\\ \n | \\ \\ [1] = [0,0,0]\n | \\ \\ [2] = [1,0,0]\n | \\ \\ [3] = [0,1,0]\n | _-[3]-_ \\ [4] = [0,0,1]\n[1]--------[2]","category":"page"},{"location":"meshing/","page":"Meshing","title":"Meshing","text":"","category":"page"},{"location":"meshing/#Parallelepiped3D-:-Hexahedron3D","page":"Meshing","title":"Parallelepiped3D <: Hexahedron3D","text":"","category":"section"},{"location":"meshing/","page":"Meshing","title":"Meshing","text":" [8]--------[7] [1] = [0,0,0]\n / | / | [2] = [1,0,0]\n[5]--------[6] | [3] = [1,1,0]\n | | | | [4] = [0,1,0]\n | | | | [5] = [0,0,1]\n | [4]-----|--[3] [6] = [1,0,1]\n | / | / [7] = [1,1,1]\n[1]--------[2] [8] = [0,1,1]\n\nNote: most finite elements only work as intended on Parallelepiped3D\n since the local<>global map stays affine in this case","category":"page"},{"location":"module_examples/Example200_LowLevelPoisson/#200-:-Poisson-Problem","page":"Example200_LowLevelPoisson","title":"200 : Poisson Problem","text":"","category":"section"},{"location":"module_examples/Example200_LowLevelPoisson/","page":"Example200_LowLevelPoisson","title":"Example200_LowLevelPoisson","text":"(source code)","category":"page"},{"location":"module_examples/Example200_LowLevelPoisson/","page":"Example200_LowLevelPoisson","title":"Example200_LowLevelPoisson","text":"This example computes the solution u of the two-dimensional Poisson problem","category":"page"},{"location":"module_examples/Example200_LowLevelPoisson/","page":"Example200_LowLevelPoisson","title":"Example200_LowLevelPoisson","text":"beginaligned\n-Delta u = f quad textin Omega\nendaligned","category":"page"},{"location":"module_examples/Example200_LowLevelPoisson/","page":"Example200_LowLevelPoisson","title":"Example200_LowLevelPoisson","text":"with right-hand side f(xy) equiv xy and homogeneous Dirichlet boundary conditions on the unit square domain Omega on a given grid.","category":"page"},{"location":"module_examples/Example200_LowLevelPoisson/","page":"Example200_LowLevelPoisson","title":"Example200_LowLevelPoisson","text":"When run, this script also measures runtimes for grid generation, assembly and solving (direct/UMFPACK) for different refinement levels.","category":"page"},{"location":"module_examples/Example200_LowLevelPoisson/","page":"Example200_LowLevelPoisson","title":"Example200_LowLevelPoisson","text":"The computed solution for the default parameters looks like this:","category":"page"},{"location":"module_examples/Example200_LowLevelPoisson/","page":"Example200_LowLevelPoisson","title":"Example200_LowLevelPoisson","text":"(Image: )","category":"page"},{"location":"module_examples/Example200_LowLevelPoisson/","page":"Example200_LowLevelPoisson","title":"Example200_LowLevelPoisson","text":"module Example200_LowLevelPoisson\n\nusing ExtendableFEMBase\nusing ExtendableGrids\nusing ExtendableSparse\nusing GridVisualize\nusing UnicodePlots\nusing Test #\n\n# data for Poisson problem\nconst μ = 1.0\nconst f = x -> x[1] - x[2]\n\nfunction main(; maxnref = 8, order = 2, Plotter = nothing)\n\n\t# Finite element type\n\tFEType = H1Pk{1, 2, order}\n\n\t# run once on a tiny mesh for compiling\n\tX = LinRange(0, 1, 4)\n\txgrid = simplexgrid(X, X)\n\tFES = FESpace{FEType}(xgrid)\n\tsol, time_assembly, time_solve = solve_poisson_lowlevel(FES, μ, f)\n\n\t# loop over uniform refinements + timings\n\tplt = GridVisualizer(; Plotter = Plotter, layout = (1, 1), clear = true, resolution = (500, 500))\n\tloop_allocations = 0\n\tfor level ∈ 1:maxnref\n\t\tX = LinRange(0, 1, 2^level + 1)\n\t\ttime_grid = @elapsed xgrid = simplexgrid(X, X)\n\t\ttime_facenodes = @elapsed xgrid[FaceNodes]\n\t\tFES = FESpace{FEType}(xgrid)\n\t\tprintln(\"\\nLEVEL = $level, ndofs = $(FES.ndofs)\\n\")\n\t\tif level < 4\n\t\t\tprintln(stdout, unicode_gridplot(xgrid))\n\t\tend\n\t\ttime_dofmap = @elapsed FES[CellDofs]\n\t\tsol, time_assembly, time_solve = solve_poisson_lowlevel(FES, μ, f)\n\n\t\t# plot statistics\n\t\tprintln(stdout, barplot([\"Grid\", \"FaceNodes\", \"celldofs\", \"Assembly\", \"Solve\"], [time_grid, time_facenodes, time_dofmap, time_assembly, time_solve], title = \"Runtimes\"))\n\n\t\t# plot\n\t\tscalarplot!(plt[1,1], xgrid, view(sol.entries, 1:num_nodes(xgrid)), limits = (-0.0125,0.0125))\n\tend\n\n\treturn sol, plt\nend\n\n\nfunction solve_poisson_lowlevel(FES, μ, f)\n\tSolution = FEVector(FES)\n\tFES = Solution[1].FES\n\tA = FEMatrix(FES, FES)\n\tb = FEVector(FES)\n\tprintln(\"Assembling...\")\n\ttime_assembly = @elapsed @time begin\n\t\tloop_allocations = assemble!(A.entries, b.entries, FES, f, μ)\n\n\t\t# fix boundary dofs\n\t\tbegin\n\t\t\tbdofs = boundarydofs(FES)\n\t\t\tfor dof in bdofs\n\t\t\t\tA.entries[dof, dof] = 1e60\n\t\t\t\tb.entries[dof] = 0\n\t\t\tend\n\t\tend\n\t\tExtendableSparse.flush!(A.entries)\n\tend\n\n\t# solve\n\tprintln(\"Solving linear system...\")\n\ttime_solve = @elapsed @time copyto!(Solution.entries, A.entries \\ b.entries)\n\n\treturn Solution, time_assembly, time_solve\nend\n\nfunction assemble!(A::ExtendableSparseMatrix, b::Vector, FES, f, μ = 1)\n\txgrid = FES.xgrid\n\tEG = xgrid[UniqueCellGeometries][1]\n\tFEType = eltype(FES)\n\tL2G = L2GTransformer(EG, xgrid, ON_CELLS)\n\n\t# quadrature formula\n\tqf = QuadratureRule{Float64, EG}(2 * (get_polynomialorder(FEType, EG) - 1))\n\tweights::Vector{Float64} = qf.w\n\txref::Vector{Vector{Float64}} = qf.xref\n\tnweights::Int = length(weights)\n\tcellvolumes = xgrid[CellVolumes]\n\n\t# FE basis evaluator and dofmap\n\tFEBasis_∇ = FEEvaluator(FES, Gradient, qf)\n\t∇vals = FEBasis_∇.cvals\n\tFEBasis_id = FEEvaluator(FES, Identity, qf)\n\tidvals = FEBasis_id.cvals\n\tcelldofs = FES[CellDofs]\n\n\t# ASSEMBLY LOOP\n\tloop_allocations = 0\n\tfunction barrier(EG, L2G::L2GTransformer)\n\t\t# barrier function to avoid allocations by type dispatch\n\t\tndofs4cell::Int = get_ndofs(ON_CELLS, FEType, EG)\n\t\tAloc = zeros(Float64, ndofs4cell, ndofs4cell)\n\t\tncells::Int = num_cells(xgrid)\n\t\tdof_j::Int, dof_k::Int = 0, 0\n\t\tx::Vector{Float64} = zeros(Float64, 2)\n\n\t\tloop_allocations += @allocated for cell ∈ 1:ncells\n\t\t\t# update FE basis evaluators\n\t\t\tFEBasis_∇.citem[] = cell\n\t\t\tupdate_basis!(FEBasis_∇)\n\n\t\t\t# assemble local stiffness matrix\n\t\t\tfor j ∈ 1:ndofs4cell, k ∈ j:ndofs4cell\n\t\t\t\ttemp = 0\n\t\t\t\tfor qp ∈ 1:nweights\n\t\t\t\t\ttemp += weights[qp] * dot(view(∇vals, :, j, qp), view(∇vals, :, k, qp))\n\t\t\t\tend\n\t\t\t\tAloc[j, k] = temp\n\t\t\tend\n\t\t\tAloc .*= μ * cellvolumes[cell]\n\n\t\t\t# add local matrix to global matrix\n\t\t\tfor j ∈ 1:ndofs4cell\n\t\t\t\tdof_j = celldofs[j, cell]\n\t\t\t\tfor k ∈ j:ndofs4cell\n\t\t\t\t\tdof_k = celldofs[k, cell]\n\t\t\t\t\tif abs(Aloc[j, k]) > 1e-15\n\t\t\t\t\t\t# write into sparse matrix, only lines with allocations\n\t\t\t\t\t\trawupdateindex!(A, +, Aloc[j, k], dof_j, dof_k)\n\t\t\t\t\t\tif k > j\n\t\t\t\t\t\t\trawupdateindex!(A, +, Aloc[j, k], dof_k, dof_j)\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\tend\n\t\t\tfill!(Aloc, 0)\n\n\t\t\t# assemble right-hand side\n\t\t\tupdate_trafo!(L2G, cell)\n\t\t\tfor j ∈ 1:ndofs4cell\n\t\t\t\t# right-hand side\n\t\t\t\ttemp = 0\n\t\t\t\tfor qp ∈ 1:nweights\n\t\t\t\t\t# get global x for quadrature point\n\t\t\t\t\teval_trafo!(x, L2G, xref[qp])\n\t\t\t\t\t# evaluate (f(x), v_j(x))\n\t\t\t\t\ttemp += weights[qp] * idvals[1, j, qp] * f(x)\n\t\t\t\tend\n\t\t\t\t# write into global vector\n\t\t\t\tdof_j = celldofs[j, cell]\n\t\t\t\tb[dof_j] += temp * cellvolumes[cell]\n\t\t\tend\n\t\tend\n\tend\n\tbarrier(EG, L2G)\n\tflush!(A)\n\treturn loop_allocations\nend\n\nfunction generateplots(dir = pwd(); Plotter = nothing, kwargs...)\n\t~, plt = main(; Plotter = Plotter, kwargs...)\n\tscene = GridVisualize.reveal(plt)\n\tGridVisualize.save(joinpath(dir, \"example200.png\"), scene; Plotter = Plotter)\nend\n\n\tFEType = H1Pk{1, 2, order}\n\tX = LinRange(0, 1, 64)\n\txgrid = simplexgrid(X, X)\n\tFES = FESpace{FEType}(xgrid)\n\tA = FEMatrix(FES, FES)\n\tb = FEVector(FES)\n\t@info \"ndofs = $(FES.ndofs)\"\n\t# first assembly causes allocations when filling sparse matrix\n\tloop_allocations = assemble!(A.entries, b.entries, FES, f, μ)\n\t@info \"allocations in 1st assembly: $loop_allocations\"\n\t# second assebly in same matrix should have allocation-free inner loop\n\tloop_allocations = assemble!(A.entries, b.entries, FES, f, μ)\n\t@info \"allocations in 2nd assembly: $loop_allocations\"\n\t@test loop_allocations == 0\nend #module","category":"page"},{"location":"module_examples/Example200_LowLevelPoisson/","page":"Example200_LowLevelPoisson","title":"Example200_LowLevelPoisson","text":"","category":"page"},{"location":"module_examples/Example200_LowLevelPoisson/","page":"Example200_LowLevelPoisson","title":"Example200_LowLevelPoisson","text":"This page was generated using Literate.jl.","category":"page"},{"location":"plutostatichtml_examples/LowLevelNavierStokes/","page":"Low level Navier-Stokes","title":"Low level Navier-Stokes","text":"\n\n\n\n\n\n\n\n

Tutorial notebook: Navier–Stokes problem

Consider the Navier-Stokes problem that seeks \\(u\\) and \\(p\\) such that

$$\\begin{aligned}\n\t- \\mu \\Delta u + (u \\cdot \\nabla) u + \\nabla p &= f\\\\\n\t\t\t\\mathrm{div}(u) & = 0.\n\\end{aligned}$$

The weak formulation seeks \\(u \\in V := H^1_0(\\Omega)\\) and \\(p \\in Q := L^2_0(\\Omega)\\) such that

$$\\begin{aligned}\n\t\\mu (\\nabla u, \\nabla v) + ((u \\cdot \\nabla) u, v) - (p, \\mathrm{div}(v)) & = (f, v)\n\t& \\text{for all } v \\in V\\\\\n\t(q, \\mathrm{div}(u)) & = 0\n\t& \\text{for all } q \\in Q\\\\\n\\end{aligned}$$

This tutorial notebook compute a planar lattice flow with inhomogeneous Dirichlet boundary conditions (which requires some modification above). Newton's method with automatic differentation is used to handle the nonlinear convection term.

\n\n\n

This is a plot of the computed velocity and pressure:

\n\n\n
2-element Vector{PlutoVTKPlot}:\n PlutoVTKPlot(Dict{String, Any}(\"2axisfontsize\" => 10, \"1\" => \"tricontour\", \"2ylabel\" => \"y\", \"2\" => \"axis\", \"cbar_levels\" => [6.123233995736766e-17, 0.16667347690578882, 0.3333469538115776, 0.5000204307173663, 0.6666939076231551, 0.833367384528944, 1.0000408614347327], \"cbar\" => 1, \"2xlabel\" => \"x\", \"2zlabel\" => \"z\", \"cbar_stops\" => [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09  …  0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1.0], \"2zoom\" => 1.0…), 300.0, 300.0, false, (title = \"\", titlefontsize = 12, axisfontsize = 10, tickfontsize = 10, xlabel = \"x\", ylabel = \"y\", zlabel = \"z\", aspect = 1.0, zoom = 1.0, legendfontsize = 10, colorbarticks = :default, clear = false, levels = 5), \"1c7481ee-6553-11ef-08b1-e3de6e2c0746\")\n PlutoVTKPlot(Dict{String, Any}(\"2axisfontsize\" => 10, \"1\" => \"tricontour\", \"2ylabel\" => \"y\", \"2\" => \"axis\", \"cbar_levels\" => [-0.5064542228750328, -0.33763730567358835, -0.1688203884721439, -3.4712706993289544e-6, 0.16881344593074513, 0.3376303631321897, 0.5064472803336342], \"cbar\" => 1, \"2xlabel\" => \"x\", \"2zlabel\" => \"z\", \"cbar_stops\" => [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09  …  0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1.0], \"2zoom\" => 1.0…), 300.0, 300.0, false, (title = \"\", titlefontsize = 12, axisfontsize = 10, tickfontsize = 10, xlabel = \"x\", ylabel = \"y\", zlabel = \"z\", aspect = 1.0, zoom = 1.0, legendfontsize = 10, colorbarticks = :default, clear = false, levels = 5), \"1d1f385a-6553-11ef-1eb7-41d0c8b897c4\")
\n\n
begin\n    ## PDE data\n    const μ = 1e-2\n    function f!(fval, x, t) # right-hand side\n        fval[1] = 8.0*π*π*μ * exp(-8.0*π*π*μ*t) * sin(2.0*π*x[1])*sin(2.0*π*x[2])\n        fval[2] = 8.0*π*π*μ * exp(-8.0*π*π*μ*t) * cos(2.0*π*x[1])*cos(2.0*π*x[2])\n        return nothing\n    end\n\n    # exact velocity (for boundary data and error calculation)\n    function u!(uval, qpinfo) \n        x = qpinfo.x\n        t = qpinfo.time\n        uval[1] = exp(-8.0*π*π*μ*t) * sin(2.0*π*x[1])*sin(2.0*π*x[2])\n        uval[2] = exp(-8.0*π*π*μ*t) * cos(2.0*π*x[1])*cos(2.0*π*x[2])\n        return nothing\n    end\n    \n    ## discretization parameters\n    const nref = 5\n    const teval = 0\n    const order = 2\n    \n    ## prepare error calculation\n    function p!(pval,x,t) # exact pressure (for error calculation)\n        pval[1] = exp(-16*pi*pi*μ*t)*(cos(4*pi*x[1])-cos(4*pi*x[2]))/4\n        return nothing\n    end\nend
\n
p! (generic function with 1 method)
\n\n
begin\n    ## create grid\n    X = LinRange(0,1,2^nref+1)\n    Y = LinRange(0,1,2^nref+1)\n    println(\"Creating grid...\")\n    @time xgrid = simplexgrid(X,Y)\n    println(\"Preparing FaceNodes...\")\n    @time xgrid[FaceNodes]\n    println(\"Preparing CellVolumes...\")\n    @time xgrid[CellVolumes]\n    xgrid\nend
\n
ExtendableGrids.ExtendableGrid{Float64, Int32};\ndim: 2 nodes: 1089 cells: 2048 bfaces: 128\n
\n\n
begin\n    ## create finite element space (Taylor--Hood)\n    FETypes = [H1Pk{2,2,order}, H1Pk{1,2,order-1}]\n\n    ## prepare finite element space and dofmaps\n    println(\"Creating FESpace...\")\n    @time FES = [FESpace{FETypes[1]}(xgrid; name = \"velocity space\"),                  \t             FESpace{FETypes[2]}(xgrid; name = \"pressure space\")]\n    FES\nend
\n
2-element Vector{FESpace{Float64, Int32, FEType, ON_CELLS} where FEType<:AbstractFiniteElement}:\n \nFESpace information\n===================\n     name = velocity space\n   FEType = H1Pk{2,2,2}\n  FEClass = ExtendableFEMBase.AbstractH1FiniteElement\n    ndofs = 8450\n\n\nDofMaps\n==========\n\n \nFESpace information\n===================\n     name = pressure space\n   FEType = H1Pk{1,2,1}\n  FEClass = ExtendableFEMBase.AbstractH1FiniteElement\n    ndofs = 1089\n\n\nDofMaps\n==========\n
\n\n
begin\n    ## call low level solver\n    sol, u_init = solve_stokes_lowlevel(FES, μ, f!)\n    sol\nend
\n
FEVector information\n====================\n   block  |  ndofs \t|     min  /  max    \t| FEType \t\t (name/tag)\n [    1]  |    8450\t| -1.00e+00/1.00e+00  \t| velocity space  \t (#1)\n [    2]  |    1089\t| -5.06e-01/5.06e-01  \t| pressure space  \t (#2)
\n\n
function solve_stokes_lowlevel(FES, μ, f!)\n    \n    println(\"Initializing system...\")\n    Solution = FEVector(FES)\n    A = FEMatrix(FES)\n    b = FEVector(FES)\n    @time update_system! = prepare_assembly!(A, b, FES[1], FES[2], Solution, f!, μ)\n    @time update_system!(true, false)\n    Alin = deepcopy(A) # = keep linear part of system matrix\n    blin = deepcopy(b) # = keep linear part of right-hand side\n    \n    println(\"Pepare boundary conditions...\")\n    @time begin\n        u_init = FEVector(FES)\n        interpolate!(u_init[1], u!; time = teval)\n        \n        fixed_dofs = [size(A.entries,1)] # fix one pressure dof = last dof\n        BFaceDofs::Adjacency{Int32} = FES[1][ExtendableFEMBase.BFaceDofs]\n        nbfaces::Int = num_sources(BFaceDofs)\n        AM::ExtendableSparseMatrix{Float64,Int64} = A.entries\n        dof_j::Int = 0\n        for bface = 1 : nbfaces\n            for j = 1 : num_targets(BFaceDofs,1)\n                dof_j = BFaceDofs[j, bface]\n                push!(fixed_dofs, dof_j)\n            end\n        end\n    end\n\n    \n    for it = 1 : 20\n        ## solve\n        println(\"\\nITERATION $it\\n=============\")\n        println(\"Solving linear system...\")\n        @time copyto!(Solution.entries, A.entries \\ b.entries)\n        res = A.entries.cscmatrix * Solution.entries .- b.entries\n        for dof in fixed_dofs\n            res[dof] = 0\n        end\n        linres = norm(res)\n        println(\"linear residual = $linres\")\n        \n        fill!(A.entries.cscmatrix.nzval,0)\n        fill!(b.entries,0)\n        println(\"Updating linear system...\")\n        @time begin\n            update_system!(false,true)\n            A.entries.cscmatrix += Alin.entries.cscmatrix\n            b.entries .+= blin.entries\n        end\n        \n        ## fix boundary dofs\n        for dof in fixed_dofs\n            AM[dof,dof] = 1e60\n            b.entries[dof] = 1e60 * u_init.entries[dof]\n        end\n        ExtendableSparse.flush!(A.entries)\n\n        ## calculate nonlinear residual\n        res = A.entries.cscmatrix * Solution.entries .- b.entries\n        for dof in fixed_dofs\n            res[dof] = 0\n        end\n        nlres = norm(res)\n        println(\"nonlinear residual = $nlres\")\n        if nlres < max(1e-12, 20*linres)\n            break\n        end\n    end\n\n    return Solution, u_init\nend
\n
solve_stokes_lowlevel (generic function with 1 method)
\n\n
function prepare_assembly!(A, b, FESu, FESp, Solution, f, μ = 1)\n\n    A = A.entries\n    b = b.entries\n    Solution = Solution.entries\n    xgrid = FESu.xgrid\n    EG = xgrid[UniqueCellGeometries][1]\n    FEType_u = eltype(FESu)\n    FEType_p = eltype(FESp)\n    L2G = L2GTransformer(EG, xgrid, ON_CELLS)\n    cellvolumes = xgrid[CellVolumes]\n    ncells::Int = num_cells(xgrid)\n\n    ## dofmap\n    CellDofs_u = FESu[ExtendableFEMBase.CellDofs]\n    CellDofs_p = FESp[ExtendableFEMBase.CellDofs]\n    offset_p = FESu.ndofs\n    \n    ## quadrature formula\n    qf = QuadratureRule{Float64, EG}(3*get_polynomialorder(FEType_u, EG)-1)\n    weights::Vector{Float64} = qf.w\n    xref::Vector{Vector{Float64}} = qf.xref\n    nweights::Int = length(weights)\n    \n    ## FE basis evaluator\n    FEBasis_∇u = FEEvaluator(FESu, Gradient, qf)\n    ∇uvals = FEBasis_∇u.cvals\n    FEBasis_idu = FEEvaluator(FESu, Identity, qf)\n    iduvals = FEBasis_idu.cvals\n    FEBasis_idp = FEEvaluator(FESp, Identity, qf)\n    idpvals = FEBasis_idp.cvals\n\n    ## prepare automatic differentation of convection operator\n    function operator!(result, input)\n        # result = (u ⋅ ∇)u\n        result[1] = input[1]*input[3]+input[2]*input[4]\n        result[2] = input[1]*input[5]+input[2]*input[6]\n    end\n    result = Vector{Float64}(undef,2)\n    input = Vector{Float64}(undef,6)\n    tempV = zeros(Float64, 2)\n    Dresult = DiffResults.JacobianResult(result, input)\n    cfg = ForwardDiff.JacobianConfig(operator!, result, input, ForwardDiff.Chunk{6}())\n    jac = DiffResults.jacobian(Dresult)\n    value = DiffResults.value(Dresult)\n    \n   \n    ## ASSEMBLY LOOP\n    function barrier(EG, L2G::L2GTransformer, linear::Bool, nonlinear::Bool)\n        ## barrier function to avoid allocations caused by L2G\n        \n    \tndofs4cell_u::Int = get_ndofs(ON_CELLS, FEType_u, EG)\n    \tndofs4cell_p::Int = get_ndofs(ON_CELLS, FEType_p, EG)\n    \tAloc = zeros(Float64, ndofs4cell_u, ndofs4cell_u)\n    \tBloc = zeros(Float64, ndofs4cell_u, ndofs4cell_p)\n    \tdof_j::Int, dof_k::Int = 0, 0\n        fval::Vector{Float64} = zeros(Float64,2)\n        x::Vector{Float64} = zeros(Float64, 2)\n        \n        for cell = 1 : ncells\n            ## update FE basis evaluators\n            update_basis!(FEBasis_∇u, cell)\n            update_basis!(FEBasis_idu, cell)\n            update_basis!(FEBasis_idp, cell) \n    \n            ## assemble local stiffness matrix (symmetric)\n            if (linear)\n                for j = 1 : ndofs4cell_u, k = 1 : ndofs4cell_u\n                    temp = 0\n                    for qp = 1 : nweights\n                        temp += weights[qp] * dot(view(∇uvals,:,j,qp), view(∇uvals,:,k,qp))\n                    end\n                    Aloc[k,j] = μ * temp\n                end\n\n                ## assemble div-pressure coupling\n                for j = 1 : ndofs4cell_u, k = 1 : ndofs4cell_p\n                    temp = 0\n                    for qp = 1 : nweights\n                        temp -= weights[qp] * (∇uvals[1,j,qp] + ∇uvals[4,j,qp]) * \n                        idpvals[1,k,qp]\n                    end\n                    Bloc[j,k] = temp\n                end\n                Bloc .*= cellvolumes[cell]\n                \n                ## assemble right-hand side\n                update_trafo!(L2G, cell)\n                for j = 1 : ndofs4cell_u\n                    ## right-hand side\n                    temp = 0\n                    for qp = 1 : nweights\n                        ## get global x for quadrature point\n                        eval_trafo!(x, L2G, xref[qp])\n                        ## evaluate (f(x), v_j(x))\n                        f!(fval, x, teval)\n                        temp += weights[qp] * dot(view(iduvals,: , j, qp), fval)\n                    end\n                    ## write into global vector\n                    dof_j = CellDofs_u[j, cell]\n                    b[dof_j] += temp * cellvolumes[cell]\n                end\n            end\n\n            ## assemble nonlinear term\n            if (nonlinear)\n                for qp = 1 : nweights\n                    fill!(input,0)\n                    for j = 1 : ndofs4cell_u\n                        dof_j = CellDofs_u[j, cell]\n                        for d = 1 : 2\n                            input[d] += Solution[dof_j] * iduvals[d,j,qp]\n                        end\n                        for d = 1 : 4\n                            input[2+d] += Solution[dof_j] * ∇uvals[d,j,qp]\n                        end\n                    end\n                    \n                \t## evaluate jacobian\n                    ForwardDiff.chunk_mode_jacobian!(Dresult, operator!, result, input, cfg)\n                    \n                    # update matrix\n                    for j = 1 : ndofs4cell_u\n                        # multiply ansatz function with local jacobian\n                        fill!(tempV,0)\n                        for d = 1 : 2\n                            tempV[1] += jac[1,d] * iduvals[d,j,qp]\n                            tempV[2] += jac[2,d] * iduvals[d,j,qp]\n                        end\n                        for d = 1 : 4\n                            tempV[1] += jac[1,2+d] * ∇uvals[d,j,qp]\n                            tempV[2] += jac[2,2+d] * ∇uvals[d,j,qp]\n                        end\n    \n                        # multiply test function operator evaluation\n                        for k = 1 : ndofs4cell_u\n                            Aloc[k,j] += dot(tempV,view(iduvals,:,k,qp)) * weights[qp]\n                        end\n                    end \n    \n                    # update rhs\n                    mul!(tempV, jac, input)\n                    tempV .-= value\n                    for j = 1 : ndofs4cell_u\n                \t\tdof_j = CellDofs_u[j, cell]\n                \t\tb[dof_j] += dot(tempV, view(iduvals,:,j,qp)) * weights[qp] * cellvolumes[cell]\n                    end\n                end\n            end\n            \n            ## add local matrices to global matrix\n            Aloc .*= cellvolumes[cell]\n            for j = 1 : ndofs4cell_u\n                dof_j = CellDofs_u[j, cell]\n                for k = 1 : ndofs4cell_u\n                    dof_k = CellDofs_u[k, cell]\n                    rawupdateindex!(A, +, Aloc[j,k], dof_j, dof_k)\n                end\n                if (linear)\n                    for k = 1 : ndofs4cell_p\n                        dof_k = CellDofs_p[k, cell] + offset_p\n                        rawupdateindex!(A, +, Bloc[j,k], dof_j, dof_k) \n                        rawupdateindex!(A, +, Bloc[j,k], dof_k, dof_j)\n                    end\n                end\n            end\n            fill!(Aloc, 0)\n            fill!(Bloc, 0)\n        end\n    end\n\n    function update_system!(linear::Bool, nonlinear::Bool)\n        barrier(EG, L2G, linear, nonlinear)\n        flush!(A)\n    end\n    update_system!\nend
\n
prepare_assembly! (generic function with 2 methods)
\n
\n

Built with Julia 1.10.5 and

\nDiffResults 1.1.0
\nExtendableFEMBase 0.6.0
\nExtendableGrids 1.9.2
\nExtendableSparse 1.5.1
\nForwardDiff 0.10.36
\nGridVisualize 1.7.0
\nPlutoVista 1.0.1\n
\n\n","category":"page"},{"location":"plutostatichtml_examples/LowLevelNavierStokes/","page":"Low level Navier-Stokes","title":"Low level Navier-Stokes","text":"EditURL = \"https://github.com/chmerdon/ExtendableFEMBase.jl/blob/master/nothing\"","category":"page"},{"location":"module_examples/Example290_InterpolationBetweenMeshes/#290-:-Interpolation-Between-Meshes","page":"Example290_InterpolationBetweenMeshes","title":"290 : Interpolation Between Meshes","text":"","category":"section"},{"location":"module_examples/Example290_InterpolationBetweenMeshes/","page":"Example290_InterpolationBetweenMeshes","title":"Example290_InterpolationBetweenMeshes","text":"(source code)","category":"page"},{"location":"module_examples/Example290_InterpolationBetweenMeshes/","page":"Example290_InterpolationBetweenMeshes","title":"Example290_InterpolationBetweenMeshes","text":"This example demonstrates the interpolation between meshes feature. Here, we interpolate a function with the P2 element of a coarse triangulation and then interpolate this P2 function on two uniform refinements into some P1 function. Then, both finite element functions are plotted.","category":"page"},{"location":"module_examples/Example290_InterpolationBetweenMeshes/","page":"Example290_InterpolationBetweenMeshes","title":"Example290_InterpolationBetweenMeshes","text":"The computed solution for the default parameters looks like this:","category":"page"},{"location":"module_examples/Example290_InterpolationBetweenMeshes/","page":"Example290_InterpolationBetweenMeshes","title":"Example290_InterpolationBetweenMeshes","text":"(Image: )","category":"page"},{"location":"module_examples/Example290_InterpolationBetweenMeshes/","page":"Example290_InterpolationBetweenMeshes","title":"Example290_InterpolationBetweenMeshes","text":"module Example290_InterpolationBetweenMeshes\n\nusing ExtendableFEMBase\nusing ExtendableGrids\nusing GridVisualize\n\n# function to interpolate\nfunction u!(result, qpinfo)\n\tx = qpinfo.x\n\tresult[1] = sin(4 * pi * x[1]) * sin(4 * pi * x[2])\n\tresult[2] = cos(4 * pi * x[1]) * cos(4 * pi * x[2])\nend\n\n# everything is wrapped in a main function\nfunction main(; ν = 1e-3, nrefs = 4, Plotter = nothing)\n\n\t# generate two grids\n\txgrid1 = uniform_refine(grid_unitsquare(Triangle2D), nrefs)\n\txgrid2 = uniform_refine(xgrid1, 3; store_parents = true)\n\n\t@show xgrid1 xgrid2\n\n\t# set finite element types for the two grids\n\tFEType1 = H1Pk{2, 2, 2}\n\tFEType2 = H1Pk{2, 2, 1}\n\n\t# generate coressponding finite element spaces and FEVectors\n\tFES1 = FESpace{FEType1}(xgrid1)\n\tFES2 = FESpace{FEType2}(xgrid2)\n\tFEFunction1 = FEVector(FES1)\n\tFEFunction2 = FEVector(FES2)\n\n\t# interpolate function onto first grid\n\t@time interpolate!(FEFunction1[1], u!)\n\t@time interpolate!(FEFunction2[1], u!)\n\n\t# interpolate onto other grid\n\t@time lazy_interpolate!(FEFunction2[1], FEFunction1)\n\t@time lazy_interpolate!(FEFunction2[1], FEFunction1; use_cellparents = true)\n\n\t# plot\n\tp = GridVisualizer(; Plotter = Plotter, layout = (1, 2), clear = true, resolution = (800, 400))\n\tscalarplot!(p[1, 1], xgrid1, view(nodevalues(FEFunction1[1]), 1, :), levels = 11, title = \"u_h ($FEType1, coarse grid)\")\n\tscalarplot!(p[1, 2], xgrid2, view(nodevalues(FEFunction2[1]), 1, :), levels = 11, title = \"u_h ($FEType2, fine grid)\")\n\n\treturn p\nend\n\nfunction generateplots(dir = pwd(); Plotter = nothing, kwargs...)\n\tplt = main(; Plotter = Plotter, kwargs...)\n\tscene = GridVisualize.reveal(plt)\n\tGridVisualize.save(joinpath(dir, \"example290.png\"), scene; Plotter = Plotter)\nend\n\nend","category":"page"},{"location":"module_examples/Example290_InterpolationBetweenMeshes/","page":"Example290_InterpolationBetweenMeshes","title":"Example290_InterpolationBetweenMeshes","text":"","category":"page"},{"location":"module_examples/Example290_InterpolationBetweenMeshes/","page":"Example290_InterpolationBetweenMeshes","title":"Example290_InterpolationBetweenMeshes","text":"This page was generated using Literate.jl.","category":"page"},{"location":"fems/#Implemented-Finite-Elements","page":"List of Finite Elements","title":"Implemented Finite Elements","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"This page describes the finite element type-tree and lists all implemented finite elements.","category":"page"},{"location":"fems/#The-Finite-Element-Type-Tree","page":"List of Finite Elements","title":"The Finite Element Type-Tree","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"Finite elements are abstract type leaves in a type-tree. The complete tree looks like this:","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"AbstractFiniteElement\n├─ AbstractH1FiniteElement\n│ ├─ AbstractH1FiniteElementWithCoefficients\n│ │ ├─ H1P1TEB\n│ │ └─ H1BR\n│ ├─ H1CR\n│ ├─ H1MINI\n│ ├─ L2P0\n│ ├─ L2P1\n│ ├─ H1P1\n│ ├─ H1P2\n│ ├─ H1P2B\n│ ├─ H1P3\n│ ├─ H1Pk\n│ ├─ H1Q1\n│ └─ H1Q2\n├─ AbstractHcurlFiniteElement\n│ ├─ HCURLN0\n│ └─ HCURLN1\n└─ AbstractHdivFiniteElement\n ├─ HDIVBDM1\n ├─ HDIVBDM2\n ├─ HDIVRT0\n ├─ HDIVRT1\n ├─ HDIVRTk\n └─ HDIVRTkENRICH","category":"page"},{"location":"fems/#Remarks","page":"List of Finite Elements","title":"Remarks","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"each type depends on one/two or three parameters, the first one is always the number of components (ncomponents) that determines if the finite element is scalar- or veector-valued; some elements additionaly require the parameter edim <: Int if they are structurally different in different space dimensions; arbitrary order elements require a third parameter that determines the order\neach finite elements mainly comes with a set of basis functions in reference coordinates for each applicable AbstractElementGeometry and degrees of freedom maps for each mesh entity\nbroken finite elements are possible via the broken switch in the FESpace constructor\nthe type steers how the basis functions are transformed from local to global coordinates and how FunctionOperators are evaluated\ndepending on additional continuity properties of the element types more basis function sets are defined:\nAbstractH1FiniteElements additionally have evaluations of nonzero basisfunctions on faces/bfaces\nAbstractHdivFiniteElements additionally have evaluations of nonzero normalfluxes of basisfunctions on faces/bfaces\nAbstractHcurlFiniteElements additionally have evaluations of nonzero tangentfluxes of basisfunctions on edges/bedges\neach finite element has its own implemented standard interpolation interpolate! (see Finite Element Interpolations) that can be applied to a function with header function(result, qpinfo), below it is shortly described what this means for each finite element","category":"page"},{"location":"fems/#List-of-implemented-Finite-Elements","page":"List of Finite Elements","title":"List of implemented Finite Elements","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The following table lists all curently implemented finite elements and on which geometries they are available (in brackets a dofmap pattern for CellDofs is shown and the number of local degrees of freedom for a vector-valued realisation). Click on the FEType to find out more details.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"FEType Triangle2D Parallelogram2D Tetrahedron3D Parallelepiped3D\nAbstractH1FiniteElementWithCoefficients \nH1BR ✓ (N1f1, 9) ✓ (N1f1, 12) ✓ (N1f1, 16) \nH1P1TEB ✓ (N1f1, 9) ✓ (N1e1, 18) \nAbstractH1FiniteElement \nH1BUBBLE ✓ (I1, 2) ✓ (I1, 2) ✓ (I1, 3) \nH1CR ✓ (F1, 6) ✓ (F1, 8) ✓ (F1, 12) \nH1MINI ✓ (N1I1, 8) ✓ (N1I1, 10) ✓ (N1I1, 15) \nL2P0 ✓ (I1, 2) ✓ (I1, 2) ✓ (I1, 3) ✓ (I1, 3)\nL2P1 ✓ (I3, 6) ✓ (I3, 6) ✓ (I4, 12) ✓ (I4, 12)\nH1P1 ✓ (N1, 6) ✓ (N1, 12) \nH1P2 ✓ (N1F1, 12) ✓ (N1E1, 30) \nH1P2B ✓ (N1F1I1, 14) \nH1P3 ✓ (N1F2I1, 20) ✓ (N1E2F1, 60) \nH1Pk ✓ (order-dep) \nH1Q1 ✓ (N1, 6) ✓ (N1, 8) ✓ (N1, 12) ✓ (N1, 24)\nH1Q2 ✓ (N1F1, 12) ✓ (N1F1I1, 18) ✓ (N1E1, 30) \nAbstractHcurlFiniteElement \nHCURLN0 ✓ (f1, 3) ✓ (f1, 4) ✓ (e1, 6) \nHCURLN1 ✓ (f1, 6) \nAbstractHdivFiniteElement \nHDIVBDM1 ✓ (f2, 6) ✓ (f2, 8) ✓ (f3, 12) \nHDIVBDM2 ✓ (f3i3, 12) \nHDIVRT0 ✓ (f1, 3) ✓ (f1, 4) ✓ (f1, 4) ✓ (f1, 6)\nHDIVRT1 ✓ (f2i2, 8) ✓ (f3i3, 15) \nHDIVRTk ✓ (order-dep) \nHDIVRTkENRICH ✓ (order-dep) ✓ (order-dep) ","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"Note: the dofmap pattern describes the connection of the local degrees of freedom to entities of the grid and also hints to the continuity. Here, \"N\" or \"n\" means nodes, \"F\" or \"f\" means faces, \"E\" or \"e\" means edges and \"I\" means interior (dofs without any continuity across elements). Capital letters cause that every component has its own degree of freedom, while small letters signalize that only one dof is associated to the entity. As an example \"N1f1\" (for the Bernardi-Raugel element) means that at each node sits one dof per component and at each face sits a single dof. Usually finite elements that involve small letters are only defined vector-valued (i.e. the number of components has to match the element dimension), while finite elements that only involve capital letters are available for any number of components.","category":"page"},{"location":"fems/#H1-conforming-finite-elements","page":"List of Finite Elements","title":"H1-conforming finite elements","text":"","category":"section"},{"location":"fems/#P0-finite-element","page":"List of Finite Elements","title":"P0 finite element","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"Piecewise constant finite element that has one degree of freedom on each cell of the grid. (It is masked as a H1-conforming finite element, because it uses the same operator evaulations.)","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The interpolation of a given function into this space preserves the cell integrals.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"L2P0","category":"page"},{"location":"fems/#ExtendableFEMBase.L2P0","page":"List of Finite Elements","title":"ExtendableFEMBase.L2P0","text":"abstract type L2P0{ncomponents} <: AbstractH1FiniteElement where {ncomponents<:Int}\n\nPiecewise constant polynomials on cells.\n\nallowed ElementGeometries:\n\nany\n\n\n\n\n\n","category":"type"},{"location":"fems/#P1-finite-element","page":"List of Finite Elements","title":"P1 finite element","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The lowest-order Courant finite element that has a degree of freedom on each vertex of the grid. On simplices the basis functions coincide with the linear barycentric coordinates. Only the L2P1 element is also defined on quads.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The interpolation of a given function into this space performs point evaluations at the nodes.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"L2P1\nH1P1","category":"page"},{"location":"fems/#ExtendableFEMBase.L2P1","page":"List of Finite Elements","title":"ExtendableFEMBase.L2P1","text":"abstract type L2P1{ncomponents} <: AbstractH1FiniteElement where {ncomponents<:Int}\n\nDiscontinuous piecewise first-order linear polynomials.\n\nallowed ElementGeometries:\n\nany\n\n\n\n\n\n","category":"type"},{"location":"fems/#ExtendableFEMBase.H1P1","page":"List of Finite Elements","title":"ExtendableFEMBase.H1P1","text":"abstract type H1P1{ncomponents} <: AbstractH1FiniteElement where {ncomponents<:Int}\n\nContinuous piecewise first-order linear polynomials.\n\nallowed ElementGeometries:\n\nEdge1D\nTriangle2D\nTetrahedron3D\n\n\n\n\n\n","category":"type"},{"location":"fems/#Q1-finite-element","page":"List of Finite Elements","title":"Q1 finite element","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The lowest-order finite element that has a degree of freedom on each vertex of the grid. On simplices the basis functions coincide with the linear barycentric coordinates. This element is also defined on quads.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The interpolation of a given function into this space performs point evaluations at the nodes.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"H1Q1","category":"page"},{"location":"fems/#ExtendableFEMBase.H1Q1","page":"List of Finite Elements","title":"ExtendableFEMBase.H1Q1","text":"abstract type Q1P1{ncomponents} <: AbstractH1FiniteElement where {ncomponents<:Int}\n\nContinuous piecewise first-order polynomials on simplices and quads, can be used for mixed geometries.\n\nallowed ElementGeometries:\n\nEdge1D (P1 space)\nTriangle2D (P1 space)\nQuadrilateral2D (Q1 space)\nTetrahedron3D (P1 space)\nHexahedron3D (Q1 space)\n\n\n\n\n\n","category":"type"},{"location":"fems/#MINI-finite-element","page":"List of Finite Elements","title":"MINI finite element","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The mini finite element adds cell bubles to the P1 element that are e.g. beneficial to define inf-sup stable finite element pairs for the Stokes problem.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The interpolation of a given function into this space performs point evaluations at the nodes and preserves its cell integral.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"H1MINI","category":"page"},{"location":"fems/#ExtendableFEMBase.H1MINI","page":"List of Finite Elements","title":"ExtendableFEMBase.H1MINI","text":"abstract type H1MINI{ncomponents,edim} <: AbstractH1FiniteElement where {ncomponents<:Int,edim<:Int}\n\nMini finite element.\n\nallowed element geometries:\n\nTriangle2D (linear polynomials + cubic cell bubble)\nQuadrilateral2D (Q1 space + quartic cell bubble)\nTetrahedron3D (linear polynomials + cubic cell bubble)\n\n\n\n\n\n","category":"type"},{"location":"fems/#P1TEB-finite-element","page":"List of Finite Elements","title":"P1TEB finite element","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"This element adds tangent-weighted edge bubbles to the P1 finite element and therefore is only available as a vector-valued element.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The interpolation of a given function into this space performs point evaluations at the nodes and preserves face integrals of its tangential flux.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"H1P1TEB","category":"page"},{"location":"fems/#ExtendableFEMBase.H1P1TEB","page":"List of Finite Elements","title":"ExtendableFEMBase.H1P1TEB","text":"abstract type H1P1TEB{edim} <: AbstractH1FiniteElementWithCoefficients where {edim<:Int}\n\nvector-valued (ncomponents = edim) element that uses P1 functions + tangential-weighted edge bubbles as suggested by [Diening, L., Storn, J. & Tscherpel, T., \"Fortin operator for the Taylor–Hood element\", Numer. Math. 150, 671–689 (2022)]\n\n(is inf-sup stable for Stokes if paired with continuous P1 pressure space, less degrees of freedom than MINI)\n\nallowed ElementGeometries:\n\nTriangle2D\nTetrahedron3D\n\n\n\n\n\n","category":"type"},{"location":"fems/#Bernardi-Raugel-(BR)-finite-element","page":"List of Finite Elements","title":"Bernardi-Raugel (BR) finite element","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The Bernardi-Raugel adds normal-weighted face bubbles to the P1 finite element and therefore is only available as a vector-valued element.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The interpolation of a given function into this space performs point evaluations at the nodes and preserves face integrals of its normal flux.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"H1BR","category":"page"},{"location":"fems/#ExtendableFEMBase.H1BR","page":"List of Finite Elements","title":"ExtendableFEMBase.H1BR","text":"abstract type H1BR{edim} <: AbstractH1FiniteElementWithCoefficients where {edim<:Int}\n\nvector-valued (ncomponents = edim) Bernardi–Raugel element (first-order polynomials + normal-weighted face bubbles)\n\nallowed ElementGeometries:\n\nTriangle2D (piecewise linear + normal-weighted face bubbles)\nQuadrilateral2D (Q1 space + normal-weighted face bubbles)\nTetrahedron3D (piecewise linear + normal-weighted face bubbles)\n\n\n\n\n\n","category":"type"},{"location":"fems/#P2-finite-element","page":"List of Finite Elements","title":"P2 finite element","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The P2 finite element method on simplices equals quadratic polynomials. On the Triangle2D shape the degrees of freedom are associated with the three vertices and the three faces of the triangle. On the Tetrahedron3D shape the degrees of freedom are associated with the four verties and the six edges.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The interpolation of a given function into this space performs point evaluations at the nodes and preserves its face/edge integrals in 2D/3D.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"H1P2","category":"page"},{"location":"fems/#ExtendableFEMBase.H1P2","page":"List of Finite Elements","title":"ExtendableFEMBase.H1P2","text":"abstract type H1P2{ncomponents,edim} <: AbstractH1FiniteElement where {ncomponents<:Int,edim<:Int}\n\nContinuous piecewise second-order polynomials.\n\nallowed ElementGeometries:\n\nEdge1D\nTriangle2D\nTetrahedron3D\n\n\n\n\n\n","category":"type"},{"location":"fems/#Q2-finite-element","page":"List of Finite Elements","title":"Q2 finite element","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"A second order finite element. On simplices it equals the P2 finite element, and on Quadrilateral2D it has 9 degrees of freedom (vertices, faces and one cell bubble).","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The interpolation of a given function into this space performs point evaluations at the nodes and preserves lowest order face moments and (only on quads) also the cell integreal mean.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"H1Q2","category":"page"},{"location":"fems/#ExtendableFEMBase.H1Q2","page":"List of Finite Elements","title":"ExtendableFEMBase.H1Q2","text":"abstract type H1Q2{ncomponents,edim} <: AbstractH1FiniteElement where {ncomponents<:Int,edim<:Int}\n\nContinuous piecewise second-order polynomials on simplices and quads. Can be used with mixed geometries (in 2D).\n\nallowed ElementGeometries:\n\nEdge1D (P2 space)\nTriangle2D (P2 space)\nQuadrilateral2D (Q2 space with cell bubble)\nTetrahedron3D (P2 space)\n\n\n\n\n\n","category":"type"},{"location":"fems/#P2B-finite-element","page":"List of Finite Elements","title":"P2B finite element","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The P2B finite element adds additional cell bubles (in 2D and 3D) and face bubbles (only in 3D) that are e.g. used to define inf-sup stable finite element pairs for the Stokes problem.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The interpolation of a given function into this space performs point evaluations at the nodes and preserves its cell and face integrals in 2D and also edge integrals in 3D.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"H1P2B","category":"page"},{"location":"fems/#ExtendableFEMBase.H1P2B","page":"List of Finite Elements","title":"ExtendableFEMBase.H1P2B","text":"abstract type H1P2B{ncomponents,edim} <: AbstractH1FiniteElement where {ncomponents<:Int,edim<:Int}\n\nContinuous piecewise second-order polynomials.\n\nallowed ElementGeometries:\n\nTriangle2D\n\n\n\n\n\n","category":"type"},{"location":"fems/#P3-finite-element","page":"List of Finite Elements","title":"P3 finite element","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The P3 finite element method on simplices equals cubic polynomials. On the Triangle2D shape the degrees of freedom are associated with the three vertices, the three faces (double dof) of the triangle and the cell itself (one cell bubble).","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The interpolation of a given function into this space performs point evaluations at the nodes and preserves cell and face integrals in 2D.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"H1P3","category":"page"},{"location":"fems/#ExtendableFEMBase.H1P3","page":"List of Finite Elements","title":"ExtendableFEMBase.H1P3","text":"abstract type H1P3{ncomponents,edim} <: AbstractH1FiniteElement where {ncomponents<:Int,edim<:Int}\n\nContinuous piecewise third-order polynomials.\n\nallowed ElementGeometries:\n\nEdge1D\nTriangle2D\nTetrahedron3D\n\n\n\n\n\n","category":"type"},{"location":"fems/#Pk-finite-element-(experimental)","page":"List of Finite Elements","title":"Pk finite element (experimental)","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The Pk finite element method generically generates polynomials of abitrary order k on simplices (Edge1D, Triangle2D so far).","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The interpolation of a given function into this space performs point evaluations at the nodes and preserves cell and face integrals in 2D (moment order depends on the order and the element dimension).","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"H1Pk","category":"page"},{"location":"fems/#ExtendableFEMBase.H1Pk","page":"List of Finite Elements","title":"ExtendableFEMBase.H1Pk","text":"abstract type H1PK{ncomponents,edim,order} <: AbstractH1FiniteElement where {ncomponents<:Int,edim<:Int,order<:Int}\n\nContinuous piecewise polynomials of arbitrary order >= 1 with ncomponents components in edim space dimensions.\n\nallowed ElementGeometries:\n\nEdge1D\nTriangle2D\n\n\n\n\n\n","category":"type"},{"location":"fems/#Crouzeix-Raviart-(CR)-finite-element","page":"List of Finite Elements","title":"Crouzeix-Raviart (CR) finite element","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The Crouzeix-Raviart element associates one lowest-order function with each face. On the Triangle2D shape, the basis function of a face is one minus two times the nodal basis function of the opposite node. ","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"The interpolation of a given function into this space preserves its face integrals.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"H1CR","category":"page"},{"location":"fems/#ExtendableFEMBase.H1CR","page":"List of Finite Elements","title":"ExtendableFEMBase.H1CR","text":"abstract type H1CR{ncomponents} <: AbstractH1FiniteElement where {ncomponents<:Int}\n\nCrouzeix-Raviart element (only continuous at face centers).\n\nallowed ElementGeometries:\n\nTriangle2D (piecewise linear, similar to P1)\nQuadrilateral2D (similar to Q1 space)\nTetrahedron3D (piecewise linear, similar to P1)\n\n\n\n\n\n","category":"type"},{"location":"fems/#Hdiv-conforming-finite-elements","page":"List of Finite Elements","title":"Hdiv-conforming finite elements","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"These Raviart-Thomas and Brezzi-Douglas-Marini finite elements of lower order and their standard interpolations are available:","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"HDIVRT0\nHDIVBDM1\nHDIVRT1\nHDIVBDM2\nHDIVRTk\nHDIVRTkENRICH","category":"page"},{"location":"fems/#ExtendableFEMBase.HDIVRT0","page":"List of Finite Elements","title":"ExtendableFEMBase.HDIVRT0","text":"abstract type HDIVRT0{edim} <: AbstractHdivFiniteElement where {edim<:Int}\n\nHdiv-conforming vector-valued (ncomponents = edim) lowest-order Raviart-Thomas space.\n\nallowed ElementGeometries:\n\nTriangle2D\nQuadrilateral2D\nTetrahedron3D\nHexahedron3D\n\n\n\n\n\n","category":"type"},{"location":"fems/#ExtendableFEMBase.HDIVBDM1","page":"List of Finite Elements","title":"ExtendableFEMBase.HDIVBDM1","text":"abstract type HDIVBDM1{edim} <: AbstractHdivFiniteElement where {edim<:Int}\n\nHdiv-conforming vector-valued (ncomponents = edim) lowest-order Brezzi-Douglas-Marini space\n\nallowed ElementGeometries:\n\nTriangle2D\nQuadrilateral2D\nTetrahedron3D\n\n\n\n\n\n","category":"type"},{"location":"fems/#ExtendableFEMBase.HDIVRT1","page":"List of Finite Elements","title":"ExtendableFEMBase.HDIVRT1","text":"abstract type HDIVRT1{edim} <: AbstractHdivFiniteElement where {edim<:Int}\n\nHdiv-conforming vector-valued (ncomponents = edim) Raviart-Thomas space of order 1.\n\nallowed ElementGeometries:\n\nTriangle2D\nTetrahedron3D\n\n\n\n\n\n","category":"type"},{"location":"fems/#ExtendableFEMBase.HDIVBDM2","page":"List of Finite Elements","title":"ExtendableFEMBase.HDIVBDM2","text":"abstract type HDIVBDM2{edim} <: AbstractHdivFiniteElement where {edim<:Int}\n\nHdiv-conforming vector-valued (ncomponents = edim) Brezzi-Douglas-Marini space of order 2\n\nallowed ElementGeometries:\n\nTriangle2D\n\n\n\n\n\n","category":"type"},{"location":"fems/#ExtendableFEMBase.HDIVRTk","page":"List of Finite Elements","title":"ExtendableFEMBase.HDIVRTk","text":"abstract type HDIVRTk{edim, order} <: AbstractHdivFiniteElement where {edim<:Int}\n\nHdiv-conforming vector-valued (ncomponents = edim) Raviart-Thomas space of arbitrary order.\n\nallowed ElementGeometries:\n\nTriangle2D\n\n\n\n\n\n","category":"type"},{"location":"fems/#ExtendableFEMBase.HDIVRTkENRICH","page":"List of Finite Elements","title":"ExtendableFEMBase.HDIVRTkENRICH","text":"abstract type HDIVRTkENRICH{k,edim} <: AbstractHdivFiniteElement where {edim<:Int}\n\nInternal (normal-zero) Hdiv-conforming vector-valued (ncomponents = edim) Raviart-Thomas space of order k ≥ 1 with the additional orthogonality property that their divergences are L2-orthogonal on P_{k-edim+1}. Example: HDIVRTkENRICH{1,2} gives the edim interior RT1 bubbles (= normal-trace-free) on a triangle, their divergences have integral mean zero; HDIVRTkENRICH{2,2} gives three RT2 bubbles on a triangle whose divergences are L2-orthogonal onto all P1 functions. The maximal order for k is 4 on a Triangle2D (edim = 2) and 3 on Tetrahedron3D (edim = 3). These spaces have no approximation power on their own, but can be used as enrichment spaces in divergence-free schemes for incompressible Stokes problems.\n\nallowed ElementGeometries:\n\nTriangle2D\nTetrahedron3D\n\n\n\n\n\n","category":"type"},{"location":"fems/#Hcurl-conforming-finite-elements","page":"List of Finite Elements","title":"Hcurl-conforming finite elements","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"So far only the lowest order Nedelec element is available in 2D and 3D. On Triangle2D it has one degree of freedom for each face (i.e. the rotated RT0 element), on Tetrahedron3D it has one degree of freedom associated to each of the six edges.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"Its standard interpolation of a given functions preserves its tangential face/edge integrals.","category":"page"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"HCURLN0\nHCURLN1","category":"page"},{"location":"fems/#ExtendableFEMBase.HCURLN0","page":"List of Finite Elements","title":"ExtendableFEMBase.HCURLN0","text":"abstract type HCURLN0{edim} <: AbstractHcurlFiniteElement where {edim<:Int}\n\nHcurl-conforming vector-valued (ncomponents = edim) lowest-order Nedelec space of first kind.\n\nallowed ElementGeometries:\n\nTriangle2D\nQuadrilateral2D\nTetrahedron3D\n\n\n\n\n\n","category":"type"},{"location":"fems/#ExtendableFEMBase.HCURLN1","page":"List of Finite Elements","title":"ExtendableFEMBase.HCURLN1","text":"abstract type HCURLN1{edim} <: AbstractHcurlFiniteElement where {edim<:Int}\n\nHcurl-conforming vector-valued (ncomponents = edim) Nedelec space of first kind and order 1.\n\nallowed ElementGeometries:\n\nTriangle2D\n\n\n\n\n\n","category":"type"},{"location":"fems/#Incomplete-finite-elements-without-approximation-power","page":"List of Finite Elements","title":"Incomplete finite elements without approximation power","text":"","category":"section"},{"location":"fems/","page":"List of Finite Elements","title":"List of Finite Elements","text":"H1BUBBLE","category":"page"},{"location":"fems/#ExtendableFEMBase.H1BUBBLE","page":"List of Finite Elements","title":"ExtendableFEMBase.H1BUBBLE","text":"abstract type H1BUBBLE{ncomponents} <: AbstractH1FiniteElement where {ncomponents<:Int}\n\nPiecewise bubbles (=zero at boundary)\n\nallowed element geometries:\n\nEdge1D (one quadratic bubble)\nTriangle2D (one cubic bubble)\nQuadrilateral2D (one quartic bubble)\nTetrahedron3D (one cubic bubble)\n\n\n\n\n\n","category":"type"},{"location":"notebooks_intro/#About-the-notebooks","page":"About the notebooks","title":"About the notebooks","text":"","category":"section"},{"location":"notebooks_intro/","page":"About the notebooks","title":"About the notebooks","text":"This sections contains Pluto.jl notebooks.","category":"page"},{"location":"notebooks_intro/","page":"About the notebooks","title":"About the notebooks","text":"Plese note, that in the html version, interactive elements like sliders are disabled. Navigation via the table of contents does work, though.","category":"page"},{"location":"module_examples/Example205_LowLevelSpaceTimePoisson/#205-:-Space-Time-FEM-for-Poisson-Problem","page":"Example205_LowLevelSpaceTimePoisson","title":"205 : Space-Time FEM for Poisson Problem","text":"","category":"section"},{"location":"module_examples/Example205_LowLevelSpaceTimePoisson/","page":"Example205_LowLevelSpaceTimePoisson","title":"Example205_LowLevelSpaceTimePoisson","text":"(source code)","category":"page"},{"location":"module_examples/Example205_LowLevelSpaceTimePoisson/","page":"Example205_LowLevelSpaceTimePoisson","title":"Example205_LowLevelSpaceTimePoisson","text":"This example computes the solution u of the two-dimensional heat equation","category":"page"},{"location":"module_examples/Example205_LowLevelSpaceTimePoisson/","page":"Example205_LowLevelSpaceTimePoisson","title":"Example205_LowLevelSpaceTimePoisson","text":"beginaligned\nu_t - Delta u = f quad textin Omega\nendaligned","category":"page"},{"location":"module_examples/Example205_LowLevelSpaceTimePoisson/","page":"Example205_LowLevelSpaceTimePoisson","title":"Example205_LowLevelSpaceTimePoisson","text":"with a (possibly space- and time-depepdent) right-hand side f and homogeneous Dirichlet boundary and initial conditions on the unit square domain Omega on a given grid with space-time finite element methods based on tensorized ansatz functions.","category":"page"},{"location":"module_examples/Example205_LowLevelSpaceTimePoisson/","page":"Example205_LowLevelSpaceTimePoisson","title":"Example205_LowLevelSpaceTimePoisson","text":"(Image: )","category":"page"},{"location":"module_examples/Example205_LowLevelSpaceTimePoisson/","page":"Example205_LowLevelSpaceTimePoisson","title":"Example205_LowLevelSpaceTimePoisson","text":"module Example205_LowLevelSpaceTimePoisson\n\nusing ExtendableFEMBase\nusing ExtendableGrids\nusing ExtendableSparse\nusing GridVisualize\nusing UnicodePlots\nusing Test #\n\n# data for Poisson problem\nconst μ = (t) -> 1e-1*t + 1*max(0,(1-2*t))\nconst f = (x, t) -> sin(3*pi*x[1])*4*t - cos(3*pi*x[2])*4*(1-t)\n\nfunction main(; dt = 0.01, Tfinal = 1, level = 5, order = 1, Plotter = nothing, produce_movie = false )\n\n\t# Finite element type\n\tFEType_time = H1Pk{1, 1, order}\n\tFEType_space = H1Pk{1, 2, order}\n\n # time grid\n T = LinRange(0, Tfinal, round(Int, Tfinal/dt + 1))\n grid_time = simplexgrid(T)\n\n # space grid\n\tX = LinRange(0, 1, 2^level + 1)\n\tgrid_space = simplexgrid(X, X)\n\n # FESpaces for time and space\n FES_time = FESpace{FEType_time}(grid_time)\n FES_space = FESpace{FEType_space}(grid_space)\n\n\t# solve\n sol = solve_poisson_lowlevel(FES_time, FES_space, μ, f)\n\n\t# visualize\n\tif produce_movie\n\t\t@info \"Producing movie...\"\n\t\tvis=GridVisualizer(Plotter=Plotter)\n\t\tmovie(vis, file=\"example205_video.mp4\") do vis\n\t\t\tfor tj = 2 : length(T)\n\t\t\t\tt = T[tj]\n\t\t\t\tfirst = (tj-1)*FES_space.ndofs+1\n\t\t\t\tlast = tj*FES_space.ndofs\n\t\t\t\tscalarplot!(vis, grid_space, view(sol,first:last), title = \"t = $(Float16(t))\")\n\t\t\t\treveal(vis)\n\t\t\tend\n\t\tend\n\t\treturn sol, vis\n\telse\n\t\t@info \"Plotting at five times...\"\n\t\tplot_timesteps = [2,round(Int,length(T)/4+0.25),round(Int,length(T)/2+0.5),round(Int,length(T)-length(T)/4),FES_time.ndofs]\n\t\tplt = GridVisualizer(; Plotter = Plotter, layout = (1, length(plot_timesteps)), clear = true, resolution = (200*length(plot_timesteps), 200))\n\t\tfor tj = 1 : length(plot_timesteps)\n\t\t\tt = plot_timesteps[tj]\n\t\t\tfirst = (t-1)*FES_space.ndofs+1\n\t\t\tlast = t*FES_space.ndofs\n\t\t\tscalarplot!(plt[1,tj], grid_space, view(sol,first:last), title = \"t = $(T[t])\")\n\t\tend\n\t\treturn sol, plt\n\tend\n\nend\n\n\nfunction solve_poisson_lowlevel(FES_time, FES_space, μ, f)\n ndofs_time = FES_time.ndofs\n ndofs_space = FES_space.ndofs\n ndofs_total = ndofs_time * ndofs_space\n\tsol = zeros(Float64, ndofs_total)\n\n\tA = ExtendableSparseMatrix{Float64, Int64}(ndofs_total, ndofs_total)\n\tb = zeros(Float64, ndofs_total)\n\n\tprintln(\"Assembling...\")\n\ttime_assembly = @elapsed @time begin\n\t\tloop_allocations = assemble!(A, b, FES_time, FES_space, f, μ)\n\n\t\t# fix homogeneous boundary dofs\n\t\tbdofs = boundarydofs(FES_space)\n\t\tfor sdof in bdofs\n\t\t\tfor dof_t = 1 : ndofs_time\n\t\t\t\tdof = (dof_t-1)*ndofs_space + sdof\n\t\t\t\tA[dof, dof] = 1e60\n\t\t\t\tb[dof] = 0\n\t\t\tend\n\t\tend\n\n # fix initial value by zero\n\t\tfor j=1:ndofs_space\n\t\t\tA[j,j] = 1e60\n\t\t\tb[j] = 0\n\t\tend\n\t\tExtendableSparse.flush!(A)\n\tend\n\n @info \".... spy plot of system matrix:\\n$(UnicodePlots.spy(sparse(A.cscmatrix)))\"\n\n\t# solve\n\tprintln(\"Solving linear system...\")\n\ttime_solve = @elapsed @time copyto!(sol, A \\ b)\n\n\t# compute linear residual\n @show norm(A*sol - b)\n\n\treturn sol\nend\n\nfunction assemble!(A::ExtendableSparseMatrix, b::Vector, FES_time, FES_space, f, μ = 1)\n\n\t# get space and time grids\n\tgrid_time = FES_time.xgrid\n\tgrid_space = FES_space.xgrid\n\n\t# get number of degrees of freedom\n ndofs_time = FES_time.ndofs\n ndofs_space = FES_space.ndofs\n\n\t# get local to global maps\n\tEG_time = grid_time[UniqueCellGeometries][1]\n\tEG_space = grid_space[UniqueCellGeometries][1]\n\tL2G_time = L2GTransformer(EG_time, grid_time, ON_CELLS)\n\tL2G_space = L2GTransformer(EG_space, grid_space, ON_CELLS)\n\n\t# get finite element types\n\tFEType_time = eltype(FES_time)\n\tFEType_space = eltype(FES_space)\n\n\t# quadrature formula in space\n\tqf_space = QuadratureRule{Float64, EG_space}(2 * (get_polynomialorder(FEType_space, EG_space) - 1))\n\tweights_space::Vector{Float64} = qf_space.w\n\txref_space::Vector{Vector{Float64}} = qf_space.xref\n\tnweights_space::Int = length(weights_space)\n\tcellvolumes_space = grid_space[CellVolumes]\n\n\t# quadrature formula in time\n\tqf_time = QuadratureRule{Float64, EG_time}(2 * (get_polynomialorder(FEType_time, EG_time) - 1))\n\tweights_time::Vector{Float64} = qf_time.w\n\txref_time::Vector{Vector{Float64}} = qf_time.xref\n\tnweights_time::Int = length(weights_time)\n\tcellvolumes_time = grid_time[CellVolumes]\n\n\t# FE basis evaluators and dofmap for space elements\n\tFEBasis_space_∇ = FEEvaluator(FES_space, Gradient, qf_space)\n\t∇vals_space = FEBasis_space_∇.cvals\n\tFEBasis_space_id = FEEvaluator(FES_space, Identity, qf_space)\n\tidvals_space = FEBasis_space_id.cvals\n\tcelldofs_space = FES_space[ExtendableFEMBase.CellDofs]\n\n\t# FE basis evaluators and dofmap for time elements\n\tFEBasis_time_∇ = FEEvaluator(FES_time, Gradient, qf_time)\n\t∇vals_time = FEBasis_time_∇.cvals\n\tFEBasis_time_id = FEEvaluator(FES_time, Identity, qf_time)\n\tidvals_time = FEBasis_time_id.cvals\n\tcelldofs_time = FES_time[ExtendableFEMBase.CellDofs]\n\n\t# ASSEMBLY LOOP\n\tloop_allocations = 0\n\tfunction barrier(EG_time, EG_space, L2G_time::L2GTransformer, L2G_space::L2GTransformer)\n\t\t# barrier function to avoid allocations by type dispatch\n\n\t\tndofs4cell_time::Int = get_ndofs(ON_CELLS, FEType_time, EG_time)\n\t\tndofs4cell_space::Int = get_ndofs(ON_CELLS, FEType_space, EG_space)\n\t\tAloc = zeros(Float64, ndofs4cell_space, ndofs4cell_space)\n Mloc = zeros(Float64, ndofs4cell_time, ndofs4cell_time)\n\t\tncells_space::Int = num_cells(grid_space)\n ncells_time::Int = num_cells(grid_time)\n\t\tx::Vector{Float64} = zeros(Float64, 2)\n\t\tt::Vector{Float64} = zeros(Float64, 1)\n\n # assemble Laplacian\n\t\tloop_allocations += @allocated for cell ∈ 1:ncells_space\n\t\t\t# update FE basis evaluators for space\n\t\t\tFEBasis_space_∇.citem[] = cell\n\t\t\tupdate_basis!(FEBasis_space_∇)\n\n\t\t\t# assemble local stiffness matrix in space\n\t\t\tfor j ∈ 1:ndofs4cell_space, k ∈ 1:ndofs4cell_space\n\t\t\t\ttemp = 0\n\t\t\t\tfor qp ∈ 1:nweights_space\n\t\t\t\t\ttemp += weights_space[qp] * dot(view(∇vals_space, :, j, qp), view(∇vals_space, :, k, qp))\n\t\t\t\tend\n\t\t\t\tAloc[j, k] = temp\n\t\t\tend\n\t\t\tAloc .*= cellvolumes_space[cell]\n\n\t\t\t# add local matrix to global matrix\n for time_cell ∈ 1:ncells_time\n\t\t\t\tupdate_trafo!(L2G_time, time_cell)\n for jT ∈ 1:ndofs4cell_time, kT ∈ 1:ndofs4cell_time\n dofTj = celldofs_time[jT, time_cell]\n dofTk = celldofs_time[kT, time_cell]\n\t\t\t\t for qpT ∈ 1:nweights_time\n\t\t\t\t\t\t# evaluate time coordinate and μ\n\t\t\t\t\t\teval_trafo!(t, L2G_time, xref_time[qpT])\n factor = μ(t[1]) * weights_time[qpT] * idvals_time[1,jT,qpT] * idvals_time[1,kT,qpT] * cellvolumes_time[time_cell]\n for j ∈ 1:ndofs4cell_space\n dof_j = celldofs_space[j, cell] + (dofTj - 1) * ndofs_space\n for k ∈ 1:ndofs4cell_space\n dof_k = celldofs_space[k, cell] + (dofTk - 1) * ndofs_space\n if abs(Aloc[j, k]) > 1e-15\n # write into sparse matrix, only lines with allocations\n rawupdateindex!(A, +, Aloc[j, k]*factor, dof_j, dof_k)\n end\n end\n end\n end\n end\n end\n\t\t\tfill!(Aloc, 0)\n\n\t\t\t# assemble right-hand side\n\t\t\tupdate_trafo!(L2G_space, cell)\n\t\t\tfor qp ∈ 1:nweights_space\n\t\t\t\t# evaluate coordinates of quadrature point in space\n\t\t\t\teval_trafo!(x, L2G_space, xref_space[qp])\n for time_cell ∈ 1:ncells_time\n\t\t\t\t\tupdate_trafo!(L2G_time, time_cell)\n\t\t\t\t\tfor qpT ∈ 1:nweights_time\n\t\t\t\t\t\t# evaluate time coordinate\n\t\t\t\t\t\teval_trafo!(t, L2G_time, xref_time[qpT])\n\n\t\t\t\t\t\t# evaluate right-hand side in x and t\n\t\t\t\t\t\tfval = f(x, t[1])\n\n\t\t\t\t\t\t# multiply with test function and add to right-hand side\n\t\t\t\t\t\tfor j ∈ 1:ndofs4cell_space\n\t\t\t\t\t\t\ttemp = weights_time[qpT] * weights_space[qp] * idvals_space[1, j, qp] * fval * cellvolumes_space[cell] * cellvolumes_time[time_cell]\n\n\t\t\t\t\t\t\t# write into global vector\n\t\t\t\t\t\t\tfor jT ∈ 1:ndofs4cell_time\n\t\t\t\t\t\t\t\tdof_j = celldofs_space[j, cell] + (celldofs_time[jT, time_cell] - 1) * ndofs_space\n\t\t\t\t\t\t\t\tb[dof_j] += temp * idvals_time[1, jT, qpT]\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n end\n\t\t\tend\n\t\tend\n\n # assemble time derivative\n\t\tloop_allocations += @allocated for time_cell ∈ 1:ncells_time\n\t\t\t# update FE basis evaluators for time derivative\n\t\t\tFEBasis_time_∇.citem[] = time_cell\n\t\t\tupdate_basis!(FEBasis_time_∇)\n\n\t\t\t# assemble local convection term in time\n\t\t\tfor j ∈ 1:ndofs4cell_time, k ∈ 1:ndofs4cell_time\n\t\t\t\ttemp = 0\n\t\t\t\tfor qpT ∈ 1:nweights_time\n\t\t\t\t\ttemp += weights_time[qpT] * dot(view(∇vals_time, :, j, qpT), view(∇vals_time, :, k, qpT))\n\t\t\t\tend\n\t\t\t\tMloc[j, k] = temp\n\t\t\tend\n\t\t\tMloc .*= cellvolumes_time[time_cell]\n\n\t\t\t# add local matrix to global matrix\n for cell ∈ 1:ncells_space\n for jX ∈ 1:ndofs4cell_space, kX ∈ 1:ndofs4cell_space\n dofXj = celldofs_space[jX, cell]\n dofXk = celldofs_space[kX, cell]\n\t\t\t\t for qpX ∈ 1:nweights_space\n factor = weights_space[qpX] * idvals_space[1, jX, qpX] * idvals_space[1, kX, qpX] * cellvolumes_space[cell]\n for j ∈ 1:ndofs4cell_time\n dof_j = dofXj + (celldofs_time[j, time_cell] - 1) * ndofs_space\n for k ∈ 1:ndofs4cell_time\n dof_k = dofXk + (celldofs_time[k, time_cell] - 1) * ndofs_space\n if abs(Mloc[j, k]) > 1e-15\n # write into sparse matrix, only lines with allocations\n rawupdateindex!(A, +, Mloc[j, k]*factor, dof_j, dof_k)\n end\n end\n end\n end\n end\n end\n\t\t\tfill!(Mloc, 0)\n\t\tend\n\tend\n\tbarrier(EG_time, EG_space, L2G_time, L2G_space)\n\tflush!(A)\n\treturn loop_allocations\nend\n\nfunction generateplots(dir = pwd(); Plotter = nothing, kwargs...)\n\t~, plt = main(; Plotter = Plotter, kwargs...)\n\tscene = GridVisualize.reveal(plt)\n\tGridVisualize.save(joinpath(dir, \"example205.png\"), scene; Plotter = Plotter)\nend\n\nend #module","category":"page"},{"location":"module_examples/Example205_LowLevelSpaceTimePoisson/","page":"Example205_LowLevelSpaceTimePoisson","title":"Example205_LowLevelSpaceTimePoisson","text":"","category":"page"},{"location":"module_examples/Example205_LowLevelSpaceTimePoisson/","page":"Example205_LowLevelSpaceTimePoisson","title":"Example205_LowLevelSpaceTimePoisson","text":"This page was generated using Literate.jl.","category":"page"},{"location":"","page":"Home","title":"Home","text":"(Image: Build status) (Image: ) (Image: ) (Image: DOI)","category":"page"},{"location":"#ExtendableFEMBase.jl","page":"Home","title":"ExtendableFEMBase.jl","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"This package provides some low level structures like finite element spaces, interpolors, matrices and vectors to assemble custom finite element solvers based on ExtendableGrids.jl infrastructure.","category":"page"},{"location":"#Dependencies-on-other-Julia-packages","page":"Home","title":"Dependencies on other Julia packages","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"ExtendableGrids.jl\nExtendableSparse.jl\nForwardDiff.jl\nDiffResults.jl\nUnicodePlots.jl\nDocStringExtensions.jl","category":"page"}] } diff --git a/dev/segmentintegrators/index.html b/dev/segmentintegrators/index.html index 0e8b7b9..82eabec 100644 --- a/dev/segmentintegrators/index.html +++ b/dev/segmentintegrators/index.html @@ -1,16 +1,16 @@ -SegmentIntegrator · ExtendableFEMBase.jl

SegmentIntegrator

Segment integrators allow to integrate a finite element function (FEVector) along arbitrary lines through mesh cells.

ExtendableFEMBase.SegmentIntegratorMethod
function SegmentIntegrator(
+SegmentIntegrator · ExtendableFEMBase.jl

SegmentIntegrator

Segment integrators allow to integrate a finite element function (FEVector) along arbitrary lines through mesh cells.

ExtendableFEMBase.SegmentIntegratorMethod
function SegmentIntegrator(
 	EG::ElementGeometry,
 	[kernel!::Function],
 	oa_args::Array{<:Tuple{<:Any, DataType},1};
-	kwargs...)

Generates an SegmentIntegrator that can intgrate over segments of the specified geometry EG. To do so, it evaluates, at each quadrature point, the specified operator evaluations, postprocesses them with the kernel function (if provided) and accumulates the results with the quadrature weights. If no kernel is given, the arguments are integrated directly. If a kernel is provided it has be conform to the interface

kernel!(result, eval_args, qpinfo)

where qpinfo allows to access information at the current quadrature point. Additionally the length of the result needs to be specified via the kwargs.

Evaluation can be triggered via the integrate_segment! function after an initialize!

Operator evaluations are tuples that pair a tag (to identify an unknown or the position in the vector) with a FunctionOperator.

Keyword arguments:

  • factor: factor that should be multiplied during assembly. Default: 1

  • resultdim: dimension of result field (default = length of arguments). Default: 0

  • matrix_mode: integrator integrates basis functions of FEspace seperately to assembly a matrix that maps solution to segment integrations (requires that kernel is linear). Default: false

  • name: name for operator used in printouts. Default: ''SegmentIntegrator''

  • params: array of parameters that should be made available in qpinfo argument of kernel function. Default: nothing

  • quadorder: quadrature order. Default: ''auto''

  • bonus_quadorder: additional quadrature order added to quadorder. Default: 0

  • entrytolerance: threshold to add entry to sparse matrix (only in matrixmode). Default: 0

  • verbosity: verbosity level. Default: 0

source
ExtendableFEMBase.initialize!Method
function initialize!(
+	kwargs...)

Generates an SegmentIntegrator that can intgrate over segments of the specified geometry EG. To do so, it evaluates, at each quadrature point, the specified operator evaluations, postprocesses them with the kernel function (if provided) and accumulates the results with the quadrature weights. If no kernel is given, the arguments are integrated directly. If a kernel is provided it has be conform to the interface

kernel!(result, eval_args, qpinfo)

where qpinfo allows to access information at the current quadrature point. Additionally the length of the result needs to be specified via the kwargs.

Evaluation can be triggered via the integrate_segment! function after an initialize!

Operator evaluations are tuples that pair a tag (to identify an unknown or the position in the vector) with a FunctionOperator.

Keyword arguments:

  • factor: factor that should be multiplied during assembly. Default: 1

  • resultdim: dimension of result field (default = length of arguments). Default: 0

  • matrix_mode: integrator integrates basis functions of FEspace seperately to assembly a matrix that maps solution to segment integrations (requires that kernel is linear). Default: false

  • name: name for operator used in printouts. Default: ''SegmentIntegrator''

  • params: array of parameters that should be made available in qpinfo argument of kernel function. Default: nothing

  • quadorder: quadrature order. Default: ''auto''

  • bonus_quadorder: additional quadrature order added to quadorder. Default: 0

  • entrytolerance: threshold to add entry to sparse matrix (only in matrixmode). Default: 0

  • verbosity: verbosity level. Default: 0

source
ExtendableFEMBase.initialize!Method
function initialize!(
 	O::SegmentIntegrator{T, UT},
 	sol;
 	time = 0,
-	kwargs...)

Initializes the SegmentIntegrator for the specified solution.

source
ExtendableFEMBase.integrate_segment!Method
function integrate_segment!(
 	result::Array{T,1},
 	SI::SegmentIntegrator,
 	w::Array{Array{T,1},1},
 	b::Array{Array{T,1},1},
 	item
-	) where {T}

Integrate a segment with world coordinates w and barycentric coordinates b in the cell with the given item number.

source
+ ) where {T}

Integrate a segment with world coordinates w and barycentric coordinates b in the cell with the given item number.

source