Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class BaseElementLinearFEMForceField : public sofa::component::solidmechanics::f

private:
using trait = sofa::component::solidmechanics::fem::elastic::trait<DataTypes, ElementType>;
using ElementStiffness = typename trait::ElementStiffness;
using ElementHessian = typename trait::ElementHessian;
using StrainDisplacement = typename trait::StrainDisplacement;
using Real = typename trait::Real;

Expand All @@ -69,7 +69,14 @@ class BaseElementLinearFEMForceField : public sofa::component::solidmechanics::f
/**
* List of precomputed element stiffness matrices
*/
sofa::Data<sofa::type::vector<ElementStiffness> > d_elementStiffness;
sofa::Data<sofa::type::vector<ElementHessian> > d_elementStiffness;

/**
* Contiguous buffer of element stiffness matrices, mirroring d_elementStiffness.
* Used in the hot path to avoid the shared-lock acquired by getReadAccessor on
* the Data, which serializes parallel forEachRange workers.
*/
sofa::type::vector<ElementHessian> m_assembledStiffnessMatrices;
};

#if !defined(ELASTICITY_COMPONENT_BASE_ELEMENT_LINEAR_FEM_FORCEFIELD_CPP)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include <sofa/component/solidmechanics/fem/elastic/BaseElementLinearFEMForceField.h>
#include <sofa/component/solidmechanics/fem/elastic/BaseLinearElasticityFEMForceField.inl>
#include <sofa/component/solidmechanics/fem/elastic/impl/ElementStiffnessMatrix.h>
#include <sofa/component/solidmechanics/fem/elastic/impl/LameParameters.h>
#include <sofa/component/solidmechanics/fem/elastic/impl/VectorTools.h>

Expand Down Expand Up @@ -98,8 +99,12 @@ void BaseElementLinearFEMForceField<DataTypes, ElementType>::precomputeElementSt
const auto elasticityTensor = makeIsotropicElasticityTensor<DataTypes::spatial_dimensions, Real>(mu, lambda);

const std::array<sofa::Coord_t<DataTypes>, trait::NumberOfNodesInElement> nodesCoordinates = extractNodesVectorFromGlobalVector(element, restPositionAccessor.ref());
elementStiffness[elementId] = integrate<DataTypes, ElementType, trait::matrixVectorProductType>(nodesCoordinates, elasticityTensor);
elementStiffness[elementId] = integrate<DataTypes, ElementType>(nodesCoordinates, elasticityTensor);
});

// Mirror into a plain vector so the hot path can read without acquiring
// the Data shared lock, which serializes parallel forEachRange workers.
m_assembledStiffnessMatrices.assign(elementStiffness.begin(), elementStiffness.end());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ class ElementCorotationalFEMForceField :

private:
using trait = sofa::component::solidmechanics::fem::elastic::trait<DataTypes, ElementType>;
using ElementForce = typename trait::ElementForce;
using ElementGradient = typename trait::ElementGradient;
using RotationMatrix = sofa::type::Mat<trait::spatial_dimensions, trait::spatial_dimensions, sofa::Real_t<DataTypes>>;


Expand All @@ -158,19 +158,19 @@ class ElementCorotationalFEMForceField :
protected:

void beforeElementForce(const sofa::core::MechanicalParams* mparams,
sofa::type::vector<ElementForce>& f,
sofa::type::vector<ElementGradient>& f,
const sofa::VecCoord_t<DataTypes>& x) override;

void computeElementsForces(
const sofa::simulation::Range<std::size_t>& range,
const sofa::core::MechanicalParams* mparams,
sofa::type::vector<ElementForce>& f,
sofa::type::vector<ElementGradient>& f,
const sofa::VecCoord_t<DataTypes>& x) override;

void computeElementsForcesDeriv(
const sofa::simulation::Range<std::size_t>& range,
const sofa::core::MechanicalParams* mparams,
sofa::type::vector<ElementForce>& elementForcesDeriv,
sofa::type::vector<ElementGradient>& elementForcesDeriv,
const sofa::VecDeriv_t<DataTypes>& nodeDx) override;

sofa::type::vector<RotationMatrix> m_rotations;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ void ElementCorotationalFEMForceField<DataTypes, ElementType>::init()

