Utils for cutting treatment

Class for canonical geometric cells

The class for canonical geometric cells.

Given a cell described by its vertices, provides:

  • recipes for building faces and edges from cell vertices.

  • recipes for building intersection polygons from cell components intersecting the surface.

The recipes for building faces and edges are arrays of local vertices. The recipes for building intersection polygons requires the list of intersecting vertices (ON-SURFACE vertices) and the list of intersecting edges (cross-edges). A binary hash is computed the 2 lists and is used as a key for finding the corresponding recipe in a hashtable. The recipe is the ordered list of cell components that would form the intersecting polygon.

Cell components are the union of N vertices and M edges:

  • Vertices are listed from 0 to N-1

  • Edges are listed from N to N+M-1

class antares.utils.geomcut.geokernel.AbstractKernel

Abstract base classe for geometric kernels.

It provides a kind of hashtable. Depending on which components of a cell intersect whith a cut-surface, returns a recipe for building the intersection polygon. The set of components that are part of the intersection is used as a key.

Attributes:

  • edgemap: list of edges for 1 cell, expressed as couples of local vertices.

  • facemap: list of faces for 1 cell. A face has 4 points at most.

    facemap is expressed as lists of four vertices.

  • ctypeset: list of possible polygons resulting from a cut, expressed as couples (nb. of vertices, name)

  • nvtxface: number of vertices per face

static build_component(vrtx_array, edge_array)

Vertices and edges are both considered as cell ‘components’. Properly merge 2 arrays of vertices and edges to output an array of components.

Parameters:
  • vrtx_array – array of cell vertices. element i holds a value for vertex i.

  • edge_array – array of cell edges. element j holds a value for edge j.

Returns:

array of cell components. element k holds a value for component k, which can be either a vertice or a edge.

static build_hash(component_bool, edge_bool=None)

Every component may be cut or not by the cut-surface. A vertex is cut when it is part of the surface. An edge is cut when its 2 ends are on opposite sides of the surface.

Parameters:
  • component_bool – a boolean mask saying wether each component is cut or not.

  • edge_bool – a boolean mask saying wether each each is cut or not. Provided if and only if component_bool contains vertex information only.

Returns:

a cell-hash (binary key) that carry the same information as the boolean mask.

classmethod recipe(hashlist)

A Geokernel object aims at providing an easy way of building polygons defined by the intersection of a plane of cut and a 3D cell. Any component cut by the surface issues a cut-point on the surface. Depending on wich cell component are cut by the surface, this function returns the ordered list of components whose corresponding cut-points draw a cut-polygon.

Parameters:

hashlist – list of cell-hash

Returns:

ctypes, recipes - ctypes: the number of cut-points per polygons. - recipes: the actual list of cut-points for each polygon.

classmethod validate_hash(hashlist)

Test if a hash represents a cut pattern that can be handled by the Geokernel object.

Parameters:

hashlist – list of cell-hash

Returns:

array of boolean

ctypeset
edgemap
facemap
nvtxface
class antares.utils.geomcut.geokernel.TriKernel

Kernel for triangle.

ctypeset = [(2, 'bi'), (3, 'tri')]
edgemap = array([[0, 1],        [0, 2],        [1, 2]])
facemap = array([[0, 1, 1, 1],        [0, 2, 2, 2],        [1, 2, 2, 2]])
nvtxface = array([2, 2, 2])
class antares.utils.geomcut.geokernel.QuaKernel

Kernel for quadrilateral.

ctypeset = [(2, 'bi'), (4, 'qua')]
edgemap = array([[0, 1],        [0, 3],        [1, 2],        [2, 3]])
facemap = array([[0, 1, 1, 1],        [0, 3, 3, 3],        [1, 2, 2, 2],        [2, 3, 3, 3]])
nvtxface = array([2, 2, 2, 2])
class antares.utils.geomcut.geokernel.TetKernel

Kernel for tetrahedra.

