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 @@ -38,6 +38,7 @@ template class SOFA_COMPONENT_MASS_API ElementFEMMass<sofa::defaulttype::Vec3Typ
template class SOFA_COMPONENT_MASS_API ElementFEMMass<sofa::defaulttype::Vec3Types, sofa::geometry::Tetrahedron>;
template class SOFA_COMPONENT_MASS_API ElementFEMMass<sofa::defaulttype::Vec3Types, sofa::geometry::Hexahedron>;
template class SOFA_COMPONENT_MASS_API ElementFEMMass<sofa::defaulttype::Vec3Types, sofa::geometry::Prism>;
template class SOFA_COMPONENT_MASS_API ElementFEMMass<sofa::defaulttype::Vec3Types, sofa::geometry::Pyramid>;

void registerFEMMass(sofa::core::ObjectFactory* factory)
{
Expand All @@ -62,6 +63,9 @@ void registerFEMMass(sofa::core::ObjectFactory* factory)

factory->registerObjects(sofa::core::ObjectRegistrationData("Finite-element mass (inertia and body force) defined on prisms")
.add< ElementFEMMass<sofa::defaulttype::Vec3Types, sofa::geometry::Prism> >(true));

factory->registerObjects(sofa::core::ObjectRegistrationData("Finite-element mass (inertia and body force) defined on pyramids")
.add< ElementFEMMass<sofa::defaulttype::Vec3Types, sofa::geometry::Pyramid> >(true));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ template class SOFA_COMPONENT_MASS_API ElementFEMMass<sofa::defaulttype::Vec3Typ
template class SOFA_COMPONENT_MASS_API ElementFEMMass<sofa::defaulttype::Vec3Types, sofa::geometry::Tetrahedron>;
template class SOFA_COMPONENT_MASS_API ElementFEMMass<sofa::defaulttype::Vec3Types, sofa::geometry::Hexahedron>;
template class SOFA_COMPONENT_MASS_API ElementFEMMass<sofa::defaulttype::Vec3Types, sofa::geometry::Prism>;
template class SOFA_COMPONENT_MASS_API ElementFEMMass<sofa::defaulttype::Vec3Types, sofa::geometry::Pyramid>;
#endif

} // namespace sofa::component::mass
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ void registerElementCorotationalFEMForceField(sofa::core::ObjectFactory* factory

factory->registerObjects(sofa::core::ObjectRegistrationData("Hooke's law on linear prisms using the corotational approach")
.add< ElementCorotationalFEMForceField<sofa::defaulttype::Vec3Types, sofa::geometry::Prism> >(true));

factory->registerObjects(sofa::core::ObjectRegistrationData("Hooke's law on linear pyramids using the corotational approach")
.add< ElementCorotationalFEMForceField<sofa::defaulttype::Vec3Types, sofa::geometry::Pyramid> >(true));
}

// template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API ElementCorotationalFEMForceField<sofa::defaulttype::Vec1Types, sofa::geometry::Edge>;
Expand All @@ -64,5 +67,6 @@ template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API ElementCorotational
template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API ElementCorotationalFEMForceField<sofa::defaulttype::Vec3Types, sofa::geometry::Tetrahedron>;
template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API ElementCorotationalFEMForceField<sofa::defaulttype::Vec3Types, sofa::geometry::Hexahedron>;
template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API ElementCorotationalFEMForceField<sofa::defaulttype::Vec3Types, sofa::geometry::Prism>;
template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API ElementCorotationalFEMForceField<sofa::defaulttype::Vec3Types, sofa::geometry::Pyramid>;

}
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API ElementCorot
extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API ElementCorotationalFEMForceField<sofa::defaulttype::Vec3Types, sofa::geometry::Tetrahedron>;
extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API ElementCorotationalFEMForceField<sofa::defaulttype::Vec3Types, sofa::geometry::Hexahedron>;
extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API ElementCorotationalFEMForceField<sofa::defaulttype::Vec3Types, sofa::geometry::Prism>;
extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API ElementCorotationalFEMForceField<sofa::defaulttype::Vec3Types, sofa::geometry::Pyramid>;
#endif

} // namespace sofa::component::solidmechanics::fem::elastic
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ void registerElementLinearSmallStrainFEMForceField(sofa::core::ObjectFactory* fa

factory->registerObjects(sofa::core::ObjectRegistrationData("Hooke's law on linear prisms assuming small strain")
.add< ElementLinearSmallStrainFEMForceField<sofa::defaulttype::Vec3Types, sofa::geometry::Prism> >(true));

factory->registerObjects(sofa::core::ObjectRegistrationData("Hooke's law on linear pyramids assuming small strain")
.add< ElementLinearSmallStrainFEMForceField<sofa::defaulttype::Vec3Types, sofa::geometry::Pyramid> >(true));
}

