Exemple #1
0
  void CVodeInt::initialize(double t0, FuncEval& func) 
  {
    m_neq = func.neq();
    m_t0  = t0;

    if (m_y) {
      N_VFree(nv(m_y));    // free solution vector if already allocated
    }
    m_y = reinterpret_cast<void*>(N_VNew(m_neq, 0));   // allocate solution vector
    // check abs tolerance array size
    if (m_itol == 1 && m_nabs < m_neq) 
      throw CVodeErr("not enough absolute tolerance values specified.");
    func.getInitialConditions(m_t0, m_neq, N_VDATA(nv(m_y)));

    // set options
    m_iopt[MXSTEP] = m_maxsteps;
    m_iopt[MAXORD] = m_maxord;
    m_ropt[HMAX]   = m_hmax;

    if (m_cvode_mem) CVodeFree(m_cvode_mem);

    // pass a pointer to func in m_data 
    m_data = (void*)&func;

    if (m_itol) {
      m_cvode_mem = CVodeMalloc(m_neq, cvode_rhs, m_t0, nv(m_y), m_method, 
				m_iter, m_itol, &m_reltol,
				nv(m_abstol), m_data, NULL, TRUE, m_iopt, 
				DATA_PTR(m_ropt), NULL);
    }
    else {
      m_cvode_mem = CVodeMalloc(m_neq, cvode_rhs, m_t0, nv(m_y), m_method, 
				m_iter, m_itol, &m_reltol,
				&m_abstols, m_data, NULL, TRUE, m_iopt, 
				DATA_PTR(m_ropt), NULL);
    }

    if (!m_cvode_mem) throw CVodeErr("CVodeMalloc failed.");

    if (m_type == DENSE + NOJAC) {
      CVDense(m_cvode_mem, NULL, NULL);
    }
    else if (m_type == DENSE + JAC) {
      CVDense(m_cvode_mem, cvode_jac, NULL);
    }
    else if (m_type == DIAG) {
      CVDiag(m_cvode_mem);
    }
    else if (m_type == GMRES) {
      CVSpgmr(m_cvode_mem, NONE, MODIFIED_GS, 0, 0.0,
	      NULL, NULL, NULL);
    }
    else {
      throw CVodeErr("unsupported option");
    }
  }
int CVodeMallocB(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 = CVodeMalloc(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);

}
Exemple #3
0
void    integrate()
{
    integer i, N, flag;
    real    tr, t;

    N = RHS.N;
    for (i = 1; i <= 2 * N; i++)
        Ith(y, i) = Ith(ystart, i);

    /* Initialize ODE solver */
    cvode_mem = CVodeMalloc(2 * N, derivs, Ith(tlist, 1), y,
                            (method == 0) ? ADAMS : BDF,
                            (itertype == 0) ? FUNCTIONAL : NEWTON,
                            (nabstol == 1) ? SS : SV,
                     &reltol, abstolp, NULL, NULL, TRUE, iopt, ropt, NULL);
    if (cvode_mem == NULL) {
        fatal_error("CVodeMalloc failed.\n");
    }
    /* Call CVDiag */
    CVDiag(cvode_mem);

    fwrite(N_VDATA(y), sizeof(real), 2 * N, op);
    for (i = 2; i <= ntimes; i++) {
        tr = Ith(tlist, i);
        flag = CVode1(cvode_mem, tr, y, &t, NORMAL);
        if (flag != SUCCESS) {
            sprintf(errmsg, "CVode failed, flag=%d.\n", flag);
            fatal_error(errmsg);
        }
        fwrite(N_VDATA(y), sizeof(real), 2 * N, op);
        progress += NHASH;
        while (progress >= ntimes - 1) {
            fprintf(stderr, "#");
            progress -= ntimes - 1;
        }
    }
    fprintf(stderr, "\n");
    CVodeFree(cvode_mem);
}
int main(int argc, char *argv[])
{
  realtype abstol, reltol, t, tout;
  N_Vector u;
  UserData data;
  PreconData predata;
  void *cvode_mem;
  int iout, flag, my_pe, npes;
  long int neq, local_N;
  MPI_Comm comm;

  u = NULL;
  data = NULL;
  predata = NULL;
  cvode_mem = 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; allocate preconditioner block */
  data = (UserData) malloc(sizeof *data);
  if (check_flag((void *)data, "malloc", 2, my_pe)) MPI_Abort(comm, 1);
  InitUserData(my_pe, comm, data);
  predata = AllocPreconData (data);

  /* Allocate u, and set initial values and tolerances */ 
  u = N_VNew_Parallel(comm, local_N, neq);
  if (check_flag((void *)u, "N_VNew", 0, my_pe)) MPI_Abort(comm, 1);
  SetInitialProfiles(u, data);
  abstol = ATOL; reltol = RTOL;

  /* 
     Call CVodeCreate to create the solver memory:
     
     CV_BDF     specifies the Backward Differentiation Formula
     CV_NEWTON  specifies a Newton iteration

     A pointer to the integrator memory is returned and stored in cvode_mem.
  */
  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 = CVodeSetFdata(cvode_mem, data);
  if (check_flag(&flag, "CVodeSetFdata", 1, my_pe)) MPI_Abort(comm, 1);

  /* 
     Call CVodeMalloc to initialize the integrator memory: 

     cvode_mem is the pointer to the integrator memory returned by CVodeCreate
     f       is the user's right hand side function in y'=f(t,y)
     T0      is the initial time
     u       is the initial dependent variable vector
     CV_SS   specifies scalar relative and absolute tolerances
     reltol  is the relative tolerance
     &abstol is a pointer to the scalar absolute tolerance
  */
  flag = CVodeMalloc(cvode_mem, f, T0, u, CV_SS, reltol, &abstol);
  if (check_flag(&flag, "CVodeMalloc", 1, my_pe)) MPI_Abort(comm, 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, my_pe)) MPI_Abort(comm, 1);

  /* Set preconditioner setup and solve routines Precond and PSolve, 
     and the pointer to the user-defined block data */
  flag = CVSpilsSetPreconditioner(cvode_mem, Precond, PSolve, predata);
  if (check_flag(&flag, "CVSpilsSetPreconditioner", 1, my_pe)) MPI_Abort(comm, 1);

  if (my_pe == 0)
    printf("\n2-species diurnal advection-diffusion problem\n\n");

  /* 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);

  /* Free memory */
  N_VDestroy_Parallel(u);
  free(data);
  FreePreconData(predata);
  CVodeFree(&cvode_mem);

  MPI_Finalize();

  return(0);
}
Bloch_McConnell_CV_Model::Bloch_McConnell_CV_Model     () {

    m_world->solverSettings = new bmnvec;
   /* for (int i=0;i<OPT_SIZE;i++) {m_iopt[i]=0; m_ropt[i]=0.0;}
    m_iopt[MXSTEP] = 1000000;
    m_ropt[HMAX]   = 10000.0;// the maximum stepsize in msec of the integrator*/
    m_reltol       = RTOL;

    //cvode2.5:
    // create cvode memory pointer; no mallocs done yet.
 //   m_cvode_mem = CVodeCreate(CV_BDF,CV_NEWTON);
   m_cvode_mem = CVodeCreate(CV_ADAMS,CV_FUNCTIONAL);

    // cvode allocate memory.
    // do CVodeMalloc with dummy values y0,abstol once here;
    // -> CVodeReInit can later be used



    //HACK
    int pools = m_world->GetNoOfCompartments();

    N_Vector y0,abstol;
    y0		= N_VNew_Serial(NEQ*pools);
    abstol	= N_VNew_Serial(NEQ*pools);
    ((bmnvec*) (m_world->solverSettings))->abstol = N_VNew_Serial(pools*NEQ);

    for(int i = 0; i< pools*NEQ; i+=NEQ){
    	NV_Ith_S(y0,AMPL+i) = 0.0; NV_Ith_S(y0,PHASE+i) = 0.0; NV_Ith_S(y0,ZC+i) = 0.0;
    	NV_Ith_S(abstol,AMPL+i) = ATOL1; NV_Ith_S(abstol,PHASE+i) = ATOL2; NV_Ith_S(abstol,ZC+i) = ATOL3;
    }
	
#ifndef CVODE26
    if(CVodeMalloc(m_cvode_mem,bloch,0,y0,CV_SV,m_reltol,abstol) != CV_SUCCESS ) {
    	cout << "CVodeMalloc failed! aborting..." << endl;exit (-1);
    }
    if(CVodeSetFdata(m_cvode_mem, (void *) m_world) !=CV_SUCCESS) {
    	cout << "CVode function data could not be set. Panic!" << endl;exit (-1);
    }

#else
    if(CVodeInit(m_cvode_mem,bloch,0,y0) != CV_SUCCESS ) {
    	cout << "CVodeInit failed! aborting..." << endl;exit (-1);
    }
    if(CVodeSVtolerances(m_cvode_mem, m_reltol, abstol)!= CV_SUCCESS){
    	cout << "CVodeSVtolerances failed! aborting..." << endl;exit (-1);
    }
    if(CVodeSetUserData(m_cvode_mem, (void *) m_world) !=CV_SUCCESS) {
    	cout << "CVode function data could not be set. Panic!" << endl;exit (-1);
    }
#endif

	/*    int flag;
	int blub = (3*pools);
	flag = CVDense(m_cvode_mem, blub);
	if (flag == CVDENSE_SUCCESS)
		cout<< "great" <<endl;
	else
		cout<< "bad" <<endl;
	*/

    N_VDestroy_Serial(y0);
    N_VDestroy_Serial(abstol);

    /*if(CVodeSetFdata(m_cvode_mem, (void *) m_world) !=CV_SUCCESS) {
    	cout << "CVode function data could not be set. Panic!" << endl;
    	exit (-1);
    }
	
    // set CVODE initial step size
  //    CVodeSetInitStep(m_cvode_mem, 1e-4);
      // set CVODE maximum step size
      CVodeSetMaxErrTestFails(m_cvode_mem, 10);
      // set CVODE minimum step size
      CVodeSetMinStep(m_cvode_mem, 1e-15);
	*/
    CVodeSetMaxNumSteps(m_cvode_mem, 10000000);

   	// maximum number of warnings t+h = t (if number negative -> no warnings are issued )
   	CVodeSetMaxHnilWarns(m_cvode_mem,2);

}
  void CVodesIntegrator::initialize(double t0, FuncEval& func) 
  {
    m_neq = func.neq();
    m_t0  = t0;

    if (m_y) {
      N_VDestroy_Serial(nv(m_y));    // free solution vector if already allocated
    }
    m_y = reinterpret_cast<void*>(N_VNew_Serial(m_neq));   // allocate solution vector
    for (int i=0; i<m_neq; i++) {
      NV_Ith_S(nv(m_y), i) = 0.0;
    }
    // check abs tolerance array size
    if (m_itol == CV_SV && m_nabs < m_neq) 
      throw CVodesErr("not enough absolute tolerance values specified.");

    func.getInitialConditions(m_t0, m_neq, NV_DATA_S(nv(m_y)));

    if (m_cvode_mem) CVodeFree(&m_cvode_mem);

    /*
     *  Specify the method and the iteration type:
     *      Cantera Defaults:
     *         CV_BDF  - Use BDF methods 
     *         CV_NEWTON - use newton's method 
     */
    m_cvode_mem = CVodeCreate(m_method, m_iter);
    if (!m_cvode_mem) throw CVodesErr("CVodeCreate failed.");

    int flag = 0;
#if defined(SUNDIALS_VERSION_22) || defined(SUNDIALS_VERSION_23)
    if (m_itol == CV_SV) {
      // vector atol
      flag = CVodeMalloc(m_cvode_mem, cvodes_rhs, m_t0, nv(m_y), m_itol,
			 m_reltol, nv(m_abstol));
    }
    else {
      // scalar atol
      flag = CVodeMalloc(m_cvode_mem, cvodes_rhs, m_t0, nv(m_y), m_itol,
			 m_reltol, &m_abstols);
    }
    if (flag != CV_SUCCESS) {
      if (flag == CV_MEM_FAIL) {
	throw CVodesErr("Memory allocation failed.");
      }
      else if (flag == CV_ILL_INPUT) {
	throw CVodesErr("Illegal value for CVodeMalloc input argument.");
      }
      else 
	throw CVodesErr("CVodeMalloc failed.");
    }
#elif defined(SUNDIALS_VERSION_24)

    flag = CVodeInit(m_cvode_mem, cvodes_rhs, m_t0, nv(m_y));
    if (flag != CV_SUCCESS) {
      if (flag == CV_MEM_FAIL) {
	throw CVodesErr("Memory allocation failed.");
      } else if (flag == CV_ILL_INPUT) {
	throw CVodesErr("Illegal value for CVodeInit input argument.");
      } else {
	throw CVodesErr("CVodeInit failed.");
      }
    }

    if (m_itol == CV_SV) {
      flag = CVodeSVtolerances(m_cvode_mem, m_reltol, nv(m_abstol));
    } else {
      flag = CVodeSStolerances(m_cvode_mem, m_reltol, m_abstols);
    }
    if (flag != CV_SUCCESS) {
      if (flag == CV_MEM_FAIL) {
	throw CVodesErr("Memory allocation failed.");
      } else if (flag == CV_ILL_INPUT) {
	throw CVodesErr("Illegal value for CVodeInit input argument.");
      } else {
	throw CVodesErr("CVodeInit failed.");
      }
    }
#else
    printf("unknown sundials verson\n");
    exit(-1);
#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 == GMRES) {
      CVSpgmr(m_cvode_mem, PREC_NONE, 0);
    }
    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 {
      throw CVodesErr("unsupported option");
    }

    // pass a pointer to func in m_data 
    m_fdata = new FuncData(&func, func.nparams());

    //m_data = (void*)&func;
