tfields package¶
Subpackages¶
Submodules¶
tfields.bounding_box module¶
- class tfields.bounding_box.Node(mesh, cuts, coord_sys=None, at_intersection='split', delta=0.0, parent=None, box=None, internal_template=None, cut_expr=None)[source]¶
Bases:
object
This class allows to increase the performance with cuts in x,y and z direction An extension to arbitrary cuts might be possible in the future
- Parameters:
parent – Parent node of self
mesh – Mesh corresponding to the node
cut_expr – Cut that determines the seperation in left and right node
cuts – List of cuts for the children nodes
- Attrs:
parent (Node) remaining_cuts (dict): key specifies dimension, value the cuts that
are still not done
- cut_expr (dict): part of parents remaining_cuts. The dimension defines
what is meant by left and right
Examples
>>> import tfields >>> mesh = tfields.Mesh3D.grid((5.6, 6.2, 3), ... (-0.25, 0.25, 4), ... (-1, 1, 10))
>>> cuts = {'x': [5.7, 6.1], ... 'y': [-0.2, 0, 0.2], ... 'z': [-0.5, 0.5]}
>>> tree = tfields.bounding_box.Node(mesh, ... cuts, ... at_intersection='keep') >>> leaves = tree.leaves() >>> leaves = tfields.bounding_box.Node.sort_leaves(leaves) >>> meshes = [leaf.mesh for leaf in leaves] >>> templates = [leaf.template for leaf in leaves] >>> special_leaf = tree.find_leaf([5.65, -0.21, 0])
- find_leaf(point, _in_recursion=False)[source]¶
- Returns:
Node: leaf note, containinig point None: point outside root box
- Return type:
Node / None
- leaves()[source]¶
Recursive function to create a list of all leaves
- Returns:
of all leaves descending from this node
- Return type:
list
- property root¶
- classmethod sort_leaves(leaves_list)[source]¶
sorting the leaves first in x, then y, then z direction
- property template¶
Get the global template for a leaf. This can be applied to the root mesh with the cut method to retrieve exactly this leaf mesh again.
- Returns:
- mesh with first scalars as an instruction on how to build
this cut (scalars point to faceIndices on mother mesh). Can be used with Mesh3D.cut
- Return type:
tfields.Mesh3D
- class tfields.bounding_box.Searcher(mesh, n_sections=None, delta=0.0, cut_length=None)[source]¶
Bases:
Node
- in_faces(tensors, delta=-1, assign_multiple=False)[source]¶
- TODO-0:
check case of point+-delta outside box!
Examples
>>> import tfields >>> import numpy as np >>> mesh = tfields.Mesh3D.grid((0, 1, 2), (1, 2, 2), (2, 3, 2)) >>> tree = tfields.bounding_box.Searcher(mesh) >>> points = tfields.Tensors([[0.5, 1, 2.1], ... [0.5, 0, 0], ... [0.5, 2, 2.1], ... [0.5, 1.5, 2.5]]) >>> box_res = tree.in_faces(points, delta=0.0001) >>> usual_res = mesh.in_faces(points, delta=0.0001) >>> assert np.array_equal(box_res, usual_res)
tfields.core module¶
Author: Daniel Boeckenhoff Mail: dboe@ipp.mpg.de
core of tfields library contains numpy ndarray derived bases of the tfields package
Notes
# noqa:E501 pylint:disable=line-too-long, * It could be worthwhile concidering np.li.mixins.NDArrayOperatorsMixin
- class tfields.core.AbstractFields(iterable=(), /)[source]¶
Bases:
list
,AbstractObject
Extension of the list to tfields polymorphism. Allow setitem and getitem by object name.
- class tfields.core.AbstractNdarray(array, **kwargs)[source]¶
Bases:
ndarray
,AbstractObject
All tensors and subclasses should derive from AbstractNdarray. AbstractNdarray implements all the inheritance specifics for np.ndarray Whene inheriting, three attributes are of interest:
- __slots__¶
If you want to add attributes to your AbstractNdarray subclass, add the attribute name to __slots__
- Type:
List(str)
- __slot_defaults__¶
if __slot_defaults__ is None, the defaults for the attributes in __slots__ will be None other values will be treaded as defaults to the corresponding arg at the same position in the __slots__ list.
- Type:
list
- __slot_dtypes__¶
for the conversion of the args in __slots__ to numpy arrays. None values mean no conversion.
- Type:
List(dtypes)
- __slot_setters__¶
Because __slots__ and properties are mutually exclusive this is a possibility to take care of proper attribute handling. None will be passed for ‘not set’.
- Type:
List(callable)
- Parameters:
array (array-like) – input array
**kwargs – arguments corresponding to __slots__
- property bulk¶
The pure ndarray version of the actual state -> nothing attached
- copy(**kwargs)[source]¶
The standard ndarray copy does not copy slots. Correct for this.
Examples
>>> import tfields >>> m = tfields.TensorMaps( ... [[1,2,3], [3,3,3], [0,0,0], [5,6,7]], ... [[1], [3], [0], [5]], ... maps=[ ... ([[0, 1, 2], [1, 2, 3]], [21, 42]), ... [[1]], ... [[0, 1, 2, 3]] ... ]) >>> mc = m.copy() >>> mc.equal(m) True >>> mc is m False >>> mc.fields is m.fields False >>> mc.fields[0] is m.fields[0] False >>> mc.maps[3].fields[0] is m.maps[3].fields[0] False
- class tfields.core.AbstractObject[source]¶
Bases:
Storable
Abstract base class for all tfields objects implementing polymorphisms
- class tfields.core.Container(*items, labels=None)[source]¶
Bases:
AbstractFields
Store lists of tfields objects. Save mechanisms are provided
Examples
>>> import numpy as np >>> import tfields >>> sphere = tfields.Mesh3D.grid( ... (1, 1, 1), ... (-np.pi, np.pi, 3), ... (-np.pi / 2, np.pi / 2, 3), ... coord_sys='spherical') >>> sphere2 = sphere.copy() * 3 >>> c = tfields.Container([sphere, sphere2])
>>> c.save("~/tmp/spheres.npz") >>> c1 = tfields.Container.load("~/tmp/spheres.npz")
- property items¶
items of the container as a list
- class tfields.core.Fields(*items)[source]¶
Bases:
AbstractFields
Container for fields which should be attached to tensors with the <>.fields attribute to make them tensor fields
- class tfields.core.Maps(*args, **kwargs)[source]¶
Bases:
SortedDict
,AbstractObject
Container for TensorFields sorted by dimension, i.e indexing by dimension
- Parameters:
( (*args) – List(TensorFields): | List(Tuple(int, TensorFields)): | TensorFields: | Tuple(Tensors, *Fields)): TODO: document
) –
**kwargs – forwarded to SortedDict
TODO: further documentation
- equal(other, **kwargs)[source]¶
Test equality with other object. :param **kwargs: passed to each item on equality check
- static to_map(map_, *fields, copy=False, **kwargs)[source]¶
- Parameters:
map (TensorFields) –
*fields (Tensors) –
copy (bool) –
**kwargs – passed to TensorFields constructor
- class tfields.core.TensorFields(tensors, *fields, **kwargs)[source]¶
Bases:
Tensors
Discrete Tensor Field
- Parameters:
tensors (array) – base tensors
*fields (array) – multiple fields assigned to one base tensor. Fields themself are also of type tensor
**kwargs – rigid (bool): demand equal field and tensor lenght … : see tfields.Tensors
Examples
>>> import tfields >>> from tfields import Tensors, TensorFields >>> scalars = Tensors([0, 1, 2]) >>> vectors = Tensors([[0, 0, 0], [0, 0, 1], [0, -1, 0]]) >>> scalar_field = TensorFields(vectors, scalars) >>> scalar_field.rank 1 >>> scalar_field.fields[0].rank 0 >>> vectorField = TensorFields(vectors, vectors) >>> vectorField.fields[0].rank 1 >>> vectorField.fields[0].dim 3 >>> multiField = TensorFields(vectors, scalars, vectors) >>> multiField.fields[0].dim 1 >>> multiField.fields[1].dim 3
Empty initialization
>>> empty_field = TensorFields([], dim=3) >>> assert empty_field.shape == (0, 3) >>> assert empty_field.fields == []
Directly initializing with lists or arrays
>>> vec_field_raw = tfields.TensorFields([[0, 1, 2], [3, 4, 5]], ... [1, 6], [2, 7]) >>> assert len(vec_field_raw.fields) == 2
Copying
>>> cp = TensorFields(vectorField) >>> assert vectorField.equal(cp)
Copying takes care of coord_sys
>>> cp.transform(tfields.bases.CYLINDER) >>> cp_cyl = TensorFields(cp) >>> assert cp_cyl.coord_sys == tfields.bases.CYLINDER
Copying with changing type
>>> tcp = TensorFields(vectorField, dtype=int) >>> assert vectorField.equal(tcp) >>> assert tcp.dtype == int
- Raises:
TypeError –
>>> import tfields –
>>> tfields.TensorFields([1, 2, 3], [3]) # doctest – +ELLIPSIS
Traceback (most recent call last) –
... –
ValueError – Length of base (3) should be the same as the length of all fields ([1]).
This error can be suppressed by setting rigid=False –
>>> loose = tfields.TensorFields([1, 2, 3], [3], rigid=False) –
>>> assert len(loose) != 1 –
- coord_sys¶
- equal(other, **kwargs)[source]¶
Test, whether the instance has the same content as other.
- Parameters:
other (iterable) –
**kwargs – see Tensors.equal
- fields¶
- classmethod merged(*objects, **kwargs)[source]¶
Factory method Merges all input arguments to one object
- Parameters:
return_templates (bool) – return the templates which can be used together with cut to retrieve the original objects
dim (int) –
**kwargs – passed to cls
Examples
>>> import numpy as np >>> import tfields >>> import tfields.bases
The new object with turn out in the most frequent coordinate system if not specified explicitly
>>> vec_a = tfields.Tensors([[0, 0, 0], [0, 0, 1], [0, -1, 0]]) >>> vec_b = tfields.Tensors([[5, 4, 1]], ... coord_sys=tfields.bases.cylinder) >>> vec_c = tfields.Tensors([[4, 2, 3]], ... coord_sys=tfields.bases.cylinder) >>> merge = tfields.Tensors.merged( ... vec_a, vec_b, vec_c, [[2, 0, 1]]) >>> assert merge.coord_sys == 'cylinder' >>> assert merge.equal([[0, 0, 0], ... [0, 0, 1], ... [1, -np.pi / 2, 0], ... [5, 4, 1], ... [4, 2, 3], ... [2, 0, 1]])
Merge also shifts the maps to still refer to the same tensors
>>> tm_a = tfields.TensorMaps(merge, maps=[[[0, 1, 2]]]) >>> tm_b = tm_a.copy() >>> assert tm_a.coord_sys == 'cylinder' >>> tm_merge = tfields.TensorMaps.merged(tm_a, tm_b) >>> assert tm_merge.coord_sys == 'cylinder' >>> assert tm_merge.maps[3].equal([[0, 1, 2], ... list(range(len(merge), ... len(merge) + 3, ... 1))])
>>> obj_list = [tfields.Tensors([[1, 2, 3]], ... coord_sys=tfields.bases.CYLINDER), ... tfields.Tensors([[3] * 3]), ... tfields.Tensors([[5, 1, 3]])] >>> merge2 = tfields.Tensors.merged( ... *obj_list, coord_sys=tfields.bases.CARTESIAN) >>> assert merge2.equal([[-0.41614684, 0.90929743, 3.], ... [3, 3, 3], [5, 1, 3]], atol=1e-8)
The return_templates argument allows to retrieve a template which can be used with the cut method.
>>> merge, templates = tfields.Tensors.merged( ... vec_a, vec_b, vec_c, return_templates=True) >>> assert merge.cut(templates[0]).equal(vec_a) >>> assert merge.cut(templates[1]).equal(vec_b) >>> assert merge.cut(templates[2]).equal(vec_c)
- name¶
- property names¶
Retrive the names of the fields as a list
Examples
>>> import tfields >>> s = tfields.Tensors([1,2,3], name=1.) >>> tf = tfields.TensorFields(s, *[s]*10) >>> assert len(tf.names) == 10 >>> assert set(tf.names) == {1.} >>> tf.names = range(10) >>> tf.names [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
- plot(*args, **kwargs)[source]¶
Generic plotting method of TensorFields.
- Parameters:
field_index – index of the field to plot (as quiver by default)
normalize – If True, normalize the field vectors to show only the direction
color – additional str argument ‘norm’ added. If color=”norm”, color with the norm.
- class tfields.core.TensorMaps(tensors, *fields, **kwargs)[source]¶
Bases:
TensorFields
- Parameters:
tensors – see Tensors class
*fields (Tensors) – see TensorFields class
**kwargs –
coord_sys (‘str’): see Tensors class maps (array-like): indices indicating a connection between the
tensors at the respective index positions
Examples
>>> import tfields >>> scalars = tfields.Tensors([0, 1, 2]) >>> vectors = tfields.Tensors([[0, 0, 0], [0, 0, 1], [0, -1, 0]]) >>> maps = [tfields.TensorFields([[0, 1, 2], [0, 1, 2]], [42, 21]), ... tfields.TensorFields([[1], [2]], [-42, -21])] >>> mesh = tfields.TensorMaps(vectors, scalars, ... maps=maps) >>> assert isinstance(mesh.maps, tfields.Maps) >>> assert len(mesh.maps) == 2 >>> assert mesh.equal(tfields.TensorFields(vectors, scalars))
Copy constructor
>>> mesh_copy = tfields.TensorMaps(mesh)
Copying takes care of coord_sys
>>> mesh_copy.transform(tfields.bases.CYLINDER) >>> mesh_cp_cyl = tfields.TensorMaps(mesh_copy) >>> assert mesh_cp_cyl.coord_sys == tfields.bases.CYLINDER
- cleaned(stale=True, duplicates=True)[source]¶
- Parameters:
stale (bool) – remove stale vertices
duplicates (bool) – replace duplicate vertices by originals
Examples
>>> import numpy as np >>> import tfields >>> mp1 = tfields.TensorFields([[0, 1, 2], [3, 4, 5]], ... *zip([1,2,3,4,5], [6,7,8,9,0])) >>> mp2 = tfields.TensorFields([[0], [3]])
>>> tm = tfields.TensorMaps([[0,0,0], [1,1,1], [2,2,2], [0,0,0], ... [3,3,3], [4,4,4], [5,6,7]], ... maps=[mp1, mp2])
>>> c = tm.cleaned() >>> assert c.equal([[0., 0., 0.], ... [1., 1., 1.], ... [2., 2., 2.], ... [3., 3., 3.], ... [4., 4., 4.]]) >>> assert np.array_equal(c.maps[3], [[0, 1, 2], [0, 3, 4]]) >>> assert np.array_equal(c.maps[1], [[0], [0]])
- Returns:
copy of self without stale vertices and duplicat points (depending on arguments)
- coord_sys¶
- disjoint_map(map_dim)[source]¶
Find the disjoint sets of map = self.maps[map_dim] As an example, this method is interesting for splitting a mesh consisting of seperate parts
- Parameters:
map_dim (int) – reference to map position used like: self.maps[map_dim]
- Returns:
map description(tuple): see self.parts
- Return type:
Tuple(int, List(List(int)))
Examples
>>> import tfields >>> a = tfields.TensorMaps( ... [[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0]], ... maps=[[[0, 1, 2], [0, 2, 3]]]) >>> b = a.copy()
>>> b[:, 0] += 2 >>> m = tfields.TensorMaps.merged(a, b) >>> mp_description = m.disjoint_map(3) >>> parts = m.parts(mp_description) >>> aa, ba = parts >>> assert aa.maps[3].equal(ba.maps[3]) >>> assert aa.equal(a) >>> assert ba.equal(b)
- equal(other, **kwargs)[source]¶
Test, whether the instance has the same content as other.
- Parameters:
other (iterable) –
optional – see TensorFields.equal
Examples
>>> import tfields >>> maps = [tfields.TensorFields([[1]], [42])] >>> tm = tfields.TensorMaps(maps[0], maps=maps)
# >>> assert tm.equal(tm)
>>> cp = tm.copy()
# >>> assert tm.equal(cp)
>>> cp.maps[1].fields[0] = -42 >>> assert tm.maps[1].fields[0] == 42 >>> assert not tm.equal(cp)
- fields¶
- keep(keep_condition)[source]¶
Return copy of self with vertices where keep_condition is True Copy because self is immutable
Examples
>>> import numpy as np >>> import tfields >>> m = tfields.TensorMaps( ... [[0,0,0], [1,1,1], [2,2,2], [0,0,0], ... [3,3,3], [4,4,4], [5,5,5]], ... maps=[tfields.TensorFields([[0, 1, 2], [0, 1, 3], ... [3, 4, 5], [3, 4, 1], ... [3, 4, 6]], ... [1, 3, 5, 7, 9], ... [2, 4, 6, 8, 0])]) >>> c = m.removed([True, True, True, False, False, False, False]) >>> c.equal([[0, 0, 0], ... [3, 3, 3], ... [4, 4, 4], ... [5, 5, 5]]) True >>> assert c.maps[3].equal(np.array([[0, 1, 2], [0, 1, 3]])) >>> assert c.maps[3].fields[0].equal([5, 9]) >>> assert c.maps[3].fields[1].equal([6, 0])
- maps¶
- classmethod merged(*objects, **kwargs)[source]¶
Factory method Merges all input arguments to one object
- Parameters:
return_templates (bool) – return the templates which can be used together with cut to retrieve the original objects
dim (int) –
**kwargs – passed to cls
Examples
>>> import numpy as np >>> import tfields >>> import tfields.bases
The new object with turn out in the most frequent coordinate system if not specified explicitly
>>> vec_a = tfields.Tensors([[0, 0, 0], [0, 0, 1], [0, -1, 0]]) >>> vec_b = tfields.Tensors([[5, 4, 1]], ... coord_sys=tfields.bases.cylinder) >>> vec_c = tfields.Tensors([[4, 2, 3]], ... coord_sys=tfields.bases.cylinder) >>> merge = tfields.Tensors.merged( ... vec_a, vec_b, vec_c, [[2, 0, 1]]) >>> assert merge.coord_sys == 'cylinder' >>> assert merge.equal([[0, 0, 0], ... [0, 0, 1], ... [1, -np.pi / 2, 0], ... [5, 4, 1], ... [4, 2, 3], ... [2, 0, 1]])
Merge also shifts the maps to still refer to the same tensors
>>> tm_a = tfields.TensorMaps(merge, maps=[[[0, 1, 2]]]) >>> tm_b = tm_a.copy() >>> assert tm_a.coord_sys == 'cylinder' >>> tm_merge = tfields.TensorMaps.merged(tm_a, tm_b) >>> assert tm_merge.coord_sys == 'cylinder' >>> assert tm_merge.maps[3].equal([[0, 1, 2], ... list(range(len(merge), ... len(merge) + 3, ... 1))])
>>> obj_list = [tfields.Tensors([[1, 2, 3]], ... coord_sys=tfields.bases.CYLINDER), ... tfields.Tensors([[3] * 3]), ... tfields.Tensors([[5, 1, 3]])] >>> merge2 = tfields.Tensors.merged( ... *obj_list, coord_sys=tfields.bases.CARTESIAN) >>> assert merge2.equal([[-0.41614684, 0.90929743, 3.], ... [3, 3, 3], [5, 1, 3]], atol=1e-8)
The return_templates argument allows to retrieve a template which can be used with the cut method.
>>> merge, templates = tfields.Tensors.merged( ... vec_a, vec_b, vec_c, return_templates=True) >>> assert merge.cut(templates[0]).equal(vec_a) >>> assert merge.cut(templates[1]).equal(vec_b) >>> assert merge.cut(templates[2]).equal(vec_c)
- name¶
- parts(*map_descriptions)[source]¶
- Parameters:
*map_descriptions (Tuple(int, List(List(int)))) –
tuples of map_dim (int): reference to map position
used like: self.maps[map_dim]
- map_indices_list (List(List(int))): each int refers
to index in a map.
- Returns:
- One TensorMaps or TensorMaps subclass per
map_description
- Return type:
List(cls)
- paths(map_dim)[source]¶
Find the minimal amount of graphs building the original graph with maximum of two links per node i.e.
where 8 is a duplicated node (one has two links and one has only one.)
Examples
>>> import tfields
Ascii figure above: >>> a = tfields.TensorMaps([[1, 0], [3, 0], [2, 2], [0, 4], [2, 4], … [4, 4], [1, 6], [3, 6], [2, 2]], … maps=[[[0, 2], [2, 4], [3, 4], [5, 4], … [1, 8], [6, 4], [6, 7], [7, 4]]])
>>> paths = a.paths(2) >>> assert paths[0].equal([[ 1., 0.], ... [ 2., 2.], ... [ 2., 4.], ... [ 0., 4.]]) >>> assert paths[0].maps[4].equal([[ 0., 1., 2., 3.]]) >>> assert paths[1].equal([[ 4., 4.], ... [ 2., 4.], ... [ 1., 6.], ... [ 3., 6.], ... [ 2., 4.]]) >>> assert paths[2].equal([[ 3., 0.], ... [ 2., 2.]])
Note
The Longest path problem is a NP-hard problem.
- plot(*args, **kwargs)[source]¶
Generic plotting method of TensorMaps.
- Parameters:
*args – Depending on Positional arguments passed to the underlying
rna.plotting.plot_tensor_map()
function for arbitrary .dim (int) – dimension of the plot representation (axes).
map (int) – index of the map to plot (default is 3).
edgecolor (color) – color of the edges (dim = 3)
- removed(remove_condition)[source]¶
Return copy of self without vertices where remove_condition is True Copy because self is immutable
Examples
>>> import tfields >>> m = tfields.TensorMaps( ... [[0,0,0], [1,1,1], [2,2,2], [0,0,0], ... [3,3,3], [4,4,4], [5,5,5]], ... maps=[tfields.TensorFields([[0, 1, 2], [0, 1, 3], ... [3, 4, 5], [3, 4, 1], ... [3, 4, 6]], ... [1, 3, 5, 7, 9], ... [2, 4, 6, 8, 0])]) >>> c = m.keep([False, False, False, True, True, True, True]) >>> c.equal([[0, 0, 0], ... [3, 3, 3], ... [4, 4, 4], ... [5, 5, 5]]) True >>> assert c.maps[3].equal([[0, 1, 2], [0, 1, 3]]) >>> assert c.maps[3].fields[0].equal([5, 9]) >>> assert c.maps[3].fields[1].equal([6, 0])
- stale()[source]¶
- Returns:
Mask for all vertices that are stale i.e. are not refered by maps
Examples
>>> import numpy as np >>> import tfields >>> vectors = tfields.Tensors( ... [[0, 0, 0], [0, 0, 1], [0, -1, 0], [4, 4, 4]]) >>> tm = tfields.TensorMaps( ... vectors, ... maps=[[[0, 1, 2], [0, 1, 2]], [[1, 1], [2, 2]]]) >>> assert np.array_equal(tm.stale(), [False, False, False, True])
- class tfields.core.Tensors(tensors, **kwargs)[source]¶
Bases:
AbstractNdarray
Set of tensors with the same basis.
- Parameters:
tensors – np.ndarray or AbstractNdarray subclass
**kwargs – name: optional - custom name, can be anything
Examples
>>> import numpy as np >>> import tfields
Initialize a scalar range
>>> scalars = tfields.Tensors([0, 1, 2]) >>> scalars.rank == 0 True
Initialize vectors
>>> vectors = tfields.Tensors([[0, 0, 0], [0, 0, 1], [0, -1, 0]]) >>> vectors.rank == 1 True >>> vectors.dim == 3 True >>> assert vectors.coord_sys == 'cartesian'
Initialize the Levi-Zivita Tensor
>>> matrices = tfields.Tensors([[[0, 0, 0], [0, 0, 1], [0, -1, 0]], ... [[0, 0, -1], [0, 0, 0], [1, 0, 0]], ... [[0, 1, 0], [-1, 0, 0], [0, 0, 0]]]) >>> matrices.shape == (3, 3, 3) True >>> matrices.rank == 2 True >>> matrices.dim == 3 True
Initializing in different start coordinate system
>>> cyl = tfields.Tensors([[5, np.arctan(4. / 3.), 42]], ... coord_sys='cylinder') >>> assert cyl.coord_sys == 'cylinder' >>> cyl.transform('cartesian') >>> assert cyl.coord_sys == 'cartesian' >>> cart = cyl >>> assert round(cart[0, 0], 10) == 3. >>> assert round(cart[0, 1], 10) == 4. >>> assert cart[0, 2] == 42
Initialize with copy constructor keeps the coordinate system
>>> with vectors.tmp_transform('cylinder'): ... vect_cyl = tfields.Tensors(vectors) ... assert vect_cyl.coord_sys == vectors.coord_sys >>> assert vect_cyl.coord_sys == 'cylinder'
You can demand a special dimension.
>>> _ = tfields.Tensors([[1, 2, 3]], dim=3) >>> _ = tfields.Tensors([[1, 2, 3]], dim=2) Traceback (most recent call last): ... ValueError: Incorrect dimension: 3 given, 2 demanded.
The dimension argument (dim) becomes necessary if you want to initialize an empty array
>>> _ = tfields.Tensors([]) Traceback (most recent call last): ... ValueError: Empty tensors need dimension parameter 'dim'. >>> tfields.Tensors([], dim=7) Tensors([], shape=(0, 7), dtype=float64)
- closest(other, **kwargs)[source]¶
- Parameters:
other (Tensors) – closest points to what? -> other
**kwargs – forwarded to scipy.spatial.cKDTree.query
- Returns:
- Indices of other points that are closest to
own points
- Return type:
array shape(len(self))
Examples
>>> import tfields >>> m = tfields.Tensors([[1,0,0], [0,1,0], [1,1,0], [0,0,1], ... [1,0,1]]) >>> p = tfields.Tensors([[1.1,1,0], [0,0.1,1], [1,0,1.1]]) >>> p.closest(m) array([2, 3, 4])
- contains(other)[source]¶
Inspired by a speed argument @ stackoverflow.com/questions/14766194/testing-whether-a-numpy-array-contains-a-given-row
Examples
>>> import tfields >>> p = tfields.Tensors([[1,2,3], [4,5,6], [6,7,8]]) >>> p.contains([4,5,6]) True
- coord_sys¶
- cov_eig(weights=None)[source]¶
Calculate the covariance eigenvectors with lenghts of eigenvalues
- Parameters:
weights (np.array | int | None) – index to scalars to weight with
- cut(expression, coord_sys=None, return_template=False, **kwargs)[source]¶
Extract a part of the object according to the logic given by <expression>.
- Parameters:
expression (sympy logical expression|tfields.TensorFields) – logical expression which will be evaluated. use symbols x, y and z. If tfields.TensorFields or subclass is given, the expression refers to a template.
coord_sys (str) – coord_sys to evaluate the expression in. Only active for template expression
Examples
>>> import tfields >>> import sympy >>> x, y, z = sympy.symbols('x y z') >>> p = tfields.Tensors([[1., 2., 3.], [4., 5., 6.], [1, 2, -6], ... [-5, -5, -5], [1,0,-1], [0,1,-1]]) >>> p.cut(x > 0).equal([[1, 2, 3], ... [4, 5, 6], ... [1, 2, -6], ... [1, 0, -1]]) True
combinations of cuts
>>> cut_expression = (x > 0) & (z < 0) >>> combi_cut = p.cut(cut_expression) >>> combi_cut.equal([[1, 2, -6], [1, 0, -1]]) True
Templates can be used to speed up the repeated cuts on the same underlying tensor with the same expression but new fields. First let us cut a but request the template on return: >>> field1 = list(range(len(p))) >>> tf = tfields.TensorFields(p, field1) >>> tf_cut, template = tf.cut(cut_expression, … return_template=True)
Now repeat the cut with a new field: >>> field2 = p >>> tf.fields.append(field2) >>> tf_template_cut = tf.cut(template) >>> tf_template_cut.equal(combi_cut) True >>> tf_template_cut.fields[0].equal([2, 4]) True >>> tf_template_cut.fields[1].equal(combi_cut) True
- Returns:
copy of self with cut applied [optional: template - requires <return_template> switch]
- property dim¶
Manifold dimension
- distances(other, **kwargs)[source]¶
- Parameters:
other (Iterable) –
**kwargs – … is forwarded to scipy.spatial.distance.cdist
Examples
>>> import tfields >>> p = tfields.Tensors.grid((0, 2, 3j), ... (0, 2, 3j), ... (0, 0, 1j)) >>> p[4,2] = 1 >>> p.distances(p)[0,0] 0.0 >>> p.distances(p)[5,1] 1.4142135623730951 >>> p.distances([[0,1,2]])[-1][0] == 3 True
- dot(b, out=None)[source]¶
Computes the n-d dot product between self and other defined as in mathematica by summing over the last dimension. When self and b are both one-dimensional vectors, this is just the “usual” dot product; when self and b are 2D matrices, this is matrix multiplication.
Note
This is not the same as the numpy.dot function.
Examples
>>> import tfields >>> import numpy as np
Scalar product by transposed dot product >>> a = tfields.Tensors([[4, 0, 4]]) >>> b = tfields.Tensors([[10, 0, 0.5]]) >>> c = a.t.dot(b) >>> assert c.equal([42]) >>> assert c.equal(np.dot(a[0], b[0])) >>> assert c.rank == 0
To get the angle between a and b you now just need >>> angle = np.arccos(c)
Matrix vector multiplication >>> a = tfields.Tensors([[[1, 20, 0], [2, 18, 1], [1, 5, 10]]]) >>> b = tfields.Tensors([[1, 2, 3]]) >>> c = a.dot(b) >>> assert c.equal([[41,41,41]])
- TODO: generalize dot product to inner
# Matrix matrix multiplication can not be done like this. It requires # >>> a = tfields.Tensors([[[1, 8], [2, 4]]]) # >>> b = tfields.Tensors([[[1, 2], [1/2, 1/4]]]) # >>> c = a.dot(b) # >>> c # >>> assert c.equal([[[5, 4], [4, 5]]])
TODO: handle types, fields and maps (which fields etc to choose for the output?)
- epsilon_neighbourhood(epsilon)[source]¶
- Returns:
indices for those sets of points that lie within epsilon around the other
Examples
Create mesh grid with one extra point that will have 8 neighbours within epsilon >>> import tfields >>> p = tfields.Tensors.grid((0, 1, 2j), … (0, 1, 2j), … (0, 1, 2j)) >>> p = tfields.Tensors.merged(p, [[0.5, 0.5, 0.5]]) >>> [len(en) for en in p.epsilon_neighbourhood(0.9)] [2, 2, 2, 2, 2, 2, 2, 2, 9]
- equal(other, rtol=None, atol=None, equal_nan=False, return_bool=True)[source]¶
Evaluate, whether the instance has the same content as other.
- Parameters:
optional – rtol (float) atol (float) equal_nan (bool)
numpy.isclose (see) –
- evalf(expression=None, coord_sys=None)[source]¶
- Parameters:
expression (sympy logical expression) –
coord_sys (str) – coord_sys to evalfuate the expression in.
- Returns:
- mask of dtype bool with lenght of number of points in
self. This array is True, where expression evalfuates True.
- Return type:
np.ndarray
Examples
>>> import tfields >>> import numpy as np >>> import sympy >>> x, y, z = sympy.symbols('x y z') >>> p = tfields.Tensors([[1., 2., 3.], [4., 5., 6.], [1, 2, -6], ... [-5, -5, -5], [1,0,-1], [0,1,-1]]) >>> np.array_equal(p.evalf(x > 0), ... [True, True, True, False, True, False]) True >>> np.array_equal(p.evalf(x >= 0), ... [True, True, True, False, True, True]) True
And combination
>>> np.array_equal(p.evalf((x > 0) & (y < 3)), ... [True, False, True, False, True, False]) True
Or combination
>>> np.array_equal(p.evalf((x > 0) | (y > 3)), ... [True, True, True, False, True, False]) True
- classmethod grid(*base_vectors, **kwargs)[source]¶
- Parameters:
*base_vectors (Iterable) – base coordinates. The amount of base vectors defines the dimension
**kwargs –
- iter_order (list): order in which the iteration will be done.
Frequency rises with position in list. default is [0, 1, 2] iteration will be done like:
- for v0 in base_vectors[iter_order[0]]:
- for v1 in base_vectors[iter_order[1]]:
- for v2 in base_vectors[iter_order[2]]:
coords0.append(locals()[‘v%i’ % iter_order[0]]) coords1.append(locals()[‘v%i’ % iter_order[1]]) coords2.append(locals()[‘v%i’ % iter_order[2]])
Examples
Initilaize using the mgrid notation
>>> import numpy as np >>> import tfields >>> mgrid = tfields.Tensors.grid((0, 1, 2j), (3, 4, 2j), (6, 7, 2j)) >>> mgrid.equal([[0, 3, 6], ... [0, 3, 7], ... [0, 4, 6], ... [0, 4, 7], ... [1, 3, 6], ... [1, 3, 7], ... [1, 4, 6], ... [1, 4, 7]]) True
Lists or arrays are accepted also. Furthermore, the iteration order can be changed
>>> lins = tfields.Tensors.grid( ... np.linspace(3, 4, 2), np.linspace(0, 1, 2), ... np.linspace(6, 7, 2), iter_order=[1, 0, 2]) >>> lins.equal([[3, 0, 6], ... [3, 0, 7], ... [4, 0, 6], ... [4, 0, 7], ... [3, 1, 6], ... [3, 1, 7], ... [4, 1, 6], ... [4, 1, 7]]) True >>> lins2 = tfields.Tensors.grid(np.linspace(0, 1, 2), ... np.linspace(3, 4, 2), ... np.linspace(6, 7, 2), ... iter_order=[2, 0, 1]) >>> lins2.equal([[0, 3, 6], ... [0, 4, 6], ... [1, 3, 6], ... [1, 4, 6], ... [0, 3, 7], ... [0, 4, 7], ... [1, 3, 7], ... [1, 4, 7]]) True
When given the coord_sys argument, the grid is performed in the given coorinate system:
>>> lins3 = tfields.Tensors.grid(np.linspace(4, 9, 2), ... np.linspace(np.pi/2, np.pi/2, 1), ... np.linspace(4, 4, 1), ... iter_order=[2, 0, 1], ... coord_sys=tfields.bases.CYLINDER) >>> assert lins3.coord_sys == 'cylinder' >>> lins3.transform('cartesian') >>> assert np.array_equal(lins3[:, 1], [4, 9])
- index(tensor, **kwargs)[source]¶
- Parameters:
tensor –
- Returns:
index of tensor occuring
- Return type:
int
- indices(tensor, rtol=None, atol=None)[source]¶
- Returns:
indices of tensor occuring
- Return type:
list of int
Examples
Rank 1 Tensors
>>> import tfields >>> p = tfields.Tensors([[1,2,3], [4,5,6], [6,7,8], [4,5,6], ... [4.1, 5, 6]]) >>> p.indices([4,5,6]) array([1, 3]) >>> p.indices([4,5,6.1], rtol=1e-5, atol=1e-1) array([1, 3, 4])
Rank 0 Tensors
>>> p = tfields.Tensors([2, 3, 6, 3.01]) >>> p.indices(3) array([1]) >>> p.indices(3, rtol=1e-5, atol=1e-1) array([1, 3])
- classmethod merged(*objects, **kwargs)[source]¶
Factory method Merges all input arguments to one object
- Parameters:
return_templates (bool) – return the templates which can be used together with cut to retrieve the original objects
dim (int) –
**kwargs – passed to cls
Examples
>>> import numpy as np >>> import tfields >>> import tfields.bases
The new object with turn out in the most frequent coordinate system if not specified explicitly
>>> vec_a = tfields.Tensors([[0, 0, 0], [0, 0, 1], [0, -1, 0]]) >>> vec_b = tfields.Tensors([[5, 4, 1]], ... coord_sys=tfields.bases.cylinder) >>> vec_c = tfields.Tensors([[4, 2, 3]], ... coord_sys=tfields.bases.cylinder) >>> merge = tfields.Tensors.merged( ... vec_a, vec_b, vec_c, [[2, 0, 1]]) >>> assert merge.coord_sys == 'cylinder' >>> assert merge.equal([[0, 0, 0], ... [0, 0, 1], ... [1, -np.pi / 2, 0], ... [5, 4, 1], ... [4, 2, 3], ... [2, 0, 1]])
Merge also shifts the maps to still refer to the same tensors
>>> tm_a = tfields.TensorMaps(merge, maps=[[[0, 1, 2]]]) >>> tm_b = tm_a.copy() >>> assert tm_a.coord_sys == 'cylinder' >>> tm_merge = tfields.TensorMaps.merged(tm_a, tm_b) >>> assert tm_merge.coord_sys == 'cylinder' >>> assert tm_merge.maps[3].equal([[0, 1, 2], ... list(range(len(merge), ... len(merge) + 3, ... 1))])
>>> obj_list = [tfields.Tensors([[1, 2, 3]], ... coord_sys=tfields.bases.CYLINDER), ... tfields.Tensors([[3] * 3]), ... tfields.Tensors([[5, 1, 3]])] >>> merge2 = tfields.Tensors.merged( ... *obj_list, coord_sys=tfields.bases.CARTESIAN) >>> assert merge2.equal([[-0.41614684, 0.90929743, 3.], ... [3, 3, 3], [5, 1, 3]], atol=1e-8)
The return_templates argument allows to retrieve a template which can be used with the cut method.
>>> merge, templates = tfields.Tensors.merged( ... vec_a, vec_b, vec_c, return_templates=True) >>> assert merge.cut(templates[0]).equal(vec_a) >>> assert merge.cut(templates[1]).equal(vec_b) >>> assert merge.cut(templates[2]).equal(vec_c)
- min_dists(other=None, **kwargs)[source]¶
- Parameters:
other (array | None) – if None: closest distance to self
**kwargs –
- memory_saving (bool): for very large array comparisons
default False
… rest is forwarded to scipy.spatial.distance.cdist
- Returns:
minimal distances of self to other
- Return type:
np.array
Examples
>>> import tfields >>> import numpy as np >>> p = tfields.Tensors.grid((0, 2, 3), ... (0, 2, 3), ... (0, 0, 1)) >>> p[4,2] = 1 >>> dMin = p.min_dists() >>> expected = [1] * 9 >>> expected[4] = np.sqrt(2) >>> np.array_equal(dMin, expected) True
>>> dMin2 = p.min_dists(memory_saving=True) >>> bool((dMin2 == dMin).all()) True
- mirror(coordinate, condition=None)[source]¶
Reflect/Mirror the entries meeting <condition> at <coordinate> = 0
- Parameters:
coordinate (int) – coordinate index
Examples
>>> import tfields >>> p = tfields.Tensors([[1., 2., 3.], [4., 5., 6.], [1, 2, -6]]) >>> p.mirror(1) >>> assert p.equal([[1, -2, 3], [4, -5, 6], [1, -2, -6]])
multiple coordinates can be mirrored at the same time i.e. a point mirrorion would be
>>> p = tfields.Tensors([[1., 2., 3.], [4., 5., 6.], [1, 2, -6]]) >>> p.mirror([0,2]) >>> assert p.equal([[-1, 2, -3], [-4, 5, -6], [-1, 2., 6.]])
You can give a condition as mask or as str. The mirroring will only be applied to the points meeting the condition.
>>> import sympy >>> x, y, z = sympy.symbols('x y z') >>> p.mirror([0, 2], y > 3) >>> p.equal([[-1, 2, -3], [4, 5, 6], [-1, 2, 6]]) True
- moment(moment, weights=None)[source]¶
- Returns:
Moments of the distribution.
- Parameters:
moment (int) – n-th moment
Examples
>>> import tfields
Skalars
>>> t = tfields.Tensors(range(1, 6)) >>> assert t.moment(1) == 0 >>> assert t.moment(1, weights=[-2, -1, 20, 1, 2]) == 0.5 >>> assert t.moment(2, weights=[0.25, 1, 17.5, 1, 0.25]) == 0.2
Vectors
>>> t = tfields.Tensors(list(zip(range(1, 6), range(1, 6)))) >>> assert tfields.Tensors([0.5, 0.5]).equal( ... t.moment(1, weights=[-2, -1, 20, 1, 2])) >>> assert tfields.Tensors([1. , 0.5]).equal( ... t.moment(1, weights=list(zip([-2, -1, 10, 1, 2], ... [-2, -1, 20, 1, 2]))))
- name¶
- norm(ord=None, axis=None, keepdims=False)[source]¶
Calculate the norm up to rank 2
- Parameters:
axis (See numpy.linal.norm except redefinition in) –
axis – by default omitting first axis
Examples
>>> import tfields >>> a = tfields.Tensors([[1, 0, 0]]) >>> assert a.norm().equal([1])
- normalized(*args, **kwargs)[source]¶
Return the self / norm(self)
- Parameters:
to (forwarded) – meth:norm
Examples
>>> import tfields >>> a = tfields.Tensors([[1, 4, 3]]) >>> assert not a.norm().equal([1]) >>> a = a.normalized() >>> assert a.norm().equal([1])
>>> a = tfields.Tensors([[1, 0, 0], ... [0, 2, 0], ... [0, 0, 3]]) >>> assert a.norm().equal([1, 2, 3]) >>> a = a.normalized() >>> assert a.equal([ ... [1, 0, 0], ... [0, 1, 0], ... [0, 0, 1], ... ]) >>> assert a.norm().equal([1, 1, 1])
- plot(*args, **kwargs)[source]¶
Generic plotting method of Tensors.
Forwarding to rna.plotting.plot_tensor
- property rank¶
Tensor rank
- property t¶
Same as self.T but for tensor dimension only. Keeping the order of stacked tensors.
Examples
>>> import tfields >>> a = tfields.Tensors([[[1,2,3,4],[5,6,7,8]]]) >>> assert a.t.equal([a[0].T])
- tmp_transform(coord_sys)[source]¶
Temporarily change the coord_sys to another coord_sys and change it back at exit This method is for cleaner code only. No speed improvements go with this.
- Parameters:
transform (see) –
Examples
>>> import tfields >>> p = tfields.Tensors([[1,2,3]], coord_sys=tfields.bases.SPHERICAL) >>> with p.tmp_transform(tfields.bases.CYLINDER): ... assert p.coord_sys == tfields.bases.CYLINDER >>> assert p.coord_sys == tfields.bases.SPHERICAL
- to_segment(segment, num_segments, coordinate, periodicity=6.283185307179586, offset=0.0, coord_sys=None)[source]¶
For circular (close into themself after <periodicity>) coordinates at index <coordinate> assume <num_segments> segments and transform all values to segment number <segment>
- Parameters:
segment (int) – segment index (starting at 0)
num_segments (int) – number of segments
coordinate (int) – coordinate index
periodicity (float) – after what lenght, the coordiante repeats
offset (float) – offset in the mapping
coord_sys (str or sympy.CoordinateSystem) – in which coord sys the transformation should be done
Examples
>>> import tfields >>> import numpy as np >>> pStart = tfields.Points3D([[6, 2 * np.pi, 1], ... [6, 2 * np.pi / 5 * 3, 1]], ... coord_sys='cylinder') >>> p = tfields.Points3D(pStart) >>> p.to_segment(0, 5, 1, offset=-2 * np.pi / 10) >>> assert np.array_equal(p[:, 1], [0, 0])
>>> p2 = tfields.Points3D(pStart) >>> p2.to_segment(1, 5, 1, offset=-2 * np.pi / 10) >>> assert np.array_equal(np.round(p2[:, 1], 4), [1.2566] * 2)
- transform(coord_sys, **kwargs)[source]¶
- Parameters:
coord_sys (str) –
Examples
>>> import numpy as np >>> import tfields
CARTESIAN to SPHERICAL >>> t = tfields.Tensors([[1, 2, 2], [1, 0, 0], [0, 0, -1], … [0, 0, 1], [0, 0, 0]]) >>> t.transform(‘spherical’)
r
>>> assert t[0, 0] == 3
phi
>>> assert t[1, 1] == 0. >>> assert t[2, 1] == 0.
theta is 0 at (0, 0, 1) and pi / 2 at (0, 0, -1)
>>> assert round(t[1, 2], 10) == round(0, 10) >>> assert t[2, 2] == -np.pi / 2 >>> assert t[3, 2] == np.pi / 2
theta is defined 0 for R == 0
>>> assert t[4, 0] == 0. >>> assert t[4, 2] == 0.
CARTESIAN to CYLINDER
>>> tCart = tfields.Tensors([[3, 4, 42], [1, 0, 0], [0, 1, -1], ... [-1, 0, 1], [0, 0, 0]]) >>> t_cyl = tCart.copy() >>> t_cyl.transform('cylinder') >>> assert t_cyl.coord_sys == 'cylinder'
R
>>> assert t_cyl[0, 0] == 5 >>> assert t_cyl[1, 0] == 1 >>> assert t_cyl[2, 0] == 1 >>> assert t_cyl[4, 0] == 0
Phi
>>> assert round(t_cyl[0, 1], 10) == round(np.arctan(4. / 3), 10) >>> assert t_cyl[1, 1] == 0 >>> assert round(t_cyl[2, 1], 10) == round(np.pi / 2, 10) >>> assert t_cyl[1, 1] == 0
Z
>>> assert t_cyl[0, 2] == 42 >>> assert t_cyl[2, 2] == -1
>>> t_cyl.transform('cartesian') >>> assert t_cyl.coord_sys == 'cartesian' >>> assert round(t_cyl[0, 0], 10) == 3
- tfields.core.as_fields(fields)[source]¶
Setter for TensorFields.fields Copies input .. rubric:: Examples
>>> import tfields >>> scalars = tfields.Tensors([0, 1, 2]) >>> vectors = tfields.Tensors([[0, 0, 0], [0, 0, 1], [0, -1, 0]]) >>> maps = [tfields.TensorFields([[0, 1, 2], [0, 1, 2]]), ... tfields.TensorFields([[1], [2]], [-42, -21])] >>> mesh = tfields.TensorMaps(vectors, scalars, ... maps=maps) >>> mesh.maps[3].fields = [[42, 21]] >>> assert len(mesh.maps[3].fields) == 1 >>> assert mesh.maps[3].fields[0].equal([42, 21])
tfields.mask module¶
Author: Daniel Boeckenhoff Mail: daniel.boeckenhoff@ipp.mpg.de
part of tfields library contains interaction methods for sympy and numpy
- tfields.mask.evalf(array, cut_expression=None, coords=None)[source]¶
Linking sympy and numpy by retrieving a mask according to the cut_expression
- Parameters:
array (numpy ndarray) –
cut_expression (sympy logical expression) –
coord_sys (str) – coord_sys to evalfuate the expression in.
- Returns:
mask which is True, where cut_expression evalfuates True.
- Return type:
np.array
Examples
>>> import sympy >>> import numpy as np >>> import tfields >>> x, y, z = sympy.symbols('x y z')
>>> a = np.array([[1., 2., 3.], [4., 5., 6.], [1, 2, -6], ... [-5, -5, -5], [1,0,-1], [0,1,-1]]) >>> assert np.array_equal( ... tfields.evalf(a, x > 0), ... np.array([ True, True, True, False, True, False]))
And combination >>> assert np.array_equal( … tfields.evalf(a, (x > 0) & (y < 3)), … np.array([True, False, True, False, True, False]))
Or combination >>> assert np.array_equal( … tfields.evalf(a, (x > 0) | (y > 3)), … np.array([True, True, True, False, True, False]))
If array of other shape than (?, 3) is given, the coords need to be specified >>> a0, a1 = sympy.symbols(‘a0 a1’) >>> assert np.array_equal( … tfields.evalf([[0., 1.], [-1, 3]], a1 > 2, coords=[a0, a1]), … np.array([False, True], dtype=bool))
>= is taken care of >>> assert np.array_equal( … tfields.evalf(a, x >= 0), … np.array([ True, True, True, False, True, True]))
tfields.mesh_3d module¶
Author: Daniel Boeckenhoff Mail: daniel.boeckenhoff@ipp.mpg.de
Triangulated mesh class and methods
- class tfields.mesh_3d.Mesh3D(tensors, *fields, **kwargs)[source]¶
Bases:
TensorMaps
Points3D child used as vertices combined with faces to build a geometrical mesh of triangles .. rubric:: Examples
>>> import tfields >>> import numpy as np >>> m = tfields.Mesh3D([[1,2,3], [3,3,3], [0,0,0], [5,6,7]], faces=[[0, 1, 2], [1, 2, 3]]) >>> m.equal([[1, 2, 3], ... [3, 3, 3], ... [0, 0, 0], ... [5, 6, 7]]) True >>> np.array_equal(m.faces, [[0, 1, 2], [1, 2, 3]]) True
conversion to points only >>> tfields.Points3D(m).equal([[1, 2, 3], … [3, 3, 3], … [0, 0, 0], … [5, 6, 7]]) True
Empty instances >>> m = tfields.Mesh3D([]);
going from Mesh3D to Triangles3D instance is easy and will be cached. >>> m = tfields.Mesh3D([[1,0,0], [0,1,0], [0,0,0]], faces=[[0, 1, 2]]); >>> assert m.triangles().equal(tfields.Triangles3D([[ 1., 0., 0.], … [ 0., 1., 0.], … [ 0., 0., 0.]]))
a list of scalars is assigned to each face >>> mScalar = tfields.Mesh3D([[1,0,0], [0,1,0], [0,0,0]], … faces=([[0, 1, 2]], [.5])); >>> np.array_equal(mScalar.faces.fields, [[ 0.5]]) True
adding together two meshes: >>> m2 = tfields.Mesh3D([[1,0,0],[2,0,0],[0,3,0]], … faces=([[0,1,2]], [.7])) >>> msum = tfields.Mesh3D.merged(mScalar, m2) >>> msum.equal([[ 1., 0., 0.], … [ 0., 1., 0.], … [ 0., 0., 0.], … [ 1., 0., 0.], … [ 2., 0., 0.], … [ 0., 3., 0.]]) True >>> assert np.array_equal(msum.faces, [[0, 1, 2], [3, 4, 5]])
Saving and reading >>> from tempfile import NamedTemporaryFile >>> outFile = NamedTemporaryFile(suffix=’.npz’) >>> m.save(outFile.name) >>> _ = outFile.seek(0) >>> m1 = tfields.Mesh3D.load(outFile.name, allow_pickle=True) >>> bool(np.all(m == m1)) True >>> assert np.array_equal(m1.faces, np.array([[0, 1, 2]]))
- coord_sys¶
- cut(*args, **kwargs)[source]¶
cut method for Mesh3D. :param expression:
- sympy locical expression: Sympy expression that defines planes
in 3D
- Mesh3D: A mesh3D will be interpreted as a template, i.e. a
fast instruction of how to cut the triangles. It is the second part of the tuple, returned by a previous cut with a sympy locial expression with ‘return_template=True’. We use the vertices and maps of the Mesh as the skelleton of the returned mesh. The fields are mapped according to indices in the template.maps[i].fields.
- Parameters:
coord_sys (coordinate system to cut in) –
at_intersection (str) –
instruction on what to do, when a cut will intersect a triangle. Options: ‘remove’ (Default) - remove the faces that are on the edge
’keep’ - keep the faces that are on the edge ‘split’ - Create new triangles that make up the old one.
return_template (bool) – If True: return the template to redo the same cut fast
Examples
define the cut >>> import numpy as np >>> import tfields >>> from sympy.abc import x,y,z >>> cut_expr = x > 1.5
>>> m = tfields.Mesh3D.grid((0, 3, 4), ... (0, 3, 4), ... (0, 0, 1)) >>> m.fields.append(tfields.Tensors(np.linspace(0, len(m) - 1, ... len(m)))) >>> m.maps[3].fields.append( ... tfields.Tensors(np.linspace(0, ... len(m.maps[3]) - 1, ... len(m.maps[3])))) >>> mNew = m.cut(cut_expr) >>> len(mNew) 8 >>> mNew.nfaces() 6 >>> float(mNew[:, 0].min()) 2.0
Cutting with the ‘keep’ option will leave triangles on the edge untouched: >>> m_keep = m.cut(cut_expr, at_intersection=’keep’) >>> float(m_keep[:, 0].min()) 1.0 >>> m_keep.nfaces() 12
Cutting with the ‘split’ option will create new triangles on the edge: >>> m_split = m.cut(cut_expr, at_intersection=’split’) >>> float(m_split[:, 0].min()) 1.5 >>> len(m_split) 15 >>> m_split.nfaces() 15
Cut with ‘return_template=True’ will return the exact same mesh but additionally an instruction to conduct the exact same cut fast (template) >>> m_split_2, template = m.cut(cut_expr, at_intersection=’split’, … return_template=True) >>> m_split_template = m.cut(template) >>> assert m_split.equal(m_split_2, equal_nan=True) >>> assert m_split.equal(m_split_template, equal_nan=True) >>> assert len(template.fields) == 1 >>> assert len(m_split.fields) == 1 >>> assert len(m_split_template.fields) == 1 >>> assert m_split.fields[0].equal( … list(range(8, 16)) + [np.nan] * 7, equal_nan=True) >>> assert m_split_template.fields[0].equal( … list(range(8, 16)) + [np.nan] * 7, equal_nan=True)
This seems irrelevant at first but consider, the map field or the tensor field changes: >>> m_altered_fields = m.copy() >>> m_altered_fields[0] += 42 >>> assert not m_split.equal(m_altered_fields.cut(template)) >>> assert tfields.Tensors(m_split).equal( … m_altered_fields.cut(template)) >>> assert tfields.Tensors(m_split.maps[3]).equal( … m_altered_fields.cut(template).maps[3])
The cut expression may be a sympy.BooleanFunction: >>> cut_expr_bool_fun = (x > 1.5) & (y < 1.5) & (y >0.2) & (z > -0.5) >>> m_split_bool = m.cut(cut_expr_bool_fun, … at_intersection=’split’)
- Returns:
copy of cut mesh * optional: template
- disjoint_parts(return_template=False)[source]¶
- Returns:
disjoint_parts(List(cls)), templates(List(cls))
>>> import tfields >>> a = tfields.Mesh3D( ... [[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0]], ... maps=[[[0, 1, 2], [0, 2, 3]]]) >>> b = a.copy()
>>> b[:, 0] += 2 >>> m = tfields.Mesh3D.merged(a, b) >>> parts = m.disjoint_parts() >>> aa, ba = parts >>> assert aa.maps[3].equal(ba.maps[3]) >>> assert aa.equal(a) >>> assert ba.equal(b)
- property faces¶
- fields¶
- classmethod grid(*base_vectors, **kwargs)[source]¶
Construct ‘cuboid’ along base_vectors .. rubric:: Examples
Building symmetric geometries were never as easy:
Approximated sphere with radius 1, translated in y by 2 units >>> import numpy as np >>> import tfields >>> sphere = tfields.Mesh3D.grid((1, 1, 1), … (-np.pi, np.pi, 12), … (-np.pi / 2, np.pi / 2, 12), … coord_sys=’spherical’) >>> sphere.transform(‘cartesian’) >>> sphere[:, 1] += 2
Oktaeder >>> oktaeder = tfields.Mesh3D.grid((1, 1, 1), … (-np.pi, np.pi, 5), … (-np.pi / 2, np.pi / 2, 3), … coord_sys=’spherical’) >>> oktaeder.transform(‘cartesian’)
Cube with edge length of 2 units >>> cube = tfields.Mesh3D.grid((-1, 1, 2), … (-1, 1, 2), … (-5, -3, 2))
Cylinder >>> cylinder = tfields.Mesh3D.grid((1, 1, 1), … (-np.pi, np.pi, 12), … (-5, 3, 12), … coord_sys=’cylinder’) >>> cylinder.transform(‘cartesian’)
- in_faces(points, delta, **kwargs)[source]¶
Check whether points lie within triangles with Barycentric Technique see Triangles3D.in_triangles. If multiple requests are done on huge meshes, this can be hugely optimized by requesting the property self.tree or setting it to self.tree = <saved tree> before calling in_faces.
- maps¶
- name¶
- classmethod plane(*base_vectors, **kwargs)[source]¶
Alternative constructor for creating a plane from :param *base_vectors: see grid constructors in core. One base_vector has
to be one-dimensional
- Parameters:
**kwargs – forwarded to __new__
- project(tensor_field, delta=None, merge_functions=None, point_face_assignment=None, return_point_face_assignment=False)[source]¶
Project the points of the tensor_field to a copy of the mesh and set the face values accord to the field to the maps field. If no field is present in tensor_field, the number of points in a mesh is counted.
- Parameters:
tensor_field (Tensors | TensorFields) –
delta (float | None) – forwarded to Mesh3D.in_faces
merge_functions (callable) – if multiple Tensors lie in the same face, they are mapped with the merge_function to one value
point_face_assignment (np.array, dtype=int) – array assigning each point to a face. Each entry position corresponds to a point of the tensor, each entry value is the index of the assigned face
return_point_face_assignment (bool) – if true, return the point_face_assignment
Examples
>>> import tfields >>> import numpy as np >>> mp = tfields.TensorFields([[0,1,2],[2,3,0],[3,2,5],[5,4,3]], ... [1, 2, 3, 4]) >>> m = tfields.Mesh3D([[0,0,0], [1,0,0], [1,1,0], [0,1,0], [0,2,0], [1,2,0]], ... maps=[mp]) >>> points = tfields.Tensors([[0.5, 0.2, 0.0], ... [0.5, 0.02, 0.0], ... [0.5, 0.8, 0.0], ... [0.5, 0.8, 0.1]]) # not contained
Projecting points onto the mesh gives the count >>> m_points = m.project(points, delta=0.01) >>> list(m_points.maps[3].fields[0]) [2, 1, 0, 0]
TensorFields with arbitrary size are projected, combinging the fields automatically >>> fields = [tfields.Tensors([1,3,42, -1]), … tfields.Tensors([[0,1,2], [2,3,4], [3,4,5], [-1] * 3]), … tfields.Tensors([[[0, 0]] * 2, … [[2, 2]] * 2, … [[3, 3]] * 2, … [[9, 9]] * 2])] >>> tf = tfields.TensorFields(points, *fields) >>> m_tf = m.project(tf, delta=0.01) >>> assert m_tf.maps[3].fields[0].equal([2, 42, np.nan, np.nan], equal_nan=True) >>> assert m_tf.maps[3].fields[1].equal([[1, 2, 3], … [3, 4, 5], … [np.nan] * 3, … [np.nan] * 3], … equal_nan=True) >>> assert m_tf.maps[3].fields[2].equal([[[1, 1]] * 2, … [[3, 3]] * 2, … [[np.nan, np.nan]] * 2, … [[np.nan, np.nan]] * 2], … equal_nan=True)
Returning the calculated point_face_assignment can speed up multiple results >>> m_tf, point_face_assignment = m.project(tf, delta=0.01, … return_point_face_assignment=True) >>> m_tf_fast = m.project(tf, delta=0.01, point_face_assignment=point_face_assignment) >>> assert m_tf.equal(m_tf_fast, equal_nan=True)
- template(sub_mesh)[source]¶
‘Manual’ way to build a template that can be used with self.cut :returns:
- template (see cut), can be used as template to retrieve
sub_mesh from self instance
- Return type:
Examples
>>> import tfields >>> from sympy.abc import y >>> mp = tfields.TensorFields([[0,1,2],[2,3,0],[3,2,5],[5,4,3]], ... [1, 2, 3, 4]) >>> m = tfields.Mesh3D([[0,0,0], [1,0,0], [1,1,0], [0,1,0], [0,2,0], [1,2,0]], ... maps=[mp]) >>> m_cut = m.cut(y < 1.5, at_intersection='split') >>> template = m.template(m_cut) >>> assert m_cut.equal(m.cut(template))
- property tree¶
Cached property to retrieve a bounding_box Searcher. This searcher can hugely optimize ‘in_faces’ searches
Examples
>>> import numpy as np >>> import tfields >>> mesh = tfields.Mesh3D.grid((0, 1, 3), (1, 2, 3), (2, 3, 3)) >>> _ = mesh.tree >>> assert hasattr(mesh, '_cache') >>> assert 'mesh_tree' in mesh._cache >>> face_indices = mesh.in_faces(tfields.Points3D([[0.2, 1.2, 2.0]]), ... 0.00001)
You might want to know the number of points per face >>> unique, counts = np.unique(face_indices, return_counts=True) >>> dict(zip(unique, counts)) # one point on triangle number 16 {16: 1}
tfields.planes_3d module¶
Author: Daniel Boeckenhoff Mail: daniel.boeckenhoff@ipp.mpg.de
part of tfields library
- class tfields.planes_3d.Planes3D(tensors, *fields, **kwargs)[source]¶
Bases:
TensorFields
Point-NormVector representaion of planes
Examples
>>> import tfields >>> points = [[0, 1, 0]] >>> norms = [[0, 0, 1]] >>> plane = tfields.Planes3D(points, norms) >>> plane.symbolic()[0] Plane(Point3D(0, 1, 0), (0, 0, 1))
- coord_sys¶
- fields¶
- name¶
tfields.points_3d module¶
Author: Daniel Boeckenhoff Mail: daniel.boeckenhoff@ipp.mpg.de
basic threedimensional tensors
- class tfields.points_3d.Points3D(tensors, **kwargs)[source]¶
Bases:
Tensors
Points3D is a general class for 3D Point operations and storage. Points are stored in np.arrays of shape (len, 3). Thus the three coordinates of the Points stay close.
- Parameters:
constructor (points3DInstance -> copy) –
[points3DInstance1 –
points3DInstance2 –
treated (...] -> coord_sys are correctly) –
coordinates (list of) –
- Kwargs:
- coord_sys (str):
Use tfields.bases.CARTESIAN -> x, y, z Use tfields.bases.CYLINDER -> r, phi, z Use tfields.bases.SPHERICAL -> r, phi, theta
Examples
Initializing with 3 vectors >>> import tfields >>> import numpy as np >>> p1 = tfields.Points3D([[1., 2., 3.], [4., 5., 6.], [1, 2, -6]]) >>> assert p1.equal([[1., 2., 3.], … [4., 5., 6.], … [1., 2., -6.]])
Initializing with list of coordinates >>> p2 = tfields.Points3D(np.array([[1., 2., 3., 4, 5,], … [4., 5., 6., 7, 8], … [1, 2, -6, -1, 0]]).T) >>> assert p2.equal( … [[ 1., 4., 1.], … [ 2., 5., 2.], … [ 3., 6., -6.], … [ 4., 7., -1.], … [ 5., 8., 0.]], atol=1e-8) >>> p2.transform(tfields.bases.CYLINDER) >>> assert p2.equal( … [[ 4.12310563, 1.32581766, 1.], … [ 5.38516481, 1.19028995, 2.], … [ 6.70820393, 1.10714872, -6.], … [ 8.06225775, 1.05165021, -1.], … [ 9.43398113, 1.01219701, 0.]], atol=1e-8)
Copy constructor with one instance preserves coord_sys of instance >>> assert tfields.Points3D(p2).coord_sys == p2.coord_sys
Unless you specify other: >>> assert tfields.Points3D(p2, … coord_sys=tfields.bases.CARTESIAN).equal( … [[ 1., 4., 1.], … [ 2., 5., 2.], … [ 3., 6., -6.], … [ 4., 7., -1.], … [ 5., 8., 0.]], atol=1e-8)
Copy constructor with many instances chooses majority of coordinates systems to avoid much transformation >>> assert tfields.Points3D.merged(p1, p2, p1).equal( … [[ 1., 2., 3.], … [ 4., 5., 6.], … [ 1., 2., -6.], … [ 1., 4., 1.], … [ 2., 5., 2.], … [ 3., 6., -6.], … [ 4., 7., -1.], … [ 5., 8., 0.], … [ 1., 2., 3.], … [ 4., 5., 6.], … [ 1., 2., -6.]], atol=1e-8) >>> p1.transform(tfields.bases.CYLINDER)
… unless specified other. Here it is specified >>> assert tfields.Points3D.merged( … p1, p2, coord_sys=tfields.bases.CYLINDER).equal( … [[ 2.23606798, 1.10714872, 3. ], … [ 6.40312424, 0.89605538, 6. ], … [ 2.23606798, 1.10714872, -6. ], … [ 4.12310563, 1.32581766, 1. ], … [ 5.38516481, 1.19028995, 2. ], … [ 6.70820393, 1.10714872, -6. ], … [ 8.06225775, 1.05165021, -1. ], … [ 9.43398113, 1.01219701, 0. ]], atol=1e-8)
Shape is always (…, 3) >>> p = tfields.Points3D([[1., 2., 3.], [4., 5., 6.], … [1, 2, -6], [-5, -5, -5], [1,0,-1], [0,1,-1]]) >>> p.shape (6, 3)
Empty array will create an ndarray of the form (0, 3) >>> tfields.Points3D([]) Points3D([], shape=(0, 3), dtype=float64)
Use it as np.ndarrays -> masking etc. is inherited >>> mask = np.array([True, False, True, False, False, True]) >>> mp = p[mask].copy()
Copy constructor >>> assert mp.equal( … [[ 1., 2., 3.], … [ 1., 2., -6.], … [ 0., 1., -1.]]) >>> assert tfields.Points3D(mp).equal( … [[ 1., 2., 3.], … [ 1., 2., -6.], … [ 0., 1., -1.]])
Coordinate system is implemented. Default is cartesian >>> p_cart = p.copy() >>> p.transform(tfields.bases.CYLINDER) >>> assert p.equal( … tfields.Points3D([[2.236, 1.107, 3.], … [6.403, 0.896, 6.], … [2.236, 1.107, -6.], … [7.071, -2.356, -5.], … [1. , 0. , -1.], … [1. , 1.571, -1.]], … coord_sys=tfields.bases.CYLINDER), … atol=1e-3) >>> p.transform(tfields.bases.CARTESIAN) >>> assert p.equal(p_cart, atol=1e-15)
- balls(radius, spacing=(5, 3))[source]¶
- Parameters:
radius (float) – radius of spheres
spacing (tuple of int) – n_phi, n_theta
- Returns:
- Builds a sphere around each point with a resolution
defined by spacing and given radius
- Return type:
tfields.Mesh3D
- coord_sys¶
- name¶
tfields.tensor_grid module¶
Implementaiton of TensorGrid class
- class tfields.tensor_grid.TensorGrid(tensors, *fields, **kwargs)[source]¶
Bases:
TensorFields
A Tensor Grid is a TensorField which is aware of it’s grid nature, which is order of iteration (iter-order) over the base vectors (base_vectors).
- Parameters:
*base_vectors (tuple) – indices of the axes which should be iterated
**kwargs – num (np.array): same as np.linspace ‘num’ iter_order (np.array): index order of building the grid. further: see TensorFields class
- base_vectors¶
- coord_sys¶
- explicit()[source]¶
Build the grid explicitly (e.g. after changing base_vector, iter_order or init with empty)
- fields¶
- classmethod grid(*base_vectors, tensors=None, fields=None, **kwargs)[source]¶
Build the grid (explicitly) from base vectors
- Parameters:
args (explicit) – see __new__
**kwargs – see TensorFields
- is_empty()[source]¶
Check if the object is an implicit grid (base points are empty but base_vectors and iter order can be used to build the explicit grid’s base points).
- iter_order¶
- classmethod merged(*objects, **kwargs)[source]¶
Factory method Merges all input arguments to one object
- Parameters:
return_templates (bool) – return the templates which can be used together with cut to retrieve the original objects
dim (int) –
**kwargs – passed to cls
Examples
>>> import numpy as np >>> import tfields >>> import tfields.bases
The new object with turn out in the most frequent coordinate system if not specified explicitly
>>> vec_a = tfields.Tensors([[0, 0, 0], [0, 0, 1], [0, -1, 0]]) >>> vec_b = tfields.Tensors([[5, 4, 1]], ... coord_sys=tfields.bases.cylinder) >>> vec_c = tfields.Tensors([[4, 2, 3]], ... coord_sys=tfields.bases.cylinder) >>> merge = tfields.Tensors.merged( ... vec_a, vec_b, vec_c, [[2, 0, 1]]) >>> assert merge.coord_sys == 'cylinder' >>> assert merge.equal([[0, 0, 0], ... [0, 0, 1], ... [1, -np.pi / 2, 0], ... [5, 4, 1], ... [4, 2, 3], ... [2, 0, 1]])
Merge also shifts the maps to still refer to the same tensors
>>> tm_a = tfields.TensorMaps(merge, maps=[[[0, 1, 2]]]) >>> tm_b = tm_a.copy() >>> assert tm_a.coord_sys == 'cylinder' >>> tm_merge = tfields.TensorMaps.merged(tm_a, tm_b) >>> assert tm_merge.coord_sys == 'cylinder' >>> assert tm_merge.maps[3].equal([[0, 1, 2], ... list(range(len(merge), ... len(merge) + 3, ... 1))])
>>> obj_list = [tfields.Tensors([[1, 2, 3]], ... coord_sys=tfields.bases.CYLINDER), ... tfields.Tensors([[3] * 3]), ... tfields.Tensors([[5, 1, 3]])] >>> merge2 = tfields.Tensors.merged( ... *obj_list, coord_sys=tfields.bases.CARTESIAN) >>> assert merge2.equal([[-0.41614684, 0.90929743, 3.], ... [3, 3, 3], [5, 1, 3]], atol=1e-8)
The return_templates argument allows to retrieve a template which can be used with the cut method.
>>> merge, templates = tfields.Tensors.merged( ... vec_a, vec_b, vec_c, return_templates=True) >>> assert merge.cut(templates[0]).equal(vec_a) >>> assert merge.cut(templates[1]).equal(vec_b) >>> assert merge.cut(templates[2]).equal(vec_c)
- name¶
- num¶
- property rank¶
Tensor rank
tfields.triangles_3d module¶
Author: Daniel Boeckenhoff Mail: daniel.boeckenhoff@ipp.mpg.de
part of tfields library
- class tfields.triangles_3d.Triangles3D(tensors, *fields, **kwargs)[source]¶
Bases:
TensorFields
Points3D child restricted to n * 3 Points. Three Points always group together to one triangle.
- Parameters:
tensors (Iterable | tfields.TensorFields) –
*fields (Iterable | tfields.Tensors) – Fields with the same length as tensors
**kwargs – passed to base class
- see :class:`~tfields.TensorFields`
Examples
>>> import tfields >>> t = tfields.Triangles3D([[1,2,3], [3,3,3], [0,0,0]])
You can add fields to each triangle
>>> t = tfields.Triangles3D(t, tfields.Tensors([42])) >>> assert t.fields[0].equal([42])
- areas(transform=None)[source]¶
Calculate area with “heron’s formula”
- Parameters:
transform (np.ndarray) – optional transformation matrix The triangle points are transformed with transform if given before calclulating the area
Examples
>>> import numpy as np >>> import tfields >>> m = tfields.Mesh3D([[1,0,0], [0,0,1], [0,0,0]], ... faces=[[0, 1, 2]]) >>> assert np.allclose(m.triangles().areas(), np.array([0.5]))
>>> m = tfields.Mesh3D([[1,0,0], [0,1,0], [0,0,0], [0,0,1]], ... faces=[[0, 1, 2], [1, 2, 3]]) >>> assert np.allclose(m.triangles().areas(), np.array([0.5, 0.5]))
>>> m = tfields.Mesh3D([[1,0,0], [0,1,0], [1,1,0], [0,0,1], [1,0,1]], ... faces=[[0, 1, 2], [0, 3, 4]]) >>> assert np.allclose(m.triangles().areas(), np.array([0.5, 0.5]))
- centroids()[source]¶
- Returns:
_centroids()
Examples
>>> import tfields >>> m = tfields.Mesh3D([[0,0,0], [1,0,0], [-1,0,0], [0,1,0], [0,0,1]], ... faces=[[0, 1, 3],[0, 2, 3],[1,2,4], [1, 3, 4]]); >>> assert m.triangles().centroids().equal( ... [[1./3, 1./3, 0.], ... [-1./3, 1./3, 0.], ... [0., 0., 1./3], ... [1./3, 1./3, 1./3]])
- circumcenters()[source]¶
Semi baricentric method to calculate circumcenter points of the triangles
Examples
>>> import numpy as np >>> import tfields >>> m = tfields.Mesh3D([[0,0,0], [1,0,0], [-1,0,0], [0,1,0], [0,0,1]], ... faces=[[0, 1, 3],[0, 2, 3],[1,2,4], [1, 3, 4]]); >>> assert np.allclose( ... m.triangles().circumcenters(), ... [[0.5, 0.5, 0.0], ... [-0.5, 0.5, 0.0], ... [0.0, 0.0, 0.0], ... [1.0 / 3, 1.0 / 3, 1.0 / 3]])
- coord_sys¶
- cut(expression, coord_sys=None)[source]¶
Default cut method for Triangles3D
Examples
>>> import sympy >>> import numpy as np >>> import tfields >>> x, y, z = sympy.symbols('x y z') >>> t = tfields.Triangles3D([[1., 2., 3.], [-4., 5., 6.], [1, 2, -6], ... [5, -5, -5], [1, 0, -1], [0, 1, -1], ... [-5, -5, -5], [1, 0, -1], [0, 1, -1]]) >>> tc = t.cut(x >= 0) >>> assert tc.equal(tfields.Triangles3D([[ 5., -5., -5.], ... [ 1., 0., -1.], ... [ 0., 1., -1.]])) >>> t.fields.append(tfields.Tensors([1,2,3])) >>> tc2 = t.cut(x >= 0) >>> assert np.array_equal(tc2.fields[-1], np.array([2.]))
- edges()[source]¶
Retrieve two of the three edge vectors
- Returns:
- vectors ab and ac, where a, b, c are corners (see
self.corners)
- Return type:
two np.ndarrays
- evalf(expression=None, coord_sys=None)[source]¶
Triangle3D implementation
Examples
>>> from sympy.abc import x >>> import numpy as np >>> import tfields >>> t = tfields.Triangles3D([[1., 2., 3.], [-4., 5., 6.], [1, 2, -6], ... [5, -5, -5], [1,0,-1], [0,1,-1], ... [-5, -5, -5], [1,0,-1], [0,1,-1]]) >>> mask = t.evalf(x >= 0) >>> assert np.array_equal(t[mask], ... tfields.Triangles3D([[ 5., -5., -5.], ... [ 1., 0., -1.], ... [ 0., 1., -1.]]))
- Returns:
mask which is True, where expression evaluates True
- Return type:
np.array
- fields¶
- in_triangles(tensors, delta: Optional[float] = 0.0, assign_multiple: bool = False) Union[List[List[int]], array] [source]¶
Barycentric method to obtain, which tensors are containes in any of the triangles
- Parameters:
tensors (Points3D instance) –
optional –
delta –
float
: Normal distance to a triangle, that the pointsare concidered to be contained in the triangle.
None
: Find the minimum distance. Default is 0.assign_multiple – If True, one point may belong to multiple triangles at the same time. In the other case the first occurence will be True the other False
- Returns:
[index(or indices if assign_multiple) of triangle for point in tensors]
- Return type:
list
- classmethod merged(*objects, **kwargs)[source]¶
Factory method Merges all input arguments to one object
- Parameters:
return_templates (bool) – return the templates which can be used together with cut to retrieve the original objects
dim (int) –
**kwargs – passed to cls
Examples
>>> import numpy as np >>> import tfields >>> import tfields.bases
The new object with turn out in the most frequent coordinate system if not specified explicitly
>>> vec_a = tfields.Tensors([[0, 0, 0], [0, 0, 1], [0, -1, 0]]) >>> vec_b = tfields.Tensors([[5, 4, 1]], ... coord_sys=tfields.bases.cylinder) >>> vec_c = tfields.Tensors([[4, 2, 3]], ... coord_sys=tfields.bases.cylinder) >>> merge = tfields.Tensors.merged( ... vec_a, vec_b, vec_c, [[2, 0, 1]]) >>> assert merge.coord_sys == 'cylinder' >>> assert merge.equal([[0, 0, 0], ... [0, 0, 1], ... [1, -np.pi / 2, 0], ... [5, 4, 1], ... [4, 2, 3], ... [2, 0, 1]])
Merge also shifts the maps to still refer to the same tensors
>>> tm_a = tfields.TensorMaps(merge, maps=[[[0, 1, 2]]]) >>> tm_b = tm_a.copy() >>> assert tm_a.coord_sys == 'cylinder' >>> tm_merge = tfields.TensorMaps.merged(tm_a, tm_b) >>> assert tm_merge.coord_sys == 'cylinder' >>> assert tm_merge.maps[3].equal([[0, 1, 2], ... list(range(len(merge), ... len(merge) + 3, ... 1))])
>>> obj_list = [tfields.Tensors([[1, 2, 3]], ... coord_sys=tfields.bases.CYLINDER), ... tfields.Tensors([[3] * 3]), ... tfields.Tensors([[5, 1, 3]])] >>> merge2 = tfields.Tensors.merged( ... *obj_list, coord_sys=tfields.bases.CARTESIAN) >>> assert merge2.equal([[-0.41614684, 0.90929743, 3.], ... [3, 3, 3], [5, 1, 3]], atol=1e-8)
The return_templates argument allows to retrieve a template which can be used with the cut method.
>>> merge, templates = tfields.Tensors.merged( ... vec_a, vec_b, vec_c, return_templates=True) >>> assert merge.cut(templates[0]).equal(vec_a) >>> assert merge.cut(templates[1]).equal(vec_b) >>> assert merge.cut(templates[2]).equal(vec_c)
- name¶
- norms()[source]¶
Examples
>>> import numpy as np >>> import tfields >>> m = tfields.Mesh3D([[0,0,0], [1,0,0], [-1,0,0], [0,1,0], [0,0,1]], ... faces=[[0, 1, 3],[0, 2, 3],[1,2,4], [1, 3, 4]]); >>> assert np.allclose(m.triangles().norms(), ... [[0.0, 0.0, 1.0], ... [0.0, 0.0, -1.0], ... [0.0, 1.0, 0.0], ... [0.57735027] * 3], ... atol=1e-8)
Module contents¶
Top-level package of tfields. TODO: proper documentation, also in dough.