ctypeset = [(3, 'tri'), (4, 'qua')]
edgemap = array([[0, 1],        [0, 2],        [0, 3],        [1, 2],        [1, 3],        [2, 3]])
facemap = array([[0, 1, 2, 2],        [0, 1, 3, 3],        [0, 2, 3, 3],        [1, 2, 3, 3]])
nvtxface = array([3, 3, 3, 3])
class antares.utils.geomcut.geokernel.PyrKernel

Kernel for pyramids.

ctypeset = [(3, 'tri'), (4, 'qua'), (5, 'pen')]
edgemap = array([[0, 1],        [0, 3],        [0, 4],        [1, 2],        [1, 4],        [2, 3],        [2, 4],        [3, 4]])
facemap = array([[0, 1, 2, 3],        [0, 1, 4, 4],        [0, 3, 4, 4],        [1, 2, 4, 4],        [2, 3, 4, 4]])
nvtxface = array([4, 3, 3, 3, 3])
class antares.utils.geomcut.geokernel.PriKernel

Kernel for prisms.

ctypeset = [(3, 'tri'), (4, 'qua'), (5, 'pen')]
edgemap = array([[0, 1],        [0, 2],        [0, 3],        [1, 2],        [1, 4],        [2, 5],        [3, 4],        [3, 5],        [4, 5]])
facemap = array([[0, 1, 2, 2],        [0, 1, 4, 3],        [0, 2, 5, 3],        [1, 2, 5, 4],        [3, 4, 5, 5]])
nvtxface = array([3, 4, 4, 4, 3])
class antares.utils.geomcut.geokernel.HexKernel

Kernel for hexahedra.

ctypeset = [(3, 'tri'), (4, 'qua'), (5, 'pen'), (6, 'hxg')]
edgemap = array([[0, 1],        [0, 3],        [0, 4],        [1, 2],        [1, 5],        [2, 3],        [2, 6],        [3, 7],        [4, 5],        [4, 7],        [5, 6],        [6, 7]])
facemap = array([[0, 1, 2, 3],        [0, 1, 5, 4],        [0, 3, 7, 4],        [1, 2, 6, 5],        [2, 3, 7, 6],        [4, 5, 6, 7]])
nvtxface = array([4, 4, 4, 4, 4, 4])

Class for geometric surfaces

Module defining classes for different types of geometric surfaces.

The class for geometric surface objects. The abstract class provides a common interface for any specific surface.

A surface is composed of 1 or more internal component.

Provided mono-component surfaces are:

  • plane: defined by an origin point and a normal vector

  • sphere: center point and radius

  • cylinder: axis (origin point and direction vector) and radius

  • cone: axis and apex angle

The only component in these surfaces encloses the whole surface.

Provided poly-component surface is:

  • extruded polyline: sequence of coplanar points and extrusion vector

Each component in a polyline is an extruded segment, defined by 2 successive points.

The API exposes the following methods:

  • partition_nodes:

    • Assign each point with a label that describe the relative position of the point to the surface.

    • The 3 partitions are FRONT, REAR, ON-SURFACE.

    • FRONT and REAR contains points on opposite sides that do not belong to the surface.

    • ON-SURFACE contains points that belong to the surface. These points are also assigned the corresponding internal component identifier.

  • bind_crossedges:

    • For mesh edges whose 2 vertices belong to opposite partitions (FRONT and REAR).

    • Computes interpolation weights that defines the intersection point from the edges vertices.

    • Assign each edges with the identifier of the internal component the intersection point belongs to.

  • normal:

    • Uses point coordinates and corresponding component id.

    • Returns vectors normal to the surface at given points, all of them oriented toward the same side of the surface. (the FRONT side)

class antares.utils.geomcut.geosurface.AbstractSurface

Abstract base class for geometric surfaces.

Declare two methods that derived classes must implement.

abstract bind_crossedges(dict_cell_conn, node_label, xyz_coords, kernels)

Abstract method.

Bind a set of edges to the surface. It consists in:

  • assigning every edges with an internal surface id.

  • computing interpolation weights for edge vertices.

