1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 // File: PlaneGCSSolver_Solver.cpp
4 // Created: 14 Dec 2014
5 // Author: Artem ZHIDKOV
7 #include <PlaneGCSSolver_Solver.h>
8 #include <Events_LongOp.h>
11 PlaneGCSSolver_Solver::PlaneGCSSolver_Solver()
12 : myEquationSystem(new GCS::System),
13 myDiagnoseBeforeSolve(false),
15 myConfCollected(false),
20 PlaneGCSSolver_Solver::~PlaneGCSSolver_Solver()
25 void PlaneGCSSolver_Solver::clear()
27 myEquationSystem->clear();
29 myConstraints.clear();
30 myConflictingIDs.clear();
34 void PlaneGCSSolver_Solver::addConstraint(GCSConstraintPtr theConstraint)
36 myEquationSystem->addConstraint(theConstraint.get());
37 myConstraints[theConstraint->getTag()].insert(theConstraint);
38 if (theConstraint->getTag() >= 0)
42 void PlaneGCSSolver_Solver::removeConstraint(ConstraintID theID)
44 myConstraints.erase(theID);
45 if (myConstraints.empty()) {
46 myEquationSystem->clear();
47 myDOF = (int)myParameters.size();
49 myEquationSystem->clearByTag(theID);
55 double* PlaneGCSSolver_Solver::createParameter()
57 double* aResult = new double(0);
58 myParameters.push_back(aResult);
59 if (myConstraints.empty() && myDOF >= 0)
60 ++myDOF; // calculate DoF by hand if and only if there is no constraints yet
62 myDiagnoseBeforeSolve = true;
66 void PlaneGCSSolver_Solver::addParameters(const GCS::SET_pD& theParams)
68 GCS::SET_pD aParams(theParams);
69 // leave new parameters only
70 GCS::VEC_pD::iterator anIt = myParameters.begin();
71 for (; anIt != myParameters.end(); ++anIt)
72 if (aParams.find(*anIt) != aParams.end())
75 myParameters.insert(myParameters.end(), aParams.begin(), aParams.end());
76 if (myConstraints.empty() && myDOF >=0)
77 myDOF += (int)aParams.size(); // calculate DoF by hand if and only if there is no constraints yet
79 myDiagnoseBeforeSolve = true;
82 void PlaneGCSSolver_Solver::removeParameters(const GCS::SET_pD& theParams)
84 for (int i = (int)myParameters.size() - 1; i >= 0; --i)
85 if (theParams.find(myParameters[i]) != theParams.end()) {
86 myParameters.erase(myParameters.begin() + i);
89 if (!myConstraints.empty())
90 myDiagnoseBeforeSolve = true;
93 void PlaneGCSSolver_Solver::initialize()
95 Events_LongOp::start(this);
96 if (myDiagnoseBeforeSolve)
98 myEquationSystem->declareUnknowns(myParameters);
99 myEquationSystem->initSolution();
100 Events_LongOp::end(this);
105 PlaneGCSSolver_Solver::SolveStatus PlaneGCSSolver_Solver::solve()
107 // clear list of conflicting constraints
108 if (myConfCollected) {
109 myConflictingIDs.clear();
110 myConfCollected = false;
113 if (myParameters.empty())
114 return STATUS_INCONSISTENT;
116 GCS::SolveStatus aResult = GCS::Success;
117 Events_LongOp::start(this);
119 aResult = (GCS::SolveStatus)myEquationSystem->solve();
121 if (myDiagnoseBeforeSolve)
123 aResult = (GCS::SolveStatus)myEquationSystem->solve(myParameters);
125 Events_LongOp::end(this);
127 // collect information about conflicting constraints every time,
128 // sometimes solver reports about succeeded recalculation but has conflicting constraints
129 // (for example, apply horizontal constraint for a copied feature)
130 collectConflicting();
131 if (!myConflictingIDs.empty())
132 aResult = GCS::Failed;
135 if (aResult == GCS::Failed)
136 aStatus = STATUS_FAILED;
138 myEquationSystem->applySolution();
140 myDOF = myEquationSystem->dofsNumber();
144 myInitilized = false;
148 void PlaneGCSSolver_Solver::undo()
150 myEquationSystem->undoSolution();
153 bool PlaneGCSSolver_Solver::isConflicting(const ConstraintID& theConstraint) const
155 if (!myConfCollected)
156 const_cast<PlaneGCSSolver_Solver*>(this)->collectConflicting();
157 return myConflictingIDs.find((int)theConstraint) != myConflictingIDs.end();
160 void PlaneGCSSolver_Solver::collectConflicting()
162 GCS::VEC_I aConflict;
163 myEquationSystem->getConflicting(aConflict);
164 myConflictingIDs.insert(aConflict.begin(), aConflict.end());
166 myEquationSystem->getRedundant(aConflict);
167 myConflictingIDs.insert(aConflict.begin(), aConflict.end());
169 myConfCollected = true;
172 int PlaneGCSSolver_Solver::dof()
174 if (myDOF < 0 && !myConstraints.empty())
179 void PlaneGCSSolver_Solver::diagnose()
181 myEquationSystem->declareUnknowns(myParameters);
182 myDOF = myEquationSystem->diagnose();
183 myDiagnoseBeforeSolve = false;