+
+
Mechanical matrix mapper
+
+
In this scene we demonstrate how to use the MechanicalMatrixMapper component. This component allows to map mechanical matrices (Stiffness, Mass) through a mapping.
+
This is needed in SOFA scenes having these two following particularities:
+
-- There are using a direct solver (e.g. SparseLDLSolver) that, unlike
+ iterative solvers, need to build the mechanical matrices.
+
-- They involves ForceFields that implement addKToMatrix (i.e. that compute internal forces such as e.g. TetrahedronFEMForceField,
+ TetrahedronHyperElasticityFEMForceField, but not ConstantForceField which only contributes to the right-hand side) and that
+ ARE USED UNDER mappings. In this scene, the HexaHedronFEMForceField is used under a SubsetMultiMapping and a RigidMapping), and the MechanicalMatrixMapper is needed to map that ForceField to the degrees of freedom closer to the root in the scene graph.
+
+
Without this component, such a scene either crashes or gives unlogical behaviour.
+
+
+
+
+
+
+
+
diff --git a/examples/Components/animationloop/MechanicalMatrixMapper.pyscn b/examples/Components/animationloop/MechanicalMatrixMapper.pyscn
new file mode 100644
index 00000000000..570db1e550d
--- /dev/null
+++ b/examples/Components/animationloop/MechanicalMatrixMapper.pyscn
@@ -0,0 +1,48 @@
+import Sofa
+
+def createScene(rootNode):
+
+ rootNode.createObject('RequiredPlugin', name='ModelOrderReduction')
+ rootNode.createObject('VisualStyle', displayFlags='showCollisionModels hideMappings showForceFields')
+
+ meshDivision = rootNode.createChild('meshDivision')
+ meshDivision.createObject('RegularGridTopology', name='topology', n=[2, 2, 4] , min=[-1, -1, -2], max=[1, 1, 2])
+ meshOfStructure = meshDivision.createObject('Mesh',name='beamMesh', src="@topology")
+ meshDivision.createObject('MechanicalObject', template='Vec3d')
+ boxFixed= meshDivision.createObject('BoxROI',template="Vec3d", name='box_roi_fix',box=[-1, -1, -2.05, 1, 1, -1.5] , position="@beamMesh.position" )
+ boxDeformable= meshDivision.createObject('BoxROI',template="Vec3d", name='box_roi_deformable',box=[-1, -1, -2.05, 1, 1, 1.5], position="@beamMesh.position" )
+ boxRigid= meshDivision.createObject('BoxROI',template="Vec3d", name='box_roi_rigid',box=[-1, -1, 1.500001, 1, 1, 2.05], position="@beamMesh.position")
+
+ SolverNode= rootNode.createChild('SolverNode')
+ SolverNode.createObject('EulerImplicit',verbose='false')
+ SolverNode.createObject('SparseLDLSolver', name="ldlsolveur")
+ SolverNode.createObject('MechanicalMatrixMapper', template='Vec3d,Rigid', object1='@./deformablePartNode/beamPart1Mech', object2='@./RigidNode/rigid1', nodeToParse='@./deformablePartNode/FEMNode')
+
+
+##### Deformable Part of the BEAM (Main Body)
+ deformablePartNode= SolverNode.createChild('deformablePartNode')
+ deformablePartNode.createObject('MechanicalObject', template='Vec3d',name='beamPart1Mech', position="@"+boxDeformable.getPathName()+".pointsInROI")
+
+##### Rigid Part of the BEAM (Top)
+ RigidNode= SolverNode.createChild('RigidNode')
+ RigidNode.createObject("MechanicalObject",template="Rigid",name="rigid1", position=[0, 0, 2, 0, 0, 0, 1], showObject=True, showObjectScale=0.5)
+ RigidifiedNode= RigidNode.createChild('RigidifiedNode')
+
+ RigidifiedNode.createObject("MechanicalObject",name="rigidMecha",template="Vec3d", position="@"+boxRigid.getPathName()+".pointsInROI")
+ RigidifiedNode.createObject("RigidMapping",globalToLocalCoords="true")
+
+##### COMBINED BEAM
+ FEMNode= deformablePartNode.createChild('FEMNode')
+ RigidifiedNode.addChild(FEMNode)
+
+ FEMNode.createObject('Mesh',name='meshInput',src="@"+meshOfStructure.getPathName())
+ FEMNode.createObject('MechanicalObject', template='Vec3d',name='beamMecha')
+ FEMNode.createObject('HexahedronFEMForceField', name='HexaFF', src="@meshInput", poissonRatio=0.49, youngModulus=2000)
+ FEMNode.createObject('RestShapeSpringsForceField', name='restShapeFF', points="@"+boxFixed.getPathName()+'.indices', stiffness=10000, angularStiffness=10000)
+ FEMNode.createObject('UniformMass', totalmass=0.1)
+ FEMNode.createObject('ConstantForceField', name='xMoins', indices=15, forces=[1000, 0, 0])
+ FEMNode.createObject("SubsetMultiMapping",name="subsetMapping",template="Vec3d,Vec3d", input="@../beamPart1Mech @../../RigidNode/RigidifiedNode/rigidMecha",output="@./beamMecha", indexPairs="0 0 0 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9 0 10 0 11 1 0 1 1 1 2 1 3")
+
+ return rootNode
+
+
diff --git a/modules/SofaGeneralAnimationLoop/CMakeLists.txt b/modules/SofaGeneralAnimationLoop/CMakeLists.txt
index 8b886f08729..403c5fb7da5 100644
--- a/modules/SofaGeneralAnimationLoop/CMakeLists.txt
+++ b/modules/SofaGeneralAnimationLoop/CMakeLists.txt
@@ -12,14 +12,17 @@ set(SOURCE_FILES
list(APPEND HEADER_FILES
MultiStepAnimationLoop.h
- MultiTagAnimationLoop.h )
+ MultiTagAnimationLoop.h
+ MechanicalMatrixMapper.h
+ MechanicalMatrixMapper.inl)
list(APPEND SOURCE_FILES
MultiStepAnimationLoop.cpp
- MultiTagAnimationLoop.cpp )
+ MultiTagAnimationLoop.cpp
+ MechanicalMatrixMapper.cpp)
add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES})
-target_link_libraries(${PROJECT_NAME} PUBLIC SofaSimulationCommon)
+target_link_libraries(${PROJECT_NAME} PUBLIC SofaSimulationCommon SofaBaseLinearSolver)
set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "-DSOFA_BUILD_GENERAL_ANIMATION_LOOP")
set_target_properties(${PROJECT_NAME} PROPERTIES PUBLIC_HEADER "${HEADER_FILES}")
diff --git a/modules/SofaGeneralAnimationLoop/MechanicalMatrixMapper.cpp b/modules/SofaGeneralAnimationLoop/MechanicalMatrixMapper.cpp
new file mode 100644
index 00000000000..7b88e7b4b15
--- /dev/null
+++ b/modules/SofaGeneralAnimationLoop/MechanicalMatrixMapper.cpp
@@ -0,0 +1,77 @@
+/******************************************************************************
+* SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1 *
+* (c) 2006-2018 MGH, INRIA, USTL, UJF, CNRS *
+* *
+* This library is free software; you can redistribute it and/or modify it *
+* under the terms of the GNU Lesser General Public License as published by *
+* the Free Software Foundation; either version 2.1 of the License, or (at *
+* your option) any later version. *
+* *
+* This library is distributed in the hope that it will be useful, but WITHOUT *
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
+* for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with this library; if not, write to the Free Software Foundation, *
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+*******************************************************************************
+* SOFA :: Modules *
+* *
+* Authors: The SOFA Team and external contributors (see Authors.txt) *
+* *
+* Contact information: contact@sofa-framework.org *
+******************************************************************************/
+#include "MechanicalMatrixMapper.inl"
+#include