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 @@ -34,8 +34,8 @@ ImprovedJacobiConstraintSolver::ImprovedJacobiConstraintSolver()
: BuiltConstraintSolver()
, d_useSpectralCorrection(initData(&d_useSpectralCorrection,false,"useSpectralCorrection","If set to true, the solution found after each iteration will be multiplied by spectralCorrectionFactor*2/spr(W), with spr() denoting the spectral radius."))
, d_spectralCorrectionFactor(initData(&d_spectralCorrectionFactor,1.0_sreal,"spectralCorrectionFactor","Factor used to modulate the spectral correction"))
, d_useConjugateResidue(initData(&d_useConjugateResidue,false,"useConjugateResidue","If set to true, the solution found after each iteration will be corrected along the solution direction using `\\lambda^{i+1} -= beta^{i} * (\\lambda^{i} - \\lambda^{i-1})` with beta following the formula beta^{i} = min(1, (i/maxIterations)^{conjugateResidueSpeedFactor}) "))
, d_conjugateResidueSpeedFactor(initData(&d_conjugateResidueSpeedFactor,10.0_sreal,"conjugateResidueSpeedFactor","Factor used to modulate the speed in which beta used in the conjugate residue part reaches 1.0. The higher the value, the slower the reach. "))
, d_useConjugateResidual(initData(&d_useConjugateResidual,false,"useConjugateResidual","If set to true, the solution found after each iteration will be corrected along the solution direction using `\\lambda^{i+1} -= beta^{i} * (\\lambda^{i} - \\lambda^{i-1})` with beta following the formula beta^{i} = min(1, (i/maxIterations)^{conjugateResidualSpeedFactor}) "))
, d_conjugateResidualSpeedFactor(initData(&d_conjugateResidualSpeedFactor,10.0_sreal,"conjugateResidualSpeedFactor","Factor used to modulate the speed in which beta used in the conjugate residual part reaches 1.0. The higher the value, the slower the reach. "))
{

}
Expand Down Expand Up @@ -119,7 +119,7 @@ void ImprovedJacobiConstraintSolver::doSolve(GenericConstraintProblem * problem
bool constraintsAreVerified = true;

error=0.0;
SReal beta = d_useConjugateResidue.getValue() * std::min(1.0, pow( ((float)i)/problem->maxIterations,d_conjugateResidueSpeedFactor.getValue()));
SReal beta = d_useConjugateResidual.getValue() * std::min(1.0, pow( ((float)i)/problem->maxIterations,d_conjugateResidualSpeedFactor.getValue()));

for(int j=0; j<dimension; ) // increment of j realized at the end of the loop
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_SOLVER_API ImprovedJacobiConstraintSo

Data<bool> d_useSpectralCorrection;
Data<SReal> d_spectralCorrectionFactor;
Data<bool> d_useConjugateResidue;
Data<SReal> d_conjugateResidueSpeedFactor;
Data<bool> d_useConjugateResidual;
Comment thread
bakpaul marked this conversation as resolved.
Resolved
Data<SReal> d_conjugateResidualSpeedFactor;

ImprovedJacobiConstraintSolver();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,10 @@ void PreconditionedConjugateResidual::doSolve(GenericConstraintProblem * problem
// Unknown update
force.eq(force, p, alpha);

// Residue update
// Residual update
r.eq(r, Wp, -alpha);

// W*residue update
// W*residual update
Wr = MW*r;
const double oldrWr = rWr;
rWr = r.dot(Wr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ StaticEquilibriumIntegrationScheme::StaticEquilibriumIntegrationScheme()
, d_maxNbIterationsLineSearch(initData(&d_maxNbIterationsLineSearch, static_cast<unsigned int>(1), "maxNbIterationsLineSearch", "Maximum number of iteration for the backtracking linesearch algorithm"))
, d_newtonStepSize(initData(&d_newtonStepSize, 1.0_sreal , "newtonStepSize", "Size of the first newton step before the linesearch"))
, d_lineSearchReductionRate(initData(&d_lineSearchReductionRate, 0.5_sreal , "lineSearchReductionRate", "Taken in [0,1[ representing the fraction of diminution of the step done in the backtracking line search (if set to 0.3, the first line search will reduce the step from 1.0 to 0.7)"))
, d_lineSearchArmijoFactor(initData(&d_lineSearchArmijoFactor, 1e-3_sreal , "lineSearchArmijoFactor", "Taken in [0,1[ it represents a tolerance on the residue in term of the linear approximation. e.g., for a value of 0.01, it means we want the solution to decrease the residue as much as 0.01 times the linear approximation in the same direction."))
, d_residueThreshold(initData(&d_residueThreshold, 1e-9_sreal , "residueThreshold", "Threshold under which, the residue is considered to be sufficiently low. Newton algorithm will stop after reaching a lower value"))
, d_currentResidue(initData(&d_currentResidue , "currentResidue", "Current value of the residue"))
, d_lineSearchArmijoFactor(initData(&d_lineSearchArmijoFactor, 1e-3_sreal , "lineSearchArmijoFactor", "Taken in [0,1[ it represents a tolerance on the residual in term of the linear approximation. e.g., for a value of 0.01, it means we want the solution to decrease the residual as much as 0.01 times the linear approximation in the same direction."))
, d_residualThreshold(initData(&d_residualThreshold, 1e-9_sreal , "residualThreshold", "Threshold under which, the residual is considered to be sufficiently low. Newton algorithm will stop after reaching a lower value"))
, d_currentResidual(initData(&d_currentResidual , "currentResidual", "Current value of the residual"))
, d_alwaysAdvanceNewton(initData(&d_alwaysAdvanceNewton , false, "alwaysAdvanceNewton", "Even if the linesearch didn't find a better solution than the current one, take the best one along the path that is not the current guess."))
{ }

Expand Down Expand Up @@ -139,7 +139,7 @@ void StaticEquilibriumIntegrationScheme::integrate(const core::ExecParams* param
const unsigned maxNewtonIt = d_maxNbIterationsNewton.getValue();
const unsigned maxLineSearchIt = d_maxNbIterationsLineSearch.getValue();
const SReal newtonStepSize = d_newtonStepSize.getValue();
const SReal residueThreshold = d_residueThreshold.getValue();
const SReal residualThreshold = d_residualThreshold.getValue();
const SReal lineSearchReductionRate = d_lineSearchReductionRate.getValue();
const SReal lineSearchArmijoFactor = d_lineSearchArmijoFactor.getValue();

Expand All @@ -150,12 +150,12 @@ void StaticEquilibriumIntegrationScheme::integrate(const core::ExecParams* param

//Compute current residual, useful for static solver to return fast
computeRHS(true);
SReal oldResidue = evaluateResidual();
SReal newResidue = evaluateResidual();
SReal oldResidual = evaluateResidual();
SReal newResidual = evaluateResidual();


unsigned it = 0;
while ( it<maxNewtonIt && newResidue>residueThreshold )
while ( it<maxNewtonIt && newResidual>residualThreshold )
{
SCOPED_TIMER_VARNAME(step_timer, "NewtonStep");

Expand All @@ -165,10 +165,10 @@ void StaticEquilibriumIntegrationScheme::integrate(const core::ExecParams* param
if ( ! firstIt )
{
computeRHS(firstIt);
oldResidue = evaluateResidual();
oldResidual = evaluateResidual();
}

double bestresidual = oldResidue;
double bestresidual = oldResidual;
double bestalpha = 0.0;

computeLHS(firstIt);
Expand All @@ -184,24 +184,24 @@ void StaticEquilibriumIntegrationScheme::integrate(const core::ExecParams* param
m_mop->propagateX(xResult); //Need to propagate explicitly to enable recomputation of mapped Forcefield

computeRHS(false);
newResidue = evaluateResidual();
newResidual = evaluateResidual();

// Compute the Armijo term
// !! Careful this approximation holds only when A is symmetric
// This comes from the fact that if the current residual is f=||r||**2 and the search
// direction results from Ap = -r, then we have \nabla f = 2*A*r, so the armijo factor can be
// simplified with \nabla f * p = 2*r^T*A^T*A^{-1}*(-r) = -2*||r||^2 if A is symmetric
// Otherwise we need to compute 2 * r^{t} * A^{T} * p
const SReal armijoTerm = - 2 * lineSearchArmijoFactor * oldResidue;
const SReal armijoTerm = - 2 * lineSearchArmijoFactor * oldResidual;

if (newResidue<bestresidual || d_alwaysAdvanceNewton.getValue())
if (newResidual<bestresidual || d_alwaysAdvanceNewton.getValue())
{
bestresidual = newResidue;
bestresidual = newResidual;
bestalpha = alpha;
}

unsigned lineSearchIt = 0;
while ((newResidue>(oldResidue + alpha*armijoTerm)) && lineSearchIt<maxLineSearchIt )
while ((newResidual>(oldResidual + alpha*armijoTerm)) && lineSearchIt<maxLineSearchIt )
{
//We are backtracking on the same line. Instead of starting from initial position and
//adding alpha each time, we go back toward the initial position
Expand All @@ -212,11 +212,11 @@ void StaticEquilibriumIntegrationScheme::integrate(const core::ExecParams* param
m_mop->propagateX(xResult); //Need to propagate explicitly to enable recomputation of mapped Forcefield

computeRHS(false);
newResidue = evaluateResidual();
newResidual = evaluateResidual();

if (newResidue<bestresidual)
if (newResidual<bestresidual)
{
bestresidual = newResidue;
bestresidual = newResidual;
bestalpha = alpha;
}

Expand All @@ -229,38 +229,38 @@ void StaticEquilibriumIntegrationScheme::integrate(const core::ExecParams* param
m_mop->propagateX(xResult); //Need to propagate explicitly to enable recomputation of mapped Forcefileld

computeRHS(false);
newResidue = evaluateResidual();
newResidual = evaluateResidual();
}


if (printLog)
{
if (newResidue>oldResidue)
if (newResidual>oldResidual)
{
msg_warning()<<"Newton step increased the residual";
}
msg_info()<<"Newton step = "<<it;
msg_info()<<"Current residue = "<<newResidue<< " | previous residue = "<<oldResidue ;
msg_info()<<"Current residual = "<<newResidual<< " | previous residual = "<<oldResidual ;
msg_info()<<"Number of line search iterations = "<<lineSearchIt;
}
++it ;
}
if (printLog)
{
if (newResidue<residueThreshold)
if (newResidual<residualThreshold)
{
msg_info()<<"Newton converged to residue "<<newResidue<<" in "<<it<<" steps.";
msg_info()<<"Newton converged to residual "<<newResidual<<" in "<<it<<" steps.";
}
else
{
msg_warning()<<"Newton didn't converge ! Current residue is "<<newResidue;
msg_warning()<<"Newton didn't converge ! Current residual is "<<newResidual;
}
}

sofa::helper::AdvancedTimer::valSet("nb_iterations", it);
sofa::helper::AdvancedTimer::valSet("residual", std::sqrt(newResidue));
sofa::helper::AdvancedTimer::valSet("residual", std::sqrt(newResidual));

d_currentResidue.setValue(newResidue);
d_currentResidual.setValue(newResidual);


}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ class SOFA_COMPONENT_INTEGRATIONSCHEME_BACKWARD_API StaticEquilibriumIntegration
Data<SReal> d_newtonStepSize;
Data<SReal> d_lineSearchReductionRate;
Data<SReal> d_lineSearchArmijoFactor;
Data<SReal> d_residueThreshold;
Data<SReal> d_currentResidue;
Data<SReal> d_residualThreshold;
Data<SReal> d_currentResidual;
Data<bool> d_alwaysAdvanceNewton;

protected:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ static constexpr SReal l = youngModulus * poissonRatio / ((1.0 + poissonRatio) *
* StaticSolver, with a choice of pluggable convergence measures (relative-to-initial,
* estimate-difference, ...) and a per-iteration residual history (d_residualGraph). After the
* refactoring, that logic lives directly in StaticEquilibriumIntegrationScheme, with a single
* residual-based stopping criterion (d_residueThreshold) and no per-iteration history exposed:
* only the final residual (d_currentResidue) can be inspected. So only the scenario that maps
* residual-based stopping criterion (d_residualThreshold) and no per-iteration history exposed:
* only the final residual (d_currentResidual) can be inspected. So only the scenario that maps
* cleanly onto the new API is kept here (force exactly d_maxNbIterationsNewton iterations and
* check the final residual); the former RelativeResiduals/AbsoluteResiduals cases exercised
* convergence criteria that no longer exist.
Expand Down Expand Up @@ -112,7 +112,7 @@ class StaticEquilibriumIntegrationSchemeTest : public sofa::testing::BaseTest
auto execute() -> SReal {
sofa::simulation::node::initRoot(root.get());
sofa::simulation::node::animate(root.get(), 1_sreal);
return std::sqrt(staticSolver->d_currentResidue.getValue());
return std::sqrt(staticSolver->d_currentResidual.getValue());
}


Expand All @@ -126,7 +126,7 @@ TEST_F(StaticEquilibriumIntegrationSchemeTest, Residuals) {
const SReal expected_force_residual_norm = 1.2283305451908398e-05;

staticSolver->d_maxNbIterationsNewton.setValue(10);
staticSolver->d_residueThreshold.setValue(0.0_sreal);
staticSolver->d_residualThreshold.setValue(0.0_sreal);

const SReal actual_force_residual_norm = this->execute();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,16 @@ void ArticulatedHierarchyBVHController::applyController(void)

frame = (int)(floor(externalTime.getValue() / ahc->dtbvh));

const double residu = (externalTime.getValue() / ahc->dtbvh) - (double) frame;
const double residual = (externalTime.getValue() / ahc->dtbvh) - (double) frame;

msg_info() << "externalTime.getValue() = "<<externalTime.getValue() <<" frame= "<<frame<<" residu = "<<residu ;
msg_info() << "externalTime.getValue() = "<<externalTime.getValue() <<" frame= "<<frame<<" residual = "<<residual ;

if(frame > ahc->numOfFrames-2)
{
frame = ahc->numOfFrames-2;
}

alpha = residu;
alpha = residual;
}
else
{
Expand Down
Loading