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

Commit c4e5102

Browse files
rfrankeOpenModelica-Hudson
authored andcommitted
Reuse factors of linear equation systems during Jacobian evaluation
Belonging to [master]: - #2261
1 parent e3f5017 commit c4e5102

File tree

3 files changed

+48
-25
lines changed

3 files changed

+48
-25
lines changed

Compiler/Template/CodegenCpp.tpl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13052,11 +13052,12 @@ case _ then
1305213052
let jacvals = if stringEq(eqsCount, "0") then '' else
1305313053
(sparsepattern |> (index,indexes) hasindex index0 =>
1305413054
let jaccol = ( indexes |> i_index hasindex index1 =>
13055-
(match indexColumn case "1" then '_<%matrixName%>jacobian(0,<%index%>) = _<%matrixName%>jac_y(0);/*test1<%index0%>,<%index1%>*/'
13056-
else '_<%matrixName%>jacobian(<%i_index%>,<%index%>) = _<%matrixName%>jac_y(<%i_index%>);/*test2<%index0%>,<%index1%>*/'
13055+
(match indexColumn case "1" then '_<%matrixName%>jacobian(0,<%index%>) = _<%matrixName%>jac_y(0);'
13056+
else '_<%matrixName%>jacobian(<%i_index%>,<%index%>) = _<%matrixName%>jac_y(<%i_index%>);'
1305713057
)
1305813058
;separator="\n")
1305913059
<<
13060+
<%if intEq(index0, 1) then 'SystemLockFreeVariables slfv(this);'%>
1306013061
_<%matrixName%>jac_x(<%index0%>) = 1;
1306113062
calc<%matrixName%>JacobianColumn();
1306213063
_<%matrixName%>jac_x.clear();

SimulationRuntime/cpp/Include/Solver/LinearSolver/LinearSolver.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ class LinearSolver : public IAlgLoopSolver
4242
_dimSys; ///< Temp - Number of unknowns (=dimension of system of equations)
4343

4444
bool
45-
_firstCall; ///< Temp - Denotes the first call to the solver, init() is called
45+
_firstCall, ///< Temp - Denotes the first call to the solver, init() is called
46+
_hasDgesvFactors, ///< =true if dgesv was called previously
47+
_hasDgetc2Factors; ///< =true if dgetc2 was called previously
4648

4749
long int *_ihelpArray, //pivot indices for lapackroutine
4850
*_jhelpArray; //pivot indices for lapackroutine

SimulationRuntime/cpp/Solver/LinearSolver/LinearSolver.cpp

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ LinearSolver::LinearSolver(ILinearAlgLoop* algLoop, ILinSolverSettings* settings
4040

4141
, _iterationStatus (CONTINUE)
4242
, _firstCall (true)
43+
, _hasDgesvFactors (false)
44+
, _hasDgetc2Factors (false)
4345
, _scale (NULL)
4446
, _generateoutput (false)
4547
, _fNominal (NULL)
@@ -198,27 +200,31 @@ void LinearSolver::solve()
198200
//if !_sparse, we use LAPACK routines, otherwise we use KLU to solve the linear system
199201
if (!_sparse) {
200202
//use lapack
201-
long int dimRHS = 1; // Dimension of right hand side of linear system (=_b)
202-
long int irtrn = 0; // Return-flag of Fortran code
203-
204-
const matrix_t& A = _algLoop->getAMatrix();
205-
const double* Atemp = A.data().begin();
206-
207-
memcpy(_A, Atemp, _dimSys*_dimSys*sizeof(double));
208-
209-
// scale Jacobian
210-
std::fill(_fNominal, _fNominal + _dimSys, 1e-6);
211-
for (int j = 0, idx = 0; j < _dimSys; j++) {
212-
for (int i = 0; i < _dimSys; i++, idx++) {
213-
_fNominal[i] = std::max(std::abs(Atemp[idx]), _fNominal[i]);
203+
long int dimRHS = 1; // Dimension of right hand side of linear system (=_b)
204+
long int info = 0; // Return-flag of Fortran code
205+
206+
if (!_algLoop->getFreeVariablesLock()) {
207+
const matrix_t& A = _algLoop->getAMatrix();
208+
const double* Atemp = A.data().begin();
209+
210+
memcpy(_A, Atemp, _dimSys*_dimSys*sizeof(double));
211+
_hasDgesvFactors = false;
212+
_hasDgetc2Factors = false;
213+
214+
// scale Jacobian
215+
std::fill(_fNominal, _fNominal + _dimSys, 1e-6);
216+
for (int j = 0, idx = 0; j < _dimSys; j++) {
217+
for (int i = 0; i < _dimSys; i++, idx++) {
218+
_fNominal[i] = std::max(std::abs(Atemp[idx]), _fNominal[i]);
219+
}
214220
}
215-
}
216221

217-
LOGGER_WRITE_VECTOR("fNominal", _fNominal, _dimSys, LC_LS, LL_DEBUG);
222+
LOGGER_WRITE_VECTOR("fNominal", _fNominal, _dimSys, LC_LS, LL_DEBUG);
218223

219-
for (int j = 0, idx = 0; j < _dimSys; j++)
220-
for (int i = 0; i < _dimSys; i++, idx++)
221-
_A[idx] /= _fNominal[i];
224+
for (int j = 0, idx = 0; j < _dimSys; j++)
225+
for (int i = 0; i < _dimSys; i++, idx++)
226+
_A[idx] /= _fNominal[i];
227+
}
222228

223229
for (int i = 0; i < _dimSys; i++)
224230
_b[i] /= _fNominal[i];
@@ -228,7 +234,7 @@ void LinearSolver::solve()
228234
std::cout << "We solve a linear system with coefficient matrix" << std::endl;
229235
for (int i=0; i<_dimSys; i++) {
230236
for (int j=0; j<_dimSys; j++) {
231-
std::cout << Atemp[i+j*_dimSys] << " ";
237+
std::cout << _A[i+j*_dimSys] << " ";
232238
}
233239
std::cout << std::endl;
234240
}
@@ -239,11 +245,25 @@ void LinearSolver::solve()
239245
std::cout << std::endl;
240246
}
241247

242-
dgesv_(&_dimSys, &dimRHS, _A, &_dimSys, _ihelpArray, _b, &_dimSys, &irtrn);
248+
if (!_hasDgesvFactors && !_hasDgetc2Factors) {
249+
dgesv_(&_dimSys, &dimRHS, _A, &_dimSys, _ihelpArray, _b, &_dimSys, &info);
250+
_hasDgesvFactors = true;
251+
}
252+
else if (_hasDgesvFactors) {
253+
// solve using previously obtained dgesv factors
254+
char trans = 'N';
255+
dgetrs_(&trans, &_dimSys, &dimRHS, _A, &_dimSys, _ihelpArray, _b, &_dimSys, &info);
256+
}
257+
else {
258+
// solve using previously obtained dgetc2 factors
259+
dgesc2_(&_dimSys, _A, &_dimSys, _b, _ihelpArray, _jhelpArray, _scale);
260+
info = 0;
261+
}
243262

244-
if (irtrn != 0) {
245-
dgetc2_(&_dimSys, _A, &_dimSys, _ihelpArray, _jhelpArray, &irtrn);
263+
if (info != 0) {
264+
dgetc2_(&_dimSys, _A, &_dimSys, _ihelpArray, _jhelpArray, &info);
246265
dgesc2_(&_dimSys, _A, &_dimSys, _b, _ihelpArray, _jhelpArray, _scale);
266+
_hasDgetc2Factors = true;
247267
LOGGER_WRITE("LinearSolver: Linear system singular, using perturbed system matrix.", LC_LS, LL_DEBUG);
248268
_iterationStatus = DONE;
249269
}

0 commit comments

Comments
 (0)