Skip to content
Open
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,7 @@ 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;
};

#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,7 +99,7 @@ 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);
});
}

Expand Down
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,7 +82,7 @@ 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();
Expand Down Expand Up @@ -130,7 +130,7 @@ 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);
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,7 +44,7 @@ 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);
Expand Down Expand Up @@ -75,7 +75,7 @@ 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);
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
Original file line number Diff line number Diff line change
Expand Up @@ -25,125 +25,16 @@
#include <sofa/type/FullySymmetric4Tensor.h>
#include <sofa/component/solidmechanics/fem/elastic/impl/OrthotropicElasticityTensor.h>
#include <sofa/component/solidmechanics/fem/elastic/impl/StrainDisplacement.h>
#include <sofa/component/solidmechanics/fem/elastic/impl/trait.h>
#include <sofa/type/Mat.h>

#include <ostream>

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

/**
* Specifies the type of matrix-vector product to be used with the stiffness matrix.
*/
enum class MatrixVectorProductType
{
/**
* The matrix-vector product is computed using the factorization of the matrix
*/
Factorization,

/**
* The matrix-vector product is computed using the dense matrix representation
*/
Dense
};

/**
* Represents an element stiffness matrix. It contains the dense matrix representation, but also
* its factorization. Both the factorization or the dense matrix can be used for the product of the
* stiffness matrix with a vector. Although it gives the same result, it has an impact on the
* performances.
*/
template <class DataTypes, class ElementType, MatrixVectorProductType matrixVectorProductType>
struct FactorizedElementStiffness
{
private:
using Real = sofa::Real_t<DataTypes>;
using FiniteElement = sofa::fem::FiniteElement<ElementType, DataTypes>;
static constexpr auto NbQuadraturePoints = FiniteElement::quadraturePoints().size();
static constexpr sofa::Size NumberOfIndependentElements = sofa::type::NumberOfIndependentElements<DataTypes::spatial_dimensions>;

/// The factors of the stiffness matrix
/// @{
std::array<StrainDisplacement<DataTypes, ElementType>, NbQuadraturePoints> B;
OrthotropicElasticityTensor<DataTypes::spatial_dimensions, sofa::Real_t<DataTypes>> elasticityTensor;
std::array<Real, NbQuadraturePoints> factors;
/// @}

/**
* The assembled stiffness matrix
*/
sofa::type::Mat<
ElementType::NumberOfNodes * DataTypes::spatial_dimensions,
ElementType::NumberOfNodes * DataTypes::spatial_dimensions,
sofa::Real_t<DataTypes>> stiffnessMatrix;

public:
const StrainDisplacement<DataTypes, ElementType>& getB(std::size_t i) const { return B[i]; }
Real getFactor(std::size_t i) const { return factors[i]; }
const OrthotropicElasticityTensor<DataTypes::spatial_dimensions, sofa::Real_t<DataTypes>>& getElasticityTensor() const { return elasticityTensor; }

void setElasticityTensor(
const sofa::type::FullySymmetric4Tensor<DataTypes::spatial_dimensions, sofa::Real_t<DataTypes>>& elasticityTensor_)
{
this->elasticityTensor.set(elasticityTensor_);
}

void addFactor(std::size_t quadraturePointIndex,
const Real factor,
const StrainDisplacement<DataTypes, ElementType>& B_)
{
this->factors[quadraturePointIndex] = factor;
this->B[quadraturePointIndex] = B_;

const auto K_i = factor * B_.multTranspose(elasticityTensor.toMat() * B_.B);
stiffnessMatrix += K_i;
}

const auto& getAssembledMatrix() const { return stiffnessMatrix; }

using Vec = sofa::type::Vec<
ElementType::NumberOfNodes * DataTypes::spatial_dimensions,
sofa::Real_t<DataTypes>>;

inline Vec operator*(const Vec& v) const
{
if constexpr (matrixVectorProductType == MatrixVectorProductType::Factorization)
{
if constexpr (NbQuadraturePoints > 1)
{
Vec result;
for (std::size_t i = 0; i < NbQuadraturePoints; ++i)
{
const auto& B = this->B[i];
result += B.multTranspose(this->factors[i] * (this->elasticityTensor * (B * v)));
}
return result;
}
else
{
return this->B[0].multTranspose(this->factors[0] * (this->elasticityTensor * (this->B[0] * v)));
}
}
else
{
return this->stiffnessMatrix * v;
}
}

friend std::ostream& operator<<(std::ostream& os, const FactorizedElementStiffness& obj)
{
return os << obj.getAssembledMatrix();
}

friend std::istream& operator>>(std::istream& in, FactorizedElementStiffness& obj)
{
return in;
}
};

template <class DataTypes, class ElementType, MatrixVectorProductType matrixVectorProductType = MatrixVectorProductType::Dense>
FactorizedElementStiffness<DataTypes, ElementType, matrixVectorProductType> integrate(
template <class DataTypes, class ElementType>
auto integrate(
const std::array<sofa::Coord_t<DataTypes>, ElementType::NumberOfNodes>& nodesCoordinates,
const sofa::type::FullySymmetric4Tensor<DataTypes::spatial_dimensions, sofa::Real_t<DataTypes>>& elasticityTensor)
{
Expand All @@ -154,8 +45,9 @@ FactorizedElementStiffness<DataTypes, ElementType, matrixVectorProductType> inte
static constexpr sofa::Size NumberOfNodesInElement = ElementType::NumberOfNodes;
static constexpr sofa::Size TopologicalDimension = FiniteElement::TopologicalDimension;

FactorizedElementStiffness<DataTypes, ElementType, matrixVectorProductType> K;
K.setElasticityTensor(elasticityTensor);
typename trait<DataTypes, ElementType>::ElementHessian K;

auto C = elasticityTensor.toVoigtMatSym().toMat();

std::size_t quadraturePointIndex = 0;
for (const auto& [quadraturePoint, weight] : FiniteElement::quadraturePoints())
Expand All @@ -180,7 +72,7 @@ FactorizedElementStiffness<DataTypes, ElementType, matrixVectorProductType> inte
dN_dq[i] = J_inv.transposed() * dN_dq_ref[i];

const auto B = makeStrainDisplacement<DataTypes, ElementType>(dN_dq);
K.addFactor(quadraturePointIndex, weight * detJ, B);
K += (weight * detJ) * B.multTranspose(C * B);

++quadraturePointIndex;
}
Expand Down
Loading
Loading