int CVSpilsSetGSTypeB(void *cvadj_mem, int gstypeB) { CVadjMem ca_mem; CVodeMem cvB_mem; int flag; if (cvadj_mem == NULL) { CVProcessError(NULL, CVSPILS_ADJMEM_NULL, "CVSPILS", "CVSpilsSetGSTypeB", MSGS_CAMEM_NULL); return(CVSPILS_ADJMEM_NULL); } ca_mem = (CVadjMem) cvadj_mem; cvB_mem = ca_mem->cvb_mem; flag = CVSpilsSetGSType(cvB_mem,gstypeB); return(flag); }
int CVSpilsSetGSTypeB(void *cvode_mem, int which, int gstypeB) { CVodeMem cv_mem; CVadjMem ca_mem; CVodeBMem cvB_mem; void *cvodeB_mem; int flag; /* Check if cvode_mem exists */ if (cvode_mem == NULL) { cvProcessError(NULL, CVSPILS_MEM_NULL, "CVSPILS", "CVSpilsSetGSTypeB", MSGS_CVMEM_NULL); return(CVSPILS_MEM_NULL); } cv_mem = (CVodeMem) cvode_mem; /* Was ASA initialized? */ if (cv_mem->cv_adjMallocDone == FALSE) { cvProcessError(cv_mem, CVSPILS_NO_ADJ, "CVSPILS", "CVSpilsSetGSTypeB", MSGS_NO_ADJ); return(CVSPILS_NO_ADJ); } ca_mem = cv_mem->cv_adj_mem; /* Check which */ if ( which >= ca_mem->ca_nbckpbs ) { cvProcessError(cv_mem, CVSPILS_ILL_INPUT, "CVSPILS", "CVSpilsSetGSTypeB", MSGS_BAD_WHICH); return(CVSPILS_ILL_INPUT); } /* Find the CVodeBMem entry in the linked list corresponding to which */ cvB_mem = ca_mem->cvB_mem; while (cvB_mem != NULL) { if ( which == cvB_mem->cv_index ) break; cvB_mem = cvB_mem->cv_next; } cvodeB_mem = (void *) (cvB_mem->cv_mem); flag = CVSpilsSetGSType(cvodeB_mem,gstypeB); return(flag); }
void FCV_BPSPGMR(int *pretype, int *gstype, int *maxl, realtype *delt, int *ier) { /* Call CVBPSpgmr to specify the SPGMR linear solver: CV_cvodemem is the pointer to the CVODE memory block pretype is the preconditioner type gstype is the Gram-Schmidt process type maxl is the maximum Krylov dimension delt is the linear convergence tolerance factor */ *ier = CVBPSpgmr(CV_cvodemem, *pretype, *maxl, CVBP_Data); if (*ier != CVSPILS_SUCCESS) return; *ier = CVSpilsSetGSType(CV_cvodemem, *gstype); if (*ier != CVSPILS_SUCCESS) return; *ier = CVSpilsSetDelt(CV_cvodemem, *delt); if (*ier != CVSPILS_SUCCESS) return; CV_ls = CV_LS_SPGMR; }
PetscErrorCode TSSetUp_Sundials(TS ts) { TS_Sundials *cvode = (TS_Sundials*)ts->data; PetscErrorCode ierr; PetscInt glosize,locsize,i,flag; PetscScalar *y_data,*parray; void *mem; PC pc; PCType pctype; PetscBool pcnone; PetscFunctionBegin; /* get the vector size */ ierr = VecGetSize(ts->vec_sol,&glosize);CHKERRQ(ierr); ierr = VecGetLocalSize(ts->vec_sol,&locsize);CHKERRQ(ierr); /* allocate the memory for N_Vec y */ cvode->y = N_VNew_Parallel(cvode->comm_sundials,locsize,glosize); if (!cvode->y) SETERRQ(PETSC_COMM_SELF,1,"cvode->y is not allocated"); /* initialize N_Vec y: copy ts->vec_sol to cvode->y */ ierr = VecGetArray(ts->vec_sol,&parray);CHKERRQ(ierr); y_data = (PetscScalar*) N_VGetArrayPointer(cvode->y); for (i = 0; i < locsize; i++) y_data[i] = parray[i]; ierr = VecRestoreArray(ts->vec_sol,NULL);CHKERRQ(ierr); ierr = VecDuplicate(ts->vec_sol,&cvode->update);CHKERRQ(ierr); ierr = VecDuplicate(ts->vec_sol,&cvode->ydot);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)cvode->update);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)cvode->ydot);CHKERRQ(ierr); /* Create work vectors for the TSPSolve_Sundials() routine. Note these are allocated with zero space arrays because the actual array space is provided by Sundials and set using VecPlaceArray(). */ ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)ts),1,locsize,PETSC_DECIDE,0,&cvode->w1);CHKERRQ(ierr); ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)ts),1,locsize,PETSC_DECIDE,0,&cvode->w2);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)cvode->w1);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)cvode->w2);CHKERRQ(ierr); /* Call CVodeCreate to create the solver memory and the use of a Newton iteration */ mem = CVodeCreate(cvode->cvode_type, CV_NEWTON); if (!mem) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"CVodeCreate() fails"); cvode->mem = mem; /* Set the pointer to user-defined data */ flag = CVodeSetUserData(mem, ts); if (flag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVodeSetUserData() fails"); /* Sundials may choose to use a smaller initial step, but will never use a larger step. */ flag = CVodeSetInitStep(mem,(realtype)ts->time_step); if (flag) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_LIB,"CVodeSetInitStep() failed"); if (cvode->mindt > 0) { flag = CVodeSetMinStep(mem,(realtype)cvode->mindt); if (flag) { if (flag == CV_MEM_NULL) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_LIB,"CVodeSetMinStep() failed, cvode_mem pointer is NULL"); else if (flag == CV_ILL_INPUT) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_LIB,"CVodeSetMinStep() failed, hmin is nonpositive or it exceeds the maximum allowable step size"); else SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_LIB,"CVodeSetMinStep() failed"); } } if (cvode->maxdt > 0) { flag = CVodeSetMaxStep(mem,(realtype)cvode->maxdt); if (flag) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_LIB,"CVodeSetMaxStep() failed"); } /* Call CVodeInit to initialize the integrator memory and specify the * user's right hand side function in u'=f(t,u), the inital time T0, and * the initial dependent variable vector cvode->y */ flag = CVodeInit(mem,TSFunction_Sundials,ts->ptime,cvode->y); if (flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVodeInit() fails, flag %d",flag); /* specifies scalar relative and absolute tolerances */ flag = CVodeSStolerances(mem,cvode->reltol,cvode->abstol); if (flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVodeSStolerances() fails, flag %d",flag); /* Specify max num of steps to be taken by cvode in its attempt to reach the next output time */ flag = CVodeSetMaxNumSteps(mem,ts->max_steps); /* call CVSpgmr to use GMRES as the linear solver. */ /* setup the ode integrator with the given preconditioner */ ierr = TSSundialsGetPC(ts,&pc);CHKERRQ(ierr); ierr = PCGetType(pc,&pctype);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)pc,PCNONE,&pcnone);CHKERRQ(ierr); if (pcnone) { flag = CVSpgmr(mem,PREC_NONE,0); if (flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVSpgmr() fails, flag %d",flag); } else { flag = CVSpgmr(mem,PREC_LEFT,cvode->maxl); if (flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVSpgmr() fails, flag %d",flag); /* Set preconditioner and solve routines Precond and PSolve, and the pointer to the user-defined block data */ flag = CVSpilsSetPreconditioner(mem,TSPrecond_Sundials,TSPSolve_Sundials); if (flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVSpilsSetPreconditioner() fails, flag %d", flag); } flag = CVSpilsSetGSType(mem, MODIFIED_GS); if (flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVSpgmrSetGSType() fails, flag %d",flag); PetscFunctionReturn(0); }
int main() { realtype abstol=ATOL, reltol=RTOL, t, tout; N_Vector c; WebData wdata; void *cvode_mem; booleantype firstrun; int jpre, gstype, flag; int ns, mxns, iout; c = NULL; wdata = NULL; cvode_mem = NULL; /* Initializations */ c = N_VNew_Serial(NEQ); if(check_flag((void *)c, "N_VNew_Serial", 0)) return(1); wdata = AllocUserData(); if(check_flag((void *)wdata, "AllocUserData", 2)) return(1); InitUserData(wdata); ns = wdata->ns; mxns = wdata->mxns; /* Print problem description */ PrintIntro(); /* Loop over jpre and gstype (four cases) */ for (jpre = PREC_LEFT; jpre <= PREC_RIGHT; jpre++) { for (gstype = MODIFIED_GS; gstype <= CLASSICAL_GS; gstype++) { /* Initialize c and print heading */ CInit(c, wdata); PrintHeader(jpre, gstype); /* Call CVodeInit or CVodeReInit, then CVSpgmr to set up problem */ firstrun = (jpre == PREC_LEFT) && (gstype == MODIFIED_GS); if (firstrun) { cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON); if(check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1); wdata->cvode_mem = cvode_mem; flag = CVodeSetUserData(cvode_mem, wdata); if(check_flag(&flag, "CVodeSetUserData", 1)) return(1); flag = CVodeInit(cvode_mem, f, T0, c); if(check_flag(&flag, "CVodeInit", 1)) return(1); flag = CVodeSStolerances(cvode_mem, reltol, abstol); if (check_flag(&flag, "CVodeSStolerances", 1)) return(1); flag = CVSpgmr(cvode_mem, jpre, MAXL); if(check_flag(&flag, "CVSpgmr", 1)) return(1); flag = CVSpilsSetGSType(cvode_mem, gstype); if(check_flag(&flag, "CVSpilsSetGSType", 1)) return(1); flag = CVSpilsSetEpsLin(cvode_mem, DELT); if(check_flag(&flag, "CVSpilsSetEpsLin", 1)) return(1); flag = CVSpilsSetPreconditioner(cvode_mem, Precond, PSolve); if(check_flag(&flag, "CVSpilsSetPreconditioner", 1)) return(1); } else { flag = CVodeReInit(cvode_mem, T0, c); if(check_flag(&flag, "CVodeReInit", 1)) return(1); flag = CVSpilsSetPrecType(cvode_mem, jpre); check_flag(&flag, "CVSpilsSetPrecType", 1); flag = CVSpilsSetGSType(cvode_mem, gstype); if(check_flag(&flag, "CVSpilsSetGSType", 1)) return(1); } /* Print initial values */ if (firstrun) PrintAllSpecies(c, ns, mxns, T0); /* Loop over output points, call CVode, print sample solution values. */ tout = T1; for (iout = 1; iout <= NOUT; iout++) { flag = CVode(cvode_mem, tout, c, &t, CV_NORMAL); PrintOutput(cvode_mem, t); if (firstrun && (iout % 3 == 0)) PrintAllSpecies(c, ns, mxns, t); if(check_flag(&flag, "CVode", 1)) break; if (tout > RCONST(0.9)) tout += DTOUT; else tout *= TOUT_MULT; } /* Print final statistics, and loop for next case */ PrintFinalStats(cvode_mem); } } /* Free all memory */ CVodeFree(&cvode_mem); N_VDestroy_Serial(c); FreeUserData(wdata); return(0); }
int main(void) { realtype abstol, reltol, t, tout; N_Vector u; UserData data; void *cvode_mem; int linsolver, iout, flag; u = NULL; data = NULL; cvode_mem = NULL; /* Allocate memory, and set problem data, initial values, tolerances */ u = N_VNew_Serial(NEQ); if(check_flag((void *)u, "N_VNew_Serial", 0)) return(1); data = AllocUserData(); if(check_flag((void *)data, "AllocUserData", 2)) return(1); InitUserData(data); SetInitialProfiles(u, data->dx, data->dy); abstol=ATOL; reltol=RTOL; /* Call CVodeCreate to create the solver memory and specify the * Backward Differentiation Formula and the use of a Newton iteration */ cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON); if(check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1); /* Set the pointer to user-defined data */ flag = CVodeSetUserData(cvode_mem, data); if(check_flag(&flag, "CVodeSetUserData", 1)) return(1); /* Call CVodeInit to initialize the integrator memory and specify the * user's right hand side function in u'=f(t,u), the inital time T0, and * the initial dependent variable vector u. */ flag = CVodeInit(cvode_mem, f, T0, u); if(check_flag(&flag, "CVodeInit", 1)) return(1); /* Call CVodeSStolerances to specify the scalar relative tolerance * and scalar absolute tolerances */ flag = CVodeSStolerances(cvode_mem, reltol, abstol); if (check_flag(&flag, "CVodeSStolerances", 1)) return(1); /* START: Loop through SPGMR, SPBCG and SPTFQMR linear solver modules */ for (linsolver = 0; linsolver < 3; ++linsolver) { if (linsolver != 0) { /* Re-initialize user data */ InitUserData(data); SetInitialProfiles(u, data->dx, data->dy); /* Re-initialize CVode for the solution of the same problem, but using a different linear solver module */ flag = CVodeReInit(cvode_mem, T0, u); if (check_flag(&flag, "CVodeReInit", 1)) return(1); } /* Attach a linear solver module */ switch(linsolver) { /* (a) SPGMR */ case(USE_SPGMR): /* Print header */ printf(" -------"); printf(" \n| SPGMR |\n"); printf(" -------\n"); /* Call CVSpgmr to specify the linear solver CVSPGMR with left preconditioning and the maximum Krylov dimension maxl */ flag = CVSpgmr(cvode_mem, PREC_LEFT, 0); if(check_flag(&flag, "CVSpgmr", 1)) return(1); /* Set modified Gram-Schmidt orthogonalization, preconditioner setup and solve routines Precond and PSolve, and the pointer to the user-defined block data */ flag = CVSpilsSetGSType(cvode_mem, MODIFIED_GS); if(check_flag(&flag, "CVSpilsSetGSType", 1)) return(1); break; /* (b) SPBCG */ case(USE_SPBCG): /* Print header */ printf(" -------"); printf(" \n| SPBCG |\n"); printf(" -------\n"); /* Call CVSpbcg to specify the linear solver CVSPBCG with left preconditioning and the maximum Krylov dimension maxl */ flag = CVSpbcg(cvode_mem, PREC_LEFT, 0); if(check_flag(&flag, "CVSpbcg", 1)) return(1); break; /* (c) SPTFQMR */ case(USE_SPTFQMR): /* Print header */ printf(" ---------"); printf(" \n| SPTFQMR |\n"); printf(" ---------\n"); /* Call CVSptfqmr to specify the linear solver CVSPTFQMR with left preconditioning and the maximum Krylov dimension maxl */ flag = CVSptfqmr(cvode_mem, PREC_LEFT, 0); if(check_flag(&flag, "CVSptfqmr", 1)) return(1); break; } /* Set preconditioner setup and solve routines Precond and PSolve, and the pointer to the user-defined block data */ flag = CVSpilsSetPreconditioner(cvode_mem, Precond, PSolve); if(check_flag(&flag, "CVSpilsSetPreconditioner", 1)) return(1); /* In loop over output points, call CVode, print results, test for error */ printf(" \n2-species diurnal advection-diffusion problem\n\n"); for (iout=1, tout = TWOHR; iout <= NOUT; iout++, tout += TWOHR) { flag = CVode(cvode_mem, tout, u, &t, CV_NORMAL); PrintOutput(cvode_mem, u, t); if(check_flag(&flag, "CVode", 1)) break; } PrintFinalStats(cvode_mem, linsolver); } /* END: Loop through SPGMR, SPBCG and SPTFQMR linear solver modules */ /* Free memory */ N_VDestroy_Serial(u); FreeUserData(data); CVodeFree(&cvode_mem); return(0); }
PetscErrorCode TSSetUp_Sundials_Nonlinear(TS ts) { TS_Sundials *cvode = (TS_Sundials*)ts->data; PetscErrorCode ierr; PetscInt glosize,locsize,i,flag; PetscScalar *y_data,*parray; void *mem; const PCType pctype; PetscTruth pcnone; Vec sol = ts->vec_sol; PetscFunctionBegin; ierr = PCSetFromOptions(cvode->pc);CHKERRQ(ierr); /* get the vector size */ ierr = VecGetSize(ts->vec_sol,&glosize);CHKERRQ(ierr); ierr = VecGetLocalSize(ts->vec_sol,&locsize);CHKERRQ(ierr); /* allocate the memory for N_Vec y */ cvode->y = N_VNew_Parallel(cvode->comm_sundials,locsize,glosize); if (!cvode->y) SETERRQ(1,"cvode->y is not allocated"); /* initialize N_Vec y: copy ts->vec_sol to cvode->y */ ierr = VecGetArray(ts->vec_sol,&parray);CHKERRQ(ierr); y_data = (PetscScalar *) N_VGetArrayPointer(cvode->y); for (i = 0; i < locsize; i++) y_data[i] = parray[i]; /*ierr = PetscMemcpy(y_data,parray,locsize*sizeof(PETSC_SCALAR)); CHKERRQ(ierr);*/ ierr = VecRestoreArray(ts->vec_sol,PETSC_NULL);CHKERRQ(ierr); ierr = VecDuplicate(ts->vec_sol,&cvode->update);CHKERRQ(ierr); ierr = VecDuplicate(ts->vec_sol,&cvode->func);CHKERRQ(ierr); ierr = PetscLogObjectParent(ts,cvode->update);CHKERRQ(ierr); ierr = PetscLogObjectParent(ts,cvode->func);CHKERRQ(ierr); /* Create work vectors for the TSPSolve_Sundials() routine. Note these are allocated with zero space arrays because the actual array space is provided by Sundials and set using VecPlaceArray(). */ ierr = VecCreateMPIWithArray(((PetscObject)ts)->comm,locsize,PETSC_DECIDE,0,&cvode->w1);CHKERRQ(ierr); ierr = VecCreateMPIWithArray(((PetscObject)ts)->comm,locsize,PETSC_DECIDE,0,&cvode->w2);CHKERRQ(ierr); ierr = PetscLogObjectParent(ts,cvode->w1);CHKERRQ(ierr); ierr = PetscLogObjectParent(ts,cvode->w2);CHKERRQ(ierr); /* Call CVodeCreate to create the solver memory and the use of a Newton iteration */ mem = CVodeCreate(cvode->cvode_type, CV_NEWTON); if (!mem) SETERRQ(PETSC_ERR_MEM,"CVodeCreate() fails"); cvode->mem = mem; /* Set the pointer to user-defined data */ flag = CVodeSetUserData(mem, ts); if (flag) SETERRQ(PETSC_ERR_LIB,"CVodeSetUserData() fails"); /* Call CVodeInit to initialize the integrator memory and specify the * user's right hand side function in u'=f(t,u), the inital time T0, and * the initial dependent variable vector cvode->y */ flag = CVodeInit(mem,TSFunction_Sundials,ts->ptime,cvode->y); if (flag){ SETERRQ1(PETSC_ERR_LIB,"CVodeInit() fails, flag %d",flag); } flag = CVodeSStolerances(mem,cvode->reltol,cvode->abstol); if (flag){ SETERRQ1(PETSC_ERR_LIB,"CVodeSStolerances() fails, flag %d",flag); } /* initialize the number of steps */ ierr = TSMonitor(ts,ts->steps,ts->ptime,sol);CHKERRQ(ierr); /* call CVSpgmr to use GMRES as the linear solver. */ /* setup the ode integrator with the given preconditioner */ ierr = PCGetType(cvode->pc,&pctype);CHKERRQ(ierr); ierr = PetscTypeCompare((PetscObject)cvode->pc,PCNONE,&pcnone);CHKERRQ(ierr); if (pcnone){ flag = CVSpgmr(mem,PREC_NONE,0); if (flag) SETERRQ1(PETSC_ERR_LIB,"CVSpgmr() fails, flag %d",flag); } else { flag = CVSpgmr(mem,PREC_LEFT,0); if (flag) SETERRQ1(PETSC_ERR_LIB,"CVSpgmr() fails, flag %d",flag); /* Set preconditioner and solve routines Precond and PSolve, and the pointer to the user-defined block data */ flag = CVSpilsSetPreconditioner(mem,TSPrecond_Sundials,TSPSolve_Sundials); if (flag) SETERRQ1(PETSC_ERR_LIB,"CVSpilsSetPreconditioner() fails, flag %d", flag); } flag = CVSpilsSetGSType(mem, MODIFIED_GS); if (flag) SETERRQ1(PETSC_ERR_LIB,"CVSpgmrSetGSType() fails, flag %d",flag); PetscFunctionReturn(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 and specify the * Backward Differentiation Formula and the use of a Newton iteration */ cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON); if(check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1); /* Set the pointer to user-defined data */ flag = CVodeSetUserData(cvode_mem, data); if(check_flag(&flag, "CVodeSetUserData", 1)) return(1); /* Call CVodeInit to initialize the integrator memory and specify the * user's right hand side function in u'=f(t,u), the inital time T0, and * the initial dependent variable vector u. */ flag = CVodeInit(cvode_mem, f, T0, u); if(check_flag(&flag, "CVodeInit", 1)) return(1); /* Call CVodeSStolerances to specify the scalar relative tolerance * and scalar absolute tolerances */ flag = CVodeSStolerances(cvode_mem, reltol, abstol); if (check_flag(&flag, "CVodeSStolerances", 1)) return(1); /* Call CVSpgmr to specify the linear solver CVSPGMR * with left preconditioning and the maximum Krylov dimension maxl */ flag = CVSpgmr(cvode_mem, PREC_LEFT, 0); if(check_flag(&flag, "CVSpgmr", 1)) return(1); /* set the JAcobian-times-vector function */ flag = CVSpilsSetJacTimesVecFn(cvode_mem, jtv); if(check_flag(&flag, "CVSpilsSetJacTimesVecFn", 1)) return(1); /* Set modified Gram-Schmidt orthogonalization */ flag = CVSpilsSetGSType(cvode_mem, MODIFIED_GS); if(check_flag(&flag, "CVSpilsSetGSType", 1)) return(1); /* Set the preconditioner solve and setup functions */ flag = CVSpilsSetPreconditioner(cvode_mem, Precond, PSolve); if(check_flag(&flag, "CVSpilsSetPreconditioner", 1)) return(1); /* In loop over output points, call CVode, print results, test for error */ printf(" \n2-species diurnal advection-diffusion problem\n\n"); for (iout=1, tout = TWOHR; iout <= NOUT; iout++, tout += TWOHR) { flag = CVode(cvode_mem, tout, u, &t, CV_NORMAL); PrintOutput(cvode_mem, u, t); if(check_flag(&flag, "CVode", 1)) break; } PrintFinalStats(cvode_mem); /* Free memory */ N_VDestroy_Serial(u); FreeUserData(data); CVodeFree(&cvode_mem); return(0); }