OMCompiler/SimulationRuntime/cpp/Solver/IDA/IDA.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * This file belongs to the OpenModelica Run-Time System | ||
| 3 | * | ||
| 4 | * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC), c/o Linköpings | ||
| 5 | * universitet, Department of Computer and Information Science, SE-58183 Linköping, Sweden. All rights | ||
| 6 | * reserved. | ||
| 7 | * | ||
| 8 | * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF THE BSD NEW LICENSE OR THE | ||
| 9 | * AGPL VERSION 3 LICENSE OR THE OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8. ANY | ||
| 10 | * USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES RECIPIENT'S | ||
| 11 | * ACCEPTANCE OF THE BSD NEW LICENSE OR THE OSMC PUBLIC LICENSE OR THE AGPL | ||
| 12 | * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. | ||
| 13 | * | ||
| 14 | * The OpenModelica software and the OSMC (Open Source Modelica Consortium) Public License | ||
| 15 | * (OSMC-PL) are obtained from OSMC, either from the above address, from the URLs: | ||
| 16 | * http://www.openmodelica.org or https://github.com/OpenModelica/ or | ||
| 17 | * http://www.ida.liu.se/projects/OpenModelica, and in the OpenModelica distribution. GNU | ||
| 18 | * AGPL version 3 is obtained from: https://www.gnu.org/licenses/licenses.html#GPL. The BSD NEW | ||
| 19 | * License is obtained from: http://www.opensource.org/licenses/BSD-3-Clause. | ||
| 20 | * | ||
| 21 | * This program is distributed WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY | ||
| 23 | * SET FORTH IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF | ||
| 24 | * OSMC-PL. | ||
| 25 | * | ||
| 26 | */ | ||
| 27 | |||
| 28 | #include <Core/ModelicaDefine.h> | ||
| 29 | #include <Core/Modelica.h> | ||
| 30 | #include <Solver/IDA/IDA.h> | ||
| 31 | #include <Core/Math/Functions.h> | ||
| 32 | |||
| 33 | |||
| 34 | 1 | Ida::Ida(IMixedSystem* system, ISolverSettings* settings) | |
| 35 | : SolverDefaultImplementation(system, settings), | ||
| 36 | 1 | _idasettings(dynamic_cast<ISolverSettings*>(_settings)), | |
| 37 | 1 | _idaMem(NULL), | |
| 38 | 1 | _sunctx(NULL), | |
| 39 | /*_z(NULL), | ||
| 40 | _zInit(NULL), | ||
| 41 | _zWrite(NULL), | ||
| 42 | */ | ||
| 43 | 1 | _y(NULL), | |
| 44 | 1 | _yp(NULL), | |
| 45 | 1 | _yInit(NULL), | |
| 46 | 1 | _yWrite(NULL), | |
| 47 | 1 | _ypWrite(NULL), | |
| 48 | 1 | _dae_res(NULL), | |
| 49 | 1 | _dimSys(0), | |
| 50 | 1 | _dimAE(0), | |
| 51 | 1 | _dimStates(0), | |
| 52 | 1 | _cv_rt(0), | |
| 53 | 1 | _outStps(0), | |
| 54 | 1 | _locStps(0), | |
| 55 | 1 | _idid(0), | |
| 56 | 1 | _hOut(0.0), | |
| 57 | 1 | _tOut(0.0), | |
| 58 | 1 | _tZero(0.0), | |
| 59 | 1 | _zeroSign(NULL), | |
| 60 | 1 | _absTol(NULL), | |
| 61 | 1 | _ida_initialized(false), | |
| 62 | 1 | _tLastEvent(0.0), | |
| 63 | 1 | _event_n(0), | |
| 64 | 1 | _properties(NULL), | |
| 65 | 1 | _continuous_system(NULL), | |
| 66 | 1 | _event_system(NULL), | |
| 67 | 1 | _mixed_system(NULL), | |
| 68 | 1 | _time_system(NULL), | |
| 69 | 1 | _delta(NULL), | |
| 70 | 1 | _deltaInv(NULL), | |
| 71 | 1 | _ysave(NULL), | |
| 72 | 1 | _colorOfColumn (NULL), | |
| 73 | 1 | _jacobianAIndex(NULL), | |
| 74 | 1 | _jacobianALeadindex(NULL), | |
| 75 | 1 | _CV_y0(), | |
| 76 | 1 | _CV_y(), | |
| 77 | 1 | _CV_yp(), | |
| 78 | 1 | _CV_yWrite(), | |
| 79 | 1 | _CV_ypWrite(), | |
| 80 | 1 | _CV_absTol(), | |
| 81 | 1 | _bWritten(false), | |
| 82 | 1 | _zeroFound(false), | |
| 83 | 1 | _maxColors(0), | |
| 84 | 1 | _tLastWrite(-1.0), | |
| 85 | 1 | _jacobianANonzeros(0) | |
| 86 | { | ||
| 87 | 1 | _data = ((void*) this); | |
| 88 | #ifdef RUNTIME_PROFILING | ||
| 89 | if(MeasureTime::getInstance() != NULL) | ||
| 90 | { | ||
| 91 | measureTimeFunctionsArray = new std::vector<MeasureTimeData*>(7, NULL); //0 calcFunction //1 solve ... //6 solver statistics | ||
| 92 | (*measureTimeFunctionsArray)[0] = new MeasureTimeData("calcFunction"); | ||
| 93 | (*measureTimeFunctionsArray)[1] = new MeasureTimeData("solve"); | ||
| 94 | (*measureTimeFunctionsArray)[2] = new MeasureTimeData("writeOutput"); | ||
| 95 | (*measureTimeFunctionsArray)[3] = new MeasureTimeData("evaluateZeroFuncs"); | ||
| 96 | (*measureTimeFunctionsArray)[4] = new MeasureTimeData("initialize"); | ||
| 97 | (*measureTimeFunctionsArray)[5] = new MeasureTimeData("stepCompleted"); | ||
| 98 | (*measureTimeFunctionsArray)[6] = new MeasureTimeData("solverStatistics"); | ||
| 99 | |||
| 100 | MeasureTime::addResultContentBlock(system->getModelName(),"ida", measureTimeFunctionsArray); | ||
| 101 | measuredFunctionStartValues = MeasureTime::getZeroValues(); | ||
| 102 | measuredFunctionEndValues = MeasureTime::getZeroValues(); | ||
| 103 | solveFunctionStartValues = MeasureTime::getZeroValues(); | ||
| 104 | solveFunctionEndValues = MeasureTime::getZeroValues(); | ||
| 105 | solverValues = new MeasureTimeValuesSolver(); | ||
| 106 | |||
| 107 | (*measureTimeFunctionsArray)[6]->_sumMeasuredValues = solverValues; | ||
| 108 | } | ||
| 109 | else | ||
| 110 | { | ||
| 111 | measureTimeFunctionsArray = new std::vector<MeasureTimeData*>(); | ||
| 112 | measuredFunctionStartValues = NULL; | ||
| 113 | measuredFunctionEndValues = NULL; | ||
| 114 | solveFunctionStartValues = NULL; | ||
| 115 | solveFunctionEndValues = NULL; | ||
| 116 | solverValues = NULL; | ||
| 117 | } | ||
| 118 | #endif | ||
| 119 | 1 | } | |
| 120 | |||
| 121 | 2 | Ida::~Ida() | |
| 122 | { | ||
| 123 | /* | ||
| 124 | if (_z) | ||
| 125 | delete[] _z; | ||
| 126 | if (_zInit) | ||
| 127 | delete[] _zInit; | ||
| 128 | if (_zWrite) | ||
| 129 | delete[] _zWrite; | ||
| 130 | */ | ||
| 131 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | if (_y) |
| 132 | 1 | delete[] _y; | |
| 133 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | if (_yp) |
| 134 | 1 | delete[] _yp; | |
| 135 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | if (_yInit) |
| 136 | 1 | delete[] _yInit; | |
| 137 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | if (_yWrite) |
| 138 | 1 | delete[] _yWrite; | |
| 139 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | if (_ypWrite) |
| 140 | 1 | delete[] _ypWrite; | |
| 141 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | if (_dae_res) |
| 142 | 1 | delete[] _dae_res; | |
| 143 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | if (_zeroSign) |
| 144 | 1 | delete[] _zeroSign; | |
| 145 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | if (_absTol) |
| 146 | 1 | delete[] _absTol; | |
| 147 | |||
| 148 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | if (_ida_initialized) |
| 149 | { | ||
| 150 | 1 | N_VDestroy_Serial(_CV_y0); | |
| 151 | 1 | N_VDestroy_Serial(_CV_y); | |
| 152 | 1 | N_VDestroy_Serial(_CV_yp); | |
| 153 | 1 | N_VDestroy_Serial(_CV_yWrite); | |
| 154 | 1 | N_VDestroy_Serial(_CV_absTol); | |
| 155 | 1 | N_VDestroy_Serial(_ida_ySolver); | |
| 156 | 1 | SUNMatDestroy(_ida_J); | |
| 157 | 1 | SUNLinSolFree(_ida_linSol); | |
| 158 | 1 | IDAFree(&_idaMem); | |
| 159 | 1 | SUNContext_Free(&_sunctx); | |
| 160 | } | ||
| 161 | |||
| 162 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (_colorOfColumn) |
| 163 | ✗ | delete [] _colorOfColumn; | |
| 164 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | if(_delta) |
| 165 | 1 | delete [] _delta; | |
| 166 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | if(_deltaInv) |
| 167 | 1 | delete [] _deltaInv; | |
| 168 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | if(_ysave) |
| 169 | 1 | delete [] _ysave; | |
| 170 | |||
| 171 | #ifdef RUNTIME_PROFILING | ||
| 172 | if(measuredFunctionStartValues) | ||
| 173 | delete measuredFunctionStartValues; | ||
| 174 | if(measuredFunctionEndValues) | ||
| 175 | delete measuredFunctionEndValues; | ||
| 176 | if(solveFunctionStartValues) | ||
| 177 | delete solveFunctionStartValues; | ||
| 178 | if(solveFunctionEndValues) | ||
| 179 | delete solveFunctionEndValues; | ||
| 180 | if(solverValues) | ||
| 181 | delete solverValues; | ||
| 182 | #endif | ||
| 183 | 2 | } | |
| 184 | |||
| 185 | 1 | void Ida::initialize() | |
| 186 | { | ||
| 187 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | _properties = dynamic_cast<ISystemProperties*>(_system); |
| 188 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | _continuous_system = dynamic_cast<IContinuous*>(_system); |
| 189 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | _event_system = dynamic_cast<IEvent*>(_system); |
| 190 | 1 | _mixed_system = dynamic_cast<IMixedSystem*>(_system); | |
| 191 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | _time_system = dynamic_cast<ITime*>(_system); |
| 192 | 1 | IGlobalSettings* global_settings = dynamic_cast<ISolverSettings*>(_idasettings)->getGlobalSettings(); | |
| 193 | // Kennzeichnung, dass initialize()() (vor der Integration) aufgerufen wurde | ||
| 194 | 1 | _idid = 5000; | |
| 195 | 1 | _tLastEvent = 0.0; | |
| 196 | 1 | _event_n = 0; | |
| 197 | 1 | SolverDefaultImplementation::initialize(); | |
| 198 | |||
| 199 | 1 | _dimStates = _continuous_system->getDimContinuousStates(); | |
| 200 | 1 | _dimZeroFunc = _event_system->getDimZeroFunc(); | |
| 201 | 1 | _dimAE = _continuous_system->getDimAE(); | |
| 202 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | if(_dimAE>0) |
| 203 | 1 | _dimSys=_dimAE+ _dimStates; | |
| 204 | else | ||
| 205 | ✗ | _dimSys=_dimStates; | |
| 206 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (_dimStates <= 0) |
| 207 | |||
| 208 | { | ||
| 209 | ✗ | _idid = -1; | |
| 210 | ✗ | throw std::invalid_argument("Ida::initialize()"); | |
| 211 | } | ||
| 212 | else | ||
| 213 | { | ||
| 214 | // Allocate state vectors, stages and temporary arrays | ||
| 215 | |||
| 216 | /*if (_z) | ||
| 217 | delete[] _z; | ||
| 218 | if (_zInit) | ||
| 219 | delete[] _zInit; | ||
| 220 | if (_zWrite) | ||
| 221 | delete[] _zWrite;*/ | ||
| 222 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (_y) |
| 223 | ✗ | delete[] _y; | |
| 224 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (_yInit) |
| 225 | ✗ | delete[] _yInit; | |
| 226 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (_yWrite) |
| 227 | ✗ | delete[] _yWrite; | |
| 228 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (_ypWrite) |
| 229 | ✗ | delete[] _ypWrite; | |
| 230 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (_yp) |
| 231 | ✗ | delete[] _yp; | |
| 232 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (_dae_res) |
| 233 | ✗ | delete[] _dae_res; | |
| 234 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (_zeroSign) |
| 235 | ✗ | delete[] _zeroSign; | |
| 236 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (_absTol) |
| 237 | ✗ | delete[] _absTol; | |
| 238 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if(_delta) |
| 239 | ✗ | delete [] _delta; | |
| 240 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if(_deltaInv) |
| 241 | ✗ | delete [] _deltaInv; | |
| 242 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if(_ysave) |
| 243 | ✗ | delete [] _ysave; | |
| 244 | |||
| 245 | |||
| 246 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | _y = new double[_dimSys]; |
| 247 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | _yp = new double[_dimSys]; |
| 248 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | _yInit = new double[_dimSys]; |
| 249 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | _yWrite = new double[_dimSys]; |
| 250 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | _ypWrite = new double[_dimSys]; |
| 251 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | _dae_res = new double[_dimSys]; |
| 252 | /* | ||
| 253 | _z = new double[_dimSys]; | ||
| 254 | _zInit = new double[_dimSys]; | ||
| 255 | _zWrite = new double[_dimSys]; | ||
| 256 | */ | ||
| 257 | |||
| 258 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | _zeroSign = new int[_dimZeroFunc]; |
| 259 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | _absTol = new double[_dimSys]; |
| 260 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | _delta =new double[_dimSys]; |
| 261 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | _deltaInv =new double[_dimSys]; |
| 262 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | _ysave =new double[_dimSys]; |
| 263 | |||
| 264 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | memset(_y, 0, _dimSys * sizeof(double)); |
| 265 | 1 | memset(_yp, 0, _dimSys * sizeof(double)); | |
| 266 | 1 | memset(_yInit, 0, _dimSys * sizeof(double)); | |
| 267 | 1 | memset(_ysave, 0, _dimSys * sizeof(double)); | |
| 268 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | std::fill_n(_absTol, _dimSys, 1.0); |
| 269 | // Counter initialisieren | ||
| 270 | 1 | _outStps = 0; | |
| 271 | |||
| 272 |
1/2✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
|
1 | if (_idasettings->getDenseOutput()) |
| 273 | { | ||
| 274 | // Ausgabeschrittweite | ||
| 275 | 1 | _hOut = global_settings->gethOutput(); | |
| 276 | |||
| 277 | } | ||
| 278 | |||
| 279 | // Allocate memory for the solver | ||
| 280 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
|
1 | if (SUNContext_Create(SUN_COMM_NULL, &_sunctx) != SUN_SUCCESS) |
| 281 | ✗ | throw ModelicaSimulationError(SOLVER,"SUNDIALS_ERROR: SUNContext_Create failed"); | |
| 282 | /* Mute SUNDIALS' own logger: package level messages go to stderr/stdout by default, and we report solver failures ourselves. */ | ||
| 283 | { | ||
| 284 | 1 | SUNLogger _sunlogger = NULL; | |
| 285 |
2/4✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
✗ Branch 4 not taken.
|
1 | if (SUNContext_GetLogger(_sunctx, &_sunlogger) == SUN_SUCCESS && _sunlogger != NULL) { |
| 286 | 1 | SUNLogger_SetErrorFilename(_sunlogger, ""); | |
| 287 | 1 | SUNLogger_SetWarningFilename(_sunlogger, ""); | |
| 288 | 1 | SUNLogger_SetInfoFilename(_sunlogger, ""); | |
| 289 | 1 | SUNLogger_SetDebugFilename(_sunlogger, ""); | |
| 290 | } | ||
| 291 | } | ||
| 292 | |||
| 293 | 1 | _idaMem = IDACreate(_sunctx); | |
| 294 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
|
1 | if (check_flag((void*) _idaMem, "IDACreate", 0)) |
| 295 | { | ||
| 296 | ✗ | _idid = -5; | |
| 297 | ✗ | throw std::invalid_argument(/*_idid,_tCurrent,*/"Ida::initialize()"); | |
| 298 | } | ||
| 299 | |||
| 300 | // | ||
| 301 | // Make Ida ready for integration | ||
| 302 | // | ||
| 303 | |||
| 304 | // Set initial values for IDA | ||
| 305 | //_continuous_system->evaluateAll(IContinuous::CONTINUOUS); | ||
| 306 | 1 | _continuous_system->getContinuousStates(_yInit); | |
| 307 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | memcpy(_y, _yInit, _dimStates * sizeof(double)); |
| 308 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | if(_dimAE>0) |
| 309 | { | ||
| 310 | 1 | _mixed_system->getAlgebraicDAEVars(_yInit+_dimStates); | |
| 311 | 1 | memcpy(_y+_dimStates, _yInit+_dimStates, _dimAE * sizeof(double)); | |
| 312 | 1 | _continuous_system->getContinuousStates(_yp); | |
| 313 | } | ||
| 314 | // Get nominal values | ||
| 315 | 1 | _continuous_system->getNominalStates(_absTol); | |
| 316 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1 time.
|
10 | for (int i = 0; i < _dimStates; i++) |
| 317 | 9 | _absTol[i] = dynamic_cast<ISolverSettings*>(_idasettings)->getATol(); | |
| 318 | |||
| 319 | 1 | _CV_y0 = N_VMake_Serial(_dimSys, _yInit, _sunctx); | |
| 320 | 1 | _CV_y = N_VMake_Serial(_dimSys, _y, _sunctx); | |
| 321 | 1 | _CV_yp = N_VMake_Serial(_dimSys, _yp, _sunctx); | |
| 322 | 1 | _CV_yWrite = N_VMake_Serial(_dimSys, _yWrite, _sunctx); | |
| 323 | 1 | _CV_ypWrite = N_VMake_Serial(_dimSys, _ypWrite, _sunctx); | |
| 324 | 1 | _CV_absTol = N_VMake_Serial(_dimSys, _absTol, _sunctx); | |
| 325 | |||
| 326 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
|
1 | if (check_flag((void*) _CV_y0, "N_VMake_Serial", 0)) |
| 327 | { | ||
| 328 | ✗ | _idid = -5; | |
| 329 | ✗ | throw std::invalid_argument("Ida::initialize()"); | |
| 330 | } | ||
| 331 | |||
| 332 | //is already initialized: calcFunction(_tCurrent, NV_DATA_S(_CV_y0), NV_DATA_S(_CV_yp),NV_DATA_S(_CV_yp)); | ||
| 333 | |||
| 334 | // Initialize Ida (Initial values are required) | ||
| 335 | 1 | _idid = IDAInit(_idaMem, rhsFunctionCB, _tCurrent, _CV_y0, _CV_yp); | |
| 336 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (_idid < 0) |
| 337 | { | ||
| 338 | ✗ | _idid = -5; | |
| 339 | ✗ | throw std::invalid_argument("Ida::initialize()"); | |
| 340 | } | ||
| 341 | 1 | _idid = SUNContext_PushErrHandler(_sunctx, errOutputIDA, _data); | |
| 342 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (_idid < 0) |
| 343 | ✗ | throw std::invalid_argument("IDA::initialize()"); | |
| 344 | // Set Tolerances | ||
| 345 | 1 | _idid = IDASVtolerances(_idaMem, dynamic_cast<ISolverSettings*>(_idasettings)->getRTol(), _CV_absTol); // RTOL and ATOL | |
| 346 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (_idid < 0) |
| 347 | ✗ | throw std::invalid_argument("IDA::initialize()"); | |
| 348 | |||
| 349 | // Set the pointer to user-defined data | ||
| 350 | 1 | _idid = IDASetUserData(_idaMem, _data); | |
| 351 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (_idid < 0) |
| 352 | ✗ | throw std::invalid_argument("IDA::initialize()"); | |
| 353 | |||
| 354 | 1 | _idid = IDASetInitStep(_idaMem, 1e-6); // INITIAL STEPSIZE | |
| 355 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (_idid < 0) |
| 356 | ✗ | throw std::invalid_argument("Ida::initialize()"); | |
| 357 | |||
| 358 | |||
| 359 | 1 | _idid = IDASetMaxStep(_idaMem, global_settings->getEndTime() / 10.0); // MAXIMUM STEPSIZE | |
| 360 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (_idid < 0) |
| 361 | ✗ | throw std::invalid_argument("IDA::initialize()"); | |
| 362 | |||
| 363 | 1 | _idid = IDASetMaxNonlinIters(_idaMem, 5); // Max number of iterations | |
| 364 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (_idid < 0) |
| 365 | ✗ | throw std::invalid_argument("IDA::initialize()"); | |
| 366 | 1 | _idid = IDASetMaxErrTestFails(_idaMem, 100); | |
| 367 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (_idid < 0) |
| 368 | ✗ | throw std::invalid_argument("IDA::initialize()"); | |
| 369 | |||
| 370 | 1 | _idid = IDASetMaxNumSteps(_idaMem, 1e3); // Max Number of steps | |
| 371 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (_idid < 0) |
| 372 | ✗ | throw std::invalid_argument(/*_idid,_tCurrent,*/"IDA::initialize()"); | |
| 373 | |||
| 374 | // Initialize dense linear solver | ||
| 375 | 1 | _ida_ySolver = N_VNew_Serial(_dimSys, _sunctx); | |
| 376 | 1 | _ida_J = SUNDenseMatrix(_dimSys, _dimSys, _sunctx); | |
| 377 | 1 | _ida_linSol = SUNLinSol_Dense(_ida_ySolver, _ida_J, _sunctx); | |
| 378 | 1 | _idid = IDASetLinearSolver(_idaMem, _ida_linSol, _ida_J); | |
| 379 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (_idid < 0) |
| 380 | ✗ | throw std::invalid_argument("IDA::initialize()"); | |
| 381 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | if(_dimAE>0) |
| 382 | { | ||
| 383 | 1 | _idid = IDASetSuppressAlg(_idaMem, SUNTRUE); | |
| 384 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | double* tmp = new double[_dimSys]; |
| 385 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | std::fill_n(tmp, _dimStates, 1.0); |
| 386 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | std::fill_n(tmp+_dimStates, _dimAE, 0.0); |
| 387 | 1 | _idid = IDASetId(_idaMem, N_VMake_Serial(_dimSys, tmp, _sunctx)); | |
| 388 | 1 | delete [] tmp; | |
| 389 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (_idid < 0) |
| 390 | ✗ | throw std::invalid_argument("IDA::initialize()"); | |
| 391 | } | ||
| 392 | |||
| 393 | // Use own jacobian matrix | ||
| 394 | //_idid = CVodeSetJacFn(_idaMem, &jacobianFunctionCB); | ||
| 395 | //if (_idid < 0) | ||
| 396 | // throw std::invalid_argument("IDA::initialize()"); | ||
| 397 | |||
| 398 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | if (_dimZeroFunc) |
| 399 | { | ||
| 400 | 1 | _idid = IDARootInit(_idaMem, _dimZeroFunc, &zeroFunctionCB); | |
| 401 | |||
| 402 | 1 | memset(_zeroSign, 0, _dimZeroFunc * sizeof(int)); | |
| 403 | 1 | _idid = IDASetRootDirection(_idaMem, _zeroSign); | |
| 404 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (_idid < 0) |
| 405 | ✗ | throw std::invalid_argument(/*_idid,_tCurrent,*/"IDA::initialize()"); | |
| 406 | 1 | memset(_zeroSign, -1, _dimZeroFunc * sizeof(int)); | |
| 407 | 1 | memset(_zeroVal, -1, _dimZeroFunc * sizeof(int)); | |
| 408 | |||
| 409 | } | ||
| 410 | |||
| 411 | |||
| 412 | 1 | _ida_initialized = true; | |
| 413 | |||
| 414 | // | ||
| 415 | // IDA is ready for integration | ||
| 416 | // | ||
| 417 | // BOOST_LOG_SEV(ida_lg::get(), ida_info) << "IDA initialized"; | ||
| 418 | } | ||
| 419 | 1 | } | |
| 420 | |||
| 421 | 4 | void Ida::solve(const SOLVERCALL action) | |
| 422 | { | ||
| 423 | 4 | bool writeEventOutput = (_settings->getGlobalSettings()->getOutputPointType() == OPT_ALL); | |
| 424 | 4 | bool writeOutput = !(_settings->getGlobalSettings()->getOutputPointType() == OPT_NONE); | |
| 425 | |||
| 426 | #ifdef RUNTIME_PROFILING | ||
| 427 | MEASURETIME_REGION_DEFINE(idaSolveFunctionHandler, "solve"); | ||
| 428 | if(MeasureTime::getInstance() != NULL) | ||
| 429 | { | ||
| 430 | MEASURETIME_START(solveFunctionStartValues, idaSolveFunctionHandler, "solve"); | ||
| 431 | } | ||
| 432 | #endif | ||
| 433 | |||
| 434 |
2/4✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
4 | if (_idasettings && _system) |
| 435 | { | ||
| 436 | // Solver und System für Integration vorbereiten | ||
| 437 |
2/2✓ Branch 0 taken 1 time.
✓ Branch 1 taken 3 times.
|
4 | if ((action & RECORDCALL) && (action & FIRST_CALL)) |
| 438 | { | ||
| 439 | #ifdef RUNTIME_PROFILING | ||
| 440 | MEASURETIME_REGION_DEFINE(idaInitializeHandler, "IDAInitialize"); | ||
| 441 | if(MeasureTime::getInstance() != NULL) | ||
| 442 | { | ||
| 443 | MEASURETIME_START(measuredFunctionStartValues, idaInitializeHandler, "IDAInitialize"); | ||
| 444 | } | ||
| 445 | #endif | ||
| 446 | |||
| 447 | 1 | initialize(); | |
| 448 | |||
| 449 | #ifdef RUNTIME_PROFILING | ||
| 450 | if(MeasureTime::getInstance() != NULL) | ||
| 451 | { | ||
| 452 | MEASURETIME_END(measuredFunctionStartValues, measuredFunctionEndValues, (*measureTimeFunctionsArray)[4], idaInitializeHandler); | ||
| 453 | } | ||
| 454 | #endif | ||
| 455 | |||
| 456 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | if (writeOutput) |
| 457 | 1 | writeToFile(0, _tCurrent, _h); | |
| 458 | 1 | _tLastWrite = 0; | |
| 459 | |||
| 460 | 1 | return; | |
| 461 | } | ||
| 462 | |||
| 463 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 time.
|
3 | if ((action & RECORDCALL) && !(action & FIRST_CALL)) |
| 464 | { | ||
| 465 | 2 | writeToFile(_accStps, _tCurrent, _h); | |
| 466 | 2 | return; | |
| 467 | } | ||
| 468 | |||
| 469 | // Nach einem TimeEvent wird der neue Zustand recorded | ||
| 470 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (action & RECALL) |
| 471 | { | ||
| 472 | ✗ | _firstStep = true; | |
| 473 | ✗ | if (writeEventOutput) | |
| 474 | ✗ | writeToFile(0, _tCurrent, _h); | |
| 475 | ✗ | if (writeOutput) | |
| 476 | ✗ | writeIDAOutput(_tCurrent, _h, _locStps); | |
| 477 | ✗ | _continuous_system->getContinuousStates(_y); | |
| 478 | } | ||
| 479 | |||
| 480 | // Solver soll fortfahren | ||
| 481 | 1 | _solverStatus = ISolver::CONTINUE; | |
| 482 | |||
| 483 |
3/4✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1 time.
✗ Branch 3 not taken.
|
3 | while ((_solverStatus & ISolver::CONTINUE) && !_interrupt ) |
| 484 | { | ||
| 485 | // Zuvor wurde initialize aufgerufen und hat funktioniert => RESET IDID | ||
| 486 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (_idid == 5000) |
| 487 | ✗ | _idid = 0; | |
| 488 | |||
| 489 | // Solveraufruf | ||
| 490 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | if (_idid == 0) |
| 491 | { | ||
| 492 | // Zähler zurücksetzen | ||
| 493 | 1 | _accStps = 0; | |
| 494 | 1 | _locStps = 0; | |
| 495 | |||
| 496 | // Solverstart | ||
| 497 | 1 | IDACore(); | |
| 498 | |||
| 499 | } | ||
| 500 | |||
| 501 | // Integration war nicht erfolgreich und wurde auch nicht vom User unterbrochen | ||
| 502 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (_idid != 0 && _idid != 1) |
| 503 | { | ||
| 504 | ✗ | _solverStatus = ISolver::SOLVERERROR; | |
| 505 | //throw std::invalid_argument(_idid,_tCurrent,"IDA::solve()"); | ||
| 506 | ✗ | throw std::invalid_argument("IDA::solve()"); | |
| 507 | } | ||
| 508 | |||
| 509 | // Abbruchkriterium (erreichen der Endzeit) | ||
| 510 |
1/2✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
|
1 | else if ((_tEnd - _tCurrent) <= dynamic_cast<ISolverSettings*>(_idasettings)->getEndTimeTol()) |
| 511 | 1 | _solverStatus = DONE; | |
| 512 | } | ||
| 513 | |||
| 514 | 1 | _firstCall = false; | |
| 515 | |||
| 516 | } | ||
| 517 | else | ||
| 518 | { | ||
| 519 | |||
| 520 | ✗ | throw std::invalid_argument("IDA::solve()"); | |
| 521 | } | ||
| 522 | |||
| 523 | #ifdef RUNTIME_PROFILING | ||
| 524 | if(MeasureTime::getInstance() != NULL) | ||
| 525 | { | ||
| 526 | MEASURETIME_END(solveFunctionStartValues, solveFunctionEndValues, (*measureTimeFunctionsArray)[1], idaSolveFunctionHandler); | ||
| 527 | |||
| 528 | long int nst, nfe, nsetups, netf, nni, ncfn; | ||
| 529 | int qlast, qcur; | ||
| 530 | sunrealtype h0u, hlast, hcur, tcur; | ||
| 531 | |||
| 532 | int flag; | ||
| 533 | |||
| 534 | flag = IDAGetIntegratorStats(_idaMem, &nst, &nfe, &nsetups, &netf, &qlast, &qcur, &h0u, &hlast, &hcur, &tcur); | ||
| 535 | flag = IDAGetNonlinSolvStats(_idaMem, &nni, &ncfn); | ||
| 536 | |||
| 537 | MeasureTimeValuesSolver solverVals = MeasureTimeValuesSolver(nfe, netf); | ||
| 538 | (*measureTimeFunctionsArray)[6]->_sumMeasuredValues->_numCalcs += nst; | ||
| 539 | (*measureTimeFunctionsArray)[6]->_sumMeasuredValues->add(&solverVals); | ||
| 540 | } | ||
| 541 | #endif | ||
| 542 | } | ||
| 543 | 4 | bool Ida::isInterrupted() | |
| 544 | { | ||
| 545 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if(_interrupt) |
| 546 | { | ||
| 547 | ✗ | _solverStatus = DONE; | |
| 548 | ✗ | return true; | |
| 549 | } | ||
| 550 | else | ||
| 551 | { | ||
| 552 | return false; | ||
| 553 | } | ||
| 554 | } | ||
| 555 | 1 | void Ida::IDACore() | |
| 556 | { | ||
| 557 | 1 | _idid = IDAReInit(_idaMem, _tCurrent, _CV_y,_CV_yp); | |
| 558 | 1 | _idid = IDASetStopTime(_idaMem, _tEnd); | |
| 559 | 1 | _idid = IDASetInitStep(_idaMem, 1e-12); | |
| 560 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (_idid < 0) |
| 561 | ✗ | throw std::runtime_error("IDA::ReInit"); | |
| 562 | |||
| 563 | 1 | bool writeEventOutput = (_settings->getGlobalSettings()->getOutputPointType() == OPT_ALL); | |
| 564 | 1 | bool writeOutput = !(_settings->getGlobalSettings()->getOutputPointType() == OPT_NONE); | |
| 565 | |||
| 566 |
3/4✓ Branch 0 taken 13348 times.
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 13348 times.
✗ Branch 3 not taken.
|
13350 | while ((_solverStatus & ISolver::CONTINUE) && !_interrupt ) |
| 567 | { | ||
| 568 | 13348 | _cv_rt = IDASolve(_idaMem, _tEnd, &_tCurrent, _CV_y, _CV_yp, IDA_ONE_STEP); | |
| 569 | |||
| 570 | 13348 | _idid = IDAGetNumSteps(_idaMem, &_locStps); | |
| 571 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 13348 times.
|
13348 | if (_idid != IDA_SUCCESS) |
| 572 | ✗ | throw std::runtime_error("IDAGetNumSteps failed. The ida mem pointer is NULL"); | |
| 573 | |||
| 574 | 13348 | _idid =IDAGetLastStep(_idaMem, &_h); | |
| 575 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 13348 times.
|
13348 | if (_idid != IDA_SUCCESS) |
| 576 | ✗ | throw std::runtime_error("IDAGetLastStep failed. The ida mem pointer is NULL"); | |
| 577 | |||
| 578 | //Check if there was at least one output-point within the last solver interval | ||
| 579 | // -> Write output if true | ||
| 580 |
1/2✓ Branch 0 taken 13348 times.
✗ Branch 1 not taken.
|
13348 | if (writeOutput) |
| 581 | { | ||
| 582 | 13348 | writeIDAOutput(_tCurrent, _h, _locStps); | |
| 583 | } | ||
| 584 | |||
| 585 | #ifdef RUNTIME_PROFILING | ||
| 586 | MEASURETIME_REGION_DEFINE(idaStepCompletedHandler, "IDAStepCompleted"); | ||
| 587 | if(MeasureTime::getInstance() != NULL) | ||
| 588 | { | ||
| 589 | MEASURETIME_START(measuredFunctionStartValues, idaStepCompletedHandler, "IDAStepCompleted"); | ||
| 590 | } | ||
| 591 | #endif | ||
| 592 | |||
| 593 | //set completed step to system and check if terminate was called | ||
| 594 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 13348 times.
|
13348 | if(_continuous_system->stepCompleted(_tCurrent)) |
| 595 | ✗ | _solverStatus = DONE; | |
| 596 | |||
| 597 | #ifdef RUNTIME_PROFILING | ||
| 598 | if(MeasureTime::getInstance() != NULL) | ||
| 599 | { | ||
| 600 | MEASURETIME_END(measuredFunctionStartValues, measuredFunctionEndValues, (*measureTimeFunctionsArray)[5], idaStepCompletedHandler); | ||
| 601 | } | ||
| 602 | #endif | ||
| 603 | |||
| 604 | // Perform state selection | ||
| 605 | 13348 | bool state_selection = stateSelection(); | |
| 606 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 13348 times.
|
13348 | if (state_selection) |
| 607 | ✗ | _continuous_system->getContinuousStates(_y); | |
| 608 | |||
| 609 | 13348 | _zeroFound = false; | |
| 610 | |||
| 611 | // Check if step was successful | ||
| 612 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 13348 times.
|
13348 | if (check_flag(&_cv_rt, "IDA", 1)) |
| 613 | { | ||
| 614 | ✗ | _solverStatus = ISolver::SOLVERERROR; | |
| 615 | ✗ | break; | |
| 616 | } | ||
| 617 | |||
| 618 | // A root was found | ||
| 619 |
3/4✓ Branch 0 taken 2 times.
✓ Branch 1 taken 13346 times.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
|
13348 | if ((_cv_rt == IDA_ROOT_RETURN) && !isInterrupted()) |
| 620 | { | ||
| 621 | // IDA is setting _tCurrent to the time where the first event occurred | ||
| 622 | 2 | double _abs = fabs(_tLastEvent - _tCurrent); | |
| 623 | 2 | _zeroFound = true; | |
| 624 | |||
| 625 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
2 | if ((_abs < 1e-3) && _event_n == 0) |
| 626 | { | ||
| 627 | ✗ | _tLastEvent = _tCurrent; | |
| 628 | ✗ | _event_n++; | |
| 629 | } | ||
| 630 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
2 | else if ((_abs < 1e-3) && (_event_n >= 1 && _event_n < 500)) |
| 631 | { | ||
| 632 | ✗ | _event_n++; | |
| 633 | } | ||
| 634 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | else if ((_abs >= 1e-3)) |
| 635 | { | ||
| 636 | //restart event counter | ||
| 637 | 2 | _tLastEvent = _tCurrent; | |
| 638 | 2 | _event_n = 0; | |
| 639 | } | ||
| 640 | else | ||
| 641 | ✗ | throw std::runtime_error("Number of events exceeded in time interval " + to_string(_abs) + " at time " + to_string(_tCurrent)); | |
| 642 | |||
| 643 | // IDA has interpolated the states at time 'tCurrent' | ||
| 644 | 2 | _time_system->setTime(_tCurrent); | |
| 645 | |||
| 646 | // To get steep steps in the result file, two value points (P1 and P2) must be added | ||
| 647 | // | ||
| 648 | // Y | (P2) X........... | ||
| 649 | // | : | ||
| 650 | // | : | ||
| 651 | // |........X (P1) | ||
| 652 | // |----------------------------------> | ||
| 653 | // | ^ t | ||
| 654 | // _tCurrent | ||
| 655 | |||
| 656 | // Write the values of (P1) | ||
| 657 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if (writeEventOutput) |
| 658 | { | ||
| 659 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if(_dimAE>0) |
| 660 | { | ||
| 661 | 2 | _continuous_system->evaluateDAE(IContinuous::CONTINUOUS); | |
| 662 | } | ||
| 663 | else | ||
| 664 | { | ||
| 665 | ✗ | _continuous_system->evaluateAll(IContinuous::CONTINUOUS); | |
| 666 | } | ||
| 667 | 2 | writeToFile(0, _tCurrent, _h); | |
| 668 | } | ||
| 669 | |||
| 670 | 2 | _idid = IDAGetRootInfo(_idaMem, _zeroSign); | |
| 671 | |||
| 672 |
2/2✓ Branch 0 taken 18 times.
✓ Branch 1 taken 2 times.
|
20 | for (int i = 0; i < _dimZeroFunc; i++) |
| 673 | 18 | _events[i] = bool(_zeroSign[i]); | |
| 674 | |||
| 675 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if (_mixed_system->handleSystemEvents(_events)) |
| 676 | { | ||
| 677 | // State variables were reinitialized, thus we have to give these values to the ida-solver | ||
| 678 | // Take care about the memory regions, _z is the same like _CV_y | ||
| 679 | ✗ | _continuous_system->getContinuousStates(_y); | |
| 680 | ✗ | if(_dimAE>0) | |
| 681 | { | ||
| 682 | ✗ | _mixed_system->getAlgebraicDAEVars(_y+_dimStates); | |
| 683 | ✗ | _continuous_system->getRHS(_yp); | |
| 684 | } | ||
| 685 | ✗ | calcFunction(_tCurrent, NV_DATA_S(_CV_y), NV_DATA_S(_CV_yp),_dae_res); | |
| 686 | |||
| 687 | } | ||
| 688 | } | ||
| 689 | |||
| 690 |
4/6✓ Branch 0 taken 13346 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13346 times.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
13348 | if ((_zeroFound || state_selection)&& !isInterrupted()) |
| 691 | { | ||
| 692 | // Write the values of (P2) | ||
| 693 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if (writeEventOutput) |
| 694 | { | ||
| 695 | // If we want to write the event-results, we should evaluate the whole system again | ||
| 696 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if(_dimAE>0) |
| 697 | { | ||
| 698 | 2 | _continuous_system->evaluateDAE(IContinuous::CONTINUOUS); | |
| 699 | } | ||
| 700 | else | ||
| 701 | { | ||
| 702 | ✗ | _continuous_system->evaluateAll(IContinuous::CONTINUOUS); | |
| 703 | } | ||
| 704 | 2 | writeToFile(0, _tCurrent, _h); | |
| 705 | } | ||
| 706 | |||
| 707 | 2 | _idid = IDAReInit(_idaMem, _tCurrent, _CV_y,_CV_yp); | |
| 708 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (_idid < 0) |
| 709 | ✗ | throw std::runtime_error("IDA::ReInit()"); | |
| 710 | |||
| 711 | // Der Eventzeitpunkt kann auf der Endzeit liegen (Time-Events). In diesem Fall wird der Solver beendet, da IDA sonst eine interne Warnung schmeißt | ||
| 712 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (_tCurrent == _tEnd) |
| 713 | ✗ | _cv_rt = IDA_TSTOP_RETURN; | |
| 714 | } | ||
| 715 | |||
| 716 | // Zähler für die Anzahl der ausgegebenen Schritte erhöhen | ||
| 717 | 13348 | ++_outStps; | |
| 718 | 13348 | _tLastSuccess = _tCurrent; | |
| 719 | |||
| 720 |
2/2✓ Branch 0 taken 13347 times.
✓ Branch 1 taken 1 time.
|
13348 | if (_cv_rt == IDA_TSTOP_RETURN) |
| 721 | { | ||
| 722 | 1 | _time_system->setTime(_tEnd); | |
| 723 | 1 | _continuous_system->setContinuousStates(NV_DATA_S(_CV_y)); | |
| 724 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | if(_dimAE>0) |
| 725 | { | ||
| 726 | 1 | _mixed_system->setAlgebraicDAEVars(NV_DATA_S(_CV_y)+_dimStates); | |
| 727 | 1 | _continuous_system->setStateDerivatives(NV_DATA_S(_CV_yp)); | |
| 728 | 1 | _continuous_system->evaluateDAE(IContinuous::CONTINUOUS); | |
| 729 | } | ||
| 730 | else | ||
| 731 | { | ||
| 732 | ✗ | _continuous_system->evaluateAll(IContinuous::CONTINUOUS); | |
| 733 | } | ||
| 734 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | if(writeOutput) |
| 735 | 1 | writeToFile(0, _tEnd, _h); | |
| 736 | |||
| 737 | 1 | _accStps += _locStps; | |
| 738 | 1 | _solverStatus = DONE; | |
| 739 | } | ||
| 740 | } | ||
| 741 | 1 | } | |
| 742 | ✗ | void Ida::setTimeOut(unsigned int time_out) | |
| 743 | { | ||
| 744 | ✗ | SimulationMonitor::setTimeOut(time_out); | |
| 745 | ✗ | } | |
| 746 | ✗ | void Ida::stop() | |
| 747 | { | ||
| 748 | ✗ | SimulationMonitor::stop(); | |
| 749 | ✗ | } | |
| 750 | 13348 | void Ida::writeIDAOutput(const double &time, const double &h, const int &stp) | |
| 751 | { | ||
| 752 | #ifdef RUNTIME_PROFILING | ||
| 753 | MEASURETIME_REGION_DEFINE(idaWriteOutputHandler, "IDAWriteOutput"); | ||
| 754 | if(MeasureTime::getInstance() != NULL) | ||
| 755 | { | ||
| 756 | MEASURETIME_START(measuredFunctionStartValues, idaWriteOutputHandler, "IDAWriteOutput"); | ||
| 757 | } | ||
| 758 | #endif | ||
| 759 | |||
| 760 |
1/2✓ Branch 0 taken 13348 times.
✗ Branch 1 not taken.
|
13348 | if (stp > 0) |
| 761 | { | ||
| 762 |
1/2✓ Branch 1 taken 13348 times.
✗ Branch 2 not taken.
|
13348 | if (_idasettings->getDenseOutput()) |
| 763 | { | ||
| 764 | 13348 | _bWritten = false; | |
| 765 | double *oldValues = NULL; | ||
| 766 | |||
| 767 | //We have to find all output-points within the last solver step | ||
| 768 |
2/2✓ Branch 2 taken 24999 times.
✓ Branch 3 taken 13348 times.
|
38347 | while (_tLastWrite + dynamic_cast<ISolverSettings*>(_idasettings)->getGlobalSettings()->gethOutput() <= time) |
| 769 | { | ||
| 770 |
2/2✓ Branch 0 taken 11734 times.
✓ Branch 1 taken 13265 times.
|
24999 | if (!_bWritten) |
| 771 | { | ||
| 772 | //Rescue the calculated derivatives | ||
| 773 |
1/2✓ Branch 1 taken 11734 times.
✗ Branch 2 not taken.
|
11734 | oldValues = new double[_continuous_system->getDimRHS()]; |
| 774 | 11734 | _continuous_system->getRHS(oldValues); | |
| 775 | } | ||
| 776 | 24999 | _bWritten = true; | |
| 777 | 24999 | _tLastWrite = _tLastWrite + dynamic_cast<ISolverSettings*>(_idasettings)->getGlobalSettings()->gethOutput(); | |
| 778 | //Get the state vars at the output-point (interpolated) | ||
| 779 | 24999 | _idid = IDAGetDky(_idaMem, _tLastWrite, 0, _CV_yWrite); | |
| 780 | 24999 | _time_system->setTime(_tLastWrite); | |
| 781 | 24999 | _continuous_system->setContinuousStates(NV_DATA_S(_CV_yWrite)); | |
| 782 |
1/2✓ Branch 0 taken 24999 times.
✗ Branch 1 not taken.
|
24999 | if(_dimAE>0) |
| 783 | { | ||
| 784 | 24999 | _mixed_system->setAlgebraicDAEVars(NV_DATA_S(_CV_y)+_dimStates); | |
| 785 | 24999 | _idid = IDAGetDky(_idaMem, _tLastWrite, 1, _CV_ypWrite); | |
| 786 | 24999 | _continuous_system->setStateDerivatives(NV_DATA_S(_CV_ypWrite)); | |
| 787 | 24999 | _continuous_system->evaluateDAE(IContinuous::CONTINUOUS); | |
| 788 | } | ||
| 789 | else | ||
| 790 | { | ||
| 791 | ✗ | _continuous_system->evaluateAll(IContinuous::CONTINUOUS); | |
| 792 | } | ||
| 793 | #ifdef RUNTIME_PROFILING | ||
| 794 | if(MeasureTime::getInstance() != NULL) | ||
| 795 | { | ||
| 796 | MEASURETIME_END(measuredFunctionStartValues, measuredFunctionEndValues, (*measureTimeFunctionsArray)[2], idaWriteOutputHandler); | ||
| 797 | } | ||
| 798 | #endif | ||
| 799 | 24999 | SolverDefaultImplementation::writeToFile(stp, _tLastWrite, h); | |
| 800 | #ifdef RUNTIME_PROFILING | ||
| 801 | MEASURETIME_REGION_DEFINE(idaWriteOutputHandler, "IDAWriteOutput"); | ||
| 802 | if(MeasureTime::getInstance() != NULL) | ||
| 803 | { | ||
| 804 | (*measureTimeFunctionsArray)[2]->_sumMeasuredValues->_numCalcs--; | ||
| 805 | MEASURETIME_START(measuredFunctionStartValues, idaWriteOutputHandler, "IDAWriteOutput"); | ||
| 806 | } | ||
| 807 | #endif | ||
| 808 | } //end if time -_tLastWritten | ||
| 809 |
2/2✓ Branch 0 taken 11734 times.
✓ Branch 1 taken 1614 times.
|
13348 | if (_bWritten) |
| 810 | { | ||
| 811 | 11734 | _time_system->setTime(time); | |
| 812 | 11734 | _continuous_system->setContinuousStates(_y); | |
| 813 | 11734 | _continuous_system->setStateDerivatives(oldValues); | |
| 814 |
1/2✓ Branch 0 taken 11734 times.
✗ Branch 1 not taken.
|
11734 | if(_dimAE>0) |
| 815 | { | ||
| 816 | 11734 | _mixed_system->setAlgebraicDAEVars(_y+_dimStates); | |
| 817 | } | ||
| 818 |
1/2✓ Branch 0 taken 11734 times.
✗ Branch 1 not taken.
|
11734 | delete[] oldValues; |
| 819 | |||
| 820 | } | ||
| 821 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 1614 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
1614 | else if (time == _tEnd && _tLastWrite != time) |
| 822 | { | ||
| 823 | ✗ | _idid = IDAGetDky(_idaMem, time, 0, _CV_y); | |
| 824 | ✗ | _idid = IDAGetDky(_idaMem, time, 1, _CV_yp); | |
| 825 | ✗ | _time_system->setTime(time); | |
| 826 | ✗ | _continuous_system->setContinuousStates(NV_DATA_S(_CV_y)); | |
| 827 | ✗ | if(_dimAE>0) | |
| 828 | { | ||
| 829 | ✗ | _mixed_system->setAlgebraicDAEVars(NV_DATA_S(_CV_y)+_dimStates); | |
| 830 | ✗ | _continuous_system->setStateDerivatives(NV_DATA_S(_CV_yp)); | |
| 831 | ✗ | _continuous_system->evaluateDAE(IContinuous::CONTINUOUS); | |
| 832 | } | ||
| 833 | else | ||
| 834 | { | ||
| 835 | ✗ | _continuous_system->evaluateAll(IContinuous::CONTINUOUS); | |
| 836 | } | ||
| 837 | #ifdef RUNTIME_PROFILING | ||
| 838 | if(MeasureTime::getInstance() != NULL) | ||
| 839 | { | ||
| 840 | MEASURETIME_END(measuredFunctionStartValues, measuredFunctionEndValues, (*measureTimeFunctionsArray)[2], idaWriteOutputHandler); | ||
| 841 | } | ||
| 842 | #endif | ||
| 843 | ✗ | SolverDefaultImplementation::writeToFile(stp, _tEnd, h); | |
| 844 | } | ||
| 845 | } | ||
| 846 | else | ||
| 847 | { | ||
| 848 | #ifdef RUNTIME_PROFILING | ||
| 849 | if(MeasureTime::getInstance() != NULL) | ||
| 850 | { | ||
| 851 | MEASURETIME_END(measuredFunctionStartValues, measuredFunctionEndValues, (*measureTimeFunctionsArray)[2], idaWriteOutputHandler); | ||
| 852 | } | ||
| 853 | #endif | ||
| 854 | ✗ | SolverDefaultImplementation::writeToFile(stp, time, h); | |
| 855 | } | ||
| 856 | } | ||
| 857 | 13348 | } | |
| 858 | |||
| 859 | 13350 | bool Ida::stateSelection() | |
| 860 | { | ||
| 861 | 13350 | return SolverDefaultImplementation::stateSelection(); | |
| 862 | } | ||
| 863 | 167637 | int Ida::calcFunction(const double& time, const double* y, double *yp,double* res) | |
| 864 | { | ||
| 865 | #ifdef RUNTIME_PROFILING | ||
| 866 | MEASURETIME_REGION_DEFINE(idaCalcFunctionHandler, "IDACalcFunction"); | ||
| 867 | if(MeasureTime::getInstance() != NULL) | ||
| 868 | { | ||
| 869 | MEASURETIME_START(measuredFunctionStartValues, idaCalcFunctionHandler, "IDACalcFunction"); | ||
| 870 | } | ||
| 871 | #endif | ||
| 872 | |||
| 873 | int returnValue = 0; | ||
| 874 | try | ||
| 875 | { | ||
| 876 |
1/2✓ Branch 0 taken 167637 times.
✗ Branch 1 not taken.
|
167637 | if(_dimAE>0) |
| 877 | { | ||
| 878 |
1/1✓ Branch 1 taken 167637 times.
|
167637 | _time_system->setTime(time); |
| 879 |
1/1✓ Branch 1 taken 167637 times.
|
167637 | _continuous_system->setContinuousStates(y); |
| 880 |
1/1✓ Branch 1 taken 167637 times.
|
167637 | _continuous_system->setStateDerivatives(yp); |
| 881 |
1/1✓ Branch 1 taken 167637 times.
|
167637 | _mixed_system->setAlgebraicDAEVars(y+_dimStates); |
| 882 |
1/1✓ Branch 1 taken 167637 times.
|
167637 | _continuous_system->evaluateDAE(IContinuous::CONTINUOUS); |
| 883 |
1/1✓ Branch 1 taken 167637 times.
|
167637 | _mixed_system->getResidual(res); |
| 884 | |||
| 885 | } | ||
| 886 | else | ||
| 887 | { | ||
| 888 | ✗ | _time_system->setTime(time); | |
| 889 | ✗ | _continuous_system->setContinuousStates(y); | |
| 890 | ✗ | _continuous_system->evaluateODE(IContinuous::CONTINUOUS); | |
| 891 | ✗ | _continuous_system->getRHS(res); | |
| 892 | ✗ | for(size_t i(0); i<_dimSys; ++i) | |
| 893 | ✗ | res[i]-=yp[i]; | |
| 894 | |||
| 895 | } | ||
| 896 | } //workaround until exception can be catch from c- libraries | ||
| 897 | ✗ | catch (std::exception& ex) | |
| 898 | { | ||
| 899 | ✗ | std::string error = ex.what(); | |
| 900 | cerr << "IDA integration error: " << error; | ||
| 901 | returnValue = -1; | ||
| 902 | ✗ | } | |
| 903 | |||
| 904 | #ifdef RUNTIME_PROFILING | ||
| 905 | if(MeasureTime::getInstance() != NULL) | ||
| 906 | { | ||
| 907 | MEASURETIME_END(measuredFunctionStartValues, measuredFunctionEndValues, (*measureTimeFunctionsArray)[0], idaCalcFunctionHandler); | ||
| 908 | } | ||
| 909 | #endif | ||
| 910 | |||
| 911 | 167637 | return returnValue; | |
| 912 | } | ||
| 913 | |||
| 914 | 167637 | int Ida::rhsFunctionCB(double t, N_Vector y, N_Vector ydot, N_Vector resval, void *user_data) | |
| 915 | { | ||
| 916 | |||
| 917 | 167637 | int status = ((Ida*) user_data)->calcFunction(t, NV_DATA_S(y), NV_DATA_S(ydot),NV_DATA_S(resval)); | |
| 918 | |||
| 919 | 167637 | return status; | |
| 920 | } | ||
| 921 | |||
| 922 | 13353 | void Ida::giveZeroVal(const double &t, const double *y,const double *yp,double *zeroValue) | |
| 923 | { | ||
| 924 | #ifdef RUNTIME_PROFILING | ||
| 925 | MEASURETIME_REGION_DEFINE(idaEvalZeroHandler, "evaluateZeroFuncs"); | ||
| 926 | if(MeasureTime::getInstance() != NULL) | ||
| 927 | { | ||
| 928 | MEASURETIME_START(measuredFunctionStartValues, idaEvalZeroHandler, "evaluateZeroFuncs"); | ||
| 929 | } | ||
| 930 | #endif | ||
| 931 | |||
| 932 | 13353 | _time_system->setTime(t); | |
| 933 | 13353 | _continuous_system->setContinuousStates(y); | |
| 934 |
1/2✓ Branch 0 taken 13353 times.
✗ Branch 1 not taken.
|
13353 | if(_dimAE>0) |
| 935 | { | ||
| 936 | 13353 | _mixed_system->setAlgebraicDAEVars(y+_dimStates); | |
| 937 | 13353 | _continuous_system->setStateDerivatives(yp); | |
| 938 | } | ||
| 939 | // System aktualisieren | ||
| 940 | 13353 | _continuous_system->evaluateZeroFuncs(IContinuous::DISCRETE); | |
| 941 | |||
| 942 | 13353 | _event_system->getZeroFunc(zeroValue); | |
| 943 | |||
| 944 | #ifdef RUNTIME_PROFILING | ||
| 945 | if(MeasureTime::getInstance() != NULL) | ||
| 946 | { | ||
| 947 | MEASURETIME_END(measuredFunctionStartValues, measuredFunctionEndValues, (*measureTimeFunctionsArray)[3], idaEvalZeroHandler); | ||
| 948 | } | ||
| 949 | #endif | ||
| 950 | 13353 | } | |
| 951 | |||
| 952 | 13353 | int Ida::zeroFunctionCB(double t, N_Vector y, N_Vector yp, double *zeroval, void *user_data) | |
| 953 | { | ||
| 954 | 13353 | ((Ida*) user_data)->giveZeroVal(t, NV_DATA_S(y),NV_DATA_S(yp), zeroval); | |
| 955 | |||
| 956 | 13353 | return (0); | |
| 957 | } | ||
| 958 | |||
| 959 | ✗ | int Ida::jacobianFunctionCB(long int N, double t, N_Vector y, N_Vector fy, SUNMatrix Jac,void *user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3) | |
| 960 | { | ||
| 961 | ✗ | return ((Ida*) user_data)->calcJacobian(t,N, tmp1, tmp2, tmp3, NV_DATA_S(y), fy, Jac); | |
| 962 | |||
| 963 | } | ||
| 964 | |||
| 965 | |||
| 966 | ✗ | int Ida::calcJacobian(double t, long int N, N_Vector fHelp, N_Vector errorWeight, N_Vector jthCol, double* y, N_Vector fy, SUNMatrix Jac) | |
| 967 | { | ||
| 968 | try | ||
| 969 | { | ||
| 970 | int l,g; | ||
| 971 | double fnorm, minInc, *f_data, *fHelp_data, *errorWeight_data, h, srur, delta_inv; | ||
| 972 | |||
| 973 | ✗ | f_data = NV_DATA_S(fy); | |
| 974 | ✗ | errorWeight_data = NV_DATA_S(errorWeight); | |
| 975 | ✗ | fHelp_data = NV_DATA_S(fHelp); | |
| 976 | |||
| 977 | |||
| 978 | //Get relevant info | ||
| 979 | ✗ | _idid = IDAGetErrWeights(_idaMem, errorWeight); | |
| 980 | ✗ | if (_idid < 0) | |
| 981 | { | ||
| 982 | ✗ | _idid = -5; | |
| 983 | ✗ | throw std::invalid_argument("IDA::calcJacobian()"); | |
| 984 | } | ||
| 985 | ✗ | _idid = IDAGetCurrentStep(_idaMem, &h); | |
| 986 | ✗ | if (_idid < 0) | |
| 987 | { | ||
| 988 | ✗ | _idid = -5; | |
| 989 | ✗ | throw std::invalid_argument("IDA::calcJacobian()"); | |
| 990 | } | ||
| 991 | |||
| 992 | srur = sqrt(UROUND); | ||
| 993 | |||
| 994 | ✗ | fnorm = N_VWrmsNorm(fy, errorWeight); | |
| 995 | ✗ | minInc = (fnorm != 0.0) ? | |
| 996 | ✗ | (1000.0 * abs(h) * UROUND * N * fnorm) : 1.0; | |
| 997 | |||
| 998 | ✗ | for(int j=0;j<N;j++) | |
| 999 | { | ||
| 1000 | ✗ | _delta[j] = max(srur*abs(y[j]), minInc/errorWeight_data[j]); | |
| 1001 | } | ||
| 1002 | ✗ | for(int j=0;j<N;j++) | |
| 1003 | { | ||
| 1004 | ✗ | _deltaInv[j] = 1/_delta[j]; | |
| 1005 | } | ||
| 1006 | |||
| 1007 | // Calculation of the jacobian | ||
| 1008 | |||
| 1009 | ✗ | if (_jacobianANonzeros != 0) | |
| 1010 | { | ||
| 1011 | ✗ | for(int color=1; color <= _maxColors; color++) | |
| 1012 | { | ||
| 1013 | ✗ | for(int k=0; k < _dimSys; k++) | |
| 1014 | { | ||
| 1015 | ✗ | if((_colorOfColumn[k] ) == color) | |
| 1016 | { | ||
| 1017 | ✗ | _ysave[k] = y[k]; | |
| 1018 | ✗ | y[k]+= _delta[k]; | |
| 1019 | } | ||
| 1020 | } | ||
| 1021 | |||
| 1022 | ✗ | calcFunction(t, y, fHelp_data,fHelp_data); | |
| 1023 | |||
| 1024 | ✗ | for (int k = 0; k < _dimSys; k++) | |
| 1025 | { | ||
| 1026 | ✗ | if((_colorOfColumn[k]) == color) | |
| 1027 | { | ||
| 1028 | ✗ | y[k] = _ysave[k]; | |
| 1029 | |||
| 1030 | ✗ | int startOfColumn = k * _dimSys; | |
| 1031 | ✗ | for (int j = _jacobianALeadindex[k]; j < _jacobianALeadindex[k+1];j++) | |
| 1032 | { | ||
| 1033 | ✗ | l = _jacobianAIndex[j]; | |
| 1034 | ✗ | g = l + startOfColumn; | |
| 1035 | ✗ | SM_DATA_D(Jac)[g] = (fHelp_data[l] - f_data[l]) * _deltaInv[k]; | |
| 1036 | } | ||
| 1037 | } | ||
| 1038 | } | ||
| 1039 | } | ||
| 1040 | } | ||
| 1041 | |||
| 1042 | /* | ||
| 1043 | //Calculation of J without colouring | ||
| 1044 | for (j = 0; j < N; j++) | ||
| 1045 | { | ||
| 1046 | |||
| 1047 | |||
| 1048 | //N_VSetArrayPointer(DENSE_COL(Jac,j), jthCol); | ||
| 1049 | |||
| 1050 | _ysave[j] = y[j]; | ||
| 1051 | |||
| 1052 | y[j] += _delta[j]; | ||
| 1053 | |||
| 1054 | calcFunction(t, y, fHelp_data); | ||
| 1055 | |||
| 1056 | y[j] = _ysave[j]; | ||
| 1057 | |||
| 1058 | delta_inv = 1.0/_delta[j]; | ||
| 1059 | N_VLinearSum(delta_inv, fHelp, -delta_inv, fy, jthCol); | ||
| 1060 | |||
| 1061 | for(int i=0; i<_dimSys; ++i) | ||
| 1062 | { | ||
| 1063 | SM_DATA_D(Jac)[i+j*_dimSys] = NV_Ith_S(jthCol,i); | ||
| 1064 | } | ||
| 1065 | |||
| 1066 | //DENSE_COL(Jac,j) = N_VGetArrayPointer(jthCol); | ||
| 1067 | } | ||
| 1068 | */ | ||
| 1069 | |||
| 1070 | } //workaround until exception can be catch from c- libraries | ||
| 1071 | ✗ | catch (std::exception& ex) | |
| 1072 | { | ||
| 1073 | ✗ | std::string error = ex.what(); | |
| 1074 | cerr << "IDA integration error: " << error; | ||
| 1075 | return 1; | ||
| 1076 | ✗ | } | |
| 1077 | |||
| 1078 | |||
| 1079 | ✗ | return 0; | |
| 1080 | } | ||
| 1081 | |||
| 1082 | |||
| 1083 | |||
| 1084 | ✗ | int Ida::reportErrorMessage(ostream& messageStream) | |
| 1085 | { | ||
| 1086 | ✗ | if (_solverStatus == ISolver::SOLVERERROR) | |
| 1087 | { | ||
| 1088 | ✗ | if (_idid == -1) | |
| 1089 | messageStream << "Invalid system dimension." << std::endl; | ||
| 1090 | ✗ | if (_idid == -2) | |
| 1091 | messageStream << "Method not implemented." << std::endl; | ||
| 1092 | ✗ | if (_idid == -3) | |
| 1093 | messageStream << "No valid system/settings available." << std::endl; | ||
| 1094 | ✗ | if (_idid == -11) | |
| 1095 | messageStream << "Step size too small." << std::endl; | ||
| 1096 | } | ||
| 1097 | |||
| 1098 | ✗ | else if (_solverStatus == ISolver::USER_STOP) | |
| 1099 | { | ||
| 1100 | ✗ | messageStream << "Simulation terminated by user at t: " << _tCurrent << std::endl; | |
| 1101 | } | ||
| 1102 | |||
| 1103 | ✗ | return _idid; | |
| 1104 | } | ||
| 1105 | |||
| 1106 | 1 | void Ida::writeSimulationInfo() | |
| 1107 | { | ||
| 1108 | long int nst, nfe, nsetups, nni, ncfn, netf; | ||
| 1109 | long int nfQe, netfQ; | ||
| 1110 | long int nfSe, nfeS, nsetupsS, nniS, ncfnS, netfS; | ||
| 1111 | long int nfQSe, netfQS; | ||
| 1112 | |||
| 1113 | int qlast, qcur; | ||
| 1114 | sunrealtype h0u, hlast, hcur, tcur; | ||
| 1115 | |||
| 1116 | int flag; | ||
| 1117 | |||
| 1118 | 1 | flag = IDAGetIntegratorStats(_idaMem, &nst, &nfe, &nsetups, &netf, &qlast, &qcur, &h0u, &hlast, &hcur, &tcur); | |
| 1119 | |||
| 1120 | 1 | flag = IDAGetNonlinSolvStats(_idaMem, &nni, &ncfn); | |
| 1121 | |||
| 1122 | ✗ | LOGGER_WRITE("IDA: number steps = " + to_string(nst), LC_SOLVER, LL_INFO); | |
| 1123 | ✗ | LOGGER_WRITE("IDA: function evaluations 'f' = " + to_string(nfe), LC_SOLVER, LL_INFO); | |
| 1124 | ✗ | LOGGER_WRITE("IDA: error test failures 'netf' = " + to_string(netfS), LC_SOLVER, LL_INFO); | |
| 1125 | ✗ | LOGGER_WRITE("IDA: linear solver setups 'nsetups' = " + to_string(nsetups), LC_SOLVER, LL_INFO); | |
| 1126 | ✗ | LOGGER_WRITE("IDA: nonlinear iterations 'nni' = " + to_string(nni), LC_SOLVER, LL_INFO); | |
| 1127 | ✗ | LOGGER_WRITE("IDA: convergence failures 'ncfn' = " + to_string(ncfn), LC_SOLVER, LL_INFO); | |
| 1128 | 1 | } | |
| 1129 | |||
| 1130 | 13350 | int Ida::check_flag(void *flagvalue, const char *funcname, int opt) | |
| 1131 | { | ||
| 1132 | int *errflag; | ||
| 1133 | |||
| 1134 | /* Check if SUNDIALS function returned NULL pointer - no memory allocated */ | ||
| 1135 | |||
| 1136 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 13350 times.
|
13350 | if (opt == 0 && flagvalue == NULL) |
| 1137 | { | ||
| 1138 | ✗ | fprintf(stderr, "\nSUNDIALS_ERROR: %s() failed - returned NULL pointer\n\n", funcname); | |
| 1139 | ✗ | return (1); | |
| 1140 | } | ||
| 1141 | |||
| 1142 | /* Check if flag < 0 */ | ||
| 1143 | |||
| 1144 |
2/2✓ Branch 0 taken 13348 times.
✓ Branch 1 taken 2 times.
|
13350 | else if (opt == 1) |
| 1145 | { | ||
| 1146 | errflag = (int *) flagvalue; | ||
| 1147 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 13348 times.
|
13348 | if (*errflag < 0) |
| 1148 | { | ||
| 1149 | ✗ | fprintf(stderr, "\nSUNDIALS_ERROR: %s() failed with flag = %d\n\n", funcname, *errflag); | |
| 1150 | ✗ | return (1); | |
| 1151 | } | ||
| 1152 | } | ||
| 1153 | |||
| 1154 | /* Check if function returned NULL pointer - no memory allocated */ | ||
| 1155 | |||
| 1156 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | else if (opt == 2 && flagvalue == NULL) |
| 1157 | { | ||
| 1158 | ✗ | fprintf(stderr, "\nMEMORY_ERROR: %s() failed - returned NULL pointer\n\n", funcname); | |
| 1159 | ✗ | return (1); | |
| 1160 | } | ||
| 1161 | |||
| 1162 | return (0); | ||
| 1163 | } | ||
| 1164 | |||
| 1165 | |||
| 1166 | ✗ | void Ida::errOutputIDA(int line, const char *func, const char *file, const char *msg, | |
| 1167 | SUNErrCode err_code, void *err_user_data, SUNContext sunctx) | ||
| 1168 | { | ||
| 1169 | ✗ | cout << "#### IDA error message #####"; | |
| 1170 | cout << " -> error code " << err_code | ||
| 1171 | ✗ | << " in function " << func << " at " << file << ":" << line; | |
| 1172 | /* Package level codes (IDA_* and friends) are not SUNErrCodes, so SUNGetErrMsg() | ||
| 1173 | only makes sense when SUNDIALS did not supply a message. */ | ||
| 1174 | ✗ | cout << " Message: " << (msg ? msg : SUNGetErrMsg(err_code)); | |
| 1175 | ✗ | } | |
| 1176 |