Simple finite element assemblers
Project description
scikitfem
is a lightweight Python 3.7+ 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 supports triangular, quadrilateral, tetrahedral and
hexahedral meshes as well as onedimensional problems.
The library fills a gap in the spectrum of finite element codes. The library is lightweight and has minimal dependencies. It contains no compiled code meaning that it's easy to install and use on all platforms that support NumPy. Despite being fully interpreted, the code has a reasonable performance.
Installation
The most recent release can be installed simply by
pip install scikitfem
Examples
Solve the Poisson problem (see also ex01.py
):
from skfem import * from skfem.helpers import dot, grad # create the mesh m = MeshTri().refined(4) # or, with your own points and cells: # m = MeshTri(points, cells) e = ElementTriP1() basis = Basis(m, e) # shorthand for CellBasis # this method could also be imported from skfem.models.laplace @BilinearForm def laplace(u, v, _): return dot(grad(u), grad(v)) # this method could also be imported from skfem.models.unit_load @LinearForm def rhs(v, _): return 1.0 * v A = asm(laplace, basis) b = asm(rhs, basis) # or: # A = laplace.assemble(basis) # b = rhs.assemble(basis) # enforce Dirichlet boundary conditions A, b = enforce(A, b, D=m.boundary_nodes()) # solve  can be anything that takes a sparse matrix and a righthand side x = solve(A, b) # plot the solution from skfem.visuals.matplotlib import plot, savefig plot(m, x, shading='gouraud', colorbar=True) savefig('solution.png')
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") mesh = MeshTet.init_tensor(*((np.linspace(0, 1, 60),) * 3))
We support many common finite elements. Below the stiffness matrix is assembled using secondorder tetrahedra:
from skfem import Basis, ElementTetP2 basis = Basis(mesh, ElementTetP2()) # quadratic tetrahedron A = laplace.assemble(basis) # type: scipy.sparse.csr_matrix
More examples can be found in the gallery.
Benchmark
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 a ThinkPad X1 Carbon laptop (7th
gen). 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
.
Degreesoffreedom  Assembly (s)  Linear solve (s) 

