This page was generated from
docs\source\notebooks/mesh_analysis.ipynb.
Mesh Analysis#
sigmaepsilon.mesh provides some useful classes and algorithms for mesh management and operations related to the geometry or the topology of polygonal meshes.
[1]:
import pyvista as pv
import numpy as np
from sigmaepsilon.mesh import PolyData
d, h, a = 6.0, 15.0, 15.0
cyl = pv.CylinderStructured(
center=(0.0, 0.0, 0.0),
direction=(0.0, 0.0, 1.0),
radius=np.linspace(d / 2, a / 2, 15),
height=h,
theta_resolution=100,
z_resolution=40,
)
mesh: PolyData = PolyData.from_pv(cyl)
Nodal Distribution Factors#
[2]:
mesh.nodal_distribution_factors()
[2]:
array([[1. , 0.47580645, 0.23790323, ..., 0.23790323, 0.11895161,
0.25 ],
[0.52419355, 0.47794118, 0.23897059, ..., 0.23897059, 0.11948529,
0.13104839],
[0.52205882, 0.47972973, 0.23986486, ..., 0.23986486, 0.11993243,
0.13051471],
...,
[0.12807377, 0.12207031, 0.24414062, ..., 0.24414062, 0.48828125,
0.51229508],
[0.12792969, 0.12220149, 0.24440299, ..., 0.24440299, 0.48880597,
0.51171875],
[0.12779851, 0.25 , 0.5 , ..., 0.5 , 1. ,
0.51119403]])
Nodal Adjacency#
To access the nodal adjacency matrix as a scipy sparse matrix:
[3]:
mesh.nodal_adjacency(frmt="scipy-csr")
[3]:
<60600x60600 sparse array of type '<class 'numpy.intc'>'
with 1527274 stored elements in Compressed Sparse Row format>
[4]:
mesh.nodal_adjacency(frmt="nx")
[4]:
<networkx.classes.graph.Graph at 0x20a5d6d3820>
as an Awkward
array:
[5]:
mesh.nodal_adjacency(frmt="jagged")
[5]:
[[0, 1, 15, 16, 1515, 1516, 1530, 1531], [0, 1, 2, 15, 16, 17, 1515, 1516, 1517, 1530, 1531, 1532], [1, 2, 3, 16, 17, 18, 1516, 1517, 1518, 1531, 1532, 1533], [2, 3, 4, 17, 18, 19, 1517, 1518, 1519, 1532, 1533, 1534], [3, 4, 5, 18, 19, 20, 1518, 1519, 1520, 1533, 1534, 1535], [4, 5, 6, 19, 20, 21, 1519, 1520, 1521, 1534, 1535, 1536], [5, 6, 7, 20, 21, 22, 1520, 1521, 1522, 1535, 1536, 1537], [6, 7, 8, 21, 22, 23, 1521, 1522, 1523, 1536, 1537, 1538], [7, 8, 9, 22, 23, 24, 1522, 1523, 1524, 1537, 1538, 1539], [8, 9, 10, 23, 24, 25, 1523, 1524, 1525, 1538, 1539, 1540], ..., [59060, 59061, 59062, 59075, 59076, ..., 60576, 60577, 60590, 60591, 60592], [59061, 59062, 59063, 59076, 59077, ..., 60577, 60578, 60591, 60592, 60593], [59062, 59063, 59064, 59077, 59078, ..., 60578, 60579, 60592, 60593, 60594], [59063, 59064, 59065, 59078, 59079, ..., 60579, 60580, 60593, 60594, 60595], [59064, 59065, 59066, 59079, 59080, ..., 60580, 60581, 60594, 60595, 60596], [59065, 59066, 59067, 59080, 59081, ..., 60581, 60582, 60595, 60596, 60597], [59066, 59067, 59068, 59081, 59082, ..., 60582, 60583, 60596, 60597, 60598], [59067, 59068, 59069, 59082, 59083, ..., 60583, 60584, 60597, 60598, 60599], [59068, 59069, 59083, 59084, 60583, 60584, 60598, 60599]] ----------------------------------------------------------------------------- type: 60600 * var * int64
or as a Numba-jittable CSR matrix from sigmaepsilon.math
:
[6]:
mesh.nodal_adjacency(frmt="csr")
[6]:
60600x60600 CSR matrix of 1527274 values.
Pseudo Peripheral Nodes#
[7]:
from sigmaepsilon.math.topology.graph import pseudo_peripheral_nodes
csr = mesh.nodal_adjacency(frmt="csr")
ppn = pseudo_peripheral_nodes(csr)
Rooted Level Structure#
[8]:
from sigmaepsilon.math.topology.graph import rooted_level_structure
rls = rooted_level_structure(csr)
K-Nearest-Neighbours with Scipy
or SkLearn
#
[11]:
from sigmaepsilon.mesh import grid, PolyData, PointData
from sigmaepsilon.mesh.cells import H8
size = 80, 60, 20
shape = 10, 8, 4
coords, topo = grid(size=size, shape=shape, eshape="H8")
pd = PointData(coords=coords)
cd = H8(topo=topo)
mesh = PolyData(pd, cd)
mesh.k_nearest_cell_neighbours(k=3, knn_options=dict(max_distance=10.0))[:5]
[11]:
array([[0, 1, 4],
[1, 2, 0],
[2, 1, 3],
[3, 2, 7],
[4, 5, 0]], dtype=int64)