Skip to content
Merged
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 @@ -26,6 +26,7 @@
#include <sofa/core/behavior/ConstraintResolution.h>
#include <sofa/core/behavior/MechanicalState.h>
#include <sofa/core/behavior/BaseIntegrationScheme.h>
#include <sofa/core/objectmodel/lifecycle/DeprecatedData.h>

namespace sofa::component::constraint::lagrangian::model
{
Expand Down Expand Up @@ -84,17 +85,22 @@ class StopperLagrangianConstraint : public core::behavior::LagrangianConstraint<
typedef core::objectmodel::Data<VecDeriv> DataVecDeriv;
typedef core::objectmodel::Data<MatrixDeriv> DataMatrixDeriv;

using Inherit::getMState;
using Inherit::isComponentStateInvalid;
using Inherit::d_componentState;
using Inherit::d_constraintIndex;
protected:
Data<int> d_index; ///< index of the stop constraint
sofa::core::objectmodel::lifecycle::DeprecatedData d_index {this, "v26.12", "v27.12", "d_index", "You should now use indices to specify the set of dof indices to constraint"};
Data<sofa::type::vector<unsigned int>> d_indices; ///< index of the stop constraint
Data<SReal> d_min; ///< minimum value accepted
Data<SReal> d_max; ///< maximum value accepted


sofa::type::vector<unsigned int> m_cid;

StopperLagrangianConstraint(MechanicalState* object = nullptr);

virtual ~StopperLagrangianConstraint() {}

void init() override;

virtual type::vector<std::string> getConstraintIdentifiers() override final
{
Expand All @@ -103,21 +109,16 @@ class StopperLagrangianConstraint : public core::behavior::LagrangianConstraint<
ids.push_back("Unilateral");
return ids;
}

virtual type::vector<std::string> getStopperIdentifiers(){ return {}; }



public:
void buildConstraintMatrix(const core::ConstraintParams* cParams, DataMatrixDeriv &c_d, unsigned int &cIndex, const DataVecCoord &x) override;
void getConstraintViolation(const core::ConstraintParams* cParams, linearalgebra::BaseVector *resV, const DataVecCoord &x, const DataVecDeriv &v) override;

void getConstraintResolution(const core::ConstraintParams *, std::vector<core::behavior::ConstraintResolution*>& resTab, unsigned int& offset) override;
};

#if !defined(SOFA_COMPONENT_CONSTRAINTSET_STOPPERLAGRANGIANCONSTRAINT_CPP)
extern template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API StopperLagrangianConstraint<defaulttype::Vec1Types>;

#endif

} //namespace sofa::component::constraint::lagrangian::model
Original file line number Diff line number Diff line change
Expand Up @@ -31,33 +31,82 @@ namespace sofa::component::constraint::lagrangian::model
template<class DataTypes>
StopperLagrangianConstraint<DataTypes>::StopperLagrangianConstraint(MechanicalState* object)
: Inherit(object)
, d_index(initData(&d_index, 0, "index", "index of the stop constraint"))
, d_indices(initData(&d_indices, "indices", "indices of the stop constraint"))
, d_min(initData(&d_min, -100.0_sreal, "min", "minimum value accepted"))
, d_max(initData(&d_max, 100.0_sreal, "max", "maximum value accepted"))
{
}

template<class DataTypes>
void StopperLagrangianConstraint<DataTypes>::init()
{
Inherit::init();
if(!getMState())
{
msg_error() << "There is no mstate to constraint";
d_componentState = sofa::core::objectmodel::ComponentState::Invalid;
return;
}

auto x = getMState()->readPositions();
if(!d_indices.isSet())
{
auto indices = sofa::helper::getWriteOnlyAccessor(d_indices);
indices.resize(x.size());
for(sofa::Index i=0;i<x.size();i++)
{
indices[i] = i;
}
}

Comment on lines +52 to +61

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes the default behavior of the ocmpoent, forcing to apply the constraint to all points if nothing is given. To keep old behavior you should only put it to the first vertex. Otherwise this PR should be marked as breaking

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank for your comment,

The PR is actually already flagged as breaking.
That's said, I think the underlying question is more what are the SOFA guidelines regarding this indices/index stuff to increase component consistency.
I searched in the doc, but cannot find guidelines, maybe worth to discuss and formalize (if not done yet).

A quick look in Lagrangian constraint plugin already contains three different pattern.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have opened an issue regarding the behavioral in-consistencies on indices/index
#6418

d_componentState = sofa::core::objectmodel::ComponentState::Valid;
}

template<class DataTypes>
void StopperLagrangianConstraint<DataTypes>::buildConstraintMatrix(const core::ConstraintParams* /*cParams*/, DataMatrixDeriv &c_d, unsigned int &cIndex, const DataVecCoord &/*x*/)
{
auto c = sofa::helper::getWriteAccessor(c_d);
if(isComponentStateInvalid())
return;

auto c = sofa::helper::getWriteOnlyAccessor(c_d);
auto indices = sofa::helper::getReadAccessor(d_indices);

MatrixDerivRowIterator c_it = c->writeLine(cIndex++);
c_it.setCol(d_index.getValue(), Coord(1));
m_cid.resize(indices.size());
for(unsigned i=0; i<m_cid.size(); ++i)
{
m_cid[i] = cIndex;
MatrixDerivRowIterator c_it = c->writeLine(m_cid[i]);
c_it.setCol(indices[i], Coord(1));
cIndex++;
}
}

template<class DataTypes>
void StopperLagrangianConstraint<DataTypes>::getConstraintViolation(const core::ConstraintParams* /*cParams*/, linearalgebra::BaseVector *resV, const DataVecCoord &x, const DataVecDeriv &/*v*/)
void StopperLagrangianConstraint<DataTypes>::getConstraintViolation(const core::ConstraintParams* /*cParams*/, linearalgebra::BaseVector *resV, const DataVecCoord& x_, const DataVecDeriv &/*v*/)
{
const auto constraintIndex = this->d_constraintIndex.getValue();
resV->set(constraintIndex, x.getValue()[d_index.getValue()][0]);
if(isComponentStateInvalid())
return;

auto x = x_.getValue();
auto indices = sofa::helper::getReadAccessor(d_indices);

for(unsigned int i =0 ; i<indices.size();i++)
{
resV->set(m_cid[i], x[indices[i]][0]);
}
}

template<class DataTypes>
void StopperLagrangianConstraint<DataTypes>::getConstraintResolution(const core::ConstraintParams *, std::vector<core::behavior::ConstraintResolution*>& resTab, unsigned int& offset)
{
for(int i=0; i<1; i++)
resTab[offset++] = new StopperLagrangianConstraintResolution1Dof(d_min.getValue(), d_max.getValue());
if(isComponentStateInvalid())
return;

auto min = d_min.getValue();
auto max = d_max.getValue();
auto indices = sofa::helper::getReadAccessor(d_indices);
for(auto _ : indices)
resTab[offset++] = new StopperLagrangianConstraintResolution1Dof(min, max);
}

} //namespace sofa::component::constraint::lagrangian::model
Loading