warp.fem#
The warp.fem
module is designed to facilitate solving physical systems described as differential
equations. For example, it can solve PDEs for diffusion, convection, fluid flow, and elasticity problems
using finite-element-based (FEM) Galerkin methods and allows users to quickly experiment with various FEM
formulations and discretization schemes.
Integrands#
The core functionality of the FEM toolkit is the ability to integrate constant, linear, and bilinear forms over various domains and using arbitrary interpolation basis.
The main mechanism is the integrand()
decorator, for instance:
@integrand
def linear_form(
s: Sample,
domain: Domain,
v: Field,
):
x = domain(s)
return v(s) * wp.max(0.0, 1.0 - wp.length(x))
@integrand
def diffusion_form(s: Sample, u: Field, v: Field, nu: float):
return nu * wp.dot(
grad(u, s),
grad(v, s),
)
Integrands are normal Warp kernels, meaning that they may contain arbitrary Warp functions. However, they accept a few special parameters:
Sample
contains information about the current integration sample point, such as the element index and coordinates in element.
Field
designates an abstract field, which will be replaced at call time by the actual field type such as a discrete field,field.TestField
orfield.TrialField
defined over someFunctionSpace
, anImplicitField
wrapping an arbitrary function, or any other of the available Fields. A field u can then be evaluated at a given sample s using the usual call operator asu(s)
. Several other operators are available, such as the gradientgrad()
; see the Operators section.
Domain
designates an abstract integration domain. Evaluating a domain at a sample s asdomain(s)
yields the corresponding world position, and several operators are also provided domains, for example evaluating the normal at a given sample:@integrand def boundary_form( s: Sample, domain: Domain, u: Field, ): nor = normal(domain, s) return wp.dot(u(s), nor)
Integrands cannot be used directly with warp.launch()
, but must be called through integrate()
or interpolate()
instead.
The Sample
and Domain
arguments of the root integrand (integrand parameter passed to integrate()
or interpolate()
call) will get automatically populated.
Field
arguments must be passed as a dictionary in the fields parameter of the launcher function, and all other standard Warp types arguments must be
passed as a dictionary in the values parameter of the launcher function, for instance:
integrate(diffusion_form, fields={"u": trial, "v": test}, values={"nu": viscosity})
Basic Workflow#
The typical steps for solving a linearized PDE with warp.fem
are as follow:
Define a
Geometry
(grid, mesh, etc). At the moment, 2D and 3D regular grids, NanoVDB volumes, and triangle, quadrilateral, tetrahedron and hexahedron unstructured meshes are supported.Define one or more
FunctionSpace
, by equipping the geometry elements with shape functions. Seemake_polynomial_space()
. At the moment, continuous/discontinuous Lagrange (\(P_{k[d]}, Q_{k[d]}\)) and Serendipity (\(S_k\)) shape functions of order \(k \leq 3\) are supported, as well as linear Nédélec (first kind) and Raviart-Thomas vector-valued shape functions.Define an integration domain, for instance the geometry’s cells (
Cells
) or boundary sides (BoundarySides
).Integrate linear forms to build the system’s right-hand-side. Define a test function over the function space using
make_test()
, aQuadrature
formula (or let the module choose one based on the function space degree), and callintegrate()
with the linear form integrand. The result is awarp.array
containing the integration result for each of the function space degrees of freedom.Integrate bilinear forms to build the system’s left-hand-side. Define a trial function over the function space using
make_trial()
, then callintegrate()
with the bilinear form integrand. The result is awarp.sparse.BsrMatrix
containing the integration result for each pair of test and trial function space degrees of freedom. Note that the trial and test functions do not have to be defined over the same function space, so that Mixed FEM is supported.Solve the resulting linear system using the solver of your choice, for instance one of the built-in Iterative Linear Solvers.
The following excerpt from the introductory example warp/examples/fem/example_diffusion.py
outlines this procedure:
# Grid geometry
geo = Grid2D(n=50, cell_size=2)
# Domain and function spaces
domain = Cells(geometry=geo)
scalar_space = make_polynomial_space(geo, degree=3)
# Right-hand-side (forcing term)
test = make_test(space=scalar_space, domain=domain)
rhs = integrate(linear_form, fields={"v": test})
# Weakly-imposed boundary conditions on Y sides
boundary = BoundarySides(geo)
bd_test = make_test(space=scalar_space, domain=boundary)
bd_trial = make_trial(space=scalar_space, domain=boundary)
bd_matrix = integrate(y_mass_form, fields={"u": bd_trial, "v": bd_test})
# Diffusion form
trial = make_trial(space=scalar_space, domain=domain)
matrix = integrate(diffusion_form, fields={"u": trial, "v": test}, values={"nu": viscosity})
# Assemble linear system (add diffusion and boundary condition matrices)
matrix += bd_matrix * boundary_strength
# Solve linear system using Conjugate Gradient
x = wp.zeros_like(rhs)
bsr_cg(matrix, b=rhs, x=x)
Note
The integrate()
function does not check that the passed integrands are actually linear or bilinear forms; it is up to the user to ensure that they are.
To solve non-linear PDEs, one can use an iterative procedure and pass the current value of the studied function DiscreteField
argument to the integrand, in which
arbitrary operations are permitted. However, the result of the form must remain linear in the test and trial fields.
This strategy is demonstrated in the example_mixed_elasticity.py
example.
Introductory Examples#
warp.fem
ships with a list of examples in the warp/examples/fem
directory demonstrating how to solve classical model problems.
example_diffusion.py
: 2D diffusion with homogeneous Neumann and Dirichlet boundary conditions
example_diffusion_3d.py
: 3D variant of the diffusion problem
example_convection_diffusion.py
: 2D convection-diffusion using semi-Lagrangian advection
example_convection_diffusion_dg.py
: 2D convection-diffusion using Discontinuous Galerkin with upwind transport and Symmetric Interior Penalty
example_burgers.py
: 2D inviscid Burgers using Discontinuous Galerkin with upwind transport and slope limiter
example_stokes.py
: 2D incompressible Stokes flow using mixed \(P_k/P_{k-1}\) or \(Q_k/P_{(k-1)d}\) elements
example_navier_stokes.py
: 2D Navier-Stokes flow using mixed \(P_k/P_{k-1}\) elements
example_mixed_elasticity.py
: 2D nonlinear elasticity using mixed continuous/discontinuous \(S_k/P_{(k-1)d}\) elements
example_distortion_energy.py
: Parameterization of a 3D surface minimizing a 2D nonlinear distortion energy
example_magnetostatics.py
: 2D magnetostatics using a curl-curl formulation
Advanced Usages#
High-order (curved) geometries#
It is possible to convert any Geometry
(grids and explicit meshes) into a curved, high-order variant by deforming them
with an arbitrary-order displacement field using the make_deformed_geometry()
method.
The process looks as follows:
# Define a base geometry
base_geo = fem.Grid3D(res=resolution)
# Define a displacement field on the base geometry
deformation_space = fem.make_polynomial_space(base_geo, degree=deformation_degree, dtype=wp.vec3)
deformation_field = deformation_space.make_field()
# Populate the field value by interpolating an expression
fem.interpolate(deformation_field_expr, dest=deformation_field)
# Construct the deformed geometry from the displacement field
deform_geo = deformation_field.make_deformed_geometry()
# Define new function spaces on the deformed geometry
scalar_space = fem.make_polynomial_space(deformed_geo, degree=scalar_space_degree)
See example_deformed_geometry.py
for a complete example.
It is also possible to define the deformation field from an ImplicitField
, as done in example_magnetostatics.py
.
Particle-based quadrature and position lookups#
The global lookup()
operator allows generating a Sample
from an arbitrary position; this is illustrated in
the example_streamlines.py
example for generating 3D streamlines by tracing through a velocity field.
This operator is also leveraged by the PicQuadrature
to provide a way to define Particle-In-Cell quadratures from a set or arbitrary particles,
making it possible to implement MPM-type methods.
The particles are automatically bucketed to the geometry cells when the quadrature is initialized.
This is illustrated by the example_stokes_transfer.py
and example_apic_fluid.py
examples.
Note
The global lookup()
operator is not currently supported for Quadmesh2D
, Hexmesh
and deformed geometries.
Nonconforming fields#
Fields defined on a given Geometry
cannot be directly used for integrating over a distinct geometry;
however, they may be wrapped in a NonconformingField
for this purpose.
This is leveraged by the example_nonconforming_contact.py
to simulate contacting bodies that are discretized separately.
Note
Currently NonconformingField
does not support wrapping a trial field, so it is not yet possible to define
bilinear forms over different geometries.
Note
The mapping between the different geometries is position based, so a NonconformingField
is not able to accurately capture discontinuous function spaces.
Moreover, the integration domain must support the lookup()
operator.
Partitioning#
The FEM toolkit makes it possible to perform integration on a subset of the domain elements,
possibly re-indexing degrees of freedom so that the linear system contains the local ones only.
This is useful for distributed computation (see warp/examples/fem/example_diffusion_mgpu.py
), or simply to limit the simulation domain to a subset of active cells (see warp/examples/fem/example_stokes_transfer.py
).
A partition of the simulation geometry can be defined using subclasses of GeometryPartition
such as LinearGeometryPartition
or ExplicitGeometryPartition
.
Function spaces can then be partitioned according to the geometry partition using make_space_partition()
.
The resulting SpacePartition
object allows translating between space-wide and partition-wide node indices,
and differentiating interior, frontier and exterior nodes.
The Subdomain
class can be used to integrate over a subset of elements while keeping the full set of degrees of freedom,
i.e, without reindexing; this is illustrated in the example_streamlines.py
example to define inflow and outflow boundaries.
Adaptivity#
While unstructured mesh refinement is currently out of scope, warp.fem
provides an adaptive version of the sparse grid geometry, AdaptiveNanogrid
,
with power-of-two voxel scales. Helpers for building such geometries from hierarchy of grids or a refinement oracle are also provided, see
adaptive_nanogrid_from_field()
and adaptive_nanogrid_from_hierarchy()
.
An example is provided in warp/examples/fem/example_adaptive_grid.py
.
Note
The existence of “T-junctions” at resolution boundaries mean that usual tri-polynomial shape functions will no longer be globally continuous. Discontinuous–Galerkin or similar techniques may be used to take into account the “jump” at multi-resolution faces.
Memory management#
Several warp.fem
functions require allocating temporary buffers to perform their computations.
If such functions are called many times in a tight loop, those many allocations and de-allocations may degrade performance,
though this is a lot less significant when Stream-Ordered Memory Pool Allocators are in use.
To overcome this issue, a cache.TemporaryStore
object may be created to persist and reuse temporary allocations across calls,
either globally using set_default_temporary_store()
or at a per-function granularity using the corresponding argument.
Visualization#
Most functions spaces define a FunctionSpace.cells_to_vtk()
method that returns a list of VTK-compatible cell types and node indices.
This can be used to visualize discrete fields in VTK-aware viewers such as pyvista
, for instance:
import numpy as np
import pyvista
import warp as wp
import warp.fem as fem
@fem.integrand
def ackley(s: fem.Sample, domain: fem.Domain):
x = domain(s)
return (
-20.0 * wp.exp(-0.2 * wp.sqrt(0.5 * wp.length_sq(x)))
- wp.exp(0.5 * (wp.cos(2.0 * wp.pi * x[0]) + wp.cos(2.0 * wp.pi * x[1])))
+ wp.e
+ 20.0
)
# Define field
geo = fem.Grid2D(res=wp.vec2i(64, 64), bounds_lo=wp.vec2(-4.0, -4.0), bounds_hi=wp.vec2(4.0, 4.0))
space = fem.make_polynomial_space(geo, degree=3)
field = space.make_field()
fem.interpolate(ackley, dest=field)
# Extract cells, nodes and values
cells, types = field.space.vtk_cells()
nodes = field.space.node_positions().numpy()
values = field.dof_values.numpy()
positions = np.hstack((nodes, values[:, np.newaxis]))
# Visualize with pyvista
grid = pyvista.UnstructuredGrid(cells, types, positions)
grid.point_data["scalars"] = values
plotter = pyvista.Plotter()
plotter.add_mesh(grid)
plotter.show()
Operators#
Domain operators#
- warp.fem.normal(domain: Domain, s: Sample)#
Evaluates the element normal at the sample point s. Non zero if the element is a side or the geometry is embedded in a higher-dimensional space (e.g.
Trimesh3D
)
- warp.fem.lookup(domain: Domain, x)#
Looks-up the sample point corresponding to a world position x, projecting to the closest point on the domain.
- Parameters:
x – world position of the point to look-up in the geometry
guess – (optional)
Sample
initial guess, may help perform the query
Note
Currently this operator is unsupported for
Hexmesh
,Quadmesh2D
,Quadmesh3D
and deformed geometries.
- warp.fem.measure(domain: Domain, s: Sample)#
Returns the measure (volume, area, or length) determinant of an element at a sample point s
- warp.fem.measure_ratio(domain: Domain, s: Sample)#
Returns the maximum ratio between the measure of this element and that of higher-dimensional neighbors.
- warp.fem.deformation_gradient(domain: Domain, s: Sample)#
Evaluates the gradient of the domain position with respect to the element reference space at the sample point s
- warp.fem.cells(domain: Domain)#
Converts a domain defined on geometry sides to a domain defined of cells.
- warp.fem.to_inner_cell(domain: Domain, s: Sample)#
Converts a
Sample
defined on a side to a sample defined on the side’s inner cell
Field operators#
- warp.fem.inner(f: Field, s: Sample)#
Evaluates the field at a sample point s. On oriented sides, uses the inner element
- warp.fem.outer(f: Field, s: Sample)#
Evaluates the field at a sample point s. On oriented sides, uses the outer element. On interior points and on domain boundaries, this is equivalent to
inner()
.
- warp.fem.grad(f: Field, s: Sample)#
Evaluates the field gradient at a sample point s. On oriented sides, uses the inner element
- warp.fem.grad_outer(f: Field, s: Sample)#
Evaluates the field gradient at a sample point s. On oriented sides, uses the outer element. On interior points and on domain boundaries, this is equivalent to
grad()
.
- warp.fem.div(f: Field, s: Sample)#
Evaluates the field divergence at a sample point s. On oriented sides, uses the inner element
- warp.fem.div_outer(f: Field, s: Sample)#
Evaluates the field divergence at a sample point s. On oriented sides, uses the outer element. On interior points and on domain boundaries, this is equivalent to
div()
.
- warp.fem.at_node(f: Field, s: Sample)#
For a Test or Trial field f, returns a copy of the Sample s moved to the coordinates of the node being evaluated
- warp.fem.curl(f: Field, s: Sample)#
Skew part of the (inner) gradient of the field at s, as a vector such that
wp.cross(curl(u), v) = skew(grad(u)) v
- warp.fem.jump(f: Field, s: Sample)#
Jump between inner and outer element values on an interior side. Zero for interior points or domain boundaries
Integration#
- warp.fem.integrate(
- integrand,
- domain=None,
- quadrature=None,
- nodal=False,
- fields=None,
- values=None,
- accumulate_dtype=wp.float64,
- output_dtype=None,
- output=None,
- device=None,
- temporary_store=None,
- kernel_options=None,
- assembly=None,
- add=False,
Integrates a constant, linear or bilinear form, and returns a scalar, array, or sparse matrix, respectively.
- Parameters:
integrand (Integrand) – Form to be integrated, must have
integrand()
decoratordomain (GeometryDomain | None) – Integration domain. If None, deduced from fields
quadrature (Quadrature | None) – Quadrature formula. If None, deduced from domain and fields degree.
nodal (bool) – Deprecated. Use the equivalent assembly=”nodal” instead.
fields (Dict[str, FieldLike] | None) – Discrete, test, and trial fields to be passed to the integrand. Keys in the dictionary must match integrand parameter names.
values (Dict[str, Any] | None) – Additional variable values to be passed to the integrand, can be of any type accepted by warp kernel launches. Keys in the dictionary must match integrand parameter names.
temporary_store (TemporaryStore | None) – shared pool from which to allocate temporary arrays
accumulate_dtype (type) – Scalar type to be used for accumulating integration samples
output (array | BsrMatrix | None) – Sparse matrix or warp array into which to store the result of the integration
output_dtype (type | None) – Scalar type for returned results in output is not provided. If None, defaults to accumulate_dtype
device – Device on which to perform the integration
kernel_options (Dict[str, Any] | None) – Overloaded options to be passed to the kernel builder (e.g,
{"enable_backward": True}
)assembly (str | None) – Specifies the strategy for assembling the integrated vector or matrix: - “nodal”: For linear or bilinear forms, use the test function nodes as the quadrature points. Assumes Lagrange interpolation functions are used, and no differential or DG operator is evaluated on the test or trial functions. - “generic”: Single-pass integration and shape-function evaluation. Makes no assumption about the integrand’s content, but may lead to many redundant computations. - “dispatch”: For linear or bilinear forms, first evaluate the form at quadrature points then dispatch to nodes in a second pass. More efficient for integrands that are expensive to evaluate. Incompatible with at_node operator on test or trial functions. - None (default): Automatically picks a suitable assembly strategy (either “generic” or “dispatch”)
add (bool) – If True and output is provided, add the integration result to output instead of replacing its content
- warp.fem.interpolate(
- integrand,
- dest=None,
- quadrature=None,
- dim=0,
- domain=None,
- fields=None,
- values=None,
- device=None,
- kernel_options=None,
Interpolates a function at a finite set of sample points and optionally assigns the result to a discrete field or a raw warp array.
- Parameters:
integrand (Integrand | FieldLike) – Function to be interpolated: either a function with
warp.fem.integrand()
decorator or a fielddest (DiscreteField | FieldRestriction | array | None) –
Where to store the interpolation result. Can be either
a
DiscreteField
, or restriction of a discrete field to a domain (frommake_restriction()
). In this case, interpolation will be performed at each node.a normal warp
array
, orNone
. In this case, the interpolation samples will determined by the quadrature or dim arguments, in that order.
quadrature (Quadrature | None) – Quadrature formula defining the interpolation samples if dest is not a discrete field or field restriction.
dim (int) – Number of interpolation samples if dest is not a discrete field or restriction and quadrature is
None
. In this case, theSample
passed to the integrand will be invalid, but the sample point indexs.qp_index
can be used to define custom interpolation logic.domain (Domain | None) – Interpolation domain, only used if dest is not a field restriction and quadrature is
None
fields (Dict[str, FieldLike] | None) – Discrete fields to be passed to the integrand. Keys in the dictionary must match integrand parameters names.
values (Dict[str, Any] | None) – Additional variable values to be passed to the integrand, can be of any type accepted by warp kernel launches. Keys in the dictionary must match integrand parameter names.
device – Device on which to perform the interpolation
kernel_options (Dict[str, Any] | None) – Overloaded options to be passed to the kernel builder (e.g,
{"enable_backward": True}
)
- warp.fem.integrand(func=None, kernel_options=None)[source]#
Decorator for functions to be integrated (or interpolated) using warp.fem
- class warp.fem.Sample#
Per-sample point context for evaluating fields and related operators in integrands.
Geometry#
- class warp.fem.Grid2D(res, bounds_lo=None, bounds_hi=None)[source]#
Bases:
Geometry
Two-dimensional regular grid geometry
- Parameters:
res (vec2i)
bounds_lo (vec2f | None)
bounds_hi (vec2f | None)
- __init__(res, bounds_lo=None, bounds_hi=None)[source]#
Constructs a dense 2D grid
- Parameters:
res (vec2i) – Resolution of the grid along each dimension
bounds_lo (vec2f | None) – Position of the lower bound of the axis-aligned grid
bounds_hi (vec2f | None) – Position of the upper bound of the axis-aligned grid
- class warp.fem.Trimesh2D(
- tri_vertex_indices,
- positions,
- build_bvh=False,
- temporary_store=None,
Bases:
Trimesh
2D Triangular mesh geometry
- Parameters:
tri_vertex_indices (array)
positions (array)
build_bvh (bool)
temporary_store (TemporaryStore | None)
- __init__(
- tri_vertex_indices,
- positions,
- build_bvh=False,
- temporary_store=None,
Constructs a D-dimensional triangular mesh.
- Parameters:
tri_vertex_indices (array) – warp array of shape (num_tris, 3) containing vertex indices for each tri
positions (array) – warp array of shape (num_vertices, D) containing the position of each vertex
temporary_store (TemporaryStore | None) – shared pool from which to allocate temporary arrays
build_bvh (bool) – Whether to also build the triangle BVH, which is necessary for the global fem.lookup operator to function without initial guess
- class warp.fem.Trimesh3D(
- tri_vertex_indices,
- positions,
- build_bvh=False,
- temporary_store=None,
Bases:
Trimesh
3D Triangular mesh geometry
- Parameters:
tri_vertex_indices (array)
positions (array)
build_bvh (bool)
temporary_store (TemporaryStore | None)
- __init__(
- tri_vertex_indices,
- positions,
- build_bvh=False,
- temporary_store=None,
Constructs a D-dimensional triangular mesh.
- Parameters:
tri_vertex_indices (array) – warp array of shape (num_tris, 3) containing vertex indices for each tri
positions (array) – warp array of shape (num_vertices, D) containing the position of each vertex
temporary_store (TemporaryStore | None) – shared pool from which to allocate temporary arrays
build_bvh (bool) – Whether to also build the triangle BVH, which is necessary for the global fem.lookup operator to function without initial guess
- class warp.fem.Quadmesh2D(quad_vertex_indices, positions, temporary_store=None)[source]#
Bases:
Quadmesh
Two-dimensional quadrilateral mesh
- Parameters:
quad_vertex_indices (array)
positions (array)
temporary_store (TemporaryStore | None)
- __init__(
- quad_vertex_indices,
- positions,
- temporary_store=None,
Constructs a D-dimensional quadrilateral mesh.
- Parameters:
quad_vertex_indices (array) – warp array of shape (num_tris, 4) containing vertex indices for each quad, in counter-clockwise order
positions (array) – warp array of shape (num_vertices, D) containing the position of each vertex
temporary_store (TemporaryStore | None) – shared pool from which to allocate temporary arrays
- class warp.fem.Quadmesh3D(quad_vertex_indices, positions, temporary_store=None)[source]#
Bases:
Quadmesh
Three-dimensional quadrilateral mesh
- Parameters:
quad_vertex_indices (array)
positions (array)
temporary_store (TemporaryStore | None)
- __init__(
- quad_vertex_indices,
- positions,
- temporary_store=None,
Constructs a D-dimensional quadrilateral mesh.
- Parameters:
quad_vertex_indices (array) – warp array of shape (num_tris, 4) containing vertex indices for each quad, in counter-clockwise order
positions (array) – warp array of shape (num_vertices, D) containing the position of each vertex
temporary_store (TemporaryStore | None) – shared pool from which to allocate temporary arrays
- class warp.fem.Grid3D(res, bounds_lo=None, bounds_hi=None)[source]#
Bases:
Geometry
Three-dimensional regular grid geometry
- Parameters:
res (vec3i)
bounds_lo (vec3f | None)
bounds_hi (vec3f | None)
- __init__(res, bounds_lo=None, bounds_hi=None)[source]#
Constructs a dense 3D grid
- Parameters:
res (vec3i) – Resolution of the grid along each dimension
bounds_lo (vec3f | None) – Position of the lower bound of the axis-aligned grid
bounds_hi (vec3f | None) – Position of the upper bound of the axis-aligned grid
- class warp.fem.Tetmesh(
- tet_vertex_indices,
- positions,
- build_bvh=False,
- temporary_store=None,
Bases:
Geometry
Tetrahedral mesh geometry
- Parameters:
tet_vertex_indices (array)
positions (array)
build_bvh (bool)
temporary_store (TemporaryStore | None)
- __init__(
- tet_vertex_indices,
- positions,
- build_bvh=False,
- temporary_store=None,
Constructs a tetrahedral mesh.
- Parameters:
tet_vertex_indices (array) – warp array of shape (num_tets, 4) containing vertex indices for each tet
positions (array) – warp array of shape (num_vertices, 3) containing 3d position for each vertex
temporary_store (TemporaryStore | None) – shared pool from which to allocate temporary arrays
build_bvh (bool) – Whether to also build the tet BVH, which is necessary for the global fem.lookup operator to function without initial guess
- class warp.fem.Hexmesh(hex_vertex_indices, positions, temporary_store=None)[source]#
Bases:
Geometry
Hexahedral mesh geometry
- Parameters:
hex_vertex_indices (array)
positions (array)
temporary_store (TemporaryStore | None)
- __init__(hex_vertex_indices, positions, temporary_store=None)[source]#
Constructs a tetrahedral mesh.
- Parameters:
hex_vertex_indices (array) – warp array of shape (num_hexes, 8) containing vertex indices for each hex following standard ordering (bottom face vertices in counter-clockwise order, then similarly for upper face)
positions (array) – warp array of shape (num_vertices, 3) containing 3d position for each vertex
temporary_store (TemporaryStore | None) – shared pool from which to allocate temporary arrays
- class warp.fem.Nanogrid(grid, temporary_store=None)[source]#
Bases:
Geometry
Sparse grid geometry
- Parameters:
grid (Volume)
temporary_store (TemporaryStore | None)
- __init__(grid, temporary_store=None)[source]#
Constructs a sparse grid geometry from an in-memory NanoVDB volume.
- Parameters:
grid (Volume) – The NanoVDB volume. Any type is accepted, but for indexing efficiency an index grid is recommended. If grid is an ‘on’ index grid, cells will be created for active voxels only, otherwise cells will be created for all leaf voxels.
temporary_store (TemporaryStore | None) – shared pool from which to allocate temporary arrays
- class warp.fem.AdaptiveNanogrid(cell_grid, cell_level, level_count, temporary_store)[source]#
Bases:
Geometry
Adaptive sparse grid
- Parameters:
cell_grid (Volume)
cell_level (array)
level_count (int)
temporary_store (TemporaryStore)
- __init__(
- cell_grid,
- cell_level,
- level_count,
- temporary_store,
Constructs an adaptive sparse grid geometry from an in-memory NanoVDB volume and a list of levels.
It is not recommended to use this constructor directly; see the helper functions
warp.fem.adaptive_nanogrid_from_field()
andwarp.fem.adaptive_nanogrid_from_hierarchy()
- Parameters:
cell_grid (Volume) – A warp volume (ideally backed by an index grid) whose voxels coordinates correspond to the lowest fine-resolution voxel of each cell. The cell’s extent is then given by the cell_level array. For instance, a voxel at coordinates
ijk
and level0
corresponds to a fine cell at the same coordinates, a voxel at coordinates2*ijk
and level1
corresponds to a cell spanning2^3
voxels from2*ijk
to2*ijk + (1,1,1)
, etc.cell_level (array) – Refinement level for each voxel of the volume. Level 0 is the finest, level
level_count-1
is the coarsest.level_count (int) – Number of levels in the grid
temporary_store (TemporaryStore)
- class warp.fem.LinearGeometryPartition(
- geometry,
- partition_rank,
- partition_count,
- device=None,
- temporary_store=None,
- Parameters:
geometry (Geometry)
partition_rank (int)
partition_count (int)
temporary_store (TemporaryStore)
- __init__(
- geometry,
- partition_rank,
- partition_count,
- device=None,
- temporary_store=None,
Creates a geometry partition by uniformly partionning cell indices
- Parameters:
geometry (Geometry) – the geometry to partition
partition_rank (int) – the index of the partition being created
partition_count (int) – the number of partitions that will be created over the geometry
device – Warp device on which to perform and store computations
temporary_store (TemporaryStore | None)
- class warp.fem.ExplicitGeometryPartition(geometry, cell_mask, temporary_store=None)[source]#
- Parameters:
geometry (Geometry)
cell_mask (wp.array(dtype=int))
temporary_store (TemporaryStore)
- __init__(
- geometry,
- cell_mask,
- temporary_store=None,
Creates a geometry partition by uniformly partionning cell indices
- Parameters:
geometry (Geometry) – the geometry to partition
cell_mask (wp.array(dtype=int)) – warp array of length
geometry.cell_count()
indicating which cells are selected. Array values must be either1
(selected) or0
(not selected).temporary_store (TemporaryStore)
- class warp.fem.Cells(geometry)[source]#
Bases:
GeometryDomain
A Domain containing all cells of the geometry or geometry partition
- Parameters:
geometry (Geometry | GeometryPartition)
- __init__(geometry)[source]#
- Parameters:
geometry (Geometry | GeometryPartition)
- class warp.fem.Sides(geometry)[source]#
Bases:
GeometryDomain
A Domain containing all (interior and boundary) sides of the geometry or geometry partition
- Parameters:
geometry (Geometry | GeometryPartition)
- __init__(geometry)[source]#
- Parameters:
geometry (Geometry | GeometryPartition)
- class warp.fem.BoundarySides(geometry)[source]#
Bases:
Sides
A Domain containing boundary sides of the geometry or geometry partition
- Parameters:
geometry (Geometry | GeometryPartition)
- __init__(geometry)[source]#
- Parameters:
geometry (Geometry | GeometryPartition)
- class warp.fem.FrontierSides(geometry)[source]#
Bases:
Sides
A Domain containing frontier sides of the geometry partition (sides shared with at least another partition)
- Parameters:
geometry (Geometry | GeometryPartition)
- __init__(geometry)[source]#
- Parameters:
geometry (Geometry | GeometryPartition)
- class warp.fem.Subdomain(
- domain,
- element_mask=None,
- element_indices=None,
- temporary_store=None,
Bases:
GeometryDomain
Subdomain – restriction of domain to a subset of its elements
- Parameters:
domain (GeometryDomain)
element_mask (array | None)
element_indices (array | None)
temporary_store (TemporaryStore | None)
- __init__(
- domain,
- element_mask=None,
- element_indices=None,
- temporary_store=None,
Create a subdomain from a subset of elements.
Exactly one of element_mask and element_indices should be provided.
- Parameters:
domain (GeometryDomain) – the containing domain
element_mask (array | None) – Array of length
domain.element_count()
indicating which elements should be included. Array values must be either1
(selected) or0
(not selected).element_indices (array | None) – Explicit array of element indices to include
temporary_store (TemporaryStore | None)
- class warp.fem.Polynomial(value)[source]#
Polynomial family defining interpolation nodes over an interval
- GAUSS_LEGENDRE = 'GL'#
Gauss–Legendre 1D polynomial family (does not include endpoints)
- LOBATTO_GAUSS_LEGENDRE = 'LGL'#
Lobatto–Gauss–Legendre 1D polynomial family (includes endpoints)
- EQUISPACED_CLOSED = 'closed'#
Closed 1D polynomial family with uniformly distributed nodes (includes endpoints)
- EQUISPACED_OPEN = 'open'#
Open 1D polynomial family with uniformly distributed nodes (does not include endpoints)
- class warp.fem.RegularQuadrature(domain, order, family=None)[source]#
Bases:
Quadrature
Regular quadrature formula, using a constant set of quadrature points per element
- Parameters:
domain (GeometryDomain)
order (int)
family (Polynomial)
- __init__(domain, order, family=None)[source]#
- Parameters:
domain (GeometryDomain)
order (int)
family (Polynomial | None)
- class warp.fem.NodalQuadrature(domain, space)[source]#
Bases:
Quadrature
Quadrature using space node points as quadrature points
Note that in contrast to the nodal=True flag for
integrate()
, using this quadrature does not imply any assumption about orthogonality of shape functions, and is thus safe to use for arbitrary integrands.- Parameters:
domain (GeometryDomain)
space (FunctionSpace)
- __init__(domain, space)[source]#
- Parameters:
domain (GeometryDomain)
space (FunctionSpace)
- class warp.fem.ExplicitQuadrature(domain, points, weights)[source]#
Bases:
Quadrature
Quadrature using explicit per-cell points and weights.
The number of quadrature points per cell is assumed to be constant and deduced from the shape of the points and weights arrays. Quadrature points may be provided for either the whole geometry or just the domain’s elements.
- Parameters:
domain (GeometryDomain) – Domain of definition of the quadrature formula
points (wp.array2d(dtype=Coords)) – 2d array of shape
(domain.element_count(), points_per_cell)
or(domain.geometry_element_count(), points_per_cell)
containing the coordinates of each quadrature point.weights (wp.array2d(dtype=float)) – 2d array of shape
(domain.element_count(), points_per_cell)
or(domain.geometry_element_count(), points_per_cell)
containing the weight for each quadrature point.
See also:
PicQuadrature
- __init__(domain, points, weights)[source]#
- Parameters:
domain (GeometryDomain)
points (wp.array2d(dtype=Coords))
weights (wp.array2d(dtype=float))
- class warp.fem.PicQuadrature(
- domain,
- positions,
- measures=None,
- requires_grad=False,
- temporary_store=None,
Bases:
Quadrature
Particle-based quadrature formula, using a global set of points unevenly spread out over geometry elements.
Useful for Particle-In-Cell and derived methods.
- Parameters:
domain (GeometryDomain) – Underlying domain for the quadrature
positions (wp.array(dtype=wp.vecXd) | Tuple[wp.array(dtype=ElementIndex), wp.array(dtype=Coords)]) – Either an array containing the world positions of all particles, or a tuple of arrays containing the cell indices and coordinates for each particle. Note that the former requires the underlying geometry to define a global
Geometry.cell_lookup()
method; currently this is only available forGrid2D
andGrid3D
.measures (wp.array(dtype=float) | None) – Array containing the measure (area/volume) of each particle, used to defined the integration weights. If
None
, defaults to the cell measure divided by the number of particles in the cell.requires_grad (bool) – Whether gradients should be allocated for the computed quantities
temporary_store (TemporaryStore) – shared pool from which to allocate temporary arrays
- __init__(
- domain,
- positions,
- measures=None,
- requires_grad=False,
- temporary_store=None,
- Parameters:
domain (GeometryDomain)
positions (wp.array(dtype=wp.vecXd) | Tuple[wp.array(dtype=ElementIndex), wp.array(dtype=Coords)])
measures (wp.array(dtype=float) | None)
requires_grad (bool)
temporary_store (TemporaryStore)
Function Spaces#
- warp.fem.make_polynomial_space(
- geo,
- dtype=float,
- dof_mapper=None,
- degree=1,
- element_basis=None,
- discontinuous=False,
- family=None,
Equips a geometry with a collocated, polynomial function space. Equivalent to successive calls to
make_polynomial_basis_space()
then make_collocated_function_space, make_covariant_function_space or make_contravariant_function_space.- Parameters:
geo (Geometry) – the Geometry on which to build the space
dtype (type) – value type the function space. If
dof_mapper
is provided, the value type from the DofMapper will be used instead.dof_mapper (DofMapper | None) – mapping from node degrees of freedom to function values, defaults to Identity. Useful for reduced coordinates, e.g.
SymmetricTensorMapper
maps 2x2 (resp 3x3) symmetric tensors to 3 (resp 6) degrees of freedom.degree (int) – polynomial degree of the per-element shape functions
discontinuous (bool) – if True, use Discontinuous Galerkin shape functions. Discontinuous is implied if degree is 0, i.e, piecewise-constant shape functions.
element_basis (ElementBasis | None) – type of basis function for the individual elements
family (Polynomial | None) – Polynomial family used to generate the shape function basis. If not provided, a reasonable basis is chosen.
- Returns:
the constructed function space
- Return type:
CollocatedFunctionSpace
- warp.fem.make_polynomial_basis_space(
- geo,
- degree=1,
- element_basis=None,
- discontinuous=False,
- family=None,
Equips a geometry with a polynomial basis.
- Parameters:
geo (Geometry) – the Geometry on which to build the space
degree (int) – polynomial degree of the per-element shape functions
discontinuous (bool) – if True, use Discontinuous Galerkin shape functions. Discontinuous is implied if degree is 0, i.e, piecewise-constant shape functions.
element_basis (ElementBasis | None) – type of basis function for the individual elements
family (Polynomial | None) – Polynomial family used to generate the shape function basis. If not provided, a reasonable basis is chosen.
- Returns:
the constructed basis space
- Return type:
- warp.fem.make_collocated_function_space(
- basis_space,
- dtype=float,
- dof_mapper=None,
Constructs a function space from a scalar-valued basis space and a value type, such that all degrees of freedom of the value type are stored at each of the basis nodes.
- Parameters:
geo – the Geometry on which to build the space
dtype (type) – value type the function space. If
dof_mapper
is provided, the value type from the DofMapper will be used instead.dof_mapper (DofMapper | None) – mapping from node degrees of freedom to function values, defaults to Identity. Useful for reduced coordinates, e.g.
SymmetricTensorMapper
maps 2x2 (resp 3x3) symmetric tensors to 3 (resp 6) degrees of freedom.basis_space (BasisSpace)
- Returns:
the constructed function space
- Return type:
CollocatedFunctionSpace
- warp.fem.make_covariant_function_space(basis_space)[source]#
Constructs a covariant function space from a vector-valued basis space
- Parameters:
basis_space (BasisSpace)
- Return type:
CovariantFunctionSpace
- warp.fem.make_contravariant_function_space(basis_space)[source]#
Constructs a contravariant function space from a vector-valued basis space
- Parameters:
basis_space (BasisSpace)
- Return type:
ContravariantFunctionSpace
- warp.fem.make_space_partition(
- space=None,
- geometry_partition=None,
- space_topology=None,
- with_halo=True,
- device=None,
- temporary_store=None,
Computes the subset of nodes from a function space topology that touch a geometry partition
Either space_topology or space must be provided (and will be considered in that order).
- Parameters:
space (FunctionSpace | None) – (deprecated) the function space defining the topology if space_topology is
None
.geometry_partition (GeometryPartition | None) – The subset of the space geometry. If not provided, use the whole geometry.
space_topology (SpaceTopology | None) – the topology of the function space to consider. If
None
, deduced from space.with_halo (bool) – if True, include the halo nodes (nodes from exterior frontier cells to the partition)
device – Warp device on which to perform and store computations
temporary_store (TemporaryStore | None)
- Returns:
the resulting space partition
- Return type:
- warp.fem.make_space_restriction(
- space=None,
- space_partition=None,
- domain=None,
- space_topology=None,
- device=None,
- temporary_store=None,
Restricts a function space partition to a Domain, i.e. a subset of its elements.
One of space_partition, space_topology, or space must be provided (and will be considered in that order).
- Parameters:
space (FunctionSpace | None) – (deprecated) if neither space_partition nor space_topology are provided, the space defining the topology to restrict
space_partition (SpacePartition | None) – the subset of nodes from the space topology to consider
domain (GeometryDomain | None) – the domain to restrict the space to, defaults to all cells of the space geometry or partition.
space_topology (SpaceTopology | None) – the space topology to be restricted, if space_partition is
None
.device – device on which to perform and store computations
temporary_store (Optional[warp.fem.cache.TemporaryStore]) – shared pool from which to allocate temporary arrays
- Return type:
- class warp.fem.ElementBasis(value)[source]#
Choice of basis function to equip individual elements
- LAGRANGE = 'P'#
Lagrange basis functions \(P_k\) for simplices, tensor products \(Q_k\) for squares and cubes
- SERENDIPITY = 'S'#
Serendipity elements \(S_k\), corresponding to Lagrange nodes with interior points removed (for degree <= 3)
- NONCONFORMING_POLYNOMIAL = 'dP'#
Simplex Lagrange basis functions \(P_{kd}\) embedded into non conforming reference elements (e.g. squares or cubes). Discontinuous only.
- NEDELEC_FIRST_KIND = 'N1'#
Nédélec (first kind) H(curl) shape functions. Should be used with covariant function space.
- RAVIART_THOMAS = 'RT'#
Raviart-Thomas H(div) shape functions. Should be used with contravariant function space.
- class warp.fem.SymmetricTensorMapper(dtype, mapping=Mapping.VOIGT)[source]#
Bases:
DofMapper
Orthonormal isomorphism from R^{n (n+1)} to nxn symmetric tensors, using usual L2 norm for vectors and half Frobenius norm, (tau : tau)/2 for tensors.
- Parameters:
dtype (type)
mapping (Mapping)
- class warp.fem.SkewSymmetricTensorMapper(dtype)[source]#
Bases:
DofMapper
Orthonormal isomorphism from R^{n (n-1)} to nxn skew-symmetric tensors, using usual L2 norm for vectors and half Frobenius norm, (tau : tau)/2 for tensors.
- Parameters:
dtype (type)
- class warp.fem.PointBasisSpace(quadrature)[source]#
Bases:
BasisSpace
An unstructured
BasisSpace
that is non-zero at a finite set of points only.The node locations and nodal quadrature weights are defined by a
Quadrature
formula.- Parameters:
quadrature (Quadrature)
- __init__(quadrature)[source]#
- Parameters:
quadrature (Quadrature)
Fields#
- warp.fem.make_test(
- space,
- space_restriction=None,
- space_partition=None,
- domain=None,
- device=None,
Constructs a test field over a function space or its restriction
- Parameters:
space (FunctionSpace) – the function space
space_restriction (SpaceRestriction | None) – restriction of the space topology to a domain
space_partition (SpacePartition | None) – if space_restriction is
None
, the optional subset of node indices to considerdomain (GeometryDomain | None) – if space_restriction is
None
, optional subset of elements to considerdevice – Warp device on which to perform and store computations
- Returns:
the test field
- Return type:
- warp.fem.make_trial(
- space,
- space_restriction=None,
- space_partition=None,
- domain=None,
Constructs a trial field over a function space or partition
- Parameters:
space (FunctionSpace) – the function space or function space restriction
space_restriction (SpaceRestriction | None) – restriction of the space topology to a domain
space_partition (SpacePartition | None) – if space_restriction is
None
, the optional subset of node indices to considerdomain (GeometryDomain | None) – if space_restriction is
None
, optional subset of elements to considerdevice – Warp device on which to perform and store computations
- Returns:
the trial field
- Return type:
- warp.fem.make_discrete_field(space, space_partition=None)[source]#
Constructs a zero-initialized discrete field over a function space or partition
See also:
warp.fem.FunctionSpace.make_field()
- Parameters:
space (FunctionSpace)
space_partition (SpacePartition | None)
- Return type:
- class warp.fem.ImplicitField(
- domain,
- func,
- values=None,
- grad_func=None,
- div_func=None,
- degree=0,
Bases:
GeometryField
Field defined from an arbitrary function over a domain. Does not support autodiff yet, so if gradient/divergence evaluation is required corresponding functions must be provided.
- Parameters:
domain (GeometryDomain) – Domain over which the field is defined
func (Function) – Warp function evaluating the field at a given position. Must accept at least one argument, with the first argument being the evaluation position (
wp.vec2
orwp.vec3
).values (Dict[str, Any] | None) – Optional dictionary of additional argument values to be passed to the evaluation function.
grad_func (Function | None) – Optional gradient evaluation function; must take same arguments as func
div_func (Function | None) – Optional divergence evaluation function; must take same arguments as func
degree – Optional hint for automatic determination of quadrature orders when integrating this field
- __init__(
- domain,
- func,
- values=None,
- grad_func=None,
- div_func=None,
- degree=0,
- Parameters:
domain (GeometryDomain)
func (Function)
grad_func (Function | None)
div_func (Function | None)
- class warp.fem.UniformField(domain, value)[source]#
Bases:
GeometryField
Field defined as a constant value over a domain.
- Parameters:
domain (GeometryDomain) – Domain over which the field is defined
value (Any) – Uniform value over the domain
- __init__(domain, value)[source]#
- Parameters:
domain (GeometryDomain)
value (Any)
- class warp.fem.NonconformingField(domain, field, background=0.0)[source]#
Bases:
GeometryField
Field defined as the map of a DiscreteField over a non-conforming geometry.
- Parameters:
domain (GeometryDomain) – The new domain over which the nonconforming field will be evaluated
field (DiscreteField) – Nonconforming discrete field
background (Any) – Uniform value or domain-conforming field determining the value outside of the geometry of definition of field
- __init__(domain, field, background=0.0)[source]#
- Parameters:
domain (GeometryDomain)
field (DiscreteField)
background (Any)
- warp.fem.make_restriction(
- field,
- space_restriction=None,
- domain=None,
- device=None,
Restricts a discrete field to a subset of elements.
- Parameters:
field (DiscreteField) – the discrete field to restrict
space_restriction (SpaceRestriction | None) – the function space restriction defining the subset of elements to consider
domain (GeometryDomain | None) – if
space_restriction
is not provided, theDomain
defining the subset of elements to considerdevice – Warp device on which to perform and store computations
- Returns:
the field restriction
- Return type:
Boundary Conditions#
- warp.fem.normalize_dirichlet_projector(projector_matrix, fixed_value=None)[source]#
Scale projector so that it becomes idempotent, and apply the same scaling to fixed_value if provided
- warp.fem.project_linear_system(
- system_matrix,
- system_rhs,
- projector_matrix,
- fixed_value=None,
- normalize_projector=True,
Projects both the left-hand-side and right-hand-side of a linear system to enforce Dirichlet boundary conditions
If normalize_projector is True, first apply scaling so that the projector_matrix is idempotent
Adaptivity#
- warp.fem.adaptive_nanogrid_from_hierarchy(
- grids,
- grading=None,
- temporary_store=None,
Constructs a
warp.fem.AdaptiveNanogrid
from a non-overlapping grid hierarchy.Warning: The result is undefined if there are partial overlaps between levels, that is if a cell at level l is only partially covered by cells at levels l-1 or lower.
- Parameters:
grids (List[Volume]) – List of sparse Volumes, from finest to coarsest
grading (str | None) – Supplementary grading condition, may be
None
, “face” or “vertex”; seeenforce_nanogrid_grading()
temporary_store (TemporaryStore | None) – Storage for temporary allocations
- Return type:
- warp.fem.adaptive_nanogrid_from_field(
- coarse_grid,
- level_count,
- refinement_field,
- samples_per_voxel=64,
- grading=None,
- temporary_store=None,
Constructs a
warp.fem.AdaptiveNanogrid
from a coarse grid and a refinement field.- Parameters:
coarse_grid (Volume) – Base grid from which to start refining. No voxels will be added outside of the base grid.
level_count (int) – Maximum number of refinement levels
refinement_field (GeometryField) – Scalar field used as a refinement oracle. If the returned value is negative, the corresponding voxel will be carved out. Positive values indicate the desired refinement with 0.0 corresponding to the finest level and 1.0 to the coarsest level.
samples_per_voxel (int) – How many samples to use for evaluating the refinement field within each voxel
grading (str | None) – Supplementary grading condition, may be
None
, “face” or “vertex”; seeenforce_nanogrid_grading()
temporary_store (TemporaryStore | None) – Storage for temporary allocations
- Return type:
Memory Management#
- warp.fem.set_default_temporary_store(temporary_store)[source]#
Globally sets the default
TemporaryStore
instance to use for temporary allocations inwarp.fem
functions.If the default temporary store is set to
None
, temporary allocations are not persisted unless aTemporaryStore
is provided at a per-function granularity.- Parameters:
temporary_store (TemporaryStore | None)
- warp.fem.borrow_temporary(
- temporary_store,
- shape,
- dtype,
- pinned=False,
- requires_grad=False,
- device=None,
Borrows and returns a temporary array with specified attributes from a shared pool.
If an array with sufficient capacity and matching desired attributes is already available in the pool, it will be returned. Otherwise, a new allocation will be performed.
- Parameters:
temporary_store (TemporaryStore | None) – the shared pool to borrow the temporary from. If temporary_store is
None
, the global default temporary store, if set, will be used.shape (int | Tuple[int]) – desired dimensions for the temporary array
dtype (type) – desired data type for the temporary array
pinned (bool) – whether a pinned allocation is desired
device – device on which the memory should be allocated; if
None
, the current device will be used.requires_grad (bool)
- Return type:
- warp.fem.borrow_temporary_like(array, temporary_store)[source]#
Borrows and returns a temporary array with the same attributes as another array or temporary.
- Parameters:
array (array | Temporary) – Warp or temporary array to read the desired attributes from
temporary_store (TemporaryStore | None) – the shared pool to borrow the temporary from. If temporary_store is
None
, the global default temporary store, if set, will be used.
- Return type:
Interfaces#
Interface classes are not meant to be constructed directly, but can be derived from extend the built-in functionality.
- class warp.fem.Geometry[source]#
Interface class for discrete geometries
A geometry is composed of cells and sides. Sides may be boundary or interior (between cells).
- boundary_side_count()[source]#
Number of boundary sides (sides with a single neighbour cell) in the geometry
- __init__()#
- class warp.fem.GeometryPartition(geometry)[source]#
Base class for geometry partitions, i.e. subset of cells and sides
- Parameters:
geometry (Geometry)
- class warp.fem.GeometryDomain(geometry)[source]#
Interface class for domains, i.e. (partial) views of elements in a Geometry
- Parameters:
geometry (Geometry | GeometryPartition)
- __init__(geometry)[source]#
- Parameters:
geometry (Geometry | GeometryPartition)
- class warp.fem.Quadrature(domain)[source]#
Interface class for quadrature rules
- Parameters:
domain (GeometryDomain)
- __init__(domain)[source]#
- Parameters:
domain (GeometryDomain)
- class warp.fem.FunctionSpace(topology)[source]#
Interface class for function spaces, i.e. geometry + interpolation basis
- The value of a function f at a position x is generally computed as
f(x) = L(x)[sum_i f_i N_i(x)]
- with:
f_i
the value of the ith node’s degrees-of-freedom (dof)N_i(x)
the weight associated to the node at xL(x)
local linear transformation from node-space to world-space
- Parameters:
topology (SpaceTopology)
- __init__(topology)[source]#
- Parameters:
topology (SpaceTopology)
- property topology: SpaceTopology[source]#
Underlying geometry
- trace()[source]#
Trace of the function space over lower-dimensional elements of the geometry
- Return type:
- make_field(space_partition=None)[source]#
Creates a zero-initialized discrete field over the function space holding values for all degrees of freedom of nodes in a space partition
- Parameters:
space_partition – If provided, the subset of nodes to consider
See also:
make_space_partition()
- class warp.fem.SpaceTopology(geometry, max_nodes_per_element)[source]#
Interface class for defining the topology of a function space.
The topology only considers the indices of the nodes in each element, and as such, the connectivity pattern of the function space. It does not specify the actual location of the nodes within the elements, or the valuation function.
- class warp.fem.BasisSpace(topology)[source]#
Interface class for defining a shape function space over a geometry.
A basis space makes it easy to define multiple function spaces sharing the same basis (and thus nodes) but with different valuation functions; however, it is not a required component of a function space.
See also:
make_polynomial_basis_space()
,make_collocated_function_space()
- Parameters:
topology (SpaceTopology)
- __init__(topology)[source]#
- Parameters:
topology (SpaceTopology)
- property topology: SpaceTopology[source]#
Underlying topology of the basis space
- class warp.fem.space.shape.ShapeFunction[source]#
Interface class for defining scalar-valued shape functions over a single element
- __init__()#
- class warp.fem.SpacePartition(space_topology, geo_partition)[source]#
- Parameters:
space_topology (SpaceTopology)
geo_partition (GeometryPartition)
- __init__(space_topology, geo_partition)[source]#
- Parameters:
space_topology (SpaceTopology)
geo_partition (GeometryPartition)
- class warp.fem.SpaceRestriction(
- space_partition,
- domain,
- device=None,
- temporary_store=None,
Restriction of a space partition to a given GeometryDomain
- Parameters:
space_partition (SpacePartition)
domain (GeometryDomain)
temporary_store (TemporaryStore)
- __init__(
- space_partition,
- domain,
- device=None,
- temporary_store=None,
- Parameters:
space_partition (SpacePartition)
domain (GeometryDomain)
temporary_store (TemporaryStore | None)
- class warp.fem.DofMapper[source]#
Base class from mapping node degrees of freedom to function values
- __init__()#
- class warp.fem.DiscreteField(space, space_partition)[source]#
Bases:
SpaceField
Explicitly-valued field defined over a partition of a discrete function space
- Parameters:
space (FunctionSpace)
space_partition (SpacePartition)
- __init__(space, space_partition)[source]#
- Parameters:
space (FunctionSpace)
space_partition (SpacePartition)
- class warp.fem.field.FieldRestriction(space_restriction, field)[source]#
Restriction of a discrete field to a given GeometryDomain
- Parameters:
space_restriction (SpaceRestriction)
field (DiscreteField)
- __init__(space_restriction, field)[source]#
- Parameters:
space_restriction (SpaceRestriction)
field (DiscreteField)
- class warp.fem.field.GeometryField[source]#
Bases:
FieldLike
Base class for fields defined over a geometry
- make_deformed_geometry(relative=True)[source]#
Returns a deformed version of the underlying geometry, with positions displaced according to this field’s values.
- Parameters:
relative – If
True
, the field is interpreted as a relative displacement over the original geometry. IfFalse
, the field values are interpreted as absolute positions.- Return type:
- __init__()#
- class warp.fem.field.SpaceField(space, space_partition)[source]#
Bases:
GeometryField
Base class for fields defined over a function space
- Parameters:
space (FunctionSpace)
space_partition (SpacePartition)
- __init__(space, space_partition)[source]#
- Parameters:
space (FunctionSpace)
space_partition (SpacePartition)
- class warp.fem.field.TestField(space_restriction, space)[source]#
Bases:
AdjointField
Field defined over a space restriction that can be used as a test function.
In order to reuse computations, it is possible to define the test field using a SpaceRestriction defined for a different value type than the test function value type, as long as the node topology is similar.
- Parameters:
space_restriction (SpaceRestriction)
space (FunctionSpace)
- __init__(space_restriction, space)[source]#
- Parameters:
space_restriction (SpaceRestriction)
space (FunctionSpace)
- class warp.fem.field.TrialField(space, space_partition, domain)[source]#
Bases:
AdjointField
Field defined over a domain that can be used as a trial function
- Parameters:
space (FunctionSpace)
space_partition (SpacePartition)
domain (GeometryDomain)
- __init__(space, space_partition, domain)[source]#
- Parameters:
space (FunctionSpace)
space_partition (SpacePartition)
domain (GeometryDomain)
- class warp.fem.TemporaryStore[source]#
Shared pool of temporary arrays that will be persisted and reused across invocations of
warp.fem
functions.A
TemporaryStore
instance may either be passed explicitly towarp.fem
functions that accept such an argument, for instanceintegrate.integrate()
, or can be set globally as the default store usingset_default_temporary_store()
.By default, there is no default temporary store, so that temporary allocations are not persisted.
- class warp.fem.cache.Temporary(*args, **kwargs)[source]#
Handle over a temporary array from a
TemporaryStore
.The array will be automatically returned to the temporary pool for reuse upon destruction of this object, unless the temporary is explicitly detached from the pool using
detach()
. The temporary may also be explicitly returned to the pool before destruction usingrelease()
.