@@ -213,8 +213,7 @@ void Newton::solve()
213213 LOG_VEC (_algLoop, " y" + to_string (totSteps), _y, _lc, LL_DEBUG);
214214 LOG_VEC (_algLoop, " f" + to_string (totSteps), _f, _lc, LL_DEBUG);
215215
216- calcJacobian (true );
217- LOG_VEC (_algLoop, " fNominal" + to_string (totSteps), _fNominal, _lc, LL_DEBUG);
216+ calcJacobian (_jac, _fNominal);
218217
219218 // check stopping criterion
220219 _iterationStatus = DONE;
@@ -375,24 +374,30 @@ void Newton::stepCompleted(double time)
375374
376375}
377376
378- void Newton::calcJacobian (bool getSymbolicJac )
377+ void Newton::calcJacobian (double *jac, double * fNominal )
379378{
380- const double *jac = NULL ;
381- std::fill (_fNominal, _fNominal + _dimSys, _newtonSettings->getAtol ());
379+ const double *Adata = NULL ;
380+ std::fill (fNominal , fNominal + _dimSys, _newtonSettings->getAtol ());
382381 // Use analytic Jacobian if available
383- if (getSymbolicJac) {
382+ try {
384383 matrix_t A = _algLoop->getSystemMatrix ();
385384 if (A.size1 () == _dimSys && A.size2 () == _dimSys) {
386- jac = A.data ().begin ();
387- std::copy (jac, jac + _dimSys* _dimSys, _jac );
388- for (int i = 0 ; i < _dimSys; i ++)
389- for (int j = 0 , idx = i; j < _dimSys; j ++, idx += _dimSys )
390- _fNominal [i] = std::max (std::abs (_jac [idx]) * _yNominal[j], _fNominal [i]);
385+ Adata = A.data ().begin ();
386+ std::copy (Adata, Adata + _dimSys * _dimSys, jac );
387+ for (int j = 0 , idx = 0 ; j < _dimSys; j ++)
388+ for (int i = 0 ; i < _dimSys; i ++, idx++ )
389+ fNominal [i] = std::max (std::abs (jac [idx]) * _yNominal[j], fNominal [i]);
391390 }
392391 }
392+ catch (ModelicaSimulationError& ex) {
393+ LOGGER_WRITE (" Analytic Jacobian failed for eq" +
394+ to_string (_algLoop->getEquationIndex ()) + " at time " +
395+ to_string (_algLoop->getSimTime ()) + " : " + ex.what (),
396+ _lc, LL_WARNING);
397+ }
393398 // Alternatively apply finite differences
394- if (jac == NULL ) {
395- for (int j = 0 ; j < _dimSys; ++j ) {
399+ if (Adata == NULL ) {
400+ for (int j = 0 ; j < _dimSys; j++ ) {
396401 // Reset variables for every column
397402 std::copy (_y, _y + _dimSys, _yHelp);
398403 double stepsize = 100.0 * _newtonSettings->getRtol () * _yNominal[j];
@@ -404,13 +409,14 @@ void Newton::calcJacobian(bool getSymbolicJac)
404409
405410 // Build Jacobian in Fortran format
406411 for (int i = 0 , idx = j * _dimSys; i < _dimSys; i++, idx++) {
407- _jac [idx] = (_fHelp[i] - _f[i]) / stepsize;
408- _fNominal [i] = std::max (std::abs (_jac [idx]) * _yNominal[j], _fNominal [i]);
412+ jac [idx] = (_fHelp[i] - _f[i]) / stepsize;
413+ fNominal [i] = std::max (std::abs (jac [idx]) * _yNominal[j], fNominal [i]);
409414 }
410415
411416 _yHelp[j] -= stepsize;
412417 }
413418 }
419+ LOG_VEC (_algLoop, " fNominal" , fNominal , _lc, LL_DEBUG);
414420}
415421
416422void Newton::restoreOldValues ()
0 commit comments