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

Commit ba5ff89

Browse files
rfrankeOpenModelica-Hudson
authored andcommitted
Apply complete pivoting to singular linear systems in FMUs, ticket:4747
Call LAPACK routines dgetc2 and dgesc2 in case of singularity. Belonging to [master]: - #2205 - OpenModelica/OMCompiler-3rdParty#28
1 parent fcdc6b2 commit ba5ff89

File tree

2 files changed

+30
-21
lines changed

2 files changed

+30
-21
lines changed

SimulationRuntime/cpp/Include/Solver/Dgesv/DgesvSolver.h

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ class DgesvSolver : public IAlgLoopSolver
2222
virtual void restoreOldValues();
2323
virtual void restoreNewValues();
2424

25-
26-
2725
private:
2826
// Member variables
2927
//---------------------------------------------------------------
@@ -35,24 +33,24 @@ class DgesvSolver : public IAlgLoopSolver
3533
_iterationStatus; ///< Output - Denotes the status of iteration
3634

3735
long int
38-
_dimSys; ///< Temp - Number of unknowns (=dimension of system of equations)
36+
_dimSys, ///< Number of unknowns (=dimension of system of equations)
37+
*_iHelp, ///< Pivot indices for LAPACK routines
38+
*_jHelp; ///< Pivot indices for LAPACK routines
3939

4040
bool
4141
_firstCall; ///< Temp - Denotes the first call to the solver, init() is called
4242

43-
long int *_ihelpArray; //pivot indices for lapackroutine
44-
4543
const char*
4644
*_yNames; ///< Names of variables
4745
double
4846
*_yNominal, ///< Nominal values of variables
4947
*_y, ///< Temp - Unknowns
5048
*_y0, ///< Temp - Auxillary variables
51-
*_y_old, //stores old solution
52-
*_y_new, //stores new solution
53-
*_b, ///< right hand side
54-
*_A, ///coefficients of linear system
55-
*_zeroVec, ///zero vector
49+
*_y_old, ///< Temp - Stores old solution
50+
*_y_new, ///< Temp - Stores new solution
51+
*_b, ///< Right hand side
52+
*_A, ///< Coefficients of linear system
53+
*_zeroVec, ///< Zero vector
5654
*_fNominal;
5755
};
5856
/** @} */ // end of solverLinearSolver

SimulationRuntime/cpp/Solver/Dgesv/DgesvSolver.cpp

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ DgesvSolver::DgesvSolver(ILinearAlgLoop* algLoop, ILinSolverSettings* settings)
2727
, _y_new (NULL)
2828
, _b (NULL)
2929
, _A (NULL)
30-
, _ihelpArray (NULL)
30+
, _iHelp (NULL)
31+
, _jHelp (NULL)
3132
, _zeroVec (NULL)
3233
, _iterationStatus (CONTINUE)
3334
, _firstCall (true)
@@ -45,7 +46,8 @@ DgesvSolver::~DgesvSolver()
4546
if (_y_new) delete [] _y_new;
4647
if (_b) delete [] _b;
4748
if (_A) delete [] _A;
48-
if (_ihelpArray) delete [] _ihelpArray;
49+
if (_iHelp) delete [] _iHelp;
50+
if (_jHelp) delete [] _jHelp;
4951
if (_zeroVec) delete [] _zeroVec;
5052
if (_fNominal) delete [] _fNominal;
5153
}
@@ -72,7 +74,8 @@ void DgesvSolver::initialize()
7274
if (_y_new) delete [] _y_new;
7375
if (_b) delete [] _b;
7476
if (_A) delete [] _A;
75-
if (_ihelpArray) delete [] _ihelpArray;
77+
if (_iHelp) delete [] _iHelp;
78+
if (_jHelp) delete [] _jHelp;
7679
if (_zeroVec) delete [] _zeroVec;
7780
if (_fNominal) delete [] _fNominal;
7881

@@ -84,7 +87,8 @@ void DgesvSolver::initialize()
8487
_y_new = new double[_dimSys];
8588
_b = new double[_dimSys];
8689
_A = new double[_dimSys*_dimSys];
87-
_ihelpArray = new long int[_dimSys];
90+
_iHelp = new long int[_dimSys];
91+
_jHelp = new long int[_dimSys];
8892
_zeroVec = new double[_dimSys];
8993
_fNominal = new double[_dimSys];
9094

@@ -95,7 +99,8 @@ void DgesvSolver::initialize()
9599
_algLoop->getReal(_y_new);
96100
_algLoop->getReal(_y_old);
97101
memset(_b, 0, _dimSys*sizeof(double));
98-
memset(_ihelpArray, 0, _dimSys*sizeof(long int));
102+
memset(_iHelp, 0, _dimSys*sizeof(long int));
103+
memset(_jHelp, 0, _dimSys*sizeof(long int));
99104
memset(_A, 0, _dimSys*_dimSys*sizeof(double));
100105
memset(_zeroVec, 0, _dimSys*sizeof(double));
101106
}
@@ -152,25 +157,31 @@ void DgesvSolver::solve()
152157
for (int i = 0; i < _dimSys; i++)
153158
_b[i] /= _fNominal[i];
154159

155-
dgesv_(&_dimSys,&dimRHS,_A,&_dimSys,_ihelpArray,_b,&_dimSys,&irtrn);
160+
dgesv_(&_dimSys, &dimRHS, _A, &_dimSys, _iHelp, _b, &_dimSys, &irtrn);
156161

157-
if (irtrn != 0) {
162+
if (irtrn > 0) {
163+
long int info = 0;
164+
double scale = 0.0;
165+
dgetc2_(&_dimSys, _A, &_dimSys, _iHelp, _jHelp, &info);
166+
dgesc2_(&_dimSys, _A, &_dimSys, _b, _iHelp, _jHelp, &scale);
167+
LOGGER_WRITE("DgesvSolver: using complete pivoting (dgesv info: " + to_string(irtrn) + ", dgesc2 scale: " + to_string(scale) + ")", LC_LS, LL_DEBUG);
168+
}
169+
else if (irtrn < 0) {
170+
_iterationStatus = SOLVERERROR;
158171
if (_algLoop->isLinearTearing())
159172
throw ModelicaSimulationError(ALGLOOP_SOLVER, "error solving linear tearing system (dgesv info: " + to_string(irtrn) + ")");
160173
else
161174
throw ModelicaSimulationError(ALGLOOP_SOLVER, "error solving linear system (dgesv info: " + to_string(irtrn) + ")");
162175
}
163-
else
164-
_iterationStatus = DONE;
165-
176+
_iterationStatus = DONE;
166177

167178
//we need to revert the sign of y, because the sign of b was changed before.
168179
if (_algLoop->isLinearTearing()) {
169180
for (int i = 0; i < _dimSys; i++)
170181
_y[i] = -_b[i];
171182
}
172183
else {
173-
memcpy(_y,_b,_dimSys*sizeof(double));
184+
memcpy(_y, _b, _dimSys*sizeof(double));
174185
}
175186

176187
_algLoop->setReal(_y);

0 commit comments

Comments
 (0)