void OpenSMOKE_RADAU<T>::Solve(const double xend) { AnalyzeUserOptions(); this->x_ = this->x0_; this->xend_ = xend; memcpy(this->y_, this->y0_, this->n_*sizeof(double)); this->tStart_ = this->GetClockTime(); #if defined(_WIN32) || defined(_WIN64) if (iSolver_ == solver_radau5) RADAU5( &this->n_, this->odeSystem_->GetSystemFunctionsStatic, &this->x_, this->y_, &this->xend_, &this->firstStep_, &this->relTolerance_[0], &this->absTolerance_[0],&this->iTolerance_, this->odeSystem_->GetAnalyticalJacobianStatic, &this->iJacobian_, &this->mLower_, &this->mUpper_, ptMassMatrix_, &imas_, &mlmas_, &mumas_, this->odeSystem_->GetWriteFunctionStatic, &this->iOutput_, rwork_, &lwork_, iwork_, &liwork_, rpar_, ipar_, &idid_); else if (iSolver_ == solver_radau) RADAU( &this->n_, this->odeSystem_->GetSystemFunctionsStatic, &this->x_, this->y_, &this->xend_, &this->firstStep_, &this->relTolerance_[0], &this->absTolerance_[0],&this->iTolerance_, this->odeSystem_->GetAnalyticalJacobianStatic, &this->iJacobian_, &this->mLower_, &this->mUpper_, ptMassMatrix_, &imas_, &mlmas_, &mumas_, this->odeSystem_->GetWriteFunctionStatic, &this->iOutput_, rwork_, &lwork_, iwork_, &liwork_, rpar_, ipar_, &idid_); #else if (iSolver_ == solver_radau5) radau5_( &this->n_, this->odeSystem_->GetSystemFunctionsStatic, &this->x_, this->y_, &this->xend_, &this->firstStep_, &this->relTolerance_[0], &this->absTolerance_[0],&this->iTolerance_, this->odeSystem_->GetAnalyticalJacobianStatic, &this->iJacobian_, &this->mLower_, &this->mUpper_, ptMassMatrix_, &imas_, &mlmas_, &mumas_, this->odeSystem_->GetWriteFunctionStatic, &this->iOutput_, rwork_, &lwork_, iwork_, &liwork_, rpar_, ipar_, &idid_); else if (iSolver_ == solver_radau) radau_( &this->n_, this->odeSystem_->GetSystemFunctionsStatic, &this->x_, this->y_, &this->xend_, &this->firstStep_, &this->relTolerance_[0], &this->absTolerance_[0],&this->iTolerance_, this->odeSystem_->GetAnalyticalJacobianStatic, &this->iJacobian_, &this->mLower_, &this->mUpper_, ptMassMatrix_, &imas_, &mlmas_, &mumas_, this->odeSystem_->GetWriteFunctionStatic, &this->iOutput_, rwork_, &lwork_, iwork_, &liwork_, rpar_, ipar_, &idid_); #endif this->tEnd_ = this->GetClockTime(); this->x0_ = this->x_; memcpy(this->y0_, this->y_, this->n_*sizeof(double)); }
PyObject* Integrate(double *ic, double t, double hinit, double hmax, double safety, double jacRecompute, double newtonStop, double stepChangeLB, double stepChangeUB, double stepSizeLB, double stepSizeUB, int hessenberg, int maxNewton, int newtonStart, int index1dim, int index2dim, int index3dim, int stepSizeStrategy, int DAEstructureM1, int DAEstructureM2, int useJac, int useMass, int verbose, int calcAux, int calcSpecTimes) { int i, j; double stats[7]; double hlast = -1; int idid = 0; /* Return code from radau5. Codes are: 1 - Successful 2 - Successful, interrupted by solout -1 - Input not consistent -2 - Larger max steps is needed -3 - Step size becomes too small -4 - Matrix is repeatedly singular */ int iout = DENSE_OUTPUT_CALL; /* Call solout at each step */ int itol = VECTOR_ERR_TOL; /* rtol, atol are vectors; must pass point to int */ int *ipar = NULL; /* No integer parameter array */ int phaseDim = 0; double tinit = 0; double tend = 0; int ijac = 0; /* if we setup Jac to return correctly oriented jacobian */ int imas = 0; /* supposed to be identity, so not DAE */ int mljac = 0; int mujac = 0; /* Bandedness not accounted for yet. */ int mlmas = 0; int mumas = 0; int lwork = 0; int liwork = 0; FILE *ErrOut = NULL; assert( gIData ); assert( gICs ); assert( ic ); if( gIData->isInitBasic != 1 || gIData->isInitIntegData != 1 ) { return PackOut(gIData, gICs, FAILURE, stats, hlast, idid); } /* Set whether to calculate output at specific times on this run */ gIData->calcSpecTimes = calcSpecTimes; gIData->calcAux = calcAux; for( i = 0; i < gIData->phaseDim; i++ ) { gIData->gIC[i] = ic[i]; } /* Call RADAU5 */ if( verbose == 1 ) ErrOut = stderr; /* for NumArray compatibility */ import_libnumarray(); phaseDim = gIData->phaseDim; tinit = t; tend = gIData->tEnd; ijac = (useJac && gIData->hasJac) ? 1 : 0; imas = (useMass && gIData->hasMass) ? 1 : 0; /* Set the direction of integration */ gIData->direction = (t < gIData->tEnd ) ? 1 : -1; /* Call RADAU5 */ if( InitializeRadauOptions( gIData, UROUND, safety, jacRecompute, newtonStop, stepChangeLB, stepChangeUB, hmax, stepSizeLB, stepSizeUB, hessenberg, gIData->maxPts, maxNewton, newtonStart, index1dim, index2dim, index3dim, stepSizeStrategy, DAEstructureM1, DAEstructureM2 ) != SUCCESS ) { return PackOut(gIData, gICs, FAILURE, stats, hlast, idid); } mljac = gIData->jacLowerBandwidth; mujac = gIData->jacUpperBandwidth; mlmas = gIData->masLowerBandwidth; mumas = gIData->masUpperBandwidth; lwork = gIData->workArrayLen; liwork = gIData->intWorkArrayLen; radau5_(&phaseDim, vfield, &tinit, gIData->gIC, &tend, &hinit, gIData->gRTol, gIData->gATol, &itol, vfieldjac, &ijac, &mljac, &mujac, vfieldmas, &imas, &mlmas, &mumas, radau_solout, &iout, gIData->gWorkArray, &lwork, gIData->gIntWorkArray, &liwork, gIData->gParams, ipar, &idid, radau_adjust_h); gIData->hasRun = 1; /* Stats are: 0 - Num function evals 1 - Num Jacobian evals 2 - Num computed steps 3 - Num accepted steps 4 - Num rejected steps 5 - Num LU decompositions 6 - Num Forward-Backward substitutions */ for( i = 0; i < 7; i++ ) { stats[i] = gIData->gIntWorkArray[i + 13]; } /* FORTRAN Radau5 routine puts last H step in hinit */ hlast = hinit; if( N_AUXVARS > 0 && calcAux != 0 ) { AuxVarCalc( gIData ); } return PackOut(gIData, gICs, SUCCESS, stats, hlast, idid); }