#if defined(SUNDIALS_VERSION_22) || defined(SUNDIALS_VERSION_23)
    flag = CVodeSetFdata(m_cvode_mem, (void*)m_fdata);
    if (flag != CV_SUCCESS) {
      throw CVodesErr("CVodeSetFdata failed.");
    }
#elif defined(SUNDIALS_VERSION_24)
    flag = CVodeSetUserData(m_cvode_mem, (void*)m_fdata);
    if (flag != CV_SUCCESS) {
      throw CVodesErr("CVodeSetUserData failed.");
    }
#endif
    if (func.nparams() > 0) {
      sensInit(t0, func);
      flag = CVodeSetSensParams(m_cvode_mem, DATA_PTR(m_fdata->m_pars), 
				NULL, NULL);
    }

    // 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);
  }
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 CVodeMalloc 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 = CVodeSetFdata(cvode_mem, wdata);
        if(check_flag(&flag, "CVodeSetFdata", 1)) return(1);

        flag = CVodeMalloc(cvode_mem, f, T0, c, CV_SS, reltol, &abstol);
        if(check_flag(&flag, "CVodeMalloc", 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 = CVSpilsSetDelt(cvode_mem, DELT);
        if(check_flag(&flag, "CVSpilsSetDelt", 1)) return(1);

        flag = CVSpilsSetPreconditioner(cvode_mem, Precond, PSolve, wdata);
        if(check_flag(&flag, "CVSpilsSetPreconditioner", 1)) return(1);

      } else {

        flag = CVodeReInit(cvode_mem, f, T0, c, CV_SS, reltol, &abstol);
        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(void)
{
  realtype dx, dy, reltol, abstol, t, tout, umax;
  N_Vector u;
  UserData data;
  void *cvode_mem;
  int iout, flag;
  long int nst;

  u = NULL;
  data = NULL;
  cvode_mem = NULL;

  /* Create a serial vector */

  u = N_VNew_Serial(NEQ);  /* Allocate u vector */
  if(check_flag((void*)u, "N_VNew_Serial", 0)) return(1);

  reltol = ZERO;  /* Set the tolerances */
  abstol = ATOL;

  data = (UserData) malloc(sizeof *data);  /* Allocate data memory */
  if(check_flag((void *)data, "malloc", 2)) return(1);
  dx = data->dx = XMAX/(MX+1);  /* Set grid coefficients in data */
  dy = data->dy = YMAX/(MY+1);
  data->hdcoef = ONE/(dx*dx);
  data->hacoef = HALF/(TWO*dx);
  data->vdcoef = ONE/(dy*dy);

  SetIC(u, data);  /* Initialize u vector */

  /* 
     Call CvodeCreate to create integrator memory 

     CV_BDF     specifies the Backward Differentiation Formula
     CV_NEWTON  specifies a Newton iteration

     A pointer to the integrator problem memory is returned and
     stored in cvode_mem.  
  */

  cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON);
  if(check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1);

  /* 
     Call CVodeMalloc to initialize the integrator memory: 

     cvode_mem is the pointer to the integrator memory returned by CVodeCreate
     f       is the user's right hand side function in y'=f(t,y)
     T0      is the initial time
     u       is the initial dependent variable vector
     CV_SS   specifies scalar relative and absolute tolerances
     reltol  is the scalar relative tolerance
     &abstol is a pointer to the scalar absolute tolerance
  */

  flag = CVodeMalloc(cvode_mem, f, T0, u, CV_SS, reltol, &abstol);
  if(check_flag(&flag, "CVodeMalloc", 1)) return(1);

  /* Set the pointer to user-defined data */

  flag = CVodeSetFdata(cvode_mem, data);
  if(check_flag(&flag, "CVodeSetFdata", 1)) return(1);

  /* Call CVBand to specify the CVBAND band linear solver */

  flag = CVBand(cvode_mem, NEQ, MY, MY);
  if(check_flag(&flag, "CVBand", 1)) return(1);

  /* Set the user-supplied Jacobian routine Jac and
     the pointer to the user-defined block data. */

  flag = CVBandSetJacFn(cvode_mem, Jac, data);
  if(check_flag(&flag, "CVBandSetJacFn", 1)) return(1);

  /* In loop over output points: call CVode, print results, test for errors */

  umax = N_VMaxNorm(u);
  PrintHeader(reltol, abstol, umax);
  for(iout=1, tout=T1; iout <= NOUT; iout++, tout += DTOUT) {
    flag = CVode(cvode_mem, tout, u, &t, CV_NORMAL);
    if(check_flag(&flag, "CVode", 1)) break;
    umax = N_VMaxNorm(u);
    flag = CVodeGetNumSteps(cvode_mem, &nst);
    check_flag(&flag, "CVodeGetNumSteps", 1);
    PrintOutput(t, umax, nst);
  }

  PrintFinalStats(cvode_mem);  /* Print some final statistics   */

  N_VDestroy_Serial(u);  /* Free the u vector */
  CVodeFree(cvode_mem);  /* Free the integrator memory */
  free(data);            /* Free the user data */

  return(0);
}
Exemple #9
0
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);
}
Exemple #10
0
int main(int argc, char *argv[])
{
  void *cvode_mem;
  UserData data;
  realtype t, tout;
  N_Vector y;
  int iout, flag;

  realtype pbar[NS];
  int is; 
  N_Vector *yS;
  booleantype sensi, err_con;
  int sensi_meth;

  cvode_mem = NULL;
  data      = NULL;
  y         =  NULL;
  yS        = NULL;

  /* Process arguments */
  ProcessArgs(argc, argv, &sensi, &sensi_meth, &err_con);

  /* User data structure */
  data = (UserData) malloc(sizeof *data);
  if (check_flag((void *)data, "malloc", 2)) return(1);
  data->p[0] = RCONST(0.04);
  data->p[1] = RCONST(1.0e4);
  data->p[2] = RCONST(3.0e7);

  /* Initial conditions */
  y = N_VNew_Serial(NEQ);
  if (check_flag((void *)y, "N_VNew_Serial", 0)) return(1);

  Ith(y,1) = Y1;
  Ith(y,2) = Y2;
  Ith(y,3) = Y3;

  /* Create CVODES object */
  cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON);
  if (check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1);

  /* Allocate space for CVODES */
  flag = CVodeMalloc(cvode_mem, f, T0, y, CV_WF, 0.0, NULL);
  if (check_flag(&flag, "CVodeMalloc", 1)) return(1);

  /* Use private function to compute error weights */
  flag = CVodeSetEwtFn(cvode_mem, ewt, NULL);
  if (check_flag(&flag, "CVodeSetEwtFn", 1)) return(1);

  /* Attach user data */
  flag = CVodeSetFdata(cvode_mem, data);
  if (check_flag(&flag, "CVodeSetFdata", 1)) return(1);

  /* Attach linear solver */
  flag = CVDense(cvode_mem, NEQ);
  if (check_flag(&flag, "CVDense", 1)) return(1);

  flag = CVDenseSetJacFn(cvode_mem, Jac, data);
  if (check_flag(&flag, "CVDenseSetJacFn", 1)) return(1);

  printf("\n3-species chemical kinetics problem\n");

  /* Sensitivity-related settings */
  if (sensi) {

    pbar[0] = data->p[0];
    pbar[1] = data->p[1];
    pbar[2] = data->p[2];

    yS = N_VNewVectorArray_Serial(NS, NEQ);
    if (check_flag((void *)yS, "N_VNewVectorArray_Serial", 0)) return(1);
    for (is=0;is<NS;is++) N_VConst(ZERO, yS[is]);

    flag = CVodeSensMalloc(cvode_mem, NS, sensi_meth, yS);
    if(check_flag(&flag, "CVodeSensMalloc", 1)) return(1);

    flag = CVodeSetSensRhs1Fn(cvode_mem, fS);
    if (check_flag(&flag, "CVodeSetSensRhs1Fn", 1)) return(1);
    flag = CVodeSetSensErrCon(cvode_mem, err_con);
    if (check_flag(&flag, "CVodeSetSensFdata", 1)) return(1);
    flag = CVodeSetSensFdata(cvode_mem, data);
    if (check_flag(&flag, "CVodeSetSensFdata", 1)) return(1);
    flag = CVodeSetSensParams(cvode_mem, NULL, pbar, NULL);
    if (check_flag(&flag, "CVodeSetSensParams", 1)) return(1);

    printf("Sensitivity: YES ");
    if(sensi_meth == CV_SIMULTANEOUS)   
      printf("( SIMULTANEOUS +");
    else 
      if(sensi_meth == CV_STAGGERED) printf("( STAGGERED +");
      else                           printf("( STAGGERED1 +");   
    if(err_con) printf(" FULL ERROR CONTROL )");
    else        printf(" PARTIAL ERROR CONTROL )");

  } else {

    printf("Sensitivity: NO ");

  }
  
  /* In loop over output points, call CVode, print results, test for error */
  
  printf("\n\n");
  printf("===================================================");
  printf("============================\n");
  printf("     T     Q       H      NST                    y1");
  printf("           y2           y3    \n");
  printf("===================================================");
  printf("============================\n");

  for (iout=1, tout=T1; iout <= NOUT; iout++, tout *= TMULT) {

    flag = CVode(cvode_mem, tout, y, &t, CV_NORMAL);
    if (check_flag(&flag, "CVode", 1)) break;

    PrintOutput(cvode_mem, t, y);

    if (sensi) {
      flag = CVodeGetSens(cvode_mem, t, yS);
      if (check_flag(&flag, "CVodeGetSens", 1)) break;
      PrintOutputS(yS);
    } 
    printf("-------------------------------------------------");
    printf("------------------------------\n");

  }

  /* Print final statistics */
  PrintFinalStats(cvode_mem, sensi);

  /* Free memory */

  N_VDestroy_Serial(y);                    /* Free y vector */
  if (sensi) {
    N_VDestroyVectorArray_Serial(yS, NS);  /* Free yS vector */
  }
  free(data);                              /* Free user data */
  CVodeFree(cvode_mem);                    /* Free CVODES memory */

  return(0);
}
Exemple #11
0
int main()
{
  realtype abstol, reltol, t, tout;
  N_Vector u;
  UserData data;
  void *cvode_mem;
  int 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 

     CV_BDF     specifies the Backward Differentiation Formula
     CV_NEWTON  specifies a Newton iteration

     A pointer to the integrator memory is returned and stored in cvode_mem. */
  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 = CVodeSetFdata(cvode_mem, data);
  if(check_flag(&flag, "CVodeSetFdata", 1)) return(1);

  /* Call CVodeMalloc to initialize the integrator memory: 

     f       is the user's right hand side function in u'=f(t,u)
     T0      is the initial time
     u       is the initial dependent variable vector
     CV_SS   specifies scalar relative and absolute tolerances
     reltol  is the relative tolerance
     &abstol is a pointer to the scalar absolute tolerance      */
  flag = CVodeMalloc(cvode_mem, f, T0, u, CV_SS, reltol, &abstol);
  if(check_flag(&flag, "CVodeMalloc", 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);

  /* Set modified Gram-Schmidt orthogonalization, preconditioner 
     setup and solve routines Precond and PSolve, and the pointer 
     to the user-defined block data */
  flag = CVSpgmrSetGSType(cvode_mem, MODIFIED_GS);
  if(check_flag(&flag, "CVSpgmrSetGSType", 1)) return(1);

  flag = CVSpgmrSetPreconditioner(cvode_mem, Precond, PSolve, data);
  if(check_flag(&flag, "CVSpgmrSetPreconditioner", 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);

  /* Free memory */
  N_VDestroy_Serial(u);
  FreeUserData(data);
  CVodeFree(cvode_mem);

  return(0);
}
Exemple #12
0
int main()
{
  realtype t, tout;
  N_Vector y;
  void *cvode_mem;
  int flag, flagr, iout;
  int rootsfound[2];

  y = NULL;
  cvode_mem = NULL;

  /* Create serial vector of length NEQ for I.C. */
  y = N_VNew_Serial(NEQ);
  if (check_flag((void *)y, "N_VNew_Serial", 0)) return(1);

  /* Initialize y */
  Ith(y,1) = Y1;
  Ith(y,2) = Y2;
  Ith(y,3) = Y3;

  /* 
     Call CVodeCreate to create the solver memory:
     
     CV_BDF     specifies the Backward Differentiation Formula
     CV_NEWTON  specifies a Newton iteration

     A pointer to the integrator problem memory is returned and stored in cvode_mem.
  */

  cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON);
  if (check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1);
  
  /* 
     Call CVodeMalloc to initialize the integrator memory: 
     
     cvode_mem is the pointer to the integrator memory returned by CVodeCreate
     f         is the user's right hand side function in y'=f(t,y)
     T0        is the initial time
     y         is the initial dependent variable vector
     CV_WF     specifies scalar relative and vector absolute tolerances
     reltol    not needed (pass 0.0)
     abstol    not needed (pass NULL)
  */

  flag = CVodeMalloc(cvode_mem, f, T0, y, CV_WF, 0.0, NULL);
  if (check_flag(&flag, "CVodeMalloc", 1)) return(1);

  /* Use private function to compute error weights */
  flag = CVodeSetEwtFn(cvode_mem, ewt, NULL);
  if (check_flag(&flag, "CVodeSetEwtFn", 1)) return(1);

  /* Call CVodeRootInit to specify the root function g with 2 components */
  flag = CVodeRootInit(cvode_mem, 2, g, NULL);
  if (check_flag(&flag, "CVodeRootInit", 1)) return(1);

  /* Call CVDense to specify the CVDENSE dense linear solver */
  flag = CVDense(cvode_mem, NEQ);
  if (check_flag(&flag, "CVDense", 1)) return(1);

  /* Set the Jacobian routine to Jac (user-supplied) */
  flag = CVDenseSetJacFn(cvode_mem, Jac, NULL);
  if (check_flag(&flag, "CVDenseSetJacFn", 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.  */
  printf(" \n3-species kinetics problem\n\n");

  iout = 0;  tout = T1;
  while(1) {
    flag = CVode(cvode_mem, tout, y, &t, CV_NORMAL);
    PrintOutput(t, Ith(y,1), Ith(y,2), Ith(y,3));

    if (flag == CV_ROOT_RETURN) {
      flagr = CVodeGetRootInfo(cvode_mem, rootsfound);
      check_flag(&flagr, "CVodeGetRootInfo", 1);
      PrintRootInfo(rootsfound[0],rootsfound[1]);
    }

    if (check_flag(&flag, "CVode", 1)) break;
    if (flag == CV_SUCCESS) {
      iout++;
      tout *= TMULT;
    }

    if (iout == NOUT) break;
  }

  /* Print some final statistics */
  PrintFinalStats(cvode_mem);

  /* Free y vector */
  N_VDestroy_Serial(y);

  /* Free integrator memory */
  CVodeFree(&cvode_mem);

  return(0);
}
Exemple #13
0
/* Main Function */
int main(int argc, char *argv[])
	{  
	char tmpLName[11],tmpFName[11];	/* rivFlux File names */
  	Model_Data mData;               /* Model Data                */
  	Control_Data cData;             /* Solver Control Data       */
  	N_Vector CV_Y;                  /* State Variables Vector    */
  	void *cvode_mem;                /* Model Data Pointer        */
  	int flag;                       /* flag to test return value */
  	FILE *Ofile[22];           	/* Output file     */
	char *ofn[22];
	FILE *iproj;			/* Project File */
  	int N;                          /* Problem size              */
  	int i,j,k;                      /* loop index                */
  	realtype t;    			/* simulation time           */
  	realtype NextPtr, StepSize;     /* stress period & step size */
  	clock_t start, end_r, end_s;    /* system clock at points    */
  	realtype cputime_r, cputime_s;  /* for duration in realtype  */
	char *filename;

	/* Project Input Name */
	if(argc!=2)
		{
		iproj=fopen("projectName.txt","r");
		if(iproj==NULL)
			{
			printf("\t\nUsage ./pihm project_name");
			printf("\t\n         OR              ");
			printf("\t\nUsage ./pihm, and have a file in the current directory named projectName.txt with the project name in it");
			exit(0);
			}
		else
			{
			filename = (char *)malloc(15*sizeof(char));
			fscanf(iproj,"%s",filename);
			}
		}
	else
		{
  		/* get user specified file name in command line */
    		filename = (char *)malloc(strlen(argv[1])*sizeof(char));
		strcpy(filename,argv[1]);
		}
	/* Open Output Files */
	ofn[0] = (char *)malloc((strlen(filename)+3)*sizeof(char));
	strcpy(ofn[0], filename);
	Ofile[0]=fopen(strcat(ofn[0], ".GW"),"w");
	ofn[1] = (char *)malloc((strlen(filename)+5)*sizeof(char));
	strcpy(ofn[1], filename);
	Ofile[1]=fopen(strcat(ofn[1], ".surf"),"w");
	ofn[2] = (char *)malloc((strlen(filename)+4)*sizeof(char));
	strcpy(ofn[2], filename);
	Ofile[2]=fopen(strcat(ofn[2], ".et0"),"w");
	ofn[3] = (char *)malloc((strlen(filename)+4)*sizeof(char));
	strcpy(ofn[3], filename);
	Ofile[3]=fopen(strcat(ofn[3], ".et1"),"w");
	ofn[4] = (char *)malloc((strlen(filename)+4)*sizeof(char));
	strcpy(ofn[4], filename);
	Ofile[4]=fopen(strcat(ofn[4], ".et2"),"w");
	ofn[5] = (char *)malloc((strlen(filename)+3)*sizeof(char));
	strcpy(ofn[5], filename);
	Ofile[5]=fopen(strcat(ofn[5], ".is"),"w");
	ofn[6] = (char *)malloc((strlen(filename)+5)*sizeof(char));
	strcpy(ofn[6], filename);
	Ofile[6]=fopen(strcat(ofn[6], ".snow"),"w");
	for(i=0;i<11;i++)
		{
		sprintf(tmpLName,".rivFlx%d",i);
		strcpy(tmpFName,filename);
		strcat(tmpFName,tmpLName);
		Ofile[7+i]=fopen(tmpFName,"w");
		}	
	ofn[18] = (char *)malloc((strlen(filename)+6)*sizeof(char));
	strcpy(ofn[18], filename);
	Ofile[18]=fopen(strcat(ofn[18], ".stage"),"w");
	ofn[19] = (char *)malloc((strlen(filename)+6)*sizeof(char));
	strcpy(ofn[19], filename);
	Ofile[19]=fopen(strcat(ofn[19], ".unsat"),"w");
	ofn[20] = (char *)malloc((strlen(filename)+5)*sizeof(char));
	strcpy(ofn[20], filename);
	Ofile[20]=fopen(strcat(ofn[20], ".Rech"),"w");

  	/* allocate memory for model data structure */
  	mData = (Model_Data)malloc(sizeof *mData);
  
  	printf("\n ...  PIHM 2.0 is starting ... \n");
 
 	/* read in 9 input files with "filename" as prefix */
  	read_alloc(filename, mData, &cData); 

/*	if(mData->UnsatMode ==1)
		{    
  		} */
	if(mData->UnsatMode ==2)
		{    
  		/* problem size */
  		N = 3*mData->NumEle + 2*mData->NumRiv;
		mData->DummyY=(realtype *)malloc((3*mData->NumEle+2*mData->NumRiv)*sizeof(realtype));
  		}  	
  	/* initial state variable depending on machine*/
  	CV_Y = N_VNew_Serial(N);
  
  	/* initialize mode data structure */
  	initialize(filename, mData, &cData, CV_Y);
  
  	printf("\nSolving ODE system ... \n");
  
  	/* allocate memory for solver */
  	cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON);
  	if(cvode_mem == NULL) {printf("CVodeMalloc failed. \n"); return(1);}
  
  	flag = CVodeSetFdata(cvode_mem, mData);  
  	flag = CVodeSetInitStep(cvode_mem,cData.InitStep);
  	flag = CVodeSetStabLimDet(cvode_mem,TRUE);  
  	flag = CVodeSetMaxStep(cvode_mem,cData.MaxStep); 
  	flag = CVodeMalloc(cvode_mem, f, cData.StartTime, CV_Y, CV_SS, cData.reltol, &cData.abstol);  
  	flag = CVSpgmr(cvode_mem, PREC_NONE, 0);
  	flag = CVSpgmrSetGSType(cvode_mem, MODIFIED_GS);
  
  	/* set start time */
  	t = cData.StartTime;
  	start = clock();

  	/* start solver in loops */
  	for(i=0; i<cData.NumSteps; i++)
  		{
	/*	if (cData.Verbose != 1)
    			{
      			printf("  Running: %-4.1f%% ... ", (100*(i+1)/((realtype) cData.NumSteps))); 
      			fflush(stdout);
    			} */
    		/* inner loops to next output points with ET step size control */
    		while(t < cData.Tout[i+1])
    			{
      			if (t + cData.ETStep >= cData.Tout[i+1])
      				{
        			NextPtr = cData.Tout[i+1];
      				}
      			else
      				{
        			NextPtr = t + cData.ETStep;
      				}
      			StepSize = NextPtr - t; 
      
      			/* calculate Interception Storage */
      			is_sm_et(t, StepSize, mData,CV_Y);
			printf("\n Tsteps = %f ",t);
      			flag = CVode(cvode_mem, NextPtr, CV_Y, &t, CV_NORMAL);  
			update(t,mData);
    			}
		PrintData(Ofile,&cData,mData, CV_Y,t);
  		}
   	/* Free memory */
  	N_VDestroy_Serial(CV_Y);
  	/* Free integrator memory */
  	CVodeFree(cvode_mem);
  	free(mData);
  	return 0;
	}
Exemple #14
0
int main()
{
  M_Env machEnv;
  realtype abstol, reltol, t, tout, ropt[OPT_SIZE];
  long int iopt[OPT_SIZE];
  N_Vector y;
  UserData data;
  CVBandPreData bpdata;
  void *cvode_mem;
  int ml, mu, iout, flag, jpre;

  /* Initialize serial machine environment */
  machEnv = M_EnvInit_Serial(NEQ);

  /* Allocate and initialize y, and set problem data and tolerances */ 

  y = N_VNew(NEQ, machEnv);
  data = (UserData) malloc(sizeof *data);
  InitUserData(data);
  SetInitialProfiles(y, data->dx, data->dz);
  abstol = ATOL; reltol = RTOL;

  /* Call CVodeMalloc to initialize CVODE: 
     NEQ     is the problem size = number of equations
     f       is the user's right hand side function in y'=f(t,y)
     T0      is the initial time
     y       is the initial dependent variable vector
     BDF     specifies the Backward Differentiation Formula
     NEWTON  specifies a Newton iteration
     SS      specifies scalar relative and absolute tolerances
     &reltol and &abstol are pointers to the scalar tolerances
     data    is the pointer to the user-defined block of coefficients
     FALSE   indicates there are no optional inputs in iopt and ropt
     iopt    and ropt arrays communicate optional integer and real input/output

     A pointer to CVODE problem memory is returned and stored in cvode_mem.  */

  cvode_mem = CVodeMalloc(NEQ, f, T0, y, BDF, NEWTON, SS, &reltol,
                          &abstol, data, NULL, FALSE, iopt, ropt, machEnv);
  if (cvode_mem == NULL) { printf("CVodeMalloc failed."); return(1); }

  /* Call CVBandPreAlloc to initialize band preconditioner */
  ml = mu = 2;
  bpdata = CVBandPreAlloc (NEQ, f, data, mu, ml, cvode_mem);

  /* Call CVSpgmr to specify the CVODE linear solver CVSPGMR with
     left preconditioning, modified Gram-Schmidt orthogonalization,
     default values for the maximum Krylov dimension maxl and the tolerance
     parameter delt, preconditioner setup and solve routines CVBandPrecond
     and CVBandPSolve, the pointer to the user-defined block data, and
     NULL for the user jtimes routine and Jacobian data pointer.             */

  flag = CVSpgmr(cvode_mem, LEFT, MODIFIED_GS, 0, 0.0, CVBandPrecond,
                  CVBandPSolve, bpdata, NULL, NULL);
  if (flag != SUCCESS) { printf("CVSpgmr failed."); return(1); }

  printf("2-species diurnal advection-diffusion problem, %d by %d mesh\n",
         MX, MZ);
  printf("SPGMR solver; band preconditioner; mu = %d, ml = %d\n\n",
         mu, ml);

  /* Loop over jpre (= LEFT, RIGHT), and solve the problem */

  for (jpre = LEFT; jpre <= RIGHT; jpre++) {

  /* On second run, re-initialize y, CVODE, CVBANDPRE, and CVSPGMR */

  if (jpre == RIGHT) {

    SetInitialProfiles(y, data->dx, data->dz);

    flag = CVReInit(cvode_mem, f, T0, y, BDF, NEWTON, SS, &reltol,
                    &abstol, data, NULL, FALSE, iopt, ropt, machEnv);
    if (flag != SUCCESS) { printf("CVReInit failed."); return(1); }

    flag = CVReInitBandPre(bpdata, NEQ, f, data, mu, ml);

    flag = CVReInitSpgmr(cvode_mem, jpre, MODIFIED_GS, 0, 0.0,
                         CVBandPrecond, CVBandPSolve, bpdata, NULL, NULL);
    if (flag != SUCCESS) { printf("CVReInitSpgmr failed."); return(1); }

    printf("\n\n-------------------------------------------------------");
    printf("------------\n");
  }

    printf("\n\nPreconditioner type is:  jpre = %s\n\n",
           (jpre == LEFT) ? "LEFT" : "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, y, &t, NORMAL);
    PrintOutput(iopt, ropt, y, t);
    if (flag != SUCCESS) {
      printf("CVode failed, flag = %d.\n", flag);
      break;
    }
  }

  /* Print final statistics */

  PrintFinalStats(iopt);

  } /* End of jpre loop */

  /* Free memory */  

  N_VFree(y);
  free(data);
  CVBandPreFree(bpdata);
  CVodeFree(cvode_mem);
  M_EnvFree_Serial(machEnv);

  return(0);
}
Exemple #15
0
void FCV_MALLOC(realtype *t0, realtype *y0, 
                int *meth, int *itmeth, int *iatol, 
                realtype *rtol, realtype *atol,
                int *optin, long int *iopt, realtype *ropt, 
                int *ier)
{
  int lmm, iter, itol;
  void *atolptr;

  atolptr = NULL;

  if(F2C_vec->ops->nvgetarraypointer == NULL ||
     F2C_vec->ops->nvsetarraypointer == NULL) {
    *ier = -1;
    printf("A required vector operation is not implemented.\n\n");
    return;
  }

  /* Save the data array in F2C_vec into data_F2C_vec and then 
     overwrite it with y0 */
  data_F2C_vec = N_VGetArrayPointer(F2C_vec);
  N_VSetArrayPointer(y0, F2C_vec);

  lmm = (*meth == 1) ? CV_ADAMS : CV_BDF;
  iter = (*itmeth == 1) ? CV_FUNCTIONAL : CV_NEWTON;
  switch (*iatol) {
  case 1:
    F2C_atolvec = NULL;
    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:
    F2C_atolvec = NULL;
    itol = CV_WF;
    break;
  }

  /* 
     Call CVodeCreate, CVodeSet*, and CVodeMalloc to initialize CVODE: 
     lmm     is the method specifier
     iter    is the iteration method specifier
     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)

     A pointer to CVODE problem memory is createded and stored in CV_cvodemem. 
  */

  *ier = 0;

  CV_cvodemem = CVodeCreate(lmm, iter);

  if (CV_cvodemem == NULL) {
    *ier = -1;
    return;
  }

  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 = CVodeMalloc(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;
  }

  /* Store the unit roundoff in ropt for user access */
  ropt[9] = UNIT_ROUNDOFF;

  CV_iopt = iopt;
  CV_ropt = ropt;

  return;
}
int main(int argc, char *argv[])
{
  UserData data;
  void *cvode_mem;
  void *pdata;
  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 = pdata = 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:
     
     CV_BDF     specifies the Backward Differentiation Formula
     CV_NEWTON  specifies a Newton iteration

     A pointer to the integrator memory is returned and stored in cvode_mem.
  */

  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 = CVodeSetFdata(cvode_mem, data);
  if(check_flag(&flag, "CVodeSetFdata", 1, my_pe)) MPI_Abort(comm, 1);

  /* 
     Call CVodeMalloc to initialize the integrator memory: 

     cvode_mem is the pointer to the integrator memory returned by CVodeCreate
     f       is the user's right hand side function in y'=f(t,y)
     T0      is the initial time
     u       is the initial dependent variable vector
     CV_SS   specifies scalar relative and absolute tolerances
     reltol  is the relative tolerance
     &abstol is a pointer to the scalar absolute tolerance
  */

  flag = CVodeMalloc(cvode_mem, f, T0, u, CV_SS, reltol, &abstol);
  if(check_flag(&flag, "CVodeMalloc", 1, my_pe)) MPI_Abort(comm, 1);

  /* Allocate preconditioner block */
  mudq = mldq = NVARS*MXSUB;
  mukeep = mlkeep = NVARS;
  pdata = CVBBDPrecAlloc(cvode_mem, local_N, mudq, mldq, 
                         mukeep, mlkeep, ZERO, flocal, NULL);
  if(check_flag((void *)pdata, "CVBBDPrecAlloc", 0, my_pe)) MPI_Abort(comm, 1);

  /* Call CVBBDSpgmr to specify the linear solver CVSPGMR using the
     CVBBDPRE preconditioner, with left preconditioning and the
     default maximum Krylov dimension maxl  */
  flag = CVBBDSpgmr(cvode_mem, PREC_LEFT, 0, pdata);
  if(check_flag(&flag, "CVBBDSpgmr", 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, f, T0, u, CV_SS, reltol, &abstol);
    if(check_flag(&flag, "CVodeReInit", 1, my_pe)) MPI_Abort(comm, 1);

    flag = CVBBDPrecReInit(pdata, mudq, mldq, ZERO, flocal, NULL);
    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, pdata);

  } /* End of jpre loop */

  /* Free memory */
  N_VDestroy_Parallel(u);
  CVBBDPrecFree(&pdata);
  free(data);
  CVodeFree(&cvode_mem);

  MPI_Finalize();

  return(0);
}
Exemple #17
0
/* Main Function */
int main(int argc, char *argv[])
{  
  char *filename = "shalehills";        /* Input file name prefix    */
  char *StateFile;                /* Output file name string   */
  char *FluxFile;
  char *ETISFile;  
  char *QFile;  
  
  Model_Data mData;               /* Model Data                */
  Control_Data cData;             /* Solver Control Data       */
  
  N_Vector CV_Y;                  /* State Variables Vector    */
  M_Env machEnv;                  /* Machine Environments      */
  
  realtype ropt[OPT_SIZE];        /* Optional real type and integer type  */
  long int iopt[OPT_SIZE];        /* vecter for Message Passing to solver */
  
  void *cvode_mem;                /* Model Data Pointer        */
  int flag;                       /* flag to test return value */
  
  FILE *res_state_file;           /* Output file for States    */
  FILE *res_flux_file;            /* Output file for Flux      */
  FILE *res_etis_file;            /* Output file for ET and IS */
  FILE *res_q_file;
  
  int N;                          /* Problem size              */
  int i;                          /* loop index                */
  realtype t;                     /* simulation time           */
  realtype NextPtr, StepSize;     /* stress period & step size */
  
  clock_t start, end_r, end_s;    /* system clock at points    */
  realtype cputime_r, cputime_s;  /* for duration in realtype  */
  
  /* allocate memory for model data structure */
  mData = (Model_Data)malloc(sizeof *mData);
  start = clock();
  
  /* get user specified file name in command line */
  if(argc >= 2)
  {
    filename = (char *)malloc(strlen(argv[1])*sizeof(char));
    strcpy(filename, argv[1]);
  }  
  
  printf("\nBelt up!  PIHM 1.0 is starting ... \n");
  
  /* read in 7 input files with "filename" as prefix */
  read_alloc(filename, mData, &cData); 
    
  /* problem size */
  N = 3*mData->NumEle + mData->NumRiv;
  
  /* initial machine environment variable */
  machEnv = M_EnvInit_Serial(N);
  
  /* initial state variable depending on machine*/
  CV_Y = N_VNew(N, machEnv);
  
  /* initialize mode data structure */
  initialize(filename, mData, &cData, CV_Y);
  
  if(cData.Debug == 1) {PrintModelData(mData);}  
  
  end_r = clock();
  cputime_r = (end_r - start)/(realtype)CLOCKS_PER_SEC;
  
  printf("\nSolving ODE system ... \n");
  
  /* initial control parameter for CVODE solver. Otherwise the default value by C could cause problems. */
  for(i=0; i<OPT_SIZE; i++)
  {
    ropt[i] = 0.0;
    iopt[i] = 0;
  }
  
  /* set user specified control parameter */
  ropt[H0] = cData.InitStep;  
  ropt[HMAX] = cData.MaxStep; 
  
  /* allocate memory for solver */
  cvode_mem = CVodeMalloc(N, f, cData.StartTime, CV_Y, BDF, NEWTON, SS, &cData.reltol, 
                          &cData.abstol, mData, NULL, TRUE, iopt, ropt, machEnv);
  if(cvode_mem == NULL) {printf("CVodeMalloc failed. \n"); return(1);}
  
  if(cData.Solver == 1)
  {
    /* using dense direct solver */
    flag = CVDense(cvode_mem, NULL, NULL);
    if(flag != SUCCESS) {printf("CVDense failed. \n"); return(1);}
  } 
  else if(cData.Solver == 2)
  {
    /* using iterative solver */
    flag = CVSpgmr(cvode_mem, NONE, cData.GSType, cData.MaxK, cData.delt, NULL, NULL,
                       mData, NULL, NULL);
    if (flag != SUCCESS) {printf("CVSpgmr failed."); return(1);}
  } 
  
  /*allocate and copy to get output file name */
  StateFile = (char *)malloc((strlen(filename)+4)*sizeof(char));
  strcpy(StateFile, filename);
  FluxFile  = (char *)malloc((strlen(filename)+5)*sizeof(char));
  strcpy(FluxFile, filename);
  ETISFile  = (char *)malloc((strlen(filename)+5)*sizeof(char));
  strcpy(ETISFile, filename);
  QFile = (char *)malloc((strlen(filename)+2)*sizeof(char));
  strcpy(QFile, filename);
  
  /* open output file */
  if (cData.res_out == 1) {res_state_file = fopen(strcat(StateFile, ".res"), "w");}
  if (cData.flux_out == 1) {res_flux_file = fopen(strcat(FluxFile, ".flux"), "w");}
  if (cData.etis_out == 1) {res_etis_file = fopen(strcat(ETISFile, ".etis"), "w");}
  if (cData.q_out == 1) {res_q_file = fopen(strcat(QFile, ".q"), "w");}
  
  /* print header of output file */
  if (cData.res_out == 1) {FPrintYheader(res_state_file, mData);}
  if (cData.etis_out == 1) {FPrintETISheader(res_etis_file, mData);}
  if (cData.q_out == 1) {FPrintETISheader(res_q_file, mData);}
  printf("\n");
  
  /* set start time */
  t = cData.StartTime;
  
  /* start solver in loops */
  for(i=0; i<cData.NumSteps; i++)
  {
    /* prompt information in non-verbose mode */
    if (cData.Verbose != 1)
    {
      printf("  Running: %-4.1f%% ... ", (100*(i+1)/((realtype) cData.NumSteps))); 
      fflush(stdout);
    }
    
    /* inner loops to next output points with ET step size control */
    while(t < cData.Tout[i+1])
    {
      if (t + cData.ETStep >= cData.Tout[i+1])
      {
        NextPtr = cData.Tout[i+1];
      }
      else
      {
        NextPtr = t + cData.ETStep;
      }
      StepSize = NextPtr - t; 
      
      /* calculate Interception Storage */
      calIS(t, StepSize, mData);
      /* solving ODE system */
      flag = CVode(cvode_mem, NextPtr, CV_Y, &t, NORMAL);  
      /* calculate ET and adjust states variables*/
      calET(t, StepSize, CV_Y, mData);
    }  
    
    if(cData.Verbose == 1) {PrintVerbose(i, t, iopt, ropt);}

    /* uncomment it if user need it verbose mode */  
    /* if(cData.Verbose == 1) {PrintY(mData, CV_Y, t);} */
    
    /* print out results to files at every output time */
    if (cData.res_out == 1) {FPrintY(mData, CV_Y, t, res_state_file);}
    if (cData.flux_out == 1) {FPrintFlux(mData, t, res_flux_file);}
    if (cData.etis_out == 1) {FPrintETIS(mData, t, res_etis_file);}
    if (cData.q_out == 1) {FPrintQ(mData, t, res_q_file);}
    
    if (cData.Verbose != 1) {printf("\r");}  
    
    if(flag != SUCCESS) {printf("CVode failed, flag = %d. \n", flag); return(flag);} 
    
    /* clear buffer */
    fflush(stdout);  
  }
  
  /* free memory */
  /*
  N_VFree(CV_Y);
  CVodeFree(cvode_mem);
  M_EnvFree_Serial(machEnv); 
  */
  
  /* capture time */
  end_s = clock();
  cputime_s = (end_s - end_r)/(realtype)CLOCKS_PER_SEC;
  
  /* print out simulation statistics */
  PrintFarewell(cData, iopt, ropt, cputime_r, cputime_s);
  if (cData.res_out == 1) {FPrintFarewell(cData, res_state_file, iopt, ropt, cputime_r, cputime_s);}
  
  /* close output files */
  if (cData.res_out == 1)  {fclose(res_state_file);}
  if (cData.flux_out == 1) {fclose(res_flux_file);}
  if (cData.etis_out == 1) {fclose(res_etis_file);}
  if (cData.q_out == 1)    {fclose(res_q_file);}
  
  free(mData);
  
  return 0;
}
Exemple #18
0
void    sdesim(integer itraj, integer ntraj)
/* Integrate a stochastic differential equation */
{
    integer flag, indx, i, j, k, l, m, N;
    real    t, xnorm2;
    real    temp, tempr, tempi, tl, tmp;

    top = Ith(tlist, 1);
    head = 0;
    N = RHS.N;
    for (j = 1; j <= 2 * N; j++)
        Ith(y, j) = Ith(ystart, j);

    /* Initialize ODE solver */
    ropt[HMAX] = dt;
    cvode_mem = CVodeMalloc(2 * N, derivs, Ith(tlist, 1), y,
                            (method == 0) ? ADAMS : BDF,
                            (itertype == 0) ? FUNCTIONAL : NEWTON,
                            (nabstol == 1) ? SS : SV,
                      &reltol, abstolp, NULL, NULL, TRUE, iopt, ropt, NULL);
    if (cvode_mem == NULL) {
        fatal_error("CVodeMalloc failed.\n");
    }
    /* Call CVDiag */
    CVDiag(cvode_mem);

    if (nopers == 0)
        fwrite(&itraj, sizeof(integer), 1, op);
    if (photocurflag)
        fwrite(&itraj, sizeof(integer), 1, php);
    if (clrecflag) {
        temp = itraj;
        fwrite(&temp, sizeof(real), 1, cp);
        temp = 0.0;
        fwrite(&temp, sizeof(real), 1, cp);
    }
    m = 1;
    tl = Ith(tlist, 1);
    if (nopers == 0)            /* Write the wave function */
        fwrite(N_VDATA(y), sizeof(real), 2 * N, op);
    else                        /* Record operator expectations in
                                 * accumulation buffer */
        operAccum(N_VDATA(y) - 1, q, N, tl, 1);


    for (i = 2; i <= ntimes; i++) {
        for (k = 1; k <= nhomodyne; k++)  /* Initialize buffers for
                                           * photocurrent records */
            h**o[k] = 0;
        for (k = 1; k <= nheterodyne; k++)
            heteror[k] = heteroi[k] = 0;
        for (l = 1; l <= refine; l++) {
            for (k = 1; k <= nhomodyne; k++)
                Ith(homnoise, k) = gennor(0.0, namplr);
            for (k = 1; k <= nheterodyne; k++) {
                Ith(hetnoiser, k) = gennor(0.0, namplc);
                Ith(hetnoisei, k) = gennor(0.0, namplc);
            }
            tl = Ith(tlist, i - 1) + (l - 1) * dt;
            flag = CVodeRestart(cvode_mem, tl, y);
            if (flag != SUCCESS) {
                sprintf(errmsg, "CVodeRestart failed, flag=%d.\n", flag);
                fatal_error(errmsg);
            }
            flag = CVode(cvode_mem, tl + dt, y, &t, NORMAL);
            if (flag != SUCCESS) {
                sprintf(errmsg, "CVode failed, flag=%d.\n", flag);
                fatal_error(errmsg);
            }
            /* Evaluate photocurrent during the previous interval */
            xnorm2 = norm2(N_VDATA(y) - 1, N);
            for (k = 1; k <= nhomodyne; k++) {
                FSmul(&homodyne[k], tl, N_VDATA(y) - 1, q); /* Calculate homodyne
                                                             * terms */
                inprod(N_VDATA(y) - 1, q, N, &tempr, &tempi);
                temp = 2 * tempr / xnorm2;
                if (photocurflag) {
                    h**o[k] += (temp + Ith(homnoise, k));
                    if (l == refine) {
                        tmp = h**o[k] / refine;
                        fwrite(&tmp, sizeof(real), 1, php);
                    }
                }
            }
            for (k = 1; k <= nheterodyne; k++) {
                FSmul(&heterodyne[k], tl, N_VDATA(y) - 1, q); /* Calculate heterodyne
                                                               * terms */
                inprod(N_VDATA(y) - 1, q, N, &tempr, &tempi);
                tempr = tempr / xnorm2;
                tempi = -tempi / xnorm2;
                if (photocurflag) {
                    heteror[k] += (tempr + Ith(hetnoiser, k));
                    heteroi[k] += (tempi + Ith(hetnoisei, k));
                    if (l == refine) {
                        tmp = heteror[k] / refine;
                        fwrite(&tmp, sizeof(real), 1, php);
                        tmp = heteroi[k] / refine;
                        fwrite(&tmp, sizeof(real), 1, php);
                    }
                }
            }
        }
        /* Normalize the wave function */
        xnorm2 = 1. / sqrt(norm2(N_VDATA(y) - 1, N));
        for (j = 1; j <= 2 * N; j++)
            pl[j] = Ith(y, j) * xnorm2;

        if (nopers == 0)
            fwrite(&pl[1], sizeof(real), 2 * N, op);
        else
            operAccum(pl, q, N, tl, i);
        if (xnorm2 < 1e-6 || xnorm2 > 1e6) {  /* Restart integrator if norm
                                               * is too large or small */
            CVodeFree(cvode_mem);
            ropt[HMAX] = dt;
            for (j = 1; j <= 2 * N; j++)
                Ith(y, j) = pl[j];
            cvode_mem = CVodeMalloc(2 * N, derivs, Ith(tlist, 1), y,
                                    (method == 0) ? ADAMS : BDF,
                                    (itertype == 0) ? FUNCTIONAL : NEWTON,
                                    (nabstol == 1) ? SS : SV,
                      &reltol, abstolp, NULL, NULL, TRUE, iopt, ropt, NULL);
            if (cvode_mem == NULL) {
                fatal_error("CVodeMalloc failed.\n");
            }
            /* Call CVDiag */
            CVDiag(cvode_mem);
        }
        progress += NHASH;
        while (progress >= (ntimes - 1) * ntraj) {
            fprintf(stderr, "#");
            progress -= (ntimes - 1) * ntraj;
        }
    }
    CVodeFree(cvode_mem);
}
int main(int argc, char *argv[])
{
  realtype dx, reltol, abstol, t, tout, umax;
  N_Vector u;
  UserData data;
  void *cvode_mem;
  int iout, flag, my_pe, npes;
  long int local_N, nperpe, nrem, my_base, nst;

  MPI_Comm comm;

  u = NULL;
  data = NULL;
  cvode_mem = NULL;

  /* Get processor number, total number of pe's, and my_pe. */
  MPI_Init(&argc, &argv);
  comm = MPI_COMM_WORLD;
  MPI_Comm_size(comm, &npes);
  MPI_Comm_rank(comm, &my_pe);

  /* Set local vector length. */
  nperpe = NEQ/npes;
  nrem = NEQ - npes*nperpe;
  local_N = (my_pe < nrem) ? nperpe+1 : nperpe;
  my_base = (my_pe < nrem) ? my_pe*local_N : my_pe*nperpe + nrem;

  data = (UserData) malloc(sizeof *data);  /* Allocate data memory */
  if(check_flag((void *)data, "malloc", 2, my_pe)) MPI_Abort(comm, 1);

  data->comm = comm;
  data->npes = npes;
  data->my_pe = my_pe;

  u = N_VNew_Parallel(comm, local_N, NEQ);  /* Allocate u vector */
  if(check_flag((void *)u, "N_VNew", 0, my_pe)) MPI_Abort(comm, 1);

  reltol = ZERO;  /* Set the tolerances */
  abstol = ATOL;

  dx = data->dx = XMAX/((realtype)(MX+1));  /* Set grid coefficients in data */
  data->hdcoef = RCONST(1.0)/(dx*dx);
  data->hacoef = RCONST(0.5)/(RCONST(2.0)*dx);

  SetIC(u, dx, local_N, my_base);  /* Initialize u vector */

  /* 
     Call CVodeCreate to create the solver memory:
     
     CV_ADAMS   specifies the Adams Method
     CV_FUNCTIONAL  specifies functional iteration

     A pointer to the integrator memory is returned and stored in cvode_mem.
  */

  cvode_mem = CVodeCreate(CV_ADAMS, CV_FUNCTIONAL);
  if(check_flag((void *)cvode_mem, "CVodeCreate", 0, my_pe)) MPI_Abort(comm, 1);

  flag = CVodeSetFdata(cvode_mem, data);
  if(check_flag(&flag, "CVodeSetFdata", 1, my_pe)) MPI_Abort(comm, 1);

  /* 
     Call CVodeMalloc to initialize the integrator memory: 

     cvode_mem is the pointer to the integrator memory returned by CVodeCreate
     f       is the user's right hand side function in y'=f(t,y)
     T0      is the initial time
     u       is the initial dependent variable vector
     CV_SS   specifies scalar relative and absolute tolerances
     reltol  is the relative tolerance
     &abstol is a pointer to the scalar absolute tolerance
  */

  flag = CVodeMalloc(cvode_mem, f, T0, u, CV_SS, reltol, &abstol);
  if(check_flag(&flag, "CVodeMalloc", 1, my_pe)) MPI_Abort(comm, 1);

  if (my_pe == 0) PrintIntro(npes);

  umax = N_VMaxNorm(u);

  if (my_pe == 0) {
    t = T0;
    PrintData(t, umax, 0);
  }

  /* In loop over output points, call CVode, print results, test for error */

  for (iout=1, tout=T1; iout <= NOUT; iout++, tout += DTOUT) {
    flag = CVode(cvode_mem, tout, u, &t, CV_NORMAL);
    if(check_flag(&flag, "CVode", 1, my_pe)) break;
    umax = N_VMaxNorm(u);
    flag = CVodeGetNumSteps(cvode_mem, &nst);
    check_flag(&flag, "CVodeGetNumSteps", 1, my_pe);
    if (my_pe == 0) PrintData(t, umax, nst);
  }

  if (my_pe == 0) 
    PrintFinalStats(cvode_mem);  /* Print some final statistics */

  N_VDestroy_Parallel(u);        /* Free the u vector */
  CVodeFree(&cvode_mem);         /* Free the integrator memory */
  free(data);                    /* Free user data */

  MPI_Finalize();

  return(0);
}
Exemple #20
0
int main(int argc, char *argv[])
{
  void *cvode_mem;
  UserData data;
  realtype abstol, reltol, t, tout;
  N_Vector y;
  int iout, flag;

  realtype *pbar;
  int is, *plist;
  N_Vector *uS;
  booleantype sensi, err_con;
  int sensi_meth;

  pbar = NULL;
  plist = NULL;
  uS = NULL;
  y = NULL;
  data = NULL;
  cvode_mem = NULL;

  /* Process arguments */
  ProcessArgs(argc, argv, &sensi, &sensi_meth, &err_con);

  /* Problem parameters */
  data = AllocUserData();
  if(check_flag((void *)data, "AllocUserData", 2)) return(1);
  InitUserData(data);

  /* Initial states */
  y = N_VNew_Serial(NEQ);
  if(check_flag((void *)y, "N_VNew_Serial", 0)) return(1);
  SetInitialProfiles(y, data->dx, data->dz);
  
  /* Tolerances */
  abstol=ATOL; 
  reltol=RTOL;

  /* Create CVODES object */
  cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON);
  if(check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1);

  flag = CVodeSetFdata(cvode_mem, data);
  if(check_flag(&flag, "CVodeSetFdata", 1)) return(1);

  flag = CVodeSetMaxNumSteps(cvode_mem, 2000);
  if(check_flag(&flag, "CVodeSetMaxNumSteps", 1)) return(1);

  /* Allocate CVODES memory */
  flag = CVodeMalloc(cvode_mem, f, T0, y, CV_SS, reltol, &abstol);
  if(check_flag(&flag, "CVodeMalloc", 1)) return(1);

  /* Attach CVSPGMR linear solver */
  flag = CVSpgmr(cvode_mem, PREC_LEFT, 0);
  if(check_flag(&flag, "CVSpgmr", 1)) return(1);

  flag = CVSpilsSetPreconditioner(cvode_mem, Precond, PSolve, data);
  if(check_flag(&flag, "CVSpilsSetPreconditioner", 1)) return(1);

  printf("\n2-species diurnal advection-diffusion problem\n");

  /* Forward sensitivity analysis */
  if(sensi) {

    plist = (int *) malloc(NS * sizeof(int));
    if(check_flag((void *)plist, "malloc", 2)) return(1);
    for(is=0; is<NS; is++) plist[is] = is;

    pbar = (realtype *) malloc(NS * sizeof(realtype));
    if(check_flag((void *)pbar, "malloc", 2)) return(1);
    for(is=0; is<NS; is++) pbar[is] = data->p[plist[is]];

    uS = N_VCloneVectorArray_Serial(NS, y);
    if(check_flag((void *)uS, "N_VCloneVectorArray_Serial", 0)) return(1);
    for(is=0;is<NS;is++)
      N_VConst(ZERO,uS[is]);

    flag = CVodeSensMalloc(cvode_mem, NS, sensi_meth, uS);
    if(check_flag(&flag, "CVodeSensMalloc", 1)) return(1);

    flag = CVodeSetSensErrCon(cvode_mem, err_con);
    if(check_flag(&flag, "CVodeSetSensErrCon", 1)) return(1);

    flag = CVodeSetSensRho(cvode_mem, ZERO);
    if(check_flag(&flag, "CVodeSetSensRho", 1)) return(1);

    flag = CVodeSetSensParams(cvode_mem, data->p, pbar, plist);
    if(check_flag(&flag, "CVodeSetSensParams", 1)) return(1);

    printf("Sensitivity: YES ");
    if(sensi_meth == CV_SIMULTANEOUS)   
      printf("( SIMULTANEOUS +");
    else 
      if(sensi_meth == CV_STAGGERED) printf("( STAGGERED +");
      else                           printf("( STAGGERED1 +");   
    if(err_con) printf(" FULL ERROR CONTROL )");
    else        printf(" PARTIAL ERROR CONTROL )");
    
  } else {

    printf("Sensitivity: NO ");

  }

  /* In loop over output points, call CVode, print results, test for error */

  printf("\n\n");
  printf("========================================================================\n");
  printf("     T     Q       H      NST                    Bottom left  Top right \n");
  printf("========================================================================\n");

  for (iout=1, tout = TWOHR; iout <= NOUT; iout++, tout += TWOHR) {
    flag = CVode(cvode_mem, tout, y, &t, CV_NORMAL);
    if(check_flag(&flag, "CVode", 1)) break;
    PrintOutput(cvode_mem, t, y);
    if (sensi) {
      flag = CVodeGetSens(cvode_mem, t, uS);
      if(check_flag(&flag, "CVodeGetSens", 1)) break;
      PrintOutputS(uS);
    }
    
    printf("------------------------------------------------------------------------\n");

  }

  /* Print final statistics */
  PrintFinalStats(cvode_mem, sensi);

  /* Free memory */
  N_VDestroy_Serial(y);
  if (sensi) {
    N_VDestroyVectorArray_Serial(uS, NS);
    free(pbar);
    free(plist);
  }
  FreeUserData(data);
  CVodeFree(&cvode_mem);

  return(0);
}
Exemple #21
0
real    docollapse(real tl, real nl, real tr, real nr, real thresh)
/* Find the time of collapse, update the wave function and restart the integrator */
{
    integer j, flag, k;
    real    tc, nc, temp, sum, t;

	for (k=1;k<=5;k++) {
        tc = tl + log(nl / thresh) / log(nl / nr) * (tr - tl);
        flag = CVode1(cvode_mem, tc, y, &t, NORMAL);
        if (flag != SUCCESS) {
            sprintf(errmsg, "CVode failed, flag=%d.\n", flag);
            fatal_error(errmsg);
        }
        nc = norm2(N_VDATA(y) - 1, N);
        if (fabs(thresh - nc) < THRESHTOL * fabs(thresh))
            break;
        else if (nc < thresh) {
            nr = nc;
            tr = tc;
        } else {
            nl = nc;
            tl = tc;
        }
    }
	/*    if (k>5) printf("\nWarning: Norm^2 of wavefunction does not attain threshold %f / %f\n"
					"Increase accuracy of integrator.\n",nc,thresh);*/
    /* Collapse occurs at tc, apply appropriate operator and restart
     * integrator */
    sum = 0.0;
    for (j = 1; j <= ncollapses; j++) {
        FSmul(&collapses[j], tc, N_VDATA(y) - 1, N_VDATA(q) - 1);
        sum += (Cprobs[j] = norm2(N_VDATA(q) - 1, N));
    }
    thresh = genunf(0.0, 1.0);  /* To determine which collapse occured */
    for (j = 1; j <= ncollapses; j++) {
        thresh -= Cprobs[j] / sum;
        if (thresh <= 0)
            break;
    }
    if (clrecflag) {            /* Write out classical record */
        fwrite(&tc, sizeof(real), 1, cp);
        temp = j;
        fwrite(&temp, sizeof(real), 1, cp);
    }
    /* Apply the collapse and normalize */
    FSmul(&collapses[j], tc, N_VDATA(y) - 1, N_VDATA(q) - 1);
    sum = sqrt(norm2(N_VDATA(q) - 1, N));
    for (j = 1; j <= 2 * N; j++)
        Ith(y, j) = Ith(q, j) / sum;
    /* Replace the integrator, since we have a new initial condition */
    CVodeFree(cvode_mem);
    cvode_mem = CVodeMalloc(2 * N, derivs, tc, y,
                            (method == 0) ? ADAMS : BDF,
                            (itertype == 0) ? FUNCTIONAL : NEWTON,
                            (nabstol == 1) ? SS : SV,
                     &reltol, abstolp, NULL, NULL, TRUE, iopt, ropt, NULL);
    if (cvode_mem == NULL) {
        fatal_error("CVodeMalloc failed.\n");
    }
    /* Call CVDiag */
    CVDiag(cvode_mem);
    return tc;
}
Exemple #22
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);
}
Exemple #23
0
void    mcwfalg(integer itraj, integer ntraj)
{
    integer i, N, exflag, flag;
    real    eps = 1.0e-6, t, temp;
    real    nl, nr, na, tl, tr, taim, thresh;
    double  sum = 0.0;

    N = RHS.N;
    for (i = 1; i <= 2 * N; i++)
        Ith(y, i) = Ith(ystart, i);

    /* Initialize ODE solver */
    cvode_mem = CVodeMalloc(2 * N, derivs, Ith(tlist, 1), y,
                            (method == 0) ? ADAMS : BDF,
                            (itertype == 0) ? FUNCTIONAL : NEWTON,
                            (nabstol == 1) ? SS : SV,
                     	     &reltol, abstolp, NULL, NULL, TRUE, iopt, ropt, NULL);
    if (cvode_mem == NULL) {
        fatal_error("CVodeMalloc failed.\n");
    }
    /* Call CVDiag */
    CVDiag(cvode_mem);

    q = N_VNew(2 * N, NULL);
    thresh = genunf(0.0, 1.0);  /* Generate target value of norm^2 */
    if (nopers == 0)
        fwrite(&itraj, sizeof(integer), 1, op);
    if (clrecflag) {
        temp = itraj;
        fwrite(&temp, sizeof(real), 1, cp);
        temp = 0.0;
        fwrite(&temp, sizeof(real), 1, cp);
    }
    tr = Ith(tlist, 1);
    nr = norm2(N_VDATA(y) - 1, N);
    if (nopers == 0)
        fwrite(N_VDATA(y), sizeof(real), 2 * N, op);
    else
        operAccum(N_VDATA(y) - 1, N_VDATA(q) - 1, N, tr, 1);

    for (i = 2; i <= ntimes;) {
        taim = Ith(tlist, i);
        tl = tr;
        nl = nr;
        flag = CVode1(cvode_mem, taim, y, &tr, ONE_STEP);
        if (flag != SUCCESS) {
            sprintf(errmsg, "CVode failed, flag=%d.\n", flag);
            fatal_error(errmsg);
        }
        nr = norm2(N_VDATA(y) - 1, N);
        for (; i <= ntimes;) {
            if (tr < taim) {
                if (nr < thresh) {
                    tr = docollapse(tl, nl, tr, nr, thresh);  /* A collapse has
                                                               * occured */
                    nr = 1.0;
                    thresh = genunf(0.0, 1.0);  /* Generate target value of
                                                 * norm^2 */
                }
                break;
            } else {
                flag = CVode1(cvode_mem, taim, y, &t, NORMAL); /* Interpolate */
                if (flag != SUCCESS) {
                    sprintf(errmsg, "CVode failed, flag=%d.\n", flag);
                    fatal_error(errmsg);
                }
                na = norm2(N_VDATA(y) - 1, N);
                if (na < thresh) {
                    tr = docollapse(tl, nl, taim, na, thresh);  /* A collapse has
                                                                 * occured */
                    nr = 1.0;
                    thresh = genunf(0.0, 1.0);  /* Generate target value of
                                                 * norm^2 */
                    break;
                } else {        /* Write out results */
                    tl = taim;
                    nl = na;
                    if (nopers == 0)
                        fwrite(N_VDATA(y), sizeof(real), 2 * N, op);
                    else
                        operAccum(N_VDATA(y) - 1, N_VDATA(q) - 1, N, taim, i);
                    i += 1;
                    progress += NHASH;
                    while (progress >= (ntimes - 1) * ntraj) {
                        fprintf(stderr, "#");
                        progress -= (ntimes - 1) * ntraj;
                    }
                    taim = Ith(tlist, i);
                }
            }
        }
    }
    CVodeFree(cvode_mem);
}
Exemple #24
0
int main()
{
  realtype abstol, reltol, t, tout;
  N_Vector u;
  UserData data;
  void *bpdata;
  void *cvode_mem;
  int flag, ml, mu, iout, jpre;

  u = NULL;
  data = NULL;
  bpdata = 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 

     CV_BDF     specifies the Backward Differentiation Formula
     CV_NEWTON  specifies a Newton iteration

     A pointer to the integrator memory is returned and stored in cvode_mem. */
  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 = CVodeSetFdata(cvode_mem, data);
  if(check_flag(&flag, "CVodeSetFdata", 1)) return(1);

  /* Call CVodeMalloc to initialize the integrator memory: 
     f       is the user's right hand side function in u'=f(t,u)
     T0      is the initial time
     u       is the initial dependent variable vector
     CV_SS   specifies scalar relative and absolute tolerances
     reltol  is the relative tolerance
     &abstol is a  pointer to the scalar absolutetolerance      */
  flag = CVodeMalloc(cvode_mem, f, T0, u, CV_SS, reltol, &abstol);
  if(check_flag(&flag, "CVodeMalloc", 1)) return(1);

  /* Call CVBandPreAlloc to initialize band preconditioner */
  ml = mu = 2;
  bpdata = CVBandPrecAlloc (cvode_mem, NEQ, mu, ml);
  if(check_flag((void *)bpdata, "CVBandPrecAlloc", 0)) return(1);

  /* Call CVBPSpgmr to specify the linear solver CVSPGMR 
     with left preconditioning and the maximum Krylov dimension maxl */
  flag = CVBPSpgmr(cvode_mem, PREC_LEFT, 0, bpdata);
  if(check_flag(&flag, "CVBPSpgmr", 1)) 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, f, T0, u, CV_SS, reltol, &abstol);
      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, bpdata);
    
  } /* End of jpre loop */

  /* Free memory */
  N_VDestroy_Serial(u);
  free(data);
  CVBandPrecFree(&bpdata);
  CVodeFree(&cvode_mem);

  return(0);
}
int main(int argc, char *argv[])
{
  realtype abstol=ATOL, reltol=RTOL, t;
  N_Vector c;
  WebData wdata;
  void *cvode_mem;
  int flag;

  void *cvadj_mem;
  int ncheck;
  
  realtype reltolB=RTOL, abstolB=ATOL;
  N_Vector cB;

  c = NULL;
  cB = NULL;
  wdata = NULL;
  cvode_mem = NULL;
  cvadj_mem = NULL;

  /* Allocate and initialize user data */

  wdata = AllocUserData();
  if(check_flag((void *)wdata, "AllocUserData", 2)) return(1);
  InitUserData(wdata);

  /* Set-up forward problem */

  /* Initializations */
  c = N_VNew_Serial(NEQ+1);
  if(check_flag((void *)c, "N_VNew_Serial", 0)) return(1);
  CInit(c, wdata);

  /* Call CVodeCreate/CVodeMalloc for forward run */
  printf("\nCreate and allocate CVODE memory for forward run\n");
  cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON);
  if(check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1);
  wdata->cvode_memF = cvode_mem; /* Used in Precond */
  flag = CVodeSetFdata(cvode_mem, wdata);
  if(check_flag(&flag, "CVodeSetFdata", 1)) return(1);
  flag = CVodeMalloc(cvode_mem, f, T0, c, CV_SS, reltol, &abstol);
  if(check_flag(&flag, "CVodeMalloc", 1)) return(1);
  
  /* Call CVSpgmr for forward run */
  flag = CVSpgmr(cvode_mem, PREC_LEFT, 0);
  if(check_flag(&flag, "CVSpgmr", 1)) return(1);
  flag = CVSpgmrSetPreconditioner(cvode_mem, Precond, PSolve, wdata);
  if(check_flag(&flag, "CVSpgmrSetPreconditioner", 1)) return(1);

  /* Set-up adjoint calculations */

  printf("\nAllocate global memory\n");
  cvadj_mem = CVadjMalloc(cvode_mem, NSTEPS);
  if(check_flag((void *)cvadj_mem, "CVadjMalloc", 0)) return(1);
  wdata->cvadj_mem = cvadj_mem;

  /* Perform forward run */

  printf("\nForward integration ... ");
  flag = CVodeF(cvadj_mem, TOUT, c, &t, CV_NORMAL, &ncheck);
  if(check_flag(&flag, "CVodeF", 1)) return(1);
  printf("done (ncheck = %d)\n",ncheck);

