Skip to content

Commit

Permalink
[SofaBaseMechanics] Remove TopologyHandler in masses to use TopologyD…
Browse files Browse the repository at this point in the history
…ata callbacks (part 5) (#2391)

* [SofaGeneralSimpleFem] Remove TopologyHandler in DiagonalMass. Set callbacks directly in the TopologyData.

* [SofaBaseMechanics] Fix point destruction in DiagonalMass

* [SofaMiscForceField] Remove TopologyHandler in MeshMatrixMass. Set callbacks directly in the TopologyData.

* Fix gcc compilation

* [SofaBaseMechanics] Update DiagonalMass and MeshMatrixMass checks on totalMass, massDensity and vertexMass to send warnings only if values are strictly negatives

* Update DiagonalMass_test, quad removal was not correct

* Fix MeshMatrixMass, topological callback should not by applyed on edge if mass is lumped
  • Loading branch information
epernod authored Oct 22, 2021
1 parent 1077d28 commit e453628
Show file tree
Hide file tree
Showing 5 changed files with 807 additions and 953 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -830,30 +830,57 @@ class DiagonalMass_test : public BaseTest
ASSERT_NE(modifier, nullptr);

const VecMass& vMasses = mass->d_vertexMass.getValue();
static const Real refValue = Real(1.0 / 4.0); // 0.125
static const Real refValue = Real(1.0 / 4.0); // 0.25
static const Real initMass = mass->getTotalMass();

// check value at init
EXPECT_EQ(vMasses.size(), 9);
// check value at init. Grid of 4 quads, should be first and third line: 0.25, 0.5, 0.25, second line: 0.5, 1.0, 0.5
// 1/4 ---- 1/2 ---- 1/4
// | m:1 | m:1 |
// | id:2 | id:3 |
// 1/2 ---- 1 ---- 1/2
// | m:1 | m:1 |
// | id:0 | id:1 |
// 1/4 ---- 1/2 ---- 1/4
EXPECT_EQ(vMasses.size(), 9);
EXPECT_NEAR(vMasses[0], refValue, 1e-4);
EXPECT_NEAR(vMasses[1], refValue * 2, 1e-4);
EXPECT_NEAR(vMasses[4], refValue * 4, 1e-4);
EXPECT_NEAR(initMass, 4, 1e-4);

sofa::type::vector<sofa::Index> ids = { 0 };
Real lastV = vMasses[8];


// remove quad id: 0
// 1/4 ---- 1/2 ---- 1/4
// | m:1 | m:1 |
// | id:2 | id:0 |
// 1/4 ---- 3/4 ---- 1/2
// | m:1 |
// | id:1 |
// 1/4 ---- 1/4
sofa::type::vector<sofa::Index> ids = { 0 };
modifier->removeQuads(ids, true, true);
EXPECT_EQ(vMasses.size(), 8);
EXPECT_NEAR(vMasses[0], refValue, 1e-4); // check update of Mass when removing tetra
EXPECT_NEAR(vMasses[1], refValue * 2, 1e-4);
EXPECT_NEAR(mass->getTotalMass(), initMass - refValue, 1e-4);
const Real lastV = vMasses[7];
EXPECT_NEAR(vMasses[0], lastV, 1e-4); // check update of Mass when removing quad, vMasses[0] is now mapped to point position 8.
EXPECT_NEAR(vMasses[1], refValue, 1e-4); // one neighboord quad removed.
EXPECT_NEAR(vMasses[4], refValue * 3, 1e-4); // one neighboord quad removed.

EXPECT_NEAR(mass->getTotalMass(), initMass - 1, 1e-4);
lastV = vMasses[7];

// remove quad id: 0
// 1/4 ---- 1/4
// | m:1 |
// | id:0 |
// 1/4 ---- 2/4 ---- 1/4
// | m:1 |
// | id:1 |
// 1/4 ---- 1/4
modifier->removeQuads(ids, true, true);
EXPECT_EQ(vMasses.size(), 7);
EXPECT_NEAR(vMasses[0], lastV, 1e-4); // check swap value
EXPECT_NEAR(vMasses[1], refValue * 2, 1e-4);
EXPECT_NEAR(mass->getTotalMass(), initMass - 2*refValue, 1e-4);
EXPECT_NEAR(vMasses[0], lastV - refValue, 1e-4); // check swap value
EXPECT_NEAR(vMasses[1], refValue, 1e-4);
EXPECT_NEAR(vMasses[4], refValue * 2, 1e-4); // one neighboord quad removed.
EXPECT_NEAR(mass->getTotalMass(), initMass - 2, 1e-4);

ids.push_back(1);
// remove quad id: 0, 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,90 +82,14 @@ class DiagonalMass : public core::behavior::Mass<DataTypes>
typedef core::topology::BaseMeshTopology::Edge Edge;
typedef core::topology::BaseMeshTopology::EdgeID EdgeID;
typedef core::topology::BaseMeshTopology::Quad Quad;
typedef core::topology::BaseMeshTopology::QuadID QuadID;
typedef core::topology::BaseMeshTopology::Triangle Triangle;
typedef core::topology::BaseMeshTopology::TriangleID TriangleID;
typedef core::topology::BaseMeshTopology::Tetrahedron Tetrahedron;
typedef core::topology::BaseMeshTopology::TetrahedronID TetrahedronID;
typedef core::topology::BaseMeshTopology::Hexahedron Hexahedron;
typedef core::topology::BaseMeshTopology::HexahedronID HexahedronID;

class DMassPointEngine : public topology::TopologyDataHandler<Point,MassVector>
{
public:
typedef typename DiagonalMass<DataTypes,TMassType>::MassVector MassVector;
DMassPointEngine(DiagonalMass<DataTypes,TMassType>* _dm, sofa::component::topology::PointData<MassVector>* _data)
: topology::TopologyDataHandler<Point,MassVector>(_data), dm(_dm)
{}

void applyCreateFunction(PointID pointIndex, TMassType& m, const Point&, const sofa::type::vector< PointID > &,
const sofa::type::vector< double > &);

using topology::TopologyDataHandler<Point,MassVector>::ApplyTopologyChange;

///////////////////////// Functions on Points //////////////////////////////////////
/// Apply removing points.
void applyPointDestruction(const sofa::type::vector<PointID> & /*indices*/);
/// Callback to remove points.
virtual void ApplyTopologyChange(const core::topology::PointsRemoved* /*event*/);

///////////////////////// Functions on Edges //////////////////////////////////////
/// Apply adding edges elements.
void applyEdgeCreation(const sofa::type::vector< EdgeID >& /*indices*/,
const sofa::type::vector< Edge >& /*elems*/,
const sofa::type::vector< sofa::type::vector< EdgeID > >& /*ancestors*/,
const sofa::type::vector< sofa::type::vector< double > >& /*coefs*/);
/// Apply removing edges elements.
void applyEdgeDestruction(const sofa::type::vector<EdgeID> & /*indices*/);

/// Callback to add edges elements.
virtual void ApplyTopologyChange(const core::topology::EdgesAdded* /*event*/);
/// Callback to remove edges elements.
virtual void ApplyTopologyChange(const core::topology::EdgesRemoved* /*event*/);

///////////////////////// Functions on Triangles //////////////////////////////////////
/// Apply adding triangles elements.
void applyTriangleCreation(const sofa::type::vector< TriangleID >& /*indices*/,
const sofa::type::vector< Triangle >& /*elems*/,
const sofa::type::vector< sofa::type::vector< TriangleID > >& /*ancestors*/,
const sofa::type::vector< sofa::type::vector< double > >& /*coefs*/);
/// Apply removing triangles elements.
void applyTriangleDestruction(const sofa::type::vector<TriangleID> & /*indices*/);

/// Callback to add triangles elements.
virtual void ApplyTopologyChange(const core::topology::TrianglesAdded* /*event*/);
/// Callback to remove triangles elements.
virtual void ApplyTopologyChange(const core::topology::TrianglesRemoved* /*event*/);

///////////////////////// Functions on Tetrahedron //////////////////////////////////////
/// Apply adding tetrahedron elements.
void applyTetrahedronCreation(const sofa::type::vector< TetrahedronID >& /*indices*/,
const sofa::type::vector< Tetrahedron >& /*elems*/,
const sofa::type::vector< sofa::type::vector< TetrahedronID > >& /*ancestors*/,
const sofa::type::vector< sofa::type::vector< double > >& /*coefs*/);
/// Apply removing tetrahedron elements.
void applyTetrahedronDestruction(const sofa::type::vector<TetrahedronID> & /*indices*/);

/// Callback to add tetrahedron elements.
virtual void ApplyTopologyChange(const core::topology::TetrahedraAdded* /*event*/);
/// Callback to remove tetrahedron elements.
virtual void ApplyTopologyChange(const core::topology::TetrahedraRemoved* /*event*/);

///////////////////////// Functions on Hexahedron //////////////////////////////////////
/// Apply adding hexahedron elements.
void applyHexahedronCreation(const sofa::type::vector< HexahedronID >& /*indices*/,
const sofa::type::vector< Hexahedron >& /*elems*/,
const sofa::type::vector< sofa::type::vector< HexahedronID > >& /*ancestors*/,
const sofa::type::vector< sofa::type::vector< double > >& /*coefs*/);
/// Apply removing hexahedron elements.
void applyHexahedronDestruction(const sofa::type::vector<HexahedronID> & /*indices*/);
/// Callback to add hexahedron elements.
virtual void ApplyTopologyChange(const core::topology::HexahedraAdded* /*event*/);
/// Callback to remove hexahedron elements.
virtual void ApplyTopologyChange(const core::topology::HexahedraRemoved* /*event*/);

protected:
DiagonalMass<DataTypes,TMassType>* dm;
};
/// the mass density used to compute the mass from a mesh topology and geometry
Data< Real > d_massDensity;

Expand All @@ -181,8 +105,6 @@ class DiagonalMass : public core::behavior::Mass<DataTypes>
Data< float > d_showAxisSize; ///< factor length of the axis displayed (only used for rigids)
core::objectmodel::DataFileName d_fileMass; ///< an Xsp3.0 file to specify the mass parameters

DMassPointEngine* m_pointEngine;

/// value defining the initialization process of the mass (0 : totalMass, 1 : massDensity, 2 : vertexMass)
int m_initializationProcess;

Expand Down Expand Up @@ -247,6 +169,88 @@ class DiagonalMass : public core::behavior::Mass<DataTypes>
/// Compute the vertexMass using input density and return the corresponding full mass.
Real computeVertexMass(Real density);

/** Method to initialize @sa MassVector when a new Point is created.
* Will be set as creation callback in the PointData @sa d_vertexMass
*/
void applyPointCreation(PointID pointIndex, MassType& m, const Point&,
const sofa::type::vector< PointID >&,
const sofa::type::vector< double >&);

/** Method to update @sa d_vertexMass when a Point is removed.
* Will be set as destruction callback in the PointData @sa d_vertexMass
*/
void applyPointDestruction(Index id, MassType& VertexMass);


/** Method to update @sa d_vertexMass when a new Edge is created.
* Will be set as callback in the PointData @sa d_vertexMass to update the mass vector when EDGESADDED event is fired.
*/
void applyEdgeCreation(const sofa::type::vector< EdgeID >& /*indices*/,
const sofa::type::vector< Edge >& /*elems*/,
const sofa::type::vector< sofa::type::vector< EdgeID > >& /*ancestors*/,
const sofa::type::vector< sofa::type::vector< double > >& /*coefs*/);

/** Method to update @sa d_vertexMass when a Edge is removed.
* Will be set as callback in the PointData @sa d_vertexMass to update the mass vector when EDGESREMOVED event is fired.
*/
void applyEdgeDestruction(const sofa::type::vector<EdgeID>& /*indices*/);


/** Method to update @sa d_vertexMass when a new Triangle is created.
* Will be set as callback in the PointData @sa d_vertexMass to update the mass vector when TRIANGLESADDED event is fired.
*/
void applyTriangleCreation(const sofa::type::vector< TriangleID >& /*indices*/,
const sofa::type::vector< Triangle >& /*elems*/,
const sofa::type::vector< sofa::type::vector< TriangleID > >& /*ancestors*/,
const sofa::type::vector< sofa::type::vector< double > >& /*coefs*/);

/** Method to update @sa d_vertexMass when a Triangle is removed.
* Will be set as callback in the PointData @sa d_vertexMass to update the mass vector when TRIANGLESREMOVED event is fired.
*/
void applyTriangleDestruction(const sofa::type::vector<TriangleID>& /*indices*/);


/** Method to update @sa d_vertexMass when a new Quad is created.
* Will be set as callback in the PointData @sa d_vertexMass to update the mass vector when QUADSADDED event is fired.
*/
void applyQuadCreation(const sofa::type::vector< QuadID >& /*indices*/,
const sofa::type::vector< Quad >& /*elems*/,
const sofa::type::vector< sofa::type::vector< QuadID > >& /*ancestors*/,
const sofa::type::vector< sofa::type::vector< double > >& /*coefs*/);

/** Method to update @sa d_vertexMass when a Quad is removed.
* Will be set as callback in the PointData @sa d_vertexMass to update the mass vector when QUADSREMOVED event is fired.
*/
void applyQuadDestruction(const sofa::type::vector<QuadID>& /*indices*/);


/** Method to update @sa d_vertexMass when a new Tetrahedron is created.
* Will be set as callback in the PointData @sa d_vertexMass to update the mass vector when TETRAHEDRAADDED event is fired.
*/
void applyTetrahedronCreation(const sofa::type::vector< TetrahedronID >& /*indices*/,
const sofa::type::vector< Tetrahedron >& /*elems*/,
const sofa::type::vector< sofa::type::vector< TetrahedronID > >& /*ancestors*/,
const sofa::type::vector< sofa::type::vector< double > >& /*coefs*/);

/** Method to update @sa d_vertexMass when a Tetrahedron is removed.
* Will be set as callback in the PointData @sa d_vertexMass to update the mass vector when TETRAHEDRAREMOVED event is fired.
*/
void applyTetrahedronDestruction(const sofa::type::vector<TetrahedronID>& /*indices*/);


/** Method to update @sa d_vertexMass when a new Hexahedron is created.
* Will be set as callback in the PointData @sa d_vertexMass to update the mass vector when HEXAHEDRAADDED event is fired.
*/
void applyHexahedronCreation(const sofa::type::vector< HexahedronID >& /*indices*/,
const sofa::type::vector< Hexahedron >& /*elems*/,
const sofa::type::vector< sofa::type::vector< HexahedronID > >& /*ancestors*/,
const sofa::type::vector< sofa::type::vector< double > >& /*coefs*/);

/** Method to update @sa d_vertexMass when a Hexahedron is removed.
* Will be set as callback in the PointData @sa d_vertexMass to update the mass vector when HEXAHEDRAREMOVED event is fired.
*/
void applyHexahedronDestruction(const sofa::type::vector<HexahedronID>& /*indices*/);

public:

SReal getTotalMass() const { return d_totalMass.getValue(); }
Expand Down
Loading

0 comments on commit e453628

Please sign in to comment.