template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API ElementLinearSmallStrainFEMForceField<sofa::defaulttype::Vec1Types, sofa::geometry::Edge>;
Expand All @@ -64,5 +67,5 @@ template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API ElementLinearSmallS
template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API ElementLinearSmallStrainFEMForceField<sofa::defaulttype::Vec3Types, sofa::geometry::Tetrahedron>;
template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API ElementLinearSmallStrainFEMForceField<sofa::defaulttype::Vec3Types, sofa::geometry::Hexahedron>;
template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API ElementLinearSmallStrainFEMForceField<sofa::defaulttype::Vec3Types, sofa::geometry::Prism>;

template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API ElementLinearSmallStrainFEMForceField<sofa::defaulttype::Vec3Types, sofa::geometry::Pyramid>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API ElementLinea
extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API ElementLinearSmallStrainFEMForceField<sofa::defaulttype::Vec3Types, sofa::geometry::Tetrahedron>;
extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API ElementLinearSmallStrainFEMForceField<sofa::defaulttype::Vec3Types, sofa::geometry::Hexahedron>;
extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API ElementLinearSmallStrainFEMForceField<sofa::defaulttype::Vec3Types, sofa::geometry::Prism>;
extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API ElementLinearSmallStrainFEMForceField<sofa::defaulttype::Vec3Types, sofa::geometry::Pyramid>;
#endif

} // namespace sofa::component::solidmechanics::fem::elastic
86 changes: 84 additions & 2 deletions Sofa/framework/Core/src/sofa/core/visual/DrawMesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,85 @@ struct SOFA_CORE_API DrawElementMesh<sofa::geometry::Prism>
}
};

template<>
struct SOFA_CORE_API DrawElementMesh<sofa::geometry::Pyramid>
: public BaseDrawMesh<DrawElementMesh<sofa::geometry::Pyramid>, 5>
{
using ElementType = sofa::geometry::Pyramid;
friend BaseDrawMesh;

static constexpr ColorContainer defaultColors {
sofa::type::RGBAColor::green(),
sofa::type::RGBAColor::teal(),
sofa::type::RGBAColor::navy(),
sofa::type::RGBAColor::gold(),
sofa::type::RGBAColor::purple()
};

private:
template<class PositionContainer, class IndicesContainer>
void doDraw(
sofa::helper::visual::DrawTool* drawTool,
const PositionContainer& position,
sofa::core::topology::BaseMeshTopology* topology,
const IndicesContainer& elementIndices,
const ColorContainer& colors)
{
if (!topology)
return;

const auto& elements = topology->getPyramids();

// Allocate space for rendering points
// 1 Quad + 4 Triangles
renderedPoints[0].resize(elementIndices.size() * sofa::geometry::Quad::NumberOfNodes);
renderedPoints[1].resize(elementIndices.size() * sofa::geometry::Triangle::NumberOfNodes);
renderedPoints[2].resize(elementIndices.size() * sofa::geometry::Triangle::NumberOfNodes);
renderedPoints[3].resize(elementIndices.size() * sofa::geometry::Triangle::NumberOfNodes);
renderedPoints[4].resize(elementIndices.size() * sofa::geometry::Triangle::NumberOfNodes);

std::array<std::size_t, NumberColors> renderedPointId {};

for (auto i : elementIndices)
{
const auto& pyramid = elements[i];
const auto center = this->elementCenter(position, pyramid);

const auto drawQuad = [&](sofa::Index bufferId, sofa::Index v0, sofa::Index v1, sofa::Index v2, sofa::Index v3)
{
const std::array vertexIndices { pyramid[v0], pyramid[v1], pyramid[v2], pyramid[v3] };
for (std::size_t k = 0; k < sofa::geometry::Quad::NumberOfNodes; ++k)
{
const auto p = this->applyElementSpace(position[vertexIndices[k]], center);
renderedPoints[bufferId][renderedPointId[bufferId]++] = sofa::type::toVec3(p);
}
};

const auto drawTriangle = [&](sofa::Index bufferId, sofa::Index v0, sofa::Index v1, sofa::Index v2)
{
const std::array vertexIndices { pyramid[v0], pyramid[v1], pyramid[v2] };
for (std::size_t k = 0; k < sofa::geometry::Triangle::NumberOfNodes; ++k)
{
const auto p = this->applyElementSpace(position[vertexIndices[k]], center);
renderedPoints[bufferId][renderedPointId[bufferId]++] = sofa::type::toVec3(p);
}
};

drawQuad(0, 0, 3, 2, 1);
drawTriangle(1, 0, 1, 4);
drawTriangle(2, 1, 2, 4);
drawTriangle(3, 3, 4, 2);
drawTriangle(4, 0, 4, 3);
}

drawTool->drawQuads(renderedPoints[0], colors[0]);
drawTool->drawTriangles(renderedPoints[1], colors[1]);
drawTool->drawTriangles(renderedPoints[2], colors[2]);
drawTool->drawTriangles(renderedPoints[3], colors[3]);
drawTool->drawTriangles(renderedPoints[4], colors[4]);
}
};

