Skip to content
This repository was archived by the owner on May 18, 2019. It is now read-only.

Commit d633a30

Browse files
qichenghuaOpenModelica-Hudson
authored andcommitted
added variation of initial guesses in nonlinear solver.
1 parent e133834 commit d633a30

File tree

2 files changed

+53
-2
lines changed
  • SimulationRuntime/cpp

2 files changed

+53
-2
lines changed

SimulationRuntime/cpp/Include/Solver/Nox/Nox.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ class Nox : public IAlgLoopSolver
4242
bool isdivisionbyzeroerror(const std::exception &ex);
4343
void modifySolverParameters(const Teuchos::RCP<Teuchos::ParameterList> solverParametersPtr,const int iter);
4444

45+
bool modify_y(const int counter);
46+
void BinRep(std::vector<double> &result, const int number);
4547

4648
//void check4EventRetry(double* y)
4749

SimulationRuntime/cpp/Solver/Nox/Nox.cpp

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,22 @@ void Nox::solve()
159159
}
160160
}
161161

162-
162+
if(BasicNLSsolve()==NOX::StatusTest::Converged){
163+
_iterationStatus=DONE;
164+
return;
165+
}
166+
167+
168+
int VaryInitGuess=0;
169+
while((_iterationStatus==CONTINUE) && (VaryInitGuess<std::pow(2,_dimSys))){
170+
modify_y(VaryInitGuess);
171+
if(BasicNLSsolve()==NOX::StatusTest::Converged){
172+
_iterationStatus=DONE;
173+
return;
174+
}
175+
VaryInitGuess++;
176+
}
177+
memcpy(_y,_y0,_dimSys*sizeof(double));
163178

164179
if (_generateoutput) std::cout << "starting while loop" << std::endl;
165180

@@ -522,7 +537,7 @@ NOX::StatusTest::StatusType Nox::BasicNLSsolve(){
522537
{
523538
throw ModelicaSimulationError(ALGLOOP_SOLVER,"solving error in Algloop " + std::to_string(_algLoop->getEquationIndex()) + " at simtime " + std::to_string(_algLoop->getSimTime()) + ", with error message: " + ex.what());
524539
}
525-
return status;
540+
return status;
526541
}
527542

528543
void Nox::modifySolverParameters(const Teuchos::RCP<Teuchos::ParameterList> solverParametersPtr,const int iter){
@@ -760,6 +775,40 @@ void Nox::divisionbyzerohandling(double const * const y0){
760775
}
761776
}
762777

778+
void Nox::BinRep(std::vector<double> &result, const int number){
779+
if (number > std::pow(2.0,static_cast<double>(result.size()))-1.0) throw std::range_error("Binary representation out of range");
780+
for(unsigned int i=0;i<result.size();i++)
781+
{
782+
result[i]=static_cast<int>(number/std::floor(std::pow(2.0,static_cast<double>(i))))%2;
783+
}
784+
}
785+
786+
bool Nox::modify_y(const int counter){
787+
std::vector<double> startvaluemodifier(_dimSys);
788+
789+
memcpy(_y,_y0,_dimSys*sizeof(double));
790+
791+
BinRep(startvaluemodifier,counter);
792+
793+
//replace 0 by -1.
794+
std::for_each(startvaluemodifier.begin(),startvaluemodifier.end(), [](double d){return (d==0.0) ? -1.0 : d;});
795+
796+
std::cout << "Varying initial guess by 10%:" << std::endl;
797+
for (int i=0;i<_dimSys;i++){
798+
_y[i] += (_y[i]!=0.0) ? 0.1*_y[i]*startvaluemodifier[i] : 0.1*startvaluemodifier[i];
799+
}
800+
801+
_algLoop->setReal(_y);
802+
try{
803+
_algLoop->evaluate();
804+
return true;
805+
}
806+
catch(const std::exception &ex){
807+
std::cout << ex.what() << " Error occured when varying initial guess." << std::endl;
808+
}
809+
return false;
810+
}
811+
763812
//writes output
764813
void Nox::printLogger(){
765814
if(!((dynamic_cast<const std::stringstream &>(*_output)).str().empty())){

0 commit comments

Comments
 (0)