#if defined(SUNDIALS_EXTENDED_PRECISION)
  printf("\n   G = int_t int_x int_y c%d(t,x,y) dx dy dt = %Lf \n\n", 
         ISPEC, NV_DATA_S(c)[NEQ]);
#else
  printf("\n   G = int_t int_x int_y c%d(t,x,y) dx dy dt = %f \n\n", 
         ISPEC, NV_DATA_S(c)[NEQ]);
#endif

  /* Set-up backward problem */

  /* Allocate cB */
  cB = N_VNew_Serial(NEQ);
  if(check_flag((void *)cB, "N_VNew_Serial", 0)) return(1);
  /* Initialize cB = 0 */
  N_VConst(ZERO, cB);

  /* Create and allocate CVODES memory for backward run */
  printf("\nCreate and allocate CVODES memory for backward run\n");
  flag = CVodeCreateB(cvadj_mem, CV_BDF, CV_NEWTON);
  if(check_flag(&flag, "CVodeCreateB", 1)) return(1);
  flag = CVodeSetFdataB(cvadj_mem, wdata);
  if(check_flag(&flag, "CVodeSetFdataB", 1)) return(1);
  flag = CVodeMallocB(cvadj_mem, fB, TOUT, cB, CV_SS, reltolB, &abstolB);
  if(check_flag(&flag, "CVodeMallocB", 1)) return(1);

  /* Call CVSpgmr */
  flag = CVSpgmrB(cvadj_mem, PREC_LEFT, 0);
  if(check_flag(&flag, "CVSpgmrB", 1)) return(1);
  flag = CVSpgmrSetPreconditionerB(cvadj_mem, PrecondB, PSolveB, wdata);
  if(check_flag(&flag, "CVSpgmrSetPreconditionerB", 1)) return(1);

  /* Perform backward integration */

  printf("\nBackward integration\n");
  flag = CVodeB(cvadj_mem, T0, cB, &t, CV_NORMAL);
  if(check_flag(&flag, "CVodeB", 1)) return(1);

  PrintOutput(cB, NS, MXNS, wdata);

  /* Free all memory */
  CVodeFree(cvode_mem);
  CVadjFree(cvadj_mem);
  N_VDestroy_Serial(c);
  N_VDestroy_Serial(cB);
  FreeUserData(wdata);

  return(0);
}