@@ -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