Distance computation from a surface mesh

Imports

[1]:
import numpy as np
import pyvista as pv
pv.global_theme._jupyter_backend = 'panel' # remove this line to get interactive 3D plots
from Muscat.Simple import *
from Muscat.Containers.MeshInspectionTools import ExtractElementsByElementFilter
from Muscat.Bridges.PyVistaBridge import MeshToPyVista
from Muscat.Containers.MeshCreationTools import CreateDisk
from Muscat.Containers.MeshFieldOperations import GetFieldTransferOp
from Muscat.Containers.MeshTools import GetElementsCenters

Mesh Creation and Target Points

[2]:
# create a mesh and be add and extra zeros to obtain a mesh in 3D
diskMesh = CreateDisk(nr = 10, nTheta= 10, r0=0.5, r1= 1., theta0= 0, theta1=np.pi/2, ofTriangles=True)
diskMesh.nodes = np.hstack((diskMesh.nodes,np.zeros((diskMesh.GetNumberOfNodes(),1), dtype=diskMesh.nodes.dtype ) ) )
[3]:
# define some target points
TargetPoints = np.array(
                        [[1.0,1.0,0],
                         [0.2,0.6,0.6],
                         [-.2,0.8,0],
                         [0.6,0.2,0.0],
                         ])

Transfer Operator

Compute the transfer operator from an isoparametric field mesh to the target points.

  • By default the FEField is isoparametric (number of nodes == number of dofs)

  • By default the method is “Interp/Clamp”

[4]:
P, status, entities =  GetFieldTransferOp(FEField('input',diskMesh),TargetPoints)

Extract Used Elements and Compute Elements Centers

[5]:
# compute the position of the information extraction
dataExtractionPoints = P.dot(diskMesh.nodes)
# generate a mask to plot elements used for the ext
mask =np.zeros(diskMesh.GetNumberOfElements(), dtype=bool)
# be sure to put true only in the case of 1: "Interp"=1 or "Clamp"=3
mask[entities] = np.logical_or(status ==1,status == 3)
# extract elements using the mask
usedElements = ExtractElementsByElementFilter(diskMesh, ElementFilter(eMask=mask))
#compute the center of the used elements
elementCenters = GetElementsCenters(usedElements)

Console Output

[6]:
np.set_printoptions(precision=3,suppress=True)
print(f"Number of target points: {TargetPoints.shape[0]}")
print("Position if the location to extract the information ")
print(dataExtractionPoints)
print(f"Status : {status.flatten()}")
print(f"Entities : {entities.flatten()}")
Number of target points: 4
Position if the location to extract the information
[[0.704 0.704 0.   ]
 [0.2   0.6   0.   ]
 [0.    0.8   0.   ]
 [0.6   0.2   0.   ]]
Status : [3 3 3 1]
Entities : [188  86 143  75]

Graphical Output

[7]:
p = pv.Plotter()
p.add_mesh(MeshToPyVista(diskMesh),style="surface",show_edges=True)
p.add_mesh(MeshToPyVista(usedElements), line_width=5,color="RED")
for tp in range(TargetPoints.shape[0]):
    p.add_ruler(dataExtractionPoints[tp,:], TargetPoints[tp,:], number_labels=2, show_labels=False, title="")
    #p.add_mesh(pv.Sphere(radius=0.001, center= TargetPoints[tp,:]))
    p.add_points(TargetPoints[tp,:],style="points")
    p.add_points(TargetPoints, render_points_as_spheres=True, point_size=1)
    p.add_point_labels(TargetPoints, labels= list(map(lambda x: "Target Point:"+str(x),range(TargetPoints.shape[0]))),shape_opacity=0.5, bold=False)
    p.add_point_labels(elementCenters, labels= list(map(lambda x : "Source Element:" +str(x) ,entities.flatten())),point_size=5, shape_opacity=0.5,justification_vertical="top",justification_horizontal="right",fill_shape=False,shape=None, bold=False)
p.show()
../_images/notebooks_DistanceComputations_14_0.png