Try to re-solve groups that fail rank test.
Sometimes, after a large change in a sketch, constraints that are
geometrically fine may still cause the rank test to fail. One way
this can happen is VectorsParallel() pivoting wrong due to the big
move, converging anyways but ending up singular. It would then
re-pivot correctly on the new solution when you re-solve, making
this a transient error. This is visible when dragging the arm in
the jansen-asm.slvs example.
After this commit, if the rank test fails, equations are regenerated
the Jacobian is rewritten, and the rank test is retried, which
prevents these transient errors from interfering with dragging.
The problem described above was invisible before c011444
, as rank
test was only performed before solving.
This commit is contained in:
parent
bc43365eff
commit
05d9c0fab9
|
@ -308,7 +308,7 @@ void SolveSpaceUI::GenerateAll(GenerateType type, bool andFindFree, bool genForB
|
|||
// The group falls inside the range, so really solve it,
|
||||
// and then regenerate the mesh based on the solved stuff.
|
||||
if(genForBBox) {
|
||||
SolveGroup(g->h, andFindFree);
|
||||
SolveGroupAndReport(g->h, andFindFree);
|
||||
} else {
|
||||
g->GenerateLoops();
|
||||
g->GenerateShellAndMesh();
|
||||
|
@ -491,6 +491,23 @@ void SolveSpaceUI::MarkDraggedParams(void) {
|
|||
}
|
||||
}
|
||||
|
||||
void SolveSpaceUI::SolveGroupAndReport(hGroup hg, bool andFindFree) {
|
||||
SolveGroup(hg, andFindFree);
|
||||
|
||||
Group *g = SK.GetGroup(hg);
|
||||
if(g->solved.how == System::REDUNDANT_OKAY) {
|
||||
// Solve again, in case we lost a degree of freedom because of a numeric error.
|
||||
SolveGroup(hg, andFindFree);
|
||||
}
|
||||
|
||||
bool isOkay = g->solved.how == System::SOLVED_OKAY ||
|
||||
(g->allowRedundant && g->solved.how == System::REDUNDANT_OKAY);
|
||||
|
||||
if(!isOkay || (isOkay && !g->IsSolvedOkay())) {
|
||||
TextWindow::ReportHowGroupSolved(g->h);
|
||||
}
|
||||
}
|
||||
|
||||
void SolveSpaceUI::SolveGroup(hGroup hg, bool andFindFree) {
|
||||
int i;
|
||||
// Clear out the system to be solved.
|
||||
|
@ -518,12 +535,6 @@ void SolveSpaceUI::SolveGroup(hGroup hg, bool andFindFree) {
|
|||
g->solved.remove.Clear();
|
||||
int how = sys.Solve(g, &(g->solved.dof),
|
||||
&(g->solved.remove), true, andFindFree);
|
||||
bool isOkay = how == System::SOLVED_OKAY ||
|
||||
(g->allowRedundant && how == System::REDUNDANT_OKAY);
|
||||
if(!isOkay || (isOkay && !g->IsSolvedOkay()))
|
||||
{
|
||||
TextWindow::ReportHowGroupSolved(g->h);
|
||||
}
|
||||
g->solved.how = how;
|
||||
FreeAllTemporary();
|
||||
}
|
||||
|
|
|
@ -912,6 +912,7 @@ public:
|
|||
void GenerateAll(GenerateType type = GENERATE_DIRTY, bool andFindFree = false,
|
||||
bool genForBBox = false);
|
||||
void SolveGroup(hGroup hg, bool andFindFree);
|
||||
void SolveGroupAndReport(hGroup hg, bool andFindFree);
|
||||
void MarkDraggedParams(void);
|
||||
void ForceReferences(void);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user