template<>
struct SOFA_CORE_API DrawElementMesh<sofa::geometry::Hexahedron>
: public BaseDrawMesh<DrawElementMesh<sofa::geometry::Hexahedron>, 6>
Expand Down Expand Up @@ -542,6 +621,7 @@ class SOFA_CORE_API DrawMesh
drawElements<sofa::geometry::Tetrahedron>(drawTool, position, topology);
drawElements<sofa::geometry::Hexahedron>(drawTool, position, topology);
drawElements<sofa::geometry::Prism>(drawTool, position, topology);
drawElements<sofa::geometry::Pyramid>(drawTool, position, topology);
}

template<class PositionContainer>
Expand All @@ -560,8 +640,9 @@ class SOFA_CORE_API DrawMesh
const auto hasTetra = !topology->getTetrahedra().empty();
const auto hasHexa = !topology->getHexahedra().empty();
const auto hasPrism = !topology->getPrisms().empty();
const auto hasPyramid = !topology->getPyramids().empty();

const bool hasVolumeElements = hasTetra || hasHexa || hasPrism;
const bool hasVolumeElements = hasTetra || hasHexa || hasPrism || hasPyramid;

if (!hasSurfaceElements && !hasVolumeElements)
{
Expand All @@ -587,7 +668,8 @@ class SOFA_CORE_API DrawMesh
DrawElementMesh<sofa::geometry::Quad>,
DrawElementMesh<sofa::geometry::Tetrahedron>,
DrawElementMesh<sofa::geometry::Hexahedron>,
DrawElementMesh<sofa::geometry::Prism>
DrawElementMesh<sofa::geometry::Prism>,
DrawElementMesh<sofa::geometry::Pyramid>
> m_meshes;
};