template <class DataTypes, class ElementType>
void ElementCorotationalFEMForceField<DataTypes, ElementType>::beforeElementForce(
const sofa::core::MechanicalParams* mparams, sofa::type::vector<ElementForce>& f,
const sofa::core::MechanicalParams* mparams, sofa::type::vector<ElementGradient>& f,
const sofa::VecCoord_t<DataTypes>& x)
{
const auto& elements = trait::FiniteElement::getElementSequence(*this->l_topology);
Expand All @@ -82,11 +82,11 @@ void ElementCorotationalFEMForceField<DataTypes, ElementType>::beforeElementForc
template <class DataTypes, class ElementType>
void ElementCorotationalFEMForceField<DataTypes, ElementType>::computeElementsForces(
const sofa::simulation::Range<std::size_t>& range, const sofa::core::MechanicalParams* mparams,
sofa::type::vector<ElementForce>& elementForces, const sofa::VecCoord_t<DataTypes>& nodePositions)
sofa::type::vector<ElementGradient>& elementForces, const sofa::VecCoord_t<DataTypes>& nodePositions)
{
const auto& elements = trait::FiniteElement::getElementSequence(*this->l_topology);
auto restPositionAccessor = this->mstate->readRestPositions();
auto elementStiffness = sofa::helper::getReadAccessor(this->d_elementStiffness);
const auto& assembledMatrices = this->m_assembledStiffnessMatrices;

for (std::size_t elementId = range.start; elementId < range.end; ++elementId)
{
Expand All @@ -112,7 +112,7 @@ void ElementCorotationalFEMForceField<DataTypes, ElementType>::computeElementsFo
transformedDisplacement = elementRotation.multTranspose(elementNodesCoordinates[j] - t) - (restElementNodesCoordinates[j] - t0);
}

const auto& stiffnessMatrix = elementStiffness[elementId];
const auto& stiffnessMatrix = assembledMatrices[elementId];

auto& elementForce = elementForces[elementId];
elementForce = stiffnessMatrix * displacement;
Expand All @@ -130,11 +130,11 @@ template <class DataTypes, class ElementType>
void ElementCorotationalFEMForceField<DataTypes, ElementType>::computeElementsForcesDeriv(
const sofa::simulation::Range<std::size_t>& range,
const sofa::core::MechanicalParams* mparams,
sofa::type::vector<ElementForce>& elementForcesDeriv,
sofa::type::vector<ElementGradient>& elementForcesDeriv,
const sofa::VecDeriv_t<DataTypes>& nodeDx)
{
const auto& elements = trait::FiniteElement::getElementSequence(*this->l_topology);
auto elementStiffness = sofa::helper::getReadAccessor(this->d_elementStiffness);
const auto& assembledMatrices = this->m_assembledStiffnessMatrices;

for (std::size_t elementId = range.start; elementId < range.end; ++elementId)
{
Expand All @@ -150,7 +150,7 @@ void ElementCorotationalFEMForceField<DataTypes, ElementType>::computeElementsFo
rotated_dx = elementRotation.multTranspose(nodeDx[element[n]]);
}

const auto& stiffnessMatrix = elementStiffness[elementId];
const auto& stiffnessMatrix = assembledMatrices[elementId];

auto& df = elementForcesDeriv[elementId];
df = stiffnessMatrix * element_dx;
Expand Down Expand Up @@ -193,7 +193,7 @@ void ElementCorotationalFEMForceField<DataTypes, ElementType>::buildStiffnessMat
{
for (sofa::Index n2 = 0; n2 < trait::NumberOfNodesInElement; ++n2)
{
stiffnessMatrix.getAssembledMatrix().getsub(trait::spatial_dimensions * n1, trait::spatial_dimensions * n2, localMatrix); // extract the submatrix corresponding to the coupling of nodes n1 and n2
stiffnessMatrix.getsub(trait::spatial_dimensions * n1, trait::spatial_dimensions * n2, localMatrix); // extract the submatrix corresponding to the coupling of nodes n1 and n2
dfdx(element[n1] * trait::spatial_dimensions, element[n2] * trait::spatial_dimensions) += -elementRotation * localMatrix * elementRotation_T;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ class ElementLinearSmallStrainFEMForceField :

private:
using trait = sofa::component::solidmechanics::fem::elastic::trait<DataTypes, ElementType>;
using ElementStiffness = typename trait::ElementStiffness;
using ElementHessian = typename trait::ElementHessian;
using ElementDisplacement = typename trait::ElementDisplacement;
using StrainDisplacement = typename trait::StrainDisplacement;
using ElementForce = typename trait::ElementForce;
using ElementGradient = typename trait::ElementGradient;

public:
void init() override;
Expand All @@ -84,13 +84,13 @@ class ElementLinearSmallStrainFEMForceField :
void computeElementsForces(
const sofa::simulation::Range<std::size_t>& range,
const sofa::core::MechanicalParams* mparams,
sofa::type::vector<ElementForce>& elementForces,
sofa::type::vector<ElementGradient>& elementForces,
const sofa::VecCoord_t<DataTypes>& nodePositions) override;

void computeElementsForcesDeriv(
const sofa::simulation::Range<std::size_t>& range,
const sofa::core::MechanicalParams* mparams,
sofa::type::vector<ElementForce>& elementForcesDeriv,
sofa::type::vector<ElementGradient>& elementForcesDeriv,
const sofa::VecDeriv_t<DataTypes>& nodeDx) override;

};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,17 @@ template <class DataTypes, class ElementType>
void ElementLinearSmallStrainFEMForceField<DataTypes, ElementType>::computeElementsForces(
const sofa::simulation::Range<std::size_t>& range,
const sofa::core::MechanicalParams* mparams,
sofa::type::vector<ElementForce>& elementForces,
sofa::type::vector<ElementGradient>& elementForces,
const sofa::VecCoord_t<DataTypes>& nodePositions)
{
const auto& elements = trait::FiniteElement::getElementSequence(*this->l_topology);
auto restPositionAccessor = this->mstate->readRestPositions();
auto elementStiffness = sofa::helper::getReadAccessor(this->d_elementStiffness);
const auto& assembledMatrices = this->m_assembledStiffnessMatrices;

for (std::size_t elementId = range.start; elementId < range.end; ++elementId)
{
const auto& element = elements[elementId];
const auto& stiffnessMatrix = elementStiffness[elementId];
const auto& stiffnessMatrix = assembledMatrices[elementId];

typename trait::ElementDisplacement displacement{ sofa::type::NOINIT };

Expand All @@ -75,16 +75,16 @@ template <class DataTypes, class ElementType>
void ElementLinearSmallStrainFEMForceField<DataTypes, ElementType>::computeElementsForcesDeriv(
const sofa::simulation::Range<std::size_t>& range,
const sofa::core::MechanicalParams* mparams,
sofa::type::vector<ElementForce>& elementForcesDeriv,
sofa::type::vector<ElementGradient>& elementForcesDeriv,
const sofa::VecDeriv_t<DataTypes>& nodeDx)
{
const auto& elements = trait::FiniteElement::getElementSequence(*this->l_topology);
auto elementStiffness = sofa::helper::getReadAccessor(this->d_elementStiffness);
const auto& assembledMatrices = this->m_assembledStiffnessMatrices;

for (std::size_t elementId = range.start; elementId < range.end; ++elementId)
{
const auto& element = elements[elementId];
const auto& stiffnessMatrix = elementStiffness[elementId];
const auto& stiffnessMatrix = assembledMatrices[elementId];

const std::array<sofa::Coord_t<DataTypes>, trait::NumberOfNodesInElement> elementNodesDx =
extractNodesVectorFromGlobalVector(element, nodeDx);
Expand Down Expand Up @@ -133,7 +133,7 @@ void ElementLinearSmallStrainFEMForceField<DataTypes, ElementType>::buildStiffne
{
for (sofa::Index n2 = 0; n2 < trait::NumberOfNodesInElement; ++n2)
{
stiffnessMatrix.getAssembledMatrix().getsub(trait::spatial_dimensions * n1, trait::spatial_dimensions * n2, localMatrix); //extract the submatrix corresponding to the coupling of nodes n1 and n2
stiffnessMatrix.getsub(trait::spatial_dimensions * n1, trait::spatial_dimensions * n2, localMatrix); //extract the submatrix corresponding to the coupling of nodes n1 and n2
dfdx(element[n1] * trait::spatial_dimensions, element[n2] * trait::spatial_dimensions) += -localMatrix;
}
}
Expand Down Expand Up @@ -169,7 +169,7 @@ void ElementLinearSmallStrainFEMForceField<DataTypes, ElementType>::addKToMatrix
{
for (sofa::Index n2 = 0; n2 < trait::NumberOfNodesInElement; ++n2)
{
stiffnessMatrix.getAssembledMatrix().getsub(trait::spatial_dimensions * n1, trait::spatial_dimensions * n2, localMatrix); //extract the submatrix corresponding to the coupling of nodes n1 and n2
stiffnessMatrix.getsub(trait::spatial_dimensions * n1, trait::spatial_dimensions * n2, localMatrix); //extract the submatrix corresponding to the coupling of nodes n1 and n2

const auto value = (-static_cast<sofa::Real_t<DataTypes>>(kFact)) * static_cast<sofa::type::ScalarOrMatrix<LocalMatType>>(localMatrix);
matrix->add(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class FEMForceField :

private:
using trait = sofa::component::solidmechanics::fem::elastic::trait<DataTypes, ElementType>;
using ElementForce = typename trait::ElementForce;
using ElementGradient = typename trait::ElementGradient;

public:
void init() override;
Expand Down Expand Up @@ -81,17 +81,17 @@ class FEMForceField :
/// Methods related to addForce
/// @{
void computeElementsForces(const sofa::core::MechanicalParams* mparams,
sofa::type::vector<ElementForce>& f,
sofa::type::vector<ElementGradient>& f,
const sofa::VecCoord_t<DataTypes>& x);

virtual void beforeElementForce(const sofa::core::MechanicalParams* mparams,
sofa::type::vector<ElementForce>& f,
sofa::type::vector<ElementGradient>& f,
const sofa::VecCoord_t<DataTypes>& x) {}

virtual void computeElementsForces(
const sofa::simulation::Range<std::size_t>& range,
const sofa::core::MechanicalParams* mparams,
sofa::type::vector<ElementForce>& f,
sofa::type::vector<ElementGradient>& f,
const sofa::VecCoord_t<DataTypes>& x) = 0;

void dispatchElementForcesToNodes(
Expand All @@ -103,13 +103,13 @@ class FEMForceField :
/// Methods related to addDForce
/// @{
void computeElementsForcesDeriv(const sofa::core::MechanicalParams* mparams,
sofa::type::vector<ElementForce>& df,
sofa::type::vector<ElementGradient>& df,
const sofa::VecDeriv_t<DataTypes>& dx);

virtual void computeElementsForcesDeriv(
const sofa::simulation::Range<std::size_t>& range,
const sofa::core::MechanicalParams* mparams,
sofa::type::vector<ElementForce>& df,
sofa::type::vector<ElementGradient>& df,
const sofa::VecDeriv_t<DataTypes>& dx) = 0;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ void FEMForceField<DataTypes, ElementType>::addForce(
template <class DataTypes, class ElementType>
void FEMForceField<DataTypes, ElementType>::computeElementsForces(
const sofa::core::MechanicalParams* mparams,
sofa::type::vector<ElementForce>& f,
sofa::type::vector<ElementGradient>& f,
const sofa::VecCoord_t<DataTypes>& x)
{
SCOPED_TIMER("ElementForces");
Expand Down Expand Up @@ -159,7 +159,7 @@ void FEMForceField<DataTypes, ElementType>::addDForce(

template <class DataTypes, class ElementType>
void FEMForceField<DataTypes, ElementType>::computeElementsForcesDeriv(
const sofa::core::MechanicalParams* mparams, sofa::type::vector<ElementForce>& df,
const sofa::core::MechanicalParams* mparams, sofa::type::vector<ElementGradient>& df,
const sofa::VecDeriv_t<DataTypes>& dx)
{
SCOPED_TIMER("ElementForcesDeriv");
Expand Down
Loading
Loading