4096  0.04805  0.04241 
8000  0.09804  0.16269 
15625  0.20347  0.87741 
32768  0.46399  5.98163 
64000  1.00143  36.47855 
125000  2.05274  nan 
262144  4.48825  nan 
512000  8.82814  nan 
1030301  18.25461  nan 
Documentation
The project is documented using Sphinx under docs/
.
Built version can be found from Read the Docs.
Here are direct links to additional resources:
Getting help
If you encounter an issue and cannot find help from the documentation, you can use the Github issue tracker to ask questions using the question label. 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:
python c "import pkg_resources; print(pkg_resources.get_distribution('scikitfem').version)"
Dependencies
The minimal dependencies for installing scikitfem
are
numpy, scipy and
meshio. In addition, many
examples use
matplotlib for visualization. Some examples
demonstrate the use of other external packages; see requirements.txt
for a
list of test dependencies.
Testing
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/scikitfemdockeraction.
The releases are tested in
kinnala/scikitfemreleasetests.
Licensing
The contents of skfem/
and the PyPI package scikitfem
are licensed under
the 3clause BSD license. Some examples under docs/examples/
have a different
license, see LICENSE.md
for more information.
Acknowledgements
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 the Academy of Finland. The approach used in the finite element assembly has been inspired by the work of A. Hannukainen and M. Juntunen.
Contributing
We are happy to welcome any contributions to the library. Reasonable projects for first timers include:
By contributing code to scikitfem, you are agreeing to release it under BSD3Clause, see LICENSE.md.
Citing the library
You may use the following BibTeX entry:
@article{skfem2020,
doi = {10.21105/joss.02369},
year = {2020},
volume = {5},
number = {52},
pages = {2369},
author = {Tom Gustafsson and G. D. McBain},
title = {scikitfem: A {P}ython package for finite element assembly},
journal = {Journal of Open Source Software}
}
Use the Zenodo DOIs if you want to cite a specific version, e.g., to ensure reproducibility.
In literature
The library has been used in the preparation of the following scientific works.
 Gustafsson, T. & Videman, J. (2021). Stabilized finite elements for Tresca friction problem. arXiv preprint arxiv:2106.12165.
 Gustafsson, T. (2020). A simple technique for unstructured mesh generation via adaptive finite elements. arXiv preprint arXiv:2011.07919.
 Huang, X., Shi, Y., & Wang, W. (2020). A MorleyWangXu element method for a fourth order elliptic singular perturbation problem. arXiv preprint arXiv:2011.14064.
 Gustafsson, T., Stenberg, R., & Videman, J. (2020). Nitsche's method for Kirchhoff plates. arXiv preprint arXiv:2007.00403.
 Aquino, A., Mallinson, S., McBain, G. D., Horrocks, G., & Barber, T. (2020). Twodimensional numerical simulation of inkjet printzone flows. 22nd Australasian Fluid Mechanics Conference AFMC2020. Open access.
 Gustafsson, T., & McBain, G. D. (2020). scikitfem: A Python package for finite element assembly. Journal of Open Source Software, 52(5). Open access.
 Gustafsson, T., Stenberg, R., & Videman, J. (2020). On Nitsche's method for elastic contact problems. SIAM Journal on Scientific Computing, 42(2), B425–B446. arXiv preprint arXiv:1902.09312.
 Gustafsson, T., Stenberg, R., & Videman, J. (2019). Nitsche's MasterSlave Method for Elastic Contact Problems. arXiv:1912.08279.
 McBain, G. D., Mallinson, S. G., Brown, B. R., Gustafsson, T. (2019). Three ways to compute multiport inertance. The ANZIAM Journal, 60, C140–C155. Open access.
 Gustafsson, T., Stenberg, R., & Videman, J. (2019). Error analysis of Nitsche's mortar method. Numerische Mathematik, 142(4), 973–994. Open access.
 Gustafsson, T., Stenberg, R., & Videman, J. (2019). Nitsche's method for unilateral contact problems. Port. Math. 75, 189–204. arXiv preprint arXiv:1805.04283.
 Gustafsson, T., Stenberg, R. & Videman, J. (2018). A posteriori estimates for conforming Kirchhoff plate elements. SIAM Journal on Scientific Computing, 40(3), A1386–A1407. arXiv preprint arXiv:1707.08396.
 Gustafsson, T., Rajagopal, K. R., Stenberg, R., & Videman, J. (2018). An adaptive finite element method for the inequalityconstrained Reynolds equation. Computer Methods in Applied Mechanics and Engineering, 336, 156–170. arXiv preprint arXiv:1711.04274.
 Gustafsson, T., Stenberg, R., & Videman, J. (2018). A stabilised finite element method for the plate obstacle problem. BIT Numerical Mathematics, 59(1), 97–124. arXiv preprint arXiv:1711.04166.
 Gustafsson, T., Stenberg, R., & Videman, J. (2017). Nitsche’s Method for the Obstacle Problem of Clamped Kirchhoff Plates. In European Conference on Numerical Mathematics and Advanced Applications, 407–415. Springer.
 Gustafsson, T., Stenberg, R., & Videman, J. (2017). A posteriori analysis of classical plate elements. Rakenteiden Mekaniikka, 50(3), 141–145. Open access.
Feel free to open a PR to add your publication to the list.
Changelog
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning with respect to documented and/or tested features.
Unreleased
[3.2.0]  20210802
 Added:
ElementTriCCR
andElementTetCCR
, conforming CrouzeixRaviart finite elements  Fixed:
Mesh.mirrored
returned a wrong mesh when a point other than the origin was used  Fixed:
MeshLine
constructor 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:
MeshTet
andMeshTri.element_finder
are 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
[3.1.0]  20210618
 Added:
Basis
, a shorthand forCellBasis
 Added:
CellBasis
, a new preferred name forInteriorBasis
 Added:
BoundaryFacetBasis
, a new preferred name forExteriorFacetBasis
 Added:
utils.penalize
, an alternative tocondense
andenforce
for essential boundary conditions  Added:
InteriorBasis.point_source
, withex38
 Added:
ElementTetDG
, similar toElementTriDG
for tetrahedral meshes  Fixed:
MeshLine1.element_finder
[3.0.0]  20210419
 Added: Completely rewritten
