PetscErrorCode TSView_Sundials(TS ts,PetscViewer viewer) { TS_Sundials *cvode = (TS_Sundials*)ts->data; PetscErrorCode ierr; char *type; char atype[] = "Adams"; char btype[] = "BDF: backward differentiation formula"; PetscBool iascii,isstring; long int nsteps,its,nfevals,nlinsetups,nfails,itmp; PetscInt qlast,qcur; PetscReal hinused,hlast,hcur,tcur,tolsfac; PC pc; PetscFunctionBegin; if (cvode->cvode_type == SUNDIALS_ADAMS) type = atype; else type = btype; ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); if (iascii) { ierr = PetscViewerASCIIPrintf(viewer,"Sundials integrater does not use SNES!\n");CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Sundials integrater type %s\n",type);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Sundials abs tol %g rel tol %g\n",cvode->abstol,cvode->reltol);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Sundials linear solver tolerance factor %g\n",cvode->linear_tol);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Sundials max dimension of Krylov subspace %D\n",cvode->maxl);CHKERRQ(ierr); if (cvode->gtype == SUNDIALS_MODIFIED_GS) { ierr = PetscViewerASCIIPrintf(viewer,"Sundials using modified Gram-Schmidt for orthogonalization in GMRES\n");CHKERRQ(ierr); } else { ierr = PetscViewerASCIIPrintf(viewer,"Sundials using unmodified (classical) Gram-Schmidt for orthogonalization in GMRES\n");CHKERRQ(ierr); } if (cvode->mindt > 0) {ierr = PetscViewerASCIIPrintf(viewer,"Sundials minimum time step %g\n",cvode->mindt);CHKERRQ(ierr);} if (cvode->maxdt > 0) {ierr = PetscViewerASCIIPrintf(viewer,"Sundials maximum time step %g\n",cvode->maxdt);CHKERRQ(ierr);} /* Outputs from CVODE, CVSPILS */ ierr = CVodeGetTolScaleFactor(cvode->mem,&tolsfac);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Sundials suggested factor for tolerance scaling %g\n",tolsfac);CHKERRQ(ierr); ierr = CVodeGetIntegratorStats(cvode->mem,&nsteps,&nfevals, &nlinsetups,&nfails,&qlast,&qcur, &hinused,&hlast,&hcur,&tcur);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Sundials cumulative number of internal steps %D\n",nsteps);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of calls to rhs function %D\n",nfevals);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of calls to linear solver setup function %D\n",nlinsetups);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of error test failures %D\n",nfails);CHKERRQ(ierr); ierr = CVodeGetNonlinSolvStats(cvode->mem,&its,&nfails);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of nonlinear solver iterations %D\n",its);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of nonlinear convergence failure %D\n",nfails);CHKERRQ(ierr); ierr = CVSpilsGetNumLinIters(cvode->mem, &its);CHKERRQ(ierr); /* its = no. of calls to TSPrecond_Sundials() */ ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of linear iterations %D\n",its);CHKERRQ(ierr); ierr = CVSpilsGetNumConvFails(cvode->mem,&itmp);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of linear convergence failures %D\n",itmp);CHKERRQ(ierr); ierr = TSSundialsGetPC(ts,&pc);CHKERRQ(ierr); ierr = PCView(pc,viewer);CHKERRQ(ierr); ierr = CVSpilsGetNumPrecEvals(cvode->mem,&itmp);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of preconditioner evaluations %D\n",itmp);CHKERRQ(ierr); ierr = CVSpilsGetNumPrecSolves(cvode->mem,&itmp);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of preconditioner solves %D\n",itmp);CHKERRQ(ierr); ierr = CVSpilsGetNumJtimesEvals(cvode->mem,&itmp);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of Jacobian-vector product evaluations %D\n",itmp);CHKERRQ(ierr); ierr = CVSpilsGetNumRhsEvals(cvode->mem,&itmp);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of rhs calls for finite diff. Jacobian-vector evals %D\n",itmp);CHKERRQ(ierr); } else if (isstring) { ierr = PetscViewerStringSPrintf(viewer,"Sundials type %s",type);CHKERRQ(ierr); } PetscFunctionReturn(0); }
void Cvode::writeSimulationInfo() { long int nst, nfe, nsetups, nni, ncfn, netf; long int nfQe, netfQ; long int nfSe, nfeS, nsetupsS, nniS, ncfnS, netfS; long int nfQSe, netfQS; int qlast, qcur; realtype h0u, hlast, hcur, tcur; int flag; flag = CVodeGetIntegratorStats(_cvodeMem, &nst, &nfe, &nsetups, &netf, &qlast, &qcur, &h0u, &hlast, &hcur, &tcur); flag = CVodeGetNonlinSolvStats(_cvodeMem, &nni, &ncfn); LOGGER_WRITE("Cvode: number steps = " + to_string(nst), LC_SOLV, LL_INFO); LOGGER_WRITE("Cvode: function evaluations 'f' = " + to_string(nfe), LC_SOLV, LL_INFO); LOGGER_WRITE("Cvode: error test failures 'netf' = " + to_string(netfS), LC_SOLV, LL_INFO); LOGGER_WRITE("Cvode: linear solver setups 'nsetups' = " + to_string(nsetups), LC_SOLV, LL_INFO); LOGGER_WRITE("Cvode: nonlinear iterations 'nni' = " + to_string(nni), LC_SOLV, LL_INFO); LOGGER_WRITE("Cvode: convergence failures 'ncfn' = " + to_string(ncfn), LC_SOLV, LL_INFO); LOGGER_WRITE("Cvode: number of evaluateODE calls 'eODE' = " + to_string(_numberOfOdeEvaluations), LC_SOLV, LL_INFO); //// Solver //outputStream << "\nSolver: " << getName() // << "\nVerfahren: "; //if(_cvodesettings->iMethod == EulerSettings::EULERFORWARD) // outputStream << " Expliziter Cvode\n\n"; //else if(_cvodesettings->iMethod == EulerSettings::EULERBACKWARD) // outputStream << " Impliziter Cvode\n\n"; //// System //outputStream // << "Dimension des Systems (ODE): " << (int)_dimSys << "\n"; //// Status, Anzahl Schritte, Nullstellenzeugs //SolverDefaultImplementation::writeSimulationInfo(outputStream); //// Nullstellensuche //if (_cvodesettings->iZeroSearchMethod == SolverSettings::NO_ZERO_SEARCH) //{ // outputStream << "Nullstellensuche: Keine\n\n" << endl; //} //else //{ // /*if (_cvodesettings->iZeroSearchMethod == SolverSettings::BISECTION) // { // outputStream << "Nullstellensuche: Bisektion\n" << endl; // } // else // {*/ // outputStream << "Nullstellensuche: Lineare Interpolation\n" << endl; // /*}*/ //} //// Schritteweite //outputStream // << "ausgegebene Schritte: " << _outStps << "\n" // << "Anfangsschrittweite: " << _cvodesettings->dH_init << "\n" // << "Ausgabeschrittweite: " << dynamic_cast<ISolverSettings*>(_cvodesettings)->getGlobalSettings()->gethOutput() << "\n" // << "Obere Grenze für Schrittweite: " << _hUpLim << "\n\n"; //// Status //outputStream // << "Solver-Status: " << _idid << "\n\n"; }
void FCV_CVODE(realtype *tout, realtype *t, realtype *y, int *itask, int *ier) { realtype h0u; int qu, qcur; /* tout is the t value where output is desired F2C_vec is the N_Vector containing the solution on return t is the returned independent variable value itask is the task indicator (1 = CV_NORMAL, 2 = CV_ONE_STEP, 3 = CV_NORMAL_TSTOP, 4 = CV_ONE_STEP_TSTOP) */ *ier = CVode(CV_cvodemem, *tout, F2C_vec, t, *itask); y = N_VGetArrayPointer(F2C_vec); /* Load optional outputs in iopt & ropt */ if ( (CV_iopt != NULL) && (CV_ropt != NULL) ) { CVodeGetIntegratorStats(CV_cvodemem, &CV_iopt[3], /* NST */ &CV_iopt[4], /* NFE */ &CV_iopt[5], /* NSETUPS */ &CV_iopt[8], /* NETF */ &qu, &qcur, &h0u, &CV_ropt[3], /* HU */ &CV_ropt[4], /* HCUR */ &CV_ropt[5]); /* TCUR */ CV_iopt[9] = (long int)qu; /* QU */ CV_iopt[10] = (long int)qcur; /* QCUR */ CVodeGetTolScaleFactor(CV_cvodemem, &CV_ropt[6]); CVodeGetNonlinSolvStats(CV_cvodemem, &CV_iopt[6], /* NNI */ &CV_iopt[7]); /* NCFN */ CVodeGetWorkSpace(CV_cvodemem, &CV_iopt[11], /* LENRW */ &CV_iopt[12]); /* LENIW */ if (CV_optin && (CV_iopt[13] > 0)) CVodeGetNumStabLimOrderReds(CV_cvodemem, &CV_iopt[14]); /* NOR */ /* Root finding is on */ if (CV_nrtfn != 0) CVodeGetNumGEvals(CV_cvodemem, &CV_iopt[24]); switch(CV_ls) { case 1: CVDenseGetWorkSpace(CV_cvodemem, &CV_iopt[15], &CV_iopt[16]); /* LRW and LIW */ CVDenseGetNumJacEvals(CV_cvodemem, &CV_iopt[17]); /* NJE */ CVDenseGetLastFlag(CV_cvodemem, (int *) &CV_iopt[25]); /* last linear solver flag */ break; case 2: CVBandGetWorkSpace(CV_cvodemem, &CV_iopt[15], &CV_iopt[16]); /* LRW and LIW */ CVBandGetNumJacEvals(CV_cvodemem, &CV_iopt[17]); /* NJE */ CVBandGetLastFlag(CV_cvodemem, (int *) &CV_iopt[25]); /* last linear solver flag */ break; case 3: CVDiagGetWorkSpace(CV_cvodemem, &CV_iopt[15], &CV_iopt[16]); /* LRW and LIW */ CVDiagGetLastFlag(CV_cvodemem, (int *) &CV_iopt[25]); /* last linear solver flag */ break; case 4: CVSpgmrGetWorkSpace(CV_cvodemem, &CV_iopt[15], &CV_iopt[16]); /* LRW and LIW */ CVSpgmrGetNumPrecEvals(CV_cvodemem, &CV_iopt[17]); /* NPE */ CVSpgmrGetNumLinIters(CV_cvodemem, &CV_iopt[18]); /* NLI */ CVSpgmrGetNumPrecSolves(CV_cvodemem, &CV_iopt[19]); /* NPS */ CVSpgmrGetNumConvFails(CV_cvodemem, &CV_iopt[20]); /* NCFL */ CVSpgmrGetLastFlag(CV_cvodemem, (int *) &CV_iopt[25]); /* last linear solver flag */ break; } } }
void Cvode::solve(const SOLVERCALL action) { bool writeEventOutput = (_settings->getGlobalSettings()->getOutputPointType() == OPT_ALL); bool writeOutput = !(_settings->getGlobalSettings()->getOutputPointType() == OPT_NONE); #ifdef RUNTIME_PROFILING MEASURETIME_REGION_DEFINE(cvodeSolveFunctionHandler, "solve"); if(MeasureTime::getInstance() != NULL) { MEASURETIME_START(solveFunctionStartValues, cvodeSolveFunctionHandler, "solve"); } #endif if (_cvodesettings && _system) { // Solver und System für Integration vorbereiten if ((action & RECORDCALL) && (action & FIRST_CALL)) { #ifdef RUNTIME_PROFILING MEASURETIME_REGION_DEFINE(cvodeInitializeHandler, "CVodeInitialize"); if(MeasureTime::getInstance() != NULL) { MEASURETIME_START(measuredFunctionStartValues, cvodeInitializeHandler, "CVodeInitialize"); } #endif initialize(); #ifdef RUNTIME_PROFILING if(MeasureTime::getInstance() != NULL) { MEASURETIME_END(measuredFunctionStartValues, measuredFunctionEndValues, (*measureTimeFunctionsArray)[4], cvodeInitializeHandler); } #endif if (writeOutput) writeToFile(0, _tCurrent, _h); _tLastWrite = 0; return; } if ((action & RECORDCALL) && !(action & FIRST_CALL)) { writeToFile(_accStps, _tCurrent, _h); return; } // Nach einem TimeEvent wird der neue Zustand recorded if (action & RECALL) { _firstStep = true; if (writeEventOutput) writeToFile(0, _tCurrent, _h); if (writeOutput) writeCVodeOutput(_tCurrent, _h, _locStps); _continuous_system->getContinuousStates(_z); } // Solver soll fortfahren _solverStatus = ISolver::CONTINUE; while ((_solverStatus & ISolver::CONTINUE) && !_interrupt ) { // Zuvor wurde initialize aufgerufen und hat funktioniert => RESET IDID if (_idid == 5000) _idid = 0; // Solveraufruf if (_idid == 0) { // Zähler zurücksetzen _accStps = 0; _locStps = 0; // Solverstart CVodeCore(); } // Integration war nicht erfolgreich und wurde auch nicht vom User unterbrochen if (_idid != 0 && _idid != 1) { _solverStatus = ISolver::SOLVERERROR; //throw ModelicaSimulationError(SOLVER,_idid,_tCurrent,"CVode::solve()"); throw ModelicaSimulationError(SOLVER,"CVode::solve()"); } // Abbruchkriterium (erreichen der Endzeit) else if ((_tEnd - _tCurrent) <= dynamic_cast<ISolverSettings*>(_cvodesettings)->getEndTimeTol()) _solverStatus = DONE; } _firstCall = false; } else { throw ModelicaSimulationError(SOLVER,"CVode::solve()"); } #ifdef RUNTIME_PROFILING if(MeasureTime::getInstance() != NULL) { MEASURETIME_END(solveFunctionStartValues, solveFunctionEndValues, (*measureTimeFunctionsArray)[1], cvodeSolveFunctionHandler); long int nst, nfe, nsetups, netf, nni, ncfn; int qlast, qcur; realtype h0u, hlast, hcur, tcur; int flag; flag = CVodeGetIntegratorStats(_cvodeMem, &nst, &nfe, &nsetups, &netf, &qlast, &qcur, &h0u, &hlast, &hcur, &tcur); flag = CVodeGetNonlinSolvStats(_cvodeMem, &nni, &ncfn); MeasureTimeValuesSolver solverVals = MeasureTimeValuesSolver(nfe, netf); (*measureTimeFunctionsArray)[6]->_sumMeasuredValues->_numCalcs += nst; (*measureTimeFunctionsArray)[6]->_sumMeasuredValues->add(&solverVals); } #endif }
void FCV_CVODE(realtype *tout, realtype *t, realtype *y, int *itask, int *ier) { /* tout is the t value where output is desired F2C_CVODE_vec is the N_Vector containing the solution on return t is the returned independent variable value itask is the task indicator (1 = CV_NORMAL, 2 = CV_ONE_STEP, 3 = CV_NORMAL_TSTOP, 4 = CV_ONE_STEP_TSTOP) */ int qu, qcur; N_VSetArrayPointer(y, F2C_CVODE_vec); *ier = CVode(CV_cvodemem, *tout, F2C_CVODE_vec, t, *itask); N_VSetArrayPointer(NULL, F2C_CVODE_vec); /* Load optional outputs in iout & rout */ CVodeGetWorkSpace(CV_cvodemem, &CV_iout[0], /* LENRW */ &CV_iout[1]); /* LENIW */ CVodeGetIntegratorStats(CV_cvodemem, &CV_iout[2], /* NST */ &CV_iout[3], /* NFE */ &CV_iout[7], /* NSETUPS */ &CV_iout[4], /* NETF */ &qu, /* QU */ &qcur, /* QCUR */ &CV_rout[0], /* H0U */ &CV_rout[1], /* HU */ &CV_rout[2], /* HCUR */ &CV_rout[3]); /* TCUR */ CV_iout[8] = (long int) qu; CV_iout[9] = (long int) qcur; CVodeGetTolScaleFactor(CV_cvodemem, &CV_rout[4]); /* TOLSFAC */ CVodeGetNonlinSolvStats(CV_cvodemem, &CV_iout[6], /* NNI */ &CV_iout[5]); /* NCFN */ CVodeGetNumStabLimOrderReds(CV_cvodemem, &CV_iout[10]); /* NOR */ /* Root finding is on */ if (CV_nrtfn != 0) CVodeGetNumGEvals(CV_cvodemem, &CV_iout[11]); /* NGE */ switch(CV_ls) { case CV_LS_STD: CVodeGetLinWorkSpace(CV_cvodemem, &CV_iout[12], &CV_iout[13]); /* LENRWLS,LENIWLS */ CVodeGetLastLinFlag(CV_cvodemem, &CV_iout[14]); /* LSTF */ CVodeGetNumLinRhsEvals(CV_cvodemem, &CV_iout[15]); /* NFELS */ CVodeGetNumJacEvals(CV_cvodemem, &CV_iout[16]); /* NJE */ CVodeGetNumJTSetupEvals(CV_cvodemem, &CV_iout[17]); /* NJTS */ CVodeGetNumJtimesEvals(CV_cvodemem, &CV_iout[18]); /* NJTV */ CVodeGetNumPrecEvals(CV_cvodemem, &CV_iout[19]); /* NPE */ CVodeGetNumPrecSolves(CV_cvodemem, &CV_iout[20]); /* NPS */ CVodeGetNumLinIters(CV_cvodemem, &CV_iout[21]); /* NLI */ CVodeGetNumLinConvFails(CV_cvodemem, &CV_iout[22]); /* NCFL */ break; case CV_LS_DIAG: CVDiagGetWorkSpace(CV_cvodemem, &CV_iout[12], &CV_iout[13]); /* LENRWLS,LENIWLS */ CVDiagGetLastFlag(CV_cvodemem, &CV_iout[14]); /* LSTF */ CVDiagGetNumRhsEvals(CV_cvodemem, &CV_iout[15]); /* NFELS */ } }