Ejemplo n.º 1
0
int SMScaleAddNew_Band(realtype c, SUNMatrix A, SUNMatrix B)
{
  sunindextype i, j, ml, mu, smu;
  realtype *A_colj, *B_colj, *C_colj;
  SUNMatrix C;

  /* create new matrix large enough to hold both A and B */
  ml  = SUNMAX(SM_LBAND_B(A),SM_LBAND_B(B));
  mu  = SUNMAX(SM_UBAND_B(A),SM_UBAND_B(B));
  smu = SUNMIN(SM_COLUMNS_B(A)-1, mu + ml);
  C = SUNBandMatrix(SM_COLUMNS_B(A), mu, ml, smu);

  /* scale/add c*A into new matrix */
  for (j=0; j<SM_COLUMNS_B(A); j++) {
    A_colj = SM_COLUMN_B(A,j);
    C_colj = SM_COLUMN_B(C,j);
    for (i=-SM_UBAND_B(A); i<=SM_LBAND_B(A); i++)
      C_colj[i] = c*A_colj[i];
  }
  
  /* add B into new matrix */
  for (j=0; j<SM_COLUMNS_B(B); j++) {
    B_colj = SM_COLUMN_B(B,j);
    C_colj = SM_COLUMN_B(C,j);
    for (i=-SM_UBAND_B(B); i<=SM_LBAND_B(B); i++)
      C_colj[i] += B_colj[i];
  }
  
  /* replace A contents with C contents, nullify C content pointer, destroy C */
  free(SM_DATA_B(A));  SM_DATA_B(A) = NULL;
  free(SM_COLS_B(A));  SM_COLS_B(A) = NULL;
  free(A->content);    A->content = NULL;
  A->content = C->content;
  C->content = NULL;
  SUNMatDestroy_Band(C);
  
  return 0;
}
Ejemplo n.º 2
0
int main(int argc, char *argv[])
{
  UserData data;

  void *cvode_mem;
  SUNMatrix A, AB;
  SUNLinearSolver LS, LSB;

  realtype dx, dy, reltol, abstol, t;
  N_Vector u;

  int indexB;

  realtype reltolB, abstolB;
  N_Vector uB;
  
  int retval, ncheck;

  data = NULL;
  cvode_mem = NULL;
  u = uB = NULL;
  LS = LSB = NULL;
  A = AB = NULL;

  /* Allocate and initialize user data memory */

  data = (UserData) malloc(sizeof *data);
  if(check_retval((void *)data, "malloc", 2)) return(1);

  dx = data->dx = XMAX/(MX+1);
  dy = data->dy = YMAX/(MY+1);
  data->hdcoef = ONE/(dx*dx);
  data->hacoef = RCONST(1.5)/(TWO*dx);
  data->vdcoef = ONE/(dy*dy);

  /* Set the tolerances for the forward integration */
  reltol = ZERO;
  abstol = ATOL;

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

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

  /* Create and allocate CVODES memory for forward run */

  printf("\nCreate and allocate CVODES memory for forward runs\n");

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

  retval = CVodeSetUserData(cvode_mem, data);
  if(check_retval(&retval, "CVodeSetUserData", 1)) return(1);

  retval = CVodeInit(cvode_mem, f, T0, u);
  if(check_retval(&retval, "CVodeInit", 1)) return(1);

  retval = CVodeSStolerances(cvode_mem, reltol, abstol);
  if(check_retval(&retval, "CVodeSStolerances", 1)) return(1);

  /* Create banded SUNMatrix for the forward problem */
  A = SUNBandMatrix(NEQ, MY, MY);
  if(check_retval((void *)A, "SUNBandMatrix", 0)) return(1);

  /* Create banded SUNLinearSolver for the forward problem */
  LS = SUNLinSol_Band(u, A);
  if(check_retval((void *)LS, "SUNLinSol_Band", 0)) return(1);

  /* Attach the matrix and linear solver */
  retval = CVodeSetLinearSolver(cvode_mem, LS, A);
  if(check_retval(&retval, "CVodeSetLinearSolver", 1)) return(1);

  /* Set the user-supplied Jacobian routine for the forward problem */
  retval = CVodeSetJacFn(cvode_mem, Jac);
  if(check_retval(&retval, "CVodeSetJacFn", 1)) return(1);

  /* Allocate global memory */

  printf("\nAllocate global memory\n");

  retval = CVodeAdjInit(cvode_mem, NSTEP, CV_HERMITE);
  if(check_retval(&retval, "CVodeAdjInit", 1)) return(1);

  /* Perform forward run */
  printf("\nForward integration\n");
  retval = CVodeF(cvode_mem, TOUT, u, &t, CV_NORMAL, &ncheck);
  if(check_retval(&retval, "CVodeF", 1)) return(1);

  printf("\nncheck = %d\n", ncheck);

  /* Set the tolerances for the backward integration */
  reltolB = RTOLB;
  abstolB = ATOL;

  /* Allocate uB */
  uB = N_VNew_Serial(NEQ);
  if(check_retval((void *)uB, "N_VNew", 0)) return(1);
  /* Initialize uB = 0 */
  N_VConst(ZERO, uB);

  /* Create and allocate CVODES memory for backward run */

  printf("\nCreate and allocate CVODES memory for backward run\n");

  retval = CVodeCreateB(cvode_mem, CV_BDF, &indexB);
  if(check_retval(&retval, "CVodeCreateB", 1)) return(1);

  retval = CVodeSetUserDataB(cvode_mem, indexB, data);
  if(check_retval(&retval, "CVodeSetUserDataB", 1)) return(1);

  retval = CVodeInitB(cvode_mem, indexB, fB, TOUT, uB);
  if(check_retval(&retval, "CVodeInitB", 1)) return(1);

  retval = CVodeSStolerancesB(cvode_mem, indexB, reltolB, abstolB);
  if(check_retval(&retval, "CVodeSStolerancesB", 1)) return(1);
 
  /* Create banded SUNMatrix for the backward problem */
  AB = SUNBandMatrix(NEQ, MY, MY);
  if(check_retval((void *)AB, "SUNBandMatrix", 0)) return(1);

  /* Create banded SUNLinearSolver for the backward problem */
  LSB = SUNLinSol_Band(uB, AB);
  if(check_retval((void *)LSB, "SUNLinSol_Band", 0)) return(1);

  /* Attach the matrix and linear solver */
  retval = CVodeSetLinearSolverB(cvode_mem, indexB, LSB, AB);
  if(check_retval(&retval, "CVodeSetLinearSolverB", 1)) return(1);

  /* Set the user-supplied Jacobian routine for the backward problem */
  retval = CVodeSetJacFnB(cvode_mem, indexB, JacB);
  if(check_retval(&retval, "CVodeSetJacFnB", 1)) return(1);

  /* Perform backward integration */
  printf("\nBackward integration\n");
  retval = CVodeB(cvode_mem, T0, CV_NORMAL);
  if(check_retval(&retval, "CVodeB", 1)) return(1);

  retval = CVodeGetB(cvode_mem, indexB, &t, uB);
  if(check_retval(&retval, "CVodeGetB", 1)) return(1);

  PrintOutput(uB, data);

  N_VDestroy(u);   /* Free the u vector                      */
  N_VDestroy(uB);  /* Free the uB vector                     */
  CVodeFree(&cvode_mem);  /* Free the CVODE problem memory          */
  SUNLinSolFree(LS);      /* Free the forward linear solver memory  */
  SUNMatDestroy(A);       /* Free the forward matrix memory         */
  SUNLinSolFree(LSB);     /* Free the backward linear solver memory */
  SUNMatDestroy(AB);      /* Free the backward matrix memory        */

  free(data);             /* Free the user data */

  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;

					/* 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);
	}
Ejemplo n.º 4
0
int main(int argc, char *argv[])
{ 
  void *ida_mem;
  SUNMatrix A;
  SUNLinearSolver LS;
  UserData webdata;
  N_Vector cc, cp, id;
  int iout, retval;
  sunindextype mu, ml;
  realtype rtol, atol, t0, tout, tret;
  int num_threads;

  ida_mem = NULL;
  A = NULL;
  LS = NULL;
  webdata = NULL;
  cc = cp = id = NULL;

  /* Set the number of threads to use */
  num_threads = 1;       /* default value */
#ifdef _OPENMP
  num_threads = omp_get_max_threads();  /* overwrite with OMP_NUM_THREADS enviroment variable */
#endif
  if (argc > 1)      /* overwrite with command line value, if supplied */
    num_threads = strtol(argv[1], NULL, 0);

  /* Allocate and initialize user data block webdata. */

  webdata = (UserData) malloc(sizeof *webdata);
  webdata->rates = N_VNew_OpenMP(NEQ, num_threads);
  webdata->acoef = newDenseMat(NUM_SPECIES, NUM_SPECIES);
  webdata->nthreads = num_threads;

  InitUserData(webdata);

  /* Allocate N-vectors and initialize cc, cp, and id. */

  cc  = N_VNew_OpenMP(NEQ, num_threads);
  if(check_retval((void *)cc, "N_VNew_OpenMP", 0)) return(1);

  cp  = N_VNew_OpenMP(NEQ, num_threads);
  if(check_retval((void *)cp, "N_VNew_OpenMP", 0)) return(1);

  id  = N_VNew_OpenMP(NEQ, num_threads);
  if(check_retval((void *)id, "N_VNew_OpenMP", 0)) return(1);
  
  SetInitialProfiles(cc, cp, id, webdata);
  
  /* Set remaining inputs to IDAMalloc. */
  
  t0 = ZERO;
  rtol = RTOL; 
  atol = ATOL;

  /* Call IDACreate and IDAMalloc to initialize IDA. */
  
  ida_mem = IDACreate();
  if(check_retval((void *)ida_mem, "IDACreate", 0)) return(1);

  retval = IDASetUserData(ida_mem, webdata);
  if(check_retval(&retval, "IDASetUserData", 1)) return(1);

  retval = IDASetId(ida_mem, id);
  if(check_retval(&retval, "IDASetId", 1)) return(1);

  retval = IDAInit(ida_mem, resweb, t0, cc, cp);
  if(check_retval(&retval, "IDAInit", 1)) return(1);

  retval = IDASStolerances(ida_mem, rtol, atol);
  if(check_retval(&retval, "IDASStolerances", 1)) return(1);

  /* Setup band matrix and linear solver, and attach to IDA. */

  mu = ml = NSMX;
  A = SUNBandMatrix(NEQ, mu, ml);
  if(check_retval((void *)A, "SUNBandMatrix", 0)) return(1);
  LS = SUNLinSol_Band(cc, A);
  if(check_retval((void *)LS, "SUNLinSol_Band", 0)) return(1);
  retval = IDASetLinearSolver(ida_mem, LS, A);
  if(check_retval(&retval, "IDASetLinearSolver", 1)) return(1);

  /* Call IDACalcIC (with default options) to correct the initial values. */

  tout = RCONST(0.001);
  retval = IDACalcIC(ida_mem, IDA_YA_YDP_INIT, tout);
  if(check_retval(&retval, "IDACalcIC", 1)) return(1);
  
  /* Print heading, basic parameters, and initial values. */

  PrintHeader(mu, ml, rtol, atol);
  PrintOutput(ida_mem, cc, ZERO);
  
  /* Loop over iout, call IDASolve (normal mode), print selected output. */
  
  for (iout = 1; iout <= NOUT; iout++) {
    
    retval = IDASolve(ida_mem, tout, &tret, cc, cp, IDA_NORMAL);
    if(check_retval(&retval, "IDASolve", 1)) return(retval);
    
    PrintOutput(ida_mem, cc, tret);
    
    if (iout < 3) tout *= TMULT; else tout += TADD;
    
  }
  
  /* Print final statistics and free memory. */  
  
  PrintFinalStats(ida_mem);
  printf("num_threads = %i\n\n", num_threads);

  /* Free memory */

  IDAFree(&ida_mem);
  SUNLinSolFree(LS);
  SUNMatDestroy(A);

  N_VDestroy_OpenMP(cc);
  N_VDestroy_OpenMP(cp);
  N_VDestroy_OpenMP(id);


  destroyMat(webdata->acoef);
  N_VDestroy_OpenMP(webdata->rates);
  free(webdata);

  return(0);
}
Ejemplo n.º 5
0
SUNMatrix SUNMatClone_Band(SUNMatrix A)
{
  SUNMatrix B = SUNBandMatrix(SM_COLUMNS_B(A), SM_UBAND_B(A),
                              SM_LBAND_B(A), SM_SUBAND_B(A));
  return(B);
}
Ejemplo n.º 6
0
/* ----------------------------------------------------------------------
 * Main SUNMatrix Testing Routine
 * --------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
  int          fails=0;                    /* counter for test failures  */
  sunindextype matrows, matcols;           /* matrix dims                */
  int          mattype;                    /* matrix storage type        */
  N_Vector     x, y, z;                    /* test vectors               */
  realtype*    vecdata;                    /* pointers to vector data    */
  SUNMatrix    A, B, C, D, I;              /* test matrices              */
  realtype*    matdata;                    /* pointer to matrix data     */
  sunindextype i, j, k, kstart, kend, N, uband, lband;
  sunindextype *colptrs, *rowindices;
  sunindextype *rowptrs, *colindices;
  int          print_timing, square;

  /* check input and set vector length */
  if (argc < 5){
    printf("ERROR: FOUR (4) Input required: matrix rows, matrix cols, matrix type (0/1), print timing \n");
    return(-1);
  }

  matrows = atol(argv[1]);
  if (matrows < 1) {
    printf("ERROR: number of rows must be a positive integer\n");
    return(-1);
  }

  matcols = atol(argv[2]);
  if (matcols < 1) {
    printf("ERROR: number of cols must be a positive integer\n");
    return(-1);
  }

  k = atol(argv[3]);
  if ((k != 0) && (k != 1)) {
    printf("ERROR: matrix type must be 0 or 1\n");
    return(-1);
  }
  mattype = (k == 0) ? CSC_MAT : CSR_MAT;

  print_timing = atoi(argv[4]);
  SetTiming(print_timing);

  square = (matrows == matcols) ? 1 : 0;
  printf("\nSparse matrix test: size %ld by %ld, type = %i\n\n",
         (long int) matrows, (long int) matcols, mattype);

  /* Initialize vectors and matrices to NULL */
  x = NULL;
  y = NULL;
  z = NULL;
  A = NULL;
  B = NULL;
  C = NULL;
  D = NULL;
  I = NULL;

  /* check creating sparse matrix from dense matrix */
  B = SUNDenseMatrix(5,6);

  matdata = SUNDenseMatrix_Data(B);
  matdata[2]  = RCONST(1.0);    /* [ 0 2 0 0 7 0 ] */
  matdata[5]  = RCONST(2.0);    /* [ 0 0 4 0 8 0 ] */
  matdata[9]  = RCONST(3.0);    /* [ 1 0 0 0 0 0 ] */
  matdata[11] = RCONST(4.0);    /* [ 0 0 5 6 0 0 ] */
  matdata[13] = RCONST(5.0);    /* [ 0 3 0 0 0 9 ] */
  matdata[18] = RCONST(6.0);
  matdata[20] = RCONST(7.0);
  matdata[21] = RCONST(8.0);
  matdata[29] = RCONST(9.0);

  if (mattype == CSR_MAT) {

    /* Check CSR */
    C = SUNSparseMatrix(5, 6, 9, CSR_MAT);
    rowptrs = SUNSparseMatrix_IndexPointers(C);
    colindices = SUNSparseMatrix_IndexValues(C);
    matdata = SUNSparseMatrix_Data(C);
    rowptrs[0] = 0;
    matdata[0] = RCONST(2.0);   colindices[0] = 1;
    matdata[1] = RCONST(7.0);   colindices[1] = 4;
    rowptrs[1] = 2;
    matdata[2] = RCONST(4.0);   colindices[2] = 2;
    matdata[3] = RCONST(8.0);   colindices[3] = 4;
    rowptrs[2] = 4;
    matdata[4] = RCONST(1.0);   colindices[4] = 0;
    rowptrs[3] = 5;
    matdata[5] = RCONST(5.0);   colindices[5] = 2;
    matdata[6] = RCONST(6.0);   colindices[6] = 3;
    rowptrs[4] = 7;
    matdata[7] = RCONST(3.0);   colindices[7] = 1;
    matdata[8] = RCONST(9.0);   colindices[8] = 5;
    rowptrs[5] = 9;

    A = SUNSparseFromDenseMatrix(B, ZERO, CSR_MAT);
    fails += check_matrix(A, C, 1e-15);

    if (fails) {
      printf("FAIL: SUNMatrix SparseFromDense CSR conversion failed\n");
      return(1);
    }

    SUNMatDestroy(A);
    SUNMatDestroy(C);

  } else {

    /* Check CSC */
    D = SUNSparseMatrix(5, 6, 9, CSC_MAT);
    colptrs = SUNSparseMatrix_IndexPointers(D);
    rowindices = SUNSparseMatrix_IndexValues(D);
    matdata = SUNSparseMatrix_Data(D);
    colptrs[0] = 0;
    matdata[0] = RCONST(1.0);   rowindices[0] = 2;
    colptrs[1] = 1;
    matdata[1] = RCONST(2.0);   rowindices[1] = 0;
    matdata[2] = RCONST(3.0);   rowindices[2] = 4;
    colptrs[2] = 3;
    matdata[3] = RCONST(4.0);   rowindices[3] = 1;
    matdata[4] = RCONST(5.0);   rowindices[4] = 3;
    colptrs[3] = 5;
    matdata[5] = RCONST(6.0);   rowindices[5] = 3;
    colptrs[4] = 6;
    matdata[6] = RCONST(7.0);   rowindices[6] = 0;
    matdata[7] = RCONST(8.0);   rowindices[7] = 1;
    colptrs[5] = 8;
    matdata[8] = RCONST(9.0);   rowindices[8] = 4;
    colptrs[6] = 9;

    A = SUNSparseFromDenseMatrix(B, 1e-15, CSC_MAT);
    fails += check_matrix(A, D, 1e-15);

    if (fails) {
      printf("FAIL: SUNMatrix SparseFromDense CSC conversion failed\n");
      return(1);
    }

    SUNMatDestroy(A);
    SUNMatDestroy(D);

  }
  SUNMatDestroy(B);


  /* check creating sparse matrix from banded matrix */
  N = 7;
  uband = 1;
  lband = 2;                                   /* B(i,j) = j + (j-i) */
  B = SUNBandMatrix(N, uband, lband);          /* B = [  0  2  0  0  0  0  0 ] */
  for (j=0; j<N; j++) {                        /*     [ -1  1  3  0  0  0  0 ] */
    matdata = SUNBandMatrix_Column(B, j);      /*     [ -2  0  2  4  0  0  0 ] */
    kstart = (j<uband) ? -j : -uband;          /*     [  0 -1  1  3  5  0  0 ] */
    kend = (j>N-1-lband) ? N-1-j: lband;       /*     [  0  0  0  2  4  6  0 ] */
    for (k=kstart; k<=kend; k++)               /*     [  0  0  0  1  3  5  7 ] */
      matdata[k] = j - k;                      /*     [  0  0  0  0  2  4  6 ] */
  }

  if (mattype == CSR_MAT) {

    /* CSR */
    C = SUNSparseMatrix(7, 7, 21, CSR_MAT);
    rowptrs = SUNSparseMatrix_IndexPointers(C);
    colindices = SUNSparseMatrix_IndexValues(C);
    matdata = SUNSparseMatrix_Data(C);
    rowptrs[ 0] = 0;
    matdata[ 0] = RCONST(2.0);   colindices[ 0] = 1;
    rowptrs[ 1] = 1;
    matdata[ 1] = RCONST(-1.0);  colindices[ 1] = 0;
    matdata[ 2] = RCONST(1.0);   colindices[ 2] = 1;
    matdata[ 3] = RCONST(3.0);   colindices[ 3] = 2;
    rowptrs[ 2] = 4;
    matdata[ 4] = RCONST(-2.0);  colindices[ 4] = 0;
    matdata[ 5] = RCONST(2.0);   colindices[ 5] = 2;
    matdata[ 6] = RCONST(4.0);   colindices[ 6] = 3;
    rowptrs[ 3] = 7;
    matdata[ 7] = RCONST(-1.0);  colindices[ 7] = 1;
    matdata[ 8] = RCONST(1.0);   colindices[ 8] = 2;
    matdata[ 9] = RCONST(3.0);   colindices[ 9] = 3;
    matdata[10] = RCONST(5.0);   colindices[10] = 4;
    rowptrs[ 4] = 11;
    matdata[11] = RCONST(2.0);   colindices[11] = 3;
    matdata[12] = RCONST(4.0);   colindices[12] = 4;
    matdata[13] = RCONST(6.0);   colindices[13] = 5;
    rowptrs[ 5] = 14;
    matdata[14] = RCONST(1.0);   colindices[14] = 3;
    matdata[15] = RCONST(3.0);   colindices[15] = 4;
    matdata[16] = RCONST(5.0);   colindices[16] = 5;
    matdata[17] = RCONST(7.0);   colindices[17] = 6;
    rowptrs[ 6] = 18;
    matdata[18] = RCONST(2.0);   colindices[18] = 4;
    matdata[19] = RCONST(4.0);   colindices[19] = 5;
    matdata[20] = RCONST(6.0);   colindices[20] = 6;
    rowptrs[ 7] = 21;

    A = SUNSparseFromBandMatrix(B, ZERO, CSR_MAT);
    fails += check_matrix(A, C, 1e-15);

    if (fails) {
      printf("FAIL: SUNMatrix SparseFromBand CSR conversion failed\n");
      return(1);
    }

    SUNMatDestroy(A);
    SUNMatDestroy(C);

  } else {

    /* Check CSC */
    D = SUNSparseMatrix(7, 7, 21, CSC_MAT);
    colptrs = SUNSparseMatrix_IndexPointers(D);
    rowindices = SUNSparseMatrix_IndexValues(D);
    matdata = SUNSparseMatrix_Data(D);
    colptrs[ 0] = 0;
    matdata[ 0] = RCONST(-1.0);  rowindices[ 0] = 1;
    matdata[ 1] = RCONST(-2.0);  rowindices[ 1] = 2;
    colptrs[ 1] = 2;
    matdata[ 2] = RCONST(2.0);   rowindices[ 2] = 0;
    matdata[ 3] = RCONST(1.0);   rowindices[ 3] = 1;
    matdata[ 4] = RCONST(-1.0);  rowindices[ 4] = 3;
    colptrs[ 2] = 5;
    matdata[ 5] = RCONST(3.0);   rowindices[ 5] = 1;
    matdata[ 6] = RCONST(2.0);   rowindices[ 6] = 2;
    matdata[ 7] = RCONST(1.0);   rowindices[ 7] = 3;
    colptrs[ 3] = 8;
    matdata[ 8] = RCONST(4.0);   rowindices[ 8] = 2;
    matdata[ 9] = RCONST(3.0);   rowindices[ 9] = 3;
    matdata[10] = RCONST(2.0);   rowindices[10] = 4;
    matdata[11] = RCONST(1.0);   rowindices[11] = 5;
    colptrs[ 4] = 12;
    matdata[12] = RCONST(5.0);   rowindices[12] = 3;
    matdata[13] = RCONST(4.0);   rowindices[13] = 4;
    matdata[14] = RCONST(3.0);   rowindices[14] = 5;
    matdata[15] = RCONST(2.0);   rowindices[15] = 6;
    colptrs[ 5] = 16;
    matdata[16] = RCONST(6.0);   rowindices[16] = 4;
    matdata[17] = RCONST(5.0);   rowindices[17] = 5;
    matdata[18] = RCONST(4.0);   rowindices[18] = 6;
    colptrs[ 6] = 19;
    matdata[19] = RCONST(7.0);   rowindices[19] = 5;
    matdata[20] = RCONST(6.0);   rowindices[20] = 6;
    colptrs[ 7] = 21;

    A = SUNSparseFromBandMatrix(B, 1e-15, CSC_MAT);
    fails += check_matrix(A, D, 1e-15);

    if (fails) {
      printf("FAIL: SUNMatrix SparseFromBand CSC conversion failed\n");
      return(1);
    }

    SUNMatDestroy(A);
    SUNMatDestroy(D);
  }

  SUNMatDestroy(B);


  /* Create/fill I matrix */
  I = NULL;
  if (square) {
    I = SUNSparseMatrix(matrows, matcols, matcols, mattype);
    matdata    = SUNSparseMatrix_Data(I);
    colindices = SUNSparseMatrix_IndexValues(I);
    rowptrs    = SUNSparseMatrix_IndexPointers(I);
    for(i=0; i<matrows; i++) {
      matdata[i] = ONE;
      colindices[i] = i;
      rowptrs[i] = i;
    }
    rowptrs[matrows] = matrows;
  }

  /* Create/fill random dense matrices, create sparse from them */
  C = SUNDenseMatrix(matrows, matcols);
  D = SUNDenseMatrix(matrows, matcols);
  for (k=0; k<3*matrows; k++) {
    i = rand() % matrows;
    j = rand() % matcols;
    matdata = SUNDenseMatrix_Column(D,j);
    matdata[i] = (realtype) rand() / (realtype) RAND_MAX;
  }
  for (k=0; k<matrows; k++) {
    i = rand() % matrows;
    j = rand() % matcols;
    matdata = SUNDenseMatrix_Column(C,j);
    matdata[i] = (realtype) rand() / (realtype) RAND_MAX;
  }
  A = SUNSparseFromDenseMatrix(C, ZERO, mattype);
  B = SUNSparseFromDenseMatrix(D, ZERO, mattype);

  /* Create vectors and fill */
  x = N_VNew_Serial(matcols);
  y = N_VNew_Serial(matrows);
  z = N_VNew_Serial(matrows);
  vecdata = N_VGetArrayPointer(x);
  for(i=0; i<matcols; i++)
    vecdata[i] = (realtype) rand() / (realtype) RAND_MAX;
  if (SUNMatMatvec(C, x, y) != 0) {
    printf("FAIL: SUNMatrix module Dense matvec failure \n \n");
    SUNMatDestroy(A);  SUNMatDestroy(B);
    SUNMatDestroy(C);  SUNMatDestroy(D);
    N_VDestroy(x);  N_VDestroy(y);  N_VDestroy(z);
    if (square)
      SUNMatDestroy(I);
    return(1);
  }
  if (SUNMatMatvec(D, x, z) != 0) {
    printf("FAIL: SUNMatrix module Dense matvec failure \n \n");
    SUNMatDestroy(A);  SUNMatDestroy(B);
    SUNMatDestroy(C);  SUNMatDestroy(D);
    N_VDestroy(x);  N_VDestroy(y);  N_VDestroy(z);
    if (square)
      SUNMatDestroy(I);
    return(1);
  }

  /* SUNMatrix Tests */
  fails += Test_SUNMatGetID(A, SUNMATRIX_SPARSE, 0);
  fails += Test_SUNMatClone(A, 0);
  fails += Test_SUNMatCopy(A, 0);
  fails += Test_SUNMatZero(A, 0);
  fails += Test_SUNMatScaleAdd(A, I, 0);
  fails += Test_SUNMatScaleAdd2(A, B, x, y, z);
  if (square) {
    fails += Test_SUNMatScaleAddI(A, I, 0);
    fails += Test_SUNMatScaleAddI2(A, x, y);
  }
  fails += Test_SUNMatMatvec(A, x, y, 0);
  fails += Test_SUNMatSpace(A, 0);

  /* Print result */
  if (fails) {
    printf("FAIL: SUNMatrix module failed %i tests \n \n", fails);
    printf("\nA =\n");
    SUNSparseMatrix_Print(A,stdout);
    printf("\nB =\n");
    SUNSparseMatrix_Print(B,stdout);
    if (square) {
      printf("\nI =\n");
      SUNSparseMatrix_Print(I,stdout);
    }
    printf("\nx =\n");
    N_VPrint_Serial(x);
    printf("\ny =\n");
    N_VPrint_Serial(y);
    printf("\nz =\n");
    N_VPrint_Serial(z);
  } else {
    printf("SUCCESS: SUNMatrix module passed all tests \n \n");
  }

  /* Free vectors and matrices */
  N_VDestroy(x);
  N_VDestroy(y);
  N_VDestroy(z);
  SUNMatDestroy(A);
  SUNMatDestroy(B);
  SUNMatDestroy(C);
  SUNMatDestroy(D);
  if (square)
    SUNMatDestroy(I);

  return(fails);
}