Skip to content

Commit b3e42f1

Browse files
bakpaulhugtalbot
andauthored
[Lagrangian] Refactoring of GenericConstraintSolver (#5666)
* First working version of exploded constraint problrms. Still lots of info in GenericCosntraintSolver data that are dependent on the method type. Need to find a way of setting the solving method by adding a component in the scene. * Changed all problems into solvers. It makes more sense to use an inheritance. Now the constraintProblem is only a container * Apply changes to scenes, tests and tutorials * Apply review comments * change ownership of d_multithreading * Add comment on do methods and changed signature to add constraint problem * Add scene check to fix and display info if GenericConstraintSolver is still being used * Revert "Add scene check to fix and display info if GenericConstraintSolver is still being used" This reverts commit dd1c031. * Add component change for GenericConstraintSolver --------- Co-authored-by: Hugo <hugo.talbot@sofa-framework.org>
1 parent 700fb0d commit b3e42f1

File tree

61 files changed

+1448
-965
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+1448
-965
lines changed

Sofa/Component/AnimationLoop/src/sofa/component/animationloop/FreeMotionAnimationLoop.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,12 @@
4444
#include <sofa/simulation/CollisionVisitor.h>
4545
#include <sofa/simulation/SolveVisitor.h>
4646
#include <sofa/simulation/MainTaskSchedulerFactory.h>
47+
#include <sofa/component/constraint/lagrangian/solver/ProjectedGaussSeidelConstraintSolver.h>
4748

4849
#include <sofa/simulation/mechanicalvisitor/MechanicalVInitVisitor.h>
4950
using sofa::simulation::mechanicalvisitor::MechanicalVInitVisitor;
5051

52+
5153
#include <sofa/simulation/mechanicalvisitor/MechanicalBeginIntegrationVisitor.h>
5254
using sofa::simulation::mechanicalvisitor::MechanicalBeginIntegrationVisitor;
5355

@@ -67,7 +69,7 @@ using namespace core::behavior;
6769
using namespace sofa::simulation;
6870
using sofa::helper::ScopedAdvancedTimer;
6971

70-
using DefaultConstraintSolver = sofa::component::constraint::lagrangian::solver::GenericConstraintSolver;
72+
using DefaultConstraintSolver = sofa::component::constraint::lagrangian::solver::ProjectedGaussSeidelConstraintSolver;
7173

7274
FreeMotionAnimationLoop::FreeMotionAnimationLoop() :
7375
d_solveVelocityConstraintFirst(initData(&d_solveVelocityConstraintFirst , false, "solveVelocityConstraintFirst", "solve separately velocity constraint violations before position constraint violations"))

Sofa/Component/Constraint/Lagrangian/Model/tests/scenes_test/BilateralInteractionConstraint.scn

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<Node name="root" dt="0.001" gravity="0 -981 0">
33
<VisualStyle displayFlags="showForceFields" />
44
<FreeMotionAnimationLoop />
5-
<GenericConstraintSolver maxIterations="100" tolerance="1e-3" />
5+
<ProjectedGaussSeidelConstraintSolver maxIterations="100" tolerance="1e-3" />
66
<CollisionPipeline depth="6" verbose="0" draw="0" />
77
<BruteForceBroadPhase/>
88
<BVHNarrowPhase/>

Sofa/Component/Constraint/Lagrangian/Solver/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,13 @@ set(HEADER_FILES
88
${SOFACOMPONENTCONSTRAINTLAGRANGIANSOLVER_SOURCE_DIR}/init.h
99
${SOFACOMPONENTCONSTRAINTLAGRANGIANSOLVER_SOURCE_DIR}/ConstraintSolverImpl.h
1010
${SOFACOMPONENTCONSTRAINTLAGRANGIANSOLVER_SOURCE_DIR}/GenericConstraintProblem.h
11+
1112
${SOFACOMPONENTCONSTRAINTLAGRANGIANSOLVER_SOURCE_DIR}/GenericConstraintSolver.h
13+
${SOFACOMPONENTCONSTRAINTLAGRANGIANSOLVER_SOURCE_DIR}/BuiltConstraintSolver.h
14+
${SOFACOMPONENTCONSTRAINTLAGRANGIANSOLVER_SOURCE_DIR}/NNCGConstraintSolver.h
15+
${SOFACOMPONENTCONSTRAINTLAGRANGIANSOLVER_SOURCE_DIR}/ProjectedGaussSeidelConstraintSolver.h
16+
${SOFACOMPONENTCONSTRAINTLAGRANGIANSOLVER_SOURCE_DIR}/UnbuiltConstraintSolver.h
17+
${SOFACOMPONENTCONSTRAINTLAGRANGIANSOLVER_SOURCE_DIR}/UnbuiltGaussSeidelConstraintSolver.h
1218
${SOFACOMPONENTCONSTRAINTLAGRANGIANSOLVER_SOURCE_DIR}/LCPConstraintSolver.h
1319

1420
${SOFACOMPONENTCONSTRAINTLAGRANGIANSOLVER_SOURCE_DIR}/visitors/ConstraintStoreLambdaVisitor.h
@@ -20,7 +26,13 @@ set(SOURCE_FILES
2026
${SOFACOMPONENTCONSTRAINTLAGRANGIANSOLVER_SOURCE_DIR}/init.cpp
2127
${SOFACOMPONENTCONSTRAINTLAGRANGIANSOLVER_SOURCE_DIR}/ConstraintSolverImpl.cpp
2228
${SOFACOMPONENTCONSTRAINTLAGRANGIANSOLVER_SOURCE_DIR}/GenericConstraintProblem.cpp
29+
2330
${SOFACOMPONENTCONSTRAINTLAGRANGIANSOLVER_SOURCE_DIR}/GenericConstraintSolver.cpp
31+
${SOFACOMPONENTCONSTRAINTLAGRANGIANSOLVER_SOURCE_DIR}/BuiltConstraintSolver.cpp
32+
${SOFACOMPONENTCONSTRAINTLAGRANGIANSOLVER_SOURCE_DIR}/NNCGConstraintSolver.cpp
33+
${SOFACOMPONENTCONSTRAINTLAGRANGIANSOLVER_SOURCE_DIR}/ProjectedGaussSeidelConstraintSolver.cpp
34+
${SOFACOMPONENTCONSTRAINTLAGRANGIANSOLVER_SOURCE_DIR}/UnbuiltConstraintSolver.cpp
35+
${SOFACOMPONENTCONSTRAINTLAGRANGIANSOLVER_SOURCE_DIR}/UnbuiltGaussSeidelConstraintSolver.cpp
2436
${SOFACOMPONENTCONSTRAINTLAGRANGIANSOLVER_SOURCE_DIR}/LCPConstraintSolver.cpp
2537

2638
${SOFACOMPONENTCONSTRAINTLAGRANGIANSOLVER_SOURCE_DIR}/visitors/ConstraintStoreLambdaVisitor.cpp
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/******************************************************************************
2+
* SOFA, Simulation Open-Framework Architecture *
3+
* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
4+
* *
5+
* This program is free software; you can redistribute it and/or modify it *
6+
* under the terms of the GNU Lesser General Public License as published by *
7+
* the Free Software Foundation; either version 2.1 of the License, or (at *
8+
* your option) any later version. *
9+
* *
10+
* This program is distributed in the hope that it will be useful, but WITHOUT *
11+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
12+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
13+
* for more details. *
14+
* *
15+
* You should have received a copy of the GNU Lesser General Public License *
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
17+
*******************************************************************************
18+
* Authors: The SOFA Team and external contributors (see Authors.txt) *
19+
* *
20+
* Contact information: contact@sofa-framework.org *
21+
******************************************************************************/
22+
23+
#include <sofa/component/constraint/lagrangian/solver/BuiltConstraintSolver.h>
24+
25+
#include <sofa/helper/ScopedAdvancedTimer.h>
26+
#include <sofa/simulation/MainTaskSchedulerFactory.h>
27+
#include <sofa/simulation/ParallelForEach.h>
28+
29+
namespace sofa::component::constraint::lagrangian::solver
30+
{
31+
BuiltConstraintSolver::BuiltConstraintSolver()
32+
: d_multithreading(initData(&d_multithreading, false, "multithreading", "Build compliances concurrently"))
33+
{}
34+
35+
void BuiltConstraintSolver::init()
36+
{
37+
Inherit1::init();
38+
if(d_multithreading.getValue())
39+
{
40+
simulation::MainTaskSchedulerFactory::createInRegistry()->init();
41+
}
42+
}
43+
44+
void BuiltConstraintSolver::doBuildSystem( const core::ConstraintParams *cParams, GenericConstraintProblem * problem ,unsigned int numConstraints)
45+
{
46+
SOFA_UNUSED(numConstraints);
47+
SCOPED_TIMER_VARNAME(getComplianceTimer, "Get Compliance");
48+
dmsg_info() <<" computeCompliance in " << l_constraintCorrections.size()<< " constraintCorrections" ;
49+
50+
const bool multithreading = d_multithreading.getValue();
51+
52+
const simulation::ForEachExecutionPolicy execution = multithreading ?
53+
simulation::ForEachExecutionPolicy::PARALLEL :
54+
simulation::ForEachExecutionPolicy::SEQUENTIAL;
55+
56+
simulation::TaskScheduler* taskScheduler = simulation::MainTaskSchedulerFactory::createInRegistry();
57+
assert(taskScheduler);
58+
59+
//Used to prevent simultaneous accesses to the main compliance matrix
60+
std::mutex mutex;
61+
62+
//Visits all constraint corrections to compute the compliance matrix projected
63+
//in the constraint space.
64+
simulation::forEachRange(execution, *taskScheduler, l_constraintCorrections.begin(), l_constraintCorrections.end(),
65+
[&cParams, this, &multithreading, &mutex, problem](const auto& range)
66+
{
67+
ComplianceWrapper compliance(problem->W, multithreading);
68+
69+
for (auto it = range.start; it != range.end; ++it)
70+
{
71+
core::behavior::BaseConstraintCorrection* cc = *it;
72+
if (cc->isActive())
73+
{
74+
cc->addComplianceInConstraintSpace(cParams, &compliance.matrix());
75+
}
76+
}
77+
78+
std::lock_guard guard(mutex);
79+
compliance.assembleMatrix();
80+
});
81+
82+
addRegularization(problem->W, d_regularizationTerm.getValue());
83+
dmsg_info() << " computeCompliance_done " ;
84+
}
85+
86+
87+
BuiltConstraintSolver::ComplianceWrapper::ComplianceMatrixType& BuiltConstraintSolver::ComplianceWrapper::matrix()
88+
{
89+
if (m_isMultiThreaded)
90+
{
91+
if (!m_threadMatrix)
92+
{
93+
m_threadMatrix = std::make_unique<ComplianceMatrixType>();
94+
m_threadMatrix->resize(m_complianceMatrix.rowSize(), m_complianceMatrix.colSize());
95+
}
96+
return *m_threadMatrix;
97+
}
98+
return m_complianceMatrix;
99+
}
100+
101+
void BuiltConstraintSolver::ComplianceWrapper::assembleMatrix() const
102+
{
103+
if (m_threadMatrix)
104+
{
105+
for (linearalgebra::BaseMatrix::Index j = 0; j < m_threadMatrix->rowSize(); ++j)
106+
{
107+
for (linearalgebra::BaseMatrix::Index l = 0; l < m_threadMatrix->colSize(); ++l)
108+
{
109+
m_complianceMatrix.add(j, l, m_threadMatrix->element(j,l));
110+
}
111+
}
112+
}
113+
}
114+
115+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/******************************************************************************
2+
* SOFA, Simulation Open-Framework Architecture *
3+
* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
4+
* *
5+
* This program is free software; you can redistribute it and/or modify it *
6+
* under the terms of the GNU Lesser General Public License as published by *
7+
* the Free Software Foundation; either version 2.1 of the License, or (at *
8+
* your option) any later version. *
9+
* *
10+
* This program is distributed in the hope that it will be useful, but WITHOUT *
11+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
12+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
13+
* for more details. *
14+
* *
15+
* You should have received a copy of the GNU Lesser General Public License *
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
17+
*******************************************************************************
18+
* Authors: The SOFA Team and external contributors (see Authors.txt) *
19+
* *
20+
* Contact information: contact@sofa-framework.org *
21+
******************************************************************************/
22+
#pragma once
23+
24+
#include <sofa/component/constraint/lagrangian/solver/GenericConstraintSolver.h>
25+
26+
namespace sofa::component::constraint::lagrangian::solver
27+
{
28+
/**
29+
* \brief This component implements a generic way of building system for solvers that use a built
30+
* version of the constraint matrix. Any solver that uses a build matrix should inherit from this.
31+
* This component is purely virtual because doSolve is not defined and needs to be defined in the
32+
* inherited class
33+
*/
34+
class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_SOLVER_API BuiltConstraintSolver : public GenericConstraintSolver
35+
{
36+
37+
38+
public:
39+
SOFA_CLASS(BuiltConstraintSolver, GenericConstraintSolver);
40+
Data<bool> d_multithreading; ///< Build compliances concurrently
41+
42+
BuiltConstraintSolver();
43+
44+
virtual void init() override;
45+
46+
protected:
47+
virtual void doBuildSystem( const core::ConstraintParams *cParams, GenericConstraintProblem * problem ,unsigned int numConstraints) override;
48+
49+
private:
50+
51+
struct ComplianceWrapper
52+
{
53+
using ComplianceMatrixType = sofa::linearalgebra::LPtrFullMatrix<SReal>;
54+
55+
ComplianceWrapper(ComplianceMatrixType& complianceMatrix, bool isMultiThreaded)
56+
: m_isMultiThreaded(isMultiThreaded), m_complianceMatrix(complianceMatrix) {}
57+
58+
ComplianceMatrixType& matrix();
59+
60+
void assembleMatrix() const;
61+
62+
private:
63+
bool m_isMultiThreaded { false };
64+
ComplianceMatrixType& m_complianceMatrix;
65+
std::unique_ptr<ComplianceMatrixType> m_threadMatrix;
66+
};
67+
};
68+
}

Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/ConstraintSolverImpl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ void ConstraintProblem::clear(int nbConstraints)
5151
dFree.resize(nbConstraints);
5252
f.resize(nbConstraints);
5353

54-
static std::atomic<unsigned int> counter = 0;
54+
static std::atomic<unsigned> counter = 0;
5555
problemId = counter.fetch_add(1, std::memory_order_relaxed);
5656
}
5757

58-
unsigned int ConstraintProblem::getProblemId()
58+
unsigned ConstraintProblem::getProblemId() const
5959
{
6060
return problemId;
6161
}

Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/ConstraintSolverImpl.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,19 @@ class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_SOLVER_API ConstraintProblem
5959

6060
// Returns the number of scalar constraints, or equivalently the number of Lagrange multipliers
6161
int getDimension() const { return dimension; }
62+
void setDimension(int dim) { dimension = dim; }
6263

6364
SReal** getW() { return W.lptr(); }
6465
SReal* getDfree() { return dFree.ptr(); }
6566
SReal* getF() { return f.ptr(); }
6667

6768
virtual void solveTimed(SReal tolerance, int maxIt, SReal timeout) = 0;
6869

69-
unsigned int getProblemId();
70+
unsigned getProblemId() const;
7071

7172
protected:
7273
int dimension;
73-
unsigned int problemId;
74+
unsigned problemId;
7475
};
7576

7677

@@ -93,16 +94,17 @@ class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_SOLVER_API ConstraintSolverImpl : pub
9394

9495
void removeConstraintCorrection(core::behavior::BaseConstraintCorrection *s) override;
9596

97+
MultiLink< ConstraintSolverImpl,
98+
core::behavior::BaseConstraintCorrection,
99+
BaseLink::FLAG_STOREPATH> l_constraintCorrections;
100+
96101
protected:
97102

98103
void postBuildSystem(const core::ConstraintParams* cParams) override;
99104
void postSolveSystem(const core::ConstraintParams* cParams) override;
100105

101106
void clearConstraintCorrections();
102107

103-
MultiLink< ConstraintSolverImpl,
104-
core::behavior::BaseConstraintCorrection,
105-
BaseLink::FLAG_STOREPATH> l_constraintCorrections;
106108

107109
/// Calls the method resetConstraint on all the mechanical states and BaseConstraintSet
108110
/// In the case of a MechanicalObject, it clears the constraint jacobian matrix

0 commit comments

Comments
 (0)