Mesh
base class which is "immutable" and usesElement
classes to define the ordering of nodes; better support for highorder and other more general mesh types in the future  Added: New quadratic mesh types:
MeshTri2
,MeshQuad2
,MeshTet2
andMeshHex2
 Added:
InteriorBasis.probes
; likeInteriorBasis.interpolator
but 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_meshtet
for splitting hexahedra into tetrahedra  Added:
MeshHex.element_finder
for 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_subdomains
for defining subdomains via Boolean lambda function  Added:
skfem.utils.projection
, a replacement ofskfem.utils.project
with a different, more intuitive order of arguments  Added:
skfem.utils.enforce
for setting essential boundary conditions by changing matrix rows to zero and diagonals to one.  Deprecated:
skfem.utils.project
in favor ofskfem.utils.projection
 Deprecated:
Mesh.define_boundary
in 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
 Changed:
Mesh.refined
no more attempts to fix the indexing ofMesh.boundaries
after refine  Changed:
skfem.utils.solve
now usesscipy.sparse.eigs
instead ofscipy.sparse.eigsh
by default; the old behavior can be retained by explicitly passingsolver=solver_scipy_eigs_sym()
 Fixed: High memory usage and other small fixes in
skfem.visuals.matplotlib
related to 1D plotting
[2.5.0]  20210213
 Deprecated:
side
keyword argument toFacetBasis
in favor of the more explicitInteriorFacetBasis
andMortarFacetBasis
.  Added:
InteriorFacetBasis
for integrating over the interior facets, e.g., evaluating error estimators with jumps and implementing DG methods.  Added:
MortarFacetBasis
for integrating over the mortar mesh.  Added:
InteriorBasis.with_element
for reinitializing an equivalent basis that uses a different element.  Added:
Form.partial
for applyingfunctools.partial
to the form function wrapped byForm
.  Fixed: Include explicit Python 3.9 support.
[2.4.0]  20210120
 Deprecated: List and tuple keyword argument types to
asm
.  Deprecated:
Mesh2D.mirror
in favor of the more generalMesh.mirrored
.  Deprecated:
Mesh.refine
,Mesh.scale
andMesh.translate
in favor ofMesh.refined
,Mesh.scaled
andMesh.translated
.  Added:
Mesh.refined
,Mesh.scaled
, andMesh.translated
. The new methods return a copy instead of modifyingself
.  Added:
Mesh.mirrored
for mirroring a mesh using a normal and a point.  Added:
Functional
now supports forms that evaluate to vectors or other tensors.  Added:
ElementHex0
, piecewise constant element for hexahedral meshes.  Added:
FacetBasis.trace
for restricting existing solutions to lower dimensional meshes on boundaries or interfaces.  Fixed:
MeshLine.refined
now correctly performs adaptive refinement of onedimensional meshes.
[2.3.0]  20201124
 Added:
ElementLineP0
, onedimensional piecewise constant element.  Added:
skfem.helpers.curl
now calculates the rotated gradient for twodimensional elements.  Added:
MeshTet.init_ball
for meshing a ball.  Fixed:
ElementQuad0
was not compatible withFacetBasis
.
[2.2.3]  20201016
 Fixed: Remove an unnecessary dependency.
[2.2.2]  20201015
 Fixed: Make the preconditioner in
TestEx32
more robust.
[2.2.1]  20201015
 Fixed: Remove
tests
from the PyPI distribution.
[2.2.0]  20201014
 Deprecated:
L2_projection
will be replaced byproject
.  Deprecated:
derivative
will be replaced byproject
.  Added:
MeshTet.element_finder
andMeshLine.element_finder
for usingInteriorBasis.interpolator
.  Added:
ElementTriCR
, the nonconforming CrouzeixRaviart element for Stokes flow.  Added:
ElementTetCR
, tetrahedral nonconforming CrouzeixRaviart element.  Added:
ElementTriHermite
, an extension ofElementLineHermite
to triangular meshes.  Fixed: Fix
Mesh.validate
for unsignedMesh.t
.
[2.1.1]  20201001
 Fixed: Further optimizations to
Mesh3D.boundary_edges
: tested to run on a laptop with over 10 million elements.
[2.1.0]  20200930
 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.
