From 5448a14f0526ac3d597c1abb8c4427acde4055cd Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Fri, 31 Jan 2025 15:10:05 +0100 Subject: [PATCH] [StateContainer] Extend the possible vector operations in vOp (#5237) * missing test * remove duplicated test * [StateContainer] Extend the possible vector operations in vOp --------- Co-authored-by: Paul Baksic <30337881+bakpaul@users.noreply.github.com> --- .../statecontainer/MechanicalObject.inl | 356 ++++++++++++------ .../tests/MechanicalObjectVOp_test.cpp | 234 +++++++++--- 2 files changed, 428 insertions(+), 162 deletions(-) diff --git a/Sofa/Component/StateContainer/src/sofa/component/statecontainer/MechanicalObject.inl b/Sofa/Component/StateContainer/src/sofa/component/statecontainer/MechanicalObject.inl index f2942f5ece6..7ccd7341dde 100644 --- a/Sofa/Component/StateContainer/src/sofa/component/statecontainer/MechanicalObject.inl +++ b/Sofa/Component/StateContainer/src/sofa/component/statecontainer/MechanicalObject.inl @@ -1784,6 +1784,228 @@ DataTypes>::getReadAccessor(core::ConstVecId v) *this->read(core::TVecId(v))); } +#define APPLY_PREDICATE_ONEPARAMS(PRED, v)\ + bool canApplyPredicate = false;\ + if (v.type == core::V_COORD)\ + {\ + canApplyPredicate = PRED(*this, v, f);\ + }\ + else if (v.type == core::V_DERIV)\ + {\ + canApplyPredicate = PRED(*this, v, f);\ + } + +#define APPLY_PREDICATE_TWOPARAMS(PRED, v, b)\ + bool canApplyPredicate = false;\ + if (v.type == core::V_COORD)\ + {\ + if (b.type == core::V_COORD)\ + {\ + canApplyPredicate = PRED(*this, v, b, f);\ + }\ + else if (b.type == core::V_DERIV)\ + {\ + canApplyPredicate = PRED(*this, v, b, f);\ + }\ + }\ + else if (v.type == core::V_DERIV)\ + {\ + if (b.type == core::V_COORD)\ + {\ + canApplyPredicate = PRED(*this, v, b, f);\ + }\ + else if (b.type == core::V_DERIV)\ + {\ + canApplyPredicate = PRED(*this, v, b, f);\ + }\ + } + +#define APPLY_PREDICATE_THREEPARAMS(PRED, v, a, b)\ + bool canApplyPredicate = false;\ + if (v.type == core::V_COORD)\ + {\ + if (a.type == core::V_COORD)\ + {\ + if (b.type == core::V_COORD)\ + {\ + canApplyPredicate = PRED(*this, v, a, b, f);\ + }\ + else if (b.type == core::V_DERIV)\ + {\ + canApplyPredicate = PRED(*this, v, a, b, f);\ + }\ + }\ + else if (a.type == core::V_DERIV)\ + {\ + if (b.type == core::V_COORD)\ + {\ + canApplyPredicate = PRED(*this, v, a, b, f);\ + }\ + else if (b.type == core::V_DERIV)\ + {\ + canApplyPredicate = PRED(*this, v, a, b, f);\ + }\ + }\ + }\ + else if (v.type == core::V_DERIV)\ + {\ + if (a.type == core::V_COORD)\ + {\ + if (b.type == core::V_COORD)\ + {\ + canApplyPredicate = PRED(*this, v, a, b, f);\ + }\ + else if (b.type == core::V_DERIV)\ + {\ + canApplyPredicate = PRED(*this, v, a, b, f);\ + }\ + }\ + else if (a.type == core::V_DERIV)\ + {\ + if (b.type == core::V_COORD)\ + {\ + canApplyPredicate = PRED(*this, v, a, b, f);\ + }\ + else if (b.type == core::V_DERIV)\ + {\ + canApplyPredicate = PRED(*this, v, a, b, f);\ + }\ + }\ + } + +template +bool vOp_vf(MechanicalObject& self, core::VecId v, Real_t f) +{ + if constexpr (requires(core::StateVecType_t vc, Real_t fc){vc[0] *= fc;}) + { + auto vv = helper::getWriteOnlyAccessor(*self.write(core::TVecId(v))); + for (unsigned int i = 0; i < vv.size(); ++i) + { + vv[i] *= f; + } + return true; + } + return false; +} + +template +bool vOp_vbf(MechanicalObject& self, core::VecId v, core::ConstVecId b, Real_t f) +{ + if constexpr (requires(core::StateVecType_t vc, core::StateVecType_t bc, Real_t fc){vc[0] = bc[0] * fc;}) + { + auto vv = helper::getWriteOnlyAccessor(*self.write(core::TVecId(v))); + auto vb = helper::getReadAccessor(*self.read(core::TVecId(b))); + vv.resize(vb.size()); + for (unsigned int i = 0; i < vv.size(); ++i) + { + vv[i] = vb[i] * f; + } + return true; + } + return false; +} + +template +bool vOp_va(MechanicalObject& self, core::VecId v, core::ConstVecId b, Real_t f) +{ + if constexpr (requires(core::StateVecType_t vc, core::StateVecType_t bc){vc[0] = bc[0];}) + { + auto vv = helper::getWriteOnlyAccessor(*self.write(core::TVecId(v))); + auto vb = helper::getReadAccessor(*self.read(core::TVecId(b))); + vv.wref() = vb.ref(); + return true; + } + return false; +} + +template +bool vOp_vb(MechanicalObject& self, core::VecId v, core::ConstVecId b, Real_t f) +{ + if constexpr (requires(core::StateVecType_t vc, core::StateVecType_t bc){vc[0] += bc[0];}) + { + auto vv = helper::getWriteOnlyAccessor(*self.write(core::TVecId(v))); + auto vb = helper::getReadAccessor(*self.read(core::TVecId(b))); + vv.resize(vb.size()); + for (unsigned int i = 0; i < vv.size(); ++i) + { + vv[i] += vb[i]; + } + return true; + } + return false; +} + +template +bool vOp_avf(MechanicalObject& self, core::VecId v, core::ConstVecId b, Real_t f) +{ + if constexpr (requires(core::StateVecType_t vc, core::StateVecType_t bc){vc[0] *= f; vc[0] += bc[0];}) + { + auto vv = helper::getWriteOnlyAccessor(*self.write(core::TVecId(v))); + auto vb = helper::getReadAccessor(*self.read(core::TVecId(b))); + vv.resize(vb.size()); + for (unsigned int i = 0; i < vv.size(); ++i) + { + vv[i] *= f; + vv[i] += vb[i]; + } + return true; + } + return false; +} + +template +bool vOp_v_inc_bf(MechanicalObject& self, core::VecId v, core::ConstVecId b, Real_t f) +{ + if constexpr (requires(core::StateVecType_t vc, core::StateVecType_t bc, Real_t fc){vc[0] += bc[0] * fc;}) + { + auto vv = helper::getWriteOnlyAccessor(*self.write(core::TVecId(v))); + auto vb = helper::getReadAccessor(*self.read(core::TVecId(b))); + vv.resize(vb.size()); + for (unsigned int i = 0; i < vv.size(); ++i) + { + vv[i] += vb[i] * f; + } + return true; + } + return false; +} + +template +bool vOp_vab(MechanicalObject& self, core::VecId v, core::ConstVecId a, core::ConstVecId b, Real_t f) +{ + if constexpr (requires(core::StateVecType_t vc, core::StateVecType_t ac, core::StateVecType_t bc){vc[0] = ac[0] + bc[0];}) + { + auto vv = helper::getWriteOnlyAccessor(*self.write(core::TVecId(v))); + auto va = helper::getReadAccessor(*self.read(core::TVecId(a))); + auto vb = helper::getReadAccessor(*self.read(core::TVecId(b))); + vv.resize(vb.size()); + for (unsigned int i = 0; i < vv.size(); ++i) + { + vv[i] = va[i] + vb[i]; + } + return true; + } + return false; +} + +template +bool vOp_vabf(MechanicalObject& self, core::VecId v, core::ConstVecId a, core::ConstVecId b, Real_t f) +{ + if constexpr (requires(core::StateVecType_t vc, core::StateVecType_t ac, core::StateVecType_t bc, Real_t fc){vc[0] = ac[0] + bc[0] * fc;}) + { + auto vv = helper::getWriteOnlyAccessor(*self.write(core::TVecId(v))); + auto va = helper::getReadAccessor(*self.read(core::TVecId(a))); + auto vb = helper::getReadAccessor(*self.read(core::TVecId(b))); + vv.resize(vb.size()); + for (unsigned int i = 0; i < vv.size(); ++i) + { + vv[i] = va[i] + vb[i] * f; + } + return true; + } + return false; +} + template void MechanicalObject::vOp(const core::ExecParams* params, core::VecId v, core::ConstVecId a, @@ -1812,54 +2034,27 @@ void MechanicalObject::vOp(const core::ExecParams* params, core::VecI } else { - if (b.type != v.type) - { - // ERROR - msg_error() << "Invalid vOp operation 2 ("<getWriteAccessor(v); - for (unsigned int i = 0; i < vv.size(); ++i) - vv[i] *= static_cast(f); - }); + APPLY_PREDICATE_ONEPARAMS(vOp_vf, v) + msg_error_when(!canApplyPredicate) << "Cannot apply vector operation v *= f (" << v << ',' << a << ',' << b << ',' << f << ")"; } else { // v = b*f - applyPredicateIfCoordOrDeriv(v.type, [this, &v, &b, f](auto vtype_v) - { - auto vv = this->getWriteAccessor(v); - auto vb = this->getReadAccessor(b); - vv.resize(vb.size()); - for (unsigned int i = 0; i < vv.size(); ++i) - vv[i] = vb[i] * static_cast(f); - }); + APPLY_PREDICATE_TWOPARAMS(vOp_vbf, v, b) + msg_error_when(!canApplyPredicate) << "Cannot apply vector operation v = b*f (" << v << ',' << a << ',' << b << ',' << f << ")"; } } } else { - if (a.type != v.type) - { - // ERROR - msg_error() << "Invalid vOp operation 3 ("<getWriteOnlyAccessor(v); - auto va = this->getReadAccessor(a); - vv.wref() = va.ref(); - }); + APPLY_PREDICATE_TWOPARAMS(vOp_va, v, a) + msg_error_when(!canApplyPredicate) << "Cannot apply vector operation v = a (" << v << ',' << a << ',' << b << ',' << f << ")"; } else { @@ -1868,36 +2063,14 @@ void MechanicalObject::vOp(const core::ExecParams* params, core::VecI if (f == 1._sreal) { // v += b - const bool isApplied = applyPredicateIfCoordOrDeriv(v.type, b.type, - [this, &v, &b](auto vtype_v, auto vtype_b) - { - auto vv = this->getWriteAccessor(v); - auto vb = this->getReadAccessor(b); - - if (vb.size() > vv.size()) - vv.resize(vb.size()); - - for (unsigned int i = 0; i < vb.size(); ++i) - vv[i] += vb[i]; - }); - msg_error_when(!isApplied) << "Invalid vOp operation 4 ("<getWriteAccessor(v); - auto vb = this->getReadAccessor(b); - - if (vb.size() > vv.size()) - vv.resize(vb.size()); - - for (unsigned int i = 0; i < vb.size(); ++i) - vv[i] += vb[i] * static_cast(f); - }); - msg_error_when(!isApplied) << "Invalid vOp operation 5 ("<::vOp(const core::ExecParams* params, core::VecI if (f == 1._sreal) { // v += a - const bool isApplied = applyPredicateIfCoordOrDeriv(v.type, a.type, - [this, &v, &a](auto vtype_v, auto vtype_a) - { - auto vv = this->getWriteAccessor(v); - auto va = this->getReadAccessor(a); - - if (va.size() > vv.size()) - vv.resize(va.size()); - - for (unsigned int i = 0; i < va.size(); ++i) - vv[i] += va[i]; - }); - msg_error_when(!isApplied) << "Invalid vOp operation 6 ("<getWriteOnlyAccessor(v); - auto va = this->getReadAccessor(a); - - vv.resize(va.size()); - for (unsigned int i = 0; i < vv.size(); ++i) - { - vv[i] *= static_cast(f); - vv[i] += va[i]; - } - }); + APPLY_PREDICATE_TWOPARAMS(vOp_avf, v, a) + msg_error_when(!canApplyPredicate) << "Cannot apply vector operation v = a+v*f (" << v << ',' << a << ',' << b << ',' << f << ")"; } } else @@ -1941,42 +2093,14 @@ void MechanicalObject::vOp(const core::ExecParams* params, core::VecI if (f == 1._sreal) { // v = a+b - const bool isApplied = applyPredicateIfCoordOrDeriv(v.type, b.type, - [this, &v, &a, &b](auto vtype_v, auto vtype_b) - { - auto vv = this->getWriteOnlyAccessor(v); - auto va = this->getReadAccessor(a); - auto vb = this->getReadAccessor(b); - - vv.resize(va.size()); - - for (unsigned int i = 0; i < vb.size(); ++i) - { - vv[i] = va[i]; - vv[i] += vb[i]; - } - }); - msg_error_when(!isApplied) << "Invalid vOp operation 7 ("<getWriteOnlyAccessor(v); - auto va = this->getReadAccessor(a); - auto vb = this->getReadAccessor(b); - - vv.resize(va.size()); - - for (unsigned int i = 0; i < vb.size(); ++i) - { - vv[i] = va[i]; - vv[i] += vb[i] * static_cast(f); - } - }); - msg_error_when(!isApplied) << "Invalid vOp operation 8 ("<; + static constexpr bool isRigid = type::isRigidType; + static constexpr Real_t positionCoefficient = 19; static constexpr Real_t restPositionCoefficient = 20; static constexpr Real_t freePositionCoefficient = 5; @@ -217,24 +219,44 @@ struct MechanicalObjectVOpTest : public testing::BaseTest void equalOtherMultiplyByScalarPositionMix() const { + //v = b*f + const auto vop = [this]() { - EXPECT_MSG_EMIT(Error); - //v = b*f m_mechanicalObject->vOp(nullptr, core::vec_id::write_access::position, core::ConstVecId::null(), core::vec_id::read_access::velocity, 2._sreal); + }; + if constexpr (isRigid) + { + EXPECT_MSG_EMIT(Error); + vop(); } - checkVecSpatialValues(positionCoefficient); + else + { + EXPECT_MSG_NOEMIT(Error); + vop(); + } + checkVecSpatialValues(isRigid ? positionCoefficient : velocityCoefficient * 2_sreal); checkVecValues(velocityCoefficient); } void equalOtherMultiplyByScalarVelocityMix() const { + //v = b*f + const auto vop = [this]() { - EXPECT_MSG_EMIT(Error); - //v = b*f m_mechanicalObject->vOp(nullptr, core::vec_id::write_access::velocity, core::ConstVecId::null(), core::vec_id::read_access::position, 2._sreal); + }; + if constexpr (isRigid) + { + EXPECT_MSG_EMIT(Error); + vop(); + } + else + { + EXPECT_MSG_NOEMIT(Error); + vop(); } checkVecSpatialValues(positionCoefficient); - checkVecValues(velocityCoefficient); + checkVecValues(isRigid ? velocityCoefficient : positionCoefficient * 2_sreal); } void equalOtherPosition() const @@ -250,12 +272,22 @@ struct MechanicalObjectVOpTest : public testing::BaseTest void equalOtherPositionMix() const { + //v = a + const auto vop = [this]() { - EXPECT_MSG_EMIT(Error); - //v = a m_mechanicalObject->vOp(nullptr, core::vec_id::write_access::position, core::vec_id::read_access::velocity, core::ConstVecId::null(), 1._sreal); + }; + if constexpr (isRigid) + { + EXPECT_MSG_EMIT(Error); + vop(); } - checkVecValues(positionCoefficient); + else + { + EXPECT_MSG_NOEMIT(Error); + vop(); + } + checkVecValues(isRigid ? positionCoefficient : velocityCoefficient); checkVecValues(velocityCoefficient); } @@ -272,13 +304,23 @@ struct MechanicalObjectVOpTest : public testing::BaseTest void equalOtherVelocityMix() const { + //v = a + const auto vop = [this]() { - EXPECT_MSG_EMIT(Error); - //v = a m_mechanicalObject->vOp(nullptr, core::vec_id::write_access::velocity, core::vec_id::read_access::restPosition, core::ConstVecId::null(), 1._sreal); + }; + if constexpr (isRigid) + { + EXPECT_MSG_EMIT(Error); + vop(); + } + else + { + EXPECT_MSG_NOEMIT(Error); + vop(); } checkVecValues(positionCoefficient); - checkVecValues(velocityCoefficient); + checkVecValues(isRigid ? velocityCoefficient : restPositionCoefficient); } void plusEqualOtherPosition() const @@ -316,13 +358,23 @@ struct MechanicalObjectVOpTest : public testing::BaseTest void plusEqualOtherVelocityMix() const { + //v += b + const auto vop = [this]() { - EXPECT_MSG_EMIT(Error); - //v += b m_mechanicalObject->vOp(nullptr, core::vec_id::write_access::velocity, core::vec_id::read_access::velocity, core::vec_id::read_access::position, 1._sreal); + }; + if constexpr (isRigid) + { + EXPECT_MSG_EMIT(Error); + vop(); + } + else + { + EXPECT_MSG_NOEMIT(Error); + vop(); } checkVecValues(positionCoefficient); - checkVecValues(velocityCoefficient); + checkVecValues(isRigid ? velocityCoefficient : velocityCoefficient + positionCoefficient); } void plusEqualOtherMultipliedByScalarPosition() const @@ -360,13 +412,23 @@ struct MechanicalObjectVOpTest : public testing::BaseTest void plusEqualOtherMultipliedByScalarVelocityMix() const { + //v += b*f + const auto vop = [this]() { - EXPECT_MSG_EMIT(Error); - //v += b*f m_mechanicalObject->vOp(nullptr, core::vec_id::write_access::velocity, core::vec_id::read_access::velocity, core::vec_id::read_access::freePosition, 2._sreal); + }; + if constexpr (isRigid) + { + EXPECT_MSG_EMIT(Error); + vop(); + } + else + { + EXPECT_MSG_NOEMIT(Error); + vop(); } checkVecValues(positionCoefficient); - checkVecValues(velocityCoefficient); + checkVecValues(isRigid ? velocityCoefficient : velocityCoefficient + freePositionCoefficient * 2); } void plusEqualOtherPosition_2() const @@ -383,11 +445,11 @@ struct MechanicalObjectVOpTest : public testing::BaseTest void plusEqualOtherPositionMix_2() const { { - EXPECT_MSG_EMIT(Error); + EXPECT_MSG_NOEMIT(Error); //v += a m_mechanicalObject->vOp(nullptr, core::vec_id::write_access::position, core::vec_id::read_access::freeVelocity, core::vec_id::read_access::position, 1._sreal); } - checkVecSpatialValues(positionCoefficient); + checkVecSpatialValues(positionCoefficient + freeVelocityCoefficient); checkVecValues(velocityCoefficient); } @@ -404,13 +466,23 @@ struct MechanicalObjectVOpTest : public testing::BaseTest void plusEqualOtherVelocityMix_2() const { + //v += a + const auto vop = [this]() { - EXPECT_MSG_EMIT(Error); - //v += a m_mechanicalObject->vOp(nullptr, core::vec_id::write_access::velocity, core::vec_id::read_access::freePosition, core::vec_id::read_access::velocity, 1._sreal); + }; + if constexpr (isRigid) + { + EXPECT_MSG_EMIT(Error); + vop(); + } + else + { + EXPECT_MSG_NOEMIT(Error); + vop(); } checkVecValues(positionCoefficient); - checkVecValues(velocityCoefficient); + checkVecValues(isRigid ? velocityCoefficient : velocityCoefficient + freePositionCoefficient); } void multipliedByScalarThenAddOtherPosition() const @@ -427,11 +499,11 @@ struct MechanicalObjectVOpTest : public testing::BaseTest void multipliedByScalarThenAddOtherPositionMix() const { { - EXPECT_MSG_EMIT(Error); + EXPECT_MSG_NOEMIT(Error); //v = a+v*f m_mechanicalObject->vOp(nullptr, core::vec_id::write_access::position, core::vec_id::read_access::freeVelocity, core::vec_id::read_access::position, 3_sreal); } - checkVecSpatialValues(positionCoefficient); + checkVecSpatialValues(freeVelocityCoefficient + positionCoefficient * 3); checkVecValues(velocityCoefficient); } @@ -448,13 +520,23 @@ struct MechanicalObjectVOpTest : public testing::BaseTest void multipliedByScalarThenAddOtherVelocityMix() const { + //v = a+v*f + const auto vop = [this]() { - EXPECT_MSG_EMIT(Error); - //v = a+v*f m_mechanicalObject->vOp(nullptr, core::vec_id::write_access::velocity, core::vec_id::read_access::freePosition, core::vec_id::read_access::velocity, 7._sreal); + }; + if constexpr (isRigid) + { + EXPECT_MSG_EMIT(Error); + vop(); + } + else + { + EXPECT_MSG_NOEMIT(Error); + vop(); } checkVecValues(positionCoefficient); - checkVecValues(velocityCoefficient); + checkVecValues(isRigid ? velocityCoefficient : freePositionCoefficient + velocityCoefficient * 7); } void equalSumPosition() const @@ -481,12 +563,22 @@ struct MechanicalObjectVOpTest : public testing::BaseTest void equalSumPositionMix2() const { + //v = a+b + const auto vop = [this]() { - EXPECT_MSG_EMIT(Error); - //v = a+b m_mechanicalObject->vOp(nullptr, core::vec_id::write_access::position, core::vec_id::read_access::freeVelocity, core::vec_id::read_access::freePosition, 1_sreal); + }; + if constexpr (isRigid) + { + EXPECT_MSG_EMIT(Error); + vop(); } - checkVecSpatialValues(positionCoefficient); + else + { + EXPECT_MSG_NOEMIT(Error); + vop(); + } + checkVecSpatialValues(isRigid ? positionCoefficient : freeVelocityCoefficient + freePositionCoefficient); checkVecValues(velocityCoefficient); } @@ -503,24 +595,44 @@ struct MechanicalObjectVOpTest : public testing::BaseTest void equalSumVelocityMix1() const { + //v = a+b + const auto vop = [this]() { - EXPECT_MSG_EMIT(Error); - //v = a+b m_mechanicalObject->vOp(nullptr, core::vec_id::write_access::velocity, core::vec_id::read_access::position, core::vec_id::read_access::freeVelocity, 1._sreal); + }; + if constexpr (isRigid) + { + EXPECT_MSG_EMIT(Error); + vop(); + } + else + { + EXPECT_MSG_NOEMIT(Error); + vop(); } checkVecValues(positionCoefficient); - checkVecValues(velocityCoefficient); + checkVecValues(isRigid ? velocityCoefficient : positionCoefficient + freeVelocityCoefficient); } void equalSumVelocityMix2() const { + //v = a+b + const auto vop = [this]() { - EXPECT_MSG_EMIT(Error); - //v = a+b m_mechanicalObject->vOp(nullptr, core::vec_id::write_access::velocity, core::vec_id::read_access::force, core::vec_id::read_access::position, 1._sreal); + }; + if constexpr (isRigid) + { + EXPECT_MSG_EMIT(Error); + vop(); + } + else + { + EXPECT_MSG_NOEMIT(Error); + vop(); } checkVecValues(positionCoefficient); - checkVecValues(velocityCoefficient); + checkVecValues(isRigid ? velocityCoefficient : forceCoefficient + positionCoefficient); } void equalSumWithScalarPosition() const @@ -536,12 +648,22 @@ struct MechanicalObjectVOpTest : public testing::BaseTest void equalSumWithScalarPositionMix1() const { + //v = a+b*f + const auto vop = [this]() { - EXPECT_MSG_EMIT(Error); - //v = a+b*f m_mechanicalObject->vOp(nullptr, core::vec_id::write_access::position, core::vec_id::read_access::velocity, core::vec_id::read_access::freePosition, 12_sreal); + }; + if constexpr (isRigid) + { + EXPECT_MSG_EMIT(Error); + vop(); } - checkVecSpatialValues(positionCoefficient); + else + { + EXPECT_MSG_NOEMIT(Error); + vop(); + } + checkVecSpatialValues(isRigid ? positionCoefficient : velocityCoefficient + freePositionCoefficient * 12); checkVecValues(velocityCoefficient); } @@ -569,24 +691,44 @@ struct MechanicalObjectVOpTest : public testing::BaseTest void equalSumWithScalarVelocityMix1() const { + //v = a+b*f + const auto vop = [this]() { - EXPECT_MSG_EMIT(Error); - //v = a+b*f m_mechanicalObject->vOp(nullptr, core::vec_id::write_access::velocity, core::vec_id::read_access::position, core::vec_id::read_access::freeVelocity, 12_sreal); + }; + if constexpr (isRigid) + { + EXPECT_MSG_EMIT(Error); + vop(); + } + else + { + EXPECT_MSG_NOEMIT(Error); + vop(); } checkVecSpatialValues(positionCoefficient); - checkVecValues(velocityCoefficient); + checkVecValues(isRigid ? velocityCoefficient : positionCoefficient + freeVelocityCoefficient * 12); } void equalSumWithScalarVelocityMix2() const { + //v = a+b*f + const auto vop = [this]() { - EXPECT_MSG_EMIT(Error); - //v = a+b*f m_mechanicalObject->vOp(nullptr, core::vec_id::write_access::velocity, core::vec_id::read_access::force, core::vec_id::read_access::position, 12_sreal); + }; + if constexpr (isRigid) + { + EXPECT_MSG_EMIT(Error); + vop(); + } + else + { + EXPECT_MSG_NOEMIT(Error); + vop(); } checkVecSpatialValues(positionCoefficient); - checkVecValues(velocityCoefficient); + checkVecValues(isRigid ? velocityCoefficient : forceCoefficient + positionCoefficient * 12); } typename MO::SPtr m_mechanicalObject;