예제 #1
0
void FSUNDENSEMAT_INIT(int *code, long int *M, long int *N, int *ier)
{
  *ier = 0;

  switch(*code) {
  case FCMIX_CVODE:
  if (F2C_CVODE_matrix)  SUNMatDestroy(F2C_CVODE_matrix);
    F2C_CVODE_matrix = NULL;
    F2C_CVODE_matrix = SUNDenseMatrix(*M, *N);
    if (F2C_CVODE_matrix == NULL) *ier = -1;
    break;
  case FCMIX_IDA:
  if (F2C_IDA_matrix)  SUNMatDestroy(F2C_IDA_matrix);
    F2C_IDA_matrix = NULL;
    F2C_IDA_matrix = SUNDenseMatrix(*M, *N);
    if (F2C_IDA_matrix == NULL) *ier = -1;
    break;
  case FCMIX_KINSOL:
  if (F2C_KINSOL_matrix)  SUNMatDestroy(F2C_KINSOL_matrix);
    F2C_KINSOL_matrix = NULL;
    F2C_KINSOL_matrix = SUNDenseMatrix(*M, *N);
    if (F2C_KINSOL_matrix == NULL) *ier = -1;
    break;
  case FCMIX_ARKODE:
  if (F2C_ARKODE_matrix)  SUNMatDestroy(F2C_ARKODE_matrix);
    F2C_ARKODE_matrix = NULL;
    F2C_ARKODE_matrix = SUNDenseMatrix(*M, *N);
    if (F2C_ARKODE_matrix == NULL) *ier = -1;
    break;
  default:
    *ier = -1;
  }
}
예제 #2
0
void FSUNDENSEMASSMAT_INIT(long int *M, long int *N, int *ier)
{
  *ier = 0;
  if (F2C_ARKODE_mass_matrix)  SUNMatDestroy(F2C_ARKODE_mass_matrix);
  F2C_ARKODE_mass_matrix = NULL;
  F2C_ARKODE_mass_matrix = SUNDenseMatrix(*M, *N);
  if (F2C_ARKODE_mass_matrix == NULL) *ier = -1;
}
int main(int argc, char *argv[])
{
  UserData data;

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

  realtype reltolQ, abstolQ;
  N_Vector y, q, constraints;

  int steps;

  int indexB;

  realtype reltolB, abstolB, abstolQB;
  N_Vector yB, qB, constraintsB;

  realtype time;
  int retval, ncheck;

  long int nst, nstB;

  CVadjCheckPointRec *ckpnt;

  data = NULL;
  A = AB = NULL;
  LS = LSB = NULL;
  cvode_mem = NULL;
  ckpnt = NULL;
  y = yB = qB = NULL;
  constraints = NULL;
  constraintsB = NULL;

  /* Print problem description */
  printf("\nAdjoint Sensitivity Example for Chemical Kinetics\n");
  printf("-------------------------------------------------\n\n");
  printf("ODE: dy1/dt = -p1*y1 + p2*y2*y3\n");
  printf("     dy2/dt =  p1*y1 - p2*y2*y3 - p3*(y2)^2\n");
  printf("     dy3/dt =  p3*(y2)^2\n\n");
  printf("Find dG/dp for\n");
  printf("     G = int_t0^tB0 g(t,p,y) dt\n");
  printf("     g(t,p,y) = y3\n\n\n");

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

  /* Initialize y */
  y = N_VNew_Serial(NEQ);
  if (check_retval((void *)y, "N_VNew_Serial", 0)) return(1);
  Ith(y,1) = RCONST(1.0);
  Ith(y,2) = ZERO;
  Ith(y,3) = ZERO;

  /* Set constraints to all 1's for nonnegative solution values. */
  constraints = N_VNew_Serial(NEQ);
  if(check_retval((void *)constraints, "N_VNew_Serial", 0)) return(1);
  N_VConst(ONE, constraints);

  /* Initialize q */
  q = N_VNew_Serial(1);
  if (check_retval((void *)q, "N_VNew_Serial", 0)) return(1);
  Ith(q,1) = ZERO;

  /* Set the scalar realtive and absolute tolerances reltolQ and abstolQ */
  reltolQ = RTOL;
  abstolQ = ATOLq;

  /* Create and allocate CVODES memory for forward run */
  printf("Create and allocate CVODES memory for forward runs\n");

  /* Call CVodeCreate to create the solver memory and specify the 
     Backward Differentiation Formula */
  cvode_mem = CVodeCreate(CV_BDF);
  if (check_retval((void *)cvode_mem, "CVodeCreate", 0)) return(1);

  /* Call CVodeInit to initialize the integrator memory and specify the
     user's right hand side function in y'=f(t,y), the initial time T0, and
     the initial dependent variable vector y. */
  retval = CVodeInit(cvode_mem, f, T0, y);
  if (check_retval(&retval, "CVodeInit", 1)) return(1);

  /* Call CVodeWFtolerances to specify a user-supplied function ewt that sets
     the multiplicative error weights w_i for use in the weighted RMS norm */
  retval = CVodeWFtolerances(cvode_mem, ewt);
  if (check_retval(&retval, "CVodeWFtolerances", 1)) return(1);

  /* Attach user data */
  retval = CVodeSetUserData(cvode_mem, data);
  if (check_retval(&retval, "CVodeSetUserData", 1)) return(1);

  /* Call CVodeSetConstraints to initialize constraints */
  retval = CVodeSetConstraints(cvode_mem, constraints);
  if (check_retval(&retval, "CVODESetConstraints", 1)) return(1);
  N_VDestroy(constraints);

  /* Create dense SUNMatrix for use in linear solves */
  A = SUNDenseMatrix(NEQ, NEQ);
  if (check_retval((void *)A, "SUNDenseMatrix", 0)) return(1);

  /* Create dense SUNLinearSolver object */
  LS = SUNLinSol_Dense(y, A);
  if (check_retval((void *)LS, "SUNLinSol_Dense", 0)) return(1);

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

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

  /* Call CVodeQuadInit to allocate initernal memory and initialize
     quadrature integration*/
  retval = CVodeQuadInit(cvode_mem, fQ, q);
  if (check_retval(&retval, "CVodeQuadInit", 1)) return(1);

  /* Call CVodeSetQuadErrCon to specify whether or not the quadrature variables
     are to be used in the step size control mechanism within CVODES. Call
     CVodeQuadSStolerances or CVodeQuadSVtolerances to specify the integration
     tolerances for the quadrature variables. */
  retval = CVodeSetQuadErrCon(cvode_mem, SUNTRUE);
  if (check_retval(&retval, "CVodeSetQuadErrCon", 1)) return(1);

  /* Call CVodeQuadSStolerances to specify scalar relative and absolute
     tolerances. */
  retval = CVodeQuadSStolerances(cvode_mem, reltolQ, abstolQ);
  if (check_retval(&retval, "CVodeQuadSStolerances", 1)) return(1);

  /* Allocate global memory */

  /* Call CVodeAdjInit to update CVODES memory block by allocting the internal 
     memory needed for backward integration.*/
  steps = STEPS; /* no. of integration steps between two consecutive ckeckpoints*/
  retval = CVodeAdjInit(cvode_mem, steps, CV_HERMITE);
  /*
  retval = CVodeAdjInit(cvode_mem, steps, CV_POLYNOMIAL);
  */
  if (check_retval(&retval, "CVodeAdjInit", 1)) return(1);

  /* Perform forward run */
  printf("Forward integration ... ");

  /* Call CVodeF to integrate the forward problem over an interval in time and
     saves checkpointing data */
  retval = CVodeF(cvode_mem, TOUT, y, &time, CV_NORMAL, &ncheck);
  if (check_retval(&retval, "CVodeF", 1)) return(1);
  retval = CVodeGetNumSteps(cvode_mem, &nst);
  if (check_retval(&retval, "CVodeGetNumSteps", 1)) return(1);

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

  retval = CVodeGetQuad(cvode_mem, &time, q);
  if (check_retval(&retval, "CVodeGetQuad", 1)) return(1);

  printf("--------------------------------------------------------\n");
#if defined(SUNDIALS_EXTENDED_PRECISION)
  printf("G:          %12.4Le \n",Ith(q,1));
#elif defined(SUNDIALS_DOUBLE_PRECISION)
  printf("G:          %12.4e \n",Ith(q,1));
#else
  printf("G:          %12.4e \n",Ith(q,1));
#endif
  printf("--------------------------------------------------------\n\n");

  /* Test check point linked list 
     (uncomment next block to print check point information) */
  
  /*
  {
    int i;
    
    printf("\nList of Check Points (ncheck = %d)\n\n", ncheck);
    ckpnt = (CVadjCheckPointRec *) malloc ( (ncheck+1)*sizeof(CVadjCheckPointRec));
    CVodeGetAdjCheckPointsInfo(cvode_mem, ckpnt);
    for (i=0;i<=ncheck;i++) {
      printf("Address:       %p\n",ckpnt[i].my_addr);
      printf("Next:          %p\n",ckpnt[i].next_addr);
      printf("Time interval: %le  %le\n",ckpnt[i].t0, ckpnt[i].t1);
      printf("Step number:   %ld\n",ckpnt[i].nstep);
      printf("Order:         %d\n",ckpnt[i].order);
      printf("Step size:     %le\n",ckpnt[i].step);
      printf("\n");
    }
    
  }
  */
  
  /* Initialize yB */
  yB = N_VNew_Serial(NEQ);
  if (check_retval((void *)yB, "N_VNew_Serial", 0)) return(1);
  Ith(yB,1) = ZERO;
  Ith(yB,2) = ZERO;
  Ith(yB,3) = ZERO;

  /* Initialize qB */
  qB = N_VNew_Serial(NP);
  if (check_retval((void *)qB, "N_VNew", 0)) return(1);
  Ith(qB,1) = ZERO;
  Ith(qB,2) = ZERO;
  Ith(qB,3) = ZERO;

  /* Set the scalar relative tolerance reltolB */
  reltolB = RTOL;               

  /* Set the scalar absolute tolerance abstolB */
  abstolB = ATOLl;

  /* Set the scalar absolute tolerance abstolQB */
  abstolQB = ATOLq;

  /* Set constraints to all 1's for nonnegative solution values. */
  constraintsB = N_VNew_Serial(NEQ);
  if(check_retval((void *)constraintsB, "N_VNew_Serial", 0)) return(1);
  N_VConst(ONE, constraintsB);

  /* Create and allocate CVODES memory for backward run */
  printf("Create and allocate CVODES memory for backward run\n");

  /* Call CVodeCreateB to specify the solution method for the backward 
     problem. */
  retval = CVodeCreateB(cvode_mem, CV_BDF, &indexB);
  if (check_retval(&retval, "CVodeCreateB", 1)) return(1);

  /* Call CVodeInitB to allocate internal memory and initialize the 
     backward problem. */
  retval = CVodeInitB(cvode_mem, indexB, fB, TB1, yB);
  if (check_retval(&retval, "CVodeInitB", 1)) return(1);

  /* Set the scalar relative and absolute tolerances. */
  retval = CVodeSStolerancesB(cvode_mem, indexB, reltolB, abstolB);
  if (check_retval(&retval, "CVodeSStolerancesB", 1)) return(1);

  /* Attach the user data for backward problem. */
  retval = CVodeSetUserDataB(cvode_mem, indexB, data);
  if (check_retval(&retval, "CVodeSetUserDataB", 1)) return(1);

  /* Call CVodeSetConstraintsB to initialize constraints */
  retval = CVodeSetConstraintsB(cvode_mem, indexB, constraintsB);
  if(check_retval(&retval, "CVodeSetConstraintsB", 1)) return(1);
  N_VDestroy(constraintsB);

  /* Create dense SUNMatrix for use in linear solves */
  AB = SUNDenseMatrix(NEQ, NEQ);
  if (check_retval((void *)AB, "SUNDenseMatrix", 0)) return(1);

  /* Create dense SUNLinearSolver object */
  LSB = SUNLinSol_Dense(yB, AB);
  if (check_retval((void *)LSB, "SUNLinSol_Dense", 0)) return(1);

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

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

  /* Call CVodeQuadInitB to allocate internal memory and initialize backward
     quadrature integration. */
  retval = CVodeQuadInitB(cvode_mem, indexB, fQB, qB);
  if (check_retval(&retval, "CVodeQuadInitB", 1)) return(1);

  /* Call CVodeSetQuadErrCon to specify whether or not the quadrature variables
     are to be used in the step size control mechanism within CVODES. Call
     CVodeQuadSStolerances or CVodeQuadSVtolerances to specify the integration
     tolerances for the quadrature variables. */
  retval = CVodeSetQuadErrConB(cvode_mem, indexB, SUNTRUE);
  if (check_retval(&retval, "CVodeSetQuadErrConB", 1)) return(1);

  /* Call CVodeQuadSStolerancesB to specify the scalar relative and absolute tolerances
     for the backward problem. */
  retval = CVodeQuadSStolerancesB(cvode_mem, indexB, reltolB, abstolQB);
  if (check_retval(&retval, "CVodeQuadSStolerancesB", 1)) return(1);

  /* Backward Integration */

  PrintHead(TB1);

  /* First get results at t = TBout1 */

  /* Call CVodeB to integrate the backward ODE problem. */
  retval = CVodeB(cvode_mem, TBout1, CV_NORMAL);
  if (check_retval(&retval, "CVodeB", 1)) return(1);

  /* Call CVodeGetB to get yB of the backward ODE problem. */
  retval = CVodeGetB(cvode_mem, indexB, &time, yB);
  if (check_retval(&retval, "CVodeGetB", 1)) return(1);

  /* Call CVodeGetAdjY to get the interpolated value of the forward solution
     y during a backward integration. */
  retval = CVodeGetAdjY(cvode_mem, TBout1, y);
  if (check_retval(&retval, "CVodeGetAdjY", 1)) return(1);

  PrintOutput1(time, TBout1, y, yB);

  /* Then at t = T0 */

  retval = CVodeB(cvode_mem, T0, CV_NORMAL);
  if (check_retval(&retval, "CVodeB", 1)) return(1);
  CVodeGetNumSteps(CVodeGetAdjCVodeBmem(cvode_mem, indexB), &nstB);
  printf("Done ( nst = %ld )\n", nstB);

  retval = CVodeGetB(cvode_mem, indexB, &time, yB);
  if (check_retval(&retval, "CVodeGetB", 1)) return(1);

  /* Call CVodeGetQuadB to get the quadrature solution vector after a 
     successful return from CVodeB. */
  retval = CVodeGetQuadB(cvode_mem, indexB, &time, qB);
  if (check_retval(&retval, "CVodeGetQuadB", 1)) return(1);

  retval = CVodeGetAdjY(cvode_mem, T0, y);
  if (check_retval(&retval, "CVodeGetAdjY", 1)) return(1);

  PrintOutput(time, y, yB, qB);

  /* Reinitialize backward phase (new tB0) */

  Ith(yB,1) = ZERO;
  Ith(yB,2) = ZERO;
  Ith(yB,3) = ZERO;

  Ith(qB,1) = ZERO;
  Ith(qB,2) = ZERO;
  Ith(qB,3) = ZERO;

  printf("Re-initialize CVODES memory for backward run\n");

  retval = CVodeReInitB(cvode_mem, indexB, TB2, yB);
  if (check_retval(&retval, "CVodeReInitB", 1)) return(1);

  retval = CVodeQuadReInitB(cvode_mem, indexB, qB); 
  if (check_retval(&retval, "CVodeQuadReInitB", 1)) return(1);

  PrintHead(TB2);

  /* First get results at t = TBout1 */

  retval = CVodeB(cvode_mem, TBout1, CV_NORMAL);
  if (check_retval(&retval, "CVodeB", 1)) return(1);

  retval = CVodeGetB(cvode_mem, indexB, &time, yB);
  if (check_retval(&retval, "CVodeGetB", 1)) return(1);

  retval = CVodeGetAdjY(cvode_mem, TBout1, y);
  if (check_retval(&retval, "CVodeGetAdjY", 1)) return(1);

  PrintOutput1(time, TBout1, y, yB);

  /* Then at t = T0 */

  retval = CVodeB(cvode_mem, T0, CV_NORMAL);
  if (check_retval(&retval, "CVodeB", 1)) return(1);
  CVodeGetNumSteps(CVodeGetAdjCVodeBmem(cvode_mem, indexB), &nstB);
  printf("Done ( nst = %ld )\n", nstB);

  retval = CVodeGetB(cvode_mem, indexB, &time, yB);
  if (check_retval(&retval, "CVodeGetB", 1)) return(1);

  retval = CVodeGetQuadB(cvode_mem, indexB, &time, qB);
  if (check_retval(&retval, "CVodeGetQuadB", 1)) return(1);

  retval = CVodeGetAdjY(cvode_mem, T0, y);
  if (check_retval(&retval, "CVodeGetAdjY", 1)) return(1);

  PrintOutput(time, y, yB, qB);

  /* Free memory */
  printf("Free memory\n\n");

  CVodeFree(&cvode_mem);
  N_VDestroy(y); 
  N_VDestroy(q);
  N_VDestroy(yB);
  N_VDestroy(qB);
  SUNLinSolFree(LS);
  SUNMatDestroy(A);
  SUNLinSolFree(LSB);
  SUNMatDestroy(AB);

  if (ckpnt != NULL) free(ckpnt);
  free(data);

  return(0);

}
예제 #4
0
int main()
{
  realtype fnormtol, scsteptol;
  N_Vector y, scale, constraints;
  int mset, flag, i;
  void *kmem;
  SUNMatrix J;
  SUNLinearSolver LS;

  y = scale = constraints = NULL;
  kmem = NULL;
  J = NULL;
  LS = NULL;

  printf("\nRobot Kinematics Example\n");
  printf("8 variables; -1 <= x_i <= 1\n");
  printf("KINSOL problem size: 8 + 2*8 = 24 \n\n");

  /* Create vectors for solution, scales, and constraints */

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

  scale = N_VNew_Serial(NEQ);
  if (check_flag((void *)scale, "N_VNew_Serial", 0)) return(1);

  constraints = N_VNew_Serial(NEQ);
  if (check_flag((void *)constraints, "N_VNew_Serial", 0)) return(1);

  /* Initialize and allocate memory for KINSOL */

  kmem = KINCreate();
  if (check_flag((void *)kmem, "KINCreate", 0)) return(1);

  flag = KINInit(kmem, func, y); /* y passed as a template */
  if (check_flag(&flag, "KINInit", 1)) return(1);

  /* Set optional inputs */

  N_VConst_Serial(ZERO,constraints);
  for (i = NVAR+1; i <= NEQ; i++) Ith(constraints, i) = ONE;
  
  flag = KINSetConstraints(kmem, constraints);
  if (check_flag(&flag, "KINSetConstraints", 1)) return(1);

  fnormtol  = FTOL; 
  flag = KINSetFuncNormTol(kmem, fnormtol);
  if (check_flag(&flag, "KINSetFuncNormTol", 1)) return(1);

  scsteptol = STOL;
  flag = KINSetScaledStepTol(kmem, scsteptol);
  if (check_flag(&flag, "KINSetScaledStepTol", 1)) return(1);

  /* Create dense SUNMatrix */
  J = SUNDenseMatrix(NEQ, NEQ);
  if(check_flag((void *)J, "SUNDenseMatrix", 0)) return(1);

  /* Create dense SUNLinearSolver object */
  LS = SUNLinSol_Dense(y, J);
  if(check_flag((void *)LS, "SUNLinSol_Dense", 0)) return(1);

  /* Attach the matrix and linear solver to KINSOL */
  flag = KINSetLinearSolver(kmem, LS, J);
  if(check_flag(&flag, "KINSetLinearSolver", 1)) return(1);

  /* Set the Jacobian function */
  flag = KINSetJacFn(kmem, jac);
  if (check_flag(&flag, "KINSetJacFn", 1)) return(1);

  /* Indicate exact Newton */

  mset = 1;
  flag = KINSetMaxSetupCalls(kmem, mset);
  if (check_flag(&flag, "KINSetMaxSetupCalls", 1)) return(1);

  /* Initial guess */

  N_VConst_Serial(ONE, y);
  for(i = 1; i <= NVAR; i++) Ith(y,i) = SUNRsqrt(TWO)/TWO;

  printf("Initial guess:\n");
  PrintOutput(y);

  /* Call KINSol to solve problem */

  N_VConst_Serial(ONE,scale);
  flag = KINSol(kmem,           /* KINSol memory block */
                y,              /* initial guess on input; solution vector */
                KIN_LINESEARCH, /* global strategy choice */
                scale,          /* scaling vector, for the variable cc */
                scale);         /* scaling vector for function values fval */
  if (check_flag(&flag, "KINSol", 1)) return(1);

  printf("\nComputed solution:\n");
  PrintOutput(y);

  /* Print final statistics and free memory */  

  PrintFinalStats(kmem);

  N_VDestroy_Serial(y);
  N_VDestroy_Serial(scale);
  N_VDestroy_Serial(constraints);
  KINFree(&kmem);
  SUNLinSolFree(LS);
  SUNMatDestroy(J);

  return(0);
}
예제 #5
0
/* ----------------------------------------------------------------------
 * Main SUNMatrix Testing Routine
 * --------------------------------------------------------------------*/
