<CaribouBarycentricMapping />¶
Doxygen:
SofaCaribou::mapping::CaribouBarycentricMapping
Generic barycentric mapping.
The CaribouBarycentricMapping allows to embed nodes into a containing domain. For each embedded nodes, called mapped nodes, the index of the element (from the container domain) that contains it is stored, paired to the barycentric coordinates of the node within this element. When paired with a mechanical object (mo), each of the mo’s node positions will automatically follow the parent element that contains it.
Attributes¶
Attribute |
Format |
Default |
Description |
---|---|---|---|
topology |
path |
N/A |
Topology that contains the embedding (parent) elements. |
Quick example¶
Here’s an example of a visual model of a cylinder mapped into a rectangular beam. The cylinder is a triangular mesh, while the rectangular beam is a complete Finite Element solution modelled using a quadratic hexahedral mesh.
import Sofa, meshio, numpy as np
from pathlib import Path
# FE hexahedral mesh
current_dir = Path(__file__).parent
beam_q2 = meshio.read((current_dir / '..' / 'Validation' / 'meshes' / 'beam_q2.vtu').resolve())
# Mapped surface mesh
cylinder = meshio.read((current_dir / '..' / 'Validation' / 'meshes' / 'cylinder_p1.vtu').resolve())
# Material
young_modulus = 10000
poisson_ratio = 0.49
# Scene creation
def createScene(root):
root.addObject('RequiredPlugin', pluginName='SofaCaribou SofaBoundaryCondition SofaEngine SofaOpenglVisual SofaGeneralVisual')
root.addObject('VisualStyle', displayFlags='showVisualModels showBehaviorModels')
root.addObject('StaticODESolver', newton_iterations=10, residual_tolerance_threshold=1e-5, pattern_analysis_strategy="BEGINNING_OF_THE_TIME_STEP")
root.addObject('LDLTSolver', backend="Pardiso")
root.addChild('mechanics')
# Mechanical model of the rectangular beam
root.mechanics.addObject('MechanicalObject', name='mo', position=(mesh.points + p).tolist(), showObject=True, showObjectScale=5)
root.mechanics.addObject('CaribouTopology', name='volumetric_topology', template=caribou_type, indices=mesh.cells_dict[meshio_type].tolist())
root.mechanics.addObject('SaintVenantKirchhoffMaterial', young_modulus=young_modulus, poisson_ratio=poisson_ratio)
root.mechanics.addObject('HyperelasticForcefield')
root.mechanics.addObject('BoxROI', name='fixed_roi', box=[p[0]-7.5, p[1]-7.5, p[2]-0.9, p[0]+7.5, p[1]+7.5, p[2]+0.1])
root.mechanics.addObject('FixedConstraint', indices='@fixed_roi.indices')
# Visual model of the cylinder mapped inside the parent mechanical beam
root.mechanics.addChild('visual')
root.mechanics.visual.addObject('CaribouTopology', name='surface_topology', template='Triangle', indices=cylinder.cell_dict['triangle'].tolist(), position=cylinder.points.tolist())
root.mechanics.visual.addObject('OglModel', name='mo', position='@surface_topology.position', triangles='@surface_topology.indices', color='green')
root.mechanics.visual.addObject('CaribouBarycentricMapping', topology='../volumetric_topology')
Available python bindings¶
None at the moment.