Expand Down
2 changes: 2 additions & 0 deletions Sofa/framework/FEM/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ set(HEADER_FILES
${SOFAFEMSRC_ROOT}/FiniteElement[Edge].h
${SOFAFEMSRC_ROOT}/FiniteElement[Hexahedron].h
${SOFAFEMSRC_ROOT}/FiniteElement[Prism].h
${SOFAFEMSRC_ROOT}/FiniteElement[Pyramid].h
${SOFAFEMSRC_ROOT}/FiniteElement[Quad].h
${SOFAFEMSRC_ROOT}/FiniteElement[Tetrahedron].h
${SOFAFEMSRC_ROOT}/FiniteElement[Triangle].h
Expand All @@ -23,6 +24,7 @@ set(SOURCE_FILES
${SOFAFEMSRC_ROOT}/FiniteElement[Edge].cpp
${SOFAFEMSRC_ROOT}/FiniteElement[Hexahedron].cpp
${SOFAFEMSRC_ROOT}/FiniteElement[Prism].cpp
${SOFAFEMSRC_ROOT}/FiniteElement[Pyramid].cpp
${SOFAFEMSRC_ROOT}/FiniteElement[Quad].cpp
${SOFAFEMSRC_ROOT}/FiniteElement[Tetrahedron].cpp
${SOFAFEMSRC_ROOT}/FiniteElement[Triangle].cpp
Expand Down
31 changes: 31 additions & 0 deletions Sofa/framework/FEM/src/sofa/fem/FiniteElement[Pyramid].cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/******************************************************************************
* 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: contact@sofa-framework.org *
******************************************************************************/
#define SOFA_FEM_FINITE_ELEMENT_PYRAMID_CPP
#include <sofa/fem/FiniteElement[Pyramid].h>
#include <sofa/defaulttype/VecTypes.h>

namespace sofa::fem
{

template struct SOFA_FEM_API FiniteElement<sofa::geometry::Pyramid, sofa::defaulttype::Vec3Types>;

}
97 changes: 97 additions & 0 deletions Sofa/framework/FEM/src/sofa/fem/FiniteElement[Pyramid].h
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/******************************************************************************
* 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: contact@sofa-framework.org *
******************************************************************************/
#pragma once
#include <sofa/fem/FiniteElement.h>
#include <sofa/geometry/Pyramid.h>

#if !defined(SOFA_FEM_FINITE_ELEMENT_PYRAMID_CPP)
#include <sofa/defaulttype/VecTypes.h>
#endif

namespace sofa::fem
{

template <class DataTypes>
struct FiniteElement<sofa::geometry::Pyramid, DataTypes>
{
FINITEELEMENT_HEADER(sofa::geometry::Pyramid, DataTypes, 3);
static_assert(spatial_dimensions == 3, "Pyramids are only defined in 3D");

constexpr static std::array<ReferenceCoord, NumberOfNodesInElement> referenceElementNodes {{
{-1, -1, -1},
{ 1, -1, -1},
{ 1, 1, -1},
{-1, 1, -1},
{ 0, 0, 1},
}};

static const sofa::type::vector<TopologyElement>& getElementSequence(sofa::core::topology::BaseMeshTopology& topology)
{
return topology.getPyramids();
}

static constexpr sofa::type::Vec<NumberOfNodesInElement, Real> shapeFunctions(const sofa::type::Vec<TopologicalDimension, Real>& q)
{
return {
static_cast<Real>(0.125) * (1 - q[0]) * (1 - q[1]) * (1 - q[2]),
static_cast<Real>(0.125) * (1 + q[0]) * (1 - q[1]) * (1 - q[2]),
static_cast<Real>(0.125) * (1 + q[0]) * (1 + q[1]) * (1 - q[2]),
static_cast<Real>(0.125) * (1 - q[0]) * (1 + q[1]) * (1 - q[2]),
static_cast<Real>(0.5) * (1 + q[2])
};
}

static constexpr sofa::type::Mat<NumberOfNodesInElement, TopologicalDimension, Real> gradientShapeFunctions(const sofa::type::Vec<TopologicalDimension, Real>& q)
{
return {
{-static_cast<Real>(0.125) * (1 - q[1]) * (1 - q[2]), -static_cast<Real>(0.125) * (1 - q[0]) * (1 - q[2]), -static_cast<Real>(0.125) * (1 - q[0]) * (1 - q[1])},
{ static_cast<Real>(0.125) * (1 - q[1]) * (1 - q[2]), -static_cast<Real>(0.125) * (1 + q[0]) * (1 - q[2]), -static_cast<Real>(0.125) * (1 + q[0]) * (1 - q[1])},
{ static_cast<Real>(0.125) * (1 + q[1]) * (1 - q[2]), static_cast<Real>(0.125) * (1 + q[0]) * (1 - q[2]), -static_cast<Real>(0.125) * (1 + q[0]) * (1 + q[1])},
{-static_cast<Real>(0.125) * (1 + q[1]) * (1 - q[2]), static_cast<Real>(0.125) * (1 - q[0]) * (1 - q[2]), -static_cast<Real>(0.125) * (1 - q[0]) * (1 + q[1])},
{ 0, 0, static_cast<Real>(0.5)}
};
}

static constexpr auto quadraturePoints()
{
constexpr Real sqrt3_1 = static_cast<Real>(1) / static_cast<Real>(1.73205080757);
constexpr Real one = static_cast<Real>(1);

// We use the 8 Gauss points of the hexahedron, which exactly integrate the (1-z)^2 Jacobian of the pyramid.
return std::array {
std::pair{ReferenceCoord{-sqrt3_1, -sqrt3_1, -sqrt3_1}, one},
std::pair{ReferenceCoord{ sqrt3_1, -sqrt3_1, -sqrt3_1}, one},
std::pair{ReferenceCoord{ sqrt3_1, sqrt3_1, -sqrt3_1}, one},
std::pair{ReferenceCoord{-sqrt3_1, sqrt3_1, -sqrt3_1}, one},
std::pair{ReferenceCoord{-sqrt3_1, -sqrt3_1, sqrt3_1}, one},
std::pair{ReferenceCoord{ sqrt3_1, -sqrt3_1, sqrt3_1}, one},
std::pair{ReferenceCoord{ sqrt3_1, sqrt3_1, sqrt3_1}, one},
std::pair{ReferenceCoord{-sqrt3_1, sqrt3_1, sqrt3_1}, one},
};
}
};

#if !defined(SOFA_FEM_FINITE_ELEMENT_PYRAMID_CPP)
extern template struct SOFA_FEM_API FiniteElement<sofa::geometry::Pyramid, sofa::defaulttype::Vec3Types>;
#endif

}
1 change: 1 addition & 0 deletions Sofa/framework/FEM/src/sofa/fem/FiniteElement[all].h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <sofa/fem/FiniteElement[Edge].h>
#include <sofa/fem/FiniteElement[Hexahedron].h>
#include <sofa/fem/FiniteElement[Prism].h>
#include <sofa/fem/FiniteElement[Pyramid].h>
#include <sofa/fem/FiniteElement[Quad].h>
#include <sofa/fem/FiniteElement[Tetrahedron].h>
#include <sofa/fem/FiniteElement[Triangle].h>
Loading
Loading