Ferrite changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
v1.0.0 - 2024-09-30
Ferrite version 1.0 is a relatively large release, with a lot of new features, improvements, deprecations and some removals. These changes are made to make the code base more consistent and more suitable for future improvements. With this 1.0 release we are aiming for long time stability, and there is no breaking release 2.0 on the horizon.
Unfortunately this means that code written for Ferrite version 0.3 will have to be updated. All changes, with upgrade paths, are listed in the sections below. Since these sections include a lot of other information as well (new features, internal changes, ...) there is also a dedicated section about upgrading code from Ferrite 0.3 to 1.0 (see below) which include the most common changes that are required. In addition, in all cases where possible, you will be presented with a descriptive error message telling you what needs to change.
Deprecations for 1.0 will be removed during the 1.x release series. When upgrading old code it is therefore recommended to use Ferrite 1.0 as a first stepping stone since this release contain descriptive deprecation error messages that might not exist in e.g. Ferrite version 1.2.
Upgrading code from Ferrite 0.3 to 1.0
This section give a short overview of the most common required changes. More details and motivation are included in the following sections (with links to issues/pull request for more discussion).
Interpolations: remove the first parameter (the reference dimension) and use new reference shapes.
Examples:
# Linear Lagrange interpolation for a line - Lagrange{1, RefCube, 1}() + Lagrange{RefLine, 1}() # Linear Lagrange interpolation for a quadrilateral - Lagrange{2, RefCube, 1}() + Lagrange{RefQuadrilateral, 1}() # Quadratic Lagrange interpolation for a triangle - Lagrange{2, RefTetrahedron, 2}() + Lagrange{RefTriangle, 2}()
For vector valued problems it is now required to explicitly vectorize the interpolation using the new
VectorizedInterpolation
. This is required when passing the interpolation toCellValues
and when adding fields to theDofHandler
usingadd!
. In both of these places the interpolation was implicitly vectorized in Ferrite 0.3.Examples:
# Linear Lagrange interpolation for a vector problem on the triangle (vector dimension # same as the reference dimension) ip_scalar = Lagrange{RefTriangle, 1}() ip_vector = ip_scalar ^ 2 # or VectorizedInterpolation{2}(ip_scalar)
Quadrature: remove the first parameter (the reference dimension) and use new reference shapes.
Examples:
# Quadrature for a line - QuadratureRule{1, RefCube}(quadrature_order) + QuadratureRule{RefLine}(quadrature_order) # Quadrature for a quadrilateral - QuadratureRule{2, RefCube}(quadrature_order) + QuadratureRule{RefQuadrilateral}(quadrature_order) # Quadrature for a tetrahedron - QuadratureRule{3, RefTetrahedron}(quadrature_order) + QuadratureRule{RefTetrahedron}(quadrature_order)
Quadrature for face integration (FacetValues): replace
QuadratureRule{dim-1, reference_shape}(quadrature_order)
withFacetQuadratureRule{reference_shape}(quadrature_order)
.Examples:
# Quadrature for the facets of a quadrilateral - QuadratureRule{1, RefCube}(quadrature_order) + FacetQuadratureRule{RefQuadrilateral}(quadrature_order) # Quadrature for the facets of a triangle - QuadratureRule{1, RefTetrahedron}(quadrature_order) + FacetQuadratureRule{RefTriangle}(quadrature_order) # Quadrature for the facets of a hexhedron - QuadratureRule{2, RefCube}(quadrature_order) + FacetQuadratureRule{RefHexahedron}(quadrature_order)
CellValues: replace usage of
CellScalarValues
andCellVectorValues
withCellValues
. For vector valued problems the interpolation passed toCellValues
should be vectorized to aVectorizedInterpolation
(see above).Examples:
# CellValues for a scalar problem with triangle elements - qr = QuadratureRule{2, RefTetrahedron}(quadrature_order) - ip = Lagrange{2, RefTetrahedron, 1}() - cv = CellScalarValues(qr, ip) + qr = QuadratureRule{RefTriangle}(quadrature_order) + ip = Lagrange{RefTriangle, 1}() + cv = CellValues(qr, ip) # CellValues for a vector problem with hexahedronal elements - qr = QuadratureRule{3, RefCube}(quadrature_order) - ip = Lagrange{3, RefCube, 1}() - cv = CellVectorValues(qr, ip) + qr = QuadratureRule{RefHexahedron}(quadrature_order) + ip = Lagrange{RefHexahedron, 1}() ^ 3 + cv = CellValues(qr, ip)
If you use
CellScalarValues
orCellVectorValues
in method signature you must replace them withCellValues
. Note that the type parameters are different.Examples:
- function do_something(cvs::CellScalarValues, cvv::CellVectorValues) + function do_something(cvs::CellValues, cvv::CellValues)
The default geometric interpolation have changed from the function interpolation to always use linear Lagrange interpolation. If you use linear elements in the grid, and a higher order interpolation for the function you can now rely on the new default:
qr = QuadratureRule(...) - ip_function = Lagrange{2, RefTetrahedron, 2}() - ip_geometry = Lagrange{2, RefTetrahedron, 1}() - cv = CellScalarValues(qr, ip_function, ip_geometry) + ip_function = Lagrange{2, RefTetrahedron, 2}() + cv = CellValues(qr, ip_function)
and if you have quadratic (or higher order) elements in the grid you must now pass the corresponding interpolation to the constructor:
qr = QuadratureRule(...) - ip_function = Lagrange{2, RefTetrahedron, 2}() - cv = CellScalarValues(qr, ip_function) + ip_function = Lagrange{2, RefTetrahedron, 2}() + ip_geometry = Lagrange{2, RefTetrahedron, 1}() + cv = CellValues(qr, ip_function, ip_geometry)
FacetValues: replace usage of
FaceScalarValues
andFaceVectorValues
withFacetValues
. For vector valued problems the interpolation passed toFacetValues
should be vectorized to aVectorizedInterpolation
(see above). The input quadrature rule should be aFacetQuadratureRule
instead of aQuadratureRule
.Examples:
# FacetValues for a scalar problem with triangle elements - qr = QuadratureRule{1, RefTetrahedron}(quadrature_order) - ip = Lagrange{2, RefTetrahedron, 1}() - cv = FaceScalarValues(qr, ip) + qr = FacetQuadratureRule{RefTriangle}(quadrature_order) + ip = Lagrange{RefTriangle, 1}() + cv = FacetValues(qr, ip) # FaceValues for a vector problem with hexahedronal elements - qr = QuadratureRule{2, RefCube}(quadrature_order) - ip = Lagrange{3, RefCube, 1}() - cv = FaceVectorValues(qr, ip) + qr = FacetQuadratureRule{RefHexahedron}(quadrature_order) + ip = Lagrange{RefHexahedron, 1}() ^ 3 + cv = FacetValues(qr, ip)
DofHandler construction: it is now required to pass the interpolation explicitly when adding new fields using
add!
(previously it was optional, defaulting to the default interpolation of the elements in the grid). For vector-valued fields the interpolation should be vectorized, instead of passing the number of components toadd!
as an integer.Examples:
dh = DofHandler(grid) # grid with triangles # Vector field :u - add!(dh, :u, 2) + add!(dh, :u, Lagrange{RefTriangle, 1}()^2) # Scalar field :p - add!(dh, :u, 1) + add!(dh, :u, Lagrange{RefTriangle, 1}())
Boundary conditions: The entity enclosing a cell was previously called
face
, but is now denoted afacet
. When applying boundary conditions, renamegetfaceset
togetfacetset
andaddfaceset!
is nowaddfacetset!
. These sets are now described byFacetIndex
instead ofFaceIndex
. When looping over thefacets
of a cell, changenfaces
tonfacets
.Examples:
# Dirichlet boundary conditions - addfaceset!(grid, "dbc", x -> x[1] ≈ 1.0) + addfacetset!(grid, "dbc", x -> x[1] ≈ 1.0) - dbc = Dirichlet(:u, getfaceset(grid, "dbc"), Returns(0.0)) + dbc = Dirichlet(:u, getfacetset(grid, "dbc"), Returns(0.0)) # Neumann boundary conditions - for facet in 1:nfaces(cell) - if (cellid(cell), facet) ∈ getfaceset(grid, "Neumann Boundary") + for facet in 1:nfacets(cell) + if (cellid(cell), facet) ∈ getfacetset(grid, "Neumann Boundary") # ...
VTK Export: The VTK export has been changed #692.
- vtk_grid(name, dh) do vtk - vtk_point_data(vtk, dh, a) - vtk_point_data(vtk, nodal_data, "my node data") - vtk_point_data(vtk, proj, projected_data, "my projected data") - vtk_cell_data(vtk, proj, projected_data, "my projected data") + VTKGridFile(name, dh) do vtk + write_solution(vtk, dh, a) + write_node_data(vtk, nodal_data, "my node data") + write_projection(vtk, proj, projected_data, "my projected data") + write_cell_data(vtk, cell_data, "my projected data") end
When using a
paraview_collection
collection for e.g. multiple timesteps theVTKGridFile
object can be used instead of the previous type returned fromvtk_grid
.Sparsity pattern and global matrix construction: since there is now explicit support for working with the sparsity pattern before instantiating a matrix the function
create_sparsity_pattern
has been removed. To recover the old functionality that return a sparse matrix from the DofHandler directly useallocate_matrix
instead.Examples:
# Create sparse matrix from DofHandler - K = create_sparsity_pattern(dh) + K = allocate_matrix(dh) # Create condensed sparse matrix from DofHandler + ConstraintHandler - K = create_sparsity_pattern(dh, ch) + K = allocate_matrix(dh, ch)
Added
InterfaceValues
for computing jumps and averages over interfaces. (#743)InterfaceIterator
andInterfaceCache
for iterating over interfaces. (#747)FacetQuadratureRule
implementation forRefPrism
andRefPyramid
. (#779)The
DofHandler
now support selectively adding fields on sub-domains (rather than the full domain). This new functionality is included with the newSubDofHandler
struct, which, as the name suggest, is aDofHandler
for a subdomain. (#624, #667, #735)New reference shape structs
RefLine
,RefTriangle
,RefQuadrilateral
,RefTetrahedron
,RefHexahedron
, andRefPrism
have been added. These encode the reference dimension, and will thus replace the old reference shapes for which it was necessary to always pair with an explicit dimension (i.e.RefLine
replaces(RefCube, 1)
,RefTriangle
replaces(RefTetrahedron, 2)
, etc.). For writing "dimension independent code" it is possible to useFerrite.RefHypercube{dim}
andFerrite.RefSimplex{dim}
. (#679)New methods for adding entitysets that are located on the boundary of the grid:
addboundaryfacetset!
andaddboundaryvertexset!
. These work similar toaddfacetset!
andaddvertexset!
, but filters out all instances not on the boundary (this can be used to avoid accidental inclusion of internal entities in sets used for boundary conditions, for example). (#606)New interpolation
VectorizedInterpolation
which vectorizes scalar interpolations for vector-valued problems. AVectorizedInterpolation
is created from a (scalar) interpolationip
using eitherip ^ dim
orVectorizedInterpolation{dim}(ip)
. For convenience, the methodVectorizedInterpolation(ip)
vectorizes the interpolation to the reference dimension of the interpolation. (#694, #736)New (scalar) interpolation
Lagrange{RefQuadrilateral, 3}()
, i.e. third order Lagrange interpolation for 2D quadrilaterals. (#701, #731)CellValues
now support embedded elements. Specifically you can now embed elements with reference dimension 1 into spatial dimension 2 or 3, and elements with reference dimension 2 in to spatial dimension 3. (#651)CellValues
now support (vector) interpolations with dimension different from the spatial dimension. (#651)FacetQuadratureRule
have been added and should be used forFacetValues
. AFacetQuadratureRule
for integration of the facets of e.g. a triangle can be constructed byFacetQuadratureRule{RefTriangle}(order)
(similar to howQuadratureRule
is constructed). (#716)New functions
Ferrite.reference_shape_value(::Interpolation, ξ::Vec, i::Int)
andFerrite.reference_shape_gradient(::Interpolation, ξ::Vec, i::Int)
for evaluating the value/gradient of thei
th shape function of an interpolation in local reference coordinateξ
. These methods are public but not exported. (Note that these methods return the value/gradient wrt. the reference coordinateξ
, whereas the corresponding methods forCellValues
etc return the value/gradient wrt the spatial coordinatex
.) (#721)FacetIterator
andFacetCache
have been added. These work similarly toCellIterator
andCellCache
but are used to iterate over (boundary) face sets instead. These simplify boundary integrals in general, and in particular Neumann boundary conditions are more convenient to implement now that you can loop directly over the face set instead of checking all faces of a cell inside the element routine. (#495)The
ConstraintHandler
now support adding Dirichlet boundary conditions on discontinuous interpolations. (#729)collect_periodic_faces
now have a keyword argumenttol
that can be used to relax the default tolerance when necessary. (#749)VTK export now work with
QuadraticHexahedron
elements. (#714)The function
bounding_box(::AbstractGrid)
has been added. It computes the bounding box for a given grid (based on its node coordinates), and returns the minimum and maximum vertices of the bounding box. (#880)Support for working with sparsity patterns has been added. This means that Ferrite exposes the intermediate "state" between the DofHandler and the instantiated matrix as the new struct
SparsityPattern
. This make it possible to insert custom equations or couplings in the pattern before instantiating the matrix. The functioncreate_sparsity_pattern
have been removed. The new functionallocate_matrix
is instead used to instantiate the matrix. Refer to the documentation for more details. (#888)To upgrade: if you want to recover the old functionality and don't need to work with the pattern, replace any usage of
create_sparsity_pattern
withallocate_matrix
.A new function,
geometric_interpolation
, is exported, which gives the geometric interpolation for each cell type. This is equivalent to the deprecatedFerrite.default_interpolation
function. (#953)CellValues and FacetValues can now store and map second order gradients (Hessians). The number of gradients computed in CellValues/FacetValues is specified using the keyword arguments
update_gradients::Bool
(default true) andupdate_hessians::Bool
(default false) in the constructors, i.e.CellValues(...; update_hessians=true)
. (#953)L2Projector
supports projecting on grids with mixed celltypes. (#949)
Changed
It is now possible to create sparsity patterns with interface couplings, see the new function
add_interface_entries!
and the rework of sparsity pattern construction. (#710)The
AbstractCell
interface has been reworked. This change should not affect user code, but may in some cases be relevant for code parsing external mesh files. In particular, the genericCell
struct have been removed in favor of concrete cell implementations (Line
,Triangle
, ...). (#679, #712)To upgrade replace any usage of
Cell{...}(...)
with calls to the concrete implementations.The default geometric mapping in
CellValues
andFacetValues
have changed. The new default is to always useLagrange{refshape, 1}()
, i.e. linear Lagrange polynomials, for the geometric interpolation. Previously, the function interpolation was (re) used also for the geometry interpolation. (#695)To upgrade, if you relied on the previous default, simply pass the function interpolation also as the third argument (the geometric interpolation).
All interpolations are now categorized as either scalar or vector interpolations. All (previously) existing interpolations are scalar. (Scalar) interpolations must now be explicitly vectorized, using the new
VectorizedInterpolation
, when used for vector problems. (Previously implicit vectorization happened in theCellValues
constructor, and when adding fields to theDofHandler
). (#694)It is now required to explicitly pass the interpolation to the
DofHandler
when adding a new field usingadd!
. For vector fields the interpolation should be vectorized, instead of passing number of components as an integer. (#694)To upgrade don't pass the dimension as an integer, and pass the interpolation explicitly. See more details in Upgrading code from Ferrite 0.3 to 1.0.
Interpolation
s should now be constructed using the new reference shapes. Since the new reference shapes encode the reference dimension the first type parameter of interpolations have been removed. (#711) To upgrade replace e.g.Lagrange{1, RefCube, 1}()
withLagrange{RefLine, 1}()
, andLagrange{2, RefTetrahedron, 1}()
withLagrange{RefTriangle, 1}()
, etc.QuadratureRule
s should now be constructed using the new reference shapes. Since the new reference shapes encode the reference dimension the first type parameter ofQuadratureRule
have been removed. (#711, #716) To upgrade replace e.g.QuadratureRule{1, RefCube}(order)
withQuadratureRule{RefLine}(order)
, andQuadratureRule{2, RefTetrahedron}(1)
withLagrange{RefTriangle}(order)
, etc.CellScalarValues
andCellVectorValues
have been merged intoCellValues
,FaceScalarValues
andFaceVectorValues
have been merged intoFacetValues
, andPointScalarValues
andPointVectorValues
have been merged intoPointValues
. The differentiation between scalar and vector have thus been moved to the interpolation (see above). Note that previouslyCellValues
,FaceValues
, andPointValues
where abstract types, but they are now concrete implementations with different type parameters, exceptFaceValues
which is nowFacetValues
(#708) To upgrade, for scalar problems, it is enough to replaceCellScalarValues
withCellValues
,FaceScalarValues
withFacetValues
andPointScalarValues
withPointValues
, respectively. For vector problems, make sure to vectorize the interpolation (see above) and then replaceCellVectorValues
withCellValues
,FaceVectorValues
withFacetValues
, andPointVectorValues
withPointValues
.The quadrature rule passed to
FacetValues
should now be of typeFacetQuadratureRule
rather than of typeQuadratureRule
. (#716) To upgrade replace the quadrature rule passed toFacetValues
with aFacetQuadratureRule
.Checking if a face
(ele_id, local_face_id) ∈ faceset
has been previously implemented by type piracy. In order to be invariant to the underlyingSet
datatype as well as omitting type piracy, (#835) implementedisequal
andhash
forBoundaryIndex
datatypes.VTK export: Ferrite no longer extends
WriteVTK.vtk_grid
and associated functions, instead the new typeVTKGridFile
should be used instead. New methods exists for writing to aVTKGridFile
, e.g.write_solution
,write_cell_data
,write_node_data
, andwrite_projection
. See #692.Definitions: Previously,
face
andedge
referred to codimension 1 relative reference shape. In Ferrite v1,volume
,face
,edge
, andvertex
refer to 3, 2, 1, and 0 dimensional entities, andfacet
replaces the old definition offace
. No direct replacement foredges
exits. See #914 and #914. The main implications of this change areFaceIndex
->FacetIndex
(FaceIndex
still exists, but has a different meaning)FaceValues
->FacetValues
nfaces
->nfacets
(nfaces
is now an internal method with different meaning)addfaceset!
->addfacetset
getfaceset
->getfacetset
Furthermore, subtypes of
Interpolation
should now definevertexdof_indices
,edgedof_indices
,facedof_indices
,volumedof_indices
(and similar) according to these definitions.Ferrite.getdim
has been changed intoFerrite.getrefdim
for getting the dimension of the reference shape andFerrite.getspatialdim
to get the spatial dimension (of the grid). (#943)Ferrite.getfielddim(::AbstractDofHandler, args...)
has been renamed toFerrite.n_components
. (#943)The constructor for
ExclusiveTopology
only accept anAbstractGrid
as input, removing the alternative of providing aVector{<:AbstractCell}
, as knowing the spatial dimension is required for correct code paths. Furthermore, it uses a new internal data structure,ArrayOfVectorViews
, to store the neighborhood information more efficiently The datatype for the neighborhood has thus changed to a view of a vector, instead of the now removedEntityNeighborhood
container. This also applies tovertex_star_stencils
. (#974).project(::L2Projector, data, qr_rhs)
now expects data to be indexed by the cellid, as opposed to the index in the vector of cellids passed to theL2Projector
. The data may be passed as anAbstractDict{Int, <:AbstractVector}
, as an alternative toAbstractArray{<:AbstractVector}
. (#949)
Deprecated
The rarely (if ever) used methods of
function_value
,function_gradient
,function_divergence
, andfunction_curl
taking vectorized dof values as in put have been deprecated. (#698)The function
reshape_to_nodes
have been deprecated in favor ofevaluate_at_grid_nodes
. (#703)start_assemble([n::Int])
has been deprecated in favor of callingFerrite.COOAssembler()
directly (#916, #1058).start_assemble(f, K)
have been deprecated in favor of the "canonical"start_assemble(K, f)
. (#707)assemble!(assembler, dofs, fe, Ke)
have been deprecated in favor of the "canonical"assemble!(assembler, dofs, Ke, fe)
. (#1059)end_assemble
have been deprecated in favor offinish_assemble
. (#754)get_point_values
have been deprecated in favor ofevaluate_at_points
. (#754)transform!
have been deprecated in favor oftransform_coordinates!
. (#754)Ferrite.default_interpolation
has been deprecated in favor ofgeometric_interpolation
. (#953)
Removed
MixedDofHandler
+FieldHandler
have been removed in favor ofDofHandler
+SubDofHandler
. Note that the syntax has changed, and note thatSubDofHandler
is much more capable compared toFieldHandler
. Previously it was often required to pass both theMixedDofHandler
and theFieldHandler
to e.g. the assembly routine, but now it is enough to pass theSubDofHandler
since it can be used for e.g. DoF queries etc. (#624, #667, #735)Some old methods to construct the
L2Projector
have been removed after being deprecated for several releases. (#697)The option
project_to_nodes
have been removed fromproject(::L2Projector, ...)
. The returned values are now always ordered according to the projectors internalDofHandler
. (#699)The function
compute_vertex_values
have been removed. (#700)The names
getweights
,getpoints
,getcellsets
,getnodesets
,getfacesets
,getedgesets
, andgetvertexsets
have been removed from the list of exported names. (For now you can still use them by prefixingFerrite.
, e.g.Ferrite.getweights
.) (#754)The
onboundary
function (and the associatedboundary_matrix
property of theGrid
datastructure) have been removed (#924). Instead of first checkingonboundary
and then check whether a facet belong to a specific facetset, check the facetset directly. For example:- if onboundary(cell, local_face_id) && (cell_id, local_face_id) in getfacesets(grid, "traction_boundary") + if (cell_id, local_face_id) in getfacesets(grid, "traction_boundary") # integrate the "traction_boundary" boundary end
Fixed
Topology construction have been generalized to, in particular, fix construction for 1D and for wedge elements. (#641, #670, #684)
Other improvements
Documentation:
- The documentation is now structured according to the Diataxis framework. There is now also clear separation between tutorials (for teaching) and code gallery (for showing off). (#737, #756)
- New section in the developer documentation that describes the (new) reference shapes and their numbering scheme. (#688)
Performance:
Ferrite.transform!(grid, f)
(for transforming the node coordinates in thegrid
according to a functionf
) is now faster and allocates less. (#675)- Slight performance improvement in construction of
PointEvalHandler
(faster reverse coordinate lookup). (#719) - Various performance improvements to topology construction. (#753, #759)
Internal improvements:
- The dof distribution interface have been updated to support higher order elements (future work). (#627, #732, #733)
- The
AbstractGrid
andAbstractDofHandler
interfaces are now used more consistently internally. This will help with the implementation of distributed grids and DofHandlers. (#655) - VTK export now uses the (geometric) interpolation directly when evaluating the finite element field instead of trying to work backwards how DoFs map to nodes. (#703)
- Improved bounds checking in
assemble!
. (#706) - Internal methods
Ferrite.value
andFerrite.derivative
for computing the value/gradient of all shape functions have been removed. (#720) Ferrite.create_incidence_matrix
now work with anyAbstractGrid
(not justGrid
). (#726)
v0.3.14 - 2023-04-03
Added
- Support reordering dofs of a
MixedDofHandler
by the built-in orderingsFieldWise
andComponentWise
. This includes support for reordering dofs of fields on subdomains. (#645) - Support specifying the coupling between fields in a
MixedDofHandler
when creating the sparsity pattern. (#650) - Support Metis dof reordering with coupling information for
MixedDofHandler
. (#650) - Pretty printing for
MixedDofHandler
andL2Projector
. (#465)
Other improvements
- The
MixedDofHandler
have gone through a performance review (see #629) and now performs the same asDofHandler
. This was part of the push to merge the two DoF handlers. SinceMixedDofHandler
is strictly more flexible, and now equally performant, it will replaceDofHandler
in the next breaking release. (#637, #639, #642, #643, #656, #660)
Internal changes
Changes listed here should not affect regular usage, but listed here in case you have been poking into Ferrite internals:
Ferrite.ndim(dh, fieldname)
has been removed, useFerrite.getfielddim(dh, fieldname)
instead. (#658)Ferrite.nfields(dh)
has been removed, uselength(Ferrite.getfieldnames(dh))
instead. (#444, #653)getfielddims(::FieldHandler)
andgetfieldinterpolations(::FieldHandler)
have been removed (#647, #659)
v0.3.13 - 2023-03-23
Added
- Support for classical trilinear and triquadratic wedge elements. (#581)
- Symmetric quadrature rules up to order 10 for prismatic elements. (#581)
- Finer granulation of dof distribution, allowing to distribute different amounts of dofs per entity. (#581)
Fixed
- Dof distribution for embedded elements. (#581)
- Improve numerical accuracy in shape function evaluation for the
Lagrange{2,Tetrahedron,(3|4|5)}
interpolations. (#582, #633)
Other improvements
- Documentation:
- Performance:
Internal changes
- To clarify the dof management
vertices(ip)
,edges(ip)
andfaces(ip)
has been deprecated in favor ofvertexdof_indices(ip)
,edgedof_indices(ip)
andfacedof_indices(ip)
. (#581) - Duplicate grid representation has been removed from the
MixedDofHandler
. (#577)
v0.3.12 - 2023-02-28
Added
- Added a basic
show
method for assemblers. (#598)
Fixed
- Fix an issue in constraint application of
Symmetric
-wrapped sparse matrices (i.e. obtained fromcreate_symmatric_sparsity_pattern
). In particular,apply!(K::Symmetric, f, ch)
would incorrectly modifyf
if any of the constraints were inhomogeneous. (#592) - Properly disable the Metis extension on Julia 1.9 instead of causing precompilation errors. (#588)
- Fix adding Dirichlet boundary conditions on nodes when using MixedDofHandler. (#593, #594)
- Fix accidentally slow implementation of
show
forGrid
s. (#599) - Fixes to topology functionality. (#453, #518, #455)
- Fix grid coloring for cell sets with 0 or 1 cells. (#600)
Other improvements
- Documentation improvements:
v0.3.11 - 2023-01-17
Added
- Metis.jl extension for fill-reducing DoF permutation. This uses Julias new package extension mechanism (requires Julia 1.10) to support a new DoF renumbering order
DofOrder.Ext{Metis}()
that can be passed torenumber!
to renumber DoFs using the Metis.jl library. (#393, #549) - BlockArrays.jl extension for creating a globally blocked system matrix.
create_sparsity_pattern(BlockMatrix, dh, ch; kwargs...)
return a matrix that is blocked by field (requires DoFs to be (re)numbered by field, i.e.renumber!(dh, DofOrder.FieldWise())
). For custom blocking it is possible to pass an uninitializedBlockMatrix
with the correct block sizes (seeBlockArrays.jl
docs). This functionality is useful for e.g. special solvers where individual blocks need to be extracted. Requires Julia version 1.9 or above. (#567) - New function
apply_analytical!
for setting the values of the degrees of freedom for a specific field according to a spatial functionf(x)
. (#532) - New cache struct
CellCache
to be used when iterating over the cells in a grid or DoF handler.CellCache
caches nodes, coordinates, and DoFs, for the cell. The cachecc
can be re-initialized for a new cell indexci
by callingreinit!(cc, ci)
. This can be used as an alternative toCellIterator
when more control over which element to loop over is needed. See documentation forCellCache
for more information. (#546) - It is now possible to create the sparsity pattern without constrained entries (they will be zeroed out later anyway) by passing
keep_constrained=false
tocreate_sparsity_pattern
. This naturally only works together with local condensation of constraints since there won't be space allocated in the global matrix for the full (i.e. "non-condensed") element matrix. Creating the matrix without constrained entries reduces the memory footprint, but unless a significant amount of DoFs are constrained (e.g. high mesh resolution at a boundary) the savings are negligible. (#539)
Changed
ConstraintHandler
:update!
is now called implicitly inclose!
. This was easy to miss, and somewhat of a strange requirement when solving problems without time stepping. (#459)- The function for computing the inhomogeneity in a
Dirichlet
constraint can now be specified as eitherf(x)
orf(x, t)
, wherex
is the spatial coordinate andt
the time. (#459) - The elements of a
CellIterator
are nowCellCache
instead of the iterator itself, which was confusing in some cases. This change does not affect typical user code. (#546)
Deprecated
- Adding fields to a DoF handler with
push!(dh, ...)
has been deprecated in favor ofadd!(dh, ...)
. This is to make it consistent with how constraints are added to a constraint handler. (#578)
Fixed
- Fix
shape_value
for the linear, discontinuous Lagrange interpolation. (#553) - Fix
reference_coordinate
dispatch for discontinuous Lagrange interpolations. (#559) - Fix
show(::Grid)
for custom cell types. (#570) - Fix
apply_zero!(Δa, ch)
when using inhomogeneous affine constraints (#575)
Other improvements
- Internal changes defining a new global matrix/vector "interface". These changes make it easy to enable more array types (e.g.
BlockMatrix
support added in this release) and solvers in the future. (#562, #571) - Performance improvements:
- Reduced time and memory allocations for global sparse matrix creation (Julia >= 1.10). (#563)
- Documentation improvements:
v0.3.10 - 2022-12-11
Added
- New functions
apply_local!
andapply_assemble!
for applying constraints locally on the element level before assembling to the global system. (#528) - New functionality to renumber DoFs by fields or by components. This is useful when you need the global matrix to be blocked. (#378, #545)
- Functionality to renumber DoFs in DofHandler and ConstraintHandler simultaneously:
renumber!(dh::DofHandler, ch::ConstraintHandler, order)
. Previously renumbering had to be done before creating the ConstraintHandler since otherwise DoF numbers would be inconsistent. However, this was inconvenient in cases where the constraints impact the new DoF order permutation. (#542) - The coupling between fields can now be specified when creating the global matrix with
create_sparsity_pattern
by passing aMatrix{Bool}
. For example, in a problem with unknowns(u, p)
and corresponding test functions(v, q)
, if there is no coupling betweenp
andq
it is unnecessary to allocate entries in the global matrix corresponding to these DoFs. This can now be communicated tocreate_sparsity_pattern
by passing the coupling matrix[true true; true false]
in the keyword argumentcoupling
. (#544)
Changed
- Runtime and allocations for application of boundary conditions in
apply!
andapply_zero!
have been improved. As a result, thestrategy
keyword argument is obsolete and thus ignored. (#489) - The internal representation of
Dirichlet
boundary conditions andAffineConstraint
s in theConstraintHandler
have been unified. As a result, conflicting constraints on DoFs are handled more consistently: the constraint added last to theConstraintHandler
now always override any previous constraints. Conflicting constraints could previously cause problems when a DoF where prescribed by bothDirichlet
andAffineConstraint
. (#529) - Entries in local matrix/vector are now ignored in the assembly procedure. This allows, for example, using a dense local matrix
[a b; c d]
even if no entries exist in the global matrix for thed
block, i.e. in[A B; C D]
theD
block is zero, and these global entries might not exist in the sparse matrix. (Such sparsity patterns can now be created bycreate_sparsity_pattern
, see #544.) (#543)
Fixed
- Fix affine constraints with prescribed DoFs in the right-hand-side. In particular, DoFs that are prescribed by just an inhomogeneity are now handled correctly, and nested affine constraints now give an error instead of silently giving the wrong result. (#530, #535)
- Fixed internal inconsistency in edge ordering for 2nd order RefTetrahedron and RefCube. (#520, #523)
Other improvements
- Performance improvements:
- Documentation improvements:
- Unification of
create_sparsity_pattern
methods to remove code duplication betweenDofHandler
andMixedDofHandler
. (#538, #540)
v0.3.9 - 2022-10-19
Added
- New higher order function interpolations for triangles (
Lagrange{2,RefTetrahedron,3}
,Lagrange{2,RefTetrahedron,4}
, andLagrange{2,RefTetrahedron,5}
). (#482, #512) - New Gaussian quadrature formula for triangles up to order 15. (#514)
- Add debug mode for working with Ferrite internals. (#524)
Changed
- The default components to constrain in
Dirichlet
andPeriodicDirichlet
have changed from component 1 to all components of the field. For scalar problems this has no effect. (#506, #509)
v0.3.8 - 2022-10-05
Added
- Ferrite.jl now has a logo! (#464)
- New keyword argument
search_nneighbors::Int
inPointEvalHandler
for specifying how many neighboring elements to consider in the kNN search. The default is still 3 (usually sufficient). (#466) - The IJV-assembler now support assembling non-square matrices. (#471)
- Periodic boundary conditions have been reworked and generalized. It now supports arbitrary relations between the mirror and image boundaries (e.g. not only translations in x/y/z direction). (#478, #481, #496, #501)
Fixed
- Fix
PointEvalHandler
when the first point is missing. (#466) - Fix the ordering of nodes on the face for
(Quadratic)Tetrahedron
cells. (#475)
Other improvements
- Many improvements to the documentation. (#467, #473, #487, #494, #500)
- Improved error messages in
reinit!
when number of geometric base functions and number of element coordinates mismatch. (#469) - Remove some unnecessary function parametrizations. (#503)
- Remove some unnecessary allocations in grid coloring. (#505)
- More efficient way of creating the sparsity pattern when using
AffineConstraints
and/orPeriodicDirichlet
. (#436)
v0.3.7 - 2022-07-05
Fixed
- Fix tests for newer version of WriteVTK (no functional change). (#462)
Other improvements
- Various improvements to the heat equation example and the hyperelasticity example in the documentation. (#460, #461)
v0.3.6 - 2022-06-30
Fixed
- Fix a bug with
L2Projection
of mixed grid. (#456)
Other improvements
- Expanded manual section of Dirichlet BCs. (#458)
v0.3.5 - 2022-05-30
Added
- Functionality for querying information about the grid topology (e.g. neighboring cells, boundaries, ...). (#363)
Fixed
- Fix application of boundary conditions when combining RHSData and affine constraints. (#431)
v0.3.4 - 2022-02-25
Added
- Affine (linear) constraints between degrees-of-freedom. (#401)
- Periodic Dirichlet boundary conditions. (#418)
- Evaluation of arbitrary quantities in FE space. (#425)
Changed
- Interpolation(s) and the quadrature rule are now stored as part of the
CellValues
structs (cv.func_interp
,cv.geo_interp
, andcv.qr
). (#428)
v0.3.3 - 2022-02-04
Changed
v0.3.2 - 2022-01-18
Added
- Support for new interpolation types:
DiscontinuousLagrange
,BubbleEnrichedLagrange
, andCrouzeixRaviart
. (#352, #392)
Changed
- Julia version 1.0 is no longer supported for Ferrite versions >= 0.3.2. Use Julia version >= 1.6. (#385)
- Quadrature data for L2 projection can now be given as a matrix of size "number of elements" x "number of quadrature points per element". (#386)
- Projected values from L2 projection can now be exported directly to VTK. (#390)
- Grid coloring can now act on a subset of cells. (#402)
- Various functions related to cell values now use traits to make it easier to extend and reuse functionality in external code. (#404)
Fixed
- Exporting tensors to VTK now use correct names for the components. (#406)