abstract normal(node_surf, node_coords)

Abstract method.

Return a vector normal to the surface for each point in a set.

Parameters:

node_coords – (x,y,z) coordinates of a set of points.

Returns:

unit vectors normal to the surface at given points.

abstract partition_nodes(xyz_coords, epsilon=1e-08)

Abstract method.

Partition a set of points into 3 subsets:

  • FRONT: one side of the surface

  • REAR: the other side

  • ON-SURFACE: points that are exactly on the surface (modulo an epsilon)

Parameters:

xyz_coords – (x,y,z) coordinates of a set of points.

Returns:

label of the partition a node belongs to

class antares.utils.geomcut.geosurface.Plane(origin, normal)

A parametric plane.

bind_crossedges(dict_cell_conn, node_label, xyz_coords, kernels)

Bind a set of edges to the surface.

It consists in:

  • assigning every edges with an internal surface id.

  • computing interpolation weights for edge vertices.

normal(node_surf, node_coords)

Return a vector normal to the plane for each point in a set.

Parameters:

xyz_coords – (x,y,z) coordinates of a set of points.

Returns:

unit vectors normal to the surface at given points.

partition_nodes(xyz_coords, epsilon=1e-08)

Partition a set of points into 3 subsets.

  • FRONT: one side of the surface

  • REAR: the other side

  • ON-SURFACE: points that are exactly on the surface

    (modulo an epsilon)

Parameters:

xyz_coords – (x,y,z) coordinates of a set of points.

Returns:

label of the partition a node belongs to

class antares.utils.geomcut.geosurface.Cylinder(origin, direction, radius)

A parametric cylinder.

bind_crossedges(dict_cell_conn, node_label, xyz_coords, kernels)

Bind a set of edges to the surface.

It consists in:

  • assigning every edges with an internal surface id.

  • computing interpolation weights for edge vertices.

normal(node_surf, node_coords)

Return a vector normal to the cylinder for each point in a set.

Normals are directed to the outside of the cylinder.

Parameters:

xyz_coords – (x,y,z) coordinates of a set of points.

Returns:

unit vectors normal to the surface at given points.

partition_nodes(xyz_coords, epsilon=1e-08)

Partition a set of points into 3 subsets.

  • FRONT: one side of the surface

  • REAR: the other side

  • ON-SURFACE: points that are exactly on the surface

    (modulo an epsilon)

Parameters:

xyz_coords – (x,y,z) coordinates of a set of points.

Returns:

label of the partition a node belongs to

class antares.utils.geomcut.geosurface.Sphere(origin, radius)

A parametric sphere.

bind_crossedges(dict_cell_conn, node_label, xyz_coords, kernels)

Bind a set of edges to the surface.

It consists in:

  • assigning every edges with an internal surface id.

  • computing interpolation weights for edge vertices.

normal(node_surf, node_coords)

Return a vector normal to the sphere for each point in a set.

Normals are directed to the outside of the sphere.

Parameters:

xyz_coords – (x,y,z) coordinates of a set of points.

Returns:

unit vectors normal to the surface at given points.

partition_nodes(xyz_coords, epsilon=1e-08)

Partition a set of points into 3 subsets.

  • FRONT: one side of the surface

  • REAR: the other side

  • ON-SURFACE: points that are exactly on the surface

    (modulo an epsilon)

Parameters:

xyz_coords – (x,y,z) coordinates of a set of points.

Returns:

label of the partition a node belongs to

radius
class antares.utils.geomcut.geosurface.Cone(origin, direction, angle)

A parametric cone.

bind_crossedges(dict_cell_conn, node_label, xyz_coords, kernels)

Bind a set of edges to the surface.

It consists in:

  • assigning every edges with an internal surface id.

  • computing interpolation weights for edge vertices.

normal(node_surf, node_coords)

Return a vector normal to the cone for each point in a set.

Normals are directed to the outside of the sphere.

Parameters:

