int main(void) { realtype dx, dy, reltol, abstol, t, tout, umax; N_Vector u; UserData data; void *cvode_mem; int iout, flag; long int nst; u = NULL; data = NULL; cvode_mem = NULL; /* Create a serial vector */ u = N_VNew_Serial(NEQ); /* Allocate u vector */ if(check_flag((void*)u, "N_VNew_Serial", 0)) return(1); reltol = ZERO; /* Set the tolerances */ abstol = ATOL; data = (UserData) malloc(sizeof *data); /* Allocate data memory */ if(check_flag((void *)data, "malloc", 2)) return(1); dx = data->dx = XMAX/(MX+1); /* Set grid coefficients in data */ dy = data->dy = YMAX/(MY+1); data->hdcoef = ONE/(dx*dx); data->hacoef = HALF/(TWO*dx); data->vdcoef = ONE/(dy*dy); SetIC(u, data); /* Initialize u vector */ /* Call CvodeCreate to create integrator memory CV_BDF specifies the Backward Differentiation Formula CV_NEWTON specifies a Newton iteration A pointer to the integrator problem memory is returned and stored in cvode_mem. */ cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON); if(check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1); /* Call CVodeMalloc to initialize the integrator memory: cvode_mem is the pointer to the integrator memory returned by CVodeCreate f is the user's right hand side function in y'=f(t,y) T0 is the initial time u is the initial dependent variable vector CV_SS specifies scalar relative and absolute tolerances reltol is the scalar relative tolerance &abstol is a pointer to the scalar absolute tolerance */ flag = CVodeMalloc(cvode_mem, f, T0, u, CV_SS, reltol, &abstol); if(check_flag(&flag, "CVodeMalloc", 1)) return(1); /* Set the pointer to user-defined data */ flag = CVodeSetFdata(cvode_mem, data); if(check_flag(&flag, "CVodeSetFdata", 1)) return(1); /* Call CVBand to specify the CVBAND band linear solver */ flag = CVBand(cvode_mem, NEQ, MY, MY); if(check_flag(&flag, "CVBand", 1)) return(1); /* Set the user-supplied Jacobian routine Jac and the pointer to the user-defined block data. */ flag = CVBandSetJacFn(cvode_mem, Jac, data); if(check_flag(&flag, "CVBandSetJacFn", 1)) return(1); /* In loop over output points: call CVode, print results, test for errors */ umax = N_VMaxNorm(u); PrintHeader(reltol, abstol, umax); for(iout=1, tout=T1; iout <= NOUT; iout++, tout += DTOUT) { flag = CVode(cvode_mem, tout, u, &t, CV_NORMAL); if(check_flag(&flag, "CVode", 1)) break; umax = N_VMaxNorm(u); flag = CVodeGetNumSteps(cvode_mem, &nst); check_flag(&flag, "CVodeGetNumSteps", 1); PrintOutput(t, umax, nst); } PrintFinalStats(cvode_mem); /* Print some final statistics */ N_VDestroy_Serial(u); /* Free the u vector */ CVodeFree(cvode_mem); /* Free the integrator memory */ free(data); /* Free the user data */ return(0); }
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 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); /* 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, f, T0, u, CV_SS, reltol, &abstol); 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); flag = CVSpilsSetPreconditioner(cvode_mem, Precond, PSolve, data); if(check_flag(&flag, "CVSpilsSetPreconditioner", 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); /* Set preconditioner setup and solve routines Precond and PSolve, and the pointer to the user-defined block data */ flag = CVSpilsSetPreconditioner(cvode_mem, Precond, PSolve, data); if(check_flag(&flag, "CVSpilsSetPreconditioner", 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); /* Set preconditioner setup and solve routines Precond and PSolve, and the pointer to the user-defined block data */ flag = CVSpilsSetPreconditioner(cvode_mem, Precond, PSolve, data); if(check_flag(&flag, "CVSpilsSetPreconditioner", 1)) return(1); break; } /* 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); }
int main() { realtype abstol, reltol, t, tout; N_Vector u; UserData data; void *bpdata; void *cvode_mem; int flag, ml, mu, iout, jpre; u = NULL; data = NULL; bpdata = cvode_mem = NULL; /* Allocate and initialize u, and set problem data and tolerances */ u = N_VNew_Serial(NEQ); if(check_flag((void *)u, "N_VNew_Serial", 0)) return(1); data = (UserData) malloc(sizeof *data); if(check_flag((void *)data, "malloc", 2)) return(1); InitUserData(data); SetInitialProfiles(u, data->dx, data->dy); abstol = ATOL; reltol = RTOL; /* Call CvodeCreate to create the solver memory CV_BDF specifies the Backward Differentiation Formula CV_NEWTON specifies a Newton iteration A pointer to the integrator memory is returned and stored in cvode_mem. */ cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON); if(check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1); /* Set the pointer to user-defined data */ flag = CVodeSetFdata(cvode_mem, data); if(check_flag(&flag, "CVodeSetFdata", 1)) return(1); /* Call CVodeMalloc to initialize the integrator memory: f is the user's right hand side function in u'=f(t,u) T0 is the initial time u is the initial dependent variable vector CV_SS specifies scalar relative and absolute tolerances reltol is the relative tolerance &abstol is a pointer to the scalar absolutetolerance */ flag = CVodeMalloc(cvode_mem, f, T0, u, CV_SS, reltol, &abstol); if(check_flag(&flag, "CVodeMalloc", 1)) return(1); /* Call CVBandPreAlloc to initialize band preconditioner */ ml = mu = 2; bpdata = CVBandPrecAlloc (cvode_mem, NEQ, mu, ml); if(check_flag((void *)bpdata, "CVBandPrecAlloc", 0)) return(1); /* Call CVBPSpgmr to specify the linear solver CVSPGMR with left preconditioning and the maximum Krylov dimension maxl */ flag = CVBPSpgmr(cvode_mem, PREC_LEFT, 0, bpdata); if(check_flag(&flag, "CVBPSpgmr", 1)) return(1); PrintIntro(mu, ml); /* Loop over jpre (= PREC_LEFT, PREC_RIGHT), and solve the problem */ for (jpre = PREC_LEFT; jpre <= PREC_RIGHT; jpre++) { /* On second run, re-initialize u, the solver, and CVSPGMR */ if (jpre == PREC_RIGHT) { SetInitialProfiles(u, data->dx, data->dy); flag = CVodeReInit(cvode_mem, f, T0, u, CV_SS, reltol, &abstol); if(check_flag(&flag, "CVodeReInit", 1)) return(1); flag = CVSpilsSetPrecType(cvode_mem, PREC_RIGHT); check_flag(&flag, "CVSpilsSetPrecType", 1); printf("\n\n-------------------------------------------------------"); printf("------------\n"); } printf("\n\nPreconditioner type is: jpre = %s\n\n", (jpre == PREC_LEFT) ? "PREC_LEFT" : "PREC_RIGHT"); /* In loop over output points, call CVode, print results, test for error */ for (iout = 1, tout = TWOHR; iout <= NOUT; iout++, tout += TWOHR) { flag = CVode(cvode_mem, tout, u, &t, CV_NORMAL); check_flag(&flag, "CVode", 1); PrintOutput(cvode_mem, u, t); if (flag != CV_SUCCESS) { break; } } /* Print final statistics */ PrintFinalStats(cvode_mem, bpdata); } /* End of jpre loop */ /* Free memory */ N_VDestroy_Serial(u); free(data); CVBandPrecFree(&bpdata); CVodeFree(&cvode_mem); return(0); }