CAMLprim value sunml_lsolver_lapack_band(value vnvec, value vbmat) { CAMLparam2(vnvec, vbmat); #if SUNDIALS_LIB_VERSION >= 300 && defined SUNDIALS_ML_LAPACK SUNMatrix bmat = MAT_VAL(vbmat); SUNLinearSolver ls = SUNLapackBand(NVEC_VAL(vnvec), bmat); if (ls == NULL) { if (SUNBandMatrix_Rows(bmat) != SUNBandMatrix_Columns(bmat)) caml_raise_constant(LSOLVER_EXN(MatrixNotSquare)); if (SUNBandMatrix_StoredUpperBandwidth(bmat) < SUNMIN(SUNBandMatrix_Rows(bmat) - 1, SUNBandMatrix_LowerBandwidth(bmat) + SUNBandMatrix_UpperBandwidth(bmat))) caml_raise_constant(LSOLVER_EXN(InsufficientStorageUpperBandwidth)); if (SUNBandMatrix_Rows(bmat) != NV_LENGTH_S(NVEC_VAL(vnvec))) caml_raise_constant(LSOLVER_EXN(MatrixVectorMismatch)); caml_raise_out_of_memory(); } CAMLreturn(alloc_lsolver(ls)); #else CAMLreturn(Val_unit); #endif }
void OpenSMOKE_CVODE_Sundials<T>::Solve(const double xend) { int flag; this->x_ = this->x0_; this->xend_ = xend; for(int i=0;i<this->n_;i++) NV_Ith_S(y0Sundials_,i) = this->y0_[i]; if (firstCall_ == true) { firstCall_ = false; /* Call CVodeCreate to create the solver memory and specify the * Backward Differentiation Formula and the use of a Newton iteration */ cvode_mem_ = CVodeCreate(CV_BDF, CV_NEWTON); if (check_flag((void *)cvode_mem_, std::string("CVodeCreate"), 0)) exit(-1); /* Call CVodeInit to initialize the integrator memory and specify the * user's right hand side function in y'=f(t,y), the inital time t0, and * the initial dependent variable vector y0Sundials_. */ flag = CVodeInit(cvode_mem_, this->odeSystem_->GetSystemFunctionsStatic, this->odeSystem_->GetWriteFunctionStatic, this->x0_, y0Sundials_); if (check_flag(&flag, std::string("CVodeInit"), 1)) exit(-1); /* Call CVodeSVtolerances to specify the scalar relative tolerance * and vector absolute tolerances */ flag = CVodeSStolerances(cvode_mem_, this->relTolerance_[0], this->absTolerance_[0]); if (check_flag(&flag, std::string("CVodeSVtolerances"), 1)) exit(-1); /* Call Solver */ if (this->iUseLapack_ == false) { if (this->mUpper_ == 0 && this->mLower_ == 0) { // std::cout << "CVODE Solver: Dense Jacobian (without Lapack)..." << std::endl; /* Create dense SUNMatrix for use in linear solves */ A = SUNDenseMatrix(this->n_, this->n_); if (check_flag((void *)A, std::string("SUNDenseMatrix"), 0)) exit(-1); /* Create SUNDenseLinearSolver solver object for use by CVode */ LS = SUNDenseLinearSolver(ySundials_, A); if (check_flag((void *)LS, std::string("SUNDenseLinearSolver"), 0)) exit(-1); } else { // std::cout << "CVODE Solver: Band Jacobian (without Lapack)..." << std::endl; /* Create banded SUNMatrix for use in linear solves -- since this will be factored, set the storage bandwidth to be the sum of upper and lower bandwidths */ A = SUNBandMatrix(this->n_, this->mUpper_, this->mLower_, (this->mUpper_+this->mLower_) ); if (check_flag((void *)A, std::string("SUNBandMatrix"), 0)) exit(-1); /* Create banded SUNLinearSolver object for use by CVode */ LS = SUNBandLinearSolver(ySundials_, A); if (check_flag((void *)LS, std::string("SUNBandLinearSolver"), 0)) exit(-1); } } else { if (this->mUpper_ == 0 && this->mLower_ == 0) { // std::cout << "CVODE Solver: Dense Jacobian (with Lapack)..." << std::endl; /* Create dense SUNMatrix for use in linear solves */ A = SUNDenseMatrix(this->n_, this->n_); if (check_flag((void *)A, std::string("SUNDenseMatrix"), 0)) exit(-1); /* Create SUNLapackDense solver object for use by CVode */ LS = SUNLapackDense(ySundials_, A); if (check_flag((void *)LS, std::string("SUNLapackDense"), 0)) exit(-1); } else { // std::cout << "CVODE Solver: Band Jacobian (with Lapack)..." << std::endl; /* Create banded SUNMatrix for use in linear solves -- since this will be factored, set the storage bandwidth to be the sum of upper and lower bandwidths */ A = SUNBandMatrix(this->n_, this->mUpper_, this->mLower_, (this->mUpper_ + this->mLower_)); if (check_flag((void *)A, std::string("SUNBandMatrix"), 0)) exit(-1); /* Create banded SUNLapackBand solver object for use by CVode */ LS = SUNLapackBand(ySundials_, A); if (check_flag((void *)LS, std::string("SUNLapackBand"), 0)) exit(-1); } } /* Call CVDlsSetLinearSolver to attach the matrix and linear solver to CVode */ flag = CVDlsSetLinearSolver(cvode_mem_, LS, A); if (check_flag(&flag, std::string("CVDlsSetLinearSolver"), 1)) exit(-1); } else { flag = CVodeReInit(cvode_mem_, this->x0_, y0Sundials_); if (check_flag(&flag, std::string("CVodeReInit"), 1)) exit(-1); } AnalyzeUserOptions(); /* Solving */ this->tStart_ = this->GetClockTime(); flag = CVode(cvode_mem_, this->xend_, ySundials_, &this->x_, CV_NORMAL); this->tEnd_ = this->GetClockTime(); this->x0_ = this->x_; for(int i=0;i<this->n_;i++) NV_Ith_S(y0Sundials_,i) = NV_Ith_S(ySundials_,i); for(int i=0;i<this->n_;i++) this->y_[i] = NV_Ith_S(ySundials_,i); }