xyz_coords – (x,y,z) coordinates of a set of points.

Returns:

unit vectors normal to the surface at given points.

partition_nodes(xyz_coords, epsilon=1e-08)

Partition a set of points into 3 subsets.

  • FRONT: one side of the surface

  • REAR: the other side

  • ON-SURFACE: points that are exactly on the surface

    (modulo an epsilon)

Parameters:

xyz_coords – (x,y,z) coordinates of a set of points.

Returns:

label of the partition a node belongs to

class antares.utils.geomcut.geosurface.PolyLine(point_coord, axis)

An extruded polyline.

bind_crossedges(dict_cell_conn, node_label, xyz_coords, kernels)

Bind a set of edges to the surface.

It consists in:

  • assigning every edges with an internal surface id.

  • computing interpolation weights for edge vertices.

Parameters:
  • node_label (ndarray of size 'total number of mesh points') – label of nodes (which side of the surface)

  • dict_cell_conn (dict) – subset of mesh cell connectivity. It includes cells that cross the surface.

normal(node_surf, node_coords)

Return a vector normal to the cone for each point in a set.

Normals are directed to the outside of the sphere.

Parameters:

xyz_coords – (x,y,z) coordinates of a set of points.

Returns:

unit vectors normal to the surface at given points.

partition_nodes(node_coords, epsilon=1e-08)

Partition a set of points into 3 subsets.

  • FRONT: one side of the surface

  • REAR: the other side

  • ON-SURFACE: points that are exactly on the surface

    (modulo an epsilon)

Parameters:

xyz_coords – (x,y,z) coordinates of a set of points.

Returns:

label of the partition a node belongs to

axis
coords

Class for Tetrahedralizer

Subdivide 3D mesh cells into tetrahedra, or 2D mesh cells into triangles.

References

How to subdivide pyramids, prisms and hexaedra into tetrahedra, J. Dompierre, P. Labbe, M-G. Vallet, R. Camarero, Rapport CERCA R99-78, 24 august 1999 Conference paper from the 8th International Meshing Roundtable, Lake Tahoe, Cal., 10-13/10/1999

class antares.utils.geomcut.tetrahedralizer.Tetrahedralizer(dim, connectivity)

Build the tetrahedralisation of a mesh.

interpolate(value, location)
Returns:

interpolated value for the tetrahedral mesh.

interpolate_cell(value)
Returns:

interpolated cells values (order 0)

interpolate_node(value)
Returns:

node values

property connectivity
Returns:

tetrahedral connectivity.

Return type:

CustomDict

property src_cell
Returns:

mapping between new cells and parent cells.

Class for Cutter

This module provides a class for building the geometric intersection between a cell-based unstructured mesh and a parametric surface.

The resulting connectivity is built during object initialization. This object can next be used to interpolate mesh data at the surface.

An object that internally computes the intersection between a surface and a 3D unstructured mesh. It records information about intersection connectivity and interpolation operands / weights.

— Cut-Connectivity —

The intersection between mesh elements and the surface.

  • Cut-nodes: The intersection points between the edge-based connectivity and the surface

  • Cut-edges: The intersection segments between the face-based connectivity and the surface.

  • Cut-cells: The intersection polygons between the cell-based connectivity and the surface.

The cut-connectivity is computed from, and is expressed as, a cell-based connectivity. This connectivity is exposed as an object read-only attribute, as long as cut-node coordinates.

— Interpolation —

The Cutter class exposes methods for computing values on the intersection from mesh values.

  • Cut-nodes: values are interpolated from pairs of mesh-node values (weighted average).

  • Cut-cells: values are inherited from parent mesh-cell values (copy).

— Algorithm —

The Cutter works as follow: - Find the list of mesh components that intersect the surface - Build intersection connectivity and record interpolation data

