int CVBBDSpgmr(void *cvode_mem, int pretype, int maxl, void *bbd_data)
{
  int flag;

  if ( bbd_data == NULL ) {
    fprintf(stderr, MSGBBDP_NO_PDATA);
    return(CV_PDATA_NULL);
  } 

  flag = CVSpgmr(cvode_mem, pretype, maxl);
  if(flag != CVSPGMR_SUCCESS) return(flag);

  flag = CVSpgmrSetPreconditioner(cvode_mem, CVBBDPrecSetup, CVBBDPrecSolve, bbd_data);
  if(flag != CVSPGMR_SUCCESS) return(flag);

  return(CVSPGMR_SUCCESS);
}
int CVSpgmrSetPreconditionerB(void *cvadj_mem, CVSpgmrPrecSetupFnB psetB,
                              CVSpgmrPrecSolveFnB psolveB, void *P_dataB)
{
  CVadjMem ca_mem;
  void *cvode_mem;
  int flag;

  if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  ca_mem = (CVadjMem) cvadj_mem;

  pset_B   = psetB;
  psolve_B = psolveB;
  P_data_B = P_dataB;

  cvode_mem = (void *) ca_mem->cvb_mem;

  flag = CVSpgmrSetPreconditioner(cvode_mem, CVAspilsPrecSetup, CVAspilsPrecSolve, cvadj_mem);

  return(flag);
}
Exemple #3
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);
}
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);
}