Skip to content

Commit

Permalink
[FEM.Elastic] Start unification of tetra FF and division of tests (so…
Browse files Browse the repository at this point in the history
…fa-framework#4778)

* [FEM.Elastic] Start unification of tetra FF and division of tests

* Fix 'd_youngModulus' was not declared in this scope

* share common topology link

* restore warning when topology has no tetras

* Rename because it can also be used for triangle force fields

* remove use of getValue

* fix Data duplicate

* use of empty

* clean Real

* apply renaming of Data

* fix test due to Data renaming
  • Loading branch information
alxbilger authored Jul 12, 2024
1 parent 93933a5 commit 9fda892
Show file tree
Hide file tree
Showing 20 changed files with 1,266 additions and 1,173 deletions.
3 changes: 3 additions & 0 deletions Sofa/Component/SolidMechanics/FEM/Elastic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ set(HEADER_FILES
${SOFACOMPONENTSOLIDMECHANICSFEMELASTIC_SOURCE_DIR}/config.h.in
${SOFACOMPONENTSOLIDMECHANICSFEMELASTIC_SOURCE_DIR}/init.h
${SOFACOMPONENTSOLIDMECHANICSFEMELASTIC_SOURCE_DIR}/fwd.h
${SOFACOMPONENTSOLIDMECHANICSFEMELASTIC_SOURCE_DIR}/BaseLinearElasticityFEMForceField.h
${SOFACOMPONENTSOLIDMECHANICSFEMELASTIC_SOURCE_DIR}/BaseLinearElasticityFEMForceField.inl
${SOFACOMPONENTSOLIDMECHANICSFEMELASTIC_SOURCE_DIR}/BeamFEMForceField.h
${SOFACOMPONENTSOLIDMECHANICSFEMELASTIC_SOURCE_DIR}/BeamFEMForceField.inl
${SOFACOMPONENTSOLIDMECHANICSFEMELASTIC_SOURCE_DIR}/FastTetrahedralCorotationalForceField.h
Expand Down Expand Up @@ -39,6 +41,7 @@ set(HEADER_FILES

set(SOURCE_FILES
${SOFACOMPONENTSOLIDMECHANICSFEMELASTIC_SOURCE_DIR}/init.cpp
${SOFACOMPONENTSOLIDMECHANICSFEMELASTIC_SOURCE_DIR}/BaseLinearElasticityFEMForceField.cpp
${SOFACOMPONENTSOLIDMECHANICSFEMELASTIC_SOURCE_DIR}/BeamFEMForceField.cpp
${SOFACOMPONENTSOLIDMECHANICSFEMELASTIC_SOURCE_DIR}/FastTetrahedralCorotationalForceField.cpp
${SOFACOMPONENTSOLIDMECHANICSFEMELASTIC_SOURCE_DIR}/HexahedralFEMForceField.cpp
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/******************************************************************************
* SOFA, Simulation Open-Framework Architecture *
* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
* *
* This program 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 program 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 program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************
* Authors: The SOFA Team and external contributors (see Authors.txt) *
* *
* Contact information: [email protected] *
******************************************************************************/
#define SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_BASETETRAHEDRONFEMFORCEFIELD_CPP
#include <sofa/component/solidmechanics/fem/elastic/BaseLinearElasticityFEMForceField.inl>

namespace sofa::component::solidmechanics::fem::elastic
{
template class BaseLinearElasticityFEMForceField<defaulttype::Vec3Types>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/******************************************************************************
* SOFA, Simulation Open-Framework Architecture *
* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
* *
* This program 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 program 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 program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************
* Authors: The SOFA Team and external contributors (see Authors.txt) *
* *
* Contact information: [email protected] *
******************************************************************************/
#pragma once
#include <sofa/component/solidmechanics/fem/elastic/config.h>
#include <sofa/core/behavior/ForceField.h>
#include <sofa/core/topology/BaseMeshTopology.h>


namespace sofa::component::solidmechanics::fem::elastic
{

template<class DataTypes>
class BaseLinearElasticityFEMForceField : public core::behavior::ForceField<DataTypes>
{
public:
using Coord = typename DataTypes::Coord;
using VecReal = typename DataTypes::VecReal;
using Real = typename DataTypes::Real;

SOFA_CLASS(SOFA_TEMPLATE(BaseLinearElasticityFEMForceField, DataTypes), SOFA_TEMPLATE(core::behavior::ForceField, DataTypes));

Data<Real> d_poissonRatio; ///< FEM Poisson Ratio in Hooke's law [0,0.5[
Data<VecReal > d_youngModulus; ///< FEM Young's Modulus in Hooke's law

/// Link to be set to the topology container in the component graph.
SingleLink<BaseLinearElasticityFEMForceField<DataTypes>, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH|BaseLink::FLAG_STRONGLINK> l_topology;

static inline const VecReal defaultYoungModulusValue = []()
{
VecReal newY;
newY.resize(1);
newY[0] = 5000;
return newY;
}();

BaseLinearElasticityFEMForceField();

void setPoissonRatio(Real val);
void setYoungModulus(Real val);

Real getYoungModulusInElement(sofa::Size elementId);
};

#if !defined(SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_BASELINEARELASTICITYFEMFORCEFIELD_CPP)
extern template class BaseLinearElasticityFEMForceField<defaulttype::Vec3Types>;
#endif

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/******************************************************************************
* SOFA, Simulation Open-Framework Architecture *
* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
* *
* This program 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 program 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 program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************
* Authors: The SOFA Team and external contributors (see Authors.txt) *
* *
* Contact information: [email protected] *
******************************************************************************/
#pragma once
#include <sofa/component/solidmechanics/fem/elastic/BaseLinearElasticityFEMForceField.h>
#include <sofa/core/behavior/ForceField.inl>

namespace sofa::component::solidmechanics::fem::elastic
{

template <class DataTypes>
BaseLinearElasticityFEMForceField<DataTypes>::BaseLinearElasticityFEMForceField()
: d_poissonRatio(initData(&d_poissonRatio,(Real)0.45,"poissonRatio","FEM Poisson Ratio in Hooke's law [0,0.5["))
, d_youngModulus(initData(&d_youngModulus, defaultYoungModulusValue, "youngModulus","FEM Young's Modulus in Hooke's law"))
, l_topology(initLink("topology", "link to the topology container"))
{
d_poissonRatio.setRequired(true);
d_poissonRatio.setWidget("poissonRatio");

d_youngModulus.setRequired(true);
}

template <class DataTypes>
void BaseLinearElasticityFEMForceField<DataTypes>::setPoissonRatio(Real val)
{
this->d_poissonRatio.setValue(val);
}

template <class DataTypes>
void BaseLinearElasticityFEMForceField<DataTypes>::setYoungModulus(Real val)
{
VecReal newY;
newY.resize(1);
newY[0] = val;
d_youngModulus.setValue(newY);
}

template <class DataTypes>
auto BaseLinearElasticityFEMForceField<DataTypes>::getYoungModulusInElement(sofa::Size elementId)
-> Real
{
Real youngModulusElement {};

const auto& youngModulus = d_youngModulus.getValue();
if (youngModulus.size() > elementId)
{
youngModulusElement = youngModulus[elementId];
}
else if (!youngModulus.empty())
{
youngModulusElement = youngModulus[0];
}
else
{
setYoungModulus(5000);
youngModulusElement = youngModulus[0];
}
return youngModulusElement;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
******************************************************************************/
#pragma once

#include <sofa/component/solidmechanics/fem/elastic/BaseLinearElasticityFEMForceField.h>
#include <sofa/component/solidmechanics/fem/elastic/config.h>
#include <sofa/core/behavior/ForceField.h>
#include <sofa/core/topology/TopologyData.h>
Expand Down Expand Up @@ -48,10 +49,10 @@ class FastTetrahedralCorotationalForceFieldData


template<class DataTypes>
class FastTetrahedralCorotationalForceField : public core::behavior::ForceField<DataTypes>
class FastTetrahedralCorotationalForceField : public BaseLinearElasticityFEMForceField<DataTypes>
{
public:
SOFA_CLASS(SOFA_TEMPLATE(FastTetrahedralCorotationalForceField,DataTypes), SOFA_TEMPLATE(core::behavior::ForceField,DataTypes));
SOFA_CLASS(SOFA_TEMPLATE(FastTetrahedralCorotationalForceField,DataTypes), SOFA_TEMPLATE(BaseLinearElasticityFEMForceField,DataTypes));

typedef core::behavior::ForceField<DataTypes> Inherited;
typedef typename DataTypes::Real Real ;
Expand Down Expand Up @@ -130,7 +131,7 @@ class FastTetrahedralCorotationalForceField : public core::behavior::ForceField<
Data<Real> f_poissonRatio;

SOFA_ATTRIBUTE_DEPRECATED__RENAME_DATA_IN_SOLIDMECHANICS_FEM_ELASTIC()
Data<Real> f_youngModulus;
SOFA_ATTRIBUTE_DISABLED("", "v24.12", "Use d_youngModulus instead") DeprecatedAndRemoved f_youngModulus;

SOFA_ATTRIBUTE_DEPRECATED__RENAME_DATA_IN_SOLIDMECHANICS_FEM_ELASTIC()
Data<bool> f_drawing;
Expand All @@ -156,20 +157,13 @@ class FastTetrahedralCorotationalForceField : public core::behavior::ForceField<
Data<std::string> d_method; ///< method for rotation computation :"qr" (by QR) or "polar" or "polar2" or "none" (Linear elastic)
RotationDecompositionMethod m_decompositionMethod;

Data<Real> d_poissonRatio; ///< Poisson ratio in Hooke's law
Data<Real> d_youngModulus; ///< Young modulus in Hooke's law

Real lambda; /// first Lame coefficient
Real mu; /// second Lame coefficient

Data<bool> d_drawing; ///< draw the forcefield if true
Data<sofa::type::RGBAColor> d_drawColor1; ///< draw color for faces 1
Data<sofa::type::RGBAColor> d_drawColor2; ///< draw color for faces 2
Data<sofa::type::RGBAColor> d_drawColor3; ///< draw color for faces 3
Data<sofa::type::RGBAColor> d_drawColor4; ///< draw color for faces 4

/// Link to be set to the topology container in the component graph.
SingleLink<FastTetrahedralCorotationalForceField<DataTypes>, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology;
using Inherit1::l_topology;

FastTetrahedralCorotationalForceField();

Expand All @@ -195,24 +189,14 @@ class FastTetrahedralCorotationalForceField : public core::behavior::ForceField<

void updateTopologyInformation();

virtual Real getLambda() const { return lambda;}
virtual Real getMu() const { return mu;}

void setYoungModulus(const Real modulus)
{
d_youngModulus.setValue(modulus);
}
void setPoissonRatio(const Real ratio)
{
d_poissonRatio.setValue(ratio);
}
void setRotationDecompositionMethod( const RotationDecompositionMethod m)
{
m_decompositionMethod = m;
}
void draw(const core::visual::VisualParams* vparams) override;

/// compute lambda and mu based on the Young modulus and Poisson ratio
void updateLameCoefficients();
static void computeLameCoefficients(Real inYoung, Real inPoisson, Real& outLambda, Real& outMu);



Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#pragma once

#include <sofa/component/solidmechanics/fem/elastic/FastTetrahedralCorotationalForceField.h>
#include <sofa/component/solidmechanics/fem/elastic/BaseLinearElasticityFEMForceField.inl>
#include <sofa/core/behavior/ForceField.inl>
#include <sofa/core/visual/VisualParams.h>
#include <sofa/helper/decompose.h>
Expand All @@ -44,8 +45,11 @@ void FastTetrahedralCorotationalForceField<DataTypes>::createTetrahedronRestInfo
const std::vector< Tetrahedron > &tetrahedronArray=this->m_topology->getTetrahedra() ;

unsigned int j,k,l,m,n;
typename DataTypes::Real lambda=getLambda();
typename DataTypes::Real mu=getMu();
Real lambda, mu;

Real youngModulusElement = this->getYoungModulusInElement(tetrahedronIndex);

computeLameCoefficients(youngModulusElement, this->d_poissonRatio.getValue(), lambda, mu);
typename DataTypes::Real volume,val;
typename DataTypes::Coord point[4]; //shapeVector[4];
const typename DataTypes::VecCoord restPosition=this->mstate->read(core::ConstVecCoordId::restPosition())->getValue();
Expand Down Expand Up @@ -140,28 +144,19 @@ FastTetrahedralCorotationalForceField<DataTypes>::FastTetrahedralCorotationalFor
, d_tetrahedronInfo(initData(&d_tetrahedronInfo, "tetrahedronInfo", "Internal tetrahedron data"))
, _initialPoints(0)
, d_method(initData(&d_method, std::string("qr"), "method", " method for rotation computation :\"qr\" (by QR) or \"polar\" or \"polar2\" or \"none\" (Linear elastic) "))
, d_poissonRatio(initData(&d_poissonRatio, Real(0.45), "poissonRatio", "Poisson ratio in Hooke's law"))
, d_youngModulus(initData(&d_youngModulus, Real(5000.), "youngModulus", "Young modulus in Hooke's law"))
, lambda(0)
, mu(0)
, d_drawing(initData(&d_drawing, true, "drawing", " draw the forcefield if true"))
, d_drawColor1(initData(&d_drawColor1, sofa::type::RGBAColor(0.0f, 0.0f, 1.0f, 1.0f), "drawColor1", " draw color for faces 1"))
, d_drawColor2(initData(&d_drawColor2, sofa::type::RGBAColor(0.0f, 0.5f, 1.0f, 1.0f), "drawColor2", " draw color for faces 2"))
, d_drawColor3(initData(&d_drawColor3, sofa::type::RGBAColor(0.0f, 1.0f, 1.0f, 1.0f), "drawColor3", " draw color for faces 3"))
, d_drawColor4(initData(&d_drawColor4, sofa::type::RGBAColor(0.5f, 1.0f, 1.0f, 1.0f), "drawColor4", " draw color for faces 4"))
, l_topology(initLink("topology", "link to the topology container"))
, m_topology(nullptr)
, updateMatrix(true)
{
d_poissonRatio.setRequired(true);
d_youngModulus.setRequired(true);

pointInfo.setParent(&d_pointInfo);
edgeInfo.setParent(&d_edgeInfo);
tetrahedronInfo.setParent(&d_tetrahedronInfo);
f_method.setParent(&d_method);
f_poissonRatio.setParent(&d_poissonRatio);
f_youngModulus.setParent(&d_youngModulus);
f_poissonRatio.setParent(&this->d_poissonRatio);
f_drawing.setParent(&d_drawing);
drawColor1.setParent(&d_drawColor1);
drawColor2.setParent(&d_drawColor2);
Expand All @@ -181,8 +176,8 @@ void FastTetrahedralCorotationalForceField<DataTypes>::init()
{
this->Inherited::init();

msg_warning_when(!d_poissonRatio.isSet()) << "The default value of the Data " << d_poissonRatio.getName() << " changed in v23.06 from 0.3 to 0.45.";
msg_warning_when(!d_youngModulus.isSet()) << "The default value of the Data " << d_youngModulus.getName() << " changed in v23.06 from 1000 to 5000";
msg_warning_when(!this->d_poissonRatio.isSet()) << "The default value of the Data " << this->d_poissonRatio.getName() << " changed in v23.06 from 0.3 to 0.45.";
msg_warning_when(!this->d_youngModulus.isSet()) << "The default value of the Data " << this->d_youngModulus.getName() << " changed in v23.06 from 1000 to 5000";

if (l_topology.empty())
{
Expand All @@ -202,19 +197,17 @@ void FastTetrahedralCorotationalForceField<DataTypes>::init()

if (m_topology->getNbTetrahedra() == 0)
{
msg_warning() << "No tetrahedra found in linked Topology.";
msg_error() << "No tetrahedra found in linked Topology.";
}

updateLameCoefficients();

const std::string& method = d_method.getValue();
if (method == "polar")
m_decompositionMethod = POLAR_DECOMPOSITION;
else if ((method == "qr") || (method == "large"))
else if ((method == "qr") || (method == "large"))
m_decompositionMethod = QR_DECOMPOSITION;
else if (method == "polar2")
m_decompositionMethod = POLAR_DECOMPOSITION_MODIFIED;
else if ((method == "none") || (method == "linear") || (method == "small"))
else if ((method == "none") || (method == "linear") || (method == "small"))
m_decompositionMethod = LINEAR_ELASTIC;
else
{
Expand Down Expand Up @@ -688,11 +681,10 @@ void FastTetrahedralCorotationalForceField<DataTypes>::addKToMatrix(sofa::linear
}

template<class DataTypes>
void FastTetrahedralCorotationalForceField<DataTypes>::updateLameCoefficients()
void FastTetrahedralCorotationalForceField<DataTypes>::computeLameCoefficients(Real inYoung, Real inPoisson, Real& outLambda, Real& outMu)
{
lambda= d_youngModulus.getValue() * d_poissonRatio.getValue() / ((1 - 2 * d_poissonRatio.getValue()) * (1 + d_poissonRatio.getValue()));
mu = d_youngModulus.getValue() / (2 * (1 + d_poissonRatio.getValue()));

outLambda = inYoung * inPoisson / ((1 - 2 * inPoisson) * (1 + inPoisson));
outMu = inYoung / (2 * (1 + inPoisson));
}


Expand Down
Loading

0 comments on commit 9fda892

Please sign in to comment.