1/ Mesh Component intersecting the surface

  • Partition nodes depending on their position to the surface:

    • ON-SURFACE partition: nodes that belong to the surface

    • FRONT partition: nodes that are “in front of” the surface.

    • REAR partition: nodes that are “behind” the surface.

    • FRONT and REAR partition denote opposite sides and depend on the surface parameters only.

  • Find cells intersecting the surface using node partitioning:

    • Cells with at least 2 vertices on opposite sides (FRONT and REAR)

    • Cells with a face belonging to the surface (ON-SURFACE face)

      • Such cells may be paired together, sharing a common face.

      • If so, only 1 cell per pair is selected.

  • In selected cells, using node partitioning, find:

    • ON-SURFACE vertices

    • Cross-edges: edges with 2 vertices and opposite sides (FRONT and REAR)

2/ Interpolating cut-nodes (intersection points)

  • ON-SURFACE nodes are also cut-nodes.

  • 1 cross-edge gives 1 cut-node. Interpolation is made from its 2 vertices.

  • Records pairs of input mesh nodes, and the corresponding weights.

  • Also build a mapping between cell components and cut-nodes, used in next step. - cell components are the union of cell vertices and edges

3/ Building cut-connectivity

  • 1 selected mesh cell <=> 1 cut-cell (intersection polygon).

  • The union of ON-SURFACE vertices and cross-edges forms a unique cut-pattern.

  • Use the cut-pattern to build intersection polygons.

  • Records a cell-based connectivity composed of polygons whose vertices are cut-nodes’ indices.

4/ Finalisation:

  • Polygon normals are oriented randomly. - Reorganise vertices so that normals are all oriented in the same consistent direction.

  • Some cells may lead to polygons with up to 6 vertices, not handled by Antares. - Such polygons are recursively split, until the output contains only triangles and quads.

— Architecture —

The algorithm is executed during the cutter initialisation. It takes as arguments:

  • mesh description: cell-based connectivity organized by cell types (dictionnary type) and node coordinates (single array).

  • surface descrption: a single object that provides methods for partitioning mesh elements and computing interpolation weights.

It also internally relies on a set of GeoKernel objects that provides:

  • mapping for building faces and edges from canonical cell vertices.

  • pre-computed recipes for building intersection polygons from canonical cell components.

class antares.utils.geomcut.cutter.Cutter(dict_cell_conn, node_coord, surface, ctypedict={2: 'bi', 3: 'tri', 4: 'qua'})

Compute the geometric intersection between a surface and a mesh.

The intersection connectivity is built during initialisation. The instanciated object can then be used as a simple wrapper for interpolating data on the surface.

This class accepts point coordinates expressed in any 3D system.

interpolate(value, location)

Get the interpolated value.

Returns:

interpolated value on the cut.

interpolate_cell(value)

Compute Interpolated value at the node of the cut.

Parameters:

value – 1D array of cell-values to interpolate.

Returns:

dict with cell-values interpolated at the cut plane.

interpolate_node(value)

Compute Interpolated value at the node of the cut.

Parameters:

value – 1D array of node-values to interpolate.

Returns:

node-values interpolated at the cut plane.

property cell_conn
Returns:

a dictionary with keys for cell types, containing the cell-base connectivity of the cut.

When using the treatment cut with the option line_points, then the following function can be used to get the values points of many slices (or sections) named section_names from a file sections.json.

from antares.utils.CutUtils import parse_json_xrcut
section_names, points = parse_json_xrcut('sections.json')
antares.utils.CutUtils.parse_json_xrcut(fname)

Read points of a (x, r) line.

Json file format: { “name of section 1”: { “type”:”x1r1x2r2”, “x1r1x2r2”: [1., 1., -4., 6.] }, “name of section 2”: { “type”:”x1r1x2r2”, “x1r1x2r2”: [7., 1., 6., 1.] } }

Parameters:

fname (str) – json filename that contains the definition of (x, r) lines. Their units must be the millimeter.

Returns:

Names of sections.

Return type:

list(str)

Returns:

Coordinates (x, r) of points of sections in (x, r, theta) system. Their units is the meter.

Return type:

list(tuple(float,float))