int cvode_eval(solver_props *props, unsigned int modelid){ cvode_mem *mem = props->mem; mem = &mem[modelid]; // Stop the solver if the stop time has been reached props->running[modelid] = (props->time[modelid] + props->timestep) < props->stoptime; if(!props->running[modelid]) return 0; // if a positive dt is specified, then we will have this function return after it reaches the next time point, // otherwise, it will just run one iteration and return if(props->timestep > 0) { // Reinitialize the function at each step if(CVodeReInit(mem->cvmem, props->time[modelid], mem->y0) != CV_SUCCESS) { PRINTF( "CVODE failed to reinitialize"); } CDATAFORMAT stop_time = MIN(props->time[modelid] + props->timestep, props->stoptime); mem->first_iteration = TRUE; if(CVode(mem->cvmem, stop_time, mem->y0, &(props->next_time[modelid]), CV_NORMAL) != CV_SUCCESS){ PRINTF( "CVODE failed to make a fixed step in model %d.\n", modelid); return 1; } } else { mem->first_iteration = TRUE; if(CVode(mem->cvmem, props->stoptime, mem->y0, &(props->next_time[modelid]), CV_ONE_STEP) != CV_SUCCESS){ PRINTF( "CVODE failed to make a step in model %d.\n", modelid); return 1; } } return 0; }
void ode_solver_reinit(ode_solver* solver, const double t0, double* y0, int lenY, const double* p, int lenP ){ int i,flag; /* Get initial conditions */ if(y0 != 0){ if( lenY != solver->odeModel->N ){ fprintf(stderr,"ode_solver_init: lenY must be equal %d, the number of variables in the ode model.\n",solver->odeModel->N); return ; } NV_DATA_S(solver->y) = y0; } else { NV_DATA_S(solver->y) = solver->odeModel->v; } /* re-initialise */ flag = CVodeReInit(solver->cvode_mem, t0, solver->y); /* Get parameters */ if (p != 0){ if (lenP != solver->odeModel->P) { fprintf(stderr,"ode_solver_init: lenP must be equal %d, the number of parameters in the ode model.\n",solver->odeModel->P); return ; } int P = solver->odeModel->P; for(i = 0; i < P; i++) solver->params[i] = p[i]; flag = CVodeSetUserData(solver->cvode_mem, solver->params); } }
int CVodeReInitB(void *cvadj_mem, CVRhsFnB fB, realtype tB0, N_Vector yB0, int itolB, realtype reltolB, void *abstolB) { CVadjMem ca_mem; void *cvode_mem; int sign, flag; if (cvadj_mem == NULL) return(CV_ADJMEM_NULL); ca_mem = (CVadjMem) cvadj_mem; sign = (tfinal - tinitial > ZERO) ? 1 : -1; if ( (sign*(tB0-tinitial) < ZERO) || (sign*(tfinal-tB0) < ZERO) ) return(CV_BAD_TB0); f_B = fB; cvode_mem = (void *) ca_mem->cvb_mem; flag = CVodeReInit(cvode_mem, CVArhs, tB0, yB0, itolB, reltolB, abstolB); if (flag != CV_SUCCESS) return(flag); CVodeSetMaxHnilWarns(cvode_mem, -1); CVodeSetFdata(cvode_mem, cvadj_mem); return(CV_SUCCESS); }
void FCV_REINIT(realtype *t0, realtype *y0, int *iatol, realtype *rtol, realtype *atol, int *ier) { N_Vector Vatol; *ier = 0; /* Initialize all pointers to NULL */ Vatol = NULL; /* Set data in F2C_CVODE_vec to y0 */ N_VSetArrayPointer(y0, F2C_CVODE_vec); /* Call CVReInit */ *ier = CVodeReInit(CV_cvodemem, *t0, F2C_CVODE_vec); /* Reset data pointers */ N_VSetArrayPointer(NULL, F2C_CVODE_vec); /* On failure, exit */ if (*ier != CV_SUCCESS) { *ier = -1; return; } /* Set tolerances */ switch (*iatol) { case 1: *ier = CVodeSStolerances(CV_cvodemem, *rtol, *atol); break; case 2: Vatol = NULL; Vatol = N_VCloneEmpty(F2C_CVODE_vec); if (Vatol == NULL) { *ier = -1; return; } N_VSetArrayPointer(atol, Vatol); *ier = CVodeSVtolerances(CV_cvodemem, *rtol, Vatol); N_VDestroy(Vatol); break; } /* On failure, exit */ if (*ier != CV_SUCCESS) { *ier = -1; return; } return; }
void CVodesIntegrator::reinitialize(double t0, FuncEval& func) { m_t0 = t0; m_time = t0; func.getState(NV_DATA_S(m_y)); int result = CVodeReInit(m_cvode_mem, m_t0, m_y); if (result != CV_SUCCESS) { throw CanteraError("CVodesIntegrator::reinitialize", "CVodeReInit failed. result = {}", result); } applyOptions(); }
void CVodesIntegrator::reinitialize(double t0, FuncEval& func) { m_t0 = t0; m_time = t0; func.getInitialConditions(m_t0, static_cast<sd_size_t>(m_neq), NV_DATA_S(m_y)); int result; result = CVodeReInit(m_cvode_mem, m_t0, m_y); if (result != CV_SUCCESS) { throw CVodesErr("CVodeReInit failed. result = "+int2str(result)); } applyOptions(); }
void CVodesIntegrator::reinitialize(double t0, FuncEval& func) { m_t0 = t0; //try { func.getInitialConditions(m_t0, m_neq, NV_DATA_S(nv(m_y))); //} //catch (CanteraError) { //showErrors(); //error("Teminating execution"); //} int result, flag; #if defined(SUNDIALS_VERSION_22) || defined(SUNDIALS_VERSION_23) if (m_itol == CV_SV) { result = CVodeReInit(m_cvode_mem, cvodes_rhs, m_t0, nv(m_y), m_itol, m_reltol, nv(m_abstol)); } else { result = CVodeReInit(m_cvode_mem, cvodes_rhs, m_t0, nv(m_y), m_itol, m_reltol, &m_abstols); } if (result != CV_SUCCESS) { throw CVodesErr("CVodeReInit failed. result = "+int2str(result)); } #elif defined(SUNDIALS_VERSION_24) result = CVodeReInit(m_cvode_mem, m_t0, nv(m_y)); if (result != CV_SUCCESS) { throw CVodesErr("CVodeReInit failed. result = "+int2str(result)); } #endif if (m_type == DENSE + NOJAC) { long int N = m_neq; CVDense(m_cvode_mem, N); } else if (m_type == DIAG) { CVDiag(m_cvode_mem); } else if (m_type == BAND + NOJAC) { long int N = m_neq; long int nu = m_mupper; long int nl = m_mlower; CVBand(m_cvode_mem, N, nu, nl); } else if (m_type == GMRES) { CVSpgmr(m_cvode_mem, PREC_NONE, 0); } else { throw CVodesErr("unsupported option"); } // set options if (m_maxord > 0) flag = CVodeSetMaxOrd(m_cvode_mem, m_maxord); if (m_maxsteps > 0) flag = CVodeSetMaxNumSteps(m_cvode_mem, m_maxsteps); if (m_hmax > 0) flag = CVodeSetMaxStep(m_cvode_mem, m_hmax); }
bool Bloch_McConnell_CV_Model::Calculate(double next_tStop){ if ( m_world->time < RTOL) m_world->time += RTOL; CVodeSetStopTime(m_cvode_mem,next_tStop); cout<<NV_Ith_S( ((bmnvec*) (m_world->solverSettings))->y,ZC ) << " "<< NV_Ith_S( ((bmnvec*) (m_world->solverSettings))->y,ZC+3 )<<endl; int flag; #ifndef CVODE26 flag = CVode(m_cvode_mem, m_world->time, ((bmnvec*) (m_world->solverSettings))->y, &m_tpoint, CV_NORMAL_TSTOP); #else do { flag=CVode(m_cvode_mem, m_world->time, ((bmnvec*) (m_world->solverSettings))->y, &m_tpoint, CV_NORMAL); } while ((flag==CV_TSTOP_RETURN) && (m_world->time-TIME_ERR_TOL > m_tpoint )); #endif if(flag < 0) m_world->solverSuccess=false; //reinit needed? if ( m_world->phase == -2.0 && m_world->solverSuccess ) { #ifndef CVODE26 CVodeReInit(m_cvode_mem,bloch,m_world->time + TIME_ERR_TOL,((bmnvec*) (m_world->solverSettings))->y,CV_SV,m_reltol,((bmnvec*) (m_world->solverSettings))->abstol); #else CVodeReInit(m_cvode_mem,m_world->time + TIME_ERR_TOL,((bmnvec*) (m_world->solverSettings))->y); #endif // avoiding warnings: (no idea why initial guess of steplength does not work right here...) CVodeSetInitStep(m_cvode_mem,m_world->pAtom->GetDuration()/1e9); } // loop over pools, stepsize NEQ for ( int i = 0; i< m_ncomp*NEQ; i+=NEQ ) { double solution_dummy_x = NV_Ith_S(((bmnvec*) (m_world->solverSettings))->y, XC+i ); double solution_dummy_y = NV_Ith_S(((bmnvec*) (m_world->solverSettings))->y, YC+i ); m_world->solution[AMPL+i] = sqrt(solution_dummy_x*solution_dummy_x + solution_dummy_y*solution_dummy_y); if (m_world->solution[AMPL+i] < EPS) m_world->solution[PHASE+i] = 0; else if (solution_dummy_y < 0 ) m_world->solution[PHASE+i] = 2*PI - acos(solution_dummy_x / m_world->solution[AMPL+i]); else m_world->solution[PHASE+i] = acos(solution_dummy_x / m_world->solution[AMPL+i]); m_world->solution[ZC+i] = NV_Ith_S(((bmnvec*) (m_world->solverSettings))->y, ZC+i ); // Kaveh, hier sind dann alle pools gleich :( //cout << " bloch solution "<<m_world->solution[ZC+i]<< " " <<" i " << i <<endl; } //higher accuray than 1e-10 not useful. Return success and hope for the best. if(m_reltol < 1e-10) m_world->solverSuccess=true; return m_world->solverSuccess; }
int main() { realtype abstol, reltol, t, tout; N_Vector u; UserData data; void *cvode_mem; int flag, iout, jpre; long int ml, mu; u = NULL; data = NULL; cvode_mem = NULL; /* Allocate and initialize u, and set problem data and tolerances */ u = N_VNew_Serial(NEQ); if(check_flag((void *)u, "N_VNew_Serial", 0)) return(1); data = (UserData) malloc(sizeof *data); if(check_flag((void *)data, "malloc", 2)) return(1); InitUserData(data); SetInitialProfiles(u, data->dx, data->dy); abstol = ATOL; reltol = RTOL; /* 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, "CVodeCreate", 0)) return(1); /* Set the pointer to user-defined data */ flag = CVodeSetUserData(cvode_mem, data); if(check_flag(&flag, "CVodeSetUserData", 1)) return(1); /* Call CVodeInit to initialize the integrator memory and specify the * user's right hand side function in u'=f(t,u), the inital time T0, and * the initial dependent variable vector u. */ flag = CVodeInit(cvode_mem, f, T0, u); if(check_flag(&flag, "CVodeInit", 1)) return(1); /* Call CVodeSStolerances to specify the scalar relative tolerance * and scalar absolute tolerances */ flag = CVodeSStolerances(cvode_mem, reltol, abstol); if (check_flag(&flag, "CVodeSStolerances", 1)) return(1); /* Call CVSpgmr to specify the linear solver CVSPGMR with left preconditioning and the maximum Krylov dimension maxl */ flag = CVSpgmr(cvode_mem, PREC_LEFT, 0); if(check_flag(&flag, "CVSpgmr", 1)) return(1); /* Call CVBandPreInit to initialize band preconditioner */ ml = mu = 2; flag = CVBandPrecInit(cvode_mem, NEQ, mu, ml); if(check_flag(&flag, "CVBandPrecInit", 0)) return(1); PrintIntro(mu, ml); /* Loop over jpre (= PREC_LEFT, PREC_RIGHT), and solve the problem */ for (jpre = PREC_LEFT; jpre <= PREC_RIGHT; jpre++) { /* On second run, re-initialize u, the solver, and CVSPGMR */ if (jpre == PREC_RIGHT) { SetInitialProfiles(u, data->dx, data->dy); flag = CVodeReInit(cvode_mem, T0, u); if(check_flag(&flag, "CVodeReInit", 1)) return(1); flag = CVSpilsSetPrecType(cvode_mem, PREC_RIGHT); check_flag(&flag, "CVSpilsSetPrecType", 1); printf("\n\n-------------------------------------------------------"); printf("------------\n"); } printf("\n\nPreconditioner type is: jpre = %s\n\n", (jpre == PREC_LEFT) ? "PREC_LEFT" : "PREC_RIGHT"); /* In loop over output points, call CVode, print results, test for error */ for (iout = 1, tout = TWOHR; iout <= NOUT; iout++, tout += TWOHR) { flag = CVode(cvode_mem, tout, u, &t, CV_NORMAL); check_flag(&flag, "CVode", 1); PrintOutput(cvode_mem, u, t); if (flag != CV_SUCCESS) { break; } } /* Print final statistics */ PrintFinalStats(cvode_mem); } /* End of jpre loop */ /* Free memory */ N_VDestroy_Serial(u); free(data); CVodeFree(&cvode_mem); return(0); }
int run_rate_state_sim(std::vector<std::vector<realtype> > &results, RSParams ¶ms) { realtype long_term_reltol, event_reltol, t, tout, tbase=0; N_Vector y, long_term_abstol, event_abstol; unsigned int i, n; int flag, err_code; void *long_term_cvode, *event_cvode, *current_cvode; // Create serial vector of length NEQ for I.C. and abstol y = N_VNew_Serial(params.num_eqs()*params.num_blocks()); if (check_flag((void *)y, "N_VNew_Serial", 0)) return(1); long_term_abstol = N_VNew_Serial(params.num_eqs()*params.num_blocks()); if (check_flag((void *)long_term_abstol, "N_VNew_Serial", 0)) return(1); event_abstol = N_VNew_Serial(params.num_eqs()*params.num_blocks()); if (check_flag((void *)event_abstol, "N_VNew_Serial", 0)) return(1); // Initialize y for (i=0;i<params.num_blocks();++i) { NV_Ith_S(y,i*params.num_eqs()+EQ_X) = params.init_val(i, EQ_X); NV_Ith_S(y,i*params.num_eqs()+EQ_V) = params.init_val(i, EQ_V); NV_Ith_S(y,i*params.num_eqs()+EQ_H) = params.init_val(i, EQ_H); } /* Initialize interactions */ /*interaction = new realtype[NBLOCKS*NBLOCKS]; double int_level = 1e-2; double dropoff = 1.1; for (i=0;i<NBLOCKS;++i) { for (n=0;n<NBLOCKS;++n) { interaction[i*NBLOCKS+n] = (i==n?(1.0-int_level):int_level); } }*/ /* Set the scalar relative tolerance */ long_term_reltol = RCONST(1.0e-12); event_reltol = RCONST(1.0e-12); /* Set the vector absolute tolerance */ for (i=0;i<params.num_blocks();++i) { Xth(long_term_abstol,i) = RCONST(1.0e-12); Vth(long_term_abstol,i) = RCONST(1.0e-12); Hth(long_term_abstol,i) = RCONST(1.0e-12); Xth(event_abstol,i) = RCONST(1.0e-12); Vth(event_abstol,i) = RCONST(1.0e-12); Hth(event_abstol,i) = RCONST(1.0e-12); } /* Call CVodeCreate to create the solver memory and specify the * Backward Differentiation Formula and the use of a Newton iteration */ long_term_cvode = CVodeCreate(CV_BDF, CV_NEWTON); if (check_flag((void *)long_term_cvode, "CVodeCreate", 0)) return(1); event_cvode = CVodeCreate(CV_BDF, CV_NEWTON); if (check_flag((void *)event_cvode, "CVodeCreate", 0)) return(1); // Turn off error messages //CVodeSetErrFile(long_term_cvode, NULL); //CVodeSetErrFile(event_cvode, NULL); /* 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 y. */ flag = CVodeInit(long_term_cvode, func, T0, y); if (check_flag(&flag, "CVodeInit", 1)) return(1); flag = CVodeInit(event_cvode, func, T0, y); if (check_flag(&flag, "CVodeInit", 1)) return(1); /* Call CVodeSVtolerances to specify the scalar relative tolerance * and vector absolute tolerances */ flag = CVodeSVtolerances(long_term_cvode, long_term_reltol, long_term_abstol); if (check_flag(&flag, "CVodeSVtolerances", 1)) return(1); flag = CVodeSVtolerances(event_cvode, event_reltol, event_abstol); if (check_flag(&flag, "CVodeSVtolerances", 1)) return(1); /* Set the root finding function */ //flag = CVodeRootInit(long_term_cvode, params.num_blocks(), vel_switch_finder); //flag = CVodeRootInit(event_cvode, params.num_blocks(), vel_switch_finder); //if (check_flag(&flag, "CVodeRootInit", 1)) return(1); /* Call CVDense to specify the CVDENSE dense linear solver */ //flag = CVSpbcg(cvode_mem, PREC_NONE, 0); //if (check_flag(&flag, "CVSpbcg", 1)) return(1); //flag = CVSpgmr(cvode_mem, PREC_NONE, 0); //if (check_flag(&flag, "CVSpgmr", 1)) return(1); flag = CVDense(long_term_cvode, params.num_eqs()*params.num_blocks()); if (check_flag(&flag, "CVDense", 1)) return(1); flag = CVDense(event_cvode, params.num_eqs()*params.num_blocks()); if (check_flag(&flag, "CVDense", 1)) return(1); flag = CVodeSetUserData(long_term_cvode, ¶ms); if (check_flag(&flag, "CVodeSetUserData", 1)) return(1); flag = CVodeSetUserData(event_cvode, ¶ms); if (check_flag(&flag, "CVodeSetUserData", 1)) return(1); CVodeSetMaxNumSteps(long_term_cvode, 100000); CVodeSetMaxNumSteps(event_cvode, 100000); /* Set the Jacobian routine to Jac (user-supplied) */ flag = CVDlsSetDenseJacFn(long_term_cvode, Jac); if (check_flag(&flag, "CVDlsSetDenseJacFn", 1)) return(1); flag = CVDlsSetDenseJacFn(event_cvode, Jac); if (check_flag(&flag, "CVDlsSetDenseJacFn", 1)) return(1); /* In loop, call CVode, print results, and test for error. Break out of loop when NOUT preset output times have been reached. */ tout = T0+params.time_step(); err_code = 0; int mode = 0; int num_res_vals = params.num_eqs()*params.num_blocks(); while(t+tbase < params.end_time()) { switch (mode) { case 0: current_cvode = long_term_cvode; break; case 1: current_cvode = event_cvode; break; } flag = CVode(current_cvode, tout, y, &t, CV_NORMAL); record_results(results, y, t, tbase, num_res_vals); if (check_flag(&flag, "CVode", 1)) { err_code = flag; break; } if (flag == CV_ROOT_RETURN) { int flagr; int rootsfound[params.num_blocks()]; flagr = CVodeGetRootInfo(current_cvode, rootsfound); if (check_flag(&flagr, "CVodeGetRootInfo", 1)) return(1); //mode = !mode; //std::cerr << rootsfound[0] << std::endl; } if (flag == CV_SUCCESS) tout += params.time_step(); if (t > 10) { t -= 10; tout -= 10; Xth(y,0) -= 10; tbase += 10; CVodeReInit(current_cvode, t, y); } } std::cerr << err_code << " X:" << Xth(y,0) << " V:" << Vth(y,0) << " H:" << Hth(y,0) << " F:" << F(0,Vth(y,0),Hth(y,0),params) << " dV:" << (Xth(y,0)-t-params.param(0, K_PARAM)*F(0,Vth(y,0),Hth(y,0),params))/params.param(0, R_PARAM) << " dH:" << -Hth(y,0)*Vth(y,0)*log(Hth(y,0)*Vth(y,0)) << std::endl; /* Print some final statistics */ //PrintFinalStats(cvode_mem); /* Free y and abstol vectors */ N_VDestroy_Serial(y); N_VDestroy_Serial(long_term_abstol); N_VDestroy_Serial(event_abstol); /* Free integrator memory */ CVodeFree(&long_term_cvode); return err_code; }
static int Problem1(void) { realtype reltol=RTOL, abstol=ATOL, t, tout, ero, er; int miter, flag, temp_flag, iout, nerr=0; N_Vector y; void *cvode_mem; booleantype firstrun; int qu; realtype hu; y = NULL; cvode_mem = NULL; y = N_VNew_Serial(P1_NEQ); if(check_flag((void *)y, "N_VNew_Serial", 0)) return(1); PrintIntro1(); cvode_mem = CVodeCreate(CV_ADAMS, CV_FUNCTIONAL); if(check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1); for (miter=FUNC; miter <= DIAG; miter++) { ero = ZERO; NV_Ith_S(y,0) = TWO; NV_Ith_S(y,1) = ZERO; firstrun = (miter==FUNC); if (firstrun) { flag = CVodeMalloc(cvode_mem, f1, P1_T0, y, CV_SS, reltol, &abstol); if(check_flag(&flag, "CVodeMalloc", 1)) return(1); } else { flag = CVodeSetIterType(cvode_mem, CV_NEWTON); if(check_flag(&flag, "CVodeSetIterType", 1)) ++nerr; flag = CVodeReInit(cvode_mem, f1, P1_T0, y, CV_SS, reltol, &abstol); if(check_flag(&flag, "CVodeReInit", 1)) return(1); } flag = PrepareNextRun(cvode_mem, CV_ADAMS, miter, 0, 0); if(check_flag(&flag, "PrepareNextRun", 1)) return(1); PrintHeader1(); for(iout=1, tout=P1_T1; iout <= P1_NOUT; iout++, tout += P1_DTOUT) { flag = CVode(cvode_mem, tout, y, &t, CV_NORMAL); check_flag(&flag, "CVode", 1); temp_flag = CVodeGetLastOrder(cvode_mem, &qu); if(check_flag(&temp_flag, "CVodeGetLastOrder", 1)) ++nerr; temp_flag = CVodeGetLastStep(cvode_mem, &hu); if(check_flag(&temp_flag, "CVodeGetLastStep", 1)) ++nerr; PrintOutput1(t, NV_Ith_S(y,0), NV_Ith_S(y,1), qu, hu); if (flag != CV_SUCCESS) { nerr++; break; } if (iout%2 == 0) { er = ABS(NV_Ith_S(y,0)) / abstol; if (er > ero) ero = er; if (er > P1_TOL_FACTOR) { nerr++; PrintErrOutput(P1_TOL_FACTOR); } } } PrintFinalStats(cvode_mem, miter, ero); } CVodeFree(cvode_mem); cvode_mem = CVodeCreate(CV_BDF, CV_FUNCTIONAL); if(check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1); for (miter=FUNC; miter <= DIAG; miter++) { ero = ZERO; NV_Ith_S(y,0) = TWO; NV_Ith_S(y,1) = ZERO; firstrun = (miter==FUNC); if (firstrun) { flag = CVodeMalloc(cvode_mem, f1, P1_T0, y, CV_SS, reltol, &abstol); if(check_flag(&flag, "CVodeMalloc", 1)) return(1); } else { flag = CVodeSetIterType(cvode_mem, CV_NEWTON); if(check_flag(&flag, "CVodeSetIterType", 1)) ++nerr; flag = CVodeReInit(cvode_mem, f1, P1_T0, y, CV_SS, reltol, &abstol); if(check_flag(&flag, "CVodeReInit", 1)) return(1); } flag = PrepareNextRun(cvode_mem, CV_BDF, miter, 0, 0); if(check_flag(&flag, "PrepareNextRun", 1)) return(1); PrintHeader1(); for(iout=1, tout=P1_T1; iout <= P1_NOUT; iout++, tout += P1_DTOUT) { flag = CVode(cvode_mem, tout, y, &t, CV_NORMAL); check_flag(&flag, "CVode", 1); temp_flag = CVodeGetLastOrder(cvode_mem, &qu); if(check_flag(&temp_flag, "CVodeGetLastOrder", 1)) ++nerr; temp_flag = CVodeGetLastStep(cvode_mem, &hu); if(check_flag(&temp_flag, "CVodeGetLastStep", 1)) ++nerr; PrintOutput1(t, NV_Ith_S(y,0), NV_Ith_S(y,1), qu, hu); if (flag != CV_SUCCESS) { nerr++; break; } if (iout%2 == 0) { er = ABS(NV_Ith_S(y,0)) / abstol; if (er > ero) ero = er; if (er > P1_TOL_FACTOR) { nerr++; PrintErrOutput(P1_TOL_FACTOR); } } } PrintFinalStats(cvode_mem, miter, ero); } CVodeFree(cvode_mem); N_VDestroy_Serial(y); return(nerr); }
void CvodeSolver::initialize(const double &pVoiStart, const int &pRatesStatesCount, double *pConstants, double *pRates, double *pStates, double *pAlgebraic, ComputeRatesFunction pComputeRates) { if (!mSolver) { // Retrieve some of the CVODE properties double maximumStep = MaximumStepDefaultValue; int maximumNumberOfSteps = MaximumNumberOfStepsDefaultValue; QString integrationMethod = IntegrationMethodDefaultValue; QString iterationType = IterationTypeDefaultValue; QString linearSolver = LinearSolverDefaultValue; QString preconditioner = PreconditionerDefaultValue; int upperHalfBandwidth = UpperHalfBandwidthDefaultValue; int lowerHalfBandwidth = LowerHalfBandwidthDefaultValue; double relativeTolerance = RelativeToleranceDefaultValue; double absoluteTolerance = AbsoluteToleranceDefaultValue; if (mProperties.contains(MaximumStepId)) { maximumStep = mProperties.value(MaximumStepId).toDouble(); } else { emit error(QObject::tr("the 'maximum step' property value could not be retrieved")); return; } if (mProperties.contains(MaximumNumberOfStepsId)) { maximumNumberOfSteps = mProperties.value(MaximumNumberOfStepsId).toInt(); } else { emit error(QObject::tr("the 'maximum number of steps' property value could not be retrieved")); return; } if (mProperties.contains(IntegrationMethodId)) { integrationMethod = mProperties.value(IntegrationMethodId).toString(); } else { emit error(QObject::tr("the 'integration method' property value could not be retrieved")); return; } if (mProperties.contains(IterationTypeId)) { iterationType = mProperties.value(IterationTypeId).toString(); if (!iterationType.compare(NewtonIteration)) { // We are dealing with a Newton iteration, so retrieve and check // its linear solver if (mProperties.contains(LinearSolverId)) { linearSolver = mProperties.value(LinearSolverId).toString(); bool needUpperAndLowerHalfBandwidths = false; if ( !linearSolver.compare(DenseLinearSolver) || !linearSolver.compare(DiagonalLinearSolver)) { // We are dealing with a dense/diagonal linear solver, // so nothing more to do } else if (!linearSolver.compare(BandedLinearSolver)) { // We are dealing with a banded linear solver, so we // need both an upper and a lower half bandwidth needUpperAndLowerHalfBandwidths = true; } else { // We are dealing with a GMRES/Bi-CGStab/TFQMR linear // solver, so retrieve and check its preconditioner if (mProperties.contains(PreconditionerId)) { preconditioner = mProperties.value(PreconditionerId).toString(); } else { emit error(QObject::tr("the 'preconditioner' property value could not be retrieved")); return; } if (!preconditioner.compare(BandedPreconditioner)) { // We are dealing with a banded preconditioner, so // we need both an upper and a lower half bandwidth needUpperAndLowerHalfBandwidths = true; } } if (needUpperAndLowerHalfBandwidths) { if (mProperties.contains(UpperHalfBandwidthId)) { upperHalfBandwidth = mProperties.value(UpperHalfBandwidthId).toInt(); if ( (upperHalfBandwidth < 0) || (upperHalfBandwidth >= pRatesStatesCount)) { emit error(QObject::tr("the 'upper half-bandwidth' property must have a value between 0 and %1").arg(pRatesStatesCount-1)); return; } } else { emit error(QObject::tr("the 'upper half-bandwidth' property value could not be retrieved")); return; } if (mProperties.contains(LowerHalfBandwidthId)) { lowerHalfBandwidth = mProperties.value(LowerHalfBandwidthId).toInt(); if ( (lowerHalfBandwidth < 0) || (lowerHalfBandwidth >= pRatesStatesCount)) { emit error(QObject::tr("the 'lower half-bandwidth' property must have a value between 0 and %1").arg(pRatesStatesCount-1)); return; } } else { emit error(QObject::tr("the 'lower half-bandwidth' property value could not be retrieved")); return; } } } else { emit error(QObject::tr("the 'linear solver' property value could not be retrieved")); return; } } } else { emit error(QObject::tr("the 'iteration type' property value could not be retrieved")); return; } if (mProperties.contains(RelativeToleranceId)) { relativeTolerance = mProperties.value(RelativeToleranceId).toDouble(); if (relativeTolerance < 0) { emit error(QObject::tr("the 'relative tolerance' property must have a value greater than or equal to 0")); return; } } else { emit error(QObject::tr("the 'relative tolerance' property value could not be retrieved")); return; } if (mProperties.contains(AbsoluteToleranceId)) { absoluteTolerance = mProperties.value(AbsoluteToleranceId).toDouble(); if (absoluteTolerance < 0) { emit error(QObject::tr("the 'absolute tolerance' property must have a value greater than or equal to 0")); return; } } else { emit error(QObject::tr("the 'absolute tolerance' property value could not be retrieved")); return; } if (mProperties.contains(InterpolateSolutionId)) { mInterpolateSolution = mProperties.value(InterpolateSolutionId).toBool(); } else { emit error(QObject::tr("the 'interpolate solution' property value could not be retrieved")); return; } // Initialise the ODE solver itself OpenCOR::Solver::OdeSolver::initialize(pVoiStart, pRatesStatesCount, pConstants, pRates, pStates, pAlgebraic, pComputeRates); // Create the states vector mStatesVector = N_VMake_Serial(pRatesStatesCount, pStates); // Create the CVODE solver bool newtonIteration = !iterationType.compare(NewtonIteration); mSolver = CVodeCreate(!integrationMethod.compare(BdfMethod)?CV_BDF:CV_ADAMS, newtonIteration?CV_NEWTON:CV_FUNCTIONAL); // Use our own error handler CVodeSetErrHandlerFn(mSolver, errorHandler, this); // Initialise the CVODE solver CVodeInit(mSolver, rhsFunction, pVoiStart, mStatesVector); // Set some user data mUserData = new CvodeSolverUserData(pConstants, pAlgebraic, pComputeRates); CVodeSetUserData(mSolver, mUserData); // Set the maximum step CVodeSetMaxStep(mSolver, maximumStep); // Set the maximum number of steps CVodeSetMaxNumSteps(mSolver, maximumNumberOfSteps); // Set the linear solver, if needed if (newtonIteration) { if (!linearSolver.compare(DenseLinearSolver)) { CVDense(mSolver, pRatesStatesCount); } else if (!linearSolver.compare(BandedLinearSolver)) { CVBand(mSolver, pRatesStatesCount, upperHalfBandwidth, lowerHalfBandwidth); } else if (!linearSolver.compare(DiagonalLinearSolver)) { CVDiag(mSolver); } else { // We are dealing with a GMRES/Bi-CGStab/TFQMR linear solver if (!preconditioner.compare(BandedPreconditioner)) { if (!linearSolver.compare(GmresLinearSolver)) CVSpgmr(mSolver, PREC_LEFT, 0); else if (!linearSolver.compare(BiCgStabLinearSolver)) CVSpbcg(mSolver, PREC_LEFT, 0); else CVSptfqmr(mSolver, PREC_LEFT, 0); CVBandPrecInit(mSolver, pRatesStatesCount, upperHalfBandwidth, lowerHalfBandwidth); } else { if (!linearSolver.compare(GmresLinearSolver)) CVSpgmr(mSolver, PREC_NONE, 0); else if (!linearSolver.compare(BiCgStabLinearSolver)) CVSpbcg(mSolver, PREC_NONE, 0); else CVSptfqmr(mSolver, PREC_NONE, 0); } } } // Set the relative and absolute tolerances CVodeSStolerances(mSolver, relativeTolerance, absoluteTolerance); } else { // Reinitialise the CVODE object CVodeReInit(mSolver, pVoiStart, mStatesVector); } }
int main() { void *cvode_mem; SUNMatrix A; SUNLinearSolver LS; N_Vector y; int flag, ret; realtype reltol, abstol, t0, t1, t2, t; long int nst1, nst2, nst; reltol = RCONST(1.0e-3); abstol = RCONST(1.0e-4); t0 = RCONST(0.0); t1 = RCONST(1.0); t2 = RCONST(2.0); /* Allocate the vector of initial conditions */ y = N_VNew_Serial(NEQ); /* Set initial condition */ NV_Ith_S(y,0) = RCONST(1.0); /* * ------------------------------------------------------------ * Shared initialization and setup * ------------------------------------------------------------ */ /* Call CVodeCreate to create CVODE memory block and specify the * Backward Differentiaion Formula */ cvode_mem = CVodeCreate(CV_BDF); if (check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1); /* Call CVodeInit to initialize integrator memory and specify the * user's right hand side function y'=f(t,y), the initial time T0 * and the initial condiition vector y. */ ret = CVodeInit(cvode_mem, f, t0, y); if (check_flag((void *)&ret, "CVodeInit", 1)) return(1); /* Call CVodeSStolerances to specify integration tolereances, * specifically the scalar relative and absolute tolerance. */ ret = CVodeSStolerances(cvode_mem, reltol, abstol); if (check_flag((void *)&ret, "CVodeSStolerances", 1)) return(1); /* Provide RHS flag as user data which can be access in user provided routines */ ret = CVodeSetUserData(cvode_mem, &flag); if (check_flag((void *)&ret, "CVodeSetUserData", 1)) return(1); /* Create dense SUNMatrix for use in linear solver */ A = SUNDenseMatrix(NEQ, NEQ); if (check_flag((void *)A, "SUNDenseMatrix", 0)) return(1); /* Create dense linear solver for use by CVode */ LS = SUNLinSol_Dense(y, A); if (check_flag((void *)LS, "SUNLinSol_Dense", 0)) return(1); /* Attach the linear solver and matrix to CVode by calling CVodeSetLinearSolver */ ret = CVodeSetLinearSolver(cvode_mem, LS, A); if (check_flag((void *)&ret, "CVodeSetLinearSolver", 1)) return(1); /* * --------------------------------------------------------------- * Discontinuity in the solution * * 1) Integrate to the discontinuity * 2) Integrate from the discontinuity * --------------------------------------------------------------- */ /* ---- Integrate to the discontinuity */ printf("\nDiscontinuity in solution\n\n"); /* set TSTOP (max time solution proceeds to) - this is not required */ ret = CVodeSetStopTime(cvode_mem, t1); if (check_flag((void *)&ret, "CVodeSetStopTime", 1)) return(1); flag = RHS1; /* use -y for RHS */ t = t0; /* set the integrator start time */ printf("%12.8e %12.8e\n",t,NV_Ith_S(y,0)); while (t<t1) { /* advance solver just one internal step */ ret = CVode(cvode_mem, t1, y, &t, CV_ONE_STEP); if (check_flag((void *)&ret, "CVode", 1)) return(1); printf("%12.8e %12.8e\n",t,NV_Ith_S(y,0)); } /* Get the number of steps the solver took to get to the discont. */ ret = CVodeGetNumSteps(cvode_mem, &nst1); if (check_flag((void *)&ret, "CvodeGetNumSteps", 1)) return(1); /* ---- Integrate from the discontinuity */ /* Include discontinuity */ NV_Ith_S(y,0) = RCONST(1.0); /* Reinitialize the solver */ ret = CVodeReInit(cvode_mem, t1, y); if (check_flag((void *)&ret, "CVodeReInit", 1)) return(1); /* set TSTOP (max time solution proceeds to) - this is not required */ ret = CVodeSetStopTime(cvode_mem, t2); if (check_flag((void *)&ret, "CVodeSetStopTime", 1)) return(1); flag = RHS1; /* use -y for RHS */ t = t1; /* set the integrator start time */ printf("%12.8e %12.8e\n",t,NV_Ith_S(y,0)); while (t<t2) { /* advance solver just one internal step */ ret = CVode(cvode_mem, t2, y, &t, CV_ONE_STEP); if (check_flag((void *)&ret, "CVode", 1)) return(1); printf("%12.8e %12.8e\n",t,NV_Ith_S(y,0)); } /* Get the number of steps the solver took after the discont. */ ret = CVodeGetNumSteps(cvode_mem, &nst2); if (check_flag((void *)&ret, "CvodeGetNumSteps", 1)) return(1); /* Print statistics */ nst = nst1 + nst2; printf("\nNumber of steps: %ld + %ld = %ld\n",nst1, nst2, nst); /* * --------------------------------------------------------------- * Discontinuity in RHS: Case 1 - explicit treatment * Note that it is not required to set TSTOP, but without it * we would have to find y(t1) to reinitialize the solver. * --------------------------------------------------------------- */ printf("\nDiscontinuity in RHS: Case 1 - explicit treatment\n\n"); /* Set initial condition */ NV_Ith_S(y,0) = RCONST(1.0); /* Reinitialize the solver. CVodeReInit does not reallocate memory * so it can only be used when the new problem size is the same as * the problem size when CVodeCreate was called. */ ret = CVodeReInit(cvode_mem, t0, y); if (check_flag((void *)&ret, "CVodeReInit", 1)) return(1); /* ---- Integrate to the discontinuity */ /* Set TSTOP (max time solution proceeds to) to location of discont. */ ret = CVodeSetStopTime(cvode_mem, t1); if (check_flag((void *)&ret, "CVodeSetStopTime", 1)) return(1); flag = RHS1; /* use -y for RHS */ t = t0; /* set the integrator start time */ printf("%12.8e %12.8e\n",t,NV_Ith_S(y,0)); while (t<t1) { /* advance solver just one internal step */ ret = CVode(cvode_mem, t1, y, &t, CV_ONE_STEP); if (check_flag((void *)&ret, "CVode", 1)) return(1); printf("%12.8e %12.8e\n",t,NV_Ith_S(y,0)); } /* Get the number of steps the solver took to get to the discont. */ ret = CVodeGetNumSteps(cvode_mem, &nst1); if (check_flag((void *)&ret, "CvodeGetNumSteps", 1)) return(1); /* If TSTOP was not set, we'd need to find y(t1): */ /* CVodeGetDky(cvode_mem, t1, 0, y); */ /* ---- Integrate from the discontinuity */ /* Reinitialize solver */ ret = CVodeReInit(cvode_mem, t1, y); /* set TSTOP (max time solution proceeds to) - this is not required */ ret = CVodeSetStopTime(cvode_mem, t2); if (check_flag((void *)&ret, "CVodeSetStopTime", 1)) return(1); flag = RHS2; /* use -5y for RHS */ t = t1; /* set the integrator start time */ printf("%12.8e %12.8e\n",t,NV_Ith_S(y,0)); while (t<t2) { /* advance solver just one internal step */ ret = CVode(cvode_mem, t2, y, &t, CV_ONE_STEP); if (check_flag((void *)&ret, "CVode", 1)) return(1); printf("%12.8e %12.8e\n",t,NV_Ith_S(y,0)); } /* Get the number of steps the solver took after the discont. */ ret = CVodeGetNumSteps(cvode_mem, &nst2); if (check_flag((void *)&ret, "CvodeGetNumSteps", 1)) return(1); /* Print statistics */ nst = nst1 + nst2; printf("\nNumber of steps: %ld + %ld = %ld\n",nst1, nst2, nst); /* * --------------------------------------------------------------- * Discontinuity in RHS: Case 2 - let CVODE deal with it * Note that here we MUST set TSTOP to ensure that the * change in the RHS happens at the appropriate time * --------------------------------------------------------------- */ printf("\nDiscontinuity in RHS: Case 2 - let CVODE deal with it\n\n"); /* Set initial condition */ NV_Ith_S(y,0) = RCONST(1.0); /* Reinitialize the solver. CVodeReInit does not reallocate memory * so it can only be used when the new problem size is the same as * the problem size when CVodeCreate was called. */ ret = CVodeReInit(cvode_mem, t0, y); if (check_flag((void *)&ret, "CVodeReInit", 1)) return(1); /* ---- Integrate to the discontinuity */ /* Set TSTOP (max time solution proceeds to) to location of discont. */ ret = CVodeSetStopTime(cvode_mem, t1); if (check_flag((void *)&ret, "CVodeSetStopTime", 1)) return(1); flag = RHS1; /* use -y for RHS */ t = t0; /* set the integrator start time */ printf("%12.8e %12.8e\n",t,NV_Ith_S(y,0)); while (t<t1) { /* advance solver just one internal step */ ret = CVode(cvode_mem, t1, y, &t, CV_ONE_STEP); if (check_flag((void *)&ret, "CVode", 1)) return(1); printf("%12.8e %12.8e\n",t,NV_Ith_S(y,0)); } /* Get the number of steps the solver took to get to the discont. */ ret = CVodeGetNumSteps(cvode_mem, &nst1); if (check_flag((void *)&ret, "CvodeGetNumSteps", 1)) return(1); /* ---- Integrate from the discontinuity */ /* set TSTOP (max time solution proceeds to) - this is not required */ ret = CVodeSetStopTime(cvode_mem, t2); if (check_flag((void *)&ret, "CVodeSetStopTime", 1)) return(1); flag = RHS2; /* use -5y for RHS */ t = t1; /* set the integrator start time */ printf("%12.8e %12.8e\n",t,NV_Ith_S(y,0)); while (t<t2) { /* advance solver just one internal step */ ret = CVode(cvode_mem, t2, y, &t, CV_ONE_STEP); if (check_flag((void *)&ret, "CVode", 1)) return(1); printf("%12.8e %12.8e\n",t,NV_Ith_S(y,0)); } /* Get the number of steps the solver took after the discont. */ ret = CVodeGetNumSteps(cvode_mem, &nst); if (check_flag((void *)&ret, "CvodeGetNumSteps", 1)) return(1); /* Print statistics */ nst2 = nst - nst1; printf("\nNumber of steps: %ld + %ld = %ld\n",nst1, nst2, nst); /* Free memory */ N_VDestroy(y); SUNMatDestroy(A); SUNLinSolFree(LS); CVodeFree(&cvode_mem); return(0); }
void Cvode::CVodeCore() { _idid = CVodeReInit(_cvodeMem, _tCurrent, _CV_y); _idid = CVodeSetStopTime(_cvodeMem, _tEnd); _idid = CVodeSetInitStep(_cvodeMem, 1e-12); if (_idid < 0) throw ModelicaSimulationError(SOLVER,"CVode::ReInit"); bool writeEventOutput = (_settings->getGlobalSettings()->getOutputPointType() == OPT_ALL); bool writeOutput = !(_settings->getGlobalSettings()->getOutputPointType() == OPT_NONE); while ((_solverStatus & ISolver::CONTINUE) && !_interrupt ) { _cv_rt = CVode(_cvodeMem, _tEnd, _CV_y, &_tCurrent, CV_ONE_STEP); _idid = CVodeGetNumSteps(_cvodeMem, &_locStps); if (_idid != CV_SUCCESS) throw ModelicaSimulationError(SOLVER,"CVodeGetNumSteps failed. The cvode mem pointer is NULL"); _idid = CVodeGetLastStep(_cvodeMem, &_h); if (_idid != CV_SUCCESS) throw ModelicaSimulationError(SOLVER,"CVodeGetLastStep failed. The cvode mem pointer is NULL"); //set completed step to system and check if terminate was called if(_continuous_system->stepCompleted(_tCurrent)) _solverStatus = DONE; //Check if there was at least one output-point within the last solver interval // -> Write output if true if (writeOutput) { writeCVodeOutput(_tCurrent, _h, _locStps); } #ifdef RUNTIME_PROFILING MEASURETIME_REGION_DEFINE(cvodeStepCompletedHandler, "CVodeStepCompleted"); if(MeasureTime::getInstance() != NULL) { MEASURETIME_START(measuredFunctionStartValues, cvodeStepCompletedHandler, "CVodeStepCompleted"); } #endif #ifdef RUNTIME_PROFILING if(MeasureTime::getInstance() != NULL) { MEASURETIME_END(measuredFunctionStartValues, measuredFunctionEndValues, (*measureTimeFunctionsArray)[5], cvodeStepCompletedHandler); } #endif // Perform state selection bool state_selection = stateSelection(); if (state_selection) _continuous_system->getContinuousStates(_z); _zeroFound = false; // Check if step was successful if (check_flag(&_cv_rt, "CVode", 1)) { _solverStatus = ISolver::SOLVERERROR; break; } // A root was found if ((_cv_rt == CV_ROOT_RETURN) && !isInterrupted()) { // CVode is setting _tCurrent to the time where the first event occurred double _abs = fabs(_tLastEvent - _tCurrent); _zeroFound = true; if ((_abs < 1e-3) && _event_n == 0) { _tLastEvent = _tCurrent; _event_n++; } else if ((_abs < 1e-3) && (_event_n >= 1 && _event_n < 500)) { _event_n++; } else if ((_abs >= 1e-3)) { //restart event counter _tLastEvent = _tCurrent; _event_n = 0; } else throw ModelicaSimulationError(EVENT_HANDLING,"Number of events exceeded in time interval " + to_string(_abs) + " at time " + to_string(_tCurrent)); // CVode has interpolated the states at time 'tCurrent' _time_system->setTime(_tCurrent); // To get steep steps in the result file, two value points (P1 and P2) must be added // // Y | (P2) X........... // | : // | : // |........X (P1) // |----------------------------------> // | ^ t // _tCurrent // Write the values of (P1) if (writeEventOutput) { _continuous_system->evaluateAll(IContinuous::CONTINUOUS); writeToFile(0, _tCurrent, _h); } _idid = CVodeGetRootInfo(_cvodeMem, _zeroSign); for (int i = 0; i < _dimZeroFunc; i++) _events[i] = bool(_zeroSign[i]); if (_mixed_system->handleSystemEvents(_events)) { // State variables were reinitialized, thus we have to give these values to the cvode-solver // Take care about the memory regions, _z is the same like _CV_y _continuous_system->getContinuousStates(_z); } } if ((_zeroFound || state_selection)&& !isInterrupted()) { // Write the values of (P2) if (writeEventOutput) { // If we want to write the event-results, we should evaluate the whole system again _continuous_system->evaluateAll(IContinuous::CONTINUOUS); writeToFile(0, _tCurrent, _h); } _idid = CVodeReInit(_cvodeMem, _tCurrent, _CV_y); if (_idid < 0) throw ModelicaSimulationError(SOLVER,"CVode::ReInit()"); // Der Eventzeitpunkt kann auf der Endzeit liegen (Time-Events). In diesem Fall wird der Solver beendet, da CVode sonst eine interne Warnung schmeißt if (_tCurrent == _tEnd) _cv_rt = CV_TSTOP_RETURN; if(_continuous_system->stepCompleted(_tCurrent)) _solverStatus = DONE; } // Zähler für die Anzahl der ausgegebenen Schritte erhöhen ++_outStps; _tLastSuccess = _tCurrent; if (_cv_rt == CV_TSTOP_RETURN) { _time_system->setTime(_tEnd); //Solver has finished calculation - calculate the final values _continuous_system->setContinuousStates(NV_DATA_S(_CV_y)); _continuous_system->evaluateAll(IContinuous::CONTINUOUS); if(writeOutput) writeToFile(0, _tEnd, _h); _accStps += _locStps; _solverStatus = DONE; } } }
void FCV_REINIT(realtype *t0, realtype *y0, int *iatol, realtype *rtol, realtype *atol, int *optin, long int *iopt, realtype *ropt, int *ier) { int itol; void *atolptr; atolptr = NULL; N_VSetArrayPointer(y0, F2C_vec); switch (*iatol) { case 1: itol = CV_SS; atolptr = (void *) atol; break; case 2: F2C_atolvec = N_VClone(F2C_vec); data_F2C_atolvec = N_VGetArrayPointer(F2C_atolvec); N_VSetArrayPointer(atol, F2C_atolvec); itol = CV_SV; atolptr = (void *) F2C_atolvec; break; case 3: itol = CV_WF; } /* Call CVodeSet* and CVReInit to re-initialize CVODE: CVf is the user's right-hand side function in y'=f(t,y) t0 is the initial time F2C_vec is the initial dependent variable vector itol specifies tolerance type rtol is the scalar relative tolerance atolptr is the absolute tolerance pointer (to scalar or vector or function) */ if (*optin == 1) { CV_optin = TRUE; if (iopt[0] > 0) CVodeSetMaxOrd(CV_cvodemem, (int)iopt[0]); if (iopt[1] > 0) CVodeSetMaxNumSteps(CV_cvodemem, iopt[1]); if (iopt[2] > 0) CVodeSetMaxHnilWarns(CV_cvodemem, (int)iopt[2]); if (iopt[13] > 0) CVodeSetStabLimDet(CV_cvodemem, TRUE); if (iopt[21] > 0) CVodeSetMaxErrTestFails(CV_cvodemem, (int)iopt[21]); if (iopt[22] > 0) CVodeSetMaxNonlinIters(CV_cvodemem, (int)iopt[22]); if (iopt[23] > 0) CVodeSetMaxConvFails(CV_cvodemem, (int)iopt[23]); if (ropt[0] != ZERO) CVodeSetInitStep(CV_cvodemem, ropt[0]); if (ropt[1] > ZERO) CVodeSetMaxStep(CV_cvodemem, ropt[1]); if (ropt[2] > ZERO) CVodeSetMinStep(CV_cvodemem, ropt[2]); if (ropt[7] != ZERO) CVodeSetStopTime(CV_cvodemem, ropt[7]); if (ropt[8] > ZERO) CVodeSetNonlinConvCoef(CV_cvodemem, ropt[8]); } else { CV_optin = FALSE; } *ier = CVodeReInit(CV_cvodemem, FCVf, *t0, F2C_vec, itol, *rtol, atolptr); /* reset data pointer into F2C_vec */ N_VSetArrayPointer(data_F2C_vec, F2C_vec); /* destroy F2C_atolvec if allocated */ if (F2C_atolvec != NULL) { N_VSetArrayPointer(data_F2C_atolvec, F2C_atolvec); N_VDestroy(F2C_atolvec); } if (*ier != CV_SUCCESS) { *ier = -1; return; } CV_iopt = iopt; CV_ropt = ropt; return; }
void SundialsCvode::initialize() { int flag = 0; if (_initialized) { // Starting over with a new IC, but the same ODE flag = CVodeReInit(sundialsMem, t0, y.forSundials()); if (check_flag(&flag, "CVodeReInit", 1)) { throw DebugException("SundialsCvode::reInitialize: error in CVodeReInit"); } CVodeSetMaxNumSteps(sundialsMem, maxNumSteps); CVodeSetMinStep(sundialsMem, minStep); return; } // On the first call to initialize, need to allocate and set up // the Sundials solver, set tolerances and link the ODE functions sundialsMem = CVodeCreate(linearMultistepMethod, nonlinearSolverMethod); if (check_flag((void *)sundialsMem, "CVodeCreate", 0)) { throw DebugException("SundialsCvode::initialize: error in CVodeCreate"); } flag = CVodeInit(sundialsMem, f, t0, y.forSundials()); if (check_flag(&flag, "CVodeMalloc", 1)) { throw DebugException("SundialsCvode::initialize: error in CVodeMalloc"); } CVodeSVtolerances(sundialsMem, reltol, abstol.forSundials()); CVodeSetUserData(sundialsMem, theODE); CVodeSetMaxNumSteps(sundialsMem, maxNumSteps); CVodeSetMinStep(sundialsMem, minStep); if (findRoots) { rootsFound.resize(nRoots); // Call CVodeRootInit to specify the root function g with nRoots components flag = CVodeRootInit(sundialsMem, nRoots, g); if (check_flag(&flag, "CVodeRootInit", 1)) { throw DebugException("SundialsCvode::initialize: error in CVodeRootInit"); } } if (bandwidth_upper == -1 && bandwidth_lower == -1) { // Call CVDense to specify the CVDENSE dense linear solver flag = CVDense(sundialsMem, nEq); if (check_flag(&flag, "CVDense", 1)) { throw DebugException("SundialsCvode::initialize: error in CVDense"); } // Set the Jacobian routine to denseJac (user-supplied) flag = CVDlsSetDenseJacFn(sundialsMem, denseJac); if (check_flag(&flag, "CVDlsSetDenseJacFn", 1)) { throw DebugException("SundialsCvode::initialize: error in CVDlsSetDenseJacFn"); } } else { // Call CVDense to specify the CVBAND Banded linear solver flag = CVBand(sundialsMem, nEq, bandwidth_upper, bandwidth_lower); if (check_flag(&flag, "CVBand", 1)) { throw DebugException("SundialsCvode::initialize: error in CVBand"); } // Set the Jacobian routine to bandJac (user-supplied) flag = CVDlsSetBandJacFn(sundialsMem, bandJac); if (check_flag(&flag, "CVDlsSetBandJacFn", 1)) { throw DebugException("SundialsCvode::initialize: error in CVDlsSetBandJacFn"); } } _initialized = true; }
static int simulate_nmr_pulse(struct bloch_sim *bs) { N_Vector M = NULL; M = N_VNew_Serial(3 * bs->num_cells); if (check_flag((void *)M, "N_VNew_Serial", 0)) return(1); int i; /* Set initial (t=0) magnetization conditions */ for(i=0; i < bs->num_cells; ++i) { X(M,i) = 0.0; Y(M,i) = 0.0; Z(M,i) = bs->cell_frequencies[i] / bs->w_avg; } realtype reltol = RCONST(1.0e-14); realtype abstol = RCONST(1.0e-14); void *cvode_mem = CVodeCreate(CV_ADAMS, CV_FUNCTIONAL); if (check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1); int flag; //TODO: check if flag should be pointer; flag = CVodeInit(cvode_mem, bloch_equations, 0.0, M); if (check_flag(&flag, "CVodeInit", 1)) return(1); flag = CVodeSetUserData(cvode_mem, bs); if (check_flag(&flag, "CVodeSetUserData", 1)) return(1); flag = CVodeSStolerances(cvode_mem, reltol, abstol); if (check_flag(&flag, "CVodeSetUserData", 1)) return(1); flag = CVDense(cvode_mem, 3 * bs->num_cells); if (check_flag(&flag, "CVDense", 1)) return(1); flag = CVDlsSetDenseJacFn(cvode_mem, bloch_jacobian); if (check_flag(&flag, "CVDlsSetDenseJacFn", 1)) return(1); /////////////////////////// // PI/2 PULSE SIMULATION // /////////////////////////// bs->rf_on = 1; flag = CVodeSetStopTime(cvode_mem, bs->pi2_duration); if (check_flag(&flag, "CVodeSetStopTime", 1)) return 1; realtype time_reached; flag = CVode(cvode_mem, bs->pi2_duration, M, &time_reached, CV_NORMAL); if (flag != CV_SUCCESS) { printf("ERROR: Failed to simulate Pi/2 pulse\n"); } // {{{ PI2 PULSE DEBUG STATEMENTS if (DEBUG) { printf("\n"); printf("#####################################\n"); printf("### PI/2 PULSE SIMULATION DETAILS ###\n"); printf("#####################################\n"); printf("\n"); printf("TIME REACHED: %.15e\n", time_reached); printf("TIME REACHED - PI2_DURATION: %.15e\n", time_reached - bs->pi2_duration); printf("\n"); printf("MAGNETIZATION AT END OF PI/2 PULSE:\n"); for (i = 0; i<bs->num_cells; ++i) { printf("CELL %d: %.4e, %.4e, %.4e\n", i, X(M,i), Y(M,i), Z(M,i)); } } // }}} //////////////////// // FID SIMULATION // //////////////////// bs->rf_on = 0; if (DEBUG) { printf("##############################\n"); printf("### FID SIMULATION DETAILS ###\n"); printf("##############################\n"); } flag = CVodeReInit(cvode_mem, 0.0, M); if (check_flag(&flag, "CVodeReInit", 1)) return(1); time_reached = 0.0; flag = CVodeSetStopTime(cvode_mem, bs->fid_duration); if (check_flag(&flag, "CVodeSetStopTime", 1)) return 1; flag = CVodeRootInit(cvode_mem, 1, bloch_root); if (check_flag(&flag, "CVodeRootInit", 1)) return 1; realtype time_desired, M_FID_X; while (time_reached < bs->fid_duration) { time_desired = time_reached + bs->fid_sampling_interval; flag = CVode(cvode_mem, time_desired, M, &time_reached, CV_NORMAL); if (flag == CV_ROOT_RETURN) { bs->zero_crossings[bs->num_zero_crossings] = time_reached; M_FID_X = 0.0; for (i=0; i < bs->num_cells; i++) { M_FID_X += X(M,i) * cos(bs->w_avg * time_reached); M_FID_X += Y(M,i) * sin(bs->w_avg * time_reached); } bs->envelope[bs->num_zero_crossings] = M_FID_X / bs->num_cells; bs->num_zero_crossings++; } } bs->zero_crossings = (realtype*) realloc(bs->zero_crossings, sizeof(realtype) * bs->num_zero_crossings); bs->envelope = (realtype*) realloc(bs->envelope, sizeof(realtype) * bs->num_zero_crossings); if (!bs->zero_crossings || !bs->envelope) { printf("ERROR: reallocating zero crossing and/or envelope array memory failed!\n"); exit(1); } N_VDestroy_Serial(M); CVodeFree(&cvode_mem); return 0; }
int main(void) { realtype abstol, reltol, t, tout; N_Vector u; UserData data; void *cvode_mem; int linsolver, iout, flag; u = NULL; data = NULL; cvode_mem = NULL; /* Allocate memory, and set problem data, initial values, tolerances */ u = N_VNew_Serial(NEQ); if(check_flag((void *)u, "N_VNew_Serial", 0)) return(1); data = AllocUserData(); if(check_flag((void *)data, "AllocUserData", 2)) return(1); InitUserData(data); SetInitialProfiles(u, data->dx, data->dy); abstol=ATOL; reltol=RTOL; /* 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, "CVodeCreate", 0)) return(1); /* Set the pointer to user-defined data */ flag = CVodeSetUserData(cvode_mem, data); if(check_flag(&flag, "CVodeSetUserData", 1)) return(1); /* Call CVodeInit to initialize the integrator memory and specify the * user's right hand side function in u'=f(t,u), the inital time T0, and * the initial dependent variable vector u. */ flag = CVodeInit(cvode_mem, f, T0, u); if(check_flag(&flag, "CVodeInit", 1)) return(1); /* Call CVodeSStolerances to specify the scalar relative tolerance * and scalar absolute tolerances */ flag = CVodeSStolerances(cvode_mem, reltol, abstol); if (check_flag(&flag, "CVodeSStolerances", 1)) return(1); /* START: Loop through SPGMR, SPBCG and SPTFQMR linear solver modules */ for (linsolver = 0; linsolver < 3; ++linsolver) { if (linsolver != 0) { /* Re-initialize user data */ InitUserData(data); SetInitialProfiles(u, data->dx, data->dy); /* Re-initialize CVode for the solution of the same problem, but using a different linear solver module */ flag = CVodeReInit(cvode_mem, T0, u); if (check_flag(&flag, "CVodeReInit", 1)) return(1); } /* Attach a linear solver module */ switch(linsolver) { /* (a) SPGMR */ case(USE_SPGMR): /* Print header */ printf(" -------"); printf(" \n| SPGMR |\n"); printf(" -------\n"); /* Call CVSpgmr to specify the linear solver CVSPGMR with left preconditioning and the maximum Krylov dimension maxl */ flag = CVSpgmr(cvode_mem, PREC_LEFT, 0); if(check_flag(&flag, "CVSpgmr", 1)) return(1); /* Set modified Gram-Schmidt orthogonalization, preconditioner setup and solve routines Precond and PSolve, and the pointer to the user-defined block data */ flag = CVSpilsSetGSType(cvode_mem, MODIFIED_GS); if(check_flag(&flag, "CVSpilsSetGSType", 1)) return(1); break; /* (b) SPBCG */ case(USE_SPBCG): /* Print header */ printf(" -------"); printf(" \n| SPBCG |\n"); printf(" -------\n"); /* Call CVSpbcg to specify the linear solver CVSPBCG with left preconditioning and the maximum Krylov dimension maxl */ flag = CVSpbcg(cvode_mem, PREC_LEFT, 0); if(check_flag(&flag, "CVSpbcg", 1)) return(1); break; /* (c) SPTFQMR */ case(USE_SPTFQMR): /* Print header */ printf(" ---------"); printf(" \n| SPTFQMR |\n"); printf(" ---------\n"); /* Call CVSptfqmr to specify the linear solver CVSPTFQMR with left preconditioning and the maximum Krylov dimension maxl */ flag = CVSptfqmr(cvode_mem, PREC_LEFT, 0); if(check_flag(&flag, "CVSptfqmr", 1)) return(1); break; } /* Set preconditioner setup and solve routines Precond and PSolve, and the pointer to the user-defined block data */ flag = CVSpilsSetPreconditioner(cvode_mem, Precond, PSolve); if(check_flag(&flag, "CVSpilsSetPreconditioner", 1)) return(1); /* In loop over output points, call CVode, print results, test for error */ printf(" \n2-species diurnal advection-diffusion problem\n\n"); for (iout=1, tout = TWOHR; iout <= NOUT; iout++, tout += TWOHR) { flag = CVode(cvode_mem, tout, u, &t, CV_NORMAL); PrintOutput(cvode_mem, u, t); if(check_flag(&flag, "CVode", 1)) break; } PrintFinalStats(cvode_mem, linsolver); } /* END: Loop through SPGMR, SPBCG and SPTFQMR linear solver modules */ /* Free memory */ N_VDestroy_Serial(u); FreeUserData(data); CVodeFree(&cvode_mem); return(0); }
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; flag = CVDense(cvode_mem_, this->n_); if (check_flag(&flag, std::string("CVDense"), 1)) exit(-1); } else { // std::cout << "CVODE Solver: Band Jacobian (without Lapack)..." << std::endl; flag = CVBand(cvode_mem_, this->n_, this->mUpper_, this->mLower_); if (check_flag(&flag, std::string("CVBand"), 1)) exit(-1); } } else { if (this->mUpper_ == 0 && this->mLower_ == 0) { // std::cout << "CVODE Solver: Dense Jacobian (with Lapack)..." << std::endl; flag = CVLapackDense(cvode_mem_, this->n_); if (check_flag(&flag, std::string("CVLapackDense"), 1)) exit(-1); } else { // std::cout << "CVODE Solver: Band Jacobian (with Lapack)..." << std::endl; flag = CVLapackBand(cvode_mem_, this->n_, this->mUpper_, this->mLower_); if (check_flag(&flag, std::string("CVLapackBand"), 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); }
static int CVAckpntGet(CVodeMem cv_mem, CkpntMem ck_mem) { int j; int flag; int qmax; void *abstol; abstol = NULL; if (next_ == NULL) { /* In this case, we just call the reinitialization routine, but make sure we use the same initial stepsize as on the first run. */ CVodeSetInitStep(cv_mem, h0u); switch (itol) { case CV_SS: abstol = (void *) &Sabstol; break; case CV_SV: abstol = (void *)Vabstol; break; case CV_EE: abstol = (void *)efun; break; } flag = CVodeReInit(cv_mem, f, t0_, zn_[0], itol, reltol, abstol); if (flag != CV_SUCCESS) return(flag); if(quadr_) { flag = CVodeQuadReInit(cv_mem, fQ, znQ_[0]); if (flag != CV_SUCCESS) return(flag); } } else { qmax = cv_mem->cv_qmax; /* Copy parameters from check point data structure */ nst = nst_; tretlast = tretlast_; q = q_; qprime = qprime_; qwait = qwait_; L = L_; gammap = gammap_; h = h_; hprime = hprime_; hscale = hscale_; eta = eta_; etamax = etamax_; tn = t0_; saved_tq5 = saved_tq5_; /* Copy the arrays from check point data structure */ for (j=0; j<=q; j++) N_VScale(ONE, zn_[j], zn[j]); if ( q < qmax ) N_VScale(ONE, zn_[qmax], zn[qmax]); if(quadr_) { for (j=0; j<=q; j++) N_VScale(ONE, znQ_[j], znQ[j]); if ( q < qmax ) N_VScale(ONE, znQ_[qmax], znQ[qmax]); } for (j=0; j<=L_MAX; j++) tau[j] = tau_[j]; for (j=0; j<=NUM_TESTS; j++) tq[j] = tq_[j]; for (j=0; j<=q; j++) l[j] = l_[j]; /* Force a call to setup */ forceSetup = TRUE; } return(CV_SUCCESS); }
int jmi_ode_cvode_solve(jmi_ode_solver_t* solver, realtype time_final, int initialize){ int flag = 0,retval = 0; jmi_ode_cvode_t* integrator = (jmi_ode_cvode_t*)solver->integrator; jmi_ode_problem_t* problem = solver -> ode_problem; realtype tret/*,*y*/; realtype time; char step_event = 0; /* boolean step_event = FALSE */ if (initialize==JMI_TRUE){ /* statements unused*/ /* if (problem->n_real_x > 0) { y = NV_DATA_S(integrator->y_work); y = problem->states; } */ memcpy (NV_DATA_S(integrator->y_work), problem->states, problem->n_real_x*sizeof(jmi_real_t)); time = problem->time; flag = CVodeReInit(integrator->cvode_mem, time, integrator->y_work); if (flag<0){ jmi_log_node(problem->log, logError, "Error", "Failed to re-initialize the solver. " "Returned with <error_flag: %d>", flag); return JMI_ODE_ERROR; } } /* Dont integrate past t_stop */ flag = CVodeSetStopTime(integrator->cvode_mem, time_final); if (flag < 0){ jmi_log_node(problem->log, logError, "Error", "Failed to specify the stop time. " "Returned with <error_flag: %d>", flag); return JMI_ODE_ERROR; } /* flag = CVode(integrator->cvode_mem, time_final, integrator->y_work, &tret, CV_NORMAL); if(flag<0){ jmi_log_node(problem->log, logError, "Error", "Failed to calculate the next step. " "Returned with <error_flag: %d>", flag); return JMI_ODE_ERROR; } */ flag = CV_SUCCESS; while (flag == CV_SUCCESS) { /* Perform a step */ flag = CVode(integrator->cvode_mem, time_final, integrator->y_work, &tret, CV_ONE_STEP); if(flag<0){ jmi_log_node(problem->log, logError, "Error", "Failed to calculate the next step. " "Returned with <error_flag: %d>", flag); return JMI_ODE_ERROR; } /* After each step call completed integrator step */ retval = problem->complete_step_func(problem, &step_event); if (retval != 0) { jmi_log_node(problem->log, logError, "Error", "Failed to complete an integrator step. " "Returned with <error_flag: %d>", retval); return JMI_ODE_ERROR; } if (step_event == TRUE) { jmi_log_node(problem->log, logInfo, "STEPEvent", "An event was detected at <t:%g>", tret); return JMI_ODE_EVENT; } } /* time = problem->time; if (time != tret) { flag = problem->rhs_func(problem, tret, NV_DATA_S(integrator->y_work), problem->states_derivative); if(flag != 0) { jmi_log_node(problem->log, logWarning, "Warning", "Evaluating the derivatives failed (recoverable error). " "Returned with <warningFlag: %d>", flag); return JMI_ODE_ERROR; } printf("Difference at time %g\n",tret); } */ if (flag == CV_ROOT_RETURN){ jmi_log_node(problem->log, logInfo, "CVODEEvent", "An event was detected at <t:%g>", tret); return JMI_ODE_EVENT; } return JMI_ODE_OK; }
int main(int narg, char **args) { realtype reltol, t, tout; N_Vector state, abstol; void *cvode_mem; int flag, flagr; int rootsfound[NRF]; int rootdir[] = {1,}; FILE *pout; if(!(pout = fopen("results/iaf_v.dat", "w"))){ fprintf(stderr, "Cannot open file results/iaf_v.dat. Are you trying to write to a non-existent directory? Exiting...\n"); exit(1); } state = abstol = NULL; cvode_mem = NULL; state = N_VNew_Serial(NEQ); if (check_flag((void *)state, "N_VNew_Serial", 0)) return(1); abstol = N_VNew_Serial(NEQ); if (check_flag((void *)abstol, "N_VNew_Serial", 0)) return(1); realtype reset = -0.07; realtype C = 3.2e-12; realtype thresh = -0.055; realtype gleak = 2e-10; realtype eleak = -0.053; realtype p[] = {reset, C, thresh, gleak, eleak, }; realtype v = reset; NV_Ith_S(state, 0) = reset; reltol = RTOL; NV_Ith_S(abstol,0) = ATOL0; /* Allocations and initializations */ cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON); if (check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1); flag = CVodeInit(cvode_mem, dstate_dt, T0, state); if (check_flag(&flag, "CVodeInit", 1)) return(1); flag = CVodeSetUserData(cvode_mem, p); if (check_flag(&flag, "CVodeSetUserData", 1)) return(1); flag = CVodeSVtolerances(cvode_mem, reltol, abstol); if (check_flag(&flag, "CVodeSVtolerances", 1)) return(1); flag = CVodeRootInit(cvode_mem, NRF, root_functions); if (check_flag(&flag, "CVodeRootInit", 1)) return(1); CVodeSetRootDirection(cvode_mem, rootdir); if (check_flag(&flag, "CVodeSetRootDirection", 1)) return(1); flag = CVDense(cvode_mem, NEQ); if (check_flag(&flag, "CVDense", 1)) return(1); printf(" \n Integrating iaf \n\n"); printf("#t v, \n"); PrintOutput(pout, t, state); tout = DT; while(1) { flag = CVode(cvode_mem, tout, state, &t, CV_NORMAL); if(flag == CV_ROOT_RETURN) { /* Event detected */ flagr = CVodeGetRootInfo(cvode_mem, rootsfound); if (check_flag(&flagr, "CVodeGetRootInfo", 1)) return(1); PrintRootInfo(t, state, rootsfound); if(rootsfound[0]){ //condition_0 v = NV_Ith_S(state, 0); NV_Ith_S(state, 0) = reset; } /* Restart integration with event-corrected state */ flag = CVodeSetUserData(cvode_mem, p); if (check_flag(&flag, "CVodeSetUserData", 1)) return(1); CVodeReInit(cvode_mem, t, state); //PrintRootInfo(t, state, rootsfound); } else { PrintOutput(pout, t, state); if(check_flag(&flag, "CVode", 1)) break; if(flag == CV_SUCCESS) { tout += DT; } if (t >= T1) break; } } PrintFinalStats(cvode_mem); N_VDestroy_Serial(state); N_VDestroy_Serial(abstol); CVodeFree(&cvode_mem); fclose(pout); return(0); }
int main(int narg, char **args) { realtype reltol, t, tout; N_Vector state, abstol; void *cvode_mem; int flag, flagr; int rootsfound[NRF]; int rootdir[] = {1,1,1,}; FILE *pout; pout = stdout; state = abstol = NULL; cvode_mem = NULL; state = N_VNew_Serial(NEQ); if (check_flag((void *)state, "N_VNew_Serial", 0)) return(1); abstol = N_VNew_Serial(NEQ); if (check_flag((void *)abstol, "N_VNew_Serial", 0)) return(1); realtype a = 0.02; realtype b = 0.2; realtype c = -50; realtype d = 2; realtype I = 0; realtype v0 = -70; realtype p[] = {a, b, c, d, I, v0, }; realtype v = v0; realtype u = b * v0; NV_Ith_S(state, 0) = v0; NV_Ith_S(state, 1) = b * v0; reltol = RTOL; NV_Ith_S(abstol,0) = ATOL0; NV_Ith_S(abstol,1) = ATOL1; /* Allocations and initializations */ cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON); if (check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1); flag = CVodeInit(cvode_mem, dstate_dt, T0, state); if (check_flag(&flag, "CVodeInit", 1)) return(1); flag = CVodeSetUserData(cvode_mem, p); if (check_flag(&flag, "CVodeSetUserData", 1)) return(1); flag = CVodeSVtolerances(cvode_mem, reltol, abstol); if (check_flag(&flag, "CVodeSVtolerances", 1)) return(1); flag = CVodeRootInit(cvode_mem, NRF, root_functions); if (check_flag(&flag, "CVodeRootInit", 1)) return(1); CVodeSetRootDirection(cvode_mem, rootdir); if (check_flag(&flag, "CVodeSetRootDirection", 1)) return(1); flag = CVDense(cvode_mem, NEQ); if (check_flag(&flag, "CVDense", 1)) return(1); printf(" \n Integrating izhikevich_burster \n\n"); printf("#t v, u, \n"); PrintOutput(pout, t, state); tout = DT; while(1) { flag = CVode(cvode_mem, tout, state, &t, CV_NORMAL); if(flag == CV_ROOT_RETURN) { /* Event detected */ flagr = CVodeGetRootInfo(cvode_mem, rootsfound); if (check_flag(&flagr, "CVodeGetRootInfo", 1)) return(1); PrintRootInfo(t, state, rootsfound); if(rootsfound[0]){ //spike v = NV_Ith_S(state, 0); u = NV_Ith_S(state, 1); NV_Ith_S(state, 0) = c; NV_Ith_S(state, 1) = u + d; } if(rootsfound[1]){ //start_inj I = 5; p[0] = a; p[1] = b; p[2] = c; p[3] = d; p[4] = I; p[5] = v0; } if(rootsfound[2]){ //end_inj I = 0; p[0] = a; p[1] = b; p[2] = c; p[3] = d; p[4] = I; p[5] = v0; } /* Restart integration with event-corrected state */ flag = CVodeSetUserData(cvode_mem, p); if (check_flag(&flag, "CVodeSetUserData", 1)) return(1); CVodeReInit(cvode_mem, t, state); //PrintRootInfo(t, state, rootsfound); } else { PrintOutput(pout, t, state); if(check_flag(&flag, "CVode", 1)) break; if(flag == CV_SUCCESS) { tout += DT; } if (t >= T1) break; } } PrintFinalStats(cvode_mem); N_VDestroy_Serial(state); N_VDestroy_Serial(abstol); CVodeFree(&cvode_mem); fclose(pout); return(0); }
static int Problem2(void) { realtype reltol=RTOL, abstol=ATOL, t, tout, er, erm, ero; int miter, flag, temp_flag, nerr=0; N_Vector y; void *cvode_mem; booleantype firstrun; int qu, iout; realtype hu; y = NULL; cvode_mem = NULL; y = N_VNew_Serial(P2_NEQ); if(check_flag((void *)y, "N_VNew", 0)) return(1); PrintIntro2(); cvode_mem = CVodeCreate(CV_ADAMS, CV_FUNCTIONAL); if(check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1); for (miter=FUNC; miter <= BAND_DQ; miter++) { if ((miter==DENSE_USER) || (miter==DENSE_DQ)) continue; ero = ZERO; N_VConst(ZERO, y); NV_Ith_S(y,0) = ONE; firstrun = (miter==FUNC); if (firstrun) { flag = CVodeMalloc(cvode_mem, f2, P2_T0, y, CV_SS, reltol, &abstol); if(check_flag(&flag, "CVodeMalloc", 1)) return(1); } else { flag = CVodeSetIterType(cvode_mem, CV_NEWTON); if(check_flag(&flag, "CVodeSetIterType", 1)) ++nerr; flag = CVodeReInit(cvode_mem, f2, P2_T0, y, CV_SS, reltol, &abstol); if(check_flag(&flag, "CVodeReInit", 1)) return(1); } flag = PrepareNextRun(cvode_mem, CV_ADAMS, miter, P2_MU, P2_ML); if(check_flag(&flag, "PrepareNextRun", 1)) return(1); PrintHeader2(); for(iout=1, tout=P2_T1; iout <= P2_NOUT; iout++, tout*=P2_TOUT_MULT) { flag = CVode(cvode_mem, tout, y, &t, CV_NORMAL); check_flag(&flag, "CVode", 1); erm = MaxError(y, t); temp_flag = CVodeGetLastOrder(cvode_mem, &qu); if(check_flag(&temp_flag, "CVodeGetLastOrder", 1)) ++nerr; temp_flag = CVodeGetLastStep(cvode_mem, &hu); if(check_flag(&temp_flag, "CVodeGetLastStep", 1)) ++nerr; PrintOutput2(t, erm, qu, hu); if (flag != CV_SUCCESS) { nerr++; break; } er = erm / abstol; if (er > ero) ero = er; if (er > P2_TOL_FACTOR) { nerr++; PrintErrOutput(P2_TOL_FACTOR); } } PrintFinalStats(cvode_mem, miter, ero); } CVodeFree(cvode_mem); cvode_mem = CVodeCreate(CV_BDF, CV_FUNCTIONAL); if(check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1); for (miter=FUNC; miter <= BAND_DQ; miter++) { if ((miter==DENSE_USER) || (miter==DENSE_DQ)) continue; ero = ZERO; N_VConst(ZERO, y); NV_Ith_S(y,0) = ONE; firstrun = (miter==FUNC); if (firstrun) { flag = CVodeMalloc(cvode_mem, f2, P2_T0, y, CV_SS, reltol, &abstol); if(check_flag(&flag, "CVodeMalloc", 1)) return(1); } else { flag = CVodeSetIterType(cvode_mem, CV_NEWTON); if(check_flag(&flag, "CVodeSetIterType", 1)) ++nerr; flag = CVodeReInit(cvode_mem, f2, P2_T0, y, CV_SS, reltol, &abstol); if(check_flag(&flag, "CVodeReInit", 1)) return(1); } flag = PrepareNextRun(cvode_mem, CV_BDF, miter, P2_MU, P2_ML); if(check_flag(&flag, "PrepareNextRun", 1)) return(1); PrintHeader2(); for(iout=1, tout=P2_T1; iout <= P2_NOUT; iout++, tout*=P2_TOUT_MULT) { flag = CVode(cvode_mem, tout, y, &t, CV_NORMAL); check_flag(&flag, "CVode", 1); erm = MaxError(y, t); temp_flag = CVodeGetLastOrder(cvode_mem, &qu); if(check_flag(&temp_flag, "CVodeGetLastOrder", 1)) ++nerr; temp_flag = CVodeGetLastStep(cvode_mem, &hu); if(check_flag(&temp_flag, "CVodeGetLastStep", 1)) ++nerr; PrintOutput2(t, erm, qu, hu); if (flag != CV_SUCCESS) { nerr++; break; } er = erm / abstol; if (er > ero) ero = er; if (er > P2_TOL_FACTOR) { nerr++; PrintErrOutput(P2_TOL_FACTOR); } } PrintFinalStats(cvode_mem, miter, ero); } CVodeFree(cvode_mem); N_VDestroy_Serial(y); return(nerr); }
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); }
int main() { realtype abstol=ATOL, reltol=RTOL, t, tout; N_Vector c; WebData wdata; void *cvode_mem; booleantype firstrun; int jpre, gstype, flag; int ns, mxns, iout; c = NULL; wdata = NULL; cvode_mem = NULL; /* Initializations */ c = N_VNew_Serial(NEQ); if(check_flag((void *)c, "N_VNew_Serial", 0)) return(1); wdata = AllocUserData(); if(check_flag((void *)wdata, "AllocUserData", 2)) return(1); InitUserData(wdata); ns = wdata->ns; mxns = wdata->mxns; /* Print problem description */ PrintIntro(); /* Loop over jpre and gstype (four cases) */ for (jpre = PREC_LEFT; jpre <= PREC_RIGHT; jpre++) { for (gstype = MODIFIED_GS; gstype <= CLASSICAL_GS; gstype++) { /* Initialize c and print heading */ CInit(c, wdata); PrintHeader(jpre, gstype); /* Call CVodeInit or CVodeReInit, then CVSpgmr to set up problem */ firstrun = (jpre == PREC_LEFT) && (gstype == MODIFIED_GS); if (firstrun) { cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON); if(check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1); wdata->cvode_mem = cvode_mem; flag = CVodeSetUserData(cvode_mem, wdata); if(check_flag(&flag, "CVodeSetUserData", 1)) return(1); flag = CVodeInit(cvode_mem, f, T0, c); if(check_flag(&flag, "CVodeInit", 1)) return(1); flag = CVodeSStolerances(cvode_mem, reltol, abstol); if (check_flag(&flag, "CVodeSStolerances", 1)) return(1); flag = CVSpgmr(cvode_mem, jpre, MAXL); if(check_flag(&flag, "CVSpgmr", 1)) return(1); flag = CVSpilsSetGSType(cvode_mem, gstype); if(check_flag(&flag, "CVSpilsSetGSType", 1)) return(1); flag = CVSpilsSetEpsLin(cvode_mem, DELT); if(check_flag(&flag, "CVSpilsSetEpsLin", 1)) return(1); flag = CVSpilsSetPreconditioner(cvode_mem, Precond, PSolve); if(check_flag(&flag, "CVSpilsSetPreconditioner", 1)) return(1); } else { flag = CVodeReInit(cvode_mem, T0, c); if(check_flag(&flag, "CVodeReInit", 1)) return(1); flag = CVSpilsSetPrecType(cvode_mem, jpre); check_flag(&flag, "CVSpilsSetPrecType", 1); flag = CVSpilsSetGSType(cvode_mem, gstype); if(check_flag(&flag, "CVSpilsSetGSType", 1)) return(1); } /* Print initial values */ if (firstrun) PrintAllSpecies(c, ns, mxns, T0); /* Loop over output points, call CVode, print sample solution values. */ tout = T1; for (iout = 1; iout <= NOUT; iout++) { flag = CVode(cvode_mem, tout, c, &t, CV_NORMAL); PrintOutput(cvode_mem, t); if (firstrun && (iout % 3 == 0)) PrintAllSpecies(c, ns, mxns, t); if(check_flag(&flag, "CVode", 1)) break; if (tout > RCONST(0.9)) tout += DTOUT; else tout *= TOUT_MULT; } /* Print final statistics, and loop for next case */ PrintFinalStats(cvode_mem); } } /* Free all memory */ CVodeFree(&cvode_mem); N_VDestroy_Serial(c); FreeUserData(wdata); return(0); }
int main(int argc, char *argv[]) { UserData data; void *cvode_mem; realtype abstol, reltol, t, tout; N_Vector u; int iout, my_pe, npes, flag, jpre; long int neq, local_N, mudq, mldq, mukeep, mlkeep; MPI_Comm comm; data = NULL; cvode_mem = NULL; u = NULL; /* Set problem size neq */ neq = NVARS*MX*MY; /* Get processor number and total number of pe's */ MPI_Init(&argc, &argv); comm = MPI_COMM_WORLD; MPI_Comm_size(comm, &npes); MPI_Comm_rank(comm, &my_pe); if (npes != NPEX*NPEY) { if (my_pe == 0) fprintf(stderr, "\nMPI_ERROR(0): npes = %d is not equal to NPEX*NPEY = %d\n\n", npes, NPEX*NPEY); MPI_Finalize(); return(1); } /* Set local length */ local_N = NVARS*MXSUB*MYSUB; /* Allocate and load user data block */ data = (UserData) malloc(sizeof *data); if(check_flag((void *)data, "malloc", 2, my_pe)) MPI_Abort(comm, 1); InitUserData(my_pe, local_N, comm, data); /* Allocate and initialize u, and set tolerances */ u = N_VNew_Parallel(comm, local_N, neq); if(check_flag((void *)u, "N_VNew_Parallel", 0, my_pe)) MPI_Abort(comm, 1); SetInitialProfiles(u, data); abstol = ATOL; reltol = RTOL; /* 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, "CVodeCreate", 0, my_pe)) MPI_Abort(comm, 1); /* Set the pointer to user-defined data */ flag = CVodeSetUserData(cvode_mem, data); if(check_flag(&flag, "CVodeSetUserData", 1, my_pe)) MPI_Abort(comm, 1); /* Call CVodeInit to initialize the integrator memory and specify the * user's right hand side function in u'=f(t,u), the inital time T0, and * the initial dependent variable vector u. */ flag = CVodeInit(cvode_mem, f, T0, u); if(check_flag(&flag, "CVodeInit", 1, my_pe)) return(1); /* Call CVodeSStolerances to specify the scalar relative tolerance * and scalar absolute tolerances */ flag = CVodeSStolerances(cvode_mem, reltol, abstol); if (check_flag(&flag, "CVodeSStolerances", 1, my_pe)) return(1); /* Call CVSpgmr to specify the linear solver CVSPGMR with left preconditioning and the default maximum Krylov dimension maxl */ flag = CVSpgmr(cvode_mem, PREC_LEFT, 0); if(check_flag(&flag, "CVBBDSpgmr", 1, my_pe)) MPI_Abort(comm, 1); /* Initialize BBD preconditioner */ mudq = mldq = NVARS*MXSUB; mukeep = mlkeep = NVARS; flag = CVBBDPrecInit(cvode_mem, local_N, mudq, mldq, mukeep, mlkeep, ZERO, flocal, NULL); if(check_flag(&flag, "CVBBDPrecAlloc", 1, my_pe)) MPI_Abort(comm, 1); /* Print heading */ if (my_pe == 0) PrintIntro(npes, mudq, mldq, mukeep, mlkeep); /* Loop over jpre (= PREC_LEFT, PREC_RIGHT), and solve the problem */ for (jpre = PREC_LEFT; jpre <= PREC_RIGHT; jpre++) { /* On second run, re-initialize u, the integrator, CVBBDPRE, and CVSPGMR */ if (jpre == PREC_RIGHT) { SetInitialProfiles(u, data); flag = CVodeReInit(cvode_mem, T0, u); if(check_flag(&flag, "CVodeReInit", 1, my_pe)) MPI_Abort(comm, 1); flag = CVBBDPrecReInit(cvode_mem, mudq, mldq, ZERO); if(check_flag(&flag, "CVBBDPrecReInit", 1, my_pe)) MPI_Abort(comm, 1); flag = CVSpilsSetPrecType(cvode_mem, PREC_RIGHT); check_flag(&flag, "CVSpilsSetPrecType", 1, my_pe); if (my_pe == 0) { printf("\n\n-------------------------------------------------------"); printf("------------\n"); } } if (my_pe == 0) { printf("\n\nPreconditioner type is: jpre = %s\n\n", (jpre == PREC_LEFT) ? "PREC_LEFT" : "PREC_RIGHT"); } /* In loop over output points, call CVode, print results, test for error */ for (iout = 1, tout = TWOHR; iout <= NOUT; iout++, tout += TWOHR) { flag = CVode(cvode_mem, tout, u, &t, CV_NORMAL); if(check_flag(&flag, "CVode", 1, my_pe)) break; PrintOutput(cvode_mem, my_pe, comm, u, t); } /* Print final statistics */ if (my_pe == 0) PrintFinalStats(cvode_mem); } /* End of jpre loop */ /* Free memory */ N_VDestroy_Parallel(u); free(data); CVodeFree(&cvode_mem); MPI_Finalize(); return(0); }
void Bloch_McConnell_CV_Model::InitSolver () { m_world = World::instance(); m_ncomp = m_world->GetNoOfCompartments(); m_nprops = m_world->GetNoOfSpinProps(); int m_ncoprops = (m_nprops - 4) / m_ncomp; double* m0s = new double[m_ncomp]; int n = 0; for (int i = 0; i < m_ncomp; i++) { m0s[i] = m_world->Values[m_ncoprops*i+M0]; if (m0s[i] > 0.0) n++; } m_bmaux.Init(m_ncomp); if (n == 1) m_bmaux.single = true; //Compute local exchange rates and return them in member matrix LocalExchangeRates (m_world->Helper(), m_bmaux.exrates, m0s, m_ncomp); delete [] m0s; m_world->auxiliary = (void*) (&m_bmaux); ((bmnvec*) (m_world->solverSettings))->y = N_VNew_Serial(NEQ*m_ncomp); // loop over pools, stepsize NEQ for ( int i = 0; i < m_ncomp*NEQ; i += NEQ ){ NV_Ith_S( ((bmnvec*) (m_world->solverSettings))->y,XC+i ) = m_world->solution[AMPL+i]*cos(m_world->solution[PHASE+i]);// polar coordinates NV_Ith_S( ((bmnvec*) (m_world->solverSettings))->y,YC+i ) = m_world->solution[AMPL+i]*sin(m_world->solution[PHASE+i]); NV_Ith_S( ((bmnvec*) (m_world->solverSettings))->y,ZC+i ) = m_world->solution[ZC+i]; } ((bmnvec*) (m_world->solverSettings))->abstol = N_VNew_Serial(NEQ*m_ncomp); // loop over pools, stepsize NEQ int poolVal = 0; for ( int i = 0; i< m_ncomp*NEQ; i+=NEQ ){ if (fabs(m_world->Values[m_ncoprops*poolVal+M0])<BEPS){ NV_Ith_S( ((bmnvec*) (m_world->solverSettings))->abstol,XC+i ) = ATOL1; NV_Ith_S( ((bmnvec*) (m_world->solverSettings))->abstol,ZC+i ) = ATOL3; } else{ NV_Ith_S( ((bmnvec*) (m_world->solverSettings))->abstol,XC+i ) = ATOL1*m_world->Values[m_ncoprops*poolVal+M0]; NV_Ith_S( ((bmnvec*) (m_world->solverSettings))->abstol,ZC+i ) = ATOL3*m_world->Values[m_ncoprops*poolVal+M0]; } NV_Ith_S( ((bmnvec*) (m_world->solverSettings))->abstol,YC+i ) = ATOL2; poolVal++; } int flag; #ifndef CVODE26 flag = CVodeReInit(m_cvode_mem,bloch,0,((bmnvec*) (m_world->solverSettings))->y,CV_SV,m_reltol,((bmnvec*) (m_world->solverSettings))->abstol); #else flag = CVodeReInit(m_cvode_mem,0,((bmnvec*) (m_world->solverSettings))->y); #endif if(flag != CV_SUCCESS ) { cout << "CVodeReInit failed! aborting..." << endl; if (flag == CV_MEM_NULL) cout << "MEM_NULL"<<endl; if (flag == CV_NO_MALLOC) cout << "CV_NO_MALLOC"<<endl; if (flag == CV_ILL_INPUT) cout << "CV_ILL_INPUT"<<endl; exit (-1); } }
void CvodeSolver::initialize(const double &pVoiStart, const int &pStatesCount, double *pConstants, double *pStates, double *pRates, double *pAlgebraic, ComputeRatesFunction pComputeRates) { if (!mSolver) { // Initialise the ODE solver itself OpenCOR::CoreSolver::CoreOdeSolver::initialize(pVoiStart, pStatesCount, pConstants, pStates, pRates, pAlgebraic, pComputeRates); // Retrieve some of the CVODE properties if (mProperties.contains(MaximumStepProperty)) { mMaximumStep = mProperties.value(MaximumStepProperty).toDouble(); } else { emit error(QObject::tr("the 'maximum step' property value could not be retrieved")); return; } if (mProperties.contains(MaximumNumberOfStepsProperty)) { mMaximumNumberOfSteps = mProperties.value(MaximumNumberOfStepsProperty).toInt(); } else { emit error(QObject::tr("the 'maximum number of steps' property value could not be retrieved")); return; } if (mProperties.contains(RelativeToleranceProperty)) { mRelativeTolerance = mProperties.value(RelativeToleranceProperty).toDouble(); } else { emit error(QObject::tr("the 'relative tolerance' property value could not be retrieved")); return; } if (mProperties.contains(AbsoluteToleranceProperty)) { mAbsoluteTolerance = mProperties.value(AbsoluteToleranceProperty).toDouble(); } else { emit error(QObject::tr("the 'absolute tolerance' property value could not be retrieved")); return; } // Create the states vector mStatesVector = N_VMake_Serial(pStatesCount, pStates); // Create the CVODE solver mSolver = CVodeCreate(CV_BDF, CV_NEWTON); // Use our own error handler CVodeSetErrHandlerFn(mSolver, errorHandler, this); // Initialise the CVODE solver CVodeInit(mSolver, rhsFunction, pVoiStart, mStatesVector); // Set some user data delete mUserData; // Just in case the solver got initialised before mUserData = new CvodeSolverUserData(pConstants, pAlgebraic, pComputeRates); CVodeSetUserData(mSolver, mUserData); // Set the linear solver CVDense(mSolver, pStatesCount); // Set the maximum step CVodeSetMaxStep(mSolver, mMaximumStep); // Set the maximum number of steps CVodeSetMaxNumSteps(mSolver, mMaximumNumberOfSteps); // Set the relative and absolute tolerances CVodeSStolerances(mSolver, mRelativeTolerance, mAbsoluteTolerance); } else { // Reinitialise the CVODE object CVodeReInit(mSolver, pVoiStart, mStatesVector); } }