[2.0.0]  20200821
 Deprecated:
project
will only support functions likelambda x: x[0]
instead oflambda x, y, z: x
in the future.  Added: Support for complexvalued forms:
BilinearForm
andLinearForm
now take an optional argumentdtype
which defaults tonp.float64
but can be alsonp.complex64
.  Added:
Dofs.__or__
andDofs.__add__
, for merging degreeoffreedom sets (i.e.Dofs
objects) using
and+
operators.  Added:
Dofs.drop
andDofs.keep
, for further filtering the degreeoffreedom sets  Removed: Support for oldstyle decorators
bilinear_form
,linear_form
, andfunctional
(deprecated since 1.0.0).  Fixed:
FacetBasis
did not initialize withElementQuadP
.
[1.2.0]  20200707
 Added:
MeshQuad._splitquads
aliased asMeshQuad.to_meshtri
.  Added:
Mesh.__add__
, for merging meshes using+
operator: duplicated nodes are joined.  Added:
ElementHexS2
, a 20node quadratic hexahedral serendipity element.  Added:
ElementLineMini
, MINIelement for onedimensional mesh.  Fixed:
Mesh3D.boundary_edges
was broken in case of hexahedral meshes.  Fixed:
skfem.utils.project
did not work forElementGlobal
.
[1.1.0]  20200518
 Added:
ElementTetMini
, MINIelement for tetrahedral mesh.  Fixed:
Mesh3D.boundary_edges
incorrectly returned all edges where both nodes are on the boundary.
[1.0.0]  20200422
 Deprecated: Oldstyle form constructors
bilinear_form
,linear_form
, andfunctional
.  Changed:
Basis.interpolate
returnsDiscreteField
objects instead of ndarray tuples.  Changed:
Basis.interpolate
works now properly for vectorial and highorder elements by interpolating all components and higher order derivatives.  Changed:
Form.assemble
accepts now any keyword arguments (with typeDiscreteField
) that are passed over to the forms.  Changed: Renamed
skfem.importers
toskfem.io
.  Changed: Renamed
skfem.models.helpers
toskfem.helpers
.  Changed:
skfem.utils.solve
will now expand also the solutions of eigenvalue problems.  Added: Newstyle form constructors
BilinearForm
,LinearForm
, andFunctional
.  Added:
skfem.io.json
for serialization of meshes to/from jsonfiles.  Added:
ElementLinePp
, pth order onedimensional elements.  Added:
ElementQuadP
, pth order quadrilateral elements.  Added:
ElementQuadDG
for transforming quadrilateral H1 elements to DG elements.  Added:
ElementQuadBFS
, BognerFoxSchmit element for biharmonic problems.  Added:
ElementTriMini
, MINIelement for Stokes problems.  Added:
ElementComposite
for using multiple elements in one bilinear form.  Added:
ElementQuadS2
, quadratic Serendipity element.  Added:
ElementLineHermite
, cubic Hermite element for EulerBernoulli beams.  Added:
Mesh.define_boundary
for defining named boundaries.  Added:
Basis.find_dofs
for finding degreeoffreedom indices.  Added:
Mesh.from_basis
for defining highorder meshes.  Added:
Basis.split
for splitting multicomponent solutions.  Added:
MortarMapping
with basic support for mortar methods in 2D.  Added:
Basis
constructors now acceptquadrature
keyword argument for specifying a custom quadrature rule.
Project details
Release history Release notifications  RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Filename, size  File type  Python version  Upload date  Hashes 

Filename, size scikit_fem3.2.0py3noneany.whl (116.0 kB)  File type Wheel  Python version py3  Upload date  Hashes View 
Filename, size scikitfem3.2.0.tar.gz (79.5 kB)  File type Source  Python version None  Upload date  Hashes View 
Hashes for scikit_fem3.2.0py3noneany.whl
Algorithm  Hash digest  

SHA256  693205fc3857c6e240701feca1350c1621de0a8af71a1fc1fc1c9b3f9d2c9caf 

MD5  0223d59eda829ca01402b324d09d16e5 

BLAKE2256  2ca43f7139f14a01a661535fc6d918ca11a5082535783e5b6d1576d4d6d39f71 