int main(int argc, char *argv[]) 
{
  int          fails = 0;        /* counter for test failures  */
  sunindextype matrows, matcols; /* vector length              */
  N_Vector     x, y;             /* test vectors               */
  realtype     *xdata, *ydata;   /* pointers to vector data    */
  SUNMatrix    A, I;             /* test matrices              */
  realtype     *Adata, *Idata;   /* pointers to matrix data    */
  int          print_timing, square;
  sunindextype i, j, m, n;

  /* check input and set vector length */
  if (argc < 4){
    printf("ERROR: THREE (3) Input required: matrix rows, matrix cols, print timing \n");
    return(-1);
  }
  
  matrows = atol(argv[1]); 
  if (matrows <= 0) {
    printf("ERROR: number of rows must be a positive integer \n");
    return(-1); 
  }
  
  matcols = atol(argv[2]); 
  if (matcols <= 0) {
    printf("ERROR: number of cols must be a positive integer \n");
    return(-1); 
  }

  print_timing = atoi(argv[3]);
  SetTiming(print_timing);
  
  square = (matrows == matcols) ? 1 : 0;
  printf("\nDense matrix test: size %ld by %ld\n\n",
         (long int) matrows, (long int) matcols);

  /* Initialize vectors and matrices to NULL */
  x = NULL;
  y = NULL;
  A = NULL;
  I = NULL;
  
  /* Create vectors and matrices */
  x = N_VNew_Serial(matcols);
  y = N_VNew_Serial(matrows);
  A = SUNDenseMatrix(matrows, matcols);
  I = NULL;
  if (square)
    I = SUNDenseMatrix(matrows, matcols);
  
  /* Fill matrices and vectors */
  Adata = SUNDenseMatrix_Data(A);
  for(j=0; j < matcols; j++) {
    for(i=0; i < matrows; i++) {
      Adata[j*matrows + i] = (j+1)*(i+j);
    }
  }

  if (square) {
    Idata = SUNDenseMatrix_Data(I);
    for(i=0, j=0; i < matrows; i++, j++) {
      Idata[j*matrows + i] = ONE;
    }
  }

  xdata = N_VGetArrayPointer(x);
  for(i=0; i < matcols; i++) {
    xdata[i] = ONE / (i+1);
  }

  ydata = N_VGetArrayPointer(y);
  for(i=0; i < matrows; i++) {
    m = i;
    n = m + matcols - 1;
    ydata[i] = HALF*(n+1-m)*(n+m);
  }
    
  /* SUNMatrix Tests */
  fails += Test_SUNMatGetID(A, SUNMATRIX_DENSE, 0);
  fails += Test_SUNMatClone(A, 0);
  fails += Test_SUNMatCopy(A, 0);
  fails += Test_SUNMatZero(A, 0);
  if (square) {
    fails += Test_SUNMatScaleAdd(A, I, 0);
    fails += Test_SUNMatScaleAddI(A, I, 0);
  }
  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");
    SUNDenseMatrix_Print(A,stdout);
    if (square) {
      printf("\nI =\n");
      SUNDenseMatrix_Print(I,stdout);
    }
    printf("\nx =\n");
    N_VPrint_Serial(x);
    printf("\ny =\n");
    N_VPrint_Serial(y);
  } else {
    printf("SUCCESS: SUNMatrix module passed all tests \n \n");
  }

  /* Free vectors and matrices */
  N_VDestroy_Serial(x);
  N_VDestroy_Serial(y);
  SUNMatDestroy(A);
  if (square)
    SUNMatDestroy(I);

  return(fails);
}
int main(int argc, char *argv[])
{
  SUNMatrix A;
  SUNLinearSolver LS;
  void *cvode_mem;
  UserData data;
  realtype t, tout;
  N_Vector y, constraints;
  int iout, retval;

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

  cvode_mem   = NULL;
  data        = NULL;
  y           = NULL;
  yS          = NULL;
  A           = NULL;
  LS          = NULL;
  constraints = NULL;

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

  /* User data structure */
  data = (UserData) malloc(sizeof *data);
  if (check_retval((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_retval((void *)y, "N_VNew_Serial", 0)) return(1);

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

  /* Set constraints to all 1's for nonnegative solution values. */
  constraints = N_VNew_Serial(NEQ);
  if(check_retval((void *)constraints, "N_VNew_Serial", 0)) return(1);
  N_VConst(ONE, constraints);  

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

  /* Allocate space for CVODES */
  retval = CVodeInit(cvode_mem, f, T0, y);
  if (check_retval(&retval, "CVodeInit", 1)) return(1);

  /* Use private function to compute error weights */
  retval = CVodeWFtolerances(cvode_mem, ewt);
  if (check_retval(&retval, "CVodeSetEwtFn", 1)) return(1);

  /* Attach user data */
  retval = CVodeSetUserData(cvode_mem, data);
  if (check_retval(&retval, "CVodeSetUserData", 1)) return(1);

  /* Call CVodeSetConstraints to initialize constraints */
  retval = CVodeSetConstraints(cvode_mem, constraints);
  if(check_retval(&retval, "CVodeSetConstraints", 1)) return(1);
  N_VDestroy(constraints);

  /* Create dense SUNMatrix */
  A = SUNDenseMatrix(NEQ, NEQ);
  if (check_retval((void *)A, "SUNDenseMatrix", 0)) return(1);

  /* Create dense SUNLinearSolver */
  LS = SUNLinSol_Dense(y, A);
  if (check_retval((void *)LS, "SUNLinSol_Dense", 0)) return(1);

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

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

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

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

    /* Set parameter scaling factor */
    pbar[0] = data->p[0];
    pbar[1] = data->p[1];
    pbar[2] = data->p[2];

    /* Set sensitivity initial conditions */
    yS = N_VCloneVectorArray(NS, y);
    if (check_retval((void *)yS, "N_VCloneVectorArray", 0)) return(1);
    for (is=0;is<NS;is++) N_VConst(ZERO, yS[is]);

    /* Call CVodeSensInit1 to activate forward sensitivity computations
       and allocate internal memory for COVEDS related to sensitivity
       calculations. Computes the right-hand sides of the sensitivity
       ODE, one at a time */
    retval = CVodeSensInit1(cvode_mem, NS, sensi_meth, fS, yS);
    if(check_retval(&retval, "CVodeSensInit", 1)) return(1);

    /* Call CVodeSensEEtolerances to estimate tolerances for sensitivity 
       variables based on the rolerances supplied for states variables and 
       the scaling factor pbar */
    retval = CVodeSensEEtolerances(cvode_mem);
    if(check_retval(&retval, "CVodeSensEEtolerances", 1)) return(1);

    /* Set sensitivity analysis optional inputs */
    /* Call CVodeSetSensErrCon to specify the error control strategy for 
       sensitivity variables */
    retval = CVodeSetSensErrCon(cvode_mem, err_con);
    if (check_retval(&retval, "CVodeSetSensErrCon", 1)) return(1);

    /* Call CVodeSetSensParams to specify problem parameter information for 
       sensitivity calculations */
    retval = CVodeSetSensParams(cvode_mem, NULL, pbar, NULL);
    if (check_retval(&retval, "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) {

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

    PrintOutput(cvode_mem, t, y);

    /* Call CVodeGetSens to get the sensitivity solution vector after a
       successful return from CVode */
    if (sensi) {
      retval = CVodeGetSens(cvode_mem, &t, yS);
      if (check_retval(&retval, "CVodeGetSens", 1)) break;
      PrintOutputS(yS);
    } 
    printf("-----------------------------------------");
    printf("------------------------------\n");

  }

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

  /* Free memory */

  N_VDestroy(y);                    /* Free y vector */
  if (sensi) {
    N_VDestroyVectorArray(yS, NS);  /* Free yS vector */
  }
  free(data);                              /* Free user data */
  CVodeFree(&cvode_mem);                   /* Free CVODES memory */
  SUNLinSolFree(LS);                       /* Free the linear solver memory */
  SUNMatDestroy(A);                        /* Free the matrix memory */

  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);
	}
예제 #8
0
int main()
{
  void *cvode_mem;
  SUNMatrix A;
  SUNLinearSolver LS;

  N_Vector y;
  int flag, ret;
  realtype reltol, abstol, t0, t1, t2, t;
  long int nst1, nst2, nst;

  reltol = RCONST(1.0e-3);
  abstol = RCONST(1.0e-4);

  t0 = RCONST(0.0);
  t1 = RCONST(1.0);
  t2 = RCONST(2.0);

  /* Allocate the vector of initial conditions */
  y = N_VNew_Serial(NEQ);

  /* Set initial condition */
  NV_Ith_S(y,0) = RCONST(1.0);

  /*
   * ------------------------------------------------------------
   *  Shared initialization and setup
   * ------------------------------------------------------------
   */

  /* Call CVodeCreate to create CVODE memory block and specify the
   * Backward Differentiaion Formula */
  cvode_mem = CVodeCreate(CV_BDF);
  if (check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1);

  /* Call CVodeInit to initialize integrator memory and specify the
   * user's right hand side function y'=f(t,y), the initial time T0
   * and the initial condiition vector y. */
  ret = CVodeInit(cvode_mem, f, t0, y);
  if (check_flag((void *)&ret, "CVodeInit", 1)) return(1);

  /* Call CVodeSStolerances to specify integration tolereances,
   * specifically the scalar relative and absolute tolerance. */
  ret = CVodeSStolerances(cvode_mem, reltol, abstol);
  if (check_flag((void *)&ret, "CVodeSStolerances", 1)) return(1);

  /* Provide RHS flag as user data which can be access in user provided routines */
  ret = CVodeSetUserData(cvode_mem, &flag);
  if (check_flag((void *)&ret, "CVodeSetUserData", 1)) return(1);

  /* Create dense SUNMatrix for use in linear solver */
  A = SUNDenseMatrix(NEQ, NEQ);
  if (check_flag((void *)A, "SUNDenseMatrix", 0)) return(1);

  /* Create dense linear solver for use by CVode */
  LS = SUNLinSol_Dense(y, A);
  if (check_flag((void *)LS, "SUNLinSol_Dense", 0)) return(1);

  /* Attach the linear solver and matrix to CVode by calling CVodeSetLinearSolver */
  ret = CVodeSetLinearSolver(cvode_mem, LS, A);
  if (check_flag((void *)&ret, "CVodeSetLinearSolver", 1)) return(1);

  /*
   * ---------------------------------------------------------------
   * Discontinuity in the solution
   *
   * 1) Integrate to the discontinuity
   * 2) Integrate from the discontinuity
   * ---------------------------------------------------------------
   */

  /* ---- Integrate to the discontinuity */
 
  printf("\nDiscontinuity in solution\n\n");
 
  /* set TSTOP (max time solution proceeds to) - this is not required */
  ret = CVodeSetStopTime(cvode_mem, t1);
  if (check_flag((void *)&ret, "CVodeSetStopTime", 1)) return(1);

  flag = RHS1; /* use -y for RHS */
  t = t0; /* set the integrator start time */

  printf("%12.8e  %12.8e\n",t,NV_Ith_S(y,0));
  while (t<t1) {
    /* advance solver just one internal step */
    ret = CVode(cvode_mem, t1, y, &t, CV_ONE_STEP);
    if (check_flag((void *)&ret, "CVode", 1)) return(1);
    printf("%12.8e  %12.8e\n",t,NV_Ith_S(y,0));
  }
  /* Get the number of steps the solver took to get to the discont. */
  ret = CVodeGetNumSteps(cvode_mem, &nst1);
  if (check_flag((void *)&ret, "CvodeGetNumSteps", 1)) return(1);

  /* ---- Integrate from the discontinuity */

  /* Include discontinuity */
  NV_Ith_S(y,0) = RCONST(1.0);
 
  /* Reinitialize the solver */
  ret = CVodeReInit(cvode_mem, t1, y);
  if (check_flag((void *)&ret, "CVodeReInit", 1)) return(1);

  /* set TSTOP (max time solution proceeds to) - this is not required */
  ret = CVodeSetStopTime(cvode_mem, t2);
  if (check_flag((void *)&ret, "CVodeSetStopTime", 1)) return(1);

  flag = RHS1; /* use -y for RHS */
  t = t1; /* set the integrator start time */

  printf("%12.8e  %12.8e\n",t,NV_Ith_S(y,0));

  while (t<t2) {
    /* advance solver just one internal step */
    ret = CVode(cvode_mem, t2, y, &t, CV_ONE_STEP);
    if (check_flag((void *)&ret, "CVode", 1)) return(1);
    printf("%12.8e  %12.8e\n",t,NV_Ith_S(y,0));
  }

  /* Get the number of steps the solver took after the discont. */
  ret = CVodeGetNumSteps(cvode_mem, &nst2);
  if (check_flag((void *)&ret, "CvodeGetNumSteps", 1)) return(1);

  /* Print statistics */
  nst = nst1 + nst2;
  printf("\nNumber of steps: %ld + %ld = %ld\n",nst1, nst2, nst);

  /*
   * ---------------------------------------------------------------
   * Discontinuity in RHS: Case 1 - explicit treatment
   * Note that it is not required to set TSTOP, but without it
   * we would have to find y(t1) to reinitialize the solver.
   * ---------------------------------------------------------------
   */

  printf("\nDiscontinuity in RHS: Case 1 - explicit treatment\n\n");

  /* Set initial condition */
  NV_Ith_S(y,0) = RCONST(1.0);

  /* Reinitialize the solver. CVodeReInit does not reallocate memory
   * so it can only be used when the new problem size is the same as
   * the problem size when CVodeCreate was called. */
  ret = CVodeReInit(cvode_mem, t0, y);
  if (check_flag((void *)&ret, "CVodeReInit", 1)) return(1);

  /* ---- Integrate to the discontinuity */

  /* Set TSTOP (max time solution proceeds to) to location of discont. */
  ret = CVodeSetStopTime(cvode_mem, t1);
  if (check_flag((void *)&ret, "CVodeSetStopTime", 1)) return(1);

  flag = RHS1; /* use -y for RHS */
  t = t0; /* set the integrator start time */

  printf("%12.8e  %12.8e\n",t,NV_Ith_S(y,0));
  while (t<t1) {
    /* advance solver just one internal step */
    ret = CVode(cvode_mem, t1, y, &t, CV_ONE_STEP);
    if (check_flag((void *)&ret, "CVode", 1)) return(1);
    printf("%12.8e  %12.8e\n",t,NV_Ith_S(y,0));
  }

  /* Get the number of steps the solver took to get to the discont. */
  ret = CVodeGetNumSteps(cvode_mem, &nst1);
  if (check_flag((void *)&ret, "CvodeGetNumSteps", 1)) return(1);

  /* If TSTOP was not set, we'd need to find y(t1): */
  /* CVodeGetDky(cvode_mem, t1, 0, y); */

  /* ---- Integrate from the discontinuity */

  /* Reinitialize solver */
  ret = CVodeReInit(cvode_mem, t1, y);

  /* set TSTOP (max time solution proceeds to) - this is not required */
  ret = CVodeSetStopTime(cvode_mem, t2);
  if (check_flag((void *)&ret, "CVodeSetStopTime", 1)) return(1);

  flag = RHS2; /* use -5y for RHS */
  t = t1; /* set the integrator start time */

  printf("%12.8e  %12.8e\n",t,NV_Ith_S(y,0));

  while (t<t2) {
    /* advance solver just one internal step */
    ret = CVode(cvode_mem, t2, y, &t, CV_ONE_STEP);
    if (check_flag((void *)&ret, "CVode", 1)) return(1);
    printf("%12.8e  %12.8e\n",t,NV_Ith_S(y,0));
  }

  /* Get the number of steps the solver took after the discont. */
  ret = CVodeGetNumSteps(cvode_mem, &nst2);
  if (check_flag((void *)&ret, "CvodeGetNumSteps", 1)) return(1);

  /* Print statistics */
  nst = nst1 + nst2;
  printf("\nNumber of steps: %ld + %ld = %ld\n",nst1, nst2, nst);


  /*
   * ---------------------------------------------------------------
   * Discontinuity in RHS: Case 2 - let CVODE deal with it
   * Note that here we MUST set TSTOP to ensure that the
   * change in the RHS happens at the appropriate time
   * ---------------------------------------------------------------
   */

  printf("\nDiscontinuity in RHS: Case 2 - let CVODE deal with it\n\n");

  /* Set initial condition */
  NV_Ith_S(y,0) = RCONST(1.0);

  /* Reinitialize the solver. CVodeReInit does not reallocate memory
   * so it can only be used when the new problem size is the same as
   * the problem size when CVodeCreate was called. */
  ret = CVodeReInit(cvode_mem, t0, y);
  if (check_flag((void *)&ret, "CVodeReInit", 1)) return(1);

  /* ---- Integrate to the discontinuity */

  /* Set TSTOP (max time solution proceeds to) to location of discont. */
  ret = CVodeSetStopTime(cvode_mem, t1);
  if (check_flag((void *)&ret, "CVodeSetStopTime", 1)) return(1);

  flag = RHS1; /* use -y for RHS */
  t = t0; /* set the integrator start time */

  printf("%12.8e  %12.8e\n",t,NV_Ith_S(y,0));
  while (t<t1) {
    /* advance solver just one internal step */
    ret = CVode(cvode_mem, t1, y, &t, CV_ONE_STEP);
    if (check_flag((void *)&ret, "CVode", 1)) return(1);
    printf("%12.8e  %12.8e\n",t,NV_Ith_S(y,0));
  }

  /* Get the number of steps the solver took to get to the discont. */
  ret = CVodeGetNumSteps(cvode_mem, &nst1);
  if (check_flag((void *)&ret, "CvodeGetNumSteps", 1)) return(1);

  /* ---- Integrate from the discontinuity */

  /* set TSTOP (max time solution proceeds to) - this is not required */
  ret = CVodeSetStopTime(cvode_mem, t2);
  if (check_flag((void *)&ret, "CVodeSetStopTime", 1)) return(1);

  flag = RHS2; /* use -5y for RHS */
  t = t1; /* set the integrator start time */

  printf("%12.8e  %12.8e\n",t,NV_Ith_S(y,0));

  while (t<t2) {
    /* advance solver just one internal step */
    ret = CVode(cvode_mem, t2, y, &t, CV_ONE_STEP);
    if (check_flag((void *)&ret, "CVode", 1)) return(1);
    printf("%12.8e  %12.8e\n",t,NV_Ith_S(y,0));
  }

  /* Get the number of steps the solver took after the discont. */
  ret = CVodeGetNumSteps(cvode_mem, &nst);
  if (check_flag((void *)&ret, "CvodeGetNumSteps", 1)) return(1);

  /* Print statistics */
  nst2 = nst - nst1;
  printf("\nNumber of steps: %ld + %ld = %ld\n",nst1, nst2, nst);

  /* Free memory */
  N_VDestroy(y);
  SUNMatDestroy(A);
  SUNLinSolFree(LS);
  CVodeFree(&cvode_mem);

  return(0);
}
예제 #9
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);
}
예제 #10
0
/* ----------------------------------------------------------------------
 * SUNLinSol_Dense Testing Routine
 * --------------------------------------------------------------------*/
