scikit-fem is a pure Python 3.9+ library for performing finite element
assembly. Its main
purpose is the transformation of bilinear forms into sparse matrices and linear
forms into vectors.
The library
- has minimal dependencies
- contains no compiled code
- supports one-dimensional, triangular, quadrilateral, tetrahedral and hexahedral finite elements
- includes special elements such as Raviart-Thomas, Nédélec, MINI, Crouzeix-Raviart, Argyris, ...
If you use the library in your research, you can cite the following article:
@article{skfem2020,
doi = {10.21105/joss.02369},
year = {2020},
volume = {5},
number = {52},
pages = {2369},
author = {Tom Gustafsson and G. D. McBain},
title = {scikit-fem: A {P}ython package for finite element assembly},
journal = {Journal of Open Source Software}
}
The most recent release can be installed simply by
pip install scikit-fem[all]
Remove [all] to not install the optional dependencies meshio for mesh
input/output, and matplotlib for creating simple visualizations.
The minimal dependencies are numpy and scipy.
Some submodules require other optional dependencies: skfem.autodiff requires jax and jaxlib, skfem.supermeshing requires shapely.
You can also try the library in browser through Google Colab.
Solve the Poisson problem (see also ex01.py):
from skfem import *
from skfem.helpers import dot, grad
# create the mesh
mesh = MeshTri().refined(4)
# or, with your own points and elements:
# mesh = MeshTri(points, elements)
basis = Basis(mesh, ElementTriP1())
@BilinearForm
def laplace(u, v, _):
return dot(grad(u), grad(v))
@LinearForm
def rhs(v, _):
return 1. * v
A = laplace.assemble(basis)
b = rhs.assemble(basis)
# Dirichlet boundary conditions
A, b = enforce(A, b, D=mesh.boundary_nodes())
# solve the linear system
x = solve(A, b)
# plot using matplotlib
mesh.plot(x, shading='gouraud', colorbar=True).show()
# or, save to external file:
# mesh.save('output.vtk', point_data={'solution': x})Meshes can be initialized manually, loaded from external files using meshio, or created with the help of special constructors:
import numpy as np
from skfem import MeshLine, MeshTri, MeshTet
mesh = MeshLine(np.array([0., .5, 1.]))
mesh = MeshTri(
np.array([[0., 0.],
[1., 0.],
[0., 1.]]).T,
np.array([[0, 1, 2]]).T,
)
mesh = MeshTri.load("docs/examples/meshes/square.msh") # requires meshio
mesh = MeshTet.init_tensor(*((np.linspace(0, 1, 60),) * 3))We support many common finite elements. Below the stiffness matrix is assembled using second-order tetrahedra:
from skfem import Basis, ElementTetP2
basis = Basis(mesh, ElementTetP2()) # quadratic tetrahedron
A = laplace.assemble(basis) # type: scipy.sparse.csr_matrixMore examples can be found in the gallery.
The following benchmark (docs/examples/performance.py) demonstrates the time
spent on finite element assembly in comparison to the time spent on linear
solve. The given numbers were calculated using Macbook Pro M2 laptop.
Note that the timings are only illustrative as they depend on, e.g., the
type of element used, the number of quadrature points used, the type of linear
solver, and the complexity of the forms. This benchmark solves the Laplace
equation using linear tetrahedral elements and the default direct sparse solver
of scipy.sparse.linalg.spsolve.
| Degrees-of-freedom | Assembly (s) | Linear solve (s) |
|---|---|---|
| 64 | 0.00633 | 0.00159 |
| 125 | 0.00275 | 0.00092 |
| 216 | 0.00334 | 0.00068 |
| 512 | 0.00593 | 0.00100 |
| 1000 | 0.00823 | 0.00182 |
| 1728 | 0.01239 | 0.00374 |
| 4096 | 0.02679 | 0.07657 |
| 8000 | 0.05288 | 0.33537 |
| 15625 | 0.11714 | 1.81805 |
| 32768 | 0.26042 | 11.48140 |
| 64000 | 0.54313 | 62.69441 |
| 125000 | 1.10499 | nan |
| 262144 | 2.72761 | nan |
| 512000 | 5.61395 | nan |
| 1030301 | 12.58563 | nan |
The conclusion is that in many cases the
time spent on linear solve will significantly dominate
and a Python package such as scikit-fem
can be fast enough for assembling
the finite element matrices.
The project is documented using Sphinx under docs/.
Built version can be found from Read the Docs.
Here are direct links to additional resources:
If you encounter an issue you can use GitHub issue tracker. If you cannot find help from the documentation, you can use the GitHub Discussions to ask questions. Try to provide a snippet of code which fails and include also the version of the library you are using. The version can be found as follows:
import skfem; print(skfem.__version__)The minimal dependencies for installing scikit-fem are
numpy and scipy. In addition,
many
examples use
matplotlib for visualization and
meshio for loading/saving different mesh
file formats. Some examples demonstrate the use of other external packages;
see requirements.txt for a list of test dependencies.
The tests are run by GitHub Actions. The Makefile in the repository root has
targets for running the testing container locally using docker. For example,
make test_py38 runs the tests using py38 branch from
kinnala/scikit-fem-docker-action.
The releases are tested in
kinnala/scikit-fem-release-tests.
The contents of skfem/ and the PyPI package scikit-fem are licensed under
the 3-clause BSD license. Some examples under docs/examples/ or snippets
in the documentation may have a different license.
This project was started while working under a grant from the Finnish Cultural Foundation. Versions 2.0.0+ were prepared while working in a project funded by Academy of Finland (decisions nr. 324611 and 338341). The approach used in the finite element assembly has been inspired by the work of A. Hannukainen and M. Juntunen.
We are happy to welcome any contributions to the library. Reasonable projects for first timers include:
- Reporting a bug
- Writing an example
- Improving the tests
- Suggesting improvements in the documentation.
By contributing code to scikit-fem, you are agreeing to release it under BSD-3-Clause, see LICENSE.md.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning with respect to documented and/or tested features.
- Added: Support for Python 3.13.
- Added:
skfem.autodiffmodule for linearizing nonlinear variational forms and solving them using the Newton method. This is done with the help of the new decoratorNonlinearForm. There are currently two examples using this functionality: ex45 and ex51. The use ofskfem.autodiffrequires the optional dependency JAX. - Added: A corresponding set of helper functions
skfem.autodiff.helpersfor defining nonlinear variational forms. - Removed: Support for Python 3.8.
- Fixed:
Mesh.loadreturned incorrect orientation for tagged holes
- Fixed:
Mesh.loadreturned incorrect orientation for some Gmsh meshes with tagged interfaces
- Fixed:
Mesh.p2ereturned incorrect incidence - Fixed:
InteriorFacetBasis.get_dofsdid not return all edge DOFs for 3D elements - Added: The lowest order, one point integration rule for tetrahedral elements
- Added:
asmwill now wrap functions with three arguments usingBilinearForm, functions with two arguments usingLinearForm, etc. - Changed: Initializing
BasisforElementTetP0without specifyingintorderorquadraturewill now automatically fall back to a one point integration rule - Changed: Default tags (left, right, top, ...) are no more
added automatically during mesh initialization, as a workaround you
can add them explicitly by calling
mesh = mesh.with_defaults() - Changed: All indices within the library are now using
np.int32for around 10% boost in performance and the corresponding reduction in memory usage for larger meshes - theoretically, the largest possible tetrahedral tensor product mesh is now roughly 550 ** 3 = 166 M vertices and 993 M elements, without the facet indexing wrapping over 2 ** 32
- Fixed: Tests now pass with
numpy==2.0rc1 - Fixed:
MappingAffinenow uses lazy evaluation also for element mappings, in addition to boundary mappings - Fixed:
MeshTet.init_tensoruses significantly less memory for large meshes - Fixed:
Mesh.loaduses less memory when loading and matching tags - Added:
Basishas new optionaldisable_doflocskwarg which can be set toTrueto avoid computingBasis.doflocs, to reduce memory usage
- Fixed:
ElementVectornow works also for split_bases/split_indices in casemesh.dim() != elem.dim
- Removed: Python 3.7 support
- Removed:
MappingMortarandMortarFacetBasisin favor ofskfem.supermeshing - Deprecated:
skfem.visuals.glvis; current version is broken and no replacement is being planned - Added: Python 3.12 support
- Added:
Mesh.loadsupports new keyword argumentsignore_orientation=Trueandignore_interior_facets=Truewhich will both speed up the loading of larger three-dimensional meshes by ignoring facet orientation and all tags not on the boundary, respectively. - Added:
skfem.supermeshing(requiresshapely>=2) for creating quadrature rules for interpolating between two 1D or 2D meshes. - Added:
Mesh.remove_unused_nodes - Added:
Mesh.remove_duplicate_nodes - Added:
Mesh.remove_elementsnow supports passing any subdomain reference throughMesh.normalize_elements; subdomains and boundaries are also properly preserved - Fixed:
MeshTetuniform refine was reindexing subdomains incorrectly - Fixed:
MeshDG.drawdid not work; now callsBasis.drawwhich works for any mesh topology - Fixed:
FacetBasisnow works withMeshTri2,MeshQuad2,MeshTet2andMeshHex2 - Fixed:
ElementGlobalnow uses outward normals to initialize DOFs on boundary facets
- Added:
ElementTriHHJ0andElementTriHHJ1matrix finite elements for implementing the Hellan-Hermann-Johnson mixed method (seeex48.py) - Added:
ElementHexSkeleton0, piecewise constant element on the skeleton of a hexahedral mesh - Added:
ElementHexC1, C1-continuous hexahedral element - Added:
Mesh.restrictnow preserves subdomains and boundaries - Added:
skfem.utils.mpcfor setting multipoint constraints - Added:
Basis.get_dofsnow supports fetching DOFs at specific nodes through kwargnodes - Added:
DofsView.sortfor sorting a set of DOFs returned byBasis.get_dofs - Added:
CellBasis.with_elementsas a shortcut for initiating a new Basis with subset of elements - Added:
Mesh.refinednow preserves subdomains in adaptive mesh refinement - Fixed:
Mesh.refinedused to modify the element connectivity of the original mesh
- Removed: The deprecated
Basis.find_dofsmethod, seeBasis.get_dofsfor a replacement - Added: Renamed
ElementTetN0toElementTriN1and added alias for backwards compatibility - Added:
ElementQuadN1, first order H(curl) conforming quadrilateral element - Added:
ElementTriN1, first order H(curl) conforming triangle element - Added:
ElementTriN2, second order H(curl) conforming triangle element - Added:
ElementTetSkeletonP0, extension ofElementTriSkeletonP0to tetrahedral meshes - Added:
Mesh.restrictwhich returns a new mesh given a subset of elements or subdomain - Added:
Mesh.tracewhich turns facets into a trace mesh - Added:
skfem.utils.bmat, a variant ofscipy.sparse.bmatwhich adds the indices of the different blocks as an attributeout.blocks - Added: Plane strain to plane stress mapping under
skfem.models.elasticity - Added: Various methods such as
Basis.interpolateandBasis.projectnow support specifyingdtypeand using complex fields - Fixed: Python 3.11
- Fixed:
Basis.intepolatedid not work properly withElementCompositewhen the basis was defined only for a subset of elements - Fixed:
Basis.splitworked incorrectly forElementVectorand multiple DOFs of same type - Fixed: Caching of
ElementQuadPbasis for reused quadrature points did not work correctly - Deprecated:
MappingMortarandMortarFacetBasisin favor of plainFacetBasisand the upcomingskfem.experimental.supermeshing(seeex04.py)
- Fixed: Updated changelog was missing.
- Changed: Removed the optimization of using
DiscreteField.is_zeroin the helpers to skip the evaluation of zero components inElementCompositeto improve type stability with respect to the size of the underlying numpy arrays; this is technically a backwards incompatible change and might affect self-created helper functions - Deprecated:
FacetBasis.tracein favor ofBasis.interpolatorandBasis.project - Added: Output of
Basis.interpolatorsupports trailing axes; can be now passed toBasis.projectfor (inexact) interpolation between meshes - Added: Renamed
ElementTriRT0toElementTriRT1and added alias for backwards compatibility - Added: Renamed
ElementTetRT0toElementTetRT1and added alias for backwards compatibility - Added: Renamed
ElementQuadRT0toElementQuadRT1and added alias for backwards compatibility - Added:
ElementTriRT2, the second order Raviart-Thomas element - Added:
ElementHexRT1, the first order Raviart-Thomas element for hexahedral meshes - Added:
Basis.projectnow better supportsElementComposite - Added:
solver_iter_cg, a simple pure Python conjugate gradient solver for environments that do not have sparse solver libraries (e.g., Pyodide) - Added:
ElementTriP2BandElementTriP1B, new aliases forElementTriMiniandElementTriCCR - Added:
ElementTriP1GandElementTriP2G, variants ofElementTriP1andElementTriP2usingElementGlobalso that second derivatives are available (useful, e.g., for stabilized methods and the Stokes problem) - Added:
Basis.plot3, a wrapper toskfem.visuals.*.plot3 - Fixed: Calculation of size in
Basis.__repr__was slow and incorrect - Fixed: Subclasses of
ElementHdivdid not work together withFacetBasis
- Changed:
DiscreteFieldis now a subclass ofndarrayinstead ofNamedTupleand, consequently, the components ofDiscreteFieldcannot no more be indexed inside forms likeu[1](useu.gradinstead) - Changed: Writing
w['u']andw.uinside the form definition is now equivalent (previouslyw.u == w['u'].value) - Changed:
Mesh.drawnow usesmatplotlibby default, callingMesh.draw("vedo")usesvedo - Changed:
skfem.visuals.matplotlibnow usesjetas the default colormap - Changed:
BoundaryFacetBasisis now an alias ofFacetBasisinstead of other way around - Deprecated:
DiscreteField.valueremains for backwards-compatibility but is now deprecated and can be dropped - Added:
Mesh.plot, a wrapper toskfem.visuals.*.plot - Added:
Basis.plot, a wrapper toskfem.visuals.*.plot - Added:
Basis.refinterpnow supports vectorial fields - Added:
skfem.visuals.matplotlib.plotnow has a basic quiver plot for vector fields - Added:
Mesh.facets_aroundwhich constructs a set of facets around a subdomain - Added:
Mesh.saveandloadnow preserve the orientation of boundaries and interfaces - Added:
OrientedBoundarywhich is a subclass ofndarrayfor facet index arrays with the orientation information (0 or 1 per facet) available asOrientedBoundary.ori - Added:
FacetBasiswill use the facet orientations (if present) to calculate traces and normal vectors - Added:
skfem.visuals.matplotlib.drawwill visualize the orientations ifboundaries=Trueis given - Added:
Mesh.facets_satisfyingallows specifying the keyword argumentnormalfor orienting the resulting interface - Added:
FacetBasisconstructor now has the keyword argumentsidewhich allows changing the side of the facet used to calculate the basis function values and gradients - Added:
Basis.boundarymethod to quickly initialize the correspondingFacetBasis - Fixed: Improvements to backwards compatibility in
asm/assemblekeyword arguments - Fixed: Save format issue with meshio 5.3.0+
- Fixed:
CellBasisdid not properly supportelementsargument - Fixed:
Basis.interpolatedid not properly interpolate all components ofElementComposite
- Added:
Basis.project, a more general and easy to use alternative forprojection - Added:
BasisandFacetBasiskwargselementsandfacetscan now be a string refering to subdomain and boundary tags - Added:
ElementQuadRT0, lowest-order quadrilateral Raviart-Thomas element - Fixed:
Functionalreturned only the first component for forms with non-scalar output
- Added:
skfem.helpers.mulfor matrix multiplication - Added:
Basis.splitwill now also splitElementVectorinto its components - Fixed:
ElementDGwas not included in the wildcard import - Fixed: Automatic visualization of
MeshTri2andMeshQuad2in Jupyter notebooks raised exception
- Changed:
meshiois now an optional dependency - Changed:
ElementCompositeusesDiscreteField()to represent zero - Added: Support more argument types in
Basis.get_dofs - Added: Version information in
skfem.__version__ - Added: Preserve
Mesh.boundariesduring uniform refinement ofMeshLine1,MeshTri1andMeshQuad1 - Fixed: Refinement of quadratic meshes will now fall back to the refinement algorithm of first-order meshes instead of crashing
- Fixed: Edge cases in the adaptive refine of
MeshTet1that failed to produce a valid mesh - Deprecated:
Basis.find_dofsin favor ofBasis.get_dofs - Deprecated: Merging
DofsViewobjects via+and|because of surprising behavior in some edge cases
- Fixed:
MappingIsoparametriccan now be pickled
- Added:
Mesh.save/Mesh.loadnow exports/importsMesh.subdomainsandMesh.boundaries - Added:
Mesh.loadnow optionally writes any mesh data to a list passed via the keyword argumentout, e.g.,out=datawheredata = ['point_data'] - Added:
Mesh.load(andskfem.io.meshio.from_file) now supports the additional keyword argumentforce_meshio_typefor loading mesh files that have multiple element types written in the same file, one element type at a time - Added:
asmwill now accept a list of bases, assemble the same form using all of the bases and sum the result (useful for jump terms and mixed meshes, seeex41.py - Added:
Mesh.with_boundariesnow allows the definition of internal boundaries/interfaces via the flagboundaries_only=False - Added:
MeshTri1DG,MeshQuad1DG,MeshHex1DG,MeshLine1DG; new mesh types for describing meshes with a discontinuous topology, e.g., periodic meshes (seeex42.py) - Added:
ElementHexDGfor transforming hexahedral H1 elements to DG/L2 elements. - Added:
ElementTriP1DG,ElementQuad1DG,ElementHex1DG,ElementLineP1DG; shorthands forElementTriDG(ElementTriP1())etc. - Added:
ElementTriSkeletonP0andElementTriSkeletonP1for defining Lagrange multipliers on the skeleton mesh (seeex40.py) - Added:
TrilinearFormfor assembling a sparse 3-tensor, e.g., when dealing with unknown material data - Added:
MeshTri.orientedfor CCW oriented triangular meshes which can be useful for debugging or interfacing to external tools - Added: partial support for
MeshWedge1andElementWedge1, the lowest order wedge mesh and element - Added:
ElementTriP3, cubic triangular Lagrange element - Added:
ElementTriP4, quartic triangular Lagrange element - Added:
ElementTri15ParamPlate, 15-parameter nonconforming triangular element for plates - Added:
ElementTriBDM1, the lowest order Brezzi-Douglas-Marini element - Added:
Mesh.draw().show()will now visualize any mesh interactively (requires vedo) - Added: Adaptive refinement for
MeshTet1 - Fixed:
MappingIsoparametricis now about 2x faster for large meshes thanks to additional caching - Fixed:
MeshHex2.savedid not work properly - Fixed:
Mesh.loadignores unparseablecell_setsinserted bymeshioin MSH 4.1 - Changed:
Meshstring representation is now more informative - Changed:
Form.assembleno more allows keyword arguments withlistordicttype: from now on onlyDiscreteFieldor 1d/2dndarrayobjects are allowed and 1dndarrayis passed automatically toBasis.interpolatefor convenience - Changed:
MeshLineis now a function which initializesMeshLine1and not an alias toMeshLine1 - Changed:
FacetBasisis now a shorthand forBoundaryFacetBasisand no longer initializesInteriorFacetBasisorMortarFacetBasisif the keyword argumentsideis passed to the constructor - Removed: the deprecated
Mesh.define_boundarymethod
- Added:
ElementTriCCRandElementTetCCR, conforming Crouzeix-Raviart finite elements - Fixed:
Mesh.mirroredreturned a wrong mesh when a point other than the origin was used - Fixed:
MeshLineconstructor accepted only numpy arrays and not plain Python lists - Fixed:
Mesh.element_finder(andCellBasis.probes,CellBasis.interpolator) was not working properly for a small number of elements (<5) or a large number of input points (>1000) - Fixed:
MeshTetandMeshTri.element_finderare now more robust against degenerate elements - Fixed:
Mesh.element_finder(andCellBasis.probes,CellBasis.interpolator) raises exception if the query point is outside of the domain
- Added:
Basis, a shorthand forCellBasis - Added:
CellBasis, a new preferred name forInteriorBasis - Added:
BoundaryFacetBasis, a new preferred name forExteriorFacetBasis - Added:
skfem.utils.penalize, an alternative tocondenseandenforcefor essential boundary conditions - Added:
InteriorBasis.point_source, withex38 - Added:
ElementTetDG, similar toElementTriDGfor tetrahedral meshes - Fixed:
MeshLine1.element_finder
- Added: Completely rewritten
Meshbase class which is "immutable" and usesElementclasses to define the ordering of nodes; better support for high-order and other more general mesh types in the future - Added: New quadratic mesh types:
MeshTri2,MeshQuad2,MeshTet2andMeshHex2 - Added:
InteriorBasis.probes; likeInteriorBasis.interpolatorbut returns a matrix that operates on solution vectors to interpolate them at the given points - Added: More overloads for
DiscreteField, e.g., multiplication, summation and subtraction are now explicitly supported inside the form definitions - Added:
MeshHex.to_meshtetfor splitting hexahedra into tetrahedra - Added:
MeshHex.element_finderfor interpolating finite element solutions on hexahedral meshes viaInteriorBasis.interpolator - Added:
Mesh.with_boundaries, a functional replacement toMesh.define_boundary, i.e. defining boundaries via Boolean lambda function - Added:
Mesh.with_subdomainsfor defining subdomains via Boolean lambda function - Added:
skfem.utils.projection, a replacement ofskfem.utils.projectwith a different, more intuitive order of arguments - Added:
skfem.utils.enforcefor setting essential boundary conditions by changing matrix rows to zero and diagonals to one. - Deprecated:
skfem.utils.projectin favor ofskfem.utils.projection - Deprecated:
Mesh.define_boundaryin favor ofMesh.with_boundaries - Removed:
Mesh.{refine,scale,translate}; the replacements areMesh.{refined,scaled,translated} - Removed:
skfem.models.helpers; available asskfem.helpers - Removed:
DiscreteField.{f,df,ddf,hod}; available asDiscreteField.{value,grad,hess,grad3,...} - Removed: Python 3.6 support
- Removed:
skfem.utils.L2_projection - Removed:
skfem.utils.derivative - Changed:
Mesh.refinedno more attempts to fix the indexing ofMesh.boundariesafter refine - Changed:
skfem.utils.solvenow usesscipy.sparse.eigsinstead ofscipy.sparse.eigshby default; the old behavior can be retained by explicitly passingsolver=solver_scipy_eigs_sym() - Fixed: High memory usage in
skfem.visuals.matplotlibrelated to 1D plotting
- Deprecated:
sidekeyword argument toFacetBasisin favor of the more explicitInteriorFacetBasisandMortarFacetBasis. - Added:
InteriorFacetBasisfor integrating over the interior facets, e.g., evaluating error estimators with jumps and implementing DG methods. - Added:
MortarFacetBasisfor integrating over the mortar mesh. - Added:
InteriorBasis.with_elementfor reinitializing an equivalent basis that uses a different element. - Added:
Form.partialfor applyingfunctools.partialto the form function wrapped byForm. - Fixed: Include explicit Python 3.9 support.
- Deprecated: List and tuple keyword argument types to
asm. - Deprecated:
Mesh2D.mirrorin favor of the more generalMesh.mirrored. - Deprecated:
Mesh.refine,Mesh.scaleandMesh.translatein favor ofMesh.refined,Mesh.scaledandMesh.translated. - Added:
Mesh.refined,Mesh.scaled, andMesh.translated. The new methods return a copy instead of modifyingself. - Added:
Mesh.mirroredfor mirroring a mesh using a normal and a point. - Added:
Functionalnow supports forms that evaluate to vectors or other tensors. - Added:
ElementHex0, piecewise constant element for hexahedral meshes. - Added:
FacetBasis.tracefor restricting existing solutions to lower dimensional meshes on boundaries or interfaces. - Fixed:
MeshLine.refinednow correctly performs adaptive refinement of one-dimensional meshes.
- Added:
ElementLineP0, one-dimensional piecewise constant element. - Added:
skfem.helpers.curlnow calculates the rotated gradient for two-dimensional elements. - Added:
MeshTet.init_ballfor meshing a ball. - Fixed:
ElementQuad0was not compatible withFacetBasis.
- Fixed: Remove an unnecessary dependency.
- Fixed: Make the preconditioner in
TestEx32more robust.
- Fixed: Remove
testsfrom the PyPI distribution.
- Deprecated:
L2_projectionwill be replaced byproject. - Deprecated:
derivativewill be replaced byproject. - Added:
MeshTet.element_finderandMeshLine.element_finderfor usingInteriorBasis.interpolator. - Added:
ElementTriCR, the nonconforming Crouzeix-Raviart element for Stokes flow. - Added:
ElementTetCR, tetrahedral nonconforming Crouzeix-Raviart element. - Added:
ElementTriHermite, an extension ofElementLineHermiteto triangular meshes. - Fixed: Fix
Mesh.validatefor unsignedMesh.t.
- Fixed: Further optimizations to
Mesh3D.boundary_edges: tested to run on a laptop with over 10 million elements.
- Added:
ElementHex2, a triquadratic hexahedral element. - Added:
MeshTri.init_circle, constructor for a circle mesh. - Fixed:
Mesh3D.boundary_edges(and, consequently,Basis.find_dofs) was slow and used lots of memory due to an exhaustive search of all edges.
- Deprecated:
projectwill only support functions likelambda x: x[0]instead oflambda x, y, z: xin the future. - Added: Support for complex-valued forms:
BilinearFormandLinearFormnow take an optional argumentdtypewhich defaults tonp.float64but can be alsonp.complex64. - Added:
Dofs.__or__andDofs.__add__, for merging degree-of-freedom sets (i.e.Dofsobjects) using|and+operators. - Added:
Dofs.dropandDofs.keep, for further filtering the degree-of-freedom sets - Removed: Support for old-style decorators
bilinear_form,linear_form, andfunctional(deprecated since 1.0.0). - Fixed:
FacetBasisdid not initialize withElementQuadP.
- Added:
MeshQuad._splitquadsaliased asMeshQuad.to_meshtri. - Added:
Mesh.__add__, for merging meshes using+operator: duplicated nodes are joined. - Added:
ElementHexS2, a 20-node quadratic hexahedral serendipity element. - Added:
ElementLineMini, MINI-element for one-dimensional mesh. - Fixed:
Mesh3D.boundary_edgeswas broken in case of hexahedral meshes. - Fixed:
skfem.utils.projectdid not work forElementGlobal.
- Added:
ElementTetMini, MINI-element for tetrahedral mesh. - Fixed:
Mesh3D.boundary_edgesincorrectly returned all edges where both nodes are on the boundary.
- Deprecated: Old-style form constructors
bilinear_form,linear_form, andfunctional. - Changed:
Basis.interpolatereturnsDiscreteFieldobjects instead of ndarray tuples. - Changed:
Basis.interpolateworks now properly for vectorial and high-order elements by interpolating all components and higher order derivatives. - Changed:
Form.assembleaccepts now any keyword arguments (with typeDiscreteField) that are passed over to the forms. - Changed: Renamed
skfem.importerstoskfem.io. - Changed: Renamed
skfem.models.helperstoskfem.helpers. - Changed:
skfem.utils.solvewill now expand also the solutions of eigenvalue problems. - Added: New-style form constructors
BilinearForm,LinearForm, andFunctional. - Added:
skfem.io.jsonfor serialization of meshes to/from json-files. - Added:
ElementLinePp, p-th order one-dimensional elements. - Added:
ElementQuadP, p-th order quadrilateral elements. - Added:
ElementQuadDGfor transforming quadrilateral H1 elements to DG elements. - Added:
ElementQuadBFS, Bogner-Fox-Schmit element for biharmonic problems. - Added:
ElementTriMini, MINI-element for Stokes problems. - Added:
ElementCompositefor using multiple elements in one bilinear form. - Added:
ElementQuadS2, quadratic Serendipity element. - Added:
ElementLineHermite, cubic Hermite element for Euler-Bernoulli beams. - Added:
Mesh.define_boundaryfor defining named boundaries. - Added:
Basis.find_dofsfor finding degree-of-freedom indices. - Added:
Mesh.from_basisfor defining high-order meshes. - Added:
Basis.splitfor splitting multicomponent solutions. - Added:
MortarMappingwith basic support for mortar methods in 2D. - Added:
Basisconstructors now acceptquadraturekeyword argument for specifying a custom quadrature rule.