diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index aeadcf1123..bf90cbb122 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.11.1","generation_timestamp":"2024-12-02T13:14:28","documenter_version":"1.7.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.11.2","generation_timestamp":"2024-12-06T15:41:37","documenter_version":"1.7.0"}} \ No newline at end of file diff --git a/dev/changelog/index.html b/dev/changelog/index.html index 1b935ae272..68281debc7 100644 --- a/dev/changelog/index.html +++ b/dev/changelog/index.html @@ -111,4 +111,4 @@ + K = allocate_matrix(dh, ch)

Added

Changed

Deprecated

Removed

Fixed

Other improvements

v0.3.14 - 2023-04-03

Added

Other improvements

Internal changes

Changes listed here should not affect regular usage, but listed here in case you have been poking into Ferrite internals:

v0.3.13 - 2023-03-23

Added

Fixed

Other improvements

Internal changes

v0.3.12 - 2023-02-28

Added

Fixed

Other improvements

v0.3.11 - 2023-01-17

Added

Changed

Deprecated

Fixed

Other improvements

v0.3.10 - 2022-12-11

Added

Changed

Fixed

Other improvements

v0.3.9 - 2022-10-19

Added

Changed

v0.3.8 - 2022-10-05

Added

Fixed

Other improvements

v0.3.7 - 2022-07-05

Fixed

Other improvements

v0.3.6 - 2022-06-30

Fixed

Other improvements

v0.3.5 - 2022-05-30

Added

Fixed

v0.3.4 - 2022-02-25

Added

Changed

v0.3.3 - 2022-02-04

Changed

v0.3.2 - 2022-01-18

Added

Changed

Fixed

+ end

Fixed

Other improvements

v0.3.14 - 2023-04-03

Added

Other improvements

Internal changes

Changes listed here should not affect regular usage, but listed here in case you have been poking into Ferrite internals:

v0.3.13 - 2023-03-23

Added

Fixed

Other improvements

Internal changes

v0.3.12 - 2023-02-28

Added

Fixed

Other improvements

v0.3.11 - 2023-01-17

Added

Changed

Deprecated

Fixed

Other improvements

v0.3.10 - 2022-12-11

Added

Changed

Fixed

Other improvements

v0.3.9 - 2022-10-19

Added

Changed

v0.3.8 - 2022-10-05

Added

Fixed

Other improvements

v0.3.7 - 2022-07-05

Fixed

Other improvements

v0.3.6 - 2022-06-30

Fixed

Other improvements

v0.3.5 - 2022-05-30

Added

Fixed

v0.3.4 - 2022-02-25

Added

Changed

v0.3.3 - 2022-02-04

Changed

v0.3.2 - 2022-01-18

Added

Changed

Fixed

diff --git a/dev/cited-literature/index.html b/dev/cited-literature/index.html index 9df98a17c7..6afce1e8f1 100644 --- a/dev/cited-literature/index.html +++ b/dev/cited-literature/index.html @@ -1,2 +1,2 @@ -Cited literature · Ferrite.jl

Cited literature

[1]
G. A. Holzapfel. Nonlinear Solid Mechanics: A Continuum Approach for Engineering (Wiley, Chichester ; New York, 2000).
[2]
[3]
[4]
D. N. Arnold, F. Brezzi, B. Cockburn and L. D. Marini. Unified Analysis of Discontinuous Galerkin Methods for Elliptic Problems. SIAM Journal on Numerical Analysis 39, 1749–1779 (2002). Accessed on Dec 20, 2023.
[5]
[6]
[7]
[8]
F. D. Witherden and P. E. Vincent. On the identification of symmetric quadrature rules for finite element methods. Computers & Mathematics with Applications 69, 1232–1241 (2015).
[9]
M. Crouzeix and P.-A. Raviart. Conforming and nonconforming finite element methods for solving the stationary Stokes equations I. Revue française d'automatique informatique recherche opérationnelle. Mathématique 7, 33–75 (1973).
[10]
R. Rannacher and S. Turek. Simple nonconforming quadrilateral Stokes element. Numerical Methods for Partial Differential Equations 8, 97–111 (1992).
[11]
[12]
M. Cenanovic. Finite element methods for surface problems. Ph.D. Thesis, Jönköping University, School of Engineering (2017).
[13]
[14]
[15]
+Cited literature · Ferrite.jl

Cited literature

[1]
G. A. Holzapfel. Nonlinear Solid Mechanics: A Continuum Approach for Engineering (Wiley, Chichester ; New York, 2000).
[2]
[3]
[4]
D. N. Arnold, F. Brezzi, B. Cockburn and L. D. Marini. Unified Analysis of Discontinuous Galerkin Methods for Elliptic Problems. SIAM Journal on Numerical Analysis 39, 1749–1779 (2002). Accessed on Dec 20, 2023.
[5]
[6]
[7]
[8]
F. D. Witherden and P. E. Vincent. On the identification of symmetric quadrature rules for finite element methods. Computers & Mathematics with Applications 69, 1232–1241 (2015).
[9]
M. Crouzeix and P.-A. Raviart. Conforming and nonconforming finite element methods for solving the stationary Stokes equations I. Revue française d'automatique informatique recherche opérationnelle. Mathématique 7, 33–75 (1973).
[10]
R. Rannacher and S. Turek. Simple nonconforming quadrilateral Stokes element. Numerical Methods for Partial Differential Equations 8, 97–111 (1992).
[11]
[12]
M. Cenanovic. Finite element methods for surface problems. Ph.D. Thesis, Jönköping University, School of Engineering (2017).
[13]
[14]
[15]
diff --git a/dev/devdocs/FEValues/index.html b/dev/devdocs/FEValues/index.html index 4adf3b3a10..51d3b0b26a 100644 --- a/dev/devdocs/FEValues/index.html +++ b/dev/devdocs/FEValues/index.html @@ -1,2 +1,2 @@ -FEValues · Ferrite.jl

FEValues

Type definitions

Internal types

Ferrite.GeometryMappingType
GeometryMapping{DiffOrder}(::Type{T}, ip_geo, qr::QuadratureRule)

Create a GeometryMapping object which contains the geometric

  • shape values
  • gradient values (if DiffOrder ≥ 1)
  • hessians values (if DiffOrder ≥ 2)

T<:AbstractFloat gives the numeric type of the values.

source
Ferrite.MappingValuesType
MappingValues(J, H)

The mapping values are calculated based on a geometric_mapping::GeometryMapping along with the cell coordinates, and the stored jacobian, J, and potentially hessian, H, are used when mapping the FunctionValues to the current cell during reinit!.

source
Ferrite.FunctionValuesType
FunctionValues{DiffOrder}(::Type{T}, ip_fun, qr::QuadratureRule, ip_geo::VectorizedInterpolation)

Create a FunctionValues object containing the shape values and gradients (up to order DiffOrder) for both the reference cell (precalculated) and the real cell (updated in reinit!).

source
Ferrite.BCValuesType
BCValues(func_interpol::Interpolation, geom_interpol::Interpolation, boundary_type::Union{Type{<:BoundaryIndex}})

BCValues stores the shape values at all facet/faces/edges/vertices (depending on boundary_type) for the geometric interpolation (geom_interpol), for each dof-position determined by the func_interpol. Used mainly by the ConstraintHandler.

source

Internal utilities

Ferrite.embedding_detFunction
embedding_det(J::SMatrix{3, 2})

Embedding determinant for surfaces in 3D.

TLDR: "det(J) =" ||∂x/∂ξ₁ × ∂x/∂ξ₂||₂

The transformation theorem for some function f on a 2D surface in 3D space leads to ∫ f ⋅ dS = ∫ f ⋅ (∂x/∂ξ₁ × ∂x/∂ξ₂) dξ₁dξ₂ = ∫ f ⋅ n ||∂x/∂ξ₁ × ∂x/∂ξ₂||₂ dξ₁dξ₂ where ||∂x/∂ξ₁ × ∂x/∂ξ₂||₂ is "detJ" and n is the unit normal. See e.g. https://scicomp.stackexchange.com/questions/41741/integration-of-d-1-dimensional-functions-on-finite-element-surfaces for simple explanation. For more details see e.g. the doctoral thesis by Mirza Cenanovic Tangential Calculus [12].

source
embedding_det(J::Union{SMatrix{2, 1}, SMatrix{3, 1}})

Embedding determinant for curves in 2D and 3D.

TLDR: "det(J) =" ||∂x/∂ξ||₂

The transformation theorem for some function f on a 1D curve in 2D and 3D space leads to ∫ f ⋅ dE = ∫ f ⋅ ∂x/∂ξ dξ = ∫ f ⋅ t ||∂x/∂ξ||₂ dξ where ||∂x/∂ξ||₂ is "detJ" and t is "the unit tangent". See e.g. https://scicomp.stackexchange.com/questions/41741/integration-of-d-1-dimensional-functions-on-finite-element-surfaces for simple explanation.

source
Ferrite.ValuesUpdateFlagsType
ValuesUpdateFlags(ip_fun::Interpolation; update_gradients = Val(true), update_hessians = Val(false), update_detJdV = Val(true))

Creates a singleton type for specifying what parts of the AbstractValues should be updated. Note that this is internal API used to get type-stable construction. Keyword arguments in AbstractValues constructors are forwarded, and the public API is passing these as Bool, while the ValuesUpdateFlags method supports both boolean and Val(::Bool) keyword args.

source

Custom FEValues

Custom FEValues, fe_v::AbstractValues, should normally implement the reinit! method. Subtypes of AbstractValues have default implementations for some functions, but require some lower-level access functions, specifically

Array bounds

  • Asking for the nth quadrature point must be inside array bounds if 1 <= n <= getnquadpoints(fe_v). (checkquadpoint can, alternatively, be dispatched to check that n is inbounds.)
  • Asking for the ith shape value or gradient must be inside array bounds if 1 <= i <= getnbasefunctions(fe_v)
  • Asking for the ith geometric value must be inside array bounds if 1 <= i <= getngeobasefunctions(fe_v)
+FEValues · Ferrite.jl

FEValues

Type definitions

Internal types

Ferrite.GeometryMappingType
GeometryMapping{DiffOrder}(::Type{T}, ip_geo, qr::QuadratureRule)

Create a GeometryMapping object which contains the geometric

  • shape values
  • gradient values (if DiffOrder ≥ 1)
  • hessians values (if DiffOrder ≥ 2)

T<:AbstractFloat gives the numeric type of the values.

source
Ferrite.MappingValuesType
MappingValues(J, H)

The mapping values are calculated based on a geometric_mapping::GeometryMapping along with the cell coordinates, and the stored jacobian, J, and potentially hessian, H, are used when mapping the FunctionValues to the current cell during reinit!.

source
Ferrite.FunctionValuesType
FunctionValues{DiffOrder}(::Type{T}, ip_fun, qr::QuadratureRule, ip_geo::VectorizedInterpolation)

Create a FunctionValues object containing the shape values and gradients (up to order DiffOrder) for both the reference cell (precalculated) and the real cell (updated in reinit!).

source
Ferrite.BCValuesType
BCValues(func_interpol::Interpolation, geom_interpol::Interpolation, boundary_type::Union{Type{<:BoundaryIndex}})

BCValues stores the shape values at all facet/faces/edges/vertices (depending on boundary_type) for the geometric interpolation (geom_interpol), for each dof-position determined by the func_interpol. Used mainly by the ConstraintHandler.

source

Internal utilities

Ferrite.embedding_detFunction
embedding_det(J::SMatrix{3, 2})

Embedding determinant for surfaces in 3D.

TLDR: "det(J) =" ||∂x/∂ξ₁ × ∂x/∂ξ₂||₂

The transformation theorem for some function f on a 2D surface in 3D space leads to ∫ f ⋅ dS = ∫ f ⋅ (∂x/∂ξ₁ × ∂x/∂ξ₂) dξ₁dξ₂ = ∫ f ⋅ n ||∂x/∂ξ₁ × ∂x/∂ξ₂||₂ dξ₁dξ₂ where ||∂x/∂ξ₁ × ∂x/∂ξ₂||₂ is "detJ" and n is the unit normal. See e.g. https://scicomp.stackexchange.com/questions/41741/integration-of-d-1-dimensional-functions-on-finite-element-surfaces for simple explanation. For more details see e.g. the doctoral thesis by Mirza Cenanovic Tangential Calculus [12].

source
embedding_det(J::Union{SMatrix{2, 1}, SMatrix{3, 1}})

Embedding determinant for curves in 2D and 3D.

TLDR: "det(J) =" ||∂x/∂ξ||₂

The transformation theorem for some function f on a 1D curve in 2D and 3D space leads to ∫ f ⋅ dE = ∫ f ⋅ ∂x/∂ξ dξ = ∫ f ⋅ t ||∂x/∂ξ||₂ dξ where ||∂x/∂ξ||₂ is "detJ" and t is "the unit tangent". See e.g. https://scicomp.stackexchange.com/questions/41741/integration-of-d-1-dimensional-functions-on-finite-element-surfaces for simple explanation.

source
Ferrite.ValuesUpdateFlagsType
ValuesUpdateFlags(ip_fun::Interpolation; update_gradients = Val(true), update_hessians = Val(false), update_detJdV = Val(true))

Creates a singleton type for specifying what parts of the AbstractValues should be updated. Note that this is internal API used to get type-stable construction. Keyword arguments in AbstractValues constructors are forwarded, and the public API is passing these as Bool, while the ValuesUpdateFlags method supports both boolean and Val(::Bool) keyword args.

source

Custom FEValues

Custom FEValues, fe_v::AbstractValues, should normally implement the reinit! method. Subtypes of AbstractValues have default implementations for some functions, but require some lower-level access functions, specifically

Array bounds

  • Asking for the nth quadrature point must be inside array bounds if 1 <= n <= getnquadpoints(fe_v). (checkquadpoint can, alternatively, be dispatched to check that n is inbounds.)
  • Asking for the ith shape value or gradient must be inside array bounds if 1 <= i <= getnbasefunctions(fe_v)
  • Asking for the ith geometric value must be inside array bounds if 1 <= i <= getngeobasefunctions(fe_v)
diff --git a/dev/devdocs/assembly/index.html b/dev/devdocs/assembly/index.html index 397e41c8b0..6992931e06 100644 --- a/dev/devdocs/assembly/index.html +++ b/dev/devdocs/assembly/index.html @@ -1,4 +1,4 @@ -Assembly · Ferrite.jl

Assembly

Type definitions

Ferrite.COOAssemblerType
struct COOAssembler{Tv, Ti}

This assembler creates a COO (coordinate format) representation of a sparse matrix during assembly and converts it into a SparseMatrixCSC{Tv, Ti} on finalization.

source

Utility functions

Ferrite.matrix_handleFunction
matrix_handle(a::AbstractAssembler)
-vector_handle(a::AbstractAssembler)

Return a reference to the underlying matrix/vector of the assembler used during assembly operations.

source
Ferrite.vector_handleFunction
matrix_handle(a::AbstractAssembler)
-vector_handle(a::AbstractAssembler)

Return a reference to the underlying matrix/vector of the assembler used during assembly operations.

source
Ferrite._sortdofs_for_assembly!Function
_sortdofs_for_assembly!(permutation::Vector{Int}, sorteddofs::Vector{Int}, dofs::AbstractVector)

Sorts the dofs into a separate buffer and returns it together with a permutation vector.

source
Ferrite.sortperm2!Function
sortperm2!(data::AbstractVector, permutation::AbstractVector)

Sort the input vector inplace and compute the corresponding permutation.

source
+Assembly · Ferrite.jl

Assembly

Type definitions

Ferrite.COOAssemblerType
struct COOAssembler{Tv, Ti}

This assembler creates a COO (coordinate format) representation of a sparse matrix during assembly and converts it into a SparseMatrixCSC{Tv, Ti} on finalization.

source

Utility functions

Ferrite.matrix_handleFunction
matrix_handle(a::AbstractAssembler)
+vector_handle(a::AbstractAssembler)

Return a reference to the underlying matrix/vector of the assembler used during assembly operations.

source
Ferrite.vector_handleFunction
matrix_handle(a::AbstractAssembler)
+vector_handle(a::AbstractAssembler)

Return a reference to the underlying matrix/vector of the assembler used during assembly operations.

source
Ferrite._sortdofs_for_assembly!Function
_sortdofs_for_assembly!(permutation::Vector{Int}, sorteddofs::Vector{Int}, dofs::AbstractVector)

Sorts the dofs into a separate buffer and returns it together with a permutation vector.

source
Ferrite.sortperm2!Function
sortperm2!(data::AbstractVector, permutation::AbstractVector)

Sort the input vector inplace and compute the corresponding permutation.

source
diff --git a/dev/devdocs/dofhandler/index.html b/dev/devdocs/dofhandler/index.html index 53d1249124..eb0357f5fc 100644 --- a/dev/devdocs/dofhandler/index.html +++ b/dev/devdocs/dofhandler/index.html @@ -1,9 +1,9 @@ -Dof Handler · Ferrite.jl

Dof Handler

Type definitions

Dof handlers are subtypes of AbstractDofhandler{sdim}, i.e. they are parametrized by the spatial dimension. Internally a helper struct InterpolationInfo is utilized to enforce type stability during dof distribution, because the interpolations are not available as concrete types.

Ferrite.InterpolationInfoType
InterpolationInfo

Gathers all the information needed to distribute dofs for a given interpolation. Note that this cache is of the same type no matter the interpolation: the purpose is to make dof-distribution type-stable.

source
Ferrite.PathOrientationInfoType
PathOrientationInfo

Orientation information for 1D entities.

The orientation for 1D entities is defined by the indices of the grid nodes associated to the vertices. To give an example, the oriented path

1 ---> 2

is called regular, indicated by regular=true, while the oriented path

2 ---> 1

is called inverted, indicated by regular=false.

source
Ferrite.SurfaceOrientationInfoType
SurfaceOrientationInfo

Orientation information for 2D entities. Such an entity can be possibly flipped (i.e. the defining vertex order is reverse to the spanning vertex order) and the vertices can be rotated against each other. Take for example the faces

1---2 2---3
+Dof Handler · Ferrite.jl

Dof Handler

Type definitions

Dof handlers are subtypes of AbstractDofhandler{sdim}, i.e. they are parametrized by the spatial dimension. Internally a helper struct InterpolationInfo is utilized to enforce type stability during dof distribution, because the interpolations are not available as concrete types.

Ferrite.InterpolationInfoType
InterpolationInfo

Gathers all the information needed to distribute dofs for a given interpolation. Note that this cache is of the same type no matter the interpolation: the purpose is to make dof-distribution type-stable.

source
Ferrite.PathOrientationInfoType
PathOrientationInfo

Orientation information for 1D entities.

The orientation for 1D entities is defined by the indices of the grid nodes associated to the vertices. To give an example, the oriented path

1 ---> 2

is called regular, indicated by regular=true, while the oriented path

2 ---> 1

is called inverted, indicated by regular=false.

source
Ferrite.SurfaceOrientationInfoType
SurfaceOrientationInfo

Orientation information for 2D entities. Such an entity can be possibly flipped (i.e. the defining vertex order is reverse to the spanning vertex order) and the vertices can be rotated against each other. Take for example the faces

1---2 2---3
 | A | | B |
 4---3 1---4

which are rotated against each other by 90° (shift index is 1) or the faces

1---2 2---1
 | A | | B |
-4---3 3---4

which are flipped against each other. Any combination of these can happen. The combination to map this local face to the defining face is encoded with this data structure via $rotate \circ flip$ where the rotation is indiced by the shift index. !!!NOTE TODO implement me.

source

Internal API

The main entry point for dof distribution is __close!.

Ferrite.__close!Function
__close!(dh::DofHandler)

Internal entry point for dof distribution.

Dofs are distributed as follows: For the DofHandler each SubDofHandler is visited in the order they were added. For each field in the SubDofHandler create dofs for the cell. This means that dofs on a particular cell will be numbered in groups for each field, so first the dofs for field 1 are distributed, then field 2, etc. For each cell dofs are first distributed on its vertices, then on the interior of edges (if applicable), then on the interior of faces (if applicable), and finally on the cell interior. The entity ordering follows the geometrical ordering found in vertices, faces and edges.

source
Ferrite.get_gridFunction
get_grid(dh::AbstractDofHandler)

Access some grid representation for the dof handler.

Note

This API function is currently not well-defined. It acts as the interface between distributed assembly and assembly on a single process, because most parts of the functionality can be handled by only acting on the locally owned cell set.

source
Ferrite.find_fieldFunction
find_field(dh::DofHandler, field_name::Symbol)::NTuple{2,Int}

Return the index of the field with name field_name in a DofHandler. The index is a NTuple{2,Int}, where the 1st entry is the index of the SubDofHandler within which the field was found and the 2nd entry is the index of the field within the SubDofHandler.

Note

Always finds the 1st occurrence of a field within DofHandler.

See also: find_field(sdh::SubDofHandler, field_name::Symbol), Ferrite._find_field(sdh::SubDofHandler, field_name::Symbol).

source
find_field(sdh::SubDofHandler, field_name::Symbol)::Int

Return the index of the field with name field_name in a SubDofHandler. Throw an error if the field is not found.

See also: find_field(dh::DofHandler, field_name::Symbol), _find_field(sdh::SubDofHandler, field_name::Symbol).

source
Ferrite._close_subdofhandler!Function
_close_subdofhandler!(dh::DofHandler{sdim}, sdh::SubDofHandler, sdh_index::Int, nextdof::Int, vertexdicts, edgedicts, facedicts) where {sdim}

Main entry point to distribute dofs for a single SubDofHandler on its subdomain.

source
Ferrite._distribute_dofs_for_cell!Function
_distribute_dofs_for_cell!(dh::DofHandler{sdim}, cell::AbstractCell, ip_info::InterpolationInfo, nextdof::Int, vertexdict, edgedict, facedict) where {sdim}

Main entry point to distribute dofs for a single cell.

source
Ferrite.permute_and_push!Function
permute_and_push!

For interpolations with more than one interior dof per edge it may be necessary to adjust the dofs. Since dofs are (initially) enumerated according to the local edge direction there can be a direction mismatch with the neighboring element. For example, in the following nodal interpolation example, with three interior dofs on each edge, the initial pass have distributed dofs 4, 5, 6 according to the local edge directions:

+-----------+
+4---3 3---4

which are flipped against each other. Any combination of these can happen. The combination to map this local face to the defining face is encoded with this data structure via $rotate \circ flip$ where the rotation is indiced by the shift index. !!!NOTE TODO implement me.

source

Internal API

The main entry point for dof distribution is __close!.

Ferrite.__close!Function
__close!(dh::DofHandler)

Internal entry point for dof distribution.

Dofs are distributed as follows: For the DofHandler each SubDofHandler is visited in the order they were added. For each field in the SubDofHandler create dofs for the cell. This means that dofs on a particular cell will be numbered in groups for each field, so first the dofs for field 1 are distributed, then field 2, etc. For each cell dofs are first distributed on its vertices, then on the interior of edges (if applicable), then on the interior of faces (if applicable), and finally on the cell interior. The entity ordering follows the geometrical ordering found in vertices, faces and edges.

source
Ferrite.get_gridFunction
get_grid(dh::AbstractDofHandler)

Access some grid representation for the dof handler.

Note

This API function is currently not well-defined. It acts as the interface between distributed assembly and assembly on a single process, because most parts of the functionality can be handled by only acting on the locally owned cell set.

source
Ferrite.find_fieldFunction
find_field(dh::DofHandler, field_name::Symbol)::NTuple{2,Int}

Return the index of the field with name field_name in a DofHandler. The index is a NTuple{2,Int}, where the 1st entry is the index of the SubDofHandler within which the field was found and the 2nd entry is the index of the field within the SubDofHandler.

Note

Always finds the 1st occurrence of a field within DofHandler.

See also: find_field(sdh::SubDofHandler, field_name::Symbol), Ferrite._find_field(sdh::SubDofHandler, field_name::Symbol).

source
find_field(sdh::SubDofHandler, field_name::Symbol)::Int

Return the index of the field with name field_name in a SubDofHandler. Throw an error if the field is not found.

See also: find_field(dh::DofHandler, field_name::Symbol), _find_field(sdh::SubDofHandler, field_name::Symbol).

source
Ferrite._close_subdofhandler!Function
_close_subdofhandler!(dh::DofHandler{sdim}, sdh::SubDofHandler, sdh_index::Int, nextdof::Int, vertexdicts, edgedicts, facedicts) where {sdim}

Main entry point to distribute dofs for a single SubDofHandler on its subdomain.

source
Ferrite._distribute_dofs_for_cell!Function
_distribute_dofs_for_cell!(dh::DofHandler{sdim}, cell::AbstractCell, ip_info::InterpolationInfo, nextdof::Int, vertexdict, edgedict, facedict) where {sdim}

Main entry point to distribute dofs for a single cell.

source
Ferrite.permute_and_push!Function
permute_and_push!

For interpolations with more than one interior dof per edge it may be necessary to adjust the dofs. Since dofs are (initially) enumerated according to the local edge direction there can be a direction mismatch with the neighboring element. For example, in the following nodal interpolation example, with three interior dofs on each edge, the initial pass have distributed dofs 4, 5, 6 according to the local edge directions:

+-----------+
 |     A     |
 +--4--5--6->+    local edge on element A
 
@@ -11,6 +11,6 @@
 
 +<-6--5--4--+    local edge on element B
 |     B     |
-+-----------+

For most scalar-valued interpolations we can simply compensate for this by reversing the numbering on all edges that do not match the global edge direction, i.e. for the edge on element B in the example.

In addition, we also have to preserve the ordering at each dof location.

For more details we refer to Scroggs et al. [13] as we follow the methodology described therein.

References

  • [13] Scroggs et al. ACM Trans. Math. Softw. 48 (2022).
source
!!!NOTE TODO implement me.

For more details we refer to [1] as we follow the methodology described therein.

[1] Scroggs, M. W., Dokken, J. S., Richardson, C. N., & Wells, G. N. (2022). Construction of arbitrary order finite element degree-of-freedom maps on polygonal and polyhedral cell meshes. ACM Transactions on Mathematical Software (TOMS), 48(2), 1-23.

!!!TODO citation via software.
++-----------+

For most scalar-valued interpolations we can simply compensate for this by reversing the numbering on all edges that do not match the global edge direction, i.e. for the edge on element B in the example.

In addition, we also have to preserve the ordering at each dof location.

For more details we refer to Scroggs et al. [13] as we follow the methodology described therein.

References

  • [13] Scroggs et al. ACM Trans. Math. Softw. 48 (2022).
source
!!!NOTE TODO implement me.

For more details we refer to [1] as we follow the methodology described therein.

[1] Scroggs, M. W., Dokken, J. S., Richardson, C. N., & Wells, G. N. (2022). Construction of arbitrary order finite element degree-of-freedom maps on polygonal and polyhedral cell meshes. ACM Transactions on Mathematical Software (TOMS), 48(2), 1-23.

!!!TODO citation via software.
 
-!!!TODO Investigate if we can somehow pass the interpolation into this function in a typestable way.
source
+!!!TODO Investigate if we can somehow pass the interpolation into this function in a typestable way.
source
diff --git a/dev/devdocs/elements/index.html b/dev/devdocs/elements/index.html index 2b721114e1..85aebf1740 100644 --- a/dev/devdocs/elements/index.html +++ b/dev/devdocs/elements/index.html @@ -1,15 +1,15 @@ -Elements and cells · Ferrite.jl

Elements and cells

Type definitions

Elements or cells are subtypes of AbstractCell{<:AbstractRefShape}. As shown, they are parametrized by the associated reference element.

Required methods to implement for all subtypes of AbstractCell to define a new element

Ferrite.get_node_idsFunction
Ferrite.get_node_ids(c::AbstractCell)

Return the node id's for cell c in the order determined by the cell's reference cell.

Default implementation: c.nodes.

source

Common utilities and definitions when working with grids internally.

First we have some topological queries on the element

Ferrite.verticesMethod
Ferrite.vertices(::AbstractCell)

Returns a tuple with the node indices (of the nodes in a grid) for each vertex in a given cell. This function induces the VertexIndex, where the second index corresponds to the local index into this tuple.

source
Ferrite.edgesMethod
Ferrite.edges(::AbstractCell)

Returns a tuple of 2-tuples containing the ordered node indices (of the nodes in a grid) corresponding to the vertices that define an oriented edge. This function induces the EdgeIndex, where the second index corresponds to the local index into this tuple.

Note that the vertices are sufficient to define an edge uniquely.

source
Ferrite.facesMethod
Ferrite.faces(::AbstractCell)

Returns a tuple of n-tuples containing the ordered node indices (of the nodes in a grid) corresponding to the vertices that define an oriented face. This function induces the FaceIndex, where the second index corresponds to the local index into this tuple.

An oriented face is a face with the first node having the local index and the other nodes spanning such that the normal to the face is pointing outwards.

Note that the vertices are sufficient to define a face uniquely.

source
Ferrite.facetsMethod
Ferrite.facets(::AbstractCell)

Returns a tuple of n-tuples containing the ordered node indices (of the nodes in a grid) corresponding to the vertices that define an oriented facet. This function induces the FacetIndex, where the second index corresponds to the local index into this tuple.

See also vertices, edges, and faces

source
Ferrite.boundaryfunctionMethod
boundaryfunction(::Type{<:BoundaryIndex})

Helper function to dispatch on the correct entity from a given boundary index.

source
Ferrite.reference_verticesMethod
reference_vertices(::Type{<:AbstractRefShape})
-reference_vertices(::AbstractCell)

Returns a tuple of integers containing the local node indices corresponding to the vertices (i.e. corners or endpoints) of the cell.

source
Ferrite.reference_edgesMethod
reference_edges(::Type{<:AbstractRefShape})
-reference_edges(::AbstractCell)

Returns a tuple of 2-tuples containing the ordered local node indices (corresponding to the vertices) that define an edge.

source
Ferrite.reference_facesMethod
reference_faces(::Type{<:AbstractRefShape})
-reference_faces(::AbstractCell)

Returns a tuple of n-tuples containing the ordered local node indices (corresponding to the vertices) that define a face.

source

and some generic utils which are commonly found in finite element codes

Ferrite.toglobalFunction
toglobal(grid::AbstractGrid, vertexidx::VertexIndex) -> Int
-toglobal(grid::AbstractGrid, vertexidx::Vector{VertexIndex}) -> Vector{Int}

This function takes the local vertex representation (a VertexIndex) and looks up the unique global id (an Int).

source
Ferrite.sortfaceFunction
sortface(face::Tuple{Int})
+Elements and cells · Ferrite.jl

Elements and cells

Type definitions

Elements or cells are subtypes of AbstractCell{<:AbstractRefShape}. As shown, they are parametrized by the associated reference element.

Required methods to implement for all subtypes of AbstractCell to define a new element

Ferrite.get_node_idsFunction
Ferrite.get_node_ids(c::AbstractCell)

Return the node id's for cell c in the order determined by the cell's reference cell.

Default implementation: c.nodes.

source

Common utilities and definitions when working with grids internally.

First we have some topological queries on the element

Ferrite.verticesMethod
Ferrite.vertices(::AbstractCell)

Returns a tuple with the node indices (of the nodes in a grid) for each vertex in a given cell. This function induces the VertexIndex, where the second index corresponds to the local index into this tuple.

source
Ferrite.edgesMethod
Ferrite.edges(::AbstractCell)

Returns a tuple of 2-tuples containing the ordered node indices (of the nodes in a grid) corresponding to the vertices that define an oriented edge. This function induces the EdgeIndex, where the second index corresponds to the local index into this tuple.

Note that the vertices are sufficient to define an edge uniquely.

source
Ferrite.facesMethod
Ferrite.faces(::AbstractCell)

Returns a tuple of n-tuples containing the ordered node indices (of the nodes in a grid) corresponding to the vertices that define an oriented face. This function induces the FaceIndex, where the second index corresponds to the local index into this tuple.

An oriented face is a face with the first node having the local index and the other nodes spanning such that the normal to the face is pointing outwards.

Note that the vertices are sufficient to define a face uniquely.

source
Ferrite.facetsMethod
Ferrite.facets(::AbstractCell)

Returns a tuple of n-tuples containing the ordered node indices (of the nodes in a grid) corresponding to the vertices that define an oriented facet. This function induces the FacetIndex, where the second index corresponds to the local index into this tuple.

See also vertices, edges, and faces

source
Ferrite.boundaryfunctionMethod
boundaryfunction(::Type{<:BoundaryIndex})

Helper function to dispatch on the correct entity from a given boundary index.

source
Ferrite.reference_verticesMethod
reference_vertices(::Type{<:AbstractRefShape})
+reference_vertices(::AbstractCell)

Returns a tuple of integers containing the local node indices corresponding to the vertices (i.e. corners or endpoints) of the cell.

source
Ferrite.reference_edgesMethod
reference_edges(::Type{<:AbstractRefShape})
+reference_edges(::AbstractCell)

Returns a tuple of 2-tuples containing the ordered local node indices (corresponding to the vertices) that define an edge.

source
Ferrite.reference_facesMethod
reference_faces(::Type{<:AbstractRefShape})
+reference_faces(::AbstractCell)

Returns a tuple of n-tuples containing the ordered local node indices (corresponding to the vertices) that define a face.

source

and some generic utils which are commonly found in finite element codes

Ferrite.toglobalFunction
toglobal(grid::AbstractGrid, vertexidx::VertexIndex) -> Int
+toglobal(grid::AbstractGrid, vertexidx::Vector{VertexIndex}) -> Vector{Int}

This function takes the local vertex representation (a VertexIndex) and looks up the unique global id (an Int).

source
Ferrite.sortfaceFunction
sortface(face::Tuple{Int})
 sortface(face::Tuple{Int,Int})
 sortface(face::Tuple{Int,Int,Int})
-sortface(face::Tuple{Int,Int,Int,Int})

Returns the unique representation of a face. Here the unique representation is the sorted node index tuple. Note that in 3D we only need indices to uniquely identify a face, so the unique representation is always a tuple length 3.

source
Ferrite.sortface_fastFunction
sortface_fast(face::Tuple{Int})
+sortface(face::Tuple{Int,Int,Int,Int})

Returns the unique representation of a face. Here the unique representation is the sorted node index tuple. Note that in 3D we only need indices to uniquely identify a face, so the unique representation is always a tuple length 3.

source
Ferrite.sortface_fastFunction
sortface_fast(face::Tuple{Int})
 sortface_fast(face::Tuple{Int,Int})
 sortface_fast(face::Tuple{Int,Int,Int})
-sortface_fast(face::Tuple{Int,Int,Int,Int})

Returns the unique representation of a face. Here the unique representation is the sorted node index tuple. Note that in 3D we only need indices to uniquely identify a face, so the unique representation is always a tuple length 3.

source
Ferrite.sortedgeFunction
sortedge(edge::Tuple{Int,Int})

Returns the unique representation of an edge and its orientation. Here the unique representation is the sorted node index tuple. The orientation is true if the edge is not flipped, where it is false if the edge is flipped.

source
Ferrite.sortedge_fastFunction

sortedge_fast(edge::Tuple{Int,Int})

Returns the unique representation of an edge. Here the unique representation is the sorted node index tuple.

source
Ferrite.element_to_facet_transformationFunction
element_to_facet_transformation(point::AbstractVector, ::Type{<:AbstractRefShape}, facet::Int)

Transform quadrature point from the cell's coordinates to the facet's reference coordinates, decreasing the number of dimensions by one. This is the inverse of facet_to_element_transformation.

source
Ferrite.facet_to_element_transformationFunction
facet_to_element_transformation(point::Vec, ::Type{<:AbstractRefShape}, facet::Int)

Transform quadrature point from the facet's reference coordinates to coordinates on the cell's facet, increasing the number of dimensions by one.

source
Ferrite.InterfaceOrientationInfoType
InterfaceOrientationInfo

Relative orientation information for 1D and 2D interfaces in 2D and 3D elements respectively. This information is used to construct the transformation matrix to transform the quadrature points from faceta to facetb achieving synced spatial coordinates. Face B's orientation relative to Face A's can possibly be flipped (i.e. the vertices indices order is reversed) and the vertices can be rotated against each other. The reference orientation of face B is such that the first node has the lowest vertex index. Thus, this structure also stores the shift of the lowest vertex index which is used to reorient the face in case of flipping transform_interface_points!.

source
Ferrite.transform_interface_points!Function
transform_interface_points!(dst::AbstractVector{Vec{3, Float64}}, points::AbstractVector{Vec{3, Float64}}, interface_transformation::InterfaceOrientationInfo)

Transform the points from face A to face B using the orientation information of the interface and store it in the vector dst. For 3D, the faces are transformed into regular polygons such that the rotation angle is the shift in reference node index × 2π ÷ number of edges in face. If the face is flipped then the flipping is about the axis that preserves the position of the first node (which is the reference node after being rotated to be in the first position, it's rotated back in the opposite direction after flipping). Take for example the interface

        2           3
+sortface_fast(face::Tuple{Int,Int,Int,Int})

Returns the unique representation of a face. Here the unique representation is the sorted node index tuple. Note that in 3D we only need indices to uniquely identify a face, so the unique representation is always a tuple length 3.

source
Ferrite.sortedgeFunction
sortedge(edge::Tuple{Int,Int})

Returns the unique representation of an edge and its orientation. Here the unique representation is the sorted node index tuple. The orientation is true if the edge is not flipped, where it is false if the edge is flipped.

source
Ferrite.sortedge_fastFunction

sortedge_fast(edge::Tuple{Int,Int})

Returns the unique representation of an edge. Here the unique representation is the sorted node index tuple.

source
Ferrite.element_to_facet_transformationFunction
element_to_facet_transformation(point::AbstractVector, ::Type{<:AbstractRefShape}, facet::Int)

Transform quadrature point from the cell's coordinates to the facet's reference coordinates, decreasing the number of dimensions by one. This is the inverse of facet_to_element_transformation.

source
Ferrite.facet_to_element_transformationFunction
facet_to_element_transformation(point::Vec, ::Type{<:AbstractRefShape}, facet::Int)

Transform quadrature point from the facet's reference coordinates to coordinates on the cell's facet, increasing the number of dimensions by one.

source
Ferrite.InterfaceOrientationInfoType
InterfaceOrientationInfo

Relative orientation information for 1D and 2D interfaces in 2D and 3D elements respectively. This information is used to construct the transformation matrix to transform the quadrature points from faceta to facetb achieving synced spatial coordinates. Face B's orientation relative to Face A's can possibly be flipped (i.e. the vertices indices order is reversed) and the vertices can be rotated against each other. The reference orientation of face B is such that the first node has the lowest vertex index. Thus, this structure also stores the shift of the lowest vertex index which is used to reorient the face in case of flipping transform_interface_points!.

source
Ferrite.transform_interface_points!Function
transform_interface_points!(dst::AbstractVector{Vec{3, Float64}}, points::AbstractVector{Vec{3, Float64}}, interface_transformation::InterfaceOrientationInfo)

Transform the points from face A to face B using the orientation information of the interface and store it in the vector dst. For 3D, the faces are transformed into regular polygons such that the rotation angle is the shift in reference node index × 2π ÷ number of edges in face. If the face is flipped then the flipping is about the axis that preserves the position of the first node (which is the reference node after being rotated to be in the first position, it's rotated back in the opposite direction after flipping). Take for example the interface

        2           3
         | \         | \
         |  \        |  \
 y       | A \       | B \
@@ -43,4 +43,4 @@
        |  \
 y      |   \
 ↑      |    \
-→ x    1-----2
source
Ferrite.get_transformation_matrixFunction
get_transformation_matrix(interface_transformation::InterfaceOrientationInfo)

Returns the transformation matrix corresponding to the interface orientation information stored in InterfaceOrientationInfo. The transformation matrix is constructed using a combination of affine transformations defined for each interface reference shape. The transformation for a flipped face is a function of both relative orientation and the orientation of the second face. If the face is not flipped then the transformation is a function of relative orientation only.

source
+→ x 1-----2
source
Ferrite.get_transformation_matrixFunction
get_transformation_matrix(interface_transformation::InterfaceOrientationInfo)

Returns the transformation matrix corresponding to the interface orientation information stored in InterfaceOrientationInfo. The transformation matrix is constructed using a combination of affine transformations defined for each interface reference shape. The transformation for a flipped face is a function of both relative orientation and the orientation of the second face. If the face is not flipped then the transformation is a function of relative orientation only.

source
diff --git a/dev/devdocs/index.html b/dev/devdocs/index.html index 1eee66d47d..3c36650012 100644 --- a/dev/devdocs/index.html +++ b/dev/devdocs/index.html @@ -1,2 +1,2 @@ -Developer documentation · Ferrite.jl
+Developer documentation · Ferrite.jl
diff --git a/dev/devdocs/interpolations/index.html b/dev/devdocs/interpolations/index.html index 45d9d39117..9cced2c956 100644 --- a/dev/devdocs/interpolations/index.html +++ b/dev/devdocs/interpolations/index.html @@ -1,5 +1,5 @@ -Interpolations · Ferrite.jl

Interpolations

Type definitions

Interpolations are subtypes of Interpolation{shape, order}, i.e. they are parametrized by the reference element and its characteristic order.

Fallback methods applicable for all subtypes of Interpolation

Ferrite.getrefshapeMethod
Ferrite.getrefshape(::Interpolation)::AbstractRefShape

Return the reference element shape of the interpolation.

source
Ferrite.reference_shape_gradientMethod
reference_shape_gradient(ip::Interpolation, ξ::Vec, i::Int)

Evaluate the gradient of the ith shape function of the interpolation ip in reference coordinate ξ.

source
Ferrite.boundarydof_indicesFunction
boundarydof_indices(::Type{<:BoundaryIndex})

Helper function to generically dispatch on the correct dof sets of a boundary entity.

source
Ferrite.reference_shape_values!Function
reference_shape_values!(values::AbstractArray{T}, ip::Interpolation, ξ::Vec)

Evaluate all shape functions of ip at once at the reference point ξ and store them in values.

source
Ferrite.reference_shape_gradients!Function
reference_shape_gradients!(gradients::AbstractArray, ip::Interpolation, ξ::Vec)

Evaluate all shape function gradients of ip at once at the reference point ξ and store them in gradients.

source
Ferrite.reference_shape_gradients_and_values!Function
reference_shape_gradients_and_values!(gradients::AbstractArray, values::AbstractArray, ip::Interpolation, ξ::Vec)

Evaluate all shape function gradients and values of ip at once at the reference point ξ and store them in values.

source
Ferrite.reference_shape_hessians_gradients_and_values!Function
reference_shape_hessians_gradients_and_values!(hessians::AbstractVector, gradients::AbstractVector, values::AbstractVector, ip::Interpolation, ξ::Vec)

Evaluate all shape function hessians, gradients and values of ip at once at the reference point ξ and store them in hessians, gradients, and values.

source
Ferrite.shape_value_typeMethod
shape_value_type(ip::Interpolation, ::Type{T}) where T<:Number

Return the type of shape_value(ip::Interpolation, ξ::Vec, ib::Int).

source

Required methods to implement for all subtypes of Interpolation to define a new finite element

Depending on the dimension of the reference element the following functions have to be implemented

Ferrite.vertexdof_indicesMethod
vertexdof_indices(ip::Interpolation)

A tuple containing tuples of local dof indices for the respective vertex in local enumeration on a cell defined by vertices(::Cell). The vertex enumeration must match the vertex enumeration of the corresponding geometrical cell.

Note

The dofs appearing in the tuple must be continuous and increasing! The first dof must be the 1, as vertex dofs are enumerated first.

source
Ferrite.dirichlet_vertexdof_indicesMethod
dirichlet_vertexdof_indices(ip::Interpolation)

A tuple containing tuples of local dof indices for the respective vertex in local enumeration on a cell defined by vertices(::Cell). The vertex enumeration must match the vertex enumeration of the corresponding geometrical cell. Used internally in ConstraintHandler and defaults to vertexdof_indices(ip::Interpolation) for continuous interpolation.

Note

The dofs appearing in the tuple must be continuous and increasing! The first dof must be the 1, as vertex dofs are enumerated first.

source
Ferrite.facedof_indicesMethod
facedof_indices(ip::Interpolation)

A tuple containing tuples of all local dof indices for the respective face in local enumeration on a cell defined by faces(::Cell). The face enumeration must match the face enumeration of the corresponding geometrical cell.

source
Ferrite.facedof_interior_indicesMethod
facedof_interior_indices(ip::Interpolation)

A tuple containing tuples of the local dof indices on the interior of the respective face in local enumeration on a cell defined by faces(::Cell). The face enumeration must match the face enumeration of the corresponding geometrical cell. Note that the vertex and edge dofs are included here.

Note

The dofs appearing in the tuple must be continuous and increasing! The first dof must be the computed via "last edge interior dof index + 1", if face dofs exist.

source
Ferrite.edgedof_indicesMethod
edgedof_indices(ip::Interpolation)

A tuple containing tuples of local dof indices for the respective edge in local enumeration on a cell defined by edges(::Cell). The edge enumeration must match the edge enumeration of the corresponding geometrical cell.

The dofs are guaranteed to be aligned with the local ordering of the entities on the oriented edge. Here the first entries are the vertex dofs, followed by the edge interior dofs.

source
Ferrite.dirichlet_edgedof_indicesMethod
dirichlet_edgedof_indices(ip::Interpolation)

A tuple containing tuples of local dof indices for the respective edge in local enumeration on a cell defined by edges(::Cell). The edge enumeration must match the edge enumeration of the corresponding geometrical cell. Used internally in ConstraintHandler and defaults to edgedof_indices(ip::Interpolation) for continuous interpolation.

The dofs are guaranteed to be aligned with the local ordering of the entities on the oriented edge. Here the first entries are the vertex dofs, followed by the edge interior dofs.

source
Ferrite.edgedof_interior_indicesMethod
edgedof_interior_indices(ip::Interpolation)

A tuple containing tuples of the local dof indices on the interior of the respective edge in local enumeration on a cell defined by edges(::Cell). The edge enumeration must match the edge enumeration of the corresponding geometrical cell. Note that the vertex dofs are included here.

Note

The dofs appearing in the tuple must be continuous and increasing! The first dof must be computed via "last vertex dof index + 1", if edge dofs exist.

source
Ferrite.volumedof_interior_indicesMethod
volumedof_interior_indices(ip::Interpolation)

Tuple containing the dof indices associated with the interior of a volume.

Note

The dofs appearing in the tuple must be continuous and increasing, volumedofs are enumerated last.

source
Ferrite.reference_coordinatesMethod
reference_coordinates(ip::Interpolation)

Returns a vector of coordinates with length getnbasefunctions(::Interpolation) and indices corresponding to the indices of a dof in vertices, faces and edges.

Only required for nodal interpolations.
+Interpolations · Ferrite.jl

Interpolations

Type definitions

Interpolations are subtypes of Interpolation{shape, order}, i.e. they are parametrized by the reference element and its characteristic order.

Fallback methods applicable for all subtypes of Interpolation

Ferrite.getrefshapeMethod
Ferrite.getrefshape(::Interpolation)::AbstractRefShape

Return the reference element shape of the interpolation.

source
Ferrite.reference_shape_gradientMethod
reference_shape_gradient(ip::Interpolation, ξ::Vec, i::Int)

Evaluate the gradient of the ith shape function of the interpolation ip in reference coordinate ξ.

source
Ferrite.boundarydof_indicesFunction
boundarydof_indices(::Type{<:BoundaryIndex})

Helper function to generically dispatch on the correct dof sets of a boundary entity.

source
Ferrite.reference_shape_values!Function
reference_shape_values!(values::AbstractArray{T}, ip::Interpolation, ξ::Vec)

Evaluate all shape functions of ip at once at the reference point ξ and store them in values.

source
Ferrite.reference_shape_gradients!Function
reference_shape_gradients!(gradients::AbstractArray, ip::Interpolation, ξ::Vec)

Evaluate all shape function gradients of ip at once at the reference point ξ and store them in gradients.

source
Ferrite.reference_shape_gradients_and_values!Function
reference_shape_gradients_and_values!(gradients::AbstractArray, values::AbstractArray, ip::Interpolation, ξ::Vec)

Evaluate all shape function gradients and values of ip at once at the reference point ξ and store them in values.

source
Ferrite.reference_shape_hessians_gradients_and_values!Function
reference_shape_hessians_gradients_and_values!(hessians::AbstractVector, gradients::AbstractVector, values::AbstractVector, ip::Interpolation, ξ::Vec)

Evaluate all shape function hessians, gradients and values of ip at once at the reference point ξ and store them in hessians, gradients, and values.

source
Ferrite.shape_value_typeMethod
shape_value_type(ip::Interpolation, ::Type{T}) where T<:Number

Return the type of shape_value(ip::Interpolation, ξ::Vec, ib::Int).

source

Required methods to implement for all subtypes of Interpolation to define a new finite element

Depending on the dimension of the reference element the following functions have to be implemented

Ferrite.vertexdof_indicesMethod
vertexdof_indices(ip::Interpolation)

A tuple containing tuples of local dof indices for the respective vertex in local enumeration on a cell defined by vertices(::Cell). The vertex enumeration must match the vertex enumeration of the corresponding geometrical cell.

Note

The dofs appearing in the tuple must be continuous and increasing! The first dof must be the 1, as vertex dofs are enumerated first.

source
Ferrite.dirichlet_vertexdof_indicesMethod
dirichlet_vertexdof_indices(ip::Interpolation)

A tuple containing tuples of local dof indices for the respective vertex in local enumeration on a cell defined by vertices(::Cell). The vertex enumeration must match the vertex enumeration of the corresponding geometrical cell. Used internally in ConstraintHandler and defaults to vertexdof_indices(ip::Interpolation) for continuous interpolation.

Note

The dofs appearing in the tuple must be continuous and increasing! The first dof must be the 1, as vertex dofs are enumerated first.

source
Ferrite.facedof_indicesMethod
facedof_indices(ip::Interpolation)

A tuple containing tuples of all local dof indices for the respective face in local enumeration on a cell defined by faces(::Cell). The face enumeration must match the face enumeration of the corresponding geometrical cell.

source
Ferrite.facedof_interior_indicesMethod
facedof_interior_indices(ip::Interpolation)

A tuple containing tuples of the local dof indices on the interior of the respective face in local enumeration on a cell defined by faces(::Cell). The face enumeration must match the face enumeration of the corresponding geometrical cell. Note that the vertex and edge dofs are included here.

Note

The dofs appearing in the tuple must be continuous and increasing! The first dof must be the computed via "last edge interior dof index + 1", if face dofs exist.

source
Ferrite.edgedof_indicesMethod
edgedof_indices(ip::Interpolation)

A tuple containing tuples of local dof indices for the respective edge in local enumeration on a cell defined by edges(::Cell). The edge enumeration must match the edge enumeration of the corresponding geometrical cell.

The dofs are guaranteed to be aligned with the local ordering of the entities on the oriented edge. Here the first entries are the vertex dofs, followed by the edge interior dofs.

source
Ferrite.dirichlet_edgedof_indicesMethod
dirichlet_edgedof_indices(ip::Interpolation)

A tuple containing tuples of local dof indices for the respective edge in local enumeration on a cell defined by edges(::Cell). The edge enumeration must match the edge enumeration of the corresponding geometrical cell. Used internally in ConstraintHandler and defaults to edgedof_indices(ip::Interpolation) for continuous interpolation.

The dofs are guaranteed to be aligned with the local ordering of the entities on the oriented edge. Here the first entries are the vertex dofs, followed by the edge interior dofs.

source
Ferrite.edgedof_interior_indicesMethod
edgedof_interior_indices(ip::Interpolation)

A tuple containing tuples of the local dof indices on the interior of the respective edge in local enumeration on a cell defined by edges(::Cell). The edge enumeration must match the edge enumeration of the corresponding geometrical cell. Note that the vertex dofs are included here.

Note

The dofs appearing in the tuple must be continuous and increasing! The first dof must be computed via "last vertex dof index + 1", if edge dofs exist.

source
Ferrite.volumedof_interior_indicesMethod
volumedof_interior_indices(ip::Interpolation)

Tuple containing the dof indices associated with the interior of a volume.

Note

The dofs appearing in the tuple must be continuous and increasing, volumedofs are enumerated last.

source
Ferrite.is_discontinuousMethod
is_discontinuous(::Interpolation)
-is_discontinuous(::Type{<:Interpolation})

Checks whether the interpolation is discontinuous (i.e. DiscontinuousLagrange)

source
Ferrite.adjust_dofs_during_distributionMethod
adjust_dofs_during_distribution(::Interpolation)

This function must return true if the dofs should be adjusted (i.e. permuted) during dof distribution. This is in contrast to i) adjusting the dofs during reinit! in the assembly loop, or ii) not adjusting at all (which is not needed for low order interpolations, generally).

source
Ferrite.mapping_typeFunction
mapping_type(ip::Interpolation)

Get the type of mapping from the reference cell to the real cell for an interpolation ip. Subtypes of ScalarInterpolation and VectorizedInterpolation return IdentityMapping(), but other non-scalar interpolations may request different mapping types.

source

for all entities which exist on that reference element. The dof functions default to having no dofs defined on a specific entity. Hence, not overloading of the dof functions will result in an element with zero dofs. Also, it should always be double checked that everything is consistent as specified in the docstring of the corresponding function, as inconsistent implementations can lead to bugs which are really difficult to track down.

+TODO: Separate nodal and non-nodal interpolations.
source
Ferrite.is_discontinuousMethod
is_discontinuous(::Interpolation)
+is_discontinuous(::Type{<:Interpolation})

Checks whether the interpolation is discontinuous (i.e. DiscontinuousLagrange)

source
Ferrite.adjust_dofs_during_distributionMethod
adjust_dofs_during_distribution(::Interpolation)

This function must return true if the dofs should be adjusted (i.e. permuted) during dof distribution. This is in contrast to i) adjusting the dofs during reinit! in the assembly loop, or ii) not adjusting at all (which is not needed for low order interpolations, generally).

source
Ferrite.mapping_typeFunction
mapping_type(ip::Interpolation)

Get the type of mapping from the reference cell to the real cell for an interpolation ip. Subtypes of ScalarInterpolation and VectorizedInterpolation return IdentityMapping(), but other non-scalar interpolations may request different mapping types.

source

for all entities which exist on that reference element. The dof functions default to having no dofs defined on a specific entity. Hence, not overloading of the dof functions will result in an element with zero dofs. Also, it should always be double checked that everything is consistent as specified in the docstring of the corresponding function, as inconsistent implementations can lead to bugs which are really difficult to track down.

diff --git a/dev/devdocs/performance/index.html b/dev/devdocs/performance/index.html index fc0791b99e..a7e8fd2869 100644 --- a/dev/devdocs/performance/index.html +++ b/dev/devdocs/performance/index.html @@ -1,2 +1,2 @@ -Performance analysis · Ferrite.jl

Performance analysis

In the benchmark folder we provide basic infrastructure to analyze the performance of Ferrite to help tracking down performance regression issues. Two basic tools can be directly executed via make: A basic benchmark for the current branch and a comparison between two commits. To execute the benchmark on the current branch only open a shell in the benchmark folder and call

make benchmark

whereas for the comparison of two commits simply call

make compare target=<target-commit> baseline=<baseline-commit>

If you have a custom julia executable that is not accessible via the julia command, then you can pass the executable via

JULIA_CMD=<path-to-julia-executable> make compare target=<target-commit> baseline=<baseline-commit>
Note

For the performance comparison between two commits you must not have any uncommitted or untracked files in your Ferrite.jl folder! Otherwise the PkgBenchmark.jl will fail to setup the comparison.

For more fine grained control you can run subsets of the benchmarks via by appending -<subset> to compare or benchmark, e.g.

make benchmark-mesh

to benchmark only the mesh functionality. The following subsets are currently available:

  • assembly
  • boundary-conditions
  • dofs
  • mesh
Note

It is recommended to run all benchmarks before running subsets to get the correct tuning parameters for each benchmark.

+Performance analysis · Ferrite.jl

Performance analysis

In the benchmark folder we provide basic infrastructure to analyze the performance of Ferrite to help tracking down performance regression issues. Two basic tools can be directly executed via make: A basic benchmark for the current branch and a comparison between two commits. To execute the benchmark on the current branch only open a shell in the benchmark folder and call

make benchmark

whereas for the comparison of two commits simply call

make compare target=<target-commit> baseline=<baseline-commit>

If you have a custom julia executable that is not accessible via the julia command, then you can pass the executable via

JULIA_CMD=<path-to-julia-executable> make compare target=<target-commit> baseline=<baseline-commit>
Note

For the performance comparison between two commits you must not have any uncommitted or untracked files in your Ferrite.jl folder! Otherwise the PkgBenchmark.jl will fail to setup the comparison.

For more fine grained control you can run subsets of the benchmarks via by appending -<subset> to compare or benchmark, e.g.

make benchmark-mesh

to benchmark only the mesh functionality. The following subsets are currently available:

  • assembly
  • boundary-conditions
  • dofs
  • mesh
Note

It is recommended to run all benchmarks before running subsets to get the correct tuning parameters for each benchmark.

diff --git a/dev/devdocs/reference_cells/index.html b/dev/devdocs/reference_cells/index.html index b1083f8b06..1c5215c301 100644 --- a/dev/devdocs/reference_cells/index.html +++ b/dev/devdocs/reference_cells/index.html @@ -1,5 +1,5 @@ -Reference cells · Ferrite.jl

Reference cells

The reference cells are used to i) define grid cells, ii) define shape functions, and iii) define quadrature rules. The numbering of vertices, edges, faces are visualized below. See also FerriteViz.elementinfo.

AbstractRefShape subtypes

Ferrite.RefLineType
RefLine <: AbstractRefShape{1}

Reference line/interval, reference dimension 1.

----------------+--------------------
+Reference cells · Ferrite.jl

Reference cells

The reference cells are used to i) define grid cells, ii) define shape functions, and iii) define quadrature rules. The numbering of vertices, edges, faces are visualized below. See also FerriteViz.elementinfo.

AbstractRefShape subtypes

Ferrite.RefLineType
RefLine <: AbstractRefShape{1}

Reference line/interval, reference dimension 1.

----------------+--------------------
 Vertex numbers: | Vertex coordinates:
   1-------2     | v1: 𝛏 = (-1.0,)
     --> ξ₁      | v2: 𝛏 = ( 1.0,)
@@ -7,7 +7,7 @@
 Face numbers:   | Face identifiers:
   1-------2     | f1: (v1,)
                 | f2: (v2,)
-----------------+--------------------
source
Ferrite.RefTriangleType
RefTriangle <: AbstractRefShape{2}

Reference triangle, reference dimension 2.

----------------+--------------------
+----------------+--------------------
source
Ferrite.RefTriangleType
RefTriangle <: AbstractRefShape{2}

Reference triangle, reference dimension 2.

----------------+--------------------
 Vertex numbers: | Vertex coordinates:
     2           |
     | \         | v1: 𝛏 = (1.0, 0.0)
@@ -22,7 +22,7 @@
     2   1       | f2: (v2, v3)
     |     \     | f3: (v3, v1)
     +---3---+   |
-----------------+--------------------
source
Ferrite.RefQuadrilateralType
RefQuadrilateral <: AbstractRefShape{2}

Reference quadrilateral, reference dimension 2.

----------------+---------------------
+----------------+--------------------
source
Ferrite.RefQuadrilateralType
RefQuadrilateral <: AbstractRefShape{2}

Reference quadrilateral, reference dimension 2.

----------------+---------------------
 Vertex numbers: | Vertex coordinates:
     4-------3   |
     |       |   | v1: 𝛏 = (-1.0, -1.0)
@@ -37,7 +37,7 @@
     4       2   | f3: (v3, v4)
     |       |   | f4: (v4, v1)
     +---1---+   |
-----------------+---------------------
source
Ferrite.RefTetrahedronType
RefTetrahedron <: AbstractRefShape{3}

Reference tetrahedron, reference dimension 3.

---------------------------------------+-------------------------
+----------------+---------------------
source
Ferrite.RefTetrahedronType
RefTetrahedron <: AbstractRefShape{3}

Reference tetrahedron, reference dimension 3.

---------------------------------------+-------------------------
 Vertex numbers:                        | Vertex coordinates:
              4                4        |
   ^ ξ₃      /  \             /| \      |  v1: 𝛏 = (0.0, 0.0, 0.0)
@@ -61,7 +61,7 @@
           /   3    \       /2 +___  \  | f3: (v2, v3, v4)
          /      __--+     / /  1 __‾-+ | f4: (v1, v4, v3)
         + __--‾‾         +/__--‾‾      |
----------------------------------------+-------------------------
source
Ferrite.RefHexahedronType
RefHexahedron <: AbstractRefShape{3}

Reference hexahedron, reference dimension 3.

-----------------------------------------+----------------------------
+---------------------------------------+-------------------------
source
Ferrite.RefHexahedronType
RefHexahedron <: AbstractRefShape{3}

Reference hexahedron, reference dimension 3.

-----------------------------------------+----------------------------
 Vertex numbers:                          | Vertex coordinates:
             5--------8        5--------8 | v1: 𝛏 = (-1.0, -1.0, -1.0)
            /        /|       /|        | | v2: 𝛏 = ( 1.0, -1.0, -1.0)
@@ -91,7 +91,7 @@
          |    3   | /      | /        /  |  f5: (v1, v5, v8, v4)
          |        |/       |/    1   /   |  f6: (v5, v6, v7, v8)
          +--------+        +--------+    |
------------------------------------------+-----------------------------
source
Ferrite.RefPrismType
RefPrism <: AbstractRefShape{3}

Reference prism, reference dimension 3.

-----------------------------------------+----------------------------
+-----------------------------------------+-----------------------------
source
Ferrite.RefPrismType
RefPrism <: AbstractRefShape{3}

Reference prism, reference dimension 3.

-----------------------------------------+----------------------------
 Vertex numbers:                          | Vertex coordinates:
             4-------/6       4--------6  |
            /     /   |      /|        |  |  v1: 𝛏 = (0.0, 0.0, 0.0)
@@ -121,8 +121,8 @@
          |       /        | /  1  /      | f5: (v4, v5, v6)
          |    /           |/   /         |
          + /              + /            |
------------------------------------------+----------------------------
source

Required methods to implement for all subtypes of AbstractRefShape to define a new reference shape

Ferrite.reference_verticesMethod
reference_vertices(::Type{<:AbstractRefShape})
-reference_vertices(::AbstractCell)

Returns a tuple of integers containing the local node indices corresponding to the vertices (i.e. corners or endpoints) of the cell.

source
Ferrite.reference_edgesMethod
reference_edges(::Type{<:AbstractRefShape})
-reference_edges(::AbstractCell)

Returns a tuple of 2-tuples containing the ordered local node indices (corresponding to the vertices) that define an edge.

source
Ferrite.reference_facesMethod
reference_faces(::Type{<:AbstractRefShape})
-reference_faces(::AbstractCell)

Returns a tuple of n-tuples containing the ordered local node indices (corresponding to the vertices) that define a face.

source

which automatically defines

Applicable methods to AbstractRefShapes

Ferrite.getrefdimMethod
Ferrite.getrefdim(RefShape::Type{<:AbstractRefShape})

Get the dimension of the reference shape

source
+-----------------------------------------+----------------------------
source

Required methods to implement for all subtypes of AbstractRefShape to define a new reference shape

Ferrite.reference_verticesMethod
reference_vertices(::Type{<:AbstractRefShape})
+reference_vertices(::AbstractCell)

Returns a tuple of integers containing the local node indices corresponding to the vertices (i.e. corners or endpoints) of the cell.

source
Ferrite.reference_edgesMethod
reference_edges(::Type{<:AbstractRefShape})
+reference_edges(::AbstractCell)

Returns a tuple of 2-tuples containing the ordered local node indices (corresponding to the vertices) that define an edge.

source
Ferrite.reference_facesMethod
reference_faces(::Type{<:AbstractRefShape})
+reference_faces(::AbstractCell)

Returns a tuple of n-tuples containing the ordered local node indices (corresponding to the vertices) that define a face.

source

which automatically defines

Applicable methods to AbstractRefShapes

Ferrite.getrefdimMethod
Ferrite.getrefdim(RefShape::Type{<:AbstractRefShape})

Get the dimension of the reference shape

source
diff --git a/dev/devdocs/special_datastructures/index.html b/dev/devdocs/special_datastructures/index.html index 89b9aa8684..718d6519e3 100644 --- a/dev/devdocs/special_datastructures/index.html +++ b/dev/devdocs/special_datastructures/index.html @@ -3,4 +3,4 @@ for (ind, val) in some_data push_at_index!(buffer, val, ind) end -end

sizehint tells how much space to allocate for the index ind if no val has been added to that index before, or how much more space to allocate in case all previously allocated space for ind has been used up.

source
ArrayOfVectorViews(b::CollectionsOfViews.ConstructionBuffer)

Creates the ArrayOfVectorViews directly from the ConstructionBuffer that was manually created and filled.

source
ArrayOfVectorViews(indices::Vector{Int}, data::Vector{T}, lin_idx::LinearIndices{N}; checkargs = true)

Creates the ArrayOfVectorViews directly where the user is responsible for having the correct input data. Checking of the argument dimensions can be elided by setting checkargs = false, but incorrect dimensions may lead to illegal out of bounds access later.

data is indexed by indices[i]:indices[i+1], where i = lin_idx[idx...] and idx... are the user-provided indices to the ArrayOfVectorViews.

source
Ferrite.CollectionsOfViews.ConstructionBufferType
ConstructionBuffer(data::Vector, dims::NTuple{N, Int}, sizehint)

Create a buffer for creating an ArrayOfVectorViews, representing an array with N axes. sizehint sets the number of elements in data allocated when a new index is added via push_at_index!, or when the current storage for the index is full, how much many additional elements are reserved for that index. Any content in data is overwritten, but performance is improved by pre-allocating it to a reasonable size or by sizehint!ing it.

source
Ferrite.CollectionsOfViews.push_at_index!Function
push_at_index!(b::ConstructionBuffer, val, indices::Int...)

push! the value val to the Vector view at the index given by indices, typically called inside the ArrayOfVectorViews constructor do-block. But can also be used when manually creating a ConstructionBuffer.

source
+end

sizehint tells how much space to allocate for the index ind if no val has been added to that index before, or how much more space to allocate in case all previously allocated space for ind has been used up.

source
ArrayOfVectorViews(b::CollectionsOfViews.ConstructionBuffer)

Creates the ArrayOfVectorViews directly from the ConstructionBuffer that was manually created and filled.

source
ArrayOfVectorViews(indices::Vector{Int}, data::Vector{T}, lin_idx::LinearIndices{N}; checkargs = true)

Creates the ArrayOfVectorViews directly where the user is responsible for having the correct input data. Checking of the argument dimensions can be elided by setting checkargs = false, but incorrect dimensions may lead to illegal out of bounds access later.

data is indexed by indices[i]:indices[i+1], where i = lin_idx[idx...] and idx... are the user-provided indices to the ArrayOfVectorViews.

source
Ferrite.CollectionsOfViews.ConstructionBufferType
ConstructionBuffer(data::Vector, dims::NTuple{N, Int}, sizehint)

Create a buffer for creating an ArrayOfVectorViews, representing an array with N axes. sizehint sets the number of elements in data allocated when a new index is added via push_at_index!, or when the current storage for the index is full, how much many additional elements are reserved for that index. Any content in data is overwritten, but performance is improved by pre-allocating it to a reasonable size or by sizehint!ing it.

source
Ferrite.CollectionsOfViews.push_at_index!Function
push_at_index!(b::ConstructionBuffer, val, indices::Int...)

push! the value val to the Vector view at the index given by indices, typically called inside the ArrayOfVectorViews constructor do-block. But can also be used when manually creating a ConstructionBuffer.

source
diff --git a/dev/gallery/helmholtz.ipynb b/dev/gallery/helmholtz.ipynb index f58c1ef2b0..434fc052c9 100644 --- a/dev/gallery/helmholtz.ipynb +++ b/dev/gallery/helmholtz.ipynb @@ -245,11 +245,11 @@ "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.11.1" + "version": "1.11.2" }, "kernelspec": { "name": "julia-1.11", - "display_name": "Julia 1.11.1", + "display_name": "Julia 1.11.2", "language": "julia" } }, diff --git a/dev/gallery/helmholtz/index.html b/dev/gallery/helmholtz/index.html index e24ba3c715..3c82a7f0fa 100644 --- a/dev/gallery/helmholtz/index.html +++ b/dev/gallery/helmholtz/index.html @@ -108,4 +108,4 @@ vtk = VTKGridFile("helmholtz", dh) write_solution(vtk, dh, u) close(vtk) -println("Helmholtz successful")
Helmholtz successful

This page was generated using Literate.jl.

+println("Helmholtz successful")
Helmholtz successful

This page was generated using Literate.jl.

diff --git a/dev/gallery/index.html b/dev/gallery/index.html index 039a5ba383..a28dbb3454 100644 --- a/dev/gallery/index.html +++ b/dev/gallery/index.html @@ -1,2 +1,2 @@ -Code gallery · Ferrite.jl

Code gallery

This page gives an overview of the code gallery. Compared to the tutorials, these programs do not focus on teaching Ferrite, but rather focus on showing how Ferrite can be used "in the wild".

Contribute to the gallery!

Most of the gallery is user contributed. If you use Ferrite, and have something you want to share, please contribute to the gallery! This could, for example, be your research code for a published paper, some interesting application, or just some nice trick.


Helmholtz equation

Solves the Helmholtz equation on the unit square using a combination of Dirichlet and Neumann boundary conditions and the method of manufactured solutions.

Contributed by: Kristoffer Carlsson (@KristofferC).


Nearly incompressible hyperelasticity

This program combines the ideas from Tutorial 3: Incompressible elasticity and Tutorial 4: Hyperelasticity to construct a mixed element solving three-dimensional displacement-pressure equations.

Contributed by: Bhavesh Shrimali (@bhaveshshrimali).


Ginzburg-Landau model energy minimization

A basic Ginzburg-Landau model is solved. ForwardDiff.jl is used to compute the gradient and hessian of the energy function. Multi-threading is used to parallelize the assembly procedure.

Contributed by: Louis Ponet (@louisponet).


Topology optimization

Topology optimization is shown for the bending problem by using a SIMP material model. To avoid numerical instabilities, a regularization scheme requiring the calculation of the Laplacian is imposed, which is done by using the grid topology functionalities.

Contributed by: Mischa Blaszczyk (@blaszm).

+Code gallery · Ferrite.jl

Code gallery

This page gives an overview of the code gallery. Compared to the tutorials, these programs do not focus on teaching Ferrite, but rather focus on showing how Ferrite can be used "in the wild".

Contribute to the gallery!

Most of the gallery is user contributed. If you use Ferrite, and have something you want to share, please contribute to the gallery! This could, for example, be your research code for a published paper, some interesting application, or just some nice trick.


Helmholtz equation

Solves the Helmholtz equation on the unit square using a combination of Dirichlet and Neumann boundary conditions and the method of manufactured solutions.

Contributed by: Kristoffer Carlsson (@KristofferC).


Nearly incompressible hyperelasticity

This program combines the ideas from Tutorial 3: Incompressible elasticity and Tutorial 4: Hyperelasticity to construct a mixed element solving three-dimensional displacement-pressure equations.

Contributed by: Bhavesh Shrimali (@bhaveshshrimali).


Ginzburg-Landau model energy minimization

A basic Ginzburg-Landau model is solved. ForwardDiff.jl is used to compute the gradient and hessian of the energy function. Multi-threading is used to parallelize the assembly procedure.

Contributed by: Louis Ponet (@louisponet).


Topology optimization

Topology optimization is shown for the bending problem by using a SIMP material model. To avoid numerical instabilities, a regularization scheme requiring the calculation of the Laplacian is imposed, which is done by using the grid topology functionalities.

Contributed by: Mischa Blaszczyk (@blaszm).

diff --git a/dev/gallery/landau.ipynb b/dev/gallery/landau.ipynb index 1ea7563c9c..46af8b8da1 100644 --- a/dev/gallery/landau.ipynb +++ b/dev/gallery/landau.ipynb @@ -596,32 +596,32 @@ "text": [ "Iter Function value Gradient norm \n", " 0 2.127588e+06 3.597094e+02\n", - " * time: 0.03091907501220703\n", + " * time: 0.02886795997619629\n", " 1 3.786155e+05 1.047687e+02\n", - " * time: 3.8988170623779297\n", + " * time: 3.7761099338531494\n", " 2 5.306125e+04 2.978953e+01\n", - " * time: 6.9175310134887695\n", + " * time: 6.71572208404541\n", " 3 -2.642320e+03 7.943136e+00\n", - " * time: 9.891350984573364\n", + " * time: 9.633095026016235\n", " 4 -1.027484e+04 1.752693e+00\n", - " * time: 12.850976943969727\n", + " * time: 12.533475160598755\n", " 5 -1.084925e+04 2.157295e-01\n", - " * time: 15.811126947402954\n", + " * time: 15.478846073150635\n", " 6 -1.085880e+04 5.288877e-03\n", - " * time: 18.79762601852417\n", + " * time: 18.399652004241943\n", " 7 -1.085881e+04 3.478176e-06\n", - " * time: 21.770689964294434\n", + " * time: 21.325783014297485\n", " 8 -1.085881e+04 1.596091e-12\n", - " * time: 24.74886989593506\n", + " * time: 24.234878063201904\n", " 9 -1.085881e+04 1.444882e-12\n", - " * time: 27.756438970565796\n", + " * time: 27.17616295814514\n", " 10 -1.085881e+04 1.548831e-13\n", - " * time: 30.768795013427734\n", + " * time: 30.096210956573486\n", " 11 -1.085881e+04 1.548831e-13\n", - " * time: 33.842238903045654\n", + " * time: 33.08599305152893\n", " 12 -1.085881e+04 1.508030e-13\n", - " * time: 34.29410004615784\n", - " 41.884315 seconds (14.84 M allocations: 4.057 GiB, 1.43% gc time, 13.55% compilation time)\n" + " * time: 33.56546902656555\n", + " 40.773502 seconds (14.89 M allocations: 4.060 GiB, 1.33% gc time, 13.07% compilation time)\n" ] } ], @@ -682,11 +682,11 @@ "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.11.1" + "version": "1.11.2" }, "kernelspec": { "name": "julia-1.11", - "display_name": "Julia 1.11.1", + "display_name": "Julia 1.11.2", "language": "julia" } }, diff --git a/dev/gallery/landau/index.html b/dev/gallery/landau/index.html index ecabd1b7d1..7366c44e78 100644 --- a/dev/gallery/landau/index.html +++ b/dev/gallery/landau/index.html @@ -190,29 +190,29 @@ @time minimize!(model) save_landau("landaufinal", model)
Iter     Function value   Gradient norm
      0     2.127588e+06     3.597094e+02
- * time: 8.893013000488281e-5
+ * time: 8.702278137207031e-5
      1     3.786155e+05     1.047687e+02
- * time: 3.4352729320526123
+ * time: 2.988862991333008
      2     5.306125e+04     2.978953e+01
- * time: 6.405318975448608
+ * time: 5.91060996055603
      3    -2.642320e+03     7.943136e+00
- * time: 9.375922918319702
+ * time: 8.841558933258057
      4    -1.027484e+04     1.752693e+00
- * time: 12.358008861541748
+ * time: 11.765846967697144
      5    -1.084925e+04     2.157295e-01
- * time: 15.347643852233887
+ * time: 14.68187689781189
      6    -1.085880e+04     5.288877e-03
- * time: 18.321012020111084
+ * time: 17.583351850509644
      7    -1.085881e+04     3.478176e-06
- * time: 21.312822818756104
+ * time: 20.49354100227356
      8    -1.085881e+04     1.596091e-12
- * time: 24.3050320148468
+ * time: 23.404705047607422
      9    -1.085881e+04     1.444882e-12
- * time: 27.305541038513184
+ * time: 26.34315299987793
     10    -1.085881e+04     1.548831e-13
- * time: 30.293956995010376
+ * time: 29.2651629447937
     11    -1.085881e+04     1.548831e-13
- * time: 33.384652853012085
+ * time: 32.28685784339905
     12    -1.085881e+04     1.508030e-13
- * time: 33.83502984046936
- 40.089090 seconds (11.20 M allocations: 3.880 GiB, 1.48% gc time, 8.42% compilation time)

as we can see this runs very quickly even for relatively large gridsizes. The key to get high performance like this is to minimize the allocations inside the threaded loops, ideally to 0.


This page was generated using Literate.jl.

+ * time: 32.71817183494568 + 39.262917 seconds (11.21 M allocations: 3.880 GiB, 1.38% gc time, 8.64% compilation time)

as we can see this runs very quickly even for relatively large gridsizes. The key to get high performance like this is to minimize the allocations inside the threaded loops, ideally to 0.


This page was generated using Literate.jl.

diff --git a/dev/gallery/quasi_incompressible_hyperelasticity.ipynb b/dev/gallery/quasi_incompressible_hyperelasticity.ipynb index a878f17e6d..c9fc32993e 100644 --- a/dev/gallery/quasi_incompressible_hyperelasticity.ipynb +++ b/dev/gallery/quasi_incompressible_hyperelasticity.ipynb @@ -610,11 +610,11 @@ "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.11.1" + "version": "1.11.2" }, "kernelspec": { "name": "julia-1.11", - "display_name": "Julia 1.11.1", + "display_name": "Julia 1.11.2", "language": "julia" } }, diff --git a/dev/gallery/quasi_incompressible_hyperelasticity/index.html b/dev/gallery/quasi_incompressible_hyperelasticity/index.html index c206497d54..085beb76d0 100644 --- a/dev/gallery/quasi_incompressible_hyperelasticity/index.html +++ b/dev/gallery/quasi_incompressible_hyperelasticity/index.html @@ -485,4 +485,4 @@ quadratic_u = Lagrange{RefTetrahedron, 2}()^3 linear_p = Lagrange{RefTetrahedron, 1}() -vol_def = solve(quadratic_u, linear_p)

This page was generated using Literate.jl.

+vol_def = solve(quadratic_u, linear_p)

This page was generated using Literate.jl.

diff --git a/dev/gallery/topology_optimization.ipynb b/dev/gallery/topology_optimization.ipynb index 8e5dce8dc6..e3ecf38a1b 100644 --- a/dev/gallery/topology_optimization.ipynb +++ b/dev/gallery/topology_optimization.ipynb @@ -827,7 +827,7 @@ " Starting Newton iterations\n", "Converged at iteration number: 65\n", "Rel. stiffness: 4.8466 \n", - " 4.730695 seconds (2.44 M allocations: 2.015 GiB, 2.06% gc time, 6.79% compilation time)\n" + " 4.598526 seconds (2.45 M allocations: 2.016 GiB, 2.03% gc time, 6.47% compilation time)\n" ] } ], @@ -869,11 +869,11 @@ "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.11.1" + "version": "1.11.2" }, "kernelspec": { "name": "julia-1.11", - "display_name": "Julia 1.11.1", + "display_name": "Julia 1.11.2", "language": "julia" } }, diff --git a/dev/gallery/topology_optimization/index.html b/dev/gallery/topology_optimization/index.html index ae42d267f2..976e93377d 100644 --- a/dev/gallery/topology_optimization/index.html +++ b/dev/gallery/topology_optimization/index.html @@ -365,7 +365,7 @@ Starting Newton iterations Converged at iteration number: 65 Rel. stiffness: 4.8466 - 4.596749 seconds (2.24 M allocations: 2.005 GiB, 2.14% gc time, 1.93% compilation time)

We observe, that the stiffness for the lower value of $ra$ is higher, but also requires more iterations until convergence and finer structures to be manufactured, as can be seen in Figure 2:

Figure 2: Optimization results of the bending beam for smaller (left) and larger (right) value of the regularization parameter $\beta$.

To prove mesh independence, the user could vary the mesh resolution and compare the results.

References

[14]
D. R. Jantos, K. Hackl and P. Junker. An accurate and fast regularization approach to thermodynamic topology optimization. International Journal for Numerical Methods in Engineering 117, 991–1017 (2019).
[15]
M. Blaszczyk, D. R. Jantos and P. Junker. Application of Taylor series combined with the weighted least square method to thermodynamic topology optimization. Computer Methods in Applied Mechanics and Engineering 393, 114698 (2022).

Plain program

Here follows a version of the program without any comments. The file is also available here: topology_optimization.jl.

using Ferrite, SparseArrays, LinearAlgebra, Tensors, Printf
+  4.499255 seconds (2.24 M allocations: 2.005 GiB, 2.33% gc time, 1.80% compilation time)

We observe, that the stiffness for the lower value of $ra$ is higher, but also requires more iterations until convergence and finer structures to be manufactured, as can be seen in Figure 2:

Figure 2: Optimization results of the bending beam for smaller (left) and larger (right) value of the regularization parameter $\beta$.

To prove mesh independence, the user could vary the mesh resolution and compare the results.

References

[14]
D. R. Jantos, K. Hackl and P. Junker. An accurate and fast regularization approach to thermodynamic topology optimization. International Journal for Numerical Methods in Engineering 117, 991–1017 (2019).
[15]
M. Blaszczyk, D. R. Jantos and P. Junker. Application of Taylor series combined with the weighted least square method to thermodynamic topology optimization. Computer Methods in Applied Mechanics and Engineering 393, 114698 (2022).

Plain program

Here follows a version of the program without any comments. The file is also available here: topology_optimization.jl.

using Ferrite, SparseArrays, LinearAlgebra, Tensors, Printf
 
 function create_grid(n)
     corners = [
@@ -755,4 +755,4 @@
 end
 
 @time topopt(0.03, 0.5, 60, "large_radius"; output = :false);
-#topopt(0.02, 0.5, 60, "topopt_animation"; output=:true); # can be used to create animations

This page was generated using Literate.jl.

+#topopt(0.02, 0.5, 60, "topopt_animation"; output=:true); # can be used to create animations

This page was generated using Literate.jl.

diff --git a/dev/howto/index.html b/dev/howto/index.html index 5cb245eaf0..7eb1da311d 100644 --- a/dev/howto/index.html +++ b/dev/howto/index.html @@ -1,2 +1,2 @@ -How-to guide overview · Ferrite.jl

How-to guides

This page gives an overview of the how-to guides. How-to guides address various common tasks one might want to do in a finite element program. Many of the guides are extensions, or build on top of, the tutorials and, therefore, some familiarity with Ferrite is assumed.


Post processing and visualization

This guide builds on top of Tutorial 1: Heat equation and discusses various post processsing techniques with the goal of visualizing primary fields (the finite element solution) and secondary quantities (e.g. fluxes, stresses, etc.). Concretely, this guide answers:

  • How to visualize data from quadrature points?
  • How to evaluate the finite element solution, or secondary quantities, in arbitrary points of the domain?

Multi-threaded assembly

This guide modifies Tutorial 2: Linear elasticity such that the program is using multi-threading to parallelize the assembly procedure. Concretely this shows how to use grid coloring and "scratch values" in order to use multi-threading without running into race-conditions.


+How-to guide overview · Ferrite.jl

How-to guides

This page gives an overview of the how-to guides. How-to guides address various common tasks one might want to do in a finite element program. Many of the guides are extensions, or build on top of, the tutorials and, therefore, some familiarity with Ferrite is assumed.


Post processing and visualization

This guide builds on top of Tutorial 1: Heat equation and discusses various post processsing techniques with the goal of visualizing primary fields (the finite element solution) and secondary quantities (e.g. fluxes, stresses, etc.). Concretely, this guide answers:

  • How to visualize data from quadrature points?
  • How to evaluate the finite element solution, or secondary quantities, in arbitrary points of the domain?

Multi-threaded assembly

This guide modifies Tutorial 2: Linear elasticity such that the program is using multi-threading to parallelize the assembly procedure. Concretely this shows how to use grid coloring and "scratch values" in order to use multi-threading without running into race-conditions.


diff --git a/dev/howto/postprocessing.ipynb b/dev/howto/postprocessing.ipynb index 4019636a38..a4f2e2ebe3 100644 --- a/dev/howto/postprocessing.ipynb +++ b/dev/howto/postprocessing.ipynb @@ -301,94 +301,94 @@ "\n", "\n", "\n", - " \n", + " \n", " \n", " \n", "\n", - "\n", + "\n", "\n", - " \n", + " \n", " \n", " \n", "\n", - "\n", + "\n", "\n", - " \n", + " \n", " \n", " \n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n" ], "image/svg+xml": [ "\n", "\n", "\n", - " \n", + " \n", " \n", " \n", "\n", - "\n", + "\n", "\n", - " \n", + " \n", " \n", " \n", "\n", - "\n", + "\n", "\n", - " \n", + " \n", " \n", " \n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n" ] }, @@ -428,98 +428,98 @@ "\n", "\n", "\n", - " \n", + " \n", " \n", " \n", "\n", - "\n", + "\n", "\n", - " \n", + " \n", " \n", " \n", "\n", - "\n", + "\n", "\n", - " \n", + " \n", " \n", " \n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n" ], "image/svg+xml": [ "\n", "\n", "\n", - " \n", + " \n", " \n", " \n", "\n", - "\n", + "\n", "\n", - " \n", + " \n", " \n", " \n", "\n", - "\n", + "\n", "\n", - " \n", + " \n", " \n", " \n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n" ] }, @@ -557,11 +557,11 @@ "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.11.1" + "version": "1.11.2" }, "kernelspec": { "name": "julia-1.11", - "display_name": "Julia 1.11.1", + "display_name": "Julia 1.11.2", "language": "julia" } }, diff --git a/dev/howto/postprocessing/cec17e3d.svg b/dev/howto/postprocessing/65fd2955.svg similarity index 85% rename from dev/howto/postprocessing/cec17e3d.svg rename to dev/howto/postprocessing/65fd2955.svg index e2f4908d60..eeed670f2c 100644 --- a/dev/howto/postprocessing/cec17e3d.svg +++ b/dev/howto/postprocessing/65fd2955.svg @@ -1,45 +1,45 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/howto/postprocessing/8f17429f.svg b/dev/howto/postprocessing/a72d71eb.svg similarity index 83% rename from dev/howto/postprocessing/8f17429f.svg rename to dev/howto/postprocessing/a72d71eb.svg index ca39f5f4ba..07ea7b4cbb 100644 --- a/dev/howto/postprocessing/8f17429f.svg +++ b/dev/howto/postprocessing/a72d71eb.svg @@ -1,47 +1,47 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/howto/postprocessing/index.html b/dev/howto/postprocessing/index.html index 2f4d2c472b..7328e4e712 100644 --- a/dev/howto/postprocessing/index.html +++ b/dev/howto/postprocessing/index.html @@ -22,7 +22,7 @@ return q end

Now call the function to get all the fluxes.

q_gp = compute_heat_fluxes(cellvalues, dh, u);

Next, create an L2Projector using the same interpolation as was used to approximate the temperature field. On instantiation, the projector assembles the coefficient matrix M and computes the Cholesky factorization of it. By doing so, the projector can be reused without having to invert M every time.

projector = L2Projector(ip, grid);

Project the integration point values to the nodal values

q_projected = project(projector, q_gp, qr);

Exporting to VTK

To visualize the heat flux, we export the projected field q_projected to a VTK-file, which can be viewed in e.g. ParaView. The result is also visualized in Figure 1.

VTKGridFile("heat_equation_flux", grid) do vtk
     write_projection(vtk, projector, q_projected, "q")
-end;

Point evaluation

Figure 2: Visualization of the cut line where we want to compute the temperature and heat flux.

Consider a cut-line through the domain like the black line in Figure 2 above. We will evaluate the temperature and the heat flux distribution along a horizontal line.

points = [Vec((x, 0.75)) for x in range(-1.0, 1.0, length = 101)];

First, we need to generate a PointEvalHandler. This will find and store the cells containing the input points.

ph = PointEvalHandler(grid, points);

After the L2-Projection, the heat fluxes q_projected are stored in the DoF-ordering determined by the projector's internal DoFHandler, so to evaluate the flux q at our points we give the PointEvalHandler, the L2Projector and the values q_projected.

q_points = evaluate_at_points(ph, projector, q_projected);

We can also extract the field values, here the temperature, right away from the result vector of the simulation, that is stored in u. These values are stored in the order of our initial DofHandler so the input is not the PointEvalHandler, the original DofHandler, the dof-vector u, and (optionally for single-field problems) the name of the field. From the L2Projection, the values are stored in the order of the degrees of freedom.

u_points = evaluate_at_points(ph, dh, u, :u);

Now, we can plot the temperature and flux values with the help of any plotting library, e.g. Plots.jl. To do this, we need to import the package:

import Plots

Firstly, we are going to plot the temperature values along the given line.

Plots.plot(getindex.(points, 1), u_points, xlabel = "x (coordinate)", ylabel = "u (temperature)", label = nothing)
Example block output

Figure 3: Temperature along the cut line from Figure 2.

Secondly, the horizontal heat flux (i.e. the first component of the heat flux vector) is plotted.

Plots.plot(getindex.(points, 1), getindex.(q_points, 1), xlabel = "x (coordinate)", ylabel = "q_x (flux in x-direction)", label = nothing)
Example block output

Figure 4: $x$-component of the flux along the cut line from Figure 2.

Plain program

Here follows a version of the program without any comments. The file is also available here: postprocessing.jl.

include("../tutorials/heat_equation.jl");
+end;

Point evaluation

Figure 2: Visualization of the cut line where we want to compute the temperature and heat flux.

Consider a cut-line through the domain like the black line in Figure 2 above. We will evaluate the temperature and the heat flux distribution along a horizontal line.

points = [Vec((x, 0.75)) for x in range(-1.0, 1.0, length = 101)];

First, we need to generate a PointEvalHandler. This will find and store the cells containing the input points.

ph = PointEvalHandler(grid, points);

After the L2-Projection, the heat fluxes q_projected are stored in the DoF-ordering determined by the projector's internal DoFHandler, so to evaluate the flux q at our points we give the PointEvalHandler, the L2Projector and the values q_projected.

q_points = evaluate_at_points(ph, projector, q_projected);

We can also extract the field values, here the temperature, right away from the result vector of the simulation, that is stored in u. These values are stored in the order of our initial DofHandler so the input is not the PointEvalHandler, the original DofHandler, the dof-vector u, and (optionally for single-field problems) the name of the field. From the L2Projection, the values are stored in the order of the degrees of freedom.

u_points = evaluate_at_points(ph, dh, u, :u);

Now, we can plot the temperature and flux values with the help of any plotting library, e.g. Plots.jl. To do this, we need to import the package:

import Plots

Firstly, we are going to plot the temperature values along the given line.

Plots.plot(getindex.(points, 1), u_points, xlabel = "x (coordinate)", ylabel = "u (temperature)", label = nothing)
Example block output

Figure 3: Temperature along the cut line from Figure 2.

Secondly, the horizontal heat flux (i.e. the first component of the heat flux vector) is plotted.

Plots.plot(getindex.(points, 1), getindex.(q_points, 1), xlabel = "x (coordinate)", ylabel = "q_x (flux in x-direction)", label = nothing)
Example block output

Figure 4: $x$-component of the flux along the cut line from Figure 2.

Plain program

Here follows a version of the program without any comments. The file is also available here: postprocessing.jl.

include("../tutorials/heat_equation.jl");
 
 function compute_heat_fluxes(cellvalues::CellValues, dh::DofHandler, a::AbstractVector{T}) where {T}
 
@@ -69,4 +69,4 @@
 
 Plots.plot(getindex.(points, 1), u_points, xlabel = "x (coordinate)", ylabel = "u (temperature)", label = nothing)
 
-Plots.plot(getindex.(points, 1), getindex.(q_points, 1), xlabel = "x (coordinate)", ylabel = "q_x (flux in x-direction)", label = nothing)

This page was generated using Literate.jl.

+Plots.plot(getindex.(points, 1), getindex.(q_points, 1), xlabel = "x (coordinate)", ylabel = "q_x (flux in x-direction)", label = nothing)

This page was generated using Literate.jl.

diff --git a/dev/howto/threaded_assembly.ipynb b/dev/howto/threaded_assembly.ipynb index 291a7a2295..633bcf5594 100644 --- a/dev/howto/threaded_assembly.ipynb +++ b/dev/howto/threaded_assembly.ipynb @@ -429,11 +429,11 @@ "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.11.1" + "version": "1.11.2" }, "kernelspec": { "name": "julia-1.11", - "display_name": "Julia 1.11.1", + "display_name": "Julia 1.11.2", "language": "julia" } }, diff --git a/dev/howto/threaded_assembly/index.html b/dev/howto/threaded_assembly/index.html index 54308f4851..5ee6492fcc 100644 --- a/dev/howto/threaded_assembly/index.html +++ b/dev/howto/threaded_assembly/index.html @@ -275,4 +275,4 @@ @time assemble_global!(K, f, dh, colors, cellvalues; ntasks = ntasks) return end -nothing # hide

This page was generated using Literate.jl.

+nothing # hide

This page was generated using Literate.jl.

diff --git a/dev/index.html b/dev/index.html index bf1c6a8993..a8133911ff 100644 --- a/dev/index.html +++ b/dev/index.html @@ -1,2 +1,2 @@ -Home · Ferrite.jl

Ferrite.jl

Welcome to the documentation for Ferrite.jl! Ferrite is a finite element toolbox that provides functionalities to implement finite element analysis in Julia. The aim is to be i) general, ii) performant, and iii) to keep mathematical abstractions.

Upgrading code from version 0.3.x to version 1.0

Ferrite version 1.0 contains a number of breaking changes compared to version 0.3.x. The Changelog documents all changes and there is also a section specifically for Upgrading code from Ferrite 0.3 to 1.0.

Note

Please help improve this documentation – if something confuses you, chances are you're not alone. It's easy to do as you read along: just click on the "Edit on GitHub" link at the top of each page, and then edit the files directly in your browser. Your changes will be vetted by developers before becoming permanent, so don't worry about whether you might say something wrong. See also Contributing to Ferrite for more details.

How the documentation is organized

This high level view of the documentation structure will help you find what you are looking for. The document is organized as follows[1]:

  • Tutorials are thoroughly documented examples which guides you through the process of solving partial differential equations using Ferrite.
  • Topic guides contains more in-depth explanations and discussions about finite element programming concepts and ideas, and specifically how these are realized in Ferrite.
  • Reference contains the technical API reference of functions and methods (e.g. the documentation strings).
  • How-to guides will guide you through the steps involved in addressing common tasks and use-cases. These usually build on top of the tutorials and thus assume basic knowledge of how Ferrite works.

The four sections above form the main user-facing parts of the documentation. In addition, the document also contain the following sections:

  • Code gallery contain user contributed example programs showcasing what can be done with Ferrite.
  • Changelog contain release notes and information about how to upgrade between releases.
  • Developer documentation contain documentation of Ferrite internal code and is mainly targeted at developers of Ferrite.

Getting started

As a new user of Ferrite it is suggested to start working with the tutorials before using Ferrite to tackle the specific equation you ultimately want to solve. The tutorials start with explaining the basic concepts and then increase in complexity. Understanding the first tutorial program, solving the heat equation, is essential in order to understand how Ferrite works. Already this rather simple program discusses many of the important concepts. See the tutorials overview for suggestion on how to progress to more advanced usage.

Getting help

If you have questions about Ferrite it is suggested to use the #ferrite-fem channel on the Julia Slack, or the #Ferrite.jl stream on Zulip. Alternatively you can use the discussion forum on the GitHub repository.

Installation

To use Ferrite you first need to install Julia, see https://julialang.org/ for details. Installing Ferrite can then be done from the Pkg REPL; press ] at the julia> promp to enter pkg> mode:

pkg> add Ferrite

This will install Ferrite and all necessary dependencies. Press backspace to get back to the julia> prompt. (See the documentation for Pkg, Julia's package manager, for more help regarding package installation and project management.)

Finally, to load Ferrite, use

using Ferrite

You are now all set to start using Ferrite!

Contributing to Ferrite

Ferrite is still under active development. If you find a bug, or have ideas for improvements, you are encouraged to interact with the developers on the Ferrite GitHub repository. There is also a thorough contributor guide which can be found in CONTRIBUTING.md.

+Home · Ferrite.jl

Ferrite.jl

Welcome to the documentation for Ferrite.jl! Ferrite is a finite element toolbox that provides functionalities to implement finite element analysis in Julia. The aim is to be i) general, ii) performant, and iii) to keep mathematical abstractions.

Upgrading code from version 0.3.x to version 1.0

Ferrite version 1.0 contains a number of breaking changes compared to version 0.3.x. The Changelog documents all changes and there is also a section specifically for Upgrading code from Ferrite 0.3 to 1.0.

Note

Please help improve this documentation – if something confuses you, chances are you're not alone. It's easy to do as you read along: just click on the "Edit on GitHub" link at the top of each page, and then edit the files directly in your browser. Your changes will be vetted by developers before becoming permanent, so don't worry about whether you might say something wrong. See also Contributing to Ferrite for more details.

How the documentation is organized

This high level view of the documentation structure will help you find what you are looking for. The document is organized as follows[1]:

  • Tutorials are thoroughly documented examples which guides you through the process of solving partial differential equations using Ferrite.
  • Topic guides contains more in-depth explanations and discussions about finite element programming concepts and ideas, and specifically how these are realized in Ferrite.
  • Reference contains the technical API reference of functions and methods (e.g. the documentation strings).
  • How-to guides will guide you through the steps involved in addressing common tasks and use-cases. These usually build on top of the tutorials and thus assume basic knowledge of how Ferrite works.

The four sections above form the main user-facing parts of the documentation. In addition, the document also contain the following sections:

  • Code gallery contain user contributed example programs showcasing what can be done with Ferrite.
  • Changelog contain release notes and information about how to upgrade between releases.
  • Developer documentation contain documentation of Ferrite internal code and is mainly targeted at developers of Ferrite.

Getting started

As a new user of Ferrite it is suggested to start working with the tutorials before using Ferrite to tackle the specific equation you ultimately want to solve. The tutorials start with explaining the basic concepts and then increase in complexity. Understanding the first tutorial program, solving the heat equation, is essential in order to understand how Ferrite works. Already this rather simple program discusses many of the important concepts. See the tutorials overview for suggestion on how to progress to more advanced usage.

Getting help

If you have questions about Ferrite it is suggested to use the #ferrite-fem channel on the Julia Slack, or the #Ferrite.jl stream on Zulip. Alternatively you can use the discussion forum on the GitHub repository.

Installation

To use Ferrite you first need to install Julia, see https://julialang.org/ for details. Installing Ferrite can then be done from the Pkg REPL; press ] at the julia> promp to enter pkg> mode:

pkg> add Ferrite

This will install Ferrite and all necessary dependencies. Press backspace to get back to the julia> prompt. (See the documentation for Pkg, Julia's package manager, for more help regarding package installation and project management.)

Finally, to load Ferrite, use

using Ferrite

You are now all set to start using Ferrite!

Contributing to Ferrite

Ferrite is still under active development. If you find a bug, or have ideas for improvements, you are encouraged to interact with the developers on the Ferrite GitHub repository. There is also a thorough contributor guide which can be found in CONTRIBUTING.md.

diff --git a/dev/reference/assembly/index.html b/dev/reference/assembly/index.html index a13cb40cab..75f4154f3f 100644 --- a/dev/reference/assembly/index.html +++ b/dev/reference/assembly/index.html @@ -1,6 +1,6 @@ Assembly · Ferrite.jl

Assembly

Ferrite.start_assembleFunction
start_assemble(K::AbstractSparseMatrixCSC;            fillzero::Bool=true) -> CSCAssembler
 start_assemble(K::AbstractSparseMatrixCSC, f::Vector; fillzero::Bool=true) -> CSCAssembler

Create a CSCAssembler from the matrix K and optional vector f.

start_assemble(K::Symmetric{AbstractSparseMatrixCSC};                 fillzero::Bool=true) -> SymmetricCSCAssembler
-start_assemble(K::Symmetric{AbstractSparseMatrixCSC}, f::Vector=Td[]; fillzero::Bool=true) -> SymmetricCSCAssembler

Create a SymmetricCSCAssembler from the matrix K and optional vector f.

CSCAssembler and SymmetricCSCAssembler allocate workspace necessary for efficient matrix assembly. To assemble the contribution from an element, use assemble!.

The keyword argument fillzero can be set to false if K and f should not be zeroed out, but instead keep their current values.

source
Ferrite.assemble!Function
assemble!(a::COOAssembler, dofs, Ke)
-assemble!(a::COOAssembler, dofs, Ke, fe)

Assembles the element matrix Ke and element vector fe into a.

source
assemble!(a::COOAssembler, rowdofs, coldofs, Ke)

Assembles the matrix Ke into a according to the dofs specified by rowdofs and coldofs.

source
assemble!(g, dofs, ge)

Assembles the element residual ge into the global residual vector g.

source
assemble!(A::AbstractAssembler, dofs::AbstractVector{Int}, Ke::AbstractMatrix)
-assemble!(A::AbstractAssembler, dofs::AbstractVector{Int}, Ke::AbstractMatrix, fe::AbstractVector)

Assemble the element stiffness matrix Ke (and optional force vector fe) into the global stiffness (and force) in A, given the element degrees of freedom dofs.

This is equivalent to K[dofs, dofs] += Ke and f[dofs] += fe, where K is the global stiffness matrix and f the global force/residual vector, but more efficient.

source
Ferrite.finish_assembleFunction
finish_assemble(a::COOAssembler) -> K, f

Finalize the assembly and return the sparse matrix K::SparseMatrixCSC and vector f::Vector. If the assembler have not been used for vector assembly, f is an empty vector.

source
+start_assemble(K::Symmetric{AbstractSparseMatrixCSC}, f::Vector=Td[]; fillzero::Bool=true) -> SymmetricCSCAssembler

Create a SymmetricCSCAssembler from the matrix K and optional vector f.

CSCAssembler and SymmetricCSCAssembler allocate workspace necessary for efficient matrix assembly. To assemble the contribution from an element, use assemble!.

The keyword argument fillzero can be set to false if K and f should not be zeroed out, but instead keep their current values.

source
Ferrite.assemble!Function
assemble!(a::COOAssembler, dofs, Ke)
+assemble!(a::COOAssembler, dofs, Ke, fe)

Assembles the element matrix Ke and element vector fe into a.

source
assemble!(a::COOAssembler, rowdofs, coldofs, Ke)

Assembles the matrix Ke into a according to the dofs specified by rowdofs and coldofs.

source
assemble!(g, dofs, ge)

Assembles the element residual ge into the global residual vector g.

source
assemble!(A::AbstractAssembler, dofs::AbstractVector{Int}, Ke::AbstractMatrix)
+assemble!(A::AbstractAssembler, dofs::AbstractVector{Int}, Ke::AbstractMatrix, fe::AbstractVector)

Assemble the element stiffness matrix Ke (and optional force vector fe) into the global stiffness (and force) in A, given the element degrees of freedom dofs.

This is equivalent to K[dofs, dofs] += Ke and f[dofs] += fe, where K is the global stiffness matrix and f the global force/residual vector, but more efficient.

source
Ferrite.finish_assembleFunction
finish_assemble(a::COOAssembler) -> K, f

Finalize the assembly and return the sparse matrix K::SparseMatrixCSC and vector f::Vector. If the assembler have not been used for vector assembly, f is an empty vector.

source
diff --git a/dev/reference/boundary_conditions/index.html b/dev/reference/boundary_conditions/index.html index 1e1c31e110..b6ba0b7798 100644 --- a/dev/reference/boundary_conditions/index.html +++ b/dev/reference/boundary_conditions/index.html @@ -1,5 +1,5 @@ -Boundary conditions · Ferrite.jl

Boundary conditions

Ferrite.ConstraintHandlerType
ConstraintHandler([T=Float64], dh::AbstractDofHandler)

A collection of constraints associated with the dof handler dh. T is the numeric type for stored values.

source
Ferrite.DirichletType
Dirichlet(u::Symbol, ∂Ω::AbstractVecOrSet, f::Function, components=nothing)

Create a Dirichlet boundary condition on u on the ∂Ω part of the boundary. f is a function of the form f(x) or f(x, t) where x is the spatial coordinate and t is the current time, and returns the prescribed value. components specify the components of u that are prescribed by this condition. By default all components of u are prescribed.

The set, ∂Ω, can be an AbstractSet or AbstractVector with elements of type FacetIndex, FaceIndex, EdgeIndex, VertexIndex, or Int. For most cases, the element type is FacetIndex, as shown below. To constrain a single point, using VertexIndex is recommended, but it is also possible to constrain a specific nodes by giving the node numbers via Int elements. To constrain e.g. an edge in 3d EdgeIndex elements can be given.

For example, here we create a Dirichlet condition for the :u field, on the facetset called ∂Ω and the value given by the sin function:

Examples

# Obtain the facetset from the grid
+Boundary conditions · Ferrite.jl

Boundary conditions

Ferrite.ConstraintHandlerType
ConstraintHandler([T=Float64], dh::AbstractDofHandler)

A collection of constraints associated with the dof handler dh. T is the numeric type for stored values.

source
Ferrite.DirichletType
Dirichlet(u::Symbol, ∂Ω::AbstractVecOrSet, f::Function, components=nothing)

Create a Dirichlet boundary condition on u on the ∂Ω part of the boundary. f is a function of the form f(x) or f(x, t) where x is the spatial coordinate and t is the current time, and returns the prescribed value. components specify the components of u that are prescribed by this condition. By default all components of u are prescribed.

The set, ∂Ω, can be an AbstractSet or AbstractVector with elements of type FacetIndex, FaceIndex, EdgeIndex, VertexIndex, or Int. For most cases, the element type is FacetIndex, as shown below. To constrain a single point, using VertexIndex is recommended, but it is also possible to constrain a specific nodes by giving the node numbers via Int elements. To constrain e.g. an edge in 3d EdgeIndex elements can be given.

For example, here we create a Dirichlet condition for the :u field, on the facetset called ∂Ω and the value given by the sin function:

Examples

# Obtain the facetset from the grid
 ∂Ω = getfacetset(grid, "boundary-1")
 
 # Prescribe scalar field :s on ∂Ω to sin(t)
@@ -9,26 +9,26 @@
 dbc = Dirichlet(:v, ∂Ω, x -> 0 * x)
 
 # Prescribe component 2 and 3 of vector field :v on ∂Ω to [sin(t), cos(t)]
-dbc = Dirichlet(:v, ∂Ω, (x, t) -> [sin(t), cos(t)], [2, 3])

Dirichlet boundary conditions are added to a ConstraintHandler which applies the condition via apply! and/or apply_zero!.

source
Ferrite.PeriodicDirichletType
PeriodicDirichlet(u::Symbol, facet_mapping, components=nothing)
 PeriodicDirichlet(u::Symbol, facet_mapping, R::AbstractMatrix, components=nothing)
-PeriodicDirichlet(u::Symbol, facet_mapping, f::Function, components=nothing)

Create a periodic Dirichlet boundary condition for the field u on the facet-pairs given in facet_mapping. The mapping can be computed with collect_periodic_facets. The constraint ensures that degrees-of-freedom on the mirror facet are constrained to the corresponding degrees-of-freedom on the image facet. components specify the components of u that are prescribed by this condition. By default all components of u are prescribed.

If the mapping is not aligned with the coordinate axis (e.g. rotated) a rotation matrix R should be passed to the constructor. This matrix rotates dofs on the mirror facet to the image facet. Note that this is only applicable for vector-valued problems.

To construct an inhomogeneous periodic constraint it is possible to pass a function f. Note that this is currently only supported when the periodicity is aligned with the coordinate axes.

See the manual section on Periodic boundary conditions for more information.

source
Ferrite.collect_periodic_facetsFunction
collect_periodic_facets(grid::Grid, mset, iset, transform::Union{Function,Nothing}=nothing; tol=1e-12)

Match all mirror facets in mset with a corresponding image facet in iset. Return a dictionary which maps each mirror facet to a image facet. The result can then be passed to PeriodicDirichlet.

mset and iset can be given as a String (an existing facet set in the grid) or as a AbstractSet{FacetIndex} directly.

By default this function looks for a matching facet in the directions of the coordinate system. For other types of periodicities the transform function can be used. The transform function is applied on the coordinates of the image facet, and is expected to transform the coordinates to the matching locations in the mirror set.

The keyword tol specifies the tolerance (i.e. distance and deviation in facet-normals) between a image-facet and mirror-facet, for them to be considered matched.

See also: collect_periodic_facets!, PeriodicDirichlet.

source
collect_periodic_facets(grid::Grid, all_facets::Union{AbstractSet{FacetIndex},String,Nothing}=nothing; tol=1e-12)

Split all facets in all_facets into image and mirror sets. For each matching pair, the facet located further along the vector (1, 1, 1) becomes the image facet.

If no set is given, all facets on the outer boundary of the grid (i.e. all facets that do not have a neighbor) is used.

See also: collect_periodic_facets!, PeriodicDirichlet.

source
Ferrite.add!Function
add!(sdh::SubDofHandler, name::Symbol, ip::Interpolation)

Add a field called name approximated by ip to the SubDofHandler sdh.

source
add!(dh::DofHandler, name::Symbol, ip::Interpolation)

Add a field called name approximated by ip to the DofHandler dh.

The field is added to all cells of the underlying grid, use SubDofHandlers if the grid contains multiple cell types, or to add the field to subset of all the cells.

source
add!(ch::ConstraintHandler, ac::AffineConstraint)

Add the AffineConstraint to the ConstraintHandler.

source
add!(ch::ConstraintHandler, dbc::Dirichlet)

Add a Dirichlet boundary condition to the ConstraintHandler.

source
add!(proj::L2Projector, set::AbstractVecOrSet{Int}, ip::Interpolation;
-    qr_rhs, [qr_lhs])

Add an interpolation ip on the cells in set to the L2Projector proj.

  • qr_rhs sets the quadrature rule used to later integrate the right-hand-side of the projection equation, when calling project. It should match the quadrature points used when creating the quadrature-point variables to project.
  • The optional qr_lhs sets the quadrature rule used to integrate the left-hand-side of the projection equation, and defaults to a quadrature rule that integrates the mass-matrix exactly for the given interpolation ip.
source
Ferrite.close!Function
close!(dh::AbstractDofHandler)

Closes dh and creates degrees of freedom for each cell.

source
close!(ch::ConstraintHandler)

Close and finalize the ConstraintHandler.

source
close!(proj::L2Projector)

Close proj which assembles and calculates the left-hand-side of the projection equation, before doing a Cholesky factorization of the mass-matrix.

source
Ferrite.update!Function
update!(ch::ConstraintHandler, time::Real=0.0)

Update time-dependent inhomogeneities for the new time. This calls f(x) or f(x, t) when applicable, where f is the function(s) corresponding to the constraints in the handler, to compute the inhomogeneities.

Note that this is called implicitly in close!(::ConstraintHandler).

source
Ferrite.apply!Function
apply!(K::SparseMatrixCSC, rhs::AbstractVector, ch::ConstraintHandler)

Adjust the matrix K and right hand side rhs to account for the Dirichlet boundary conditions specified in ch such that K \ rhs gives the expected solution.

Note

apply!(K, rhs, ch) essentially calculates

rhs[free] = rhs[free] - K[constrained, constrained] * a[constrained]

where a[constrained] are the inhomogeneities. Consequently, the sign of rhs matters (in contrast with apply_zero!).

apply!(v::AbstractVector, ch::ConstraintHandler)

Apply Dirichlet boundary conditions and affine constraints, specified in ch, to the solution vector v.

Examples

K, f = assemble_system(...) # Assemble system
+PeriodicDirichlet(u::Symbol, facet_mapping, f::Function, components=nothing)

Create a periodic Dirichlet boundary condition for the field u on the facet-pairs given in facet_mapping. The mapping can be computed with collect_periodic_facets. The constraint ensures that degrees-of-freedom on the mirror facet are constrained to the corresponding degrees-of-freedom on the image facet. components specify the components of u that are prescribed by this condition. By default all components of u are prescribed.

If the mapping is not aligned with the coordinate axis (e.g. rotated) a rotation matrix R should be passed to the constructor. This matrix rotates dofs on the mirror facet to the image facet. Note that this is only applicable for vector-valued problems.

To construct an inhomogeneous periodic constraint it is possible to pass a function f. Note that this is currently only supported when the periodicity is aligned with the coordinate axes.

See the manual section on Periodic boundary conditions for more information.

source
Ferrite.collect_periodic_facetsFunction
collect_periodic_facets(grid::Grid, mset, iset, transform::Union{Function,Nothing}=nothing; tol=1e-12)

Match all mirror facets in mset with a corresponding image facet in iset. Return a dictionary which maps each mirror facet to a image facet. The result can then be passed to PeriodicDirichlet.

mset and iset can be given as a String (an existing facet set in the grid) or as a AbstractSet{FacetIndex} directly.

By default this function looks for a matching facet in the directions of the coordinate system. For other types of periodicities the transform function can be used. The transform function is applied on the coordinates of the image facet, and is expected to transform the coordinates to the matching locations in the mirror set.

The keyword tol specifies the tolerance (i.e. distance and deviation in facet-normals) between a image-facet and mirror-facet, for them to be considered matched.

See also: collect_periodic_facets!, PeriodicDirichlet.

source
collect_periodic_facets(grid::Grid, all_facets::Union{AbstractSet{FacetIndex},String,Nothing}=nothing; tol=1e-12)

Split all facets in all_facets into image and mirror sets. For each matching pair, the facet located further along the vector (1, 1, 1) becomes the image facet.

If no set is given, all facets on the outer boundary of the grid (i.e. all facets that do not have a neighbor) is used.

See also: collect_periodic_facets!, PeriodicDirichlet.

source
Ferrite.add!Function
add!(sdh::SubDofHandler, name::Symbol, ip::Interpolation)

Add a field called name approximated by ip to the SubDofHandler sdh.

source
add!(dh::DofHandler, name::Symbol, ip::Interpolation)

Add a field called name approximated by ip to the DofHandler dh.

The field is added to all cells of the underlying grid, use SubDofHandlers if the grid contains multiple cell types, or to add the field to subset of all the cells.

source
add!(ch::ConstraintHandler, ac::AffineConstraint)

Add the AffineConstraint to the ConstraintHandler.

source
add!(ch::ConstraintHandler, dbc::Dirichlet)

Add a Dirichlet boundary condition to the ConstraintHandler.

source
add!(proj::L2Projector, set::AbstractVecOrSet{Int}, ip::Interpolation;
+    qr_rhs, [qr_lhs])

Add an interpolation ip on the cells in set to the L2Projector proj.

  • qr_rhs sets the quadrature rule used to later integrate the right-hand-side of the projection equation, when calling project. It should match the quadrature points used when creating the quadrature-point variables to project.
  • The optional qr_lhs sets the quadrature rule used to integrate the left-hand-side of the projection equation, and defaults to a quadrature rule that integrates the mass-matrix exactly for the given interpolation ip.
source
Ferrite.close!Function
close!(dh::AbstractDofHandler)

Closes dh and creates degrees of freedom for each cell.

source
close!(ch::ConstraintHandler)

Close and finalize the ConstraintHandler.

source
close!(proj::L2Projector)

Close proj which assembles and calculates the left-hand-side of the projection equation, before doing a Cholesky factorization of the mass-matrix.

source
Ferrite.update!Function
update!(ch::ConstraintHandler, time::Real=0.0)

Update time-dependent inhomogeneities for the new time. This calls f(x) or f(x, t) when applicable, where f is the function(s) corresponding to the constraints in the handler, to compute the inhomogeneities.

Note that this is called implicitly in close!(::ConstraintHandler).

source
Ferrite.apply!Function
apply!(K::SparseMatrixCSC, rhs::AbstractVector, ch::ConstraintHandler)

Adjust the matrix K and right hand side rhs to account for the Dirichlet boundary conditions specified in ch such that K \ rhs gives the expected solution.

Note

apply!(K, rhs, ch) essentially calculates

rhs[free] = rhs[free] - K[constrained, constrained] * a[constrained]

where a[constrained] are the inhomogeneities. Consequently, the sign of rhs matters (in contrast with apply_zero!).

apply!(v::AbstractVector, ch::ConstraintHandler)

Apply Dirichlet boundary conditions and affine constraints, specified in ch, to the solution vector v.

Examples

K, f = assemble_system(...) # Assemble system
 apply!(K, f, ch)            # Adjust K and f to account for boundary conditions
 u = K \ f                   # Solve the system, u should be "approximately correct"
-apply!(u, ch)               # Explicitly make sure bcs are correct
Note

The last operation is not strictly necessary since the boundary conditions should already be fulfilled after apply!(K, f, ch). However, solvers of linear systems are not exact, and thus apply!(u, ch) can be used to make sure the boundary conditions are fulfilled exactly.

source
Ferrite.apply_zero!Function
apply_zero!(K::SparseMatrixCSC, rhs::AbstractVector, ch::ConstraintHandler)

Adjust the matrix K and the right hand side rhs to account for prescribed Dirichlet boundary conditions and affine constraints such that du = K \ rhs gives the expected result (e.g. du zero for all prescribed degrees of freedom).

apply_zero!(v::AbstractVector, ch::ConstraintHandler)

Zero-out values in v corresponding to prescribed degrees of freedom and update values prescribed by affine constraints, such that if a fulfills the constraints, a ± v also will.

These methods are typically used in e.g. a Newton solver where the increment, du, should be prescribed to zero even for non-homogeneouos boundary conditions.

See also: apply!.

Examples

u = un + Δu                 # Current guess
+apply!(u, ch)               # Explicitly make sure bcs are correct
Note

The last operation is not strictly necessary since the boundary conditions should already be fulfilled after apply!(K, f, ch). However, solvers of linear systems are not exact, and thus apply!(u, ch) can be used to make sure the boundary conditions are fulfilled exactly.

source
Ferrite.apply_zero!Function
apply_zero!(K::SparseMatrixCSC, rhs::AbstractVector, ch::ConstraintHandler)

Adjust the matrix K and the right hand side rhs to account for prescribed Dirichlet boundary conditions and affine constraints such that du = K \ rhs gives the expected result (e.g. du zero for all prescribed degrees of freedom).

apply_zero!(v::AbstractVector, ch::ConstraintHandler)

Zero-out values in v corresponding to prescribed degrees of freedom and update values prescribed by affine constraints, such that if a fulfills the constraints, a ± v also will.

These methods are typically used in e.g. a Newton solver where the increment, du, should be prescribed to zero even for non-homogeneouos boundary conditions.

See also: apply!.

Examples

u = un + Δu                 # Current guess
 K, g = assemble_system(...) # Assemble residual and tangent for current guess
 apply_zero!(K, g, ch)       # Adjust tangent and residual to take prescribed values into account
 ΔΔu = K \ g                # Compute the (negative) increment, prescribed values are "approximately" zero
 apply_zero!(ΔΔu, ch)        # Make sure values are exactly zero
-Δu .-= ΔΔu                  # Update current guess
Note

The last call to apply_zero! is only strictly necessary for affine constraints. However, even if the Dirichlet boundary conditions should be fulfilled after apply!(K, g, ch), solvers of linear systems are not exact. apply!(ΔΔu, ch) can be used to make sure the values for the prescribed degrees of freedom are fulfilled exactly.

source
Ferrite.apply_local!Function
apply_local!(
+Δu .-= ΔΔu                  # Update current guess
Note

The last call to apply_zero! is only strictly necessary for affine constraints. However, even if the Dirichlet boundary conditions should be fulfilled after apply!(K, g, ch), solvers of linear systems are not exact. apply!(ΔΔu, ch) can be used to make sure the values for the prescribed degrees of freedom are fulfilled exactly.

source
Ferrite.apply_local!Function
apply_local!(
     local_matrix::AbstractMatrix, local_vector::AbstractVector,
     global_dofs::AbstractVector, ch::ConstraintHandler;
     apply_zero::Bool = false
-)

Similar to apply! but perform condensation of constrained degrees-of-freedom locally in local_matrix and local_vector before they are to be assembled into the global system.

When the keyword argument apply_zero is true all inhomogeneities are set to 0 (cf. apply! vs apply_zero!).

This method can only be used if all constraints are "local", i.e. no constraint couples with dofs outside of the element dofs (global_dofs) since condensation of such constraints requires writing to entries in the global matrix/vector. For such a case, apply_assemble! can be used instead.

Note that this method is destructive since it, by definition, modifies local_matrix and local_vector.

source
Ferrite.apply_assemble!Function
apply_assemble!(
+)

Similar to apply! but perform condensation of constrained degrees-of-freedom locally in local_matrix and local_vector before they are to be assembled into the global system.

When the keyword argument apply_zero is true all inhomogeneities are set to 0 (cf. apply! vs apply_zero!).

This method can only be used if all constraints are "local", i.e. no constraint couples with dofs outside of the element dofs (global_dofs) since condensation of such constraints requires writing to entries in the global matrix/vector. For such a case, apply_assemble! can be used instead.

Note that this method is destructive since it, by definition, modifies local_matrix and local_vector.

source
Ferrite.apply_assemble!Function
apply_assemble!(
     assembler::AbstractAssembler, ch::ConstraintHandler,
     global_dofs::AbstractVector{Int},
     local_matrix::AbstractMatrix, local_vector::AbstractVector;
     apply_zero::Bool = false
-)

Assemble local_matrix and local_vector into the global system in assembler by first doing constraint condensation using apply_local!.

This is similar to using apply_local! followed by assemble! with the advantage that non-local constraints can be handled, since this method can write to entries of the global matrix and vector outside of the indices in global_dofs.

When the keyword argument apply_zero is true all inhomogeneities are set to 0 (cf. apply! vs apply_zero!).

Note that this method is destructive since it modifies local_matrix and local_vector.

source
Ferrite.get_rhs_dataFunction
get_rhs_data(ch::ConstraintHandler, A::SparseMatrixCSC) -> RHSData

Returns the needed RHSData for apply_rhs!.

This must be used when the same stiffness matrix is reused for multiple steps, for example when timestepping, with different non-homogeneouos Dirichlet boundary conditions.

source
Ferrite.apply_rhs!Function
apply_rhs!(data::RHSData, f::AbstractVector, ch::ConstraintHandler, applyzero::Bool=false)

Applies the boundary condition to the right-hand-side vector without modifying the stiffness matrix.

See also: get_rhs_data.

source
Ferrite.RHSDataType
RHSData

Stores the constrained columns and mean of the diagonal of stiffness matrix A.

source

Initial conditions

Ferrite.apply_analytical!Function
apply_analytical!(
+)

Assemble local_matrix and local_vector into the global system in assembler by first doing constraint condensation using apply_local!.

This is similar to using apply_local! followed by assemble! with the advantage that non-local constraints can be handled, since this method can write to entries of the global matrix and vector outside of the indices in global_dofs.

When the keyword argument apply_zero is true all inhomogeneities are set to 0 (cf. apply! vs apply_zero!).

Note that this method is destructive since it modifies local_matrix and local_vector.

source
Ferrite.get_rhs_dataFunction
get_rhs_data(ch::ConstraintHandler, A::SparseMatrixCSC) -> RHSData

Returns the needed RHSData for apply_rhs!.

This must be used when the same stiffness matrix is reused for multiple steps, for example when timestepping, with different non-homogeneouos Dirichlet boundary conditions.

source
Ferrite.apply_rhs!Function
apply_rhs!(data::RHSData, f::AbstractVector, ch::ConstraintHandler, applyzero::Bool=false)

Applies the boundary condition to the right-hand-side vector without modifying the stiffness matrix.

See also: get_rhs_data.

source
Ferrite.RHSDataType
RHSData

Stores the constrained columns and mean of the diagonal of stiffness matrix A.

source

Initial conditions

Ferrite.apply_analytical!Function
apply_analytical!(
     a::AbstractVector, dh::AbstractDofHandler, fieldname::Symbol,
-    f::Function, cellset=1:getncells(get_grid(dh)))

Apply a solution f(x) by modifying the values in the degree of freedom vector a pertaining to the field fieldname for all cells in cellset. The function f(x) are given the spatial coordinate of the degree of freedom. For scalar fields, f(x)::Number, and for vector fields with dimension dim, f(x)::Vec{dim}.

This function can be used to apply initial conditions for time dependent problems.

Note

This function only works for standard nodal finite element interpolations when the function value at the (algebraic) node is equal to the corresponding degree of freedom value. This holds for e.g. Lagrange and Serendipity interpolations, including sub- and superparametric elements.

source
+ f::Function, cellset=1:getncells(get_grid(dh)))

Apply a solution f(x) by modifying the values in the degree of freedom vector a pertaining to the field fieldname for all cells in cellset. The function f(x) are given the spatial coordinate of the degree of freedom. For scalar fields, f(x)::Number, and for vector fields with dimension dim, f(x)::Vec{dim}.

This function can be used to apply initial conditions for time dependent problems.

Note

This function only works for standard nodal finite element interpolations when the function value at the (algebraic) node is equal to the corresponding degree of freedom value. This holds for e.g. Lagrange and Serendipity interpolations, including sub- and superparametric elements.

source
diff --git a/dev/reference/dofhandler/index.html b/dev/reference/dofhandler/index.html index e3b634a1ff..edf0928e13 100644 --- a/dev/reference/dofhandler/index.html +++ b/dev/reference/dofhandler/index.html @@ -4,7 +4,7 @@ ip_p = Lagrange{RefTriangle, 1}() # scalar interpolation for a field p add!(dh, :u, ip_u) add!(dh, :p, ip_p) -close!(dh)source
Ferrite.SubDofHandlerType
SubDofHandler(dh::AbstractDofHandler, cellset::AbstractVecOrSet{Int})

Create an sdh::SubDofHandler from the parent dh, pertaining to the cells in cellset. This allows you to add fields to parts of the domain, or using different interpolations or cell types (e.g. Triangles and Quadrilaterals). All fields and cell types must be the same in one SubDofHandler.

After construction any number of discrete fields can be added to the SubDofHandler using add!. Construction is finalized by calling close! on the parent dh.

Examples

We assume we have a grid containing "Triangle" and "Quadrilateral" cells, including the cellsets "triangles" and "quadilaterals" for to these cells.

dh = DofHandler(grid)
+close!(dh)
source
Ferrite.SubDofHandlerType
SubDofHandler(dh::AbstractDofHandler, cellset::AbstractVecOrSet{Int})

Create an sdh::SubDofHandler from the parent dh, pertaining to the cells in cellset. This allows you to add fields to parts of the domain, or using different interpolations or cell types (e.g. Triangles and Quadrilaterals). All fields and cell types must be the same in one SubDofHandler.

After construction any number of discrete fields can be added to the SubDofHandler using add!. Construction is finalized by calling close! on the parent dh.

Examples

We assume we have a grid containing "Triangle" and "Quadrilateral" cells, including the cellsets "triangles" and "quadilaterals" for to these cells.

dh = DofHandler(grid)
 
 sdh_tri = SubDofHandler(dh, getcellset(grid, "triangles"))
 ip_tri = Lagrange{RefTriangle, 2}()^2 # vector interpolation for a field u
@@ -14,10 +14,10 @@
 ip_quad = Lagrange{RefQuadrilateral, 2}()^2 # vector interpolation for a field u
 add!(sdh_quad, :u, ip_quad)
 
-close!(dh) # Finalize by closing the parent
source

Adding fields to the DofHandlers

Ferrite.add!Method
add!(dh::DofHandler, name::Symbol, ip::Interpolation)

Add a field called name approximated by ip to the DofHandler dh.

The field is added to all cells of the underlying grid, use SubDofHandlers if the grid contains multiple cell types, or to add the field to subset of all the cells.

source
Ferrite.add!Method
add!(sdh::SubDofHandler, name::Symbol, ip::Interpolation)

Add a field called name approximated by ip to the SubDofHandler sdh.

source
Ferrite.close!Method
close!(dh::AbstractDofHandler)

Closes dh and creates degrees of freedom for each cell.

source

Dof renumbering

Ferrite.renumber!Function
renumber!(dh::AbstractDofHandler, order)
-renumber!(dh::AbstractDofHandler, ch::ConstraintHandler, order)

Renumber the degrees of freedom in the DofHandler and/or ConstraintHandler according to the ordering order.

order can be given by one of the following options:

  • A permutation vector perm::AbstractVector{Int} such that dof i is renumbered to perm[i].
  • DofOrder.FieldWise() for renumbering dofs field wise.
  • DofOrder.ComponentWise() for renumbering dofs component wise.
  • DofOrder.Ext{T} for "external" renumber permutations, see documentation for DofOrder.Ext for details.
Warning

The dof numbering in the DofHandler and ConstraintHandler must always be consistent. It is therefore necessary to either renumber before creating the ConstraintHandler in the first place, or to renumber the DofHandler and the ConstraintHandler together.

source
Ferrite.DofOrder.FieldWiseType
DofOrder.FieldWise()
-DofOrder.FieldWise(target_blocks::Vector{Int})

Dof order passed to renumber! to renumber global dofs field wise resulting in a globally blocked system.

The default behavior is to group dofs of each field into their own block, with the same order as in the DofHandler. This can be customized by passing a vector of the same length as the total number of fields in the DofHandler (see getfieldnames(dh)) that maps each field to a "target block": to renumber a DofHandler with three fields :u, :v, :w such that dofs for :u and :w end up in the first global block, and dofs for :v in the second global block use DofOrder.FieldWise([1, 2, 1]).

This renumbering is stable such that the original relative ordering of dofs within each target block is maintained.

source
Ferrite.DofOrder.ComponentWiseType
DofOrder.ComponentWise()
-DofOrder.ComponentWise(target_blocks::Vector{Int})

Dof order passed to renumber! to renumber global dofs component wise resulting in a globally blocked system.

The default behavior is to group dofs of each component into their own block, with the same order as in the DofHandler. This can be customized by passing a vector of length ncomponents that maps each component to a "target block" (see DofOrder.FieldWise for details).

This renumbering is stable such that the original relative ordering of dofs within each target block is maintained.

source

Common methods

Ferrite.ndofsFunction
ndofs(dh::AbstractDofHandler)

Return the number of degrees of freedom in dh

source
Ferrite.ndofs_per_cellFunction
ndofs_per_cell(dh::AbstractDofHandler[, cell::Int=1])

Return the number of degrees of freedom for the cell with index cell.

See also ndofs.

source
Ferrite.dof_rangeFunction
dof_range(sdh::SubDofHandler, field_idx::Int)
+close!(dh) # Finalize by closing the parent
source

Adding fields to the DofHandlers

Ferrite.add!Method
add!(dh::DofHandler, name::Symbol, ip::Interpolation)

Add a field called name approximated by ip to the DofHandler dh.

The field is added to all cells of the underlying grid, use SubDofHandlers if the grid contains multiple cell types, or to add the field to subset of all the cells.

source
Ferrite.add!Method
add!(sdh::SubDofHandler, name::Symbol, ip::Interpolation)

Add a field called name approximated by ip to the SubDofHandler sdh.

source
Ferrite.close!Method
close!(dh::AbstractDofHandler)

Closes dh and creates degrees of freedom for each cell.

source

Dof renumbering

Ferrite.renumber!Function
renumber!(dh::AbstractDofHandler, order)
+renumber!(dh::AbstractDofHandler, ch::ConstraintHandler, order)

Renumber the degrees of freedom in the DofHandler and/or ConstraintHandler according to the ordering order.

order can be given by one of the following options:

  • A permutation vector perm::AbstractVector{Int} such that dof i is renumbered to perm[i].
  • DofOrder.FieldWise() for renumbering dofs field wise.
  • DofOrder.ComponentWise() for renumbering dofs component wise.
  • DofOrder.Ext{T} for "external" renumber permutations, see documentation for DofOrder.Ext for details.
Warning

The dof numbering in the DofHandler and ConstraintHandler must always be consistent. It is therefore necessary to either renumber before creating the ConstraintHandler in the first place, or to renumber the DofHandler and the ConstraintHandler together.

source
Ferrite.DofOrder.FieldWiseType
DofOrder.FieldWise()
+DofOrder.FieldWise(target_blocks::Vector{Int})

Dof order passed to renumber! to renumber global dofs field wise resulting in a globally blocked system.

The default behavior is to group dofs of each field into their own block, with the same order as in the DofHandler. This can be customized by passing a vector of the same length as the total number of fields in the DofHandler (see getfieldnames(dh)) that maps each field to a "target block": to renumber a DofHandler with three fields :u, :v, :w such that dofs for :u and :w end up in the first global block, and dofs for :v in the second global block use DofOrder.FieldWise([1, 2, 1]).

This renumbering is stable such that the original relative ordering of dofs within each target block is maintained.

source
Ferrite.DofOrder.ComponentWiseType
DofOrder.ComponentWise()
+DofOrder.ComponentWise(target_blocks::Vector{Int})

Dof order passed to renumber! to renumber global dofs component wise resulting in a globally blocked system.

The default behavior is to group dofs of each component into their own block, with the same order as in the DofHandler. This can be customized by passing a vector of length ncomponents that maps each component to a "target block" (see DofOrder.FieldWise for details).

This renumbering is stable such that the original relative ordering of dofs within each target block is maintained.

source

Common methods

Ferrite.ndofsFunction
ndofs(dh::AbstractDofHandler)

Return the number of degrees of freedom in dh

source
Ferrite.ndofs_per_cellFunction
ndofs_per_cell(dh::AbstractDofHandler[, cell::Int=1])

Return the number of degrees of freedom for the cell with index cell.

See also ndofs.

source
Ferrite.dof_rangeFunction
dof_range(sdh::SubDofHandler, field_idx::Int)
 dof_range(sdh::SubDofHandler, field_name::Symbol)
 dof_range(dh:DofHandler, field_name::Symbol)

Return the local dof range for a given field. The field can be specified by its name or index, where field_idx represents the index of a field within a SubDofHandler and field_idxs is a tuple of the SubDofHandler-index within the DofHandler and the field_idx.

Note

The dof_range of a field can vary between different SubDofHandlers. Therefore, it is advised to use the field_idxs or refer to a given SubDofHandler directly in case several SubDofHandlers exist. Using the field_name will always refer to the first occurrence of field within the DofHandler.

Example:

julia> grid = generate_grid(Triangle, (3, 3))
 Grid{2, Triangle, Float64} with 18 Triangle cells and 16 nodes
@@ -34,19 +34,19 @@
 1:9
 
 julia> dof_range(dh.subdofhandlers[1], 2) # field :p
-10:12
source
Ferrite.celldofsFunction
celldofs(dh::AbstractDofHandler, i::Int)

Return a vector with the degrees of freedom that belong to cell i.

See also celldofs!.

source
Ferrite.celldofs!Function
celldofs!(global_dofs::Vector{Int}, dh::AbstractDofHandler, i::Int)

Store the degrees of freedom that belong to cell i in global_dofs.

See also celldofs.

source

Grid iterators

Ferrite.CellCacheType
CellCache(grid::Grid)
-CellCache(dh::AbstractDofHandler)

Create a cache object with pre-allocated memory for the nodes, coordinates, and dofs of a cell. The cache is updated for a new cell by calling reinit!(cache, cellid) where cellid::Int is the cell id.

Methods with CellCache

  • reinit!(cc, i): reinitialize the cache for cell i
  • cellid(cc): get the cell id of the currently cached cell
  • getnodes(cc): get the global node ids of the cell
  • getcoordinates(cc): get the coordinates of the cell
  • celldofs(cc): get the global dof ids of the cell
  • reinit!(fev, cc): reinitialize CellValues or FacetValues

See also CellIterator.

source
Ferrite.CellIteratorType
CellIterator(grid::Grid, cellset=1:getncells(grid))
+10:12
source
Ferrite.celldofsFunction
celldofs(dh::AbstractDofHandler, i::Int)

Return a vector with the degrees of freedom that belong to cell i.

See also celldofs!.

source
Ferrite.celldofs!Function
celldofs!(global_dofs::Vector{Int}, dh::AbstractDofHandler, i::Int)

Store the degrees of freedom that belong to cell i in global_dofs.

See also celldofs.

source

Grid iterators

Ferrite.CellCacheType
CellCache(grid::Grid)
+CellCache(dh::AbstractDofHandler)

Create a cache object with pre-allocated memory for the nodes, coordinates, and dofs of a cell. The cache is updated for a new cell by calling reinit!(cache, cellid) where cellid::Int is the cell id.

Methods with CellCache

  • reinit!(cc, i): reinitialize the cache for cell i
  • cellid(cc): get the cell id of the currently cached cell
  • getnodes(cc): get the global node ids of the cell
  • getcoordinates(cc): get the coordinates of the cell
  • celldofs(cc): get the global dof ids of the cell
  • reinit!(fev, cc): reinitialize CellValues or FacetValues

See also CellIterator.

source
Ferrite.CellIteratorType
CellIterator(grid::Grid, cellset=1:getncells(grid))
 CellIterator(dh::AbstractDofHandler, cellset=1:getncells(dh))

Create a CellIterator to conveniently iterate over all, or a subset, of the cells in a grid. The elements of the iterator are CellCaches which are properly reinit!ialized. See CellCache for more details.

Looping over a CellIterator, i.e.:

for cc in CellIterator(grid, cellset)
     # ...
 end

is thus simply convenience for the following equivalent snippet:

cc = CellCache(grid)
 for idx in cellset
     reinit!(cc, idx)
     # ...
-end
Warning

CellIterator is stateful and should not be used for things other than for-looping (e.g. broadcasting over, or collecting the iterator may yield unexpected results).

source
Ferrite.FacetCacheType
FacetCache(grid::Grid)
-FacetCache(dh::AbstractDofHandler)

Create a cache object with pre-allocated memory for the nodes, coordinates, and dofs of a cell suitable for looping over faces in a grid. The cache is updated for a new face by calling reinit!(cache, fi::FacetIndex).

Methods with fc::FacetCache

  • reinit!(fc, fi): reinitialize the cache for face fi::FacetIndex
  • cellid(fc): get the current cellid
  • getnodes(fc): get the global node ids of the cell
  • getcoordinates(fc): get the coordinates of the cell
  • celldofs(fc): get the global dof ids of the cell
  • reinit!(fv, fc): reinitialize FacetValues

See also FacetIterator.

source
Ferrite.FacetIteratorType
FacetIterator(gridordh::Union{Grid,AbstractDofHandler}, facetset::AbstractVecOrSet{FacetIndex})

Create a FacetIterator to conveniently iterate over the faces in facestet. The elements of the iterator are FacetCaches which are properly reinit!ialized. See FacetCache for more details.

Looping over a FacetIterator, i.e.:

for fc in FacetIterator(grid, facetset)
+end
Warning

CellIterator is stateful and should not be used for things other than for-looping (e.g. broadcasting over, or collecting the iterator may yield unexpected results).

source
Ferrite.FacetCacheType
FacetCache(grid::Grid)
+FacetCache(dh::AbstractDofHandler)

Create a cache object with pre-allocated memory for the nodes, coordinates, and dofs of a cell suitable for looping over faces in a grid. The cache is updated for a new face by calling reinit!(cache, fi::FacetIndex).

Methods with fc::FacetCache

  • reinit!(fc, fi): reinitialize the cache for face fi::FacetIndex
  • cellid(fc): get the current cellid
  • getnodes(fc): get the global node ids of the cell
  • getcoordinates(fc): get the coordinates of the cell
  • celldofs(fc): get the global dof ids of the cell
  • reinit!(fv, fc): reinitialize FacetValues

See also FacetIterator.

source
Ferrite.FacetIteratorType
FacetIterator(gridordh::Union{Grid,AbstractDofHandler}, facetset::AbstractVecOrSet{FacetIndex})

Create a FacetIterator to conveniently iterate over the faces in facestet. The elements of the iterator are FacetCaches which are properly reinit!ialized. See FacetCache for more details.

Looping over a FacetIterator, i.e.:

for fc in FacetIterator(grid, facetset)
     # ...
-end

is thus simply convenience for the following equivalent snippet: ```julia fc = FacetCache(grid) for faceindex in facetset reinit!(fc, faceindex) # ... end

source
Ferrite.InterfaceCacheType
InterfaceCache(grid::Grid)
-InterfaceCache(dh::AbstractDofHandler)

Create a cache object with pre-allocated memory for the nodes, coordinates, and dofs of an interface. The cache is updated for a new cell by calling reinit!(cache, facet_a, facet_b) where facet_a::FacetIndex and facet_b::FacetIndex are the two interface faces.

Struct fields of InterfaceCache

  • ic.a :: FacetCache: face cache for the first face of the interface
  • ic.b :: FacetCache: face cache for the second face of the interface
  • ic.dofs :: Vector{Int}: global dof ids for the interface (union of ic.a.dofs and ic.b.dofs)

Methods with InterfaceCache

  • reinit!(cache::InterfaceCache, facet_a::FacetIndex, facet_b::FacetIndex): reinitialize the cache for a new interface
  • interfacedofs(ic): get the global dof ids of the interface

See also InterfaceIterator.

source
Ferrite.InterfaceIteratorType
InterfaceIterator(grid::Grid, [topology::ExclusiveTopology])
+end

is thus simply convenience for the following equivalent snippet: ```julia fc = FacetCache(grid) for faceindex in facetset reinit!(fc, faceindex) # ... end

source
Ferrite.InterfaceCacheType
InterfaceCache(grid::Grid)
+InterfaceCache(dh::AbstractDofHandler)

Create a cache object with pre-allocated memory for the nodes, coordinates, and dofs of an interface. The cache is updated for a new cell by calling reinit!(cache, facet_a, facet_b) where facet_a::FacetIndex and facet_b::FacetIndex are the two interface faces.

Struct fields of InterfaceCache

  • ic.a :: FacetCache: face cache for the first face of the interface
  • ic.b :: FacetCache: face cache for the second face of the interface
  • ic.dofs :: Vector{Int}: global dof ids for the interface (union of ic.a.dofs and ic.b.dofs)

Methods with InterfaceCache

  • reinit!(cache::InterfaceCache, facet_a::FacetIndex, facet_b::FacetIndex): reinitialize the cache for a new interface
  • interfacedofs(ic): get the global dof ids of the interface

See also InterfaceIterator.

source
Ferrite.InterfaceIteratorType
InterfaceIterator(grid::Grid, [topology::ExclusiveTopology])
 InterfaceIterator(dh::AbstractDofHandler, [topology::ExclusiveTopology])

Create an InterfaceIterator to conveniently iterate over all the interfaces in a grid. The elements of the iterator are InterfaceCaches which are properly reinit!ialized. See InterfaceCache for more details. Looping over an InterfaceIterator, i.e.:

for ic in InterfaceIterator(grid, topology)
     # ...
 end

is thus simply convenience for the following equivalent snippet for grids of dimensions > 1:

ic = InterfaceCache(grid, topology)
@@ -56,4 +56,4 @@
     neighbor_face = neighborhood[1]
     reinit!(ic, face, neighbor_face)
     # ...
-end
Warning

InterfaceIterator is stateful and should not be used for things other than for-looping (e.g. broadcasting over, or collecting the iterator may yield unexpected results).

source
+end
Warning

InterfaceIterator is stateful and should not be used for things other than for-looping (e.g. broadcasting over, or collecting the iterator may yield unexpected results).

source diff --git a/dev/reference/export/index.html b/dev/reference/export/index.html index 2818b4589b..9e96293cb3 100644 --- a/dev/reference/export/index.html +++ b/dev/reference/export/index.html @@ -15,8 +15,8 @@ end end -projected = project(proj, vals)

where projected can be used in e.g. evaluate_at_points with the PointEvalHandler, or with evaluate_at_grid_nodes.

source
Ferrite.add!Method
add!(proj::L2Projector, set::AbstractVecOrSet{Int}, ip::Interpolation;
-    qr_rhs, [qr_lhs])

Add an interpolation ip on the cells in set to the L2Projector proj.

  • qr_rhs sets the quadrature rule used to later integrate the right-hand-side of the projection equation, when calling project. It should match the quadrature points used when creating the quadrature-point variables to project.
  • The optional qr_lhs sets the quadrature rule used to integrate the left-hand-side of the projection equation, and defaults to a quadrature rule that integrates the mass-matrix exactly for the given interpolation ip.
source
Ferrite.close!Method
close!(proj::L2Projector)

Close proj which assembles and calculates the left-hand-side of the projection equation, before doing a Cholesky factorization of the mass-matrix.

source
Ferrite.L2ProjectorMethod
L2Projector(ip::Interpolation, grid::AbstractGrid; [qr_lhs], [set])

A quick way to initiate an L2Projector, add an interpolation ip on the set to it, and then close! it so that it can be used to project. The optional keyword argument set defaults to all cells in the grid, while qr_lhs defaults to a quadrature rule that integrates the mass matrix exactly for the interpolation ip.

source
Ferrite.projectFunction
project(proj::L2Projector, vals, [qr_rhs::QuadratureRule])

Makes a L2 projection of data vals to the nodes of the grid using the projector proj (see L2Projector).

project integrates the right hand side, and solves the projection $u$ from the following projection equation: Find projection $u \in U_h(\Omega) \subset L_2(\Omega)$ such that

\[\int v u \ \mathrm{d}\Omega = \int v f \ \mathrm{d}\Omega \quad \forall v \in U_h(\Omega),\]

where $f \in L_2(\Omega)$ is the data to project. The function space $U_h(\Omega)$ is the finite element approximation given by the interpolations in proj.

The data vals should be an AbstractVector or AbstractDict that is indexed by the cell number. Each index in vals should give an AbstractVector with one element for each cell quadrature point.

If proj was created by calling L2Projector(ip, grid, set), qr_rhs must be given. Otherwise, this is added for each domain when calling add!(proj, args...).

Alternatively, vals can be a matrix, with the column index referring the cell number, and the row index corresponding to quadrature point number. Example (scalar) input data:

vals = [
+projected = project(proj, vals)

where projected can be used in e.g. evaluate_at_points with the PointEvalHandler, or with evaluate_at_grid_nodes.

source
Ferrite.add!Method
add!(proj::L2Projector, set::AbstractVecOrSet{Int}, ip::Interpolation;
+    qr_rhs, [qr_lhs])

Add an interpolation ip on the cells in set to the L2Projector proj.

  • qr_rhs sets the quadrature rule used to later integrate the right-hand-side of the projection equation, when calling project. It should match the quadrature points used when creating the quadrature-point variables to project.
  • The optional qr_lhs sets the quadrature rule used to integrate the left-hand-side of the projection equation, and defaults to a quadrature rule that integrates the mass-matrix exactly for the given interpolation ip.
source
Ferrite.close!Method
close!(proj::L2Projector)

Close proj which assembles and calculates the left-hand-side of the projection equation, before doing a Cholesky factorization of the mass-matrix.

source
Ferrite.L2ProjectorMethod
L2Projector(ip::Interpolation, grid::AbstractGrid; [qr_lhs], [set])

A quick way to initiate an L2Projector, add an interpolation ip on the set to it, and then close! it so that it can be used to project. The optional keyword argument set defaults to all cells in the grid, while qr_lhs defaults to a quadrature rule that integrates the mass matrix exactly for the interpolation ip.

source
Ferrite.projectFunction
project(proj::L2Projector, vals, [qr_rhs::QuadratureRule])

Makes a L2 projection of data vals to the nodes of the grid using the projector proj (see L2Projector).

project integrates the right hand side, and solves the projection $u$ from the following projection equation: Find projection $u \in U_h(\Omega) \subset L_2(\Omega)$ such that

\[\int v u \ \mathrm{d}\Omega = \int v f \ \mathrm{d}\Omega \quad \forall v \in U_h(\Omega),\]

where $f \in L_2(\Omega)$ is the data to project. The function space $U_h(\Omega)$ is the finite element approximation given by the interpolations in proj.

The data vals should be an AbstractVector or AbstractDict that is indexed by the cell number. Each index in vals should give an AbstractVector with one element for each cell quadrature point.

If proj was created by calling L2Projector(ip, grid, set), qr_rhs must be given. Otherwise, this is added for each domain when calling add!(proj, args...).

Alternatively, vals can be a matrix, with the column index referring the cell number, and the row index corresponding to quadrature point number. Example (scalar) input data:

vals = [
     [0.44, 0.98, 0.32], # data for quadrature point 1, 2, 3 of element 1
     [0.29, 0.48, 0.55], # data for quadrature point 1, 2, 3 of element 2
     # ...
@@ -24,19 +24,19 @@
     0.44 0.29 # ...
     0.98 0.48 # ...
     0.32 0.55 # ...
-]

Supported data types to project are Numbers and AbstractTensors.

Note

The order of the returned data correspond to the order of the L2Projector's internal DofHandler. The data can be further analyzed with evaluate_at_points and evaluate_at_grid_nodes. Use write_projection to export the result.

source

Evaluation at points

Ferrite.evaluate_at_grid_nodesFunction
evaluate_at_grid_nodes(dh::AbstractDofHandler, u::AbstractVector{T}, fieldname::Symbol) where T

Evaluate the approximated solution for field fieldname at the node coordinates of the grid given the Dof handler dh and the solution vector u.

Return a vector of length getnnodes(grid) where entry i contains the evaluation of the approximation in the coordinate of node i. If the field does not live on parts of the grid, the corresponding values for those nodes will be returned as NaNs.

source
Ferrite.PointEvalHandlerType
PointEvalHandler(grid::Grid, points::AbstractVector{Vec{dim,T}}; kwargs...) where {dim, T}

The PointEvalHandler can be used for function evaluation in arbitrary points in the domain – not just in quadrature points or nodes.

The constructor takes a grid and a vector of coordinates for the points. The PointEvalHandler computes i) the corresponding cell, and ii) the (local) coordinate within the cell, for each point. The fields of the PointEvalHandler are:

  • cells::Vector{Union{Int,Nothing}}: vector with cell IDs for the points, with nothing for points that could not be found.
  • local_coords::Vector{Union{Vec,Nothing}}: vector with the local coordinates (i.e. coordinates in the reference configuration) for the points, with nothing for points that could not be found.

There are two ways to use the PointEvalHandler to evaluate functions:

  • evaluate_at_points: can be used when the function is described by i) a dh::DofHandler + uh::Vector (for example the FE-solution), or ii) a p::L2Projector + ph::Vector (for projected data).
  • Iteration with PointIterator + PointValues: can be used for more flexible evaluation in the points, for example to compute gradients.
source
Ferrite.evaluate_at_pointsFunction
evaluate_at_points(ph::PointEvalHandler, dh::AbstractDofHandler, dof_values::Vector{T}, [fieldname::Symbol]) where T
-evaluate_at_points(ph::PointEvalHandler, proj::L2Projector, dof_values::Vector{T}) where T

Return a Vector{T} (for a 1-dimensional field) or a Vector{Vec{fielddim, T}} (for a vector field) with the field values of field fieldname in the points of the PointEvalHandler. The fieldname can be omitted if only one field is stored in dh. The field values are computed based on the dof_values and interpolated to the local coordinates by the function interpolation of the corresponding field stored in the AbstractDofHandler or the L2Projector.

Points that could not be found in the domain when constructing the PointEvalHandler will have NaNs for the corresponding entries in the output vector.

source
Ferrite.PointValuesType
PointValues(cv::CellValues)
-PointValues([::Type{T}], func_interpol::Interpolation, [geom_interpol::Interpolation])

Similar to CellValues but with a single updateable "quadrature point". PointValues are used for evaluation of functions/gradients in arbitrary points of the domain together with a PointEvalHandler.

PointValues can be created from CellValues, or from the interpolations directly.

PointValues are reinitialized like other CellValues, but since the local reference coordinate of the "quadrature point" changes this needs to be passed to reinit!, in addition to the element coordinates: reinit!(pv, coords, local_coord). Alternatively, it can be reinitialized with a PointLocation when iterating a PointEvalHandler with a PointIterator.

For function/gradient evaluation, PointValues are used in the same way as CellValues, i.e. by using function_value, function_gradient, etc, with the exception that there is no need to specify the quadrature point index (since PointValues only have 1, this is the default).

source
Ferrite.PointIteratorType
PointIterator(ph::PointEvalHandler)

Create an iterator over the points in the PointEvalHandler. The elements of the iterator are either a PointLocation, if the corresponding point could be found in the grid, or nothing, if the point was not found.

A PointLocation can be used to query the cell ID with the cellid function, and can be used to reinitialize PointValues with reinit!.

Examples

ph = PointEvalHandler(grid, points)
+]

Supported data types to project are Numbers and AbstractTensors.

Note

The order of the returned data correspond to the order of the L2Projector's internal DofHandler. The data can be further analyzed with evaluate_at_points and evaluate_at_grid_nodes. Use write_projection to export the result.

source

Evaluation at points

Ferrite.evaluate_at_grid_nodesFunction
evaluate_at_grid_nodes(dh::AbstractDofHandler, u::AbstractVector{T}, fieldname::Symbol) where T

Evaluate the approximated solution for field fieldname at the node coordinates of the grid given the Dof handler dh and the solution vector u.

Return a vector of length getnnodes(grid) where entry i contains the evaluation of the approximation in the coordinate of node i. If the field does not live on parts of the grid, the corresponding values for those nodes will be returned as NaNs.

source
Ferrite.PointEvalHandlerType
PointEvalHandler(grid::Grid, points::AbstractVector{Vec{dim,T}}; kwargs...) where {dim, T}

The PointEvalHandler can be used for function evaluation in arbitrary points in the domain – not just in quadrature points or nodes.

The constructor takes a grid and a vector of coordinates for the points. The PointEvalHandler computes i) the corresponding cell, and ii) the (local) coordinate within the cell, for each point. The fields of the PointEvalHandler are:

  • cells::Vector{Union{Int,Nothing}}: vector with cell IDs for the points, with nothing for points that could not be found.
  • local_coords::Vector{Union{Vec,Nothing}}: vector with the local coordinates (i.e. coordinates in the reference configuration) for the points, with nothing for points that could not be found.

There are two ways to use the PointEvalHandler to evaluate functions:

  • evaluate_at_points: can be used when the function is described by i) a dh::DofHandler + uh::Vector (for example the FE-solution), or ii) a p::L2Projector + ph::Vector (for projected data).
  • Iteration with PointIterator + PointValues: can be used for more flexible evaluation in the points, for example to compute gradients.
source
Ferrite.evaluate_at_pointsFunction
evaluate_at_points(ph::PointEvalHandler, dh::AbstractDofHandler, dof_values::Vector{T}, [fieldname::Symbol]) where T
+evaluate_at_points(ph::PointEvalHandler, proj::L2Projector, dof_values::Vector{T}) where T

Return a Vector{T} (for a 1-dimensional field) or a Vector{Vec{fielddim, T}} (for a vector field) with the field values of field fieldname in the points of the PointEvalHandler. The fieldname can be omitted if only one field is stored in dh. The field values are computed based on the dof_values and interpolated to the local coordinates by the function interpolation of the corresponding field stored in the AbstractDofHandler or the L2Projector.

Points that could not be found in the domain when constructing the PointEvalHandler will have NaNs for the corresponding entries in the output vector.

source
Ferrite.PointValuesType
PointValues(cv::CellValues)
+PointValues([::Type{T}], func_interpol::Interpolation, [geom_interpol::Interpolation])

Similar to CellValues but with a single updateable "quadrature point". PointValues are used for evaluation of functions/gradients in arbitrary points of the domain together with a PointEvalHandler.

PointValues can be created from CellValues, or from the interpolations directly.

PointValues are reinitialized like other CellValues, but since the local reference coordinate of the "quadrature point" changes this needs to be passed to reinit!, in addition to the element coordinates: reinit!(pv, coords, local_coord). Alternatively, it can be reinitialized with a PointLocation when iterating a PointEvalHandler with a PointIterator.

For function/gradient evaluation, PointValues are used in the same way as CellValues, i.e. by using function_value, function_gradient, etc, with the exception that there is no need to specify the quadrature point index (since PointValues only have 1, this is the default).

source
Ferrite.PointIteratorType
PointIterator(ph::PointEvalHandler)

Create an iterator over the points in the PointEvalHandler. The elements of the iterator are either a PointLocation, if the corresponding point could be found in the grid, or nothing, if the point was not found.

A PointLocation can be used to query the cell ID with the cellid function, and can be used to reinitialize PointValues with reinit!.

Examples

ph = PointEvalHandler(grid, points)
 
 for point in PointIterator(ph)
     point === nothing && continue # Skip any points that weren't found
     reinit!(pointvalues, point)   # Update pointvalues
     # ...
-end
source
Ferrite.PointLocationType
PointLocation

Element of a PointIterator, typically used to reinitialize PointValues. Fields:

  • cid::Int: ID of the cell containing the point
  • local_coord::Vec: the local (reference) coordinate of the point
  • coords::Vector{Vec}: the coordinates of the cell
source

VTK export

Ferrite.VTKGridFileType
VTKGridFile(filename::AbstractString, grid::AbstractGrid; kwargs...)
+end
source
Ferrite.PointLocationType
PointLocation

Element of a PointIterator, typically used to reinitialize PointValues. Fields:

  • cid::Int: ID of the cell containing the point
  • local_coord::Vec: the local (reference) coordinate of the point
  • coords::Vector{Vec}: the coordinates of the cell
source

VTK export

Ferrite.VTKGridFileType
VTKGridFile(filename::AbstractString, grid::AbstractGrid; kwargs...)
 VTKGridFile(filename::AbstractString, dh::DofHandler; kwargs...)

Create a VTKGridFile that contains an unstructured VTK grid. The keyword arguments are forwarded to WriteVTK.vtk_grid, see Data Formatting Options

This file handler can be used to to write data with

It is necessary to call close(::VTKGridFile) to save the data after writing to the file handler. Using the supported do-block does this automatically:

VTKGridFile(filename, grid) do vtk
     write_solution(vtk, dh, u)
     write_cell_data(vtk, celldata)
-end
source
Ferrite.write_solutionFunction
write_solution(vtk::VTKGridFile, dh::AbstractDofHandler, u::Vector, suffix="")

Save the values at the nodes in the degree of freedom vector u to vtk. Each field in dh will be saved separately, and suffix can be used to append to the fieldname.

u can also contain tensorial values, but each entry in u must correspond to a degree of freedom in dh, see write_node_data for details. Use write_node_data directly when exporting values that are already sorted by the nodes in the grid.

source
Ferrite.write_projectionFunction
write_projection(vtk::VTKGridFile, proj::L2Projector, vals::Vector, name::AbstractString)

Project vals to the grid nodes with proj and save to vtk.

source
Ferrite.write_cell_dataFunction
write_cell_data(vtk::VTKGridFile, celldata::AbstractVector, name::String)

Write the celldata that is ordered by the cells in the grid to the vtk file.

source
Ferrite.write_node_dataFunction
write_node_data(vtk::VTKGridFile, nodedata::Vector{Real}, name)
-write_node_data(vtk::VTKGridFile, nodedata::Vector{<:AbstractTensor}, name)

Write the nodedata that is ordered by the nodes in the grid to vtk.

When nodedata contains Tensors.Vecs, each component is exported. Two-dimensional vectors are padded with zeros.

When nodedata contains second order tensors, the index order, [11, 22, 33, 23, 13, 12, 32, 31, 21], follows the default Voigt order in Tensors.jl.

source
Ferrite.write_cellsetFunction
write_cellset(vtk, grid::AbstractGrid)
+end
source
Ferrite.write_solutionFunction
write_solution(vtk::VTKGridFile, dh::AbstractDofHandler, u::Vector, suffix="")

Save the values at the nodes in the degree of freedom vector u to vtk. Each field in dh will be saved separately, and suffix can be used to append to the fieldname.

u can also contain tensorial values, but each entry in u must correspond to a degree of freedom in dh, see write_node_data for details. Use write_node_data directly when exporting values that are already sorted by the nodes in the grid.

source
Ferrite.write_projectionFunction
write_projection(vtk::VTKGridFile, proj::L2Projector, vals::Vector, name::AbstractString)

Project vals to the grid nodes with proj and save to vtk.

source
Ferrite.write_cell_dataFunction
write_cell_data(vtk::VTKGridFile, celldata::AbstractVector, name::String)

Write the celldata that is ordered by the cells in the grid to the vtk file.

source
Ferrite.write_node_dataFunction
write_node_data(vtk::VTKGridFile, nodedata::Vector{Real}, name)
+write_node_data(vtk::VTKGridFile, nodedata::Vector{<:AbstractTensor}, name)

Write the nodedata that is ordered by the nodes in the grid to vtk.

When nodedata contains Tensors.Vecs, each component is exported. Two-dimensional vectors are padded with zeros.

When nodedata contains second order tensors, the index order, [11, 22, 33, 23, 13, 12, 32, 31, 21], follows the default Voigt order in Tensors.jl.

source
Ferrite.write_cellsetFunction
write_cellset(vtk, grid::AbstractGrid)
 write_cellset(vtk, grid::AbstractGrid, cellset::String)
-write_cellset(vtk, grid::AbstractGrid, cellsets::Union{AbstractVector{String},AbstractSet{String})

Write all cell sets in the grid with name according to their keys and celldata 1 if the cell is in the set, and 0 otherwise. It is also possible to only export a single cellset, or multiple cellsets.

source
Ferrite.write_nodesetFunction
write_nodeset(vtk::VTKGridFile, grid::AbstractGrid, nodeset::String)

Write nodal values of 1 for nodes in nodeset, and 0 otherwise

source
Ferrite.write_constraintsFunction
write_constraints(vtk::VTKGridFile, ch::ConstraintHandler)

Saves the dirichlet boundary conditions to a vtkfile. Values will have a 1 where bcs are active and 0 otherwise

source
Ferrite.write_cell_colorsFunction
write_cell_colors(vtk::VTKGridFile, grid::AbstractGrid, cell_colors, name="coloring")

Write cell colors (see create_coloring) to a VTK file for visualization.

In case of coloring a subset, the cells which are not part of the subset are represented as color 0.

source
+write_cellset(vtk, grid::AbstractGrid, cellsets::Union{AbstractVector{String},AbstractSet{String})

Write all cell sets in the grid with name according to their keys and celldata 1 if the cell is in the set, and 0 otherwise. It is also possible to only export a single cellset, or multiple cellsets.

source
Ferrite.write_nodesetFunction
write_nodeset(vtk::VTKGridFile, grid::AbstractGrid, nodeset::String)

Write nodal values of 1 for nodes in nodeset, and 0 otherwise

source
Ferrite.write_constraintsFunction
write_constraints(vtk::VTKGridFile, ch::ConstraintHandler)

Saves the dirichlet boundary conditions to a vtkfile. Values will have a 1 where bcs are active and 0 otherwise

source
Ferrite.write_cell_colorsFunction
write_cell_colors(vtk::VTKGridFile, grid::AbstractGrid, cell_colors, name="coloring")

Write cell colors (see create_coloring) to a VTK file for visualization.

In case of coloring a subset, the cells which are not part of the subset are represented as color 0.

source
diff --git a/dev/reference/fevalues/index.html b/dev/reference/fevalues/index.html index b6b3a9ea1a..8b84f6e822 100644 --- a/dev/reference/fevalues/index.html +++ b/dev/reference/fevalues/index.html @@ -1,11 +1,11 @@ -FEValues · Ferrite.jl

FEValues

Main types

CellValues and FacetValues are the most common subtypes of Ferrite.AbstractValues. For more details about how these work, please see the related topic guide.

Ferrite.CellValuesType
CellValues([::Type{T},] quad_rule::QuadratureRule, func_interpol::Interpolation, [geom_interpol::Interpolation])

A CellValues object facilitates the process of evaluating values of shape functions, gradients of shape functions, values of nodal functions, gradients and divergences of nodal functions etc. in the finite element cell.

Arguments:

  • T: an optional argument (default to Float64) to determine the type the internal data is stored as.
  • quad_rule: an instance of a QuadratureRule
  • func_interpol: an instance of an Interpolation used to interpolate the approximated function
  • geom_interpol: an optional instance of a Interpolation which is used to interpolate the geometry. By default linear Lagrange interpolation is used. For embedded elements the geometric interpolations should be vectorized to the spatial dimension.

Keyword arguments: The following keyword arguments are experimental and may change in future minor releases

  • update_gradients: Specifies if the gradients of the shape functions should be updated (default true)
  • update_hessians: Specifies if the hessians of the shape functions should be updated (default false)
  • update_detJdV: Specifies if the volume associated with each quadrature point should be updated (default true)

Common methods:

source
Ferrite.FacetValuesType
FacetValues([::Type{T}], quad_rule::FacetQuadratureRule, func_interpol::Interpolation, [geom_interpol::Interpolation])

A FacetValues object facilitates the process of evaluating values of shape functions, gradients of shape functions, values of nodal functions, gradients and divergences of nodal functions etc. on the facets of finite elements.

Arguments:

  • T: an optional argument (default to Float64) to determine the type the internal data is stored as.
  • quad_rule: an instance of a FacetQuadratureRule
  • func_interpol: an instance of an Interpolation used to interpolate the approximated function
  • geom_interpol: an optional instance of an Interpolation which is used to interpolate the geometry. By default linear Lagrange interpolation is used.

Keyword arguments: The following keyword arguments are experimental and may change in future minor releases

  • update_gradients: Specifies if the gradients of the shape functions should be updated (default true)
  • update_hessians: Specifies if the hessians of the shape functions should be updated (default false)

Common methods:

source
Embedded API

Currently, embedded FEValues returns SArrays, which behave differently from the Tensors for normal value. In the future, we expect to return an AbstractTensor, this change may happen in a minor release, and the API for embedded FEValues should therefore be considered experimental.

Applicable functions

The following functions are applicable to both CellValues and FacetValues.

Ferrite.reinit!Function
reinit!(cv::CellValues, cell::AbstractCell, x::AbstractVector)
+FEValues · Ferrite.jl

FEValues

Main types

CellValues and FacetValues are the most common subtypes of Ferrite.AbstractValues. For more details about how these work, please see the related topic guide.

Ferrite.CellValuesType
CellValues([::Type{T},] quad_rule::QuadratureRule, func_interpol::Interpolation, [geom_interpol::Interpolation])

A CellValues object facilitates the process of evaluating values of shape functions, gradients of shape functions, values of nodal functions, gradients and divergences of nodal functions etc. in the finite element cell.

Arguments:

  • T: an optional argument (default to Float64) to determine the type the internal data is stored as.
  • quad_rule: an instance of a QuadratureRule
  • func_interpol: an instance of an Interpolation used to interpolate the approximated function
  • geom_interpol: an optional instance of a Interpolation which is used to interpolate the geometry. By default linear Lagrange interpolation is used. For embedded elements the geometric interpolations should be vectorized to the spatial dimension.

Keyword arguments: The following keyword arguments are experimental and may change in future minor releases

  • update_gradients: Specifies if the gradients of the shape functions should be updated (default true)
  • update_hessians: Specifies if the hessians of the shape functions should be updated (default false)
  • update_detJdV: Specifies if the volume associated with each quadrature point should be updated (default true)

Common methods:

source
Ferrite.FacetValuesType
FacetValues([::Type{T}], quad_rule::FacetQuadratureRule, func_interpol::Interpolation, [geom_interpol::Interpolation])

A FacetValues object facilitates the process of evaluating values of shape functions, gradients of shape functions, values of nodal functions, gradients and divergences of nodal functions etc. on the facets of finite elements.

Arguments:

  • T: an optional argument (default to Float64) to determine the type the internal data is stored as.
  • quad_rule: an instance of a FacetQuadratureRule
  • func_interpol: an instance of an Interpolation used to interpolate the approximated function
  • geom_interpol: an optional instance of an Interpolation which is used to interpolate the geometry. By default linear Lagrange interpolation is used.

Keyword arguments: The following keyword arguments are experimental and may change in future minor releases

  • update_gradients: Specifies if the gradients of the shape functions should be updated (default true)
  • update_hessians: Specifies if the hessians of the shape functions should be updated (default false)

Common methods:

source
Embedded API

Currently, embedded FEValues returns SArrays, which behave differently from the Tensors for normal value. In the future, we expect to return an AbstractTensor, this change may happen in a minor release, and the API for embedded FEValues should therefore be considered experimental.

Applicable functions

The following functions are applicable to both CellValues and FacetValues.

Ferrite.reinit!Function
reinit!(cv::CellValues, cell::AbstractCell, x::AbstractVector)
 reinit!(cv::CellValues, x::AbstractVector)
 reinit!(fv::FacetValues, cell::AbstractCell, x::AbstractVector, facet::Int)
-reinit!(fv::FacetValues, x::AbstractVector, function_gradient::Int)

Update the CellValues/FacetValues object for a cell or facet with cell coordinates x. The derivatives of the shape functions, and the new integration weights are computed. For interpolations with non-identity mappings, the current cell is also required.

source
Ferrite.getnquadpointsFunction
getnquadpoints(fe_v::AbstractValues)

Return the number of quadrature points. For FacetValues, this is the number for the current facet.

source
Ferrite.getdetJdVFunction
getdetJdV(fe_v::AbstractValues, q_point::Int)

Return the product between the determinant of the Jacobian and the quadrature point weight for the given quadrature point: $\det(J(\mathbf{x})) w_q$.

This value is typically used when one integrates a function on a finite element cell or facet as

$\int\limits_\Omega f(\mathbf{x}) d \Omega \approx \sum\limits_{q = 1}^{n_q} f(\mathbf{x}_q) \det(J(\mathbf{x})) w_q$ $\int\limits_\Gamma f(\mathbf{x}) d \Gamma \approx \sum\limits_{q = 1}^{n_q} f(\mathbf{x}_q) \det(J(\mathbf{x})) w_q$

source
Ferrite.shape_valueMethod
shape_value(fe_v::AbstractValues, q_point::Int, base_function::Int)

Return the value of shape function base_function evaluated in quadrature point q_point.

source
Ferrite.shape_gradientMethod
shape_gradient(fe_v::AbstractValues, q_point::Int, base_function::Int)

Return the gradient of shape function base_function evaluated in quadrature point q_point.

source
Ferrite.shape_symmetric_gradientFunction
shape_symmetric_gradient(fe_v::AbstractValues, q_point::Int, base_function::Int)

Return the symmetric gradient of shape function base_function evaluated in quadrature point q_point.

source
Ferrite.shape_divergenceFunction
shape_divergence(fe_v::AbstractValues, q_point::Int, base_function::Int)

Return the divergence of shape function base_function evaluated in quadrature point q_point.

source
Ferrite.shape_curlFunction
shape_curl(fe_v::AbstractValues, q_point::Int, base_function::Int)

Return the curl of shape function base_function evaluated in quadrature point q_point.

source
Ferrite.geometric_valueFunction
geometric_value(fe_v::AbstractValues, q_point, base_function::Int)

Return the value of the geometric shape function base_function evaluated in quadrature point q_point.

source
Ferrite.function_valueFunction
function_value(iv::InterfaceValues, q_point::Int, u; here::Bool)
-function_value(iv::InterfaceValues, q_point::Int, u, dof_range_here, dof_range_there; here::Bool)

Compute the value of the function in quadrature point q_point on the "here" (here=true) or "there" (here=false) side of the interface. u_here and u_there are the values of the degrees of freedom for the respective element.

u is a vector of scalar values for the degrees of freedom. This function can be used with a single u vector containing the dofs of both elements of the interface or two vectors (u_here and u_there) which contain the dofs of each cell of the interface respectively.

here determines which element to use for calculating function value. true uses the value on the first element's side of the interface, while false uses the value on the second element's side.

The value of a scalar valued function is computed as $u(\mathbf{x}) = \sum\limits_{i = 1}^n N_i (\mathbf{x}) u_i$ where $u_i$ are the value of $u$ in the nodes. For a vector valued function the value is calculated as $\mathbf{u}(\mathbf{x}) = \sum\limits_{i = 1}^n N_i (\mathbf{x}) \mathbf{u}_i$ where $\mathbf{u}_i$ are the nodal values of $\mathbf{u}$.

source
function_value(fe_v::AbstractValues, q_point::Int, u::AbstractVector, [dof_range])

Compute the value of the function in a quadrature point. u is a vector with values for the degrees of freedom. For a scalar valued function, u contains scalars. For a vector valued function, u can be a vector of scalars (for use of VectorValues) or u can be a vector of Vecs (for use with ScalarValues).

The value of a scalar valued function is computed as $u(\mathbf{x}) = \sum\limits_{i = 1}^n N_i (\mathbf{x}) u_i$ where $u_i$ are the value of $u$ in the nodes. For a vector valued function the value is calculated as $\mathbf{u}(\mathbf{x}) = \sum\limits_{i = 1}^n N_i (\mathbf{x}) \mathbf{u}_i$ where $\mathbf{u}_i$ are the nodal values of $\mathbf{u}$.

source
Ferrite.function_gradientFunction
function_gradient(iv::InterfaceValues, q_point::Int, u; here::Bool)
-function_gradient(iv::InterfaceValues, q_point::Int, u, dof_range_here, dof_range_there; here::Bool)

Compute the gradient of the function in a quadrature point. u is a vector of scalar values for the degrees of freedom. This function can be used with a single u vector containing the dofs of both elements of the interface or two vectors (u_here and u_there) which contain the dofs of each cell of the interface respectively.

here determines which element to use for calculating function value. true uses the value on the first element's side of the interface, while false uses the value on the second element's side.

The gradient of a scalar function or a vector valued function with use of VectorValues is computed as $\mathbf{\nabla} u(\mathbf{x}) = \sum\limits_{i = 1}^n \mathbf{\nabla} N_i (\mathbf{x}) u_i$ or $\mathbf{\nabla} u(\mathbf{x}) = \sum\limits_{i = 1}^n \mathbf{\nabla} \mathbf{N}_i (\mathbf{x}) u_i$ respectively, where $u_i$ are the nodal values of the function. For a vector valued function with use of ScalarValues the gradient is computed as $\mathbf{\nabla} \mathbf{u}(\mathbf{x}) = \sum\limits_{i = 1}^n \mathbf{u}_i \otimes \mathbf{\nabla} N_i (\mathbf{x})$ where $\mathbf{u}_i$ are the nodal values of $\mathbf{u}$.

source
function_gradient(fe_v::AbstractValues{dim}, q_point::Int, u::AbstractVector, [dof_range])

Compute the gradient of the function in a quadrature point. u is a vector with values for the degrees of freedom. For a scalar valued function, u contains scalars. For a vector valued function, u can be a vector of scalars (for use of VectorValues) or u can be a vector of Vecs (for use with ScalarValues).

The gradient of a scalar function or a vector valued function with use of VectorValues is computed as $\mathbf{\nabla} u(\mathbf{x}) = \sum\limits_{i = 1}^n \mathbf{\nabla} N_i (\mathbf{x}) u_i$ or $\mathbf{\nabla} u(\mathbf{x}) = \sum\limits_{i = 1}^n \mathbf{\nabla} \mathbf{N}_i (\mathbf{x}) u_i$ respectively, where $u_i$ are the nodal values of the function. For a vector valued function with use of ScalarValues the gradient is computed as $\mathbf{\nabla} \mathbf{u}(\mathbf{x}) = \sum\limits_{i = 1}^n \mathbf{u}_i \otimes \mathbf{\nabla} N_i (\mathbf{x})$ where $\mathbf{u}_i$ are the nodal values of $\mathbf{u}$.

source
Ferrite.function_symmetric_gradientFunction
function_symmetric_gradient(fe_v::AbstractValues, q_point::Int, u::AbstractVector, [dof_range])

Compute the symmetric gradient of the function, see function_gradient. Return a SymmetricTensor.

The symmetric gradient of a scalar function is computed as $\left[ \mathbf{\nabla} \mathbf{u}(\mathbf{x_q}) \right]^\text{sym} = \sum\limits_{i = 1}^n \frac{1}{2} \left[ \mathbf{\nabla} N_i (\mathbf{x}_q) \otimes \mathbf{u}_i + \mathbf{u}_i \otimes \mathbf{\nabla} N_i (\mathbf{x}_q) \right]$ where $\mathbf{u}_i$ are the nodal values of the function.

source
Ferrite.function_divergenceFunction
function_divergence(fe_v::AbstractValues, q_point::Int, u::AbstractVector, [dof_range])

Compute the divergence of the vector valued function in a quadrature point.

The divergence of a vector valued functions in the quadrature point $\mathbf{x}_q)$ is computed as $\mathbf{\nabla} \cdot \mathbf{u}(\mathbf{x_q}) = \sum\limits_{i = 1}^n \mathbf{\nabla} N_i (\mathbf{x_q}) \cdot \mathbf{u}_i$ where $\mathbf{u}_i$ are the nodal values of the function.

source
Ferrite.function_curlFunction
function_curl(fe_v::AbstractValues, q_point::Int, u::AbstractVector, [dof_range])

Compute the curl of the vector valued function in a quadrature point.

The curl of a vector valued functions in the quadrature point $\mathbf{x}_q)$ is computed as $\mathbf{\nabla} \times \mathbf{u}(\mathbf{x_q}) = \sum\limits_{i = 1}^n \mathbf{\nabla} N_i \times (\mathbf{x_q}) \cdot \mathbf{u}_i$ where $\mathbf{u}_i$ are the nodal values of the function.

source
Ferrite.spatial_coordinateFunction
spatial_coordinate(fe_v::AbstractValues, q_point::Int, x::AbstractVector)

Compute the spatial coordinate in a quadrature point. x contains the nodal coordinates of the cell.

The coordinate is computed, using the geometric interpolation, as $\mathbf{x} = \sum\limits_{i = 1}^n M_i (\mathbf{\xi}) \mathbf{\hat{x}}_i$.

where $\xi$is the coordinate of the given quadrature point q_point of the associated quadrature rule.

source
spatial_coordinate(ip::ScalarInterpolation, ξ::Vec, x::AbstractVector{<:Vec{sdim, T}})

Compute the spatial coordinate in a given quadrature point. x contains the nodal coordinates of the cell.

The coordinate is computed, using the geometric interpolation, as $\mathbf{x} = \sum\limits_{i = 1}^n M_i (\mathbf{\xi}) \mathbf{\hat{x}}_i$

source

In addition, there are some methods that are unique for FacetValues.

Ferrite.getcurrentfacetFunction
getcurrentfacet(fv::FacetValues)

Return the current active facet of the FacetValues object (from last reinit!).

source
Ferrite.getnormalFunction
getnormal(fv::FacetValues, qp::Int)

Return the normal at the quadrature point qp for the active facet of the FacetValues object(from last reinit!).

source
getnormal(iv::InterfaceValues, qp::Int; here::Bool=true)

Return the normal vector in the quadrature point qp on the interface. If here = true (default) the outward normal to the "here" element is returned, otherwise the outward normal to the "there" element.

source

InterfaceValues

All of the methods for FacetValues apply for InterfaceValues as well. In addition, there are some methods that are unique for InterfaceValues:

Ferrite.InterfaceValuesType
InterfaceValues

An InterfaceValues object facilitates the process of evaluating values, averages, jumps and gradients of shape functions and function on the interfaces between elements.

The first element of the interface is denoted "here" and the second element "there".

Constructors

  • InterfaceValues(qr::FacetQuadratureRule, ip::Interpolation): same quadrature rule and interpolation on both sides, default linear Lagrange geometric interpolation.
  • InterfaceValues(qr::FacetQuadratureRule, ip::Interpolation, ip_geo::Interpolation): same as above but with given geometric interpolation.
  • InterfaceValues(qr_here::FacetQuadratureRule, ip_here::Interpolation, qr_there::FacetQuadratureRule, ip_there::Interpolation): different quadrature rule and interpolation on the two sides, default linear Lagrange geometric interpolation.
  • InterfaceValues(qr_here::FacetQuadratureRule, ip_here::Interpolation, ip_geo_here::Interpolation, qr_there::FacetQuadratureRule, ip_there::Interpolation, ip_geo_there::Interpolation): same as above but with given geometric interpolation.
  • InterfaceValues(fv::FacetValues): quadrature rule and interpolations from face values (same on both sides).
  • InterfaceValues(fv_here::FacetValues, fv_there::FacetValues): quadrature rule and interpolations from the face values.

Associated methods:

Common methods:

source
Ferrite.shape_value_averageFunction
shape_value_average(iv::InterfaceValues, qp::Int, i::Int)

Compute the average of the value of shape function i at quadrature point qp across the interface.

source
Ferrite.shape_value_jumpFunction
shape_value_jump(iv::InterfaceValues, qp::Int, i::Int)

Compute the jump of the value of shape function i at quadrature point qp across the interface in the default normal direction.

This function uses the definition $\llbracket \vec{v} \rrbracket=\vec{v}^\text{there} -\vec{v}^\text{here}$. To obtain the form, $\llbracket \vec{v} \rrbracket=\vec{v}^\text{there} \cdot \vec{n}^\text{there} + \vec{v}^\text{here} \cdot \vec{n}^\text{here}$, multiply by minus the outward facing normal to the first element's side of the interface (which is the default normal for getnormal with InterfaceValues).

source
Ferrite.shape_gradient_averageFunction
shape_gradient_average(iv::InterfaceValues, qp::Int, i::Int)

Compute the average of the gradient of shape function i at quadrature point qp across the interface.

source
Ferrite.shape_gradient_jumpFunction
shape_gradient_jump(iv::InterfaceValues, qp::Int, i::Int)

Compute the jump of the gradient of shape function i at quadrature point qp across the interface in the default normal direction.

This function uses the definition $\llbracket \vec{v} \rrbracket=\vec{v}^\text{there} -\vec{v}^\text{here}$. To obtain the form, $\llbracket \vec{v} \rrbracket=\vec{v}^\text{there} ⋅ \vec{n}^\text{there} + \vec{v}^\text{here} ⋅ \vec{n}^\text{here}$, multiply by minus the outward facing normal to the first element's side of the interface (which is the default normal for getnormal with InterfaceValues).

source
Ferrite.function_value_averageFunction
function_value_average(iv::InterfaceValues, q_point::Int, u)
-function_value_average(iv::InterfaceValues, q_point::Int, u, dof_range_here, dof_range_there)

Compute the average of the function value at the quadrature point on the interface.

source
Ferrite.function_value_jumpFunction
function_value_jump(iv::InterfaceValues, q_point::Int, u)
-function_value_jump(iv::InterfaceValues, q_point::Int, u, dof_range_here, dof_range_there)

Compute the jump of the function value at the quadrature point over the interface along the default normal direction.

This function uses the definition $\llbracket \vec{v} \rrbracket=\vec{v}^\text{there} -\vec{v}^\text{here}$. To obtain the form, $\llbracket \vec{v} \rrbracket=\vec{v}^\text{there} ⋅ \vec{n}^\text{there} + \vec{v}^\text{here} ⋅ \vec{n}^\text{here}$, multiply by minus the outward facing normal to the first element's side of the interface (which is the default normal for getnormal with InterfaceValues).

source
Ferrite.function_gradient_averageFunction
function_gradient_average(iv::InterfaceValues, q_point::Int, u)
-function_gradient_average(iv::InterfaceValues, q_point::Int, u, dof_range_here, dof_range_there)

Compute the average of the function gradient at the quadrature point on the interface.

source
Ferrite.function_gradient_jumpFunction
function_gradient_jump(iv::InterfaceValues, q_point::Int, u)
-function_gradient_jump(iv::InterfaceValues, q_point::Int, u, dof_range_here, dof_range_there)

Compute the jump of the function gradient at the quadrature point over the interface along the default normal direction.

This function uses the definition $\llbracket \vec{v} \rrbracket=\vec{v}^\text{there} -\vec{v}^\text{here}$. To obtain the form, $\llbracket \vec{v} \rrbracket=\vec{v}^\text{there} ⋅ \vec{n}^\text{there} + \vec{v}^\text{here} ⋅ \vec{n}^\text{here}$, multiply by minus the outward facing normal to the first element's side of the interface (which is the default normal for getnormal with InterfaceValues).

source
+reinit!(fv::FacetValues, x::AbstractVector, function_gradient::Int)

Update the CellValues/FacetValues object for a cell or facet with cell coordinates x. The derivatives of the shape functions, and the new integration weights are computed. For interpolations with non-identity mappings, the current cell is also required.

source
Ferrite.getnquadpointsFunction
getnquadpoints(fe_v::AbstractValues)

Return the number of quadrature points. For FacetValues, this is the number for the current facet.

source
Ferrite.getdetJdVFunction
getdetJdV(fe_v::AbstractValues, q_point::Int)

Return the product between the determinant of the Jacobian and the quadrature point weight for the given quadrature point: $\det(J(\mathbf{x})) w_q$.

This value is typically used when one integrates a function on a finite element cell or facet as

$\int\limits_\Omega f(\mathbf{x}) d \Omega \approx \sum\limits_{q = 1}^{n_q} f(\mathbf{x}_q) \det(J(\mathbf{x})) w_q$ $\int\limits_\Gamma f(\mathbf{x}) d \Gamma \approx \sum\limits_{q = 1}^{n_q} f(\mathbf{x}_q) \det(J(\mathbf{x})) w_q$

source
Ferrite.shape_valueMethod
shape_value(fe_v::AbstractValues, q_point::Int, base_function::Int)

Return the value of shape function base_function evaluated in quadrature point q_point.

source
Ferrite.shape_gradientMethod
shape_gradient(fe_v::AbstractValues, q_point::Int, base_function::Int)

Return the gradient of shape function base_function evaluated in quadrature point q_point.

source
Ferrite.shape_symmetric_gradientFunction
shape_symmetric_gradient(fe_v::AbstractValues, q_point::Int, base_function::Int)

Return the symmetric gradient of shape function base_function evaluated in quadrature point q_point.

source
Ferrite.shape_divergenceFunction
shape_divergence(fe_v::AbstractValues, q_point::Int, base_function::Int)

Return the divergence of shape function base_function evaluated in quadrature point q_point.

source
Ferrite.shape_curlFunction
shape_curl(fe_v::AbstractValues, q_point::Int, base_function::Int)

Return the curl of shape function base_function evaluated in quadrature point q_point.

source
Ferrite.geometric_valueFunction
geometric_value(fe_v::AbstractValues, q_point, base_function::Int)

Return the value of the geometric shape function base_function evaluated in quadrature point q_point.

source
Ferrite.function_valueFunction
function_value(iv::InterfaceValues, q_point::Int, u; here::Bool)
+function_value(iv::InterfaceValues, q_point::Int, u, dof_range_here, dof_range_there; here::Bool)

Compute the value of the function in quadrature point q_point on the "here" (here=true) or "there" (here=false) side of the interface. u_here and u_there are the values of the degrees of freedom for the respective element.

u is a vector of scalar values for the degrees of freedom. This function can be used with a single u vector containing the dofs of both elements of the interface or two vectors (u_here and u_there) which contain the dofs of each cell of the interface respectively.

here determines which element to use for calculating function value. true uses the value on the first element's side of the interface, while false uses the value on the second element's side.

The value of a scalar valued function is computed as $u(\mathbf{x}) = \sum\limits_{i = 1}^n N_i (\mathbf{x}) u_i$ where $u_i$ are the value of $u$ in the nodes. For a vector valued function the value is calculated as $\mathbf{u}(\mathbf{x}) = \sum\limits_{i = 1}^n N_i (\mathbf{x}) \mathbf{u}_i$ where $\mathbf{u}_i$ are the nodal values of $\mathbf{u}$.

source
function_value(fe_v::AbstractValues, q_point::Int, u::AbstractVector, [dof_range])

Compute the value of the function in a quadrature point. u is a vector with values for the degrees of freedom. For a scalar valued function, u contains scalars. For a vector valued function, u can be a vector of scalars (for use of VectorValues) or u can be a vector of Vecs (for use with ScalarValues).

The value of a scalar valued function is computed as $u(\mathbf{x}) = \sum\limits_{i = 1}^n N_i (\mathbf{x}) u_i$ where $u_i$ are the value of $u$ in the nodes. For a vector valued function the value is calculated as $\mathbf{u}(\mathbf{x}) = \sum\limits_{i = 1}^n N_i (\mathbf{x}) \mathbf{u}_i$ where $\mathbf{u}_i$ are the nodal values of $\mathbf{u}$.

source
Ferrite.function_gradientFunction
function_gradient(iv::InterfaceValues, q_point::Int, u; here::Bool)
+function_gradient(iv::InterfaceValues, q_point::Int, u, dof_range_here, dof_range_there; here::Bool)

Compute the gradient of the function in a quadrature point. u is a vector of scalar values for the degrees of freedom. This function can be used with a single u vector containing the dofs of both elements of the interface or two vectors (u_here and u_there) which contain the dofs of each cell of the interface respectively.

here determines which element to use for calculating function value. true uses the value on the first element's side of the interface, while false uses the value on the second element's side.

The gradient of a scalar function or a vector valued function with use of VectorValues is computed as $\mathbf{\nabla} u(\mathbf{x}) = \sum\limits_{i = 1}^n \mathbf{\nabla} N_i (\mathbf{x}) u_i$ or $\mathbf{\nabla} u(\mathbf{x}) = \sum\limits_{i = 1}^n \mathbf{\nabla} \mathbf{N}_i (\mathbf{x}) u_i$ respectively, where $u_i$ are the nodal values of the function. For a vector valued function with use of ScalarValues the gradient is computed as $\mathbf{\nabla} \mathbf{u}(\mathbf{x}) = \sum\limits_{i = 1}^n \mathbf{u}_i \otimes \mathbf{\nabla} N_i (\mathbf{x})$ where $\mathbf{u}_i$ are the nodal values of $\mathbf{u}$.

source
function_gradient(fe_v::AbstractValues{dim}, q_point::Int, u::AbstractVector, [dof_range])

Compute the gradient of the function in a quadrature point. u is a vector with values for the degrees of freedom. For a scalar valued function, u contains scalars. For a vector valued function, u can be a vector of scalars (for use of VectorValues) or u can be a vector of Vecs (for use with ScalarValues).

The gradient of a scalar function or a vector valued function with use of VectorValues is computed as $\mathbf{\nabla} u(\mathbf{x}) = \sum\limits_{i = 1}^n \mathbf{\nabla} N_i (\mathbf{x}) u_i$ or $\mathbf{\nabla} u(\mathbf{x}) = \sum\limits_{i = 1}^n \mathbf{\nabla} \mathbf{N}_i (\mathbf{x}) u_i$ respectively, where $u_i$ are the nodal values of the function. For a vector valued function with use of ScalarValues the gradient is computed as $\mathbf{\nabla} \mathbf{u}(\mathbf{x}) = \sum\limits_{i = 1}^n \mathbf{u}_i \otimes \mathbf{\nabla} N_i (\mathbf{x})$ where $\mathbf{u}_i$ are the nodal values of $\mathbf{u}$.

source
Ferrite.function_symmetric_gradientFunction
function_symmetric_gradient(fe_v::AbstractValues, q_point::Int, u::AbstractVector, [dof_range])

Compute the symmetric gradient of the function, see function_gradient. Return a SymmetricTensor.

The symmetric gradient of a scalar function is computed as $\left[ \mathbf{\nabla} \mathbf{u}(\mathbf{x_q}) \right]^\text{sym} = \sum\limits_{i = 1}^n \frac{1}{2} \left[ \mathbf{\nabla} N_i (\mathbf{x}_q) \otimes \mathbf{u}_i + \mathbf{u}_i \otimes \mathbf{\nabla} N_i (\mathbf{x}_q) \right]$ where $\mathbf{u}_i$ are the nodal values of the function.

source
Ferrite.function_divergenceFunction
function_divergence(fe_v::AbstractValues, q_point::Int, u::AbstractVector, [dof_range])

Compute the divergence of the vector valued function in a quadrature point.

The divergence of a vector valued functions in the quadrature point $\mathbf{x}_q)$ is computed as $\mathbf{\nabla} \cdot \mathbf{u}(\mathbf{x_q}) = \sum\limits_{i = 1}^n \mathbf{\nabla} N_i (\mathbf{x_q}) \cdot \mathbf{u}_i$ where $\mathbf{u}_i$ are the nodal values of the function.

source
Ferrite.function_curlFunction
function_curl(fe_v::AbstractValues, q_point::Int, u::AbstractVector, [dof_range])

Compute the curl of the vector valued function in a quadrature point.

The curl of a vector valued functions in the quadrature point $\mathbf{x}_q)$ is computed as $\mathbf{\nabla} \times \mathbf{u}(\mathbf{x_q}) = \sum\limits_{i = 1}^n \mathbf{\nabla} N_i \times (\mathbf{x_q}) \cdot \mathbf{u}_i$ where $\mathbf{u}_i$ are the nodal values of the function.

source
Ferrite.spatial_coordinateFunction
spatial_coordinate(fe_v::AbstractValues, q_point::Int, x::AbstractVector)

Compute the spatial coordinate in a quadrature point. x contains the nodal coordinates of the cell.

The coordinate is computed, using the geometric interpolation, as $\mathbf{x} = \sum\limits_{i = 1}^n M_i (\mathbf{\xi}) \mathbf{\hat{x}}_i$.

where $\xi$is the coordinate of the given quadrature point q_point of the associated quadrature rule.

source
spatial_coordinate(ip::ScalarInterpolation, ξ::Vec, x::AbstractVector{<:Vec{sdim, T}})

Compute the spatial coordinate in a given quadrature point. x contains the nodal coordinates of the cell.

The coordinate is computed, using the geometric interpolation, as $\mathbf{x} = \sum\limits_{i = 1}^n M_i (\mathbf{\xi}) \mathbf{\hat{x}}_i$

source

In addition, there are some methods that are unique for FacetValues.

Ferrite.getcurrentfacetFunction
getcurrentfacet(fv::FacetValues)

Return the current active facet of the FacetValues object (from last reinit!).

source
Ferrite.getnormalFunction
getnormal(fv::FacetValues, qp::Int)

Return the normal at the quadrature point qp for the active facet of the FacetValues object(from last reinit!).

source
getnormal(iv::InterfaceValues, qp::Int; here::Bool=true)

Return the normal vector in the quadrature point qp on the interface. If here = true (default) the outward normal to the "here" element is returned, otherwise the outward normal to the "there" element.

source

InterfaceValues

All of the methods for FacetValues apply for InterfaceValues as well. In addition, there are some methods that are unique for InterfaceValues:

Ferrite.InterfaceValuesType
InterfaceValues

An InterfaceValues object facilitates the process of evaluating values, averages, jumps and gradients of shape functions and function on the interfaces between elements.

The first element of the interface is denoted "here" and the second element "there".

Constructors

  • InterfaceValues(qr::FacetQuadratureRule, ip::Interpolation): same quadrature rule and interpolation on both sides, default linear Lagrange geometric interpolation.
  • InterfaceValues(qr::FacetQuadratureRule, ip::Interpolation, ip_geo::Interpolation): same as above but with given geometric interpolation.
  • InterfaceValues(qr_here::FacetQuadratureRule, ip_here::Interpolation, qr_there::FacetQuadratureRule, ip_there::Interpolation): different quadrature rule and interpolation on the two sides, default linear Lagrange geometric interpolation.
  • InterfaceValues(qr_here::FacetQuadratureRule, ip_here::Interpolation, ip_geo_here::Interpolation, qr_there::FacetQuadratureRule, ip_there::Interpolation, ip_geo_there::Interpolation): same as above but with given geometric interpolation.
  • InterfaceValues(fv::FacetValues): quadrature rule and interpolations from face values (same on both sides).
  • InterfaceValues(fv_here::FacetValues, fv_there::FacetValues): quadrature rule and interpolations from the face values.

Associated methods:

Common methods:

source
Ferrite.shape_value_averageFunction
shape_value_average(iv::InterfaceValues, qp::Int, i::Int)

Compute the average of the value of shape function i at quadrature point qp across the interface.

source
Ferrite.shape_value_jumpFunction
shape_value_jump(iv::InterfaceValues, qp::Int, i::Int)

Compute the jump of the value of shape function i at quadrature point qp across the interface in the default normal direction.

This function uses the definition $\llbracket \vec{v} \rrbracket=\vec{v}^\text{there} -\vec{v}^\text{here}$. To obtain the form, $\llbracket \vec{v} \rrbracket=\vec{v}^\text{there} \cdot \vec{n}^\text{there} + \vec{v}^\text{here} \cdot \vec{n}^\text{here}$, multiply by minus the outward facing normal to the first element's side of the interface (which is the default normal for getnormal with InterfaceValues).

source
Ferrite.shape_gradient_averageFunction
shape_gradient_average(iv::InterfaceValues, qp::Int, i::Int)

Compute the average of the gradient of shape function i at quadrature point qp across the interface.

source
Ferrite.shape_gradient_jumpFunction
shape_gradient_jump(iv::InterfaceValues, qp::Int, i::Int)

Compute the jump of the gradient of shape function i at quadrature point qp across the interface in the default normal direction.

This function uses the definition $\llbracket \vec{v} \rrbracket=\vec{v}^\text{there} -\vec{v}^\text{here}$. To obtain the form, $\llbracket \vec{v} \rrbracket=\vec{v}^\text{there} ⋅ \vec{n}^\text{there} + \vec{v}^\text{here} ⋅ \vec{n}^\text{here}$, multiply by minus the outward facing normal to the first element's side of the interface (which is the default normal for getnormal with InterfaceValues).

source
Ferrite.function_value_averageFunction
function_value_average(iv::InterfaceValues, q_point::Int, u)
+function_value_average(iv::InterfaceValues, q_point::Int, u, dof_range_here, dof_range_there)

Compute the average of the function value at the quadrature point on the interface.

source
Ferrite.function_value_jumpFunction
function_value_jump(iv::InterfaceValues, q_point::Int, u)
+function_value_jump(iv::InterfaceValues, q_point::Int, u, dof_range_here, dof_range_there)

Compute the jump of the function value at the quadrature point over the interface along the default normal direction.

This function uses the definition $\llbracket \vec{v} \rrbracket=\vec{v}^\text{there} -\vec{v}^\text{here}$. To obtain the form, $\llbracket \vec{v} \rrbracket=\vec{v}^\text{there} ⋅ \vec{n}^\text{there} + \vec{v}^\text{here} ⋅ \vec{n}^\text{here}$, multiply by minus the outward facing normal to the first element's side of the interface (which is the default normal for getnormal with InterfaceValues).

source
Ferrite.function_gradient_averageFunction
function_gradient_average(iv::InterfaceValues, q_point::Int, u)
+function_gradient_average(iv::InterfaceValues, q_point::Int, u, dof_range_here, dof_range_there)

Compute the average of the function gradient at the quadrature point on the interface.

source
Ferrite.function_gradient_jumpFunction
function_gradient_jump(iv::InterfaceValues, q_point::Int, u)
+function_gradient_jump(iv::InterfaceValues, q_point::Int, u, dof_range_here, dof_range_there)

Compute the jump of the function gradient at the quadrature point over the interface along the default normal direction.

This function uses the definition $\llbracket \vec{v} \rrbracket=\vec{v}^\text{there} -\vec{v}^\text{here}$. To obtain the form, $\llbracket \vec{v} \rrbracket=\vec{v}^\text{there} ⋅ \vec{n}^\text{there} + \vec{v}^\text{here} ⋅ \vec{n}^\text{here}$, multiply by minus the outward facing normal to the first element's side of the interface (which is the default normal for getnormal with InterfaceValues).

source
diff --git a/dev/reference/grid/index.html b/dev/reference/grid/index.html index 51b7c5edab..87b251d25b 100644 --- a/dev/reference/grid/index.html +++ b/dev/reference/grid/index.html @@ -1,26 +1,26 @@ -Grid & AbstractGrid · Ferrite.jl

Grid & AbstractGrid

Grid

Ferrite.generate_gridFunction
generate_grid(celltype::Cell, nel::NTuple, [left::Vec, right::Vec)

Return a Grid for a rectangle in 1, 2 or 3 dimensions. celltype defined the type of cells, e.g. Triangle or Hexahedron. nel is a tuple of the number of elements in each direction. left and right are optional endpoints of the domain. Defaults to -1 and 1 in all directions.

source
Ferrite.NodeType
Node{dim, T}

A Node is a point in space.

Fields

  • x::Vec{dim,T}: stores the coordinates
source
Ferrite.VertexIndexType

A VertexIndex wraps an (Int, Int) and defines a local vertex by pointing to a (cell, vert).

source
Ferrite.EdgeIndexType

A EdgeIndex wraps an (Int, Int) and defines a local edge by pointing to a (cell, edge).

source
Ferrite.FaceIndexType

A FaceIndex wraps an (Int, Int) and defines a local face by pointing to a (cell, face).

source
Ferrite.FacetIndexType

A FacetIndex wraps an (Int, Int) and defines a local facet by pointing to a (cell, facet).

source
Ferrite.GridType
Grid{dim, C<:AbstractCell, T<:Real} <: AbstractGrid}

A Grid is a collection of Ferrite.AbstractCells and Ferrite.Nodes which covers the computational domain. Helper structures for applying boundary conditions or define subdomains are gathered in cellsets, nodesets, facetsets, and vertexsets.

Fields

  • cells::Vector{C}: stores all cells of the grid
  • nodes::Vector{Node{dim,T}}: stores the dim dimensional nodes of the grid
  • cellsets::Dict{String, OrderedSet{Int}}: maps a String key to an OrderedSet of cell ids
  • nodesets::Dict{String, OrderedSet{Int}}: maps a String key to an OrderedSet of global node ids
  • facetsets::Dict{String, OrderedSet{FacetIndex}}: maps a String to an OrderedSet of FacetIndex
  • vertexsets::Dict{String, OrderedSet{VertexIndex}}: maps a String key to an OrderedSet of VertexIndex
source

Utility Functions

Ferrite.getcellsFunction
getcells(grid::AbstractGrid)
+Grid & AbstractGrid · Ferrite.jl

Grid & AbstractGrid

Grid

Ferrite.generate_gridFunction
generate_grid(celltype::Cell, nel::NTuple, [left::Vec, right::Vec)

Return a Grid for a rectangle in 1, 2 or 3 dimensions. celltype defined the type of cells, e.g. Triangle or Hexahedron. nel is a tuple of the number of elements in each direction. left and right are optional endpoints of the domain. Defaults to -1 and 1 in all directions.

source
Ferrite.NodeType
Node{dim, T}

A Node is a point in space.

Fields

  • x::Vec{dim,T}: stores the coordinates
source
Ferrite.VertexIndexType

A VertexIndex wraps an (Int, Int) and defines a local vertex by pointing to a (cell, vert).

source
Ferrite.EdgeIndexType

A EdgeIndex wraps an (Int, Int) and defines a local edge by pointing to a (cell, edge).

source
Ferrite.FaceIndexType

A FaceIndex wraps an (Int, Int) and defines a local face by pointing to a (cell, face).

source
Ferrite.FacetIndexType

A FacetIndex wraps an (Int, Int) and defines a local facet by pointing to a (cell, facet).

source
Ferrite.GridType
Grid{dim, C<:AbstractCell, T<:Real} <: AbstractGrid}

A Grid is a collection of Ferrite.AbstractCells and Ferrite.Nodes which covers the computational domain. Helper structures for applying boundary conditions or define subdomains are gathered in cellsets, nodesets, facetsets, and vertexsets.

Fields

  • cells::Vector{C}: stores all cells of the grid
  • nodes::Vector{Node{dim,T}}: stores the dim dimensional nodes of the grid
  • cellsets::Dict{String, OrderedSet{Int}}: maps a String key to an OrderedSet of cell ids
  • nodesets::Dict{String, OrderedSet{Int}}: maps a String key to an OrderedSet of global node ids
  • facetsets::Dict{String, OrderedSet{FacetIndex}}: maps a String to an OrderedSet of FacetIndex
  • vertexsets::Dict{String, OrderedSet{VertexIndex}}: maps a String key to an OrderedSet of VertexIndex
source

Utility Functions

Ferrite.getcellsFunction
getcells(grid::AbstractGrid)
 getcells(grid::AbstractGrid, v::Union{Int,Vector{Int}}
-getcells(grid::AbstractGrid, setname::String)

Returns either all cells::Collection{C<:AbstractCell} of a <:AbstractGrid or a subset based on an Int, Vector{Int} or String. Whereas the last option tries to call a cellset of the grid. Collection can be any indexable type, for Grid it is Vector{C<:AbstractCell}.

source
Ferrite.getnodesFunction
getnodes(grid::AbstractGrid)
+getcells(grid::AbstractGrid, setname::String)

Returns either all cells::Collection{C<:AbstractCell} of a <:AbstractGrid or a subset based on an Int, Vector{Int} or String. Whereas the last option tries to call a cellset of the grid. Collection can be any indexable type, for Grid it is Vector{C<:AbstractCell}.

source
Ferrite.getnodesFunction
getnodes(grid::AbstractGrid)
 getnodes(grid::AbstractGrid, v::Union{Int,Vector{Int}}
-getnodes(grid::AbstractGrid, setname::String)

Returns either all nodes::Collection{N} of a <:AbstractGrid or a subset based on an Int, Vector{Int} or String. The last option tries to call a nodeset of the <:AbstractGrid. Collection{N} refers to some indexable collection where each element corresponds to a Node.

source
Ferrite.getcellsetFunction
getcellset(grid::AbstractGrid, setname::String)

Returns all cells as cellid in the set with name setname.

source
Ferrite.getnodesetFunction
getnodeset(grid::AbstractGrid, setname::String)

Returns all nodes as nodeid in the set with name setname.

source
Ferrite.getfacetsetFunction
getfacetset(grid::AbstractGrid, setname::String)

Returns all faces as FacetIndex in the set with name setname.

source
Ferrite.getvertexsetFunction
getvertexset(grid::AbstractGrid, setname::String)

Returns all vertices as VertexIndex in the set with name setname.

source
Ferrite.transform_coordinates!Function
transform_coordinates!(grid::Abstractgrid, f::Function)

Transform the coordinates of all nodes of the grid based on some transformation function f(x).

source
Ferrite.getcoordinatesFunction
getcoordinates(grid::AbstractGrid, idx::Union{Int,CellIndex})
-getcoordinates(cache::CellCache)

Get a vector with the coordinates of the cell corresponding to idx or cache

source
Ferrite.getcoordinates!Function
getcoordinates!(x::Vector{<:Vec}, grid::AbstractGrid, idx::Union{Int,CellIndex})
-getcoordinates!(x::Vector{<:Vec}, grid::AbstractGrid, cell::AbstractCell)

Mutate x to the coordinates of the cell corresponding to idx or cell.

source
Ferrite.geometric_interpolationMethod
geometric_interpolation(::AbstractCell)::ScalarInterpolation
-geometric_interpolation(::Type{<:AbstractCell})::ScalarInterpolation

Each AbstractCell type has a unique geometric interpolation describing its geometry. This function returns that interpolation, which is always a scalar interpolation.

source
Ferrite.get_node_coordinateFunction
get_node_coordinate(::Node)

Get the value of the node coordinate.

source
get_node_coordinate(grid::AbstractGrid, n::Int)

Return the coordinate of the nth node in grid

source
Ferrite.getspatialdimMethod
Ferrite.getspatialdim(grid::AbstractGrid)

Get the spatial dimension of the grid, corresponding to the vector dimension of the grid's coordinates.

source
Ferrite.getrefdimMethod
Ferrite.getrefdim(cell::AbstractCell)
-Ferrite.getrefdim(::Type{<:AbstractCell})

Get the reference dimension of the cell, i.e. the dimension of the cell's reference shape.

source

Topology

Ferrite.ExclusiveTopologyType
ExclusiveTopology(grid::AbstractGrid)

The experimental feature ExclusiveTopology saves topological (connectivity/neighborhood) data of the grid. Only the highest dimensional neighborhood is saved. I.e., if something is connected by a face and an edge, only the face neighborhood is saved. The lower dimensional neighborhood is recomputed when calling getneighborhood if needed.

Fields

  • vertex_to_cell::AbstractArray{AbstractVector{Int}, 1}: global vertex id to all cells containing the vertex
  • cell_neighbor::AbstractArray{AbstractVector{Int}, 1}: cellid to all connected cells
  • face_neighbor::AbstractArray{AbstractVector{FaceIndex}, 2}: face_neighbor[cellid, local_face_id] -> neighboring faces
  • edge_neighbor::AbstractArray{AbstractVector{EdgeIndex}, 2}: edge_neighbor[cellid, local_edge_id] -> neighboring edges
  • vertex_neighbor::AbstractArray{AbstractVector{VertexIndex}, 2}: vertex_neighbor[cellid, local_vertex_id] -> neighboring vertices
  • face_skeleton::Union{Vector{FaceIndex}, Nothing}: List of unique faces in the grid given as FaceIndex
  • edge_skeleton::Union{Vector{EdgeIndex}, Nothing}: List of unique edges in the grid given as EdgeIndex
  • vertex_skeleton::Union{Vector{VertexIndex}, Nothing}: List of unique vertices in the grid given as VertexIndex
Limitations

The implementation only works with conforming grids, i.e. grids without "hanging nodes". Non-conforming grids will give unexpected results. Grids with embedded cells (different reference dimension compared to the spatial dimension) are not supported, and will error on construction.

source
Ferrite.getneighborhoodFunction
getneighborhood(topology, grid::AbstractGrid, cellidx::CellIndex, include_self=false)
+getnodes(grid::AbstractGrid, setname::String)

Returns either all nodes::Collection{N} of a <:AbstractGrid or a subset based on an Int, Vector{Int} or String. The last option tries to call a nodeset of the <:AbstractGrid. Collection{N} refers to some indexable collection where each element corresponds to a Node.

source
Ferrite.getcellsetFunction
getcellset(grid::AbstractGrid, setname::String)

Returns all cells as cellid in the set with name setname.

source
Ferrite.getnodesetFunction
getnodeset(grid::AbstractGrid, setname::String)

Returns all nodes as nodeid in the set with name setname.

source
Ferrite.getfacetsetFunction
getfacetset(grid::AbstractGrid, setname::String)

Returns all faces as FacetIndex in the set with name setname.

source
Ferrite.getvertexsetFunction
getvertexset(grid::AbstractGrid, setname::String)

Returns all vertices as VertexIndex in the set with name setname.

source
Ferrite.transform_coordinates!Function
transform_coordinates!(grid::Abstractgrid, f::Function)

Transform the coordinates of all nodes of the grid based on some transformation function f(x).

source
Ferrite.getcoordinatesFunction
getcoordinates(grid::AbstractGrid, idx::Union{Int,CellIndex})
+getcoordinates(cache::CellCache)

Get a vector with the coordinates of the cell corresponding to idx or cache

source
Ferrite.getcoordinates!Function
getcoordinates!(x::Vector{<:Vec}, grid::AbstractGrid, idx::Union{Int,CellIndex})
+getcoordinates!(x::Vector{<:Vec}, grid::AbstractGrid, cell::AbstractCell)

Mutate x to the coordinates of the cell corresponding to idx or cell.

source
Ferrite.geometric_interpolationMethod
geometric_interpolation(::AbstractCell)::ScalarInterpolation
+geometric_interpolation(::Type{<:AbstractCell})::ScalarInterpolation

Each AbstractCell type has a unique geometric interpolation describing its geometry. This function returns that interpolation, which is always a scalar interpolation.

source
Ferrite.get_node_coordinateFunction
get_node_coordinate(::Node)

Get the value of the node coordinate.

source
get_node_coordinate(grid::AbstractGrid, n::Int)

Return the coordinate of the nth node in grid

source
Ferrite.getspatialdimMethod
Ferrite.getspatialdim(grid::AbstractGrid)

Get the spatial dimension of the grid, corresponding to the vector dimension of the grid's coordinates.

source
Ferrite.getrefdimMethod
Ferrite.getrefdim(cell::AbstractCell)
+Ferrite.getrefdim(::Type{<:AbstractCell})

Get the reference dimension of the cell, i.e. the dimension of the cell's reference shape.

source

Topology

Ferrite.ExclusiveTopologyType
ExclusiveTopology(grid::AbstractGrid)

The experimental feature ExclusiveTopology saves topological (connectivity/neighborhood) data of the grid. Only the highest dimensional neighborhood is saved. I.e., if something is connected by a face and an edge, only the face neighborhood is saved. The lower dimensional neighborhood is recomputed when calling getneighborhood if needed.

Fields

  • vertex_to_cell::AbstractArray{AbstractVector{Int}, 1}: global vertex id to all cells containing the vertex
  • cell_neighbor::AbstractArray{AbstractVector{Int}, 1}: cellid to all connected cells
  • face_neighbor::AbstractArray{AbstractVector{FaceIndex}, 2}: face_neighbor[cellid, local_face_id] -> neighboring faces
  • edge_neighbor::AbstractArray{AbstractVector{EdgeIndex}, 2}: edge_neighbor[cellid, local_edge_id] -> neighboring edges
  • vertex_neighbor::AbstractArray{AbstractVector{VertexIndex}, 2}: vertex_neighbor[cellid, local_vertex_id] -> neighboring vertices
  • face_skeleton::Union{Vector{FaceIndex}, Nothing}: List of unique faces in the grid given as FaceIndex
  • edge_skeleton::Union{Vector{EdgeIndex}, Nothing}: List of unique edges in the grid given as EdgeIndex
  • vertex_skeleton::Union{Vector{VertexIndex}, Nothing}: List of unique vertices in the grid given as VertexIndex
Limitations

The implementation only works with conforming grids, i.e. grids without "hanging nodes". Non-conforming grids will give unexpected results. Grids with embedded cells (different reference dimension compared to the spatial dimension) are not supported, and will error on construction.

source
Ferrite.getneighborhoodFunction
getneighborhood(topology, grid::AbstractGrid, cellidx::CellIndex, include_self=false)
 getneighborhood(topology, grid::AbstractGrid, faceidx::FaceIndex, include_self=false)
 getneighborhood(topology, grid::AbstractGrid, vertexidx::VertexIndex, include_self=false)
-getneighborhood(topology, grid::AbstractGrid, edgeidx::EdgeIndex, include_self=false)

Returns all connected entities of the same type as defined by the respective topology. If include_self is true, the given entity is included in the returned list as well.

source
Ferrite.facetskeletonFunction
facetskeleton(top::ExclusiveTopology, grid::AbstractGrid)

Materializes the skeleton from the neighborhood information by returning an iterable over the unique facets in the grid, described by FacetIndex.

source
Ferrite.vertex_star_stencilsFunction
vertex_star_stencils(top::ExclusiveTopology, grid::Grid) -> AbstractVector{AbstractVector{VertexIndex}}

Computes the stencils induced by the edge connectivity of the vertices.

source
Ferrite.getstencilFunction
getstencil(top::ArrayOfVectorViews{VertexIndex, 1}, grid::AbstractGrid, vertex_idx::VertexIndex) -> AbstractVector{VertexIndex}

Get an iterateable over the stencil members for a given local entity.

source

Grid Sets Utility

Ferrite.addcellset!Function
addcellset!(grid::AbstractGrid, name::String, cellid::AbstractVecOrSet{Int})
+getneighborhood(topology, grid::AbstractGrid, edgeidx::EdgeIndex, include_self=false)

Returns all connected entities of the same type as defined by the respective topology. If include_self is true, the given entity is included in the returned list as well.

source
Ferrite.facetskeletonFunction
facetskeleton(top::ExclusiveTopology, grid::AbstractGrid)

Materializes the skeleton from the neighborhood information by returning an iterable over the unique facets in the grid, described by FacetIndex.

source
Ferrite.vertex_star_stencilsFunction
vertex_star_stencils(top::ExclusiveTopology, grid::Grid) -> AbstractVector{AbstractVector{VertexIndex}}

Computes the stencils induced by the edge connectivity of the vertices.

source
Ferrite.getstencilFunction
getstencil(top::ArrayOfVectorViews{VertexIndex, 1}, grid::AbstractGrid, vertex_idx::VertexIndex) -> AbstractVector{VertexIndex}

Get an iterateable over the stencil members for a given local entity.

source

Grid Sets Utility

Ferrite.addcellset!Function
addcellset!(grid::AbstractGrid, name::String, cellid::AbstractVecOrSet{Int})
 addcellset!(grid::AbstractGrid, name::String, f::function; all::Bool=true)

Adds a cellset to the grid with key name. Cellsets are typically used to define subdomains of the problem, e.g. two materials in the computational domain. The DofHandler can construct different fields which live not on the whole domain, but rather on a cellset. all=true implies that f(x) must return true for all nodal coordinates x in the cell if the cell should be added to the set, otherwise it suffices that f(x) returns true for one node.

addcellset!(grid, "left", Set((1,3))) #add cells with id 1 and 3 to cellset left
-addcellset!(grid, "right", x -> norm(x[1]) < 2.0 ) #add cell to cellset right, if x[1] of each cell's node is smaller than 2.0
source
Ferrite.addfacetset!Function
addfacetset!(grid::AbstractGrid, name::String, faceid::AbstractVecOrSet{FacetIndex})
+addcellset!(grid, "right", x -> norm(x[1]) < 2.0 ) #add cell to cellset right, if x[1] of each cell's node is smaller than 2.0
source
Ferrite.addfacetset!Function
addfacetset!(grid::AbstractGrid, name::String, faceid::AbstractVecOrSet{FacetIndex})
 addfacetset!(grid::AbstractGrid, name::String, f::Function; all::Bool=true)

Adds a facetset to the grid with key name. A facetset maps a String key to a OrderedSet of tuples corresponding to (global_cell_id, local_facet_id). Facetsets can be used to initialize Dirichlet boundary conditions for the ConstraintHandler. all=true implies that f(x) must return true for all nodal coordinates x on the facet if the facet should be added to the set, otherwise it suffices that f(x) returns true for one node.

addfacetset!(grid, "right", Set((FacetIndex(2,2), FacetIndex(4,2)))) #see grid manual example for reference
-addfacetset!(grid, "clamped", x -> norm(x[1]) ≈ 0.0) #see incompressible elasticity example for reference
source
Ferrite.addboundaryfacetset!Function

addboundaryfacetset!(grid::AbstractGrid, topology::ExclusiveTopology, name::String, f::Function; all::Bool=true)

Adds a boundary facetset to the grid with key name. A facetset maps a String key to a OrderedSet of tuples corresponding to (global_cell_id, local_facet_id). Facetsets are used to initialize Dirichlet structs, that are needed to specify the boundary for the ConstraintHandler. all=true implies that f(x) must return true for all nodal coordinates x on the facet if the facet should be added to the set, otherwise it suffices that f(x) returns true for one node.

source
Ferrite.addvertexset!Function
addvertexset!(grid::AbstractGrid, name::String, faceid::AbstractVecOrSet{FaceIndex})
+addfacetset!(grid, "clamped", x -> norm(x[1]) ≈ 0.0) #see incompressible elasticity example for reference
source
Ferrite.addboundaryfacetset!Function

addboundaryfacetset!(grid::AbstractGrid, topology::ExclusiveTopology, name::String, f::Function; all::Bool=true)

Adds a boundary facetset to the grid with key name. A facetset maps a String key to a OrderedSet of tuples corresponding to (global_cell_id, local_facet_id). Facetsets are used to initialize Dirichlet structs, that are needed to specify the boundary for the ConstraintHandler. all=true implies that f(x) must return true for all nodal coordinates x on the facet if the facet should be added to the set, otherwise it suffices that f(x) returns true for one node.

source
Ferrite.addvertexset!Function
addvertexset!(grid::AbstractGrid, name::String, faceid::AbstractVecOrSet{FaceIndex})
 addvertexset!(grid::AbstractGrid, name::String, f::Function)

Adds a vertexset to the grid with key name. A vertexset maps a String key to a OrderedSet of tuples corresponding to (global_cell_id, local_vertex_id). Vertexsets can be used to initialize Dirichlet boundary conditions for the ConstraintHandler.

addvertexset!(grid, "right", Set((VertexIndex(2,2), VertexIndex(4,2))))
-addvertexset!(grid, "clamped", x -> norm(x[1]) ≈ 0.0)
source
Ferrite.addboundaryvertexset!Function

addboundaryvertexset!(grid::AbstractGrid, topology::ExclusiveTopology, name::String, f::Function; all::Bool=true)

Adds a boundary vertexset to the grid with key name. A vertexset maps a String key to an OrderedSet of tuples corresponding to (global_cell_id, local_vertex_id). all=true implies that f(x) must return true for all nodal coordinates x on the face if the face should be added to the set, otherwise it suffices that f(x) returns true for one node.

source
Ferrite.addnodeset!Function
addnodeset!(grid::AbstractGrid, name::String, nodeid::AbstractVecOrSet{Int})
-addnodeset!(grid::AbstractGrid, name::String, f::Function)

Adds a nodeset::OrderedSet{Int} to the grid's nodesets with key name. Has the same interface as addcellset. However, instead of mapping a cell id to the String key, a set of node ids is returned.

source

Multithreaded Assembly

Ferrite.create_coloringFunction
create_coloring(g::Grid, cellset=1:getncells(g); alg::ColoringAlgorithm)

Create a coloring of the cells in grid g such that no neighboring cells have the same color. If only a subset of cells should be colored, the cells to color can be specified by cellset.

Returns a vector of vectors with cell indexes, e.g.:

ret = [
+addvertexset!(grid, "clamped", x -> norm(x[1]) ≈ 0.0)
source
Ferrite.addboundaryvertexset!Function

addboundaryvertexset!(grid::AbstractGrid, topology::ExclusiveTopology, name::String, f::Function; all::Bool=true)

Adds a boundary vertexset to the grid with key name. A vertexset maps a String key to an OrderedSet of tuples corresponding to (global_cell_id, local_vertex_id). all=true implies that f(x) must return true for all nodal coordinates x on the face if the face should be added to the set, otherwise it suffices that f(x) returns true for one node.

source
Ferrite.addnodeset!Function
addnodeset!(grid::AbstractGrid, name::String, nodeid::AbstractVecOrSet{Int})
+addnodeset!(grid::AbstractGrid, name::String, f::Function)

Adds a nodeset::OrderedSet{Int} to the grid's nodesets with key name. Has the same interface as addcellset. However, instead of mapping a cell id to the String key, a set of node ids is returned.

source

Multithreaded Assembly

Ferrite.create_coloringFunction
create_coloring(g::Grid, cellset=1:getncells(g); alg::ColoringAlgorithm)

Create a coloring of the cells in grid g such that no neighboring cells have the same color. If only a subset of cells should be colored, the cells to color can be specified by cellset.

Returns a vector of vectors with cell indexes, e.g.:

ret = [
    [1, 3, 5, 10, ...], # cells for color 1
    [2, 4, 6, 12, ...], # cells for color 2
 ]

Two different algorithms are available, specified with the alg keyword argument:

  • alg = ColoringAlgorithm.WorkStream (default): Three step algorithm from Turcksin et al. [11], albeit with a greedy coloring in the second step. Generally results in more colors than ColoringAlgorithm.Greedy, however the cells are more equally distributed among the colors.
  • alg = ColoringAlgorithm.Greedy: greedy algorithm that works well for structured quadrilateral grids such as e.g. quadrilateral grids from generate_grid.

The resulting colors can be visualized using Ferrite.write_cell_colors.

Cell to color mapping

In a previous version of Ferrite this function returned a dictionary mapping cell ID to color numbers as the first argument. If you need this mapping you can create it using the following construct:

colors = create_coloring(...)
 cell_colormap = Dict{Int,Int}(
     cellid => color for (color, cellids) in enumerate(final_colors) for cellid in cellids
-)

References

  • [11] Turcksin et al. ACM Trans. Math. Softw. 43 (2016).
source
+)

References

source diff --git a/dev/reference/index.html b/dev/reference/index.html index 1f4924aef8..44307196e1 100644 --- a/dev/reference/index.html +++ b/dev/reference/index.html @@ -1,2 +1,2 @@ -Reference overview · Ferrite.jl
+Reference overview · Ferrite.jl
diff --git a/dev/reference/interpolations/index.html b/dev/reference/interpolations/index.html index b0be99527a..1f7a4bac44 100644 --- a/dev/reference/interpolations/index.html +++ b/dev/reference/interpolations/index.html @@ -3,4 +3,4 @@ Lagrange{RefTriangle, 2}() julia> getnbasefunctions(ip) -6source
Ferrite.getnbasefunctionsFunction
Ferrite.getnbasefunctions(ip::Interpolation)

Return the number of base functions for the interpolation ip.

source
Ferrite.getrefdimMethod
Ferrite.getrefdim(::Interpolation)

Return the dimension of the reference element for a given interpolation.

source
Ferrite.getrefshapeFunction
Ferrite.getrefshape(::Interpolation)::AbstractRefShape

Return the reference element shape of the interpolation.

source
Ferrite.getorderFunction
Ferrite.getorder(::Interpolation)

Return order of the interpolation.

source

Implemented interpolations:

Ferrite.LagrangeType
Lagrange{refshape, order} <: ScalarInterpolation

Standard continuous Lagrange polynomials with equidistant node placement.

source
Ferrite.SerendipityType
Serendipity{refshape, order} <: ScalarInterpolation

Serendipity element on hypercubes. Currently only second order variants are implemented.

source
Ferrite.DiscontinuousLagrangeType

Piecewise discontinuous Lagrange basis via Gauss-Lobatto points.

source
Ferrite.BubbleEnrichedLagrangeType

Lagrange element with bubble stabilization.

source
Ferrite.CrouzeixRaviartType
CrouzeixRaviart{refshape, order} <: ScalarInterpolation

Classical non-conforming Crouzeix–Raviart element.

For details we refer to the original paper [9].

source
Ferrite.RannacherTurekType
RannacherTurek{refshape, order} <: ScalarInterpolation

Classical non-conforming Rannacher-Turek element.

This element is basically the idea from Crouzeix and Raviart applied to hypercubes. For details see the original paper [10].

source
+6source
Ferrite.getnbasefunctionsFunction
Ferrite.getnbasefunctions(ip::Interpolation)

Return the number of base functions for the interpolation ip.

source
Ferrite.getrefdimMethod
Ferrite.getrefdim(::Interpolation)

Return the dimension of the reference element for a given interpolation.

source
Ferrite.getrefshapeFunction
Ferrite.getrefshape(::Interpolation)::AbstractRefShape

Return the reference element shape of the interpolation.

source
Ferrite.getorderFunction
Ferrite.getorder(::Interpolation)

Return order of the interpolation.

source

Implemented interpolations:

Ferrite.LagrangeType
Lagrange{refshape, order} <: ScalarInterpolation

Standard continuous Lagrange polynomials with equidistant node placement.

source
Ferrite.SerendipityType
Serendipity{refshape, order} <: ScalarInterpolation

Serendipity element on hypercubes. Currently only second order variants are implemented.

source
Ferrite.DiscontinuousLagrangeType

Piecewise discontinuous Lagrange basis via Gauss-Lobatto points.

source
Ferrite.BubbleEnrichedLagrangeType

Lagrange element with bubble stabilization.

source
Ferrite.CrouzeixRaviartType
CrouzeixRaviart{refshape, order} <: ScalarInterpolation

Classical non-conforming Crouzeix–Raviart element.

For details we refer to the original paper [9].

source
Ferrite.RannacherTurekType
RannacherTurek{refshape, order} <: ScalarInterpolation

Classical non-conforming Rannacher-Turek element.

This element is basically the idea from Crouzeix and Raviart applied to hypercubes. For details see the original paper [10].

source
diff --git a/dev/reference/quadrature/index.html b/dev/reference/quadrature/index.html index f3300e4e15..1ef929f035 100644 --- a/dev/reference/quadrature/index.html +++ b/dev/reference/quadrature/index.html @@ -5,20 +5,20 @@ julia> getpoints(qr) 1-element Vector{Vec{2, Float64}}: - [0.33333333333333, 0.33333333333333]source
Ferrite.FacetQuadratureRuleType
FacetQuadratureRule{shape}([::Type{T},] [quad_rule_type::Symbol,] order::Int)
+ [0.33333333333333, 0.33333333333333]
source
Ferrite.FacetQuadratureRuleType
FacetQuadratureRule{shape}([::Type{T},] [quad_rule_type::Symbol,] order::Int)
 FacetQuadratureRule{shape}(face_rules::NTuple{<:Any, <:QuadratureRule{shape}})
-FacetQuadratureRule{shape}(face_rules::AbstractVector{<:QuadratureRule{shape}})

Create a FacetQuadratureRule used for integration of the faces of the refshape shape (of type AbstractRefShape). order is the order of the quadrature rule. If no symbol is provided, the default quad_rule_type for each facet's reference shape is used (see QuadratureRule). For non-default quad_rule_types on cells with mixed facet types (e.g. RefPrism and RefPyramid), the face_rules must be provided explicitly.

FacetQuadratureRule is used as one of the components to create FacetValues.

source
Ferrite.getnquadpointsMethod
getnquadpoints(qr::QuadratureRule)

Return the number of quadrature points in qr.

source
Ferrite.getnquadpointsMethod
getnquadpoints(qr::FacetQuadratureRule, face::Int)

Return the number of quadrature points in qr for local face index face.

source
Ferrite.getpointsFunction
getpoints(qr::QuadratureRule)
+FacetQuadratureRule{shape}(face_rules::AbstractVector{<:QuadratureRule{shape}})

Create a FacetQuadratureRule used for integration of the faces of the refshape shape (of type AbstractRefShape). order is the order of the quadrature rule. If no symbol is provided, the default quad_rule_type for each facet's reference shape is used (see QuadratureRule). For non-default quad_rule_types on cells with mixed facet types (e.g. RefPrism and RefPyramid), the face_rules must be provided explicitly.

FacetQuadratureRule is used as one of the components to create FacetValues.

source
Ferrite.getnquadpointsMethod
getnquadpoints(qr::QuadratureRule)

Return the number of quadrature points in qr.

source
Ferrite.getnquadpointsMethod
getnquadpoints(qr::FacetQuadratureRule, face::Int)

Return the number of quadrature points in qr for local face index face.

source
Ferrite.getpointsFunction
getpoints(qr::QuadratureRule)
 getpoints(qr::FacetQuadratureRule, face::Int)

Return the points of the quadrature rule.

Examples

julia> qr = QuadratureRule{RefTriangle}(:legendre, 2);
 
 julia> getpoints(qr)
 3-element Vector{Vec{2, Float64}}:
  [0.16666666666667, 0.16666666666667]
  [0.16666666666667, 0.66666666666667]
- [0.66666666666667, 0.16666666666667]
source
Ferrite.getweightsFunction
getweights(qr::QuadratureRule)
+ [0.66666666666667, 0.16666666666667]
source
Ferrite.getweightsFunction
getweights(qr::QuadratureRule)
 getweights(qr::FacetQuadratureRule, face::Int)

Return the weights of the quadrature rule.

Examples

julia> qr = QuadratureRule{RefTriangle}(:legendre, 2);
 
 julia> getweights(qr)
 3-element Array{Float64,1}:
  0.166667
  0.166667
- 0.166667
source
+ 0.166667source diff --git a/dev/reference/sparsity_pattern/index.html b/dev/reference/sparsity_pattern/index.html index 35a66aea15..dd66c177f8 100644 --- a/dev/reference/sparsity_pattern/index.html +++ b/dev/reference/sparsity_pattern/index.html @@ -1,5 +1,5 @@ -Sparsity pattern and sparse matrices · Ferrite.jl

Sparsity pattern and sparse matrices

This is the reference documentation for sparsity patterns and sparse matrix instantiation. See the topic section on Sparsity pattern and sparse matrices.

Sparsity patterns

AbstractSparsityPattern

The following applies to all subtypes of AbstractSparsityPattern:

Ferrite.init_sparsity_patternFunction
init_sparsity_pattern(dh::DofHandler; nnz_per_row::Int)

Initialize an empty SparsityPattern with ndofs(dh) rows and ndofs(dh) columns.

Keyword arguments

  • nnz_per_row: memory optimization hint for the number of non-zero entries per row that will be added to the pattern.
source
Ferrite.add_sparsity_entries!Function
add_sparsity_entries!(
+Sparsity pattern and sparse matrices · Ferrite.jl

Sparsity pattern and sparse matrices

This is the reference documentation for sparsity patterns and sparse matrix instantiation. See the topic section on Sparsity pattern and sparse matrices.

Sparsity patterns

AbstractSparsityPattern

The following applies to all subtypes of AbstractSparsityPattern:

Ferrite.init_sparsity_patternFunction
init_sparsity_pattern(dh::DofHandler; nnz_per_row::Int)

Initialize an empty SparsityPattern with ndofs(dh) rows and ndofs(dh) columns.

Keyword arguments

  • nnz_per_row: memory optimization hint for the number of non-zero entries per row that will be added to the pattern.
source
Ferrite.add_sparsity_entries!Function
add_sparsity_entries!(
     sp::AbstractSparsityPattern,
     dh::DofHandler,
     ch::Union{ConstraintHandler, Nothing} = nothing;
@@ -7,37 +7,37 @@
     keep_constrained::Bool = true,
     coupling = nothing,
     interface_coupling = nothing,
-)

Convenience method for doing the common task of calling add_cell_entries!, add_interface_entries!, and add_constraint_entries!, depending on what arguments are passed:

  • add_cell_entries! is always called
  • add_interface_entries! is called if topology is provided (i.e. not nothing)
  • add_constraint_entries! is called if the ConstraintHandler is provided

For more details about arguments and keyword arguments, see the respective functions.

source
Ferrite.add_cell_entries!Function
add_cell_entries!(
+)

Convenience method for doing the common task of calling add_cell_entries!, add_interface_entries!, and add_constraint_entries!, depending on what arguments are passed:

  • add_cell_entries! is always called
  • add_interface_entries! is called if topology is provided (i.e. not nothing)
  • add_constraint_entries! is called if the ConstraintHandler is provided

For more details about arguments and keyword arguments, see the respective functions.

source
Ferrite.add_cell_entries!Function
add_cell_entries!(
     sp::AbstractSparsityPattern,
     dh::DofHandler,
     ch::Union{ConstraintHandler, Nothing} = nothing;
     keep_constrained::Bool = true,
     coupling::Union{AbstractMatrix{Bool}, Nothing}, = nothing
-)

Add entries to the sparsity pattern sp corresponding to DoF couplings within the cells as described by the DofHandler dh.

Keyword arguments

  • keep_constrained: whether or not entries for constrained DoFs should be kept (keep_constrained = true) or eliminated (keep_constrained = false) from the sparsity pattern. keep_constrained = false requires passing the ConstraintHandler ch.
  • coupling: the coupling between fields/components within each cell. By default (coupling = nothing) it is assumed that all DoFs in each cell couple with each other.
source
Ferrite.add_interface_entries!Function
add_interface_entries!(
+)

Add entries to the sparsity pattern sp corresponding to DoF couplings within the cells as described by the DofHandler dh.

Keyword arguments

  • keep_constrained: whether or not entries for constrained DoFs should be kept (keep_constrained = true) or eliminated (keep_constrained = false) from the sparsity pattern. keep_constrained = false requires passing the ConstraintHandler ch.
  • coupling: the coupling between fields/components within each cell. By default (coupling = nothing) it is assumed that all DoFs in each cell couple with each other.
source
Ferrite.add_interface_entries!Function
add_interface_entries!(
     sp::SparsityPattern, dh::DofHandler, ch::Union{ConstraintHandler, Nothing};
     topology::ExclusiveTopology, keep_constrained::Bool = true,
     interface_coupling::AbstractMatrix{Bool},
-)

Add entries to the sparsity pattern sp corresponding to DoF couplings on the interface between cells as described by the DofHandler dh.

Keyword arguments

  • topology: the topology corresponding to the grid.
  • keep_constrained: whether or not entries for constrained DoFs should be kept (keep_constrained = true) or eliminated (keep_constrained = false) from the sparsity pattern. keep_constrained = false requires passing the ConstraintHandler ch.
  • interface_coupling: the coupling between fields/components across the interface.
source
Ferrite.add_constraint_entries!Function
add_constraint_entries!(
+)

Add entries to the sparsity pattern sp corresponding to DoF couplings on the interface between cells as described by the DofHandler dh.

Keyword arguments

  • topology: the topology corresponding to the grid.
  • keep_constrained: whether or not entries for constrained DoFs should be kept (keep_constrained = true) or eliminated (keep_constrained = false) from the sparsity pattern. keep_constrained = false requires passing the ConstraintHandler ch.
  • interface_coupling: the coupling between fields/components across the interface.
source
Ferrite.add_constraint_entries!Function
add_constraint_entries!(
     sp::AbstractSparsityPattern, ch::ConstraintHandler;
     keep_constrained::Bool = true,
-)

Add all entries resulting from constraints in the ConstraintHandler ch to the sparsity pattern. Note that, since this operation depends on existing entries in the pattern, this function must be called as the last step when creating the sparsity pattern.

Keyword arguments

  • keep_constrained: whether or not entries for constrained DoFs should be kept (keep_constrained = true) or eliminated (keep_constrained = false) from the sparsity pattern.
source
Ferrite.add_entry!Function
add_entry!(sp::AbstractSparsityPattern, row::Int, col::Int)

Add an entry to the sparsity pattern sp at row row and column col.

source

SparsityPattern

Ferrite.SparsityPatternMethod
SparsityPattern(nrows::Int, ncols::Int; nnz_per_row::Int = 8)

Create an empty SparsityPattern with nrows rows and ncols columns. nnz_per_row is used as a memory hint for the number of non zero entries per row.

SparsityPattern is the default sparsity pattern type for the standard DofHandler and is therefore commonly constructed using init_sparsity_pattern instead of with this constructor.

Examples

# Create a sparsity pattern for an 100 x 100 matrix, hinting at 10 entries per row
-sparsity_pattern = SparsityPattern(100, 100; nnz_per_row = 10)

Methods

The following methods apply to SparsityPattern (see their respective documentation for more details):

source
Ferrite.SparsityPatternType
struct SparsityPattern <: AbstractSparsityPattern

Data structure representing non-zero entries in the eventual sparse matrix.

See the constructor SparsityPattern(::Int, ::Int) for the user-facing documentation.

Struct fields

  • nrows::Int: number of rows
  • ncols::Int: number of column
  • rows::Vector{Vector{Int}}: vector of length nrows, where rows[i] is a sorted vector of column indices for non zero entries in row i.
Internal struct

The specific implementation of this struct, such as struct fields, type layout and type parameters, are internal and should not be relied upon.

source

BlockSparsityPattern

Package extension

This functionality is only enabled when the package BlockArrays.jl is installed (pkg> add BlockArrays) and loaded (using BlockArrays) in the session.

Ferrite.BlockSparsityPatternMethod
BlockSparsityPattern(block_sizes::Vector{Int})

Create an empty BlockSparsityPattern with row and column block sizes given by block_sizes.

Examples

# Create a block sparsity pattern with block size 10 x 5
-sparsity_pattern = BlockSparsityPattern([10, 5])

Methods

The following methods apply to BlockSparsityPattern (see their respective documentation for more details):

Package extension

This functionality is only enabled when the package BlockArrays.jl is installed (pkg> add BlockArrays) and loaded (using BlockArrays) in the session.

source
Ferrite.BlockSparsityPatternType
struct BlockSparsityPattern <: AbstractSparsityPattern

Data structure representing non-zero entries for an eventual blocked sparse matrix.

See the constructor BlockSparsityPattern(::Vector{Int}) for the user-facing documentation.

Struct fields

  • nrows::Int: number of rows
  • ncols::Int: number of column
  • block_sizes::Vector{Int}: row and column block sizes
  • blocks::Matrix{SparsityPattern}: matrix of size length(block_sizes) × length(block_sizes) where blocks[i, j] is a SparsityPattern corresponding to block (i, j).
Internal struct

The specific implementation of this struct, such as struct fields, type layout and type parameters, are internal and should not be relied upon.

source
Ferrite.allocate_matrixMethod
allocate_matrix(::Type{SparseMatrixCSC{Tv, Ti}}, sp::SparsityPattern)

Allocate a sparse matrix of type SparseMatrixCSC{Tv, Ti} from the sparsity pattern sp.

source
allocate_matrix(::Type{Symmetric{Tv, SparseMatrixCSC{Tv, Ti}}}, sp::SparsityPattern)

Instantiate a sparse matrix of type Symmetric{Tv, SparseMatrixCSC{Tv, Ti}}, i.e. a LinearAlgebra.Symmetric-wrapped SparseMatrixCSC, from the sparsity pattern sp. The resulting matrix will only store entries above, and including, the diagonal.

source
allocate_matrix(MatrixType, dh::DofHandler, args...; kwargs...)

Allocate a matrix of type MatrixType from the DofHandler dh.

This is a convenience method and is equivalent to:

julia sp = init_sparsity_pattern(dh) add_sparsity_entries!(sp, dh, args...; kwargs...) allocate_matrix(MatrixType, sp)`

Refer to allocate_matrix for supported matrix types, and to init_sparsity_pattern for details about supported arguments args and keyword arguments kwargs.

Note

If more than one sparse matrix is needed (e.g. a stiffness and a mass matrix) it is more efficient to explicitly create the sparsity pattern instead of using this method, i.e. use

sp = init_sparsity_pattern(dh)
+)

Add all entries resulting from constraints in the ConstraintHandler ch to the sparsity pattern. Note that, since this operation depends on existing entries in the pattern, this function must be called as the last step when creating the sparsity pattern.

Keyword arguments

  • keep_constrained: whether or not entries for constrained DoFs should be kept (keep_constrained = true) or eliminated (keep_constrained = false) from the sparsity pattern.
source
Ferrite.add_entry!Function
add_entry!(sp::AbstractSparsityPattern, row::Int, col::Int)

Add an entry to the sparsity pattern sp at row row and column col.

source

SparsityPattern

Ferrite.SparsityPatternMethod
SparsityPattern(nrows::Int, ncols::Int; nnz_per_row::Int = 8)

Create an empty SparsityPattern with nrows rows and ncols columns. nnz_per_row is used as a memory hint for the number of non zero entries per row.

SparsityPattern is the default sparsity pattern type for the standard DofHandler and is therefore commonly constructed using init_sparsity_pattern instead of with this constructor.

Examples

# Create a sparsity pattern for an 100 x 100 matrix, hinting at 10 entries per row
+sparsity_pattern = SparsityPattern(100, 100; nnz_per_row = 10)

Methods

The following methods apply to SparsityPattern (see their respective documentation for more details):

source
Ferrite.SparsityPatternType
struct SparsityPattern <: AbstractSparsityPattern

Data structure representing non-zero entries in the eventual sparse matrix.

See the constructor SparsityPattern(::Int, ::Int) for the user-facing documentation.

Struct fields

  • nrows::Int: number of rows
  • ncols::Int: number of column
  • rows::Vector{Vector{Int}}: vector of length nrows, where rows[i] is a sorted vector of column indices for non zero entries in row i.
Internal struct

The specific implementation of this struct, such as struct fields, type layout and type parameters, are internal and should not be relied upon.

source

BlockSparsityPattern

Package extension

This functionality is only enabled when the package BlockArrays.jl is installed (pkg> add BlockArrays) and loaded (using BlockArrays) in the session.

Ferrite.BlockSparsityPatternMethod
BlockSparsityPattern(block_sizes::Vector{Int})

Create an empty BlockSparsityPattern with row and column block sizes given by block_sizes.

Examples

# Create a block sparsity pattern with block size 10 x 5
+sparsity_pattern = BlockSparsityPattern([10, 5])

Methods

The following methods apply to BlockSparsityPattern (see their respective documentation for more details):

Package extension

This functionality is only enabled when the package BlockArrays.jl is installed (pkg> add BlockArrays) and loaded (using BlockArrays) in the session.

source
Ferrite.BlockSparsityPatternType
struct BlockSparsityPattern <: AbstractSparsityPattern

Data structure representing non-zero entries for an eventual blocked sparse matrix.

See the constructor BlockSparsityPattern(::Vector{Int}) for the user-facing documentation.

Struct fields

  • nrows::Int: number of rows
  • ncols::Int: number of column
  • block_sizes::Vector{Int}: row and column block sizes
  • blocks::Matrix{SparsityPattern}: matrix of size length(block_sizes) × length(block_sizes) where blocks[i, j] is a SparsityPattern corresponding to block (i, j).
Internal struct

The specific implementation of this struct, such as struct fields, type layout and type parameters, are internal and should not be relied upon.

source
Ferrite.allocate_matrixMethod
allocate_matrix(::Type{SparseMatrixCSC{Tv, Ti}}, sp::SparsityPattern)

Allocate a sparse matrix of type SparseMatrixCSC{Tv, Ti} from the sparsity pattern sp.

source
allocate_matrix(::Type{Symmetric{Tv, SparseMatrixCSC{Tv, Ti}}}, sp::SparsityPattern)

Instantiate a sparse matrix of type Symmetric{Tv, SparseMatrixCSC{Tv, Ti}}, i.e. a LinearAlgebra.Symmetric-wrapped SparseMatrixCSC, from the sparsity pattern sp. The resulting matrix will only store entries above, and including, the diagonal.

source
allocate_matrix(MatrixType, dh::DofHandler, args...; kwargs...)

Allocate a matrix of type MatrixType from the DofHandler dh.

This is a convenience method and is equivalent to:

julia sp = init_sparsity_pattern(dh) add_sparsity_entries!(sp, dh, args...; kwargs...) allocate_matrix(MatrixType, sp)`

Refer to allocate_matrix for supported matrix types, and to init_sparsity_pattern for details about supported arguments args and keyword arguments kwargs.

Note

If more than one sparse matrix is needed (e.g. a stiffness and a mass matrix) it is more efficient to explicitly create the sparsity pattern instead of using this method, i.e. use

sp = init_sparsity_pattern(dh)
 add_sparsity_entries!(sp, dh)
 K = allocate_matrix(sp)
 M = allocate_matrix(sp)

instead of

K = allocate_matrix(dh)
-M = allocate_matrix(dh)

Note that for some matrix types it is possible to copy the instantiated matrix (M = copy(K)) instead.

source
allocate_matrix(::Type{BlockMatrix}, sp::BlockSparsityPattern)
+M = allocate_matrix(dh)

Note that for some matrix types it is possible to copy the instantiated matrix (M = copy(K)) instead.

source
allocate_matrix(::Type{BlockMatrix}, sp::BlockSparsityPattern)
 allocate_matrix(::Type{BlockMatrix{T, Matrix{S}}}, sp::BlockSparsityPattern)

Instantiate a blocked sparse matrix from the blocked sparsity pattern sp.

The type of the returned matrix is a BlockMatrix with blocks of type S (defaults to SparseMatrixCSC{T, Int}).

Examples

# Create a sparse matrix with default block type
 allocate_matrix(BlockMatrix, sparsity_pattern)
 
 # Create a sparse matrix with blocks of type SparseMatrixCSC{Float32, Int}
-allocate_matrix(BlockMatrix{Float32, Matrix{SparseMatrixCSC{Float32, Int}}}, sparsity_pattern)
Package extension

This functionality is only enabled when the package BlockArrays.jl is installed (pkg> add BlockArrays) and loaded (using BlockArrays) in the session.

source
Ferrite.allocate_matrixMethod
allocate_matrix(::Type{BlockMatrix}, sp::BlockSparsityPattern)
+allocate_matrix(BlockMatrix{Float32, Matrix{SparseMatrixCSC{Float32, Int}}}, sparsity_pattern)
Package extension

This functionality is only enabled when the package BlockArrays.jl is installed (pkg> add BlockArrays) and loaded (using BlockArrays) in the session.

source
Ferrite.allocate_matrixMethod
allocate_matrix(::Type{BlockMatrix}, sp::BlockSparsityPattern)
 allocate_matrix(::Type{BlockMatrix{T, Matrix{S}}}, sp::BlockSparsityPattern)

Instantiate a blocked sparse matrix from the blocked sparsity pattern sp.

The type of the returned matrix is a BlockMatrix with blocks of type S (defaults to SparseMatrixCSC{T, Int}).

Examples

# Create a sparse matrix with default block type
 allocate_matrix(BlockMatrix, sparsity_pattern)
 
 # Create a sparse matrix with blocks of type SparseMatrixCSC{Float32, Int}
-allocate_matrix(BlockMatrix{Float32, Matrix{SparseMatrixCSC{Float32, Int}}}, sparsity_pattern)
Package extension

This functionality is only enabled when the package BlockArrays.jl is installed (pkg> add BlockArrays) and loaded (using BlockArrays) in the session.

source

Sparse matrices

Creating matrix from SparsityPattern

Ferrite.allocate_matrixMethod
allocate_matrix(::Type{SparseMatrixCSC{Tv, Ti}}, sp::SparsityPattern)

Allocate a sparse matrix of type SparseMatrixCSC{Tv, Ti} from the sparsity pattern sp.

source
Ferrite.allocate_matrixMethod
allocate_matrix(::Type{Symmetric{Tv, SparseMatrixCSC{Tv, Ti}}}, sp::SparsityPattern)

Instantiate a sparse matrix of type Symmetric{Tv, SparseMatrixCSC{Tv, Ti}}, i.e. a LinearAlgebra.Symmetric-wrapped SparseMatrixCSC, from the sparsity pattern sp. The resulting matrix will only store entries above, and including, the diagonal.

source

Creating matrix from DofHandler

Ferrite.allocate_matrixMethod
allocate_matrix(MatrixType, dh::DofHandler, args...; kwargs...)

Allocate a matrix of type MatrixType from the DofHandler dh.

This is a convenience method and is equivalent to:

julia sp = init_sparsity_pattern(dh) add_sparsity_entries!(sp, dh, args...; kwargs...) allocate_matrix(MatrixType, sp)`

Refer to allocate_matrix for supported matrix types, and to init_sparsity_pattern for details about supported arguments args and keyword arguments kwargs.

Note

If more than one sparse matrix is needed (e.g. a stiffness and a mass matrix) it is more efficient to explicitly create the sparsity pattern instead of using this method, i.e. use

sp = init_sparsity_pattern(dh)
+allocate_matrix(BlockMatrix{Float32, Matrix{SparseMatrixCSC{Float32, Int}}}, sparsity_pattern)
Package extension

This functionality is only enabled when the package BlockArrays.jl is installed (pkg> add BlockArrays) and loaded (using BlockArrays) in the session.

source

Sparse matrices

Creating matrix from SparsityPattern

Ferrite.allocate_matrixMethod
allocate_matrix(::Type{SparseMatrixCSC{Tv, Ti}}, sp::SparsityPattern)

Allocate a sparse matrix of type SparseMatrixCSC{Tv, Ti} from the sparsity pattern sp.

source
Ferrite.allocate_matrixMethod
allocate_matrix(::Type{Symmetric{Tv, SparseMatrixCSC{Tv, Ti}}}, sp::SparsityPattern)

Instantiate a sparse matrix of type Symmetric{Tv, SparseMatrixCSC{Tv, Ti}}, i.e. a LinearAlgebra.Symmetric-wrapped SparseMatrixCSC, from the sparsity pattern sp. The resulting matrix will only store entries above, and including, the diagonal.

source

Creating matrix from DofHandler

Ferrite.allocate_matrixMethod
allocate_matrix(MatrixType, dh::DofHandler, args...; kwargs...)

Allocate a matrix of type MatrixType from the DofHandler dh.

This is a convenience method and is equivalent to:

julia sp = init_sparsity_pattern(dh) add_sparsity_entries!(sp, dh, args...; kwargs...) allocate_matrix(MatrixType, sp)`

Refer to allocate_matrix for supported matrix types, and to init_sparsity_pattern for details about supported arguments args and keyword arguments kwargs.

Note

If more than one sparse matrix is needed (e.g. a stiffness and a mass matrix) it is more efficient to explicitly create the sparsity pattern instead of using this method, i.e. use

sp = init_sparsity_pattern(dh)
 add_sparsity_entries!(sp, dh)
 K = allocate_matrix(sp)
 M = allocate_matrix(sp)

instead of

K = allocate_matrix(dh)
-M = allocate_matrix(dh)

Note that for some matrix types it is possible to copy the instantiated matrix (M = copy(K)) instead.

source
+M = allocate_matrix(dh)

Note that for some matrix types it is possible to copy the instantiated matrix (M = copy(K)) instead.

source
Ferrite.allocate_matrixMethod
allocate_matrix(dh::DofHandler, args...; kwargs...)

Allocate a matrix of type SparseMatrixCSC{Float64, Int} from the DofHandler dh.

This method is a shorthand for the equivalent allocate_matrix(SparseMatrixCSC{Float64, Int}, dh, args...; kwargs...) – refer to that method for details.

source
diff --git a/dev/reference/utils/index.html b/dev/reference/utils/index.html index ea981c7210..1d45792c40 100644 --- a/dev/reference/utils/index.html +++ b/dev/reference/utils/index.html @@ -1,2 +1,2 @@ -Development utility functions · Ferrite.jl

Development utility functions

Ferrite.debug_modeFunction
Ferrite.debug_mode(; enable=true)

Helper to turn on (enable=true) or off (enable=false) debug expressions in Ferrite.

Debug mode influences Ferrite.@debug expr: when debug mode is enabled, expr is evaluated, and when debug mode is disabled expr is ignored.

source
+Development utility functions · Ferrite.jl

Development utility functions

Ferrite.debug_modeFunction
Ferrite.debug_mode(; enable=true)

Helper to turn on (enable=true) or off (enable=false) debug expressions in Ferrite.

Debug mode influences Ferrite.@debug expr: when debug mode is enabled, expr is evaluated, and when debug mode is disabled expr is ignored.

source
diff --git a/dev/topics/FEValues/index.html b/dev/topics/FEValues/index.html index 460859c449..57efcf0a80 100644 --- a/dev/topics/FEValues/index.html +++ b/dev/topics/FEValues/index.html @@ -125,4 +125,4 @@ reinit!(cv, x);

If we now pretend we are inside an element routine and have a vector of element degree of freedom values, ue. Then, we can check that our function values and gradients match Ferrite's builtin CellValues:

ue = rand(getnbasefunctions(simple_cv))
 q_point = 2
 @test function_value(cv, q_point, ue) ≈ function_value(simple_cv, q_point, ue)
-@test function_gradient(cv, q_point, ue) ≈ function_gradient(simple_cv, q_point, ue)
Test Passed

Further reading

+@test function_gradient(cv, q_point, ue) ≈ function_gradient(simple_cv, q_point, ue)
Test Passed

Further reading

diff --git a/dev/topics/assembly/index.html b/dev/topics/assembly/index.html index e075b116a5..a63d845374 100644 --- a/dev/topics/assembly/index.html +++ b/dev/topics/assembly/index.html @@ -90,4 +90,4 @@ @time assemble_system!(assemble_v4, K, dh, cellvalues)

We then obtain the following results (running on the same machine as above):

12.175625 seconds (719.99 k allocations: 149.809 GiB, 11.59% gc time)
  0.009313 seconds (8 allocations: 928 bytes)
  0.006055 seconds (8 allocations: 928 bytes)
- 0.004530 seconds (10 allocations: 1.062 KiB)

This follows the same trend as for the benchmarks for individual cell assembly and shows that the efficiency of the assembly strategy is crucial for the overall performance of the program. In particular this benchmark shows that allocations in such a tight loop from the first strategy is very costly and puts a strain on the garbage collector: 11% of the time is spent in GC instead of crunching numbers.

It should of course be noted that the more expensive the element routine is, the less the performance of the assembly strategy matters for the total runtime. However, there are no reason not to use the fastest method given that it is readily available in Ferrite.

+ 0.004530 seconds (10 allocations: 1.062 KiB)

This follows the same trend as for the benchmarks for individual cell assembly and shows that the efficiency of the assembly strategy is crucial for the overall performance of the program. In particular this benchmark shows that allocations in such a tight loop from the first strategy is very costly and puts a strain on the garbage collector: 11% of the time is spent in GC instead of crunching numbers.

It should of course be noted that the more expensive the element routine is, the less the performance of the assembly strategy matters for the total runtime. However, there are no reason not to use the fastest method given that it is readily available in Ferrite.

diff --git a/dev/topics/boundary_conditions/index.html b/dev/topics/boundary_conditions/index.html index f95a98dd23..4af9f8fcf8 100644 --- a/dev/topics/boundary_conditions/index.html +++ b/dev/topics/boundary_conditions/index.html @@ -78,4 +78,4 @@ grid = generate_grid(Quadrilateral, (10,10)) dh = DofHandler(grid); add!(dh, :u, 2); add!(dh, :p, 1); close!(dh) u = zeros(ndofs(dh)) -apply_analytical!(u, dh, :p, x -> ρ * g * x[2])

See also Transient heat equation for one example.

Consistency

apply_analytical! does not enforce consistency of the applied solution with the system of equations. Some problems, like for example differential-algebraic systems of equations (DAEs) need extra care during initialization. We refer to the paper "Consistent Initial Condition Calculation for Differential-Algebraic Systems" by Brown et al. for more details on this matter.

+apply_analytical!(u, dh, :p, x -> ρ * g * x[2])

See also Transient heat equation for one example.

Consistency

apply_analytical! does not enforce consistency of the applied solution with the system of equations. Some problems, like for example differential-algebraic systems of equations (DAEs) need extra care during initialization. We refer to the paper "Consistent Initial Condition Calculation for Differential-Algebraic Systems" by Brown et al. for more details on this matter.

diff --git a/dev/topics/constraints/index.html b/dev/topics/constraints/index.html index 465dd9b585..3137a3c873 100644 --- a/dev/topics/constraints/index.html +++ b/dev/topics/constraints/index.html @@ -21,4 +21,4 @@ apply_zero!(Δa, ch) # Change the constrained values in `Δa` such that `a-Δa` # fulfills constraints if `a` did. a .-= Δa -end +end diff --git a/dev/topics/degrees_of_freedom/index.html b/dev/topics/degrees_of_freedom/index.html index 73713a42e7..516ac2b301 100644 --- a/dev/topics/degrees_of_freedom/index.html +++ b/dev/topics/degrees_of_freedom/index.html @@ -12,4 +12,4 @@ :p, Lagrange{RefTriangle, 1}() :u, Lagrange{RefTriangle, 1}()^2 Dofs per cell: 9 - Total dofs: 1323

Ordering of Dofs

Todo

Describe dof ordering within elements (vertices -> edges -> faces -> volumes) and dof_range. Describe (global) dof renumbering

+ Total dofs: 1323

Ordering of Dofs

Todo

Describe dof ordering within elements (vertices -> edges -> faces -> volumes) and dof_range. Describe (global) dof renumbering

diff --git a/dev/topics/export/index.html b/dev/topics/export/index.html index 014acc1888..9c229674d8 100644 --- a/dev/topics/export/index.html +++ b/dev/topics/export/index.html @@ -19,4 +19,4 @@ "my_results_2.vtu" "my_results_3.vtu" "my_results_4.vtu" - "my_results_5.vtu"

See Transient heat equation for an example

+ "my_results_5.vtu"

See Transient heat equation for an example

diff --git a/dev/topics/fe_intro/index.html b/dev/topics/fe_intro/index.html index 43b8e94f6e..2090f3692c 100644 --- a/dev/topics/fe_intro/index.html +++ b/dev/topics/fe_intro/index.html @@ -12,4 +12,4 @@ \int_{\Gamma_\mathrm{N}} \phi_i \, q^\mathrm{p} \, \mathrm{d}\Gamma + \int_{\Omega_\mathrm{h}} \phi_i \, f \, \mathrm{d}\Omega \, .\]

Finally we also need to take care of the Dirichlet boundary conditions. These are enforced by setting the corresponding $\hat{u}_i$ to the prescribed values and eliminating the associated equations from the system. Now, solving this equation system yields the nodal values and thus an approximation to the true solution.

Notes on the implementation

In practice, the shape functions $\phi_i$ are only non-zero on parts of the domain $\Omega_\mathrm{h}$. Thus, the integrals are evaluated on sub-domains, called elements or cells.

Each cell gives a contribution to the global stiffness matrix and force vector. The process of constructing the system of equations is also called assembly. For clarification, let us rewrite the formula for the stiffness matrix entries as follows:

\[(\underline{\underline{K}})_{ij} = \int_{\Omega_\mathrm{h}} \nabla \phi_i \cdot (k \nabla \phi_j) \mathrm{d}\Omega = \sum_{E \in \Omega_\mathrm{h}} \int_E \nabla \phi_i \cdot (k \nabla \phi_j) \mathrm{d}\Omega \, .\]

This formulation underlines the element-centric perspective of finite element methods and reflects how it is usually implemented in software.

Computing the element integrals by hand can become a tedious task. To avoid this issue we approximate the element integrals with a technique called numerical integration. Skipping any of the mathematical details, the basic idea is to evaluate the function under the integral at specific points and weighting the evaluations accordingly, such that their sum approximates the volume properly. A very nice feature of these techniques is, that under quite general circumstances the formula is not just an approximation, but the exact evaluation of the integral. To avoid the recomputation of the just mentioned evaluation positions of the integral for each individual element, we perform a coordinate transformation onto a so-called reference element. Formally we write

\[ \int_E \nabla \phi_i \cdot (k \nabla \phi_j) \mathrm{d}\Omega - \approx \sum_q \nabla \phi_i(\textbf{x}_q) \cdot (k(\textbf{x}_q) \nabla \phi_j(\textbf{x}_q)) \, w_q \, \textrm{det}(J(\textbf{x}_q)) \, ,\]

where $J$ is the Jacobian of the coordinate transformation function. The computation of the transformation, weights, positions and of the Jacobi determinant is handled by Ferrite. On an intuitive level, and to explain the notation used in the implementation, we think of

\[ \mathrm{d}\Omega \approx \, w \, \textrm{det}(J)\]

being the chosen approximation when changing from the integral to the finite summation.

For an example of the implementation to solve a heat problem with Ferrite check out this thoroughly commented example.

More details

We finally want to note that this quick introduction barely scratches the surface of the finite element method. Also, we presented some things in a simplified way for the sake of keeping this article short and concise. There is a large corpus of literature and online tutorials containing more details about the finite element method. To give a few recommendations there is:

This list is neither meant to be exhaustive, nor does the absence of a work mean that it is in any way bad or not recommendable. The ordering of the articles also has no particular meaning.

+ \approx \sum_q \nabla \phi_i(\textbf{x}_q) \cdot (k(\textbf{x}_q) \nabla \phi_j(\textbf{x}_q)) \, w_q \, \textrm{det}(J(\textbf{x}_q)) \, ,\]

where $J$ is the Jacobian of the coordinate transformation function. The computation of the transformation, weights, positions and of the Jacobi determinant is handled by Ferrite. On an intuitive level, and to explain the notation used in the implementation, we think of

\[ \mathrm{d}\Omega \approx \, w \, \textrm{det}(J)\]

being the chosen approximation when changing from the integral to the finite summation.

For an example of the implementation to solve a heat problem with Ferrite check out this thoroughly commented example.

More details

We finally want to note that this quick introduction barely scratches the surface of the finite element method. Also, we presented some things in a simplified way for the sake of keeping this article short and concise. There is a large corpus of literature and online tutorials containing more details about the finite element method. To give a few recommendations there is:

This list is neither meant to be exhaustive, nor does the absence of a work mean that it is in any way bad or not recommendable. The ordering of the articles also has no particular meaning.

diff --git a/dev/topics/grid/index.html b/dev/topics/grid/index.html index 170b2bfa20..d04310bb96 100644 --- a/dev/topics/grid/index.html +++ b/dev/topics/grid/index.html @@ -19,4 +19,4 @@ Ferrite.getnnodes(grid::SmallGrid) = length(grid.nodes_test) Ferrite.get_coordinate_eltype(::SmallGrid) = Float64 Ferrite.get_coordinate_type(::SmallGrid{dim}) where dim = Vec{dim,Float64} -Ferrite.nnodes_per_cell(grid::SmallGrid, i::Int=1) = Ferrite.nnodes(grid.cells_test[i])

These definitions make many of Ferrite functions work out of the box, e.g. you can now call getcoordinates(grid, cellid) on the SmallGrid.

Now, you would be able to assemble the heat equation example over the new custom SmallGrid type. Note that this particular subtype isn't able to handle boundary entity sets and so, you can't describe boundaries with it. In order to use boundaries, e.g. for Dirichlet constraints in the ConstraintHandler, you would need to dispatch the AbstractGrid sets utility functions on SmallGrid.

Topology

Ferrite.jl's Grid type offers experimental features w.r.t. topology information. The functions getneighborhood and facetskeleton are the interface to obtain topological information. The getneighborhood can construct lists of directly connected entities based on a given entity (CellIndex, FacetIndex, FaceIndex, EdgeIndex, or VertexIndex). The facetskeleton function can be used to evaluate integrals over material interfaces or computing element interface values such as jumps.

+Ferrite.nnodes_per_cell(grid::SmallGrid, i::Int=1) = Ferrite.nnodes(grid.cells_test[i])

These definitions make many of Ferrite functions work out of the box, e.g. you can now call getcoordinates(grid, cellid) on the SmallGrid.

Now, you would be able to assemble the heat equation example over the new custom SmallGrid type. Note that this particular subtype isn't able to handle boundary entity sets and so, you can't describe boundaries with it. In order to use boundaries, e.g. for Dirichlet constraints in the ConstraintHandler, you would need to dispatch the AbstractGrid sets utility functions on SmallGrid.

Topology

Ferrite.jl's Grid type offers experimental features w.r.t. topology information. The functions getneighborhood and facetskeleton are the interface to obtain topological information. The getneighborhood can construct lists of directly connected entities based on a given entity (CellIndex, FacetIndex, FaceIndex, EdgeIndex, or VertexIndex). The facetskeleton function can be used to evaluate integrals over material interfaces or computing element interface values such as jumps.

diff --git a/dev/topics/index.html b/dev/topics/index.html index c7d3f1ca06..a5d6fa9170 100644 --- a/dev/topics/index.html +++ b/dev/topics/index.html @@ -1,2 +1,2 @@ -Topic guide overview · Ferrite.jl

Topic guides

This is an overview of the topic guides.

+Topic guide overview · Ferrite.jl

Topic guides

This is an overview of the topic guides.

diff --git a/dev/topics/my_results_1.vtu b/dev/topics/my_results_1.vtu index f68c07c1b9..b3aeb8cc7c 100644 Binary files a/dev/topics/my_results_1.vtu and b/dev/topics/my_results_1.vtu differ diff --git a/dev/topics/my_results_2.vtu b/dev/topics/my_results_2.vtu index f68c07c1b9..b3aeb8cc7c 100644 Binary files a/dev/topics/my_results_2.vtu and b/dev/topics/my_results_2.vtu differ diff --git a/dev/topics/my_results_3.vtu b/dev/topics/my_results_3.vtu index f68c07c1b9..b3aeb8cc7c 100644 Binary files a/dev/topics/my_results_3.vtu and b/dev/topics/my_results_3.vtu differ diff --git a/dev/topics/my_results_4.vtu b/dev/topics/my_results_4.vtu index f68c07c1b9..b3aeb8cc7c 100644 Binary files a/dev/topics/my_results_4.vtu and b/dev/topics/my_results_4.vtu differ diff --git a/dev/topics/my_results_5.vtu b/dev/topics/my_results_5.vtu index f68c07c1b9..b3aeb8cc7c 100644 Binary files a/dev/topics/my_results_5.vtu and b/dev/topics/my_results_5.vtu differ diff --git a/dev/topics/my_solution.vtu b/dev/topics/my_solution.vtu index f68c07c1b9..b3aeb8cc7c 100644 Binary files a/dev/topics/my_solution.vtu and b/dev/topics/my_solution.vtu differ diff --git a/dev/topics/reference_shapes/index.html b/dev/topics/reference_shapes/index.html index cee0826085..89107b3716 100644 --- a/dev/topics/reference_shapes/index.html +++ b/dev/topics/reference_shapes/index.html @@ -1,2 +1,2 @@ -Reference shapes · Ferrite.jl

Reference shapes

The reference shapes in Ferrite are used to define grid cells, function interpolations (i.e. shape functions), and quadrature rules. Currently, the following reference shapes are defined

  • RefLine
  • RefTriangle
  • RefQuadrilateral
  • RefTetrahedron
  • RefHexahedron
  • RefPrism
  • RefPyramid

Entity naming

Ferrite denotes the entities of a reference shape as follows

EntityDescription
Vertex0-dimensional entity in the reference shape.
Edge1-dimensional entity connecting two vertices.
Face2-dimensional entity enclosed by edges.
Volume3-dimensional entity enclosed by faces.

Note that a node in Ferrite is not the same as a vertex. Vertices denote endpoints of edges, while nodes may also be located in the middle of edges (e.g. for a QuadraticLine cell).

To write dimensionally independent code, Ferrite also denotes entities by their codimension, defined relative the reference shape dimension. Specifically, Ferrite has the entities

EntityDescription
Cell0-codimensional entity, i.e. the same as the reference shape.
Facet1-codimensional entity defining the boundary of cells.

Standard use cases mostly deal with these codimensional entities, such as CellValues and FacetValues.

Definition of codimension

In Ferrite, codimension is defined relative to the reference dimension of the specific entity. Note that other finite element codes may define it differently (e.g. relative the highest reference dimension in the grid).

Entity numbering

Each reference shape defines the numbering of its vertices, edges, and faces entities, where the edge and face entities are defined from their vertex numbers.

Note

The numbering and identification of entities is (mostly) for internal use and typically not something users of Ferrite need to interact with.

Example

The RefQuadrilateral is defined on the domain $[-1, 1] \times [-1, 1]$ in the local $\xi_1-\xi_2$ coordinate system.

local element

The vertices of a RefQuadrilateral are then

Ferrite.reference_vertices(RefQuadrilateral)
(1, 2, 3, 4)

and its edges are then defined as

Ferrite.reference_edges(RefQuadrilateral)
((1, 2), (2, 3), (3, 4), (4, 1))

where the numbers refer to the vertex number. Finally, this reference shape is 2-dimensional, so it only has a single face, corresponding to the cell itself,

Ferrite.reference_faces(RefQuadrilateral)
((1, 2, 3, 4),)

also defined in terms of its vertices.

As this is a 2-dimensional reference shape, the facets are the edges, i.e.

Ferrite.reference_facets(RefQuadrilateral)
((1, 2), (2, 3), (3, 4), (4, 1))
Not public API

The functions reference_vertices, reference_edges, reference_faces, and reference_facets are not public and only shown here to explain the numbering concept. The specific ordering may also change, and is therefore only documented in the Developer documentation.

+Reference shapes · Ferrite.jl

Reference shapes

The reference shapes in Ferrite are used to define grid cells, function interpolations (i.e. shape functions), and quadrature rules. Currently, the following reference shapes are defined

  • RefLine
  • RefTriangle
  • RefQuadrilateral
  • RefTetrahedron
  • RefHexahedron
  • RefPrism
  • RefPyramid

Entity naming

Ferrite denotes the entities of a reference shape as follows

EntityDescription
Vertex0-dimensional entity in the reference shape.
Edge1-dimensional entity connecting two vertices.
Face2-dimensional entity enclosed by edges.
Volume3-dimensional entity enclosed by faces.

Note that a node in Ferrite is not the same as a vertex. Vertices denote endpoints of edges, while nodes may also be located in the middle of edges (e.g. for a QuadraticLine cell).

To write dimensionally independent code, Ferrite also denotes entities by their codimension, defined relative the reference shape dimension. Specifically, Ferrite has the entities

EntityDescription
Cell0-codimensional entity, i.e. the same as the reference shape.
Facet1-codimensional entity defining the boundary of cells.

Standard use cases mostly deal with these codimensional entities, such as CellValues and FacetValues.

Definition of codimension

In Ferrite, codimension is defined relative to the reference dimension of the specific entity. Note that other finite element codes may define it differently (e.g. relative the highest reference dimension in the grid).

Entity numbering

Each reference shape defines the numbering of its vertices, edges, and faces entities, where the edge and face entities are defined from their vertex numbers.

Note

The numbering and identification of entities is (mostly) for internal use and typically not something users of Ferrite need to interact with.

Example

The RefQuadrilateral is defined on the domain $[-1, 1] \times [-1, 1]$ in the local $\xi_1-\xi_2$ coordinate system.

local element

The vertices of a RefQuadrilateral are then

Ferrite.reference_vertices(RefQuadrilateral)
(1, 2, 3, 4)

and its edges are then defined as

Ferrite.reference_edges(RefQuadrilateral)
((1, 2), (2, 3), (3, 4), (4, 1))

where the numbers refer to the vertex number. Finally, this reference shape is 2-dimensional, so it only has a single face, corresponding to the cell itself,

Ferrite.reference_faces(RefQuadrilateral)
((1, 2, 3, 4),)

also defined in terms of its vertices.

As this is a 2-dimensional reference shape, the facets are the edges, i.e.

Ferrite.reference_facets(RefQuadrilateral)
((1, 2), (2, 3), (3, 4), (4, 1))
Not public API

The functions reference_vertices, reference_edges, reference_faces, and reference_facets are not public and only shown here to explain the numbering concept. The specific ordering may also change, and is therefore only documented in the Developer documentation.

diff --git a/dev/topics/sparse_matrix/index.html b/dev/topics/sparse_matrix/index.html index 3df4716415..90b6e1a9a1 100644 --- a/dev/topics/sparse_matrix/index.html +++ b/dev/topics/sparse_matrix/index.html @@ -3,4 +3,4 @@ 0.0 0.0 ⋅ ⋅ 0.0 0.0 0.0 ⋅ ⋅ 0.0 0.0 0.0 - ⋅ ⋅ 0.0 0.0

Moreover, if the problem is solved with periodic boundary conditions, for example by constraining the value on the right side to the value on the left side, there will be additional couplings. In the example above, this means that DoF 4 should be equal to DoF

  1. Since DoF 4 is constrained it has to be eliminated from the system. Existing entries

that include DoF 4 are (3, 4), (4, 3), and (4, 4). Given the simple constraint in this case we can simply replace DoF 4 with DoF 1 in these entries and we end up with entries (3, 1), (1, 3), and (1, 1). This results in two new entries: (3, 1) and (1, 3) (entry (1, 1) is already included).

Creating sparsity patterns

Creating a sparsity pattern can be quite expensive if not done properly and therefore Ferrite provides efficient methods and data structures for this. In general the sparsity pattern is not known in advance and has to be created incrementally. To make this incremental construction efficient it is necessary to use a dynamic data structure which allow for fast insertions.

The sparsity pattern also serves as a "matrix builder". When all entries are inserted into the sparsity pattern the dynamic data structure is typically converted, or "compressed", into a sparse matrix format such as e.g. the compressed sparse row (CSR) format or the compressed sparse column (CSC) format, where the latter is the default sparse matrix type implemented in the SparseArrays standard library. These matrix formats allow for fast linear algebra operations, such as factorizations and matrix-vector multiplications, that are needed when the linear system is solved. See Instantiating the sparse matrix for more details.

In summary, a dynamic structure is more efficient when incrementally building the pattern by inserting new entries, and a static or compressed structure is more efficient for linear algebra operations.

Basic sparsity patterns construction

Working with the sparsity pattern explicitly is in many cases not necessary. For basic usage (e.g. when only one matrix needed, when no customization of the pattern is required, etc) there exist convenience methods of allocate_matrix that return the matrix directly. Most examples in this documentation don't deal with the sparsity pattern explicitly because the basic method suffice. See also Instantiating the sparse matrix for more details.

Custom sparsity pattern construction

In more advanced cases there might be a need for more fine grained control of the sparsity pattern. The following steps are typically taken when constructing a sparsity pattern in Ferrite:

  1. Initialize an empty pattern: This can be done by either using the init_sparsity_pattern(dh) function or by using a constructor directly. init_sparsity_pattern will return a default pattern type that is compatible with the DofHandler. In some cases you might require another type of pattern (for example a blocked pattern, see Blocked sparsity pattern) and in that case you can use the constructor directly.

  2. Add entries to the pattern: There are a number of functions that add entries to the pattern:

  3. Instantiate the matrix: A sparse matrix can be created from the sparsity pattern using allocate_matrix, see Instantiating the sparse matrix below for more details.

Increasing the sparsity

By default, when creating a sparsity pattern, it is assumed that each DoF within an element couple with with all other DoFs in the element.

Todo

Blocked sparsity pattern

Todo

Discuss BlockSparsityPattern and BlockArrays extension.

Instantiating the sparse matrix

As mentioned above, for many simple cases there is no need to work with the sparsity pattern directly and using methods of allocate_matrix that take the DofHandler as input is enough, for example:

K = allocate_matrix(dh, ch)

allocate_matrix is also used to instantiate a matrix from a sparsity pattern, for example:

K = allocate_matrix(sp)
Multiple matrices with the same pattern

For some problems there is a need for multiple matrices with the same sparsity pattern, for example a mass matrix and a stiffness matrix. In this case it is more efficient to create the sparsity pattern once and then instantiate both matrices from it.

+ ⋅ ⋅ 0.0 0.0

Moreover, if the problem is solved with periodic boundary conditions, for example by constraining the value on the right side to the value on the left side, there will be additional couplings. In the example above, this means that DoF 4 should be equal to DoF

  1. Since DoF 4 is constrained it has to be eliminated from the system. Existing entries

that include DoF 4 are (3, 4), (4, 3), and (4, 4). Given the simple constraint in this case we can simply replace DoF 4 with DoF 1 in these entries and we end up with entries (3, 1), (1, 3), and (1, 1). This results in two new entries: (3, 1) and (1, 3) (entry (1, 1) is already included).

Creating sparsity patterns

Creating a sparsity pattern can be quite expensive if not done properly and therefore Ferrite provides efficient methods and data structures for this. In general the sparsity pattern is not known in advance and has to be created incrementally. To make this incremental construction efficient it is necessary to use a dynamic data structure which allow for fast insertions.

The sparsity pattern also serves as a "matrix builder". When all entries are inserted into the sparsity pattern the dynamic data structure is typically converted, or "compressed", into a sparse matrix format such as e.g. the compressed sparse row (CSR) format or the compressed sparse column (CSC) format, where the latter is the default sparse matrix type implemented in the SparseArrays standard library. These matrix formats allow for fast linear algebra operations, such as factorizations and matrix-vector multiplications, that are needed when the linear system is solved. See Instantiating the sparse matrix for more details.

In summary, a dynamic structure is more efficient when incrementally building the pattern by inserting new entries, and a static or compressed structure is more efficient for linear algebra operations.

Basic sparsity patterns construction

Working with the sparsity pattern explicitly is in many cases not necessary. For basic usage (e.g. when only one matrix needed, when no customization of the pattern is required, etc) there exist convenience methods of allocate_matrix that return the matrix directly. Most examples in this documentation don't deal with the sparsity pattern explicitly because the basic method suffice. See also Instantiating the sparse matrix for more details.

Custom sparsity pattern construction

In more advanced cases there might be a need for more fine grained control of the sparsity pattern. The following steps are typically taken when constructing a sparsity pattern in Ferrite:

  1. Initialize an empty pattern: This can be done by either using the init_sparsity_pattern(dh) function or by using a constructor directly. init_sparsity_pattern will return a default pattern type that is compatible with the DofHandler. In some cases you might require another type of pattern (for example a blocked pattern, see Blocked sparsity pattern) and in that case you can use the constructor directly.

  2. Add entries to the pattern: There are a number of functions that add entries to the pattern:

  3. Instantiate the matrix: A sparse matrix can be created from the sparsity pattern using allocate_matrix, see Instantiating the sparse matrix below for more details.

Increasing the sparsity

By default, when creating a sparsity pattern, it is assumed that each DoF within an element couple with with all other DoFs in the element.

Todo

Blocked sparsity pattern

Todo

Discuss BlockSparsityPattern and BlockArrays extension.

Instantiating the sparse matrix

As mentioned above, for many simple cases there is no need to work with the sparsity pattern directly and using methods of allocate_matrix that take the DofHandler as input is enough, for example:

K = allocate_matrix(dh, ch)

allocate_matrix is also used to instantiate a matrix from a sparsity pattern, for example:

K = allocate_matrix(sp)
Multiple matrices with the same pattern

For some problems there is a need for multiple matrices with the same sparsity pattern, for example a mass matrix and a stiffness matrix. In this case it is more efficient to create the sparsity pattern once and then instantiate both matrices from it.

diff --git a/dev/tutorials/computational_homogenization.ipynb b/dev/tutorials/computational_homogenization.ipynb index 4985d74707..3227d3a0ec 100644 --- a/dev/tutorials/computational_homogenization.ipynb +++ b/dev/tutorials/computational_homogenization.ipynb @@ -832,11 +832,11 @@ "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.11.1" + "version": "1.11.2" }, "kernelspec": { "name": "julia-1.11", - "display_name": "Julia 1.11.1", + "display_name": "Julia 1.11.2", "language": "julia" } }, diff --git a/dev/tutorials/computational_homogenization/index.html b/dev/tutorials/computational_homogenization/index.html index f3a822cf6b..f65879afea 100644 --- a/dev/tutorials/computational_homogenization/index.html +++ b/dev/tutorials/computational_homogenization/index.html @@ -471,4 +471,4 @@ write_solution(vtk, dh, uM + u.periodic[i], "_periodic_$i") write_projection(vtk, projector, σ.periodic[i], "σvM_periodic_$i") end -end;

This page was generated using Literate.jl.

+end;

This page was generated using Literate.jl.

diff --git a/dev/tutorials/dg_heat_equation.ipynb b/dev/tutorials/dg_heat_equation.ipynb index 201085239a..cfd7d65e65 100644 --- a/dev/tutorials/dg_heat_equation.ipynb +++ b/dev/tutorials/dg_heat_equation.ipynb @@ -522,11 +522,11 @@ "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.11.1" + "version": "1.11.2" }, "kernelspec": { "name": "julia-1.11", - "display_name": "Julia 1.11.1", + "display_name": "Julia 1.11.2", "language": "julia" } }, diff --git a/dev/tutorials/dg_heat_equation/index.html b/dev/tutorials/dg_heat_equation/index.html index 258fba4df8..16b095d888 100644 --- a/dev/tutorials/dg_heat_equation/index.html +++ b/dev/tutorials/dg_heat_equation/index.html @@ -297,4 +297,4 @@ u = K \ f; VTKGridFile("dg_heat_equation", dh) do vtk write_solution(vtk, dh, u) -end;

This page was generated using Literate.jl.

+end;

This page was generated using Literate.jl.

diff --git a/dev/tutorials/heat_equation.ipynb b/dev/tutorials/heat_equation.ipynb index 730a221a1a..17e3825096 100644 --- a/dev/tutorials/heat_equation.ipynb +++ b/dev/tutorials/heat_equation.ipynb @@ -469,11 +469,11 @@ "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.11.1" + "version": "1.11.2" }, "kernelspec": { "name": "julia-1.11", - "display_name": "Julia 1.11.1", + "display_name": "Julia 1.11.2", "language": "julia" } }, diff --git a/dev/tutorials/heat_equation/index.html b/dev/tutorials/heat_equation/index.html index 707bae8565..744bff095b 100644 --- a/dev/tutorials/heat_equation/index.html +++ b/dev/tutorials/heat_equation/index.html @@ -159,4 +159,4 @@ VTKGridFile("heat_equation", dh) do vtk write_solution(vtk, dh, u) -end

This page was generated using Literate.jl.

+end

This page was generated using Literate.jl.

diff --git a/dev/tutorials/hyperelasticity.ipynb b/dev/tutorials/hyperelasticity.ipynb index e392d1c175..ccbe031368 100644 --- a/dev/tutorials/hyperelasticity.ipynb +++ b/dev/tutorials/hyperelasticity.ipynb @@ -529,14 +529,14 @@ "-------------------------------------------------------------------------------\n", " Analysis with 6000 elements Time Allocations \n", " ----------------------- ------------------------\n", - " Tot / % measured: 2.06s / 49.7% 146MiB / 43.9% \n", + " Tot / % measured: 1.94s / 48.2% 145MiB / 44.0% \n", "\n", "Section ncalls time %tot avg alloc %tot avg\n", "-------------------------------------------------------------------------------\n", - "export 1 839ms 82.0% 839ms 58.1MiB 90.7% 58.1MiB\n", - "assemble 6 110ms 10.7% 18.3ms 5.50MiB 8.6% 938KiB\n", - " element assemble 36.0k 63.8ms 6.2% 1.77μs 0.00B 0.0% 0.00B\n", - "linear solve 5 74.2ms 7.3% 14.8ms 473KiB 0.7% 94.6KiB\n", + "export 1 758ms 80.8% 758ms 58.0MiB 90.7% 58.0MiB\n", + "assemble 6 106ms 11.3% 17.6ms 5.50MiB 8.6% 938KiB\n", + " element assemble 36.0k 62.1ms 6.6% 1.73μs 0.00B 0.0% 0.00B\n", + "linear solve 5 73.7ms 7.9% 14.7ms 473KiB 0.7% 94.6KiB\n", "-------------------------------------------------------------------------------\n" ] } @@ -564,11 +564,11 @@ "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.11.1" + "version": "1.11.2" }, "kernelspec": { "name": "julia-1.11", - "display_name": "Julia 1.11.1", + "display_name": "Julia 1.11.2", "language": "julia" } }, diff --git a/dev/tutorials/hyperelasticity/index.html b/dev/tutorials/hyperelasticity/index.html index d29d5c83e9..c5a66257ee 100644 --- a/dev/tutorials/hyperelasticity/index.html +++ b/dev/tutorials/hyperelasticity/index.html @@ -246,14 +246,14 @@ ------------------------------------------------------------------------------- Analysis with 6000 elements Time Allocations ----------------------- ------------------------ - Tot / % measured: 302ms / 67.4% 29.6MiB / 33.4% + Tot / % measured: 292ms / 66.9% 29.7MiB / 33.4% Section ncalls time %tot avg alloc %tot avg ------------------------------------------------------------------------------- -assemble 6 111ms 54.5% 18.5ms 5.50MiB 55.5% 938KiB - element assemble 36.0k 63.4ms 31.2% 1.76μs 0.00B 0.0% 0.00B -linear solve 5 78.2ms 38.5% 15.6ms 473KiB 4.7% 94.6KiB -export 1 14.2ms 7.0% 14.2ms 3.94MiB 39.8% 3.94MiB +assemble 6 106ms 54.2% 17.7ms 5.50MiB 55.5% 938KiB + element assemble 36.0k 61.8ms 31.6% 1.72μs 0.00B 0.0% 0.00B +linear solve 5 75.4ms 38.6% 15.1ms 473KiB 4.7% 94.6KiB +export 1 14.1ms 7.2% 14.1ms 3.94MiB 39.8% 3.94MiB -------------------------------------------------------------------------------

Plain program

Here follows a version of the program without any comments. The file is also available here: hyperelasticity.jl.

using Ferrite, Tensors, TimerOutputs, ProgressMeter, IterativeSolvers
 
 struct NeoHooke
@@ -463,4 +463,4 @@
     return u
 end
 
-u = solve();

This page was generated using Literate.jl.

+u = solve();

This page was generated using Literate.jl.

diff --git a/dev/tutorials/incompressible_elasticity.ipynb b/dev/tutorials/incompressible_elasticity.ipynb index 7a7e10927c..2532a5356a 100644 --- a/dev/tutorials/incompressible_elasticity.ipynb +++ b/dev/tutorials/incompressible_elasticity.ipynb @@ -494,11 +494,11 @@ "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.11.1" + "version": "1.11.2" }, "kernelspec": { "name": "julia-1.11", - "display_name": "Julia 1.11.1", + "display_name": "Julia 1.11.2", "language": "julia" } }, diff --git a/dev/tutorials/incompressible_elasticity/index.html b/dev/tutorials/incompressible_elasticity/index.html index f266427014..dd91fc0129 100644 --- a/dev/tutorials/incompressible_elasticity/index.html +++ b/dev/tutorials/incompressible_elasticity/index.html @@ -443,4 +443,4 @@ quadratic_u = Lagrange{RefTriangle, 2}()^2 u1 = solve(0.5, linear_u, linear_p); -u2 = solve(0.5, quadratic_u, linear_p);

This page was generated using Literate.jl.

+u2 = solve(0.5, quadratic_u, linear_p);

This page was generated using Literate.jl.

diff --git a/dev/tutorials/index.html b/dev/tutorials/index.html index bd50bc18e8..d9ab2db808 100644 --- a/dev/tutorials/index.html +++ b/dev/tutorials/index.html @@ -1,2 +1,2 @@ -Tutorials overview · Ferrite.jl

Tutorials

On this page you find an overview of Ferrite tutorials. The tutorials explain and show how Ferrite can be used to solve a wide range of problems. See also the Code gallery for more examples.

The tutorials all follow roughly the same structure:

  • Introduction introduces the problem to be solved and discusses the learning outcomes of the tutorial.
  • Commented program is the code for solving the problem with explanations and comments.
  • Plain program is the raw source code of the program.

When studying the tutorials it is a good idea to obtain a local copy of the code and run it on your own machine as you read along. Some of the tutorials also include suggestions for tweaks to the program that you can try out on your own.

Tutorial index

The tutorials are listed in roughly increasing order of complexity. However, since they focus on different aspects, and solve different problems, it is suggested to have a look at the brief descriptions below to get an idea about what you will learn from each tutorial.

If you are new to Ferrite then Tutorial 1 - Tutorial 6 is the best place to start. These tutorials introduces and teaches most of the basic finite element techniques (e.g. linear and non-linear problems, scalar- and vector-valued problems, Dirichlet and Neumann boundary conditions, mixed finite elements, time integration, direct and iterative linear solvers, etc). In particular the very first tutorial is essential in order to be able to follow any of the other tutorials. The remaining tutorials discuss more advanced topics.


Tutorial 1: Heat equation

This tutorial guides you through the process of solving the linear stationary heat equation (i.e. Poisson's equation) on a unit square with homogeneous Dirichlet boundary conditions. This tutorial introduces and teaches many important parts of Ferrite: problem setup, degree of freedom management, assembly procedure, boundary conditions, solving the linear system, visualization of the result). Understanding this tutorial is essential to follow more complex tutorials.

Keywords: scalar-valued solution, Dirichlet boundary conditions.


Tutorial 2: Linear elasticity

TBW.

Keywords: vector-valued solution, Dirichlet and Neumann boundary conditions.


Tutorial 3: Incompressible elasticity

This tutorial focuses on a mixed formulation of linear elasticity, with (vector) displacement and (scalar) pressure as the two unknowns, suitable for incompressibility. Thus, this tutorial guides you through the process of solving a problem with two unknowns from two coupled weak forms. The problem that is studied is Cook's membrane in the incompressible limit.

Keywords: mixed finite elements, Dirichlet and Neumann boundary conditions.


Tutorial 4: Hyperelasticity

In this tutorial you will learn how to solve a non-linear finite element problem. In particular, a hyperelastic material model, in a finite strain setting, is used to solve the rotation of a cube. Automatic differentiatio (AD) is used for the consitutive relations. Newton's method is used for the non-linear iteration, and a conjugate gradient (CG) solver is used for the linear solution of the increment.

Keywords: non-linear finite element, finite strain, automatic differentiation (AD), Newton's method, conjugate gradient (CG).


Tutorial 5: von Mises Plasticity

This tutorial revisits the cantilever beam problem from Tutorial 2: Linear elasticity, but instead of linear elasticity a plasticity model is used for the constitutive relation. You will learn how to solve a problem which require the solution of a local material problem, and the storage of material state, in each quadrature point. Newton's method is used both locally in the material routine, and globally on the finite element level.

Keywords: non-linear finite element, plasticity, material modeling, state variables, Newton’s method.


Tutorial 6: Transient heat equation

In this tutorial the transient heat equation is solved on the unit square. The problem to be solved is thus similar to the one solved in the first tutorial, Heat equation, but with time-varying boundary conditions. In particular you will learn how to solve a time dependent problem with an implicit Euler scheme for the time integration.

Keywords: time dependent finite elements, implicit Euler time integration.


Tutorial 7: Computational homogenization

This tutorial guides you through computational homogenization of an representative volume element (RVE) consisting of a soft matrix material with stiff inclusions. The computational mesh is read from an external mesh file generated with Gmsh. Dirichlet and periodic boundary conditions are used.

Keywords: Gmsh mesh reading, Dirichlet and periodic boundary conditions


Tutorial 8: Stokes flow

In this tutorial Stokes flow with (vector) velocity and (scalar) pressure is solved on on a quarter circle. Rotationally periodic boundary conditions is used for the inlet/outlet coupling. To obtain a unique solution, a mean value constraint is applied on the pressure using an affine constraint. The computational mesh is generated directly using the Gmsh API.

Keywords: periodic boundary conditions, mean value constraint, mesh generation with Gmsh.


Tutorial 9: Porous media (SubDofHandler)

This tutorial introduces how to solve a complex linear problem, where there are different fields on different subdomains, and different cell types in the grid. This requires using the SubDofHandler interface.

Keywords: Mixed grids, multiple fields, porous media, SubDofHandler


Tutorial 10: Incompressible Navier-Stokes equations

In this tutorial the incompressible Navier-Stokes equations are solved. The domain is discretized in space with Ferrite as usual, and then forumalated in a way to be compatible with the OrdinaryDiffEq.jl package, which is used for the time-integration.

Keywords: non-linear time dependent problem


Tutorial 10: Reactive surface

In this tutorial a reaction diffusion system on a sphere surface embedded in 3D is solved. Ferrite is used to assemble the diffusion operators and the mass matrices. The problem is solved by using the usual first order reaction diffusion operator splitting.

Keywords: embedded elements, operator splitting, gmsh


Tutorial 11: Linear shell

In this tutorial a linear shell element formulation is set up as a two-dimensional domain embedded in three-dimensional space. This will teach, and perhaps inspire, you on how Ferrite can be used for non-standard things and how to add "hacks" that build on top of Ferrite.

Keywords: shell elements, automatic differentiation


Tutorial 12: Discontinuous Galerkin heat equation

This tutorial guides you through the process of solving the linear stationary heat equation (i.e. Poisson's equation) on a unit square with inhomogeneous Dirichlet and Neumann boundary conditions using the interior penalty discontinuous Galerkin method. This tutorial follows the heat equation tutorial, introducing face and interface iterators, jump and average operators, and cross-element coupling in sparsity patterns. This example was developed as part of the Google Summer of Code funded project "Discontinuous Galerkin Infrastructure For the finite element toolbox Ferrite.jl".

Keywords: scalar-valued solution, Dirichlet boundary conditions, Discontinuous Galerkin, Interior penalty

+Tutorials overview · Ferrite.jl

Tutorials

On this page you find an overview of Ferrite tutorials. The tutorials explain and show how Ferrite can be used to solve a wide range of problems. See also the Code gallery for more examples.

The tutorials all follow roughly the same structure:

  • Introduction introduces the problem to be solved and discusses the learning outcomes of the tutorial.
  • Commented program is the code for solving the problem with explanations and comments.
  • Plain program is the raw source code of the program.

When studying the tutorials it is a good idea to obtain a local copy of the code and run it on your own machine as you read along. Some of the tutorials also include suggestions for tweaks to the program that you can try out on your own.

Tutorial index

The tutorials are listed in roughly increasing order of complexity. However, since they focus on different aspects, and solve different problems, it is suggested to have a look at the brief descriptions below to get an idea about what you will learn from each tutorial.

If you are new to Ferrite then Tutorial 1 - Tutorial 6 is the best place to start. These tutorials introduces and teaches most of the basic finite element techniques (e.g. linear and non-linear problems, scalar- and vector-valued problems, Dirichlet and Neumann boundary conditions, mixed finite elements, time integration, direct and iterative linear solvers, etc). In particular the very first tutorial is essential in order to be able to follow any of the other tutorials. The remaining tutorials discuss more advanced topics.


Tutorial 1: Heat equation

This tutorial guides you through the process of solving the linear stationary heat equation (i.e. Poisson's equation) on a unit square with homogeneous Dirichlet boundary conditions. This tutorial introduces and teaches many important parts of Ferrite: problem setup, degree of freedom management, assembly procedure, boundary conditions, solving the linear system, visualization of the result). Understanding this tutorial is essential to follow more complex tutorials.

Keywords: scalar-valued solution, Dirichlet boundary conditions.


Tutorial 2: Linear elasticity

TBW.

Keywords: vector-valued solution, Dirichlet and Neumann boundary conditions.


Tutorial 3: Incompressible elasticity

This tutorial focuses on a mixed formulation of linear elasticity, with (vector) displacement and (scalar) pressure as the two unknowns, suitable for incompressibility. Thus, this tutorial guides you through the process of solving a problem with two unknowns from two coupled weak forms. The problem that is studied is Cook's membrane in the incompressible limit.

Keywords: mixed finite elements, Dirichlet and Neumann boundary conditions.


Tutorial 4: Hyperelasticity

In this tutorial you will learn how to solve a non-linear finite element problem. In particular, a hyperelastic material model, in a finite strain setting, is used to solve the rotation of a cube. Automatic differentiatio (AD) is used for the consitutive relations. Newton's method is used for the non-linear iteration, and a conjugate gradient (CG) solver is used for the linear solution of the increment.

Keywords: non-linear finite element, finite strain, automatic differentiation (AD), Newton's method, conjugate gradient (CG).


Tutorial 5: von Mises Plasticity

This tutorial revisits the cantilever beam problem from Tutorial 2: Linear elasticity, but instead of linear elasticity a plasticity model is used for the constitutive relation. You will learn how to solve a problem which require the solution of a local material problem, and the storage of material state, in each quadrature point. Newton's method is used both locally in the material routine, and globally on the finite element level.

Keywords: non-linear finite element, plasticity, material modeling, state variables, Newton’s method.


Tutorial 6: Transient heat equation

In this tutorial the transient heat equation is solved on the unit square. The problem to be solved is thus similar to the one solved in the first tutorial, Heat equation, but with time-varying boundary conditions. In particular you will learn how to solve a time dependent problem with an implicit Euler scheme for the time integration.

Keywords: time dependent finite elements, implicit Euler time integration.


Tutorial 7: Computational homogenization

This tutorial guides you through computational homogenization of an representative volume element (RVE) consisting of a soft matrix material with stiff inclusions. The computational mesh is read from an external mesh file generated with Gmsh. Dirichlet and periodic boundary conditions are used.

Keywords: Gmsh mesh reading, Dirichlet and periodic boundary conditions


Tutorial 8: Stokes flow

In this tutorial Stokes flow with (vector) velocity and (scalar) pressure is solved on on a quarter circle. Rotationally periodic boundary conditions is used for the inlet/outlet coupling. To obtain a unique solution, a mean value constraint is applied on the pressure using an affine constraint. The computational mesh is generated directly using the Gmsh API.

Keywords: periodic boundary conditions, mean value constraint, mesh generation with Gmsh.


Tutorial 9: Porous media (SubDofHandler)

This tutorial introduces how to solve a complex linear problem, where there are different fields on different subdomains, and different cell types in the grid. This requires using the SubDofHandler interface.

Keywords: Mixed grids, multiple fields, porous media, SubDofHandler


Tutorial 10: Incompressible Navier-Stokes equations

In this tutorial the incompressible Navier-Stokes equations are solved. The domain is discretized in space with Ferrite as usual, and then forumalated in a way to be compatible with the OrdinaryDiffEq.jl package, which is used for the time-integration.

Keywords: non-linear time dependent problem


Tutorial 10: Reactive surface

In this tutorial a reaction diffusion system on a sphere surface embedded in 3D is solved. Ferrite is used to assemble the diffusion operators and the mass matrices. The problem is solved by using the usual first order reaction diffusion operator splitting.

Keywords: embedded elements, operator splitting, gmsh


Tutorial 11: Linear shell

In this tutorial a linear shell element formulation is set up as a two-dimensional domain embedded in three-dimensional space. This will teach, and perhaps inspire, you on how Ferrite can be used for non-standard things and how to add "hacks" that build on top of Ferrite.

Keywords: shell elements, automatic differentiation


Tutorial 12: Discontinuous Galerkin heat equation

This tutorial guides you through the process of solving the linear stationary heat equation (i.e. Poisson's equation) on a unit square with inhomogeneous Dirichlet and Neumann boundary conditions using the interior penalty discontinuous Galerkin method. This tutorial follows the heat equation tutorial, introducing face and interface iterators, jump and average operators, and cross-element coupling in sparsity patterns. This example was developed as part of the Google Summer of Code funded project "Discontinuous Galerkin Infrastructure For the finite element toolbox Ferrite.jl".

Keywords: scalar-valued solution, Dirichlet boundary conditions, Discontinuous Galerkin, Interior penalty

diff --git a/dev/tutorials/linear_elasticity.ipynb b/dev/tutorials/linear_elasticity.ipynb index d9cab061ac..8409a54498 100644 --- a/dev/tutorials/linear_elasticity.ipynb +++ b/dev/tutorials/linear_elasticity.ipynb @@ -713,11 +713,11 @@ "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.11.1" + "version": "1.11.2" }, "kernelspec": { "name": "julia-1.11", - "display_name": "Julia 1.11.1", + "display_name": "Julia 1.11.2", "language": "julia" } }, diff --git a/dev/tutorials/linear_elasticity/index.html b/dev/tutorials/linear_elasticity/index.html index dcc3622304..0687277402 100644 --- a/dev/tutorials/linear_elasticity/index.html +++ b/dev/tutorials/linear_elasticity/index.html @@ -290,4 +290,4 @@ end write_projection(vtk, proj, stress_field, "stress field") Ferrite.write_cellset(vtk, grid) -end

This page was generated using Literate.jl.

+end

This page was generated using Literate.jl.

diff --git a/dev/tutorials/linear_shell.ipynb b/dev/tutorials/linear_shell.ipynb index f915788cbf..374c1f6654 100644 --- a/dev/tutorials/linear_shell.ipynb +++ b/dev/tutorials/linear_shell.ipynb @@ -429,11 +429,11 @@ "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.11.1" + "version": "1.11.2" }, "kernelspec": { "name": "julia-1.11", - "display_name": "Julia 1.11.1", + "display_name": "Julia 1.11.2", "language": "julia" } }, diff --git a/dev/tutorials/linear_shell/index.html b/dev/tutorials/linear_shell/index.html index b27e43c16c..9c684d939f 100644 --- a/dev/tutorials/linear_shell/index.html +++ b/dev/tutorials/linear_shell/index.html @@ -182,4 +182,4 @@ ke .+= B'*data.C*B * dV end end -end;

Run everything:

main()
VTKGridFile for the closed file "linear_shell.vtu".

This page was generated using Literate.jl.

+end;

Run everything:

main()
VTKGridFile for the closed file "linear_shell.vtu".

This page was generated using Literate.jl.

diff --git a/dev/tutorials/ns_vs_diffeq.ipynb b/dev/tutorials/ns_vs_diffeq.ipynb index 3928939087..851b1bedee 100644 --- a/dev/tutorials/ns_vs_diffeq.ipynb +++ b/dev/tutorials/ns_vs_diffeq.ipynb @@ -964,11 +964,11 @@ "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.11.1" + "version": "1.11.2" }, "kernelspec": { "name": "julia-1.11", - "display_name": "Julia 1.11.1", + "display_name": "Julia 1.11.2", "language": "julia" } }, diff --git a/dev/tutorials/ns_vs_diffeq/index.html b/dev/tutorials/ns_vs_diffeq/index.html index 4ea4965db6..515fc4ec83 100644 --- a/dev/tutorials/ns_vs_diffeq/index.html +++ b/dev/tutorials/ns_vs_diffeq/index.html @@ -546,4 +546,4 @@ pvd[t] = vtk end end -vtk_save(pvd);

This page was generated using Literate.jl.

+vtk_save(pvd);

This page was generated using Literate.jl.

diff --git a/dev/tutorials/plasticity.ipynb b/dev/tutorials/plasticity.ipynb index a44488671b..5113537967 100644 --- a/dev/tutorials/plasticity.ipynb +++ b/dev/tutorials/plasticity.ipynb @@ -720,182 +720,182 @@ "\n", "\n", "\n", - " \n", + " \n", " \n", " \n", "\n", - "\n", + "\n", "\n", - " \n", + " \n", " \n", " \n", "\n", - "\n", + "\n", "\n", - " \n", + " \n", " \n", " \n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n" ], "image/svg+xml": [ "\n", "\n", "\n", - " \n", + " \n", " \n", " \n", "\n", - "\n", + "\n", "\n", - " \n", + " \n", " \n", " \n", "\n", - "\n", + "\n", "\n", - " \n", + " \n", " \n", " \n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n" ] }, @@ -944,11 +944,11 @@ "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.11.1" + "version": "1.11.2" }, "kernelspec": { "name": "julia-1.11", - "display_name": "Julia 1.11.1", + "display_name": "Julia 1.11.2", "language": "julia" } }, diff --git a/dev/tutorials/plasticity/fed2bb6c.svg b/dev/tutorials/plasticity/a092dd4a.svg similarity index 83% rename from dev/tutorials/plasticity/fed2bb6c.svg rename to dev/tutorials/plasticity/a092dd4a.svg index bd0242c5d3..92ecf1347f 100644 --- a/dev/tutorials/plasticity/fed2bb6c.svg +++ b/dev/tutorials/plasticity/a092dd4a.svg @@ -1,89 +1,89 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/tutorials/plasticity/index.html b/dev/tutorials/plasticity/index.html index 3b5a7bd475..2a79063c9b 100644 --- a/dev/tutorials/plasticity/index.html +++ b/dev/tutorials/plasticity/index.html @@ -346,7 +346,7 @@ markershape = :auto ) ylabel!("Traction [Pa]") -xlabel!("Maximum deflection [m]")Example block output

Figure 2. Load-displacement-curve for the beam, showing a clear decrease in stiffness as more material starts to yield.

Plain program

Here follows a version of the program without any comments. The file is also available here: plasticity.jl.

using Ferrite, Tensors, SparseArrays, LinearAlgebra, Printf
+xlabel!("Maximum deflection [m]")
Example block output

Figure 2. Load-displacement-curve for the beam, showing a clear decrease in stiffness as more material starts to yield.

Plain program

Here follows a version of the program without any comments. The file is also available here: plasticity.jl.

using Ferrite, Tensors, SparseArrays, LinearAlgebra, Printf
 
 struct J2Plasticity{T, S <: SymmetricTensor{4, 3, T}}
     G::T  # Shear modulus
@@ -649,4 +649,4 @@
     markershape = :auto
 )
 ylabel!("Traction [Pa]")
-xlabel!("Maximum deflection [m]")

This page was generated using Literate.jl.

+xlabel!("Maximum deflection [m]")

This page was generated using Literate.jl.

diff --git a/dev/tutorials/porous_media.ipynb b/dev/tutorials/porous_media.ipynb index 50c19e29f6..0276a25cca 100644 --- a/dev/tutorials/porous_media.ipynb +++ b/dev/tutorials/porous_media.ipynb @@ -545,11 +545,11 @@ "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.11.1" + "version": "1.11.2" }, "kernelspec": { "name": "julia-1.11", - "display_name": "Julia 1.11.1", + "display_name": "Julia 1.11.2", "language": "julia" } }, diff --git a/dev/tutorials/porous_media/index.html b/dev/tutorials/porous_media/index.html index 5f8c38e9d1..c095340b9c 100644 --- a/dev/tutorials/porous_media/index.html +++ b/dev/tutorials/porous_media/index.html @@ -478,4 +478,4 @@ end; dh, ch, domains = setup_problem() -solve(dh, ch, domains);

This page was generated using Literate.jl.

+solve(dh, ch, domains);

This page was generated using Literate.jl.

diff --git a/dev/tutorials/reactive_surface.ipynb b/dev/tutorials/reactive_surface.ipynb index a615929e8d..64e6549c18 100644 --- a/dev/tutorials/reactive_surface.ipynb +++ b/dev/tutorials/reactive_surface.ipynb @@ -332,10 +332,10 @@ "text": [ "Info : Meshing 1D...\n", "Info : [ 40%] Meshing curve 2 (Circle)\n", - "Info : Done meshing 1D (Wall 9.8083e-05s, CPU 9.8e-05s)\n", + "Info : Done meshing 1D (Wall 9.3956e-05s, CPU 9.5e-05s)\n", "Info : Meshing 2D...\n", "Info : Meshing surface 1 (Sphere, Frontal-Delaunay)\n", - "Info : Done meshing 2D (Wall 0.00928318s, CPU 0.009268s)\n", + "Info : Done meshing 2D (Wall 0.00937435s, CPU 0.009358s)\n", "Info : 160 nodes 328 elements\n", "Info : Refining mesh...\n", "Info : Meshing order 2 (curvilinear on)...\n", @@ -345,8 +345,8 @@ "Info : [ 70%] Meshing surface 1 order 2\n", "Info : [ 90%] Meshing volume 1 order 2\n", "Info : Surface mesh: worst distortion = 0.970866 (0 elements in ]0, 0.2]); worst gamma = 0.433887\n", - "Info : Done meshing order 2 (Wall 0.00112904s, CPU 0.001116s)\n", - "Info : Done refining mesh (Wall 0.001496s, CPU 0.001484s)\n", + "Info : Done meshing order 2 (Wall 0.00110945s, CPU 0.001108s)\n", + "Info : Done refining mesh (Wall 0.00145114s, CPU 0.001451s)\n", "Info : Refining mesh...\n", "Info : Meshing order 2 (curvilinear on)...\n", "Info : [ 0%] Meshing curve 1 order 2\n", @@ -355,8 +355,8 @@ "Info : [ 70%] Meshing surface 1 order 2\n", "Info : [ 90%] Meshing volume 1 order 2\n", "Info : Surface mesh: worst distortion = 0.992408 (0 elements in ]0, 0.2]); worst gamma = 0.421451\n", - "Info : Done meshing order 2 (Wall 0.0043664s, CPU 0.004366s)\n", - "Info : Done refining mesh (Wall 0.005654s, CPU 0.005654s)\n", + "Info : Done meshing order 2 (Wall 0.00424228s, CPU 0.004241s)\n", + "Info : Done refining mesh (Wall 0.00555073s, CPU 0.00555s)\n", "Info : Refining mesh...\n", "Info : Meshing order 2 (curvilinear on)...\n", "Info : [ 0%] Meshing curve 1 order 2\n", @@ -365,8 +365,8 @@ "Info : [ 70%] Meshing surface 1 order 2\n", "Info : [ 90%] Meshing volume 1 order 2\n", "Info : Surface mesh: worst distortion = 0.998082 (0 elements in ]0, 0.2]); worst gamma = 0.418317\n", - "Info : Done meshing order 2 (Wall 0.016895s, CPU 0.016894s)\n", - "Info : Done refining mesh (Wall 0.0223493s, CPU 0.022349s)\n" + "Info : Done meshing order 2 (Wall 0.0162302s, CPU 0.016229s)\n", + "Info : Done refining mesh (Wall 0.0214515s, CPU 0.021445s)\n" ] } ], @@ -478,11 +478,11 @@ "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.11.1" + "version": "1.11.2" }, "kernelspec": { "name": "julia-1.11", - "display_name": "Julia 1.11.1", + "display_name": "Julia 1.11.2", "language": "julia" } }, diff --git a/dev/tutorials/reactive_surface/index.html b/dev/tutorials/reactive_surface/index.html index ddf5f326e8..ec2dda9f6c 100644 --- a/dev/tutorials/reactive_surface/index.html +++ b/dev/tutorials/reactive_surface/index.html @@ -222,10 +222,10 @@ material = GrayScottMaterial(0.00016, 0.00008, 0.06, 0.062) gray_scott_on_sphere(material, 10.0, 32000.0, 3)
Info    : Meshing 1D...
 Info    : [ 40%] Meshing curve 2 (Circle)
-Info    : Done meshing 1D (Wall 8.8214e-05s, CPU 8.9e-05s)
+Info    : Done meshing 1D (Wall 8.8836e-05s, CPU 9e-05s)
 Info    : Meshing 2D...
 Info    : Meshing surface 1 (Sphere, Frontal-Delaunay)
-Info    : Done meshing 2D (Wall 0.0090786s, CPU 0.009064s)
+Info    : Done meshing 2D (Wall 0.0091879s, CPU 0.009172s)
 Info    : 160 nodes 328 elements
 Info    : Refining mesh...
 Info    : Meshing order 2 (curvilinear on)...
@@ -235,8 +235,8 @@
 Info    : [ 70%] Meshing surface 1 order 2
 Info    : [ 90%] Meshing volume 1 order 2
 Info    : Surface mesh: worst distortion = 0.970866 (0 elements in ]0, 0.2]); worst gamma = 0.433887
-Info    : Done meshing order 2 (Wall 0.00116038s, CPU 0.00116s)
-Info    : Done refining mesh (Wall 0.0014956s, CPU 0.001495s)
+Info    : Done meshing order 2 (Wall 0.00107854s, CPU 0.001065s)
+Info    : Done refining mesh (Wall 0.00140329s, CPU 0.001385s)
 Info    : Refining mesh...
 Info    : Meshing order 2 (curvilinear on)...
 Info    : [  0%] Meshing curve 1 order 2
@@ -245,8 +245,8 @@
 Info    : [ 70%] Meshing surface 1 order 2
 Info    : [ 90%] Meshing volume 1 order 2
 Info    : Surface mesh: worst distortion = 0.992408 (0 elements in ]0, 0.2]); worst gamma = 0.421451
-Info    : Done meshing order 2 (Wall 0.00437948s, CPU 0.004366s)
-Info    : Done refining mesh (Wall 0.00567625s, CPU 0.005662s)
+Info    : Done meshing order 2 (Wall 0.0041848s, CPU 0.004182s)
+Info    : Done refining mesh (Wall 0.00546973s, CPU 0.005467s)
 Info    : Refining mesh...
 Info    : Meshing order 2 (curvilinear on)...
 Info    : [  0%] Meshing curve 1 order 2
@@ -255,8 +255,8 @@
 Info    : [ 70%] Meshing surface 1 order 2
 Info    : [ 90%] Meshing volume 1 order 2
 Info    : Surface mesh: worst distortion = 0.998082 (0 elements in ]0, 0.2]); worst gamma = 0.418317
-Info    : Done meshing order 2 (Wall 0.0165809s, CPU 0.016581s)
-Info    : Done refining mesh (Wall 0.0219264s, CPU 0.021927s)

Plain program

Here follows a version of the program without any comments. The file is also available here: reactive_surface.jl.

using Ferrite, FerriteGmsh
+Info    : Done meshing order 2 (Wall 0.0160742s, CPU 0.016073s)
+Info    : Done refining mesh (Wall 0.0211212s, CPU 0.021121s)

Plain program

Here follows a version of the program without any comments. The file is also available here: reactive_surface.jl.

using Ferrite, FerriteGmsh
 using BlockArrays, SparseArrays, LinearAlgebra, WriteVTK
 
 struct GrayScottMaterial{T}
@@ -484,4 +484,4 @@
 
 # This parametrization gives the spot pattern shown in the gif above.
 material = GrayScottMaterial(0.00016, 0.00008, 0.06, 0.062)
-    gray_scott_on_sphere(material, 10.0, 32000.0, 3)

This page was generated using Literate.jl.

+ gray_scott_on_sphere(material, 10.0, 32000.0, 3)

This page was generated using Literate.jl.

diff --git a/dev/tutorials/stokes-flow.ipynb b/dev/tutorials/stokes-flow.ipynb index 41da655822..a207699a27 100644 --- a/dev/tutorials/stokes-flow.ipynb +++ b/dev/tutorials/stokes-flow.ipynb @@ -671,11 +671,11 @@ "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.11.1" + "version": "1.11.2" }, "kernelspec": { "name": "julia-1.11", - "display_name": "Julia 1.11.1", + "display_name": "Julia 1.11.2", "language": "julia" } }, diff --git a/dev/tutorials/stokes-flow/index.html b/dev/tutorials/stokes-flow/index.html index e576e558a8..11dbce35f0 100644 --- a/dev/tutorials/stokes-flow/index.html +++ b/dev/tutorials/stokes-flow/index.html @@ -482,4 +482,4 @@ return end -main()

This page was generated using Literate.jl.

+main()

This page was generated using Literate.jl.

diff --git a/dev/tutorials/transient_heat_equation.ipynb b/dev/tutorials/transient_heat_equation.ipynb index e2aac2d6ff..1e7036414f 100644 --- a/dev/tutorials/transient_heat_equation.ipynb +++ b/dev/tutorials/transient_heat_equation.ipynb @@ -508,11 +508,11 @@ "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.11.1" + "version": "1.11.2" }, "kernelspec": { "name": "julia-1.11", - "display_name": "Julia 1.11.1", + "display_name": "Julia 1.11.2", "language": "julia" } }, diff --git a/dev/tutorials/transient_heat_equation/index.html b/dev/tutorials/transient_heat_equation/index.html index 75bac56140..5513d5997f 100644 --- a/dev/tutorials/transient_heat_equation/index.html +++ b/dev/tutorials/transient_heat_equation/index.html @@ -233,4 +233,4 @@ uₙ .= u end -vtk_save(pvd);

This page was generated using Literate.jl.

+vtk_save(pvd);

This page was generated using Literate.jl.

diff --git a/dev/tutorials/vortex-street.pvd b/dev/tutorials/vortex-street.pvd index 56cbde33d3..128b4ba77f 100755 --- a/dev/tutorials/vortex-street.pvd +++ b/dev/tutorials/vortex-street.pvd @@ -3,37 +3,37 @@ - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + +