Reference
This page provides comprehensive documentation for all modules, classes, and functions in TTFEMesh.
Domain Module
- class Curve[source]
Bases:
ABCAbstract base class for a curve in the domain. Defines the interface for all curve implementations.
- abstract evaluate(t: ndarray | float) ndarray[source]
Evaluate the curve at parameter values t.
- Parameters:
t (Union[np.ndarray, float]) – Array of or scalar parameter values in [-1, 1].
- Returns:
Array of shape (len(t), 2) with (x, y) coordinates.
- Return type:
np.ndarray
- abstract tangent(t: ndarray | float) ndarray[source]
Compute the tangent vector (not normalized) to the curve at parameter values t.
- Parameters:
t (Union[np.ndarray, float]) – Array of or scalar parameter values in [-1, 1].
- Returns:
Array of shape (len(t), 2) with tangent vectors.
- Return type:
np.ndarray
- class Line2D(start: tuple[float, float], end: tuple[float, float])[source]
Bases:
CurveA line segment in 2D space.
Example
>>> from ttfemesh.domain import Line2D >>> from ttfemesh.utils import plot_curve_with_tangents >>> line = Line2D((0, 0), (1, 1)) >>> print(line) >>> plot_curve_with_tangents(line, "Line")
- __init__(start: tuple[float, float], end: tuple[float, float])[source]
Initialize a line segment from start to end.
- class CircularArc2D(center: tuple[float, float], radius: float, start_angle: float = 0.0, angle_sweep: float = 3.141592653589793)[source]
Bases:
CurveA circular arc in 2D space.
Example
>>> import numpy as np >>> from ttfemesh.domain import CircularArc2D >>> from ttfemesh.utils import plot_curve_with_tangents >>> circular_arc = CircularArc2D((0, 0), 1, np.pi/2., 0.5*np.pi) >>> print(circular_arc) >>> plot_curve_with_tangents(circular_arc, "Circular Arc")
- __init__(center: tuple[float, float], radius: float, start_angle: float = 0.0, angle_sweep: float = 3.141592653589793)[source]
Initialize a circular arc defined by a center, radius, and angle sweep.
- class ParametricCurve2D(x_func: Callable[[ndarray], ndarray], y_func: Callable[[ndarray], ndarray])[source]
Bases:
CurveA parametric curve in 2D space.
Example
>>> from ttfemesh.domain import ParametricCurve2D >>> from ttfemesh.utils import plot_curve_with_tangents >>> parametric_curve = ParametricCurve2D( ... lambda t: np.sin(t * np.pi), ... lambda t: np.cos(t * np.pi) ... ) >>> print(parametric_curve) >>> plot_curve_with_tangents(parametric_curve, "Parametric Curve")
- __init__(x_func: Callable[[ndarray], ndarray], y_func: Callable[[ndarray], ndarray])[source]
Initialize a parametric curve defined by functions x(t) and y(t). Uses a finite difference approximation to compute the tangent.
- Parameters:
x_func (Callable[[np.ndarray], np.ndarray]) – Function x(t) where t is in [-1, 1].
y_func (Callable[[np.ndarray], np.ndarray]) – Function y(t) where t is in [-1, 1].
- class Subdomain[source]
Bases:
ABCAbstract base class for a subdomain in the domain. The subdomains are intended to “glue” more complex domains together.
- class Subdomain2D(curves: Sequence[Curve])[source]
Bases:
SubdomainA 2D subdomain defined by 4 boundary curves. The curves must connect properly to form a closed subdomain. The start and end points of the curves must be ordered counter-clockwise. Note that the curves are considered to be ordered as follows: bottom (curve 0), right (curve 1), top (curve 2), left (curve 3). This is important for the boundary condition to work correctly. It may lead to confusion if, e.g., your curve 0 is visually the right edge of the domain.
Example: >>> import numpy as np >>> from ttfemesh.domain import CircularArc2D, Line2D >>> from ttfemesh.domain import Subdomain2D
>>> arc0 = CircularArc2D((0, 0), 1, np.pi/2., 0.5*np.pi) >>> line1 = Line2D((-1, 0), (1, -1)) >>> line2 = Line2D((1, -1), (2, 1)) >>> line3 = Line2D((2, 1), (0, 1))
>>> subdomain = Subdomain2D([arc0, line1, line2, line3]) >>> subdomain.plot()
- __init__(curves: Sequence[Curve])[source]
Initialize a 2D subdomain defined by 4 boundary curves.
- Parameters:
curves (Sequence[Curve]) – List of 4 boundary curves.
- class Quad(curves: Sequence[Line2D])[source]
Bases:
Subdomain2DQuadrilateral subdomain defined by 4 boundary lines. Note that the lines are considered to be ordered as follows: bottom (line 0), right (line 1), top (line 2), left (line 3). This is important for the boundary condition to work correctly. It may lead to confusion if, e.g., your line 0 is visually the right edge of the domain.
Recommend using the QuadFactory or the RectangleFactory to create a quadrilateral subdomain.
Example: >>> from ttfemesh.domain import Line2D >>> from ttfemesh.domain import Quad
>>> line0 = Line2D((0, 1), (-1, 0)) >>> line1 = Line2D((-1, 0), (1, -1)) >>> line2 = Line2D((1, -1), (2, 1)) >>> line3 = Line2D((2, 1), (0, 1))
>>> subdomain = Quad([line0, line1, line2, line3]) >>> subdomain.plot()
- class RectangleFactory[source]
Bases:
SubdomainFactoryFactory class for creating rectangle subdomains.
Example
>>> from ttfemesh.domain import RectangleFactory >>> lower_left = (0, 0) >>> upper_right = (2, 1) >>> rectangle = RectangleFactory.create(lower_left, upper_right) >>> rectangle.plot()
- class QuadFactory[source]
Bases:
SubdomainFactoryFactory class for creating quadrilateral subdomains. Note that the lines are considered to be ordered as follows: bottom (line 0), right (line 1), top (line 2), left (line 3). This is important for the boundary condition to work correctly. It may lead to confusion if, e.g., your line 0 is visually the right edge of the domain.
Example
>>> from ttfemesh.domain import QuadFactory >>> p1 = (3, 0) >>> p2 = (1, -3) >>> p3 = (7, -4) >>> p4 = (5, -1) >>> quad3 = QuadFactory.create(p1, p2, p3, p4) >>> quad3.plot()
- class VertexConnection2D(connection: List[Tuple[int, int, Literal['start', 'end']]])[source]
Bases:
SubdomainConnection2DInitialize a 2D vertex connection. The subdomain indexes reference into the list of subdomains passed to the Domain constructor.
- Parameters:
connection (List[Tuple[int, int, CurvePosition]]) – List of subdomains sharing this vertex. Each connection is a tuple of (subdomain index, curve index, position). Curve position is either “start” or “end”.
Example: >>> from ttfemesh.domain import RectangleFactory, CurveConnection2D, VertexConnection2D >>> from ttfemesh.domain import Domain2D >>> lower_left = (0, 0) >>> upper_right = (2, 1) >>> rectangle1 = RectangleFactory.create(lower_left, upper_right)
>>> lower_left = (2, 0) >>> upper_right = (3, 1) >>> rectangle2 = RectangleFactory.create(lower_left, upper_right)
>>> lower_left = (-2, 1) >>> upper_right = (0, 2) >>> rectangle3 = RectangleFactory.create(lower_left, upper_right)
>>> domain_idxs = [0, 1] >>> curve_idxs = [1, 3] >>> edge = CurveConnection2D(domain_idxs, curve_idxs)
>>> vertex_idxs = [(0, 3, "start"), (2, 0, "end")] >>> vertex = VertexConnection2D(vertex_idxs)
>>> domain = Domain2D([rectangle1, rectangle2, rectangle3], [edge, vertex]) >>> domain.plot()
- validate(subdomains: List[Subdomain2D], tol: float = 1e-06)[source]
Validate that all specified subdomains, curves, and positions share the given vertex.
- Parameters:
subdomains (List[Subdomain2D]) – List of subdomains in the domain.
tol (float) – Tolerance for point-wise comparison
- Raises:
ValueError – If the vertex connections are not consistent.
- get_connection_pairs() List[Tuple[Tuple[int, int], Tuple[int, int], Tuple[Literal['start', 'end'], Literal['start', 'end']]]][source]
Get all unique pairs of connected subdomains with their curve indices and positions.
Get the shared vertex between the connected subdomains.
- Parameters:
subdomains (List[Subdomain2D]) – List of subdomains in the domain.
- Returns:
Shared vertex coordinates.
- Return type:
np.ndarray
- class CurveConnection2D(subdomains_indices: Tuple[int, int], curve_indices: Tuple[int, int])[source]
Bases:
SubdomainConnection2DInitialize a curve connection between two subdomains. Only two subdomains can be connected by a curve.
- Parameters:
Example: >>> from ttfemesh.domain import RectangleFactory, CurveConnection2D, VertexConnection2D >>> from ttfemesh.domain import Domain2D >>> lower_left = (0, 0) >>> upper_right = (2, 1) >>> rectangle1 = RectangleFactory.create(lower_left, upper_right)
>>> lower_left = (2, 0) >>> upper_right = (3, 1) >>> rectangle2 = RectangleFactory.create(lower_left, upper_right)
>>> lower_left = (-2, 1) >>> upper_right = (0, 2) >>> rectangle3 = RectangleFactory.create(lower_left, upper_right)
>>> domain_idxs = [0, 1] >>> curve_idxs = [1, 3] >>> edge = CurveConnection2D(domain_idxs, curve_idxs)
>>> vertex_idxs = [(0, 3, "start"), (2, 0, "end")] >>> vertex = VertexConnection2D(vertex_idxs)
>>> domain = Domain2D([rectangle1, rectangle2, rectangle3], [edge, vertex]) >>> domain.plot()
- validate(subdomains: List[Subdomain2D], num_points: int = 100, tol: float = 1e-06)[source]
Validate that the curves are approximately equal.
- Parameters:
subdomains (List[Subdomain2D]) – List of subdomains in the domain.
num_points (int) – Number of points to sample along the curve.
tol (float) – Tolerance for point-wise comparison.
Get the shared curve between the connected subdomains.
- Parameters:
subdomains (List[Subdomain2D]) – List of subdomains in the domain.
- Returns:
Shared curve.
- Return type:
- class DirichletBoundary2D(boundary: List[Tuple[int, int]])[source]
Bases:
BoundaryConditionImplements a Dirichlet boundary condition for a 2D curve. Boundary values are implicitly assumed to be zero.
Example: >>> from ttfemesh.domain import RectangleFactory, CurveConnection2D, VertexConnection2D >>> from ttfemesh.domain import DirichletBoundary2D, Domain2D >>> lower_left = (0, 0) >>> upper_right = (2, 1) >>> rectangle1 = RectangleFactory.create(lower_left, upper_right)
>>> lower_left = (2, 0) >>> upper_right = (3, 1) >>> rectangle2 = RectangleFactory.create(lower_left, upper_right)
>>> lower_left = (-2, 1) >>> upper_right = (0, 2) >>> rectangle3 = RectangleFactory.create(lower_left, upper_right)
>>> domain_idxs = [0, 1] >>> curve_idxs = [1, 3] >>> edge = CurveConnection2D(domain_idxs, curve_idxs)
>>> vertex_idxs = [(0, 3, "start"), (2, 0, "end")] >>> vertex = VertexConnection2D(vertex_idxs)
>>> bc = DirichletBoundary2D([(1, 1), (2, 3)])
>>> domain = Domain2D([rectangle1, rectangle2, rectangle3], [edge, vertex], bc) >>> domain.plot()
- validate(subdomains: List[Subdomain2D])[source]
Validate the boundary condition. Ensure that the specified curve exists.
- Parameters:
subdomains (List[Subdomain]) – List of subdomains in the domain.
- class Domain(subdomains: Sequence[Subdomain], connections: Sequence[SubdomainConnection], boundary_condition: BoundaryCondition | None = None)[source]
Bases:
ABCDomain class that contains subdomains and their connections.
- __init__(subdomains: Sequence[Subdomain], connections: Sequence[SubdomainConnection], boundary_condition: BoundaryCondition | None = None)[source]
Initialize a domain with subdomains and their connections.
- Parameters:
subdomains (Sequence[Subdomain]) – List of subdomains in the domain.
connections (Sequence[SubdomainConnection]) – List of connections between subdomains.
boundary_condition (Optional[BoundaryCondition]) – Optional boundary condition.
- get_subdomain(idx) Subdomain[source]
Get a subdomain by index.
- Parameters:
idx (int) – Index of the subdomain to get.
- Returns:
The subdomain at the given index.
- Return type:
- Raises:
ValueError – If the index is out of bounds.
- abstract property dimension
The dimension of the domain.
- class Domain2D(subdomains: Sequence[Subdomain2D], connections: Sequence[SubdomainConnection2D], boundary_condition: DirichletBoundary2D | None = None)[source]
Bases:
DomainA 2D domain with subdomains and their connections.
Example: >>> from ttfemesh.domain import RectangleFactory, CurveConnection2D, VertexConnection2D >>> from ttfemesh.domain import DirichletBoundary2D, Domain2D >>> lower_left = (0, 0) >>> upper_right = (2, 1) >>> rectangle1 = RectangleFactory.create(lower_left, upper_right)
>>> lower_left = (2, 0) >>> upper_right = (3, 1) >>> rectangle2 = RectangleFactory.create(lower_left, upper_right)
>>> lower_left = (-2, 1) >>> upper_right = (0, 2) >>> rectangle3 = RectangleFactory.create(lower_left, upper_right)
>>> domain_idxs = [0, 1] >>> curve_idxs = [1, 3] >>> edge = CurveConnection2D(domain_idxs, curve_idxs)
>>> vertex_idxs = [(0, 3, "start"), (2, 0, "end")] >>> vertex = VertexConnection2D(vertex_idxs)
>>> bc = DirichletBoundary2D([(1, 1), (2, 3)])
>>> domain = Domain2D([rectangle1, rectangle2, rectangle3], [edge, vertex], bc) >>> domain.plot()
- __init__(subdomains: Sequence[Subdomain2D], connections: Sequence[SubdomainConnection2D], boundary_condition: DirichletBoundary2D | None = None)[source]
Initialize a 2D domain with subdomains and their connections.
- Parameters:
subdomains (Sequence[Subdomain2D]) – List of 2D subdomains in the domain.
connections (Sequence[SubdomainConnection2D]) – List of connections between subdomains.
boundary_condition (Optional[DirichletBoundary2D]) – Optional 2D boundary condition.
Mesh Module
- class SubdomainMesh2D(subdomain: Subdomain2D, quadrature_rule: QuadratureRule2D, mesh_size_exponent: int, tt_cross_config: TTCrossConfig | None = None)[source]
Bases:
SubdomainMeshSubdomain mesh for a 2D finite element problem.
Example: >>> from ttfemesh.domain import RectangleFactory >>> from ttfemesh.quadrature import GaussLegendre2D >>> from ttfemesh.mesh import SubdomainMesh2D
>>> lower_left = (0, 0) >>> upper_right = (2, 1) >>> rectangle = RectangleFactory.create(lower_left, upper_right) >>> quadrature_rule = GaussLegendre2D() >>> mesh_size_exponent = 3 >>> mesh = SubdomainMesh2D(rectangle, quadrature_rule, mesh_size_exponent) >>> mesh.plot()
- __init__(subdomain: Subdomain2D, quadrature_rule: QuadratureRule2D, mesh_size_exponent: int, tt_cross_config: TTCrossConfig | None = None)[source]
Initialize a 2D subdomain mesh.
- Parameters:
subdomain (Subdomain2D) – The 2D subdomain to mesh.
quadrature_rule (QuadratureRule2D) – The quadrature rule to use.
mesh_size_exponent (int) – The exponent of the discretization size. The discretization size is 2**(mesh_size_exponent) per dimension.
tt_cross_config (Optional[TTCrossConfig]) – Configuration for the tensor train cross approximation. If None, default configuration is used.
- property dimension
Return the dimension of the mesh.
- property num_points1d
Number of points per dimension.
- property num_points
Total number of points.
- property num_elements1d
Number of elements per dimension.
- property num_elements
Total number of elements.
- property index_map
Index map for binary index to 2D tuple.
- property tt_cross_config
Configuration for the tensor train cross approximation.
- ref2domain_map(xi_eta: ndarray) ndarray[source]
Map from reference quadrilateral [-1, 1]^2 to domain.
- Parameters:
xi_eta (np.ndarray) – The reference coordinates in the quadrilateral. Of shape (num_points, 2) or (2,).
- Returns:
- The physical coordinates in the domain.
Of shape (num_points, 2).
- Return type:
np.ndarray
- ref2element_map(index: Tuple[int, int], xi_eta: ndarray) ndarray[source]
Map from reference quadrilateral [-1, 1]^2 to element indexed by (index_x, index_y).
- ref2domain_jacobian(xi_eta: ndarray) ndarray[source]
Compute the Jacobian of the reference to domain map.
- Parameters:
xi_eta (np.ndarray) – The reference coordinates in the quadrilateral. Of shape (num_points, 2) or (2,).
- Returns:
- The Jacobian of the reference to domain map.
Of shape (num_points, 2, 2).
- Return type:
np.ndarray
- ref2element_jacobian(index: Tuple[int, int], xi_eta: ndarray) ndarray[source]
Compute the Jacobian of the reference to element map.
- get_jacobian_tensor_trains() ndarray[source]
Compute the tensor train approximating the Jacobian evaluated on all elements. The tensor index corresponds to the element index. This is done for each Jacobian component and each quadrature point within the element. The output is thus a total of 4*(num_quadrature_points_per_element) tensor trains.
- Returns:
- 3D array of tensor trains for the Jacobian components.
Indexing: [quadrature_point_index, component_index_i, component_index_j].
- Return type:
np.ndarray
- get_jacobian_det_tensor_trains() ndarray[source]
Compute the tensor train approximating the Jacobian determinants evaluated on all elements.
- Returns:
- 1D array of tensor trains for the Jacobian determinants.
Indexing: [quadrature_point_index].
- Return type:
np.ndarray
- get_jacobian_invdet_tensor_trains() ndarray[source]
Compute the tensor train approximating the inverse of Jacobian determinants evaluated on all elements.
- Returns:
- 1D array of tensor trains for the inverse Jacobian determinants.
Indexing: [quadrature_point_index].
- Return type:
np.ndarray
- get_jacobian_tensors() ndarray[source]
Compute the Jacobians evaluated on all elements and all quadrature points.
- Returns:
- Jacobians.
Of shape (num_elements_x+1, num_elements_y+1, num_quadrature_points, 2, 2).
- Return type:
np.ndarray
Warning
This method is not efficient for large meshes. Intended only for small meshes for testing.
- get_jacobian_dets() ndarray[source]
Compute the determinants of the Jacobians evaluated on all elements and all quadrature points.
- Returns:
- Jacobian determinants.
Of shape (num_elements_x+1, num_elements_y+1, num_quadrature_points).
- Return type:
np.ndarray
- get_jacobian_invdets() ndarray[source]
Compute the inverse of the determinants of the Jacobians evaluated on all elements and all quadrature points.
- Returns:
- Inverse Jacobian determinants.
Of shape (num_elements_x+1, num_elements_y+1, num_quadrature_points).
- Return type:
np.ndarray
- plot_element(index: Tuple[int, int], num_points: int = 100) None[source]
Plot the 2D points generated by the ref2element_map for a given index.
- plot(num_points: int = 100) None[source]
Plot the boundaries of all elements in the mesh with interpolated curves.
- Parameters:
num_points (int) – Number of points to sample along each curve.
Warning
This method is not efficient for large meshes, call it with a small number of points for visualization purposes only.
- class QuadMesh(quad: Quad, quadrature_rule: QuadratureRule2D, mesh_size_exponent: int, tt_cross_config: TTCrossConfig | None = None)[source]
Bases:
SubdomainMesh2DMesh for a quadrilateral subdomain. The Jacobians of quadrilateral meshes depend linearly on the element index. Hence, instead of using the tensor train cross approximation for a generic subdomain, we can represent the Jacobians for all elements and all quadrature points numerically exactly with a low-rank Tensor Train.
Example: >>> from ttfemesh.domain import RectangleFactory >>> from ttfemesh.quadrature import GaussLegendre2D >>> from ttfemesh.mesh import QuadMesh
>>> lower_left = (0, 0) >>> upper_right = (2, 1) >>> rectangle = RectangleFactory.create(lower_left, upper_right) >>> quadrature_rule = GaussLegendre2D() >>> mesh_size_exponent = 3 >>> mesh = QuadMesh(rectangle, quadrature_rule, mesh_size_exponent) >>> mesh.plot()
- __init__(quad: Quad, quadrature_rule: QuadratureRule2D, mesh_size_exponent: int, tt_cross_config: TTCrossConfig | None = None)[source]
Initialize a quadrilateral mesh.
- Parameters:
quad (Quad) – The quadrilateral subdomain to mesh.
quadrature_rule (QuadratureRule2D) – The quadrature rule to use.
mesh_size_exponent (int) – The exponent of the discretization size. The discretization size is 2**(mesh_size_exponent) per dimension.
tt_cross_config (Optional[TTCrossConfig]) – Configuration for the tensor train cross approximation. If None, default configuration is used.
- bindex2dtuple(bindex: ndarray) Tuple[int, int][source]
Convert a binary index to a 2D tuple. Implements the mapping (i0, j0, i1, j1, …) -> (i, j), where i = i0 + 2*i1 + 4*i2 + … and j = j0 + 2*j1 + 4*j2 + … This is the common little-endian convention in QTT literature.
- Parameters:
bindex (np.ndarray) – A binary index of shape (2 * num_bits1d,).
- Returns:
A 2D tuple.
- Return type:
- Raises:
ValueError – If bindex is not a 1D array, does not contain an even number of elements, or contains values other than 0 or 1.
- qindex2dtuple(index: ndarray) Tuple[int, int][source]
Convert a quaternary index to a 2D tuple. The ordering of the quaternary index is assumed to be (0, 1, 2, 3) -> ((0, 0), (1, 0), (0, 1), (1, 1)), i.e., column-major with index = i + 2*j. This is consistent with the little-endian ordering of the binary index commonly used in QTT literature.
- Parameters:
index (np.ndarray) – An index of shape (num_quats,) with values in {0, 1, 2, 3}.
- Returns:
A 2D tuple.
- Return type:
- Raises:
ValueError – If index is not a 1D array or contains values other than {0, 1, 2, 3}.
- class DomainMesh(domain: Domain, quadrature_rule: QuadratureRule, mesh_size_exponent: int, basis: TensorProductBasis, tt_cross_config: TTCrossConfig | None = None)[source]
Bases:
ABCDomainMesh base class that ties together the domain, subdomain meshes, and basis functions. It provides an interface for the element jacobians of the subdomains, the element to global index maps, the boundary masks and the concatenation maps.
- __init__(domain: Domain, quadrature_rule: QuadratureRule, mesh_size_exponent: int, basis: TensorProductBasis, tt_cross_config: TTCrossConfig | None = None)[source]
Initialize a DomainMesh.
- Parameters:
domain (Domain) – The domain containing subdomains and their connections.
quadrature_rule (QuadratureRule) – Quadrature rule for integration.
mesh_size_exponent (int) – Discretization size exponent.
basis (TensorProductBasis) – The basis functions for the domain.
cross_config (Optional[TTCrossConfig]) – Optional configuration for tensor cross approximation. If None, the default configuration is used.
- get_subdomain_mesh(subdomain_index: int) SubdomainMesh[source]
Get the SubdomainMesh for a subdomain.
- Parameters:
subdomain_index (int) – The index of the subdomain.
- Returns:
The SubdomainMesh for the subdomain.
- Return type:
SubdomainMesh
- Raises:
ValueError – If the subdomain index is invalid.
- get_element2global_index_map() ndarray[source]
Get the TT-representation of transformations mapping from element index to global basis function index for all reference basis functions on a reference element in a subdomain. This map depends on the type of basis functions used and the discretization size of the subdomain.
- Parameters:
subdomain_index (int) – The index of the subdomain.
- Returns:
- A matrix of TT-representations, i.e.,
each element of the matrix is a TT-vector. Indexing of the matrix corresponds to the reference basis function indexing. For example, for a bilinear basis in 2D, the indexing is: (i, j) where i and j are the indices of the basis functions in x and y direction Specifically, (0, 0), (1, 0), (0, 1) and (1, 1), representing the four basis functions corresponding to the four vertices of the reference element: lower left, lower right, upper right and upper left, respectively. See also the documentation for the chosen Basis class.
- Return type:
np.ndarray
- get_dirichlet_masks() Dict[int, TT][source]
Get the dirichlet boundary masks.
- Returns:
- A dictionary where the keys are subdomain indices,
and the values are TT-representations of the boundary masks.
- Return type:
Dict[TensorTrain]
- class DomainMesh2D(domain: Domain, quadrature_rule: QuadratureRule, mesh_size_exponent: int, basis: TensorProductBasis, tt_cross_config: TTCrossConfig | None = None)[source]
Bases:
DomainMeshMesh for 2D domains. This is essentially a factory for SubdomainMesh2D objects.
- class DomainBilinearMesh2D(domain: Domain, quadrature_rule: QuadratureRule, mesh_size_exponent: int, tt_cross_config: TTCrossConfig | None = None)[source]
Bases:
DomainMesh2DMesh for 2D domains with bilinear basis functions. This implementation of the concatenation maps works only for bilinear basis functions.
Example: >>> from ttfemesh.domain import RectangleFactory, CurveConnection2D, VertexConnection2D >>> from ttfemesh.domain import DirichletBoundary2D, Domain2D >>> from ttfemesh.quadrature import GaussLegendre2D >>> from ttfemesh.mesh import DomainBilinearMesh2D
>>> lower_left = (0, 0) >>> upper_right = (2, 1) >>> rectangle1 = RectangleFactory.create(lower_left, upper_right)
>>> lower_left = (2, 0) >>> upper_right = (3, 1) >>> rectangle2 = RectangleFactory.create(lower_left, upper_right)
>>> lower_left = (-2, 1) >>> upper_right = (0, 2) >>> rectangle3 = RectangleFactory.create(lower_left, upper_right)
>>> domain_idxs = [0, 1] >>> curve_idxs = [1, 3] >>> edge = CurveConnection2D(domain_idxs, curve_idxs)
>>> vertex_idxs = [(0, 3, "start"), (2, 0, "end")] >>> vertex = VertexConnection2D(vertex_idxs)
>>> bc = DirichletBoundary2D([(1, 1), (2, 3)])
>>> domain = Domain2D([rectangle1, rectangle2, rectangle3], [edge, vertex], bc)
>>> quadrature_rule = GaussLegendre2D() >>> mesh_size_exponent = 3 >>> domain_mesh = DomainBilinearMesh2D(domain, quadrature_rule, mesh_size_exponent) >>> print(domain_mesh)
- __init__(domain: Domain, quadrature_rule: QuadratureRule, mesh_size_exponent: int, tt_cross_config: TTCrossConfig | None = None)[source]
Initialize a DomainMesh.
- Parameters:
domain (Domain) – The domain containing subdomains and their connections.
quadrature_rule (QuadratureRule) – Quadrature rule for integration.
mesh_size_exponent (int) – Discretization size exponent.
basis (TensorProductBasis) – The basis functions for the domain.
cross_config (Optional[TTCrossConfig]) – Optional configuration for tensor cross approximation. If None, the default configuration is used.
- get_concatenation_maps() Dict[Tuple[int, int], Tuple[TT, TT, TT]][source]
Get the TT-representations of the concatenation maps for all pairs of connected subdomains. See Section 5 of arXiv:1802.02839 for details. Pmp describes which nodes in the left domain are connected to which nodes in the right domain, Pmm describes which nodes in the left domain are to be connected, Ppp describes which nodes in the right domain are to be connected.
- Returns:
A dictionary where the keys are pairs of subdomain indices, and the values are tuples TT-representations of the connectivity maps.
- Return type:
Dict[Tuple[int, int], Tuple[TensorTrain, TensorTrain, TensorTrain]]
- Raises:
ValueError – If the connection type is not supported.
Quadrature Module
- class QuadratureRule[source]
Bases:
ABCAbstract base class for a quadrature rule.
- abstract get_points_weights() Tuple[ndarray, ndarray][source]
Retrieve the quadrature points and weights.
- class GaussLegendre(order: int = 1, dimension: int = 1)[source]
Bases:
QuadratureRuleImplements Gauss-Legendre quadrature on [-1, 1]^(dimension).
Example: >>> from ttfemesh.quadrature import GaussLegendre
>>> order = 3 >>> dim = 3 >>> qrule = GaussLegendre(order, dim)
>>> points, weights = qrule.get_points_weights()
>>> print(points) >>> print(weights)
- __init__(order: int = 1, dimension: int = 1)[source]
Initialize the Gauss-Legendre quadrature rule.
- get_points_weights() Tuple[ndarray, ndarray][source]
Get the quadrature points and weights.
- Returns:
Quadrature points and weights.
- Return type:
Tuple[np.ndarray, np.ndarray]
- class GaussLegendre2D(order: int = 1)[source]
Bases:
GaussLegendreImplements Gauss-Legendre quadrature on [-1, 1]^2.
Example: >>> from ttfemesh.quadrature import GaussLegendre2D
>>> order = 3 >>> qrule2D = GaussLegendre2D(order)
>>> points2D, weights2D = qrule2D.get_points_weights()
>>> print(points2D) >>> print(weights2D)
Basis Module
- class LinearBasis[source]
Bases:
Basis1DLinear basis functions on the reference element [-1, 1]. The basis functions are defined as: - 0.5 * (1 - x) for idx = 0 (left basis function) - 0.5 * (1 + x) for idx = 1 (right basis function)
Example
>>> from ttfemesh.basis import LinearBasis >>> basis1d = LinearBasis() >>> fig = basis1d.plot(0) >>> fig.show() >>> fig = basis1d.plot(1) >>> fig.show()
- derivative(idx: int, _: float | None = None) float[source]
Evaluate the derivative of the basis function at a given point. Derivative is constant, so the point x is not used.
- property index_range
Range of valid indices for the basis functions. 0 for the left basis function, 1 for the right basis function.
- get_element2global_ttmap(index: int, mesh_size_exponent: int) TT[source]
Get the TT-representation of a corner element index to global basis index map.
- Parameters:
- Returns:
TT-representation of the corner to global index map.
- Return type:
TensorTrain
- Raises:
ValueError – If the index is invalid.
- get_all_element2global_ttmaps(mesh_size_exponent: int) Tuple[TT, ...][source]
Get TT-representations for all indices in index_range.
- Parameters:
mesh_size_exponent (int) – Exponent of the 1D mesh size (length of TT).
- Returns:
- TT-representations of all corner-to-global index maps.
First element is the map for index 0, second element is the map for index 1.
- Return type:
Tuple[TensorTrain, …]
- get_dirichlet_mask_left(mesh_size_exponent: int) TT[source]
Get the mask for the left Dirichlet boundary condition. The mask is 1 everywhere except at the left boundary.
- Parameters:
mesh_size_exponent (int) – Exponent of the 1D mesh size (length of TT).
- Returns:
TT-representation of the Dirichlet mask.
- Return type:
TensorTrain
- get_dirichlet_mask_right(mesh_size_exponent: int) TT[source]
Get the mask for the right Dirichlet boundary condition. The mask is 1 everywhere except at the right boundary.
- Parameters:
mesh_size_exponent (int) – Exponent of the 1D mesh size (length of TT).
- Returns:
TT-representation of the Dirichlet mask.
- Return type:
TensorTrain
- get_dirichlet_mask_left_right(mesh_size_exponent: int) TT[source]
Get the mask for the left and right Dirichlet boundary conditions. The mask is 1 everywhere except at the left and right boundaries.
- Parameters:
mesh_size_exponent (int) – Exponent of the 1D mesh size (length of TT).
- Returns:
TT-representation of the Dirichlet mask.
- Return type:
TensorTrain
- class TensorProductBasis(basis_functions: List[Basis1D])[source]
Bases:
BasisAbstract base class for tensor product basis functions for arbitrary dimensions. Combines 1D basis functions to define basis functions in higher dimensions.
- __init__(basis_functions: List[Basis1D])[source]
Initialize the tensor product basis function.
- Parameters:
basis_functions (List[BasisFunction1D]) – List of 1D basis functions for each dimension.
- abstract get_element2global_ttmap(*args, **kwargs) TT[source]
Get the TT-representation of a corner element index to global basis index map.
- Returns:
TT-representation of the corner to global index map.
- Return type:
TensorTrain
- abstract get_all_element2global_ttmaps(*args, **kwargs) ndarray[source]
Get the TT-representation for all corner elements in index_range to global basis index maps.
- Returns:
- A 2D matrix of TT-representations, indexed by (i, j)
where i and j are the indices of the basis functions in each dimension.
- Return type:
np.ndarray
- abstract get_dirichlet_mask(*args, **kwargs) TT[source]
Get the mask for the Dirichlet boundary condition on the specified sides.
- Returns:
TT-representation of the Dirichlet mask.
- Return type:
TensorTrain
- property index_range
Range of valid indices for the basis functions.
- evaluate(idx: List[int], x: List[float]) float[source]
Evaluate the tensor product basis function at a given point.
- class BilinearBasis[source]
Bases:
TensorProductBasisBilinear basis functions on the reference element [-1, 1]^2. The basis functions are defined as: - 0.25 * (1 - x) * (1 - y) for idx = (0, 0) - 0.25 * (1 + x) * (1 - y) for idx = (1, 0) - 0.25 * (1 - x) * (1 + y) for idx = (0, 1) - 0.25 * (1 + x) * (1 + y) for idx = (1, 1)
Example
>>> from ttfemesh.basis import BilinearBasis >>> basis2d = BilinearBasis() >>> fig = basis2d.plot([0, 0]) >>> fig.show() >>> fig = basis2d.plot([0, 1]) >>> fig.show() >>> fig = basis2d.plot([1, 0]) >>> fig.show() >>> fig = basis2d.plot([1, 1]) >>> fig.show()
- __init__()[source]
Initialize the tensor product basis function.
- Parameters:
basis_functions (List[BasisFunction1D]) – List of 1D basis functions for each dimension.
- get_element2global_ttmap(index: List[int], mesh_size_exponent: int) TT[source]
Get the TT-representation of a corner element index to global basis index map.
- Parameters:
- Returns:
TT-representation of the corner to global index map.
- Return type:
TensorTrain
- Raises:
ValueError – If the index is invalid.
- get_all_element2global_ttmaps(mesh_size_exponent: int) ndarray[source]
Get the TT-representation for all corner elements in index_range to global basis index maps.
- Parameters:
mesh_size_exponent (int) – Exponent of the 1D mesh size.
- Returns:
- A 2D matrix of TT-representations, indexed by (i, j)
where i and j are the indices of the basis functions in each dimension.
- Return type:
np.ndarray
- get_dirichlet_mask(mesh_size_exponent: int, *sides: BoundarySide2D | int) TT[source]
Get the mask for the Dirichlet 2D boundary condition on the specified sides.
Note that the sides are considered to be ordered as follows: bottom (side 0), right (side 1), top (side 2), left (side 3). This is important for the boundary condition to work correctly. It may lead to confusion if, e.g., your side 0 is visually the right edge of the domain.
- Parameters:
mesh_size_exponent (int) – Exponent of the 1D mesh size.
*sides (Union[BoundarySide2D, int]) – Boundary sides to apply the Dirichlet condition. Specify either as integers (0 for bottom, 1 for right, 2 for top, 3 for left) or as BoundarySide2D enums.
- Returns:
TT-representation of the Dirichlet mask.
- Return type:
TensorTrain
- Raises:
ValueError – If no sides are specified or if an invalid side is given.
Tensor Train Tools Module
- anova_init_tensor_train(oracle: Callable[[ndarray], ndarray], train_indices: ndarray, order: int = 2) List[ndarray][source]
Initialize the tensor train with the ANOVA decomposition of the training data.
- Parameters:
oracle (Callable[[np.ndarray], np.ndarray]) – Oracle function.
train_indices (np.ndarray) – Training indices.
order (int, optional) – Order of the ANOVA decomposition. Defaults to 2.
- Returns:
List of TT-cores for the ANOVA decomposition of the training data.
- Return type:
List[np.ndarray]
- gen_teneva_indices(num_indices: int, tensor_shape: List[int]) ndarray[source]
Generate random indices for a tensor of shape tensor_shape.
- class TTCrossConfig(cache: dict | None = None, info: dict | None = None, num_sweeps: int = 10, rel_stagnation_tol: float = 0.0001, max_func_calls: int | None = None, cache_calls_factor: int = 5, num_anova_init: int = 1000, anova_order: int = 2, verbose: bool = False)[source]
Bases:
objectConfiguration class for the tensor train cross approximation algorithm.
- Parameters:
cache (dict, optional) – Cache for storing requested function values.
info (dict, optional) – Stores TTCross run information.
num_sweeps (int, optional) – Number of sweeps for DMRG. Defaults to 10.
rel_stagnation_tol (float, optional) – Relative stagnation tolerance. Defaults to 1e-4.
max_func_calls (Optional[int], optional) – Maximum number of function calls. Defaults to None.
cache_calls_factor (int, optional) – If the number of calls to cache is this factor times larger than number of function calls, TTCross stops. Defaults to 20.
num_anova_init (int, optional) – Number of training indices for ANOVA initialization. Defaults to 1000.
anova_order (int, optional) – Order of the ANOVA decomposition. Defaults to 2.
verbose (bool, optional) – Verbose output. Defaults to False.
- tensor_train_cross_approximation(oracle: Callable[[ndarray], ndarray], tt_init: List[ndarray], **kwargs) List[ndarray][source]
Approximate the tensor train with the cross approximation algorithm.
- Parameters:
oracle (Callable[[np.ndarray], np.ndarray]) – Oracle function.
tt_init (List[np.ndarray]) – Initial tensor train.
**kwargs – Additional keyword arguments for the cross approximation algorithm.
- Returns:
List of TT-cores for the approximated tensor train.
- Return type:
List[np.ndarray]
- error_on_indices(oracle: Callable[[ndarray], ndarray], approx_tt: List[ndarray], test_indices: ndarray) float[source]
Test the accuracy of the approximated tensor train.
- Parameters:
oracle (Callable[[np.ndarray], np.ndarray]) – Oracle function.
approx_tt (List[np.ndarray]) – Approximated tensor train cores.
test_indices (np.ndarray) – Test indices.
- Returns:
Relative error of the approximated tensor train.
- Return type:
- error_on_random_indices(oracle: Callable[[ndarray], ndarray], approx_tt: List[ndarray], num_test_indices: int, tensor_shape: List[int]) float[source]
Test the accuracy of the approximated tensor train with random test indices.
- Parameters:
- Returns:
Relative error of the approximated tensor train.
- Return type:
- zorder_kron(left: TT, right: TT) TT[source]
Compute the Kronecker product of two TT-tensors using the Z-ordering (a.k.a. transposed or level-wise ordering). The ordering is column-major, i.e., for every index z in the resulting tensor, the relationship to index (i, j) in the left and right tensors is: z = i + j * 2. This is consistent with the little-endian ordering of the binary index commonly used in QTT literature.
- Parameters:
left (TensorTrain) – Left TT-tensor.
right (TensorTrain) – Right TT-tensor.
- Returns:
TensorTrain resulting from the Kronecker product of left and right.
- Raises:
ValueError – If the TT-length of left and right tensors are not equal.
- transpose_kron(left: TT, right: TT) TT
Compute the Kronecker product of two TT-tensors using the Z-ordering (a.k.a. transposed or level-wise ordering). The ordering is column-major, i.e., for every index z in the resulting tensor, the relationship to index (i, j) in the left and right tensors is: z = i + j * 2. This is consistent with the little-endian ordering of the binary index commonly used in QTT literature.
- Parameters:
left (TensorTrain) – Left TT-tensor.
right (TensorTrain) – Right TT-tensor.
- Returns:
TensorTrain resulting from the Kronecker product of left and right.
- Raises:
ValueError – If the TT-length of left and right tensors are not equal.
- levelwise_kron(left: TT, right: TT) TT
Compute the Kronecker product of two TT-tensors using the Z-ordering (a.k.a. transposed or level-wise ordering). The ordering is column-major, i.e., for every index z in the resulting tensor, the relationship to index (i, j) in the left and right tensors is: z = i + j * 2. This is consistent with the little-endian ordering of the binary index commonly used in QTT literature.
- Parameters:
left (TensorTrain) – Left TT-tensor.
right (TensorTrain) – Right TT-tensor.
- Returns:
TensorTrain resulting from the Kronecker product of left and right.
- Raises:
ValueError – If the TT-length of left and right tensors are not equal.
- range_meshgrid2d(mesh_size_exponent: int) TT[source]
Compute the meshgrid corresponding to X and Y tensors counting from 0 to 2**d.
- Parameters:
mesh_size_exponent (int) – Exponent of 1D grid size.
- Returns:
TensorTrain resulting from the meshgrid of two index tensors.
- zmeshgrid2d(X: TT, Y: TT) TT[source]
Compute the meshgrid of two TT-tensors using the Z-ordering.
- Parameters:
X (TensorTrain) – First TT-tensor.
Y (TensorTrain) – Second TT-tensor.
- Returns:
TensorTrain resulting from the meshgrid of X and Y.
- map2canonical2d(mesh_size_exponent: int) ndarray[source]
Computes a vector where the i-th element is the index of the i-th element in the z-ordering of the meshgrid. The canonical ordering for a 2D grid indexed by (i, j) is computed as i + j * 2**d and does not correspond to the z-ordering of (i, j). When a TT-tensor in the z-ordering is reshaped to a vector, the order of the elements is given by the vector returned by this function. This effectively allows to map the z-ordering back to the canonical ordering. Useful for debugging and testing.
- Parameters:
mesh_size_exponent (int) – Exponent of 1D grid size.
- Returns:
Vector of indices mapping z-ordering to canonical ordering.
- Return type:
np.ndarray
Example
>>> array = tt.full().flatten("F") >>> zmap = map2canonical2d(3) >>> canonical_array = np.empty_like(array) >>> canonical_array[zmap] = array
- interpolate_linear2d(func: Callable[[ndarray], float], mesh_size_exponent: int) TT[source]
Interpolate a function on a 2D grid using linear interpolation. The function takes a quaternary argument index, corresponding to an index on the grid, arranged in the z-order, and returns a float value, corresponding to the function value at that point.
- unit_vector_binary_tt(length: int, index: int) TT[source]
Generate a unit vector with a 1 at the specified index for a binary quantized tensor train.
- Parameters:
- Returns:
A tensor train of dimension length representing the unit vector.
- Return type:
TensorTrain
- Raises:
ValueError – If index is negative or greater than or equal to 2^length.
Types Module
- class BoundarySide2D(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)[source]
Bases:
EnumEnum for the sides of a 2D domain. Note that the sides are considered to be ordered as follows: bottom (side 0), right (side 1), top (side 2), left (side 3). This is important for the boundary condition to work correctly. It may lead to confusion if, e.g., your side 0 is visually the right edge of the domain.
- BOTTOM = 0
- RIGHT = 1
- TOP = 2
- LEFT = 3
- class BoundaryVertex2D(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)[source]
Bases:
EnumEnum for the vertices of a 2D domain. Note that the vertices are considered to be ordered as follows: bottom_left (vertex 0), bottom_right (vertex 1), top_right (vertex 2), top_left (vertex 3). This is important for the boundary condition to work correctly. It may lead to confusion if, e.g., your vertex 0 is visually the bottom left corner of the domain.
- BOTTOM_LEFT = 0
- BOTTOM_RIGHT = 1
- TOP_RIGHT = 2
- TOP_LEFT = 3