int main(int argc, char *argv[]) 
{
  int             fails = 0;          /* counter for test failures  */
  sunindextype    cols, rows;         /* matrix columns, rows       */
  SUNLinearSolver LS;                 /* solver object              */
  SUNMatrix       A, B, I;            /* test matrices              */
  N_Vector        x, y, b;            /* test vectors               */
  int             print_timing;
  sunindextype    j, k;
  realtype        *colj, *xdata, *colIj;

  /* check input and set matrix dimensions */
  if (argc < 3){
    printf("ERROR: TWO (2) Inputs required: matrix cols, print timing \n");
    return(-1);
  }

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

  rows = cols;

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

  printf("\nDense linear solver test: size %ld\n\n",
         (long int) cols);

  /* Create matrices and vectors */
  A = SUNDenseMatrix(rows, cols);
  B = SUNDenseMatrix(rows, cols);
  I = SUNDenseMatrix(rows, cols);
  x = N_VNew_Serial(cols);
  y = N_VNew_Serial(cols);
  b = N_VNew_Serial(cols);

  /* Fill A matrix with uniform random data in [0,1/cols] */
  for (j=0; j<cols; j++) {
    colj = SUNDenseMatrix_Column(A, j);
    for (k=0; k<rows; k++)
      colj[k] = (realtype) rand() / (realtype) RAND_MAX / cols;    
  }

  /* Create anti-identity matrix */
  j=cols-1;
  for (k=0; k<rows; k++) {
    colj = SUNDenseMatrix_Column(I,j);
    colj[k] = 1;
    j = j-1;
  }    
  
  /* Add anti-identity to ensure the solver needs to do row-swapping */
  for (k=0; k<rows; k++){
    for(j=0; j<cols; j++){
      colj = SUNDenseMatrix_Column(A,j);
      colIj = SUNDenseMatrix_Column(I,j);
      colj[k]  = colj[k] + colIj[k]; 
   }
  }

  /* Fill x vector with uniform random data in [0,1] */
  xdata = N_VGetArrayPointer(x);
  for (j=0; j<cols; j++) {
    xdata[j] = (realtype) rand() / (realtype) RAND_MAX;
  } 

  /* copy A and x into B and y to print in case of solver failure */
  SUNMatCopy(A, B);
  N_VScale(ONE, x, y);

  /* create right-hand side vector for linear solve */
  fails = SUNMatMatvec(A, x, b);
  if (fails) {
    printf("FAIL: SUNLinSol SUNMatMatvec failure\n");

    /* Free matrices and vectors */
    SUNMatDestroy(A);
    SUNMatDestroy(B);
    SUNMatDestroy(I);
    N_VDestroy(x);
    N_VDestroy(y);
    N_VDestroy(b);

    return(1);
  }

  /* Create dense linear solver */
  LS = SUNLinSol_Dense(x, A);
  
  /* Run Tests */
  fails += Test_SUNLinSolInitialize(LS, 0);
  fails += Test_SUNLinSolSetup(LS, A, 0);
  fails += Test_SUNLinSolSolve(LS, A, x, b, 10*UNIT_ROUNDOFF, 0);
 
  fails += Test_SUNLinSolGetType(LS, SUNLINEARSOLVER_DIRECT, 0);
  fails += Test_SUNLinSolLastFlag(LS, 0);
  fails += Test_SUNLinSolSpace(LS, 0);

  /* Print result */
  if (fails) {
    printf("FAIL: SUNLinSol module failed %i tests \n \n", fails);
    printf("\nA (original) =\n");
    SUNDenseMatrix_Print(B,stdout);
    printf("\nA (factored) =\n");
    SUNDenseMatrix_Print(A,stdout);
    printf("\nx (original) =\n");
    N_VPrint_Serial(y);
    printf("\nx (computed) =\n");
    N_VPrint_Serial(x);
  } else {
    printf("SUCCESS: SUNLinSol module passed all tests \n \n");
  }

  /* Free solver, matrix and vectors */
  SUNLinSolFree(LS);
  SUNMatDestroy(A);
  SUNMatDestroy(B);
  SUNMatDestroy(I);
  N_VDestroy(x);
  N_VDestroy(y);
  N_VDestroy(b);

  return(fails);
}