From 03d60b04c8d09d2c45053f5b47fab9b0f6ea755e Mon Sep 17 00:00:00 2001 From: EulalieCoevoet Date: Mon, 17 Feb 2025 17:13:08 +0100 Subject: [PATCH 1/2] [BeamInterpolation] generalizes parameters per egde --- .../AdaptiveBeamForceFieldAndMassTest.cpp | 2 +- src/BeamAdapter/component/BeamInterpolation.h | 37 ++-- .../component/BeamInterpolation.inl | 208 ++++++++++-------- .../AdaptiveBeamForceFieldAndMass.h | 4 +- .../AdaptiveBeamForceFieldAndMass.inl | 38 +++- .../AdaptiveInflatableBeamForceField.inl | 2 +- 6 files changed, 182 insertions(+), 109 deletions(-) diff --git a/BeamAdapter_test/component/forcefield/AdaptiveBeamForceFieldAndMassTest.cpp b/BeamAdapter_test/component/forcefield/AdaptiveBeamForceFieldAndMassTest.cpp index 1c99e90db..521df0c3e 100644 --- a/BeamAdapter_test/component/forcefield/AdaptiveBeamForceFieldAndMassTest.cpp +++ b/BeamAdapter_test/component/forcefield/AdaptiveBeamForceFieldAndMassTest.cpp @@ -126,7 +126,7 @@ struct AdaptiveBeamForceFieldAndMassTest : public sofa::testing::BaseSimulationT // Check component state and Data default values ASSERT_EQ(beamForceFieldMass->d_componentState.getValue(), sofa::core::objectmodel::ComponentState::Valid); ASSERT_EQ(beamForceFieldMass->d_computeMass.getValue(), true); - ASSERT_FLOAT_EQ(beamForceFieldMass->d_massDensity.getValue(), 10.0); + ASSERT_FLOAT_EQ(beamForceFieldMass->d_massDensity.getValue()[0], 10.0); ASSERT_FLOAT_EQ(beamForceFieldMass->rayleighMass.getValue(), 0.0); ASSERT_FLOAT_EQ(beamForceFieldMass->rayleighStiffness.getValue(), 0.0); } diff --git a/src/BeamAdapter/component/BeamInterpolation.h b/src/BeamAdapter/component/BeamInterpolation.h index 728e4ee72..39218eb92 100644 --- a/src/BeamAdapter/component/BeamInterpolation.h +++ b/src/BeamAdapter/component/BeamInterpolation.h @@ -141,7 +141,9 @@ class BeamInterpolation : public BaseBeamInterpolation const BeamSection& getBeamSection(sofa::Index beamId) override { SOFA_UNUSED(beamId); - return this->m_constantSection; + if (m_constantBeam) + return this->m_constantSection; + return this->m_section[beamId]; } void getInterpolationParameters(sofa::Index beamId, Real &_L, Real &_A, Real &_Iy , Real &_Iz, Real &_Asy, Real &_Asz, Real &J) override; @@ -149,21 +151,18 @@ class BeamInterpolation : public BaseBeamInterpolation void getTangentUsingSplinePoints(unsigned int edgeInList, const Real& baryCoord, const sofa::core::ConstVecCoordId &vecXId, Vec3& t ); - /// computeActualLength => given the 4 control points of the spline, it provides an estimate of the length (using gauss points integration) - - - virtual void getCurvAbsAtBeam(const unsigned int& edgeInList_input, const Real& baryCoord_input, Real& x_output) {} virtual void getBeamAtCurvAbs(const Real& x_input, unsigned int& edgeInList_output, Real& baryCoord_output, unsigned int start = 0) {} - Data crossSectionShape; /// Circular Cross Section - Data d_radius; - Data d_innerRadius; + Real m_defaultRadius; + Data> d_radius; + Real m_defaultInnerRadius; + Data> d_innerRadius; /// Square Cross Section Data d_sideLength; @@ -173,14 +172,17 @@ class BeamInterpolation : public BaseBeamInterpolation Data d_largeRadius; /// Rectangular Cross Section - Data d_lengthY; - Data d_lengthZ; + Real m_defaultLengthY; + Data> d_lengthY; + Real m_defaultLengthZ; + Data> d_lengthZ; Data d_dofsAndBeamsAligned; - Real m_defaultYoungModulus; - Real m_defaultPoissonRatio; - Data> d_defaultYoungModulus; - Data> d_poissonRatio; + Real m_defaultYoungModulus; + Data> d_defaultYoungModulus; + + Real m_defaultPoissonRatio; + Data> d_poissonRatio; Data d_straight; @@ -214,7 +216,14 @@ protected : Data< VecDeriv > d_InterpolatedVel; /// GEOMETRICAL COMPUTATION (for now we suppose that the radius of the beam do not vary in space / in time) + bool m_constantBeam{true}; BeamSection m_constantSection; + type::vector m_section; + + void checkDataSize(Real& defaultValue, Data>& dataList, const size_t& nbEdges); + + void computeRectangularCrossSectionInertiaMatrix(const Real &Ly, const Real &Lz, BeamSection §ion); + void computeCircularCrossSectionInertiaMatrix(const Real &r, const Real &rInner, BeamSection §ion); }; #if !defined(SOFA_PLUGIN_BEAMADAPTER_BEAMINTERPOLATION_CPP) diff --git a/src/BeamAdapter/component/BeamInterpolation.inl b/src/BeamAdapter/component/BeamInterpolation.inl index 4a011261d..19e63d522 100644 --- a/src/BeamAdapter/component/BeamInterpolation.inl +++ b/src/BeamAdapter/component/BeamInterpolation.inl @@ -55,17 +55,28 @@ BeamInterpolation::BeamInterpolation() : {"circular","elliptic (not available)","rectangular"}, "crossSectionShape", "shape of the cross-section. Can be: circular, elliptic, square, rectangular. Default is circular" )) - , d_radius(initData(&d_radius, Real(1.0), "radius", "radius of the beam (if circular cross-section is considered)")) - , d_innerRadius(initData(&d_innerRadius, Real(0.0), "innerRadius", "inner radius of the beam if it applies")) + , m_defaultRadius(Real(1.0)) + , d_radius(initData(&d_radius, type::vector(1, m_defaultRadius), "radius", "radius of the beam (if circular cross-section is considered)")) + + , m_defaultInnerRadius(Real(1.0)) + , d_innerRadius(initData(&d_innerRadius, type::vector(1, m_defaultInnerRadius), "innerRadius", "inner radius of the beam if it applies")) + , d_sideLength(initData(&d_sideLength, Real(1.0), "sideLength", "side length of the beam (if square cross-section is considered)")) + , d_smallRadius(initData(&d_smallRadius, Real(1.0), "smallRadius", "small radius of the beam (if elliptic cross-section is considered)")) , d_largeRadius(initData(&d_largeRadius, Real(1.0), "largeRadius", "large radius of the beam (if elliptic cross-section is considered)")) - , d_lengthY(initData(&d_lengthY, Real(1.0), "lengthY", "length of the beam section along Y (if rectangular cross-section is considered)")) - , d_lengthZ(initData(&d_lengthZ, Real(1.0), "lengthZ", "length of the beam section along Z (if rectangular cross-section is considered)")) + + , m_defaultLengthY(Real(1.0)) + , d_lengthY(initData(&d_lengthY, type::vector(1, m_defaultLengthY), "lengthY", "length of the beam section along Y (if rectangular cross-section is considered)")) + + , m_defaultLengthZ(Real(1.0)) + , d_lengthZ(initData(&d_lengthZ, type::vector(1, m_defaultLengthZ), "lengthZ", "length of the beam section along Z (if rectangular cross-section is considered)")) + , m_defaultYoungModulus(Real(1e5)) - , m_defaultPoissonRatio(Real(0.4)) , d_defaultYoungModulus(initData(&d_defaultYoungModulus, type::vector(1, m_defaultYoungModulus), "defaultYoungModulus", "value of the young modulus if not defined in an other component")) + + , m_defaultPoissonRatio(Real(0.4)) , d_poissonRatio(initData(&d_poissonRatio, type::vector(1, m_defaultPoissonRatio), "defaultPoissonRatio", "value of the poisson ratio if not defined in an other component")) , d_straight(initData(&d_straight,true,"straight","If true, will consider straight beams for the rest position")) @@ -78,44 +89,75 @@ BeamInterpolation::BeamInterpolation() : } +template +void BeamInterpolation::computeRectangularCrossSectionInertiaMatrix(const Real& Ly, const Real& Lz, BeamSection& section) +{ + section._Iy=Ly*Lz*Lz*Lz/12.0; + section._Iz=Lz*Ly*Ly*Ly/12.0; + section._J=section._Iy + section._Iz; + section._A = Ly*Lz; + + section._Asy = 0.0; + section._Asz = 0.0; +} template -void BeamInterpolation::computeCrossSectionInertiaMatrix() +void BeamInterpolation::computeCircularCrossSectionInertiaMatrix(const Real &r, const Real &rInner, BeamSection §ion) { - if ( crossSectionShape.getValue().getSelectedItem() == "elliptic") - { - /* code */ - } - else if ( crossSectionShape.getValue().getSelectedItem() == "rectangular" ) - { - Real Ly = d_lengthY.getValue(); - Real Lz = d_lengthZ.getValue(); + section._r = r; + section._rInner = rInner; + + section._Iz = M_PI*(r*r*r*r - rInner*rInner*rInner*rInner)/4.0; - m_constantSection._Iy=Ly*Lz*Lz*Lz/12.0; - m_constantSection._Iz=Lz*Ly*Ly*Ly/12.0; - m_constantSection._J=m_constantSection._Iy + m_constantSection._Iz; - m_constantSection._A = Ly*Lz; + ///_Iz = M_PI*(r*r*r*r)/4.0; + section._Iy = section._Iz ; + section._J = section._Iz + section._Iy; + section._A = M_PI*(r*r - rInner*rInner); - m_constantSection._Asy = 0.0; - m_constantSection._Asz = 0.0; + section._Asy = 0.0; + section._Asz = 0.0; +} + +template +void BeamInterpolation::computeCrossSectionInertiaMatrix() +{ + msg_info() << "Cross section shape:" << crossSectionShape.getValue().getSelectedItem() ; + if (m_constantBeam) + { + if ( crossSectionShape.getValue().getSelectedItem() == "elliptic") + { + /* code */ + } + else if ( crossSectionShape.getValue().getSelectedItem() == "rectangular" ) + { + computeRectangularCrossSectionInertiaMatrix(m_defaultLengthY, m_defaultLengthZ, m_constantSection); + } + else + { + computeCircularCrossSectionInertiaMatrix(m_defaultRadius, m_defaultInnerRadius, m_constantSection); + } } else { - msg_info() << "Cross section shape." << crossSectionShape.getValue().getSelectedItem() ; - m_constantSection._r = d_radius.getValue(); - m_constantSection._rInner = d_innerRadius.getValue(); - - double r = d_radius.getValue(); - double rInner = d_innerRadius.getValue(); - m_constantSection._Iz = M_PI*(r*r*r*r - rInner*rInner*rInner*rInner)/4.0; - - ///_Iz = M_PI*(r*r*r*r)/4.0; - m_constantSection._Iy = m_constantSection._Iz ; - m_constantSection._J = m_constantSection._Iz + m_constantSection._Iy; - m_constantSection._A = M_PI*(r*r - rInner*rInner); - - m_constantSection._Asy = 0.0; - m_constantSection._Asz = 0.0; + Size nbEdges = this->m_topology->getNbEdges(); + m_section.resize(nbEdges); + if ( crossSectionShape.getValue().getSelectedItem() == "elliptic") + { + /* code */ + } + else if ( crossSectionShape.getValue().getSelectedItem() == "rectangular" ) + { + const auto& lengthY = helper::getReadAccessor(d_lengthY); + const auto& lengthZ = helper::getReadAccessor(d_lengthZ); + for (int beamId=0; beamId::computeCrossSectionInertiaMatrix() template void BeamInterpolation::init() { - computeCrossSectionInertiaMatrix(); +} + +template +void BeamInterpolation::checkDataSize(Real& defaultValue, Data>& dataList, const size_t& nbEdges) +{ + auto values = sofa::helper::getWriteOnlyAccessor(dataList); + if (values.size() != nbEdges) + { + Real value = defaultValue; + if (values.size() == 0) + { + msg_warning() << "Empty data field for " << dataList.getName() <<". Set default " << value; + } else + { + value = values[0]; + } + values.resize(nbEdges); + for (auto& _value: values) + _value = value; + } + else + { + m_constantBeam = false; + } + defaultValue = values[0]; // if the sizes mismatch again at runtime, will use this default value } template @@ -137,36 +203,13 @@ void BeamInterpolation::bwdInit() return; Size nbEdges = this->m_topology->getNbEdges(); - auto youngModulus = sofa::helper::getWriteOnlyAccessor(d_defaultYoungModulus); - if (youngModulus.size() != nbEdges) - { - Real value = m_defaultYoungModulus; - if (youngModulus.size() == 0){ - msg_warning() << "Empty data field for " << d_defaultYoungModulus.getName() <<". Set default " << value; - } else { - value = youngModulus[0]; - } - youngModulus.resize(nbEdges); - for (auto& beamYoungModulus: youngModulus) - beamYoungModulus = value; - } - m_defaultYoungModulus = youngModulus[0]; // if the sizes mismatch again at runtime, will use this default value - - auto poissonRatio = sofa::helper::getWriteOnlyAccessor(d_poissonRatio); - if (poissonRatio.size() != nbEdges) - { - Real value = m_defaultPoissonRatio; - if (poissonRatio.size() == 0){ - msg_warning() << "Empty data field for " << d_poissonRatio.getName() << ". Set default " << value; - } else { - value = poissonRatio[0]; - } - poissonRatio.resize(nbEdges); - for (auto& beamPoissonRatio: poissonRatio) - beamPoissonRatio = value; - } - m_defaultPoissonRatio = poissonRatio[0]; // if the sizes mismatch again at runtime, will use this default value - + checkDataSize(m_defaultRadius, d_radius, nbEdges); + checkDataSize(m_defaultInnerRadius, d_innerRadius, nbEdges); + checkDataSize(m_defaultLengthY, d_lengthY, nbEdges); + checkDataSize(m_defaultLengthZ, d_lengthZ, nbEdges); + checkDataSize(m_defaultYoungModulus, d_defaultYoungModulus, nbEdges); + checkDataSize(m_defaultPoissonRatio, d_poissonRatio, nbEdges); + computeCrossSectionInertiaMatrix(); if (!interpolationIsAlreadyInitialized()) { @@ -359,9 +402,6 @@ void BeamInterpolation::addBeam(const BaseMeshTopology::EdgeID &eID } - - - template void BeamInterpolation::getSamplingParameters(type::vector& /*xP_noticeable*/, type::vector< int>& /*nbP_density*/) { @@ -401,12 +441,14 @@ void BeamInterpolation::getInterpolationParameters(sofa::Index beamId { /// get the length of the beam: _L = this->d_lengthList.getValue()[beamId]; - _A = m_constantSection._A; - _Iy = m_constantSection._Iy; - _Iz = m_constantSection._Iz; - _Asy = m_constantSection._Asy; - _Asz = m_constantSection._Asz; - _J = m_constantSection._J; + + const auto& section = getBeamSection(beamId); + _A = section._A; + _Iy = section._Iy; + _Iz = section._Iz; + _Asy = section._Asy; + _Asz = section._Asz; + _J = section._J; } @@ -414,22 +456,10 @@ template void BeamInterpolation::getMechanicalParameters(sofa::Index beamId, Real& youngModulus, Real& cPoisson, Real& massDensity) { const auto& defaultYoungModuli = d_defaultYoungModulus.getValue(); - if (beamId < int(defaultYoungModuli.size())) { - - youngModulus = defaultYoungModuli[beamId]; - } - else { - youngModulus = m_defaultYoungModulus; - } + youngModulus = (beamId < int(defaultYoungModuli.size()))? defaultYoungModuli[beamId]: m_defaultYoungModulus; const auto& poissonRatios = d_poissonRatio.getValue(); - if (beamId < int(poissonRatios.size())) { - - cPoisson = poissonRatios[beamId]; - } - else { - cPoisson = m_defaultPoissonRatio; - } + cPoisson = (beamId < int(defaultYoungModuli.size()))? poissonRatios[beamId]: m_defaultPoissonRatio; //TODO: massDensity?? } diff --git a/src/BeamAdapter/component/forcefield/AdaptiveBeamForceFieldAndMass.h b/src/BeamAdapter/component/forcefield/AdaptiveBeamForceFieldAndMass.h index 786c37fbf..9912ddf95 100644 --- a/src/BeamAdapter/component/forcefield/AdaptiveBeamForceFieldAndMass.h +++ b/src/BeamAdapter/component/forcefield/AdaptiveBeamForceFieldAndMass.h @@ -192,9 +192,9 @@ class AdaptiveBeamForceFieldAndMass : public core::behavior::Mass void computeStiffness(int beam, BeamLocalMatrices& beamLocalMatrices); void computeMass(int beam, BeamLocalMatrices& beamMatrices); - Data d_computeMass; ///< if false, only compute the stiff elastic model - Data d_massDensity; ///< Density of the mass (usually in kg/m^3) + Real m_defaultMassDensity; + Data> d_massDensity; ///< Density of the mass Data d_useShearStressComputation; ///< if false, suppress the shear stress in the computation Data d_reinforceLength; ///< if true, perform a separate computation to evaluate the elongation diff --git a/src/BeamAdapter/component/forcefield/AdaptiveBeamForceFieldAndMass.inl b/src/BeamAdapter/component/forcefield/AdaptiveBeamForceFieldAndMass.inl index 2f908fa46..8ede11257 100644 --- a/src/BeamAdapter/component/forcefield/AdaptiveBeamForceFieldAndMass.inl +++ b/src/BeamAdapter/component/forcefield/AdaptiveBeamForceFieldAndMass.inl @@ -60,10 +60,12 @@ using sofa::helper::ScopedAdvancedTimer; template AdaptiveBeamForceFieldAndMass::AdaptiveBeamForceFieldAndMass() : d_computeMass(initData(&d_computeMass,true,"computeMass","if false, only compute the stiff elastic model")) - , d_massDensity(initData(&d_massDensity,(Real)1.0,"massDensity", "Density of the mass (usually in kg/m^3)" )) + , m_defaultMassDensity(Real(1.)) + , d_massDensity(initData(&d_massDensity,type::vector(1, m_defaultMassDensity),"massDensity", "Density of the mass" )) , d_useShearStressComputation(initData(&d_useShearStressComputation, true, "shearStressComputation","if false, suppress the shear stress in the computation")) , d_reinforceLength(initData(&d_reinforceLength, false, "reinforceLength", "if true, a separate computation for the error in elongation is peformed")) , l_interpolation(initLink("interpolation","Path to the Interpolation component on scene")) + { } @@ -79,6 +81,29 @@ void AdaptiveBeamForceFieldAndMass::init() msg_error() << "No Beam Interpolation found, the component can not work."; this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); } + else + { + BaseContext* context = this->getContext(); + core::topology::BaseMeshTopology* topology = context->getMeshTopology(); + auto massDensity = sofa::helper::getWriteOnlyAccessor(d_massDensity); + if (topology) + { + const auto& nbEdges = topology->getNbEdges(); + if (massDensity.size() != nbEdges) + { + Real value = m_defaultMassDensity; + if (massDensity.size() == 0){ + msg_warning() << "Empty data field for " << d_massDensity.getName() <<". Set default " << value; + } else { + value = massDensity[0]; + } + massDensity.resize(nbEdges); + for (auto& beammassDensity: massDensity) + beammassDensity = value; + } + } + m_defaultMassDensity = massDensity[0]; // if the sizes mismatch again at runtime, will use this default value + } ForceField::init(); this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Valid); @@ -541,7 +566,16 @@ void AdaptiveBeamForceFieldAndMass::addForce (const MechanicalParams* beamInterpolation->getInterpolationParameters(beamId, beamMatrices._L, beamMatrices._A, beamMatrices._Iy, beamMatrices._Iz, beamMatrices._Asy, beamMatrices._Asz, beamMatrices._J); - beamMatrices._rho = d_massDensity.getValue(); // for BeamInterpolation which is not overidding the _rho + const auto& massDensity = helper::getReadAccessor(d_massDensity); + // for BeamInterpolation which is not overidding the _rho + if (beamId < int(massDensity.size())) + { + beamMatrices._rho = massDensity[beamId]; + } + else + { + beamMatrices._rho = m_defaultMassDensity; + } beamInterpolation->getMechanicalParameters(beamId, beamMatrices._youngM, beamMatrices._cPoisson, beamMatrices._rho); /// compute the local mass matrices diff --git a/src/BeamAdapter/component/forcefield/AdaptiveInflatableBeamForceField.inl b/src/BeamAdapter/component/forcefield/AdaptiveInflatableBeamForceField.inl index cebba2b2b..434b0f992 100644 --- a/src/BeamAdapter/component/forcefield/AdaptiveInflatableBeamForceField.inl +++ b/src/BeamAdapter/component/forcefield/AdaptiveInflatableBeamForceField.inl @@ -618,7 +618,7 @@ void AdaptiveInflatableBeamForceField::addForce (const MechanicalPara /// ADD the effect of the pressure in the axial direction // inner radius of the tube - Real r = l_interpolation->d_innerRadius.getValue(); + Real r = l_interpolation->m_defaultInnerRadius; if (r==(Real)0){ msg_warning()<<" Inflatable Beam Force Field suppose that the interpolation is a tube "; From 4889361dec9be58a84424c86abff0de0dd27ca7b Mon Sep 17 00:00:00 2001 From: EulalieCoevoet Date: Wed, 5 Mar 2025 13:53:10 +0100 Subject: [PATCH 2/2] adds tests and fixes failing AdaptiveBeamForceFieldAndMassTest.checkValues --- BeamAdapter_test/BeamInterpolation_test.cpp | 72 ++++++++++++++++++- .../AdaptiveBeamForceFieldAndMassTest.cpp | 7 +- .../component/BeamInterpolation.inl | 2 +- 3 files changed, 78 insertions(+), 3 deletions(-) diff --git a/BeamAdapter_test/BeamInterpolation_test.cpp b/BeamAdapter_test/BeamInterpolation_test.cpp index 7724bfe8f..47d046d8c 100644 --- a/BeamAdapter_test/BeamInterpolation_test.cpp +++ b/BeamAdapter_test/BeamInterpolation_test.cpp @@ -55,6 +55,8 @@ using sofa::component::statecontainer::MechanicalObject ; using std::string; #include +#include +using sofa::component::fem::_beaminterpolation_::BeamInterpolation; namespace sofa { @@ -71,6 +73,68 @@ struct BeamInterpolationTest : public sofa::testing::BaseSimulationTest, sofa::simpleapi::importPlugin("BeamAdapter"); } + Node::SPtr createSingleBeam() + { + string scene = + "" + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " "; + + Node::SPtr root = SceneLoaderXML::loadFromMemory("singleBeam", scene.c_str()); + sofa::simulation::node::initRoot(root.get()); + + return root; + } + + void checkDataInitialization(const Data>& data, + const SReal& defaultValue, + const sofa::Size& nbBeam, + const SReal& value) + { + const auto& vector = helper::getReadAccessor(data); + ASSERT_EQ(vector.size(), nbBeam); + for (const auto& v: vector) + ASSERT_FLOAT_EQ(v, value); + ASSERT_FLOAT_EQ(defaultValue, value); + } + + void checkCreation() + { + Node::SPtr root = createSingleBeam(); + + // Search for Beam FF + BeamInterpolation* beamInterpolation = nullptr; + root->getTreeObject(beamInterpolation); + ASSERT_NE(beamInterpolation, nullptr); + + sofa::Size nbBeam = 199; + + // Check component state and Data default values + checkDataInitialization(beamInterpolation->d_radius, beamInterpolation->m_defaultRadius, nbBeam, 0.1); + checkDataInitialization(beamInterpolation->d_innerRadius, beamInterpolation->m_defaultInnerRadius, nbBeam, 0.0); + checkDataInitialization(beamInterpolation->d_lengthY, beamInterpolation->m_defaultLengthY, nbBeam, 1.0); + checkDataInitialization(beamInterpolation->d_lengthZ, beamInterpolation->m_defaultLengthZ, nbBeam, 1.0); + checkDataInitialization(beamInterpolation->d_defaultYoungModulus, beamInterpolation->m_defaultYoungModulus, nbBeam, 1e5); + checkDataInitialization(beamInterpolation->d_poissonRatio, beamInterpolation->m_defaultPoissonRatio, nbBeam, 0.4); + } + void simpleScene(const std::vector& lines) { assert(lines.size()==3); @@ -96,7 +160,8 @@ struct BeamInterpolationTest : public sofa::testing::BaseSimulationTest, root->init(core::ExecParams::defaultInstance()); root->reinit(core::ExecParams::defaultInstance()) ; - }else if(lines[2]=="W") + } + else if(lines[2]=="W") { EXPECT_MSG_EMIT(Error) ; EXPECT_MSG_NOEMIT(Warning) ; @@ -110,6 +175,7 @@ struct BeamInterpolationTest : public sofa::testing::BaseSimulationTest, } }; + static std::vector> teststrings ={ { "" @@ -143,6 +209,10 @@ TEST_P(BeamInterpolationTest, checkMinimalScene) { ASSERT_NO_THROW(this->simpleScene(GetParam())) ; } +TEST_F(BeamInterpolationTest, checkCreation) { + ASSERT_NO_THROW(this->checkCreation()); +} + INSTANTIATE_TEST_SUITE_P(checkMinimalScene, BeamInterpolationTest, ::testing::ValuesIn(teststrings) ) ; diff --git a/BeamAdapter_test/component/forcefield/AdaptiveBeamForceFieldAndMassTest.cpp b/BeamAdapter_test/component/forcefield/AdaptiveBeamForceFieldAndMassTest.cpp index 521df0c3e..2298d9554 100644 --- a/BeamAdapter_test/component/forcefield/AdaptiveBeamForceFieldAndMassTest.cpp +++ b/BeamAdapter_test/component/forcefield/AdaptiveBeamForceFieldAndMassTest.cpp @@ -126,7 +126,12 @@ struct AdaptiveBeamForceFieldAndMassTest : public sofa::testing::BaseSimulationT // Check component state and Data default values ASSERT_EQ(beamForceFieldMass->d_componentState.getValue(), sofa::core::objectmodel::ComponentState::Valid); ASSERT_EQ(beamForceFieldMass->d_computeMass.getValue(), true); - ASSERT_FLOAT_EQ(beamForceFieldMass->d_massDensity.getValue()[0], 10.0); + + const auto& massDensity = helper::getReadAccessor(beamForceFieldMass->d_massDensity); + ASSERT_EQ(massDensity.size(), 199); + for (const auto& m: massDensity) + ASSERT_FLOAT_EQ(m, 10.0); + ASSERT_FLOAT_EQ(beamForceFieldMass->m_defaultMassDensity, 10.0); ASSERT_FLOAT_EQ(beamForceFieldMass->rayleighMass.getValue(), 0.0); ASSERT_FLOAT_EQ(beamForceFieldMass->rayleighStiffness.getValue(), 0.0); } diff --git a/src/BeamAdapter/component/BeamInterpolation.inl b/src/BeamAdapter/component/BeamInterpolation.inl index 19e63d522..116562831 100644 --- a/src/BeamAdapter/component/BeamInterpolation.inl +++ b/src/BeamAdapter/component/BeamInterpolation.inl @@ -58,7 +58,7 @@ BeamInterpolation::BeamInterpolation() : , m_defaultRadius(Real(1.0)) , d_radius(initData(&d_radius, type::vector(1, m_defaultRadius), "radius", "radius of the beam (if circular cross-section is considered)")) - , m_defaultInnerRadius(Real(1.0)) + , m_defaultInnerRadius(Real(0.0)) , d_innerRadius(initData(&d_innerRadius, type::vector(1, m_defaultInnerRadius), "innerRadius", "inner radius of the beam if it applies")) , d_sideLength(initData(&d_sideLength, Real(1.0), "sideLength", "side length of the beam (if square cross-section is considered)"))