/* Print final statistics contained in iopt */ static void PrintFinalStats(void *arkode_mem) { long int lenrw, leniw ; long int lenrwLS, leniwLS; long int lenrwBBDP, leniwBBDP, ngevalsBBDP; long int nst, nfe, nfi, nsetups, nni, ncfn, netf; long int nli, npe, nps, ncfl, nfeLS; int flag; flag = ARKodeGetWorkSpace(arkode_mem, &lenrw, &leniw); check_flag(&flag, "ARKodeGetWorkSpace", 1, 0); flag = ARKodeGetNumSteps(arkode_mem, &nst); check_flag(&flag, "ARKodeGetNumSteps", 1, 0); flag = ARKodeGetNumRhsEvals(arkode_mem, &nfe, &nfi); check_flag(&flag, "ARKodeGetNumRhsEvals", 1, 0); flag = ARKodeGetNumLinSolvSetups(arkode_mem, &nsetups); check_flag(&flag, "ARKodeGetNumLinSolvSetups", 1, 0); flag = ARKodeGetNumErrTestFails(arkode_mem, &netf); check_flag(&flag, "ARKodeGetNumErrTestFails", 1, 0); flag = ARKodeGetNumNonlinSolvIters(arkode_mem, &nni); check_flag(&flag, "ARKodeGetNumNonlinSolvIters", 1, 0); flag = ARKodeGetNumNonlinSolvConvFails(arkode_mem, &ncfn); check_flag(&flag, "ARKodeGetNumNonlinSolvConvFails", 1, 0); flag = ARKSpilsGetWorkSpace(arkode_mem, &lenrwLS, &leniwLS); check_flag(&flag, "ARKSpilsGetWorkSpace", 1, 0); flag = ARKSpilsGetNumLinIters(arkode_mem, &nli); check_flag(&flag, "ARKSpilsGetNumLinIters", 1, 0); flag = ARKSpilsGetNumPrecEvals(arkode_mem, &npe); check_flag(&flag, "ARKSpilsGetNumPrecEvals", 1, 0); flag = ARKSpilsGetNumPrecSolves(arkode_mem, &nps); check_flag(&flag, "ARKSpilsGetNumPrecSolves", 1, 0); flag = ARKSpilsGetNumConvFails(arkode_mem, &ncfl); check_flag(&flag, "ARKSpilsGetNumConvFails", 1, 0); flag = ARKSpilsGetNumRhsEvals(arkode_mem, &nfeLS); check_flag(&flag, "ARKSpilsGetNumRhsEvals", 1, 0); printf("\nFinal Statistics: \n\n"); printf("lenrw = %5ld leniw = %5ld\n", lenrw, leniw); printf("lenrwls = %5ld leniwls = %5ld\n", lenrwLS, leniwLS); printf("nst = %5ld nfe = %5ld\n", nst, nfe); printf("nfe = %5ld nfels = %5ld\n", nfi, nfeLS); printf("nni = %5ld nli = %5ld\n", nni, nli); printf("nsetups = %5ld netf = %5ld\n", nsetups, netf); printf("npe = %5ld nps = %5ld\n", npe, nps); printf("ncfn = %5ld ncfl = %5ld\n\n", ncfn, ncfl); flag = ARKBBDPrecGetWorkSpace(arkode_mem, &lenrwBBDP, &leniwBBDP); check_flag(&flag, "ARKBBDPrecGetWorkSpace", 1, 0); flag = ARKBBDPrecGetNumGfnEvals(arkode_mem, &ngevalsBBDP); check_flag(&flag, "ARKBBDPrecGetNumGfnEvals", 1, 0); printf("In ARKBBDPRE: real/integer local work space sizes = %ld, %ld\n", lenrwBBDP, leniwBBDP); printf(" no. flocal evals. = %ld\n",ngevalsBBDP); }
/* Main Program */ int main() { /* general problem parameters */ realtype T0 = RCONST(0.0); /* initial time */ realtype Tf = RCONST(10.0); /* final time */ realtype dTout = RCONST(1.0); /* time between outputs */ long int NEQ = 3; /* number of dependent vars. */ int Nt = ceil(Tf/dTout); /* number of output times */ int test = 2; /* test problem to run */ realtype reltol = 1.0e-6; /* tolerances */ realtype abstol = 1.0e-10; realtype a, b, ep, u0, v0, w0; /* general problem variables */ int flag; /* reusable error-checking flag */ N_Vector y = NULL; /* empty vector for storing solution */ void *arkode_mem = NULL; /* empty ARKode memory structure */ realtype rdata[3]; FILE *UFID; realtype t, tout; int iout; long int nst, nst_a, nfe, nfi, nsetups, nje, nfeLS, nni, ncfn, netf; /* set up the test problem according to the desired test */ if (test == 1) { u0 = RCONST(3.9); v0 = RCONST(1.1); w0 = RCONST(2.8); a = RCONST(1.2); b = RCONST(2.5); ep = RCONST(1.0e-5); } else if (test == 3) { u0 = RCONST(3.0); v0 = RCONST(3.0); w0 = RCONST(3.5); a = RCONST(0.5); b = RCONST(3.0); ep = RCONST(5.0e-4); } else { u0 = RCONST(1.2); v0 = RCONST(3.1); w0 = RCONST(3.0); a = RCONST(1.0); b = RCONST(3.5); ep = RCONST(5.0e-6); } /* Initial problem output */ printf("\nBrusselator ODE test problem:\n"); printf(" initial conditions: u0 = %g, v0 = %g, w0 = %g\n",u0,v0,w0); printf(" problem parameters: a = %g, b = %g, ep = %g\n",a,b,ep); printf(" reltol = %.1e, abstol = %.1e\n\n",reltol,abstol); /* Initialize data structures */ rdata[0] = a; /* set user data */ rdata[1] = b; rdata[2] = ep; y = N_VNew_Serial(NEQ); /* Create serial vector for solution */ if (check_flag((void *)y, "N_VNew_Serial", 0)) return 1; NV_Ith_S(y,0) = u0; /* Set initial conditions */ NV_Ith_S(y,1) = v0; NV_Ith_S(y,2) = w0; arkode_mem = ARKodeCreate(); /* Create the solver memory */ if (check_flag((void *)arkode_mem, "ARKodeCreate", 0)) return 1; /* Call ARKodeInit to initialize the integrator memory and specify the hand-side side function in y'=f(t,y), the inital time T0, and the initial dependent variable vector y. Note: since this problem is fully implicit, we set f_E to NULL and f_I to f. */ flag = ARKodeInit(arkode_mem, NULL, f, T0, y); if (check_flag(&flag, "ARKodeInit", 1)) return 1; /* Set routines */ flag = ARKodeSetUserData(arkode_mem, (void *) rdata); /* Pass rdata to user functions */ if (check_flag(&flag, "ARKodeSetUserData", 1)) return 1; flag = ARKodeSStolerances(arkode_mem, reltol, abstol); /* Specify tolerances */ if (check_flag(&flag, "ARKodeSStolerances", 1)) return 1; /* Linear solver specification */ flag = ARKDense(arkode_mem, NEQ); /* Specify dense linear solver */ if (check_flag(&flag, "ARKDense", 1)) return 1; flag = ARKDlsSetDenseJacFn(arkode_mem, Jac); /* Set Jacobian routine */ if (check_flag(&flag, "ARKDlsSetDenseJacFn", 1)) return 1; /* Open output stream for results, output comment line */ UFID = fopen("solution.txt","w"); fprintf(UFID,"# t u v w\n"); /* output initial condition to disk */ fprintf(UFID," %.16e %.16e %.16e %.16e\n", T0, NV_Ith_S(y,0), NV_Ith_S(y,1), NV_Ith_S(y,2)); /* Main time-stepping loop: calls ARKode to perform the integration, then prints results. Stops when the final time has been reached */ t = T0; tout = T0+dTout; printf(" t u v w\n"); printf(" -------------------------------------------\n"); for (iout=0; iout<Nt; iout++) { flag = ARKode(arkode_mem, tout, y, &t, ARK_NORMAL); /* call integrator */ if (check_flag(&flag, "ARKode", 1)) break; printf(" %10.6f %10.6f %10.6f %10.6f\n", /* access/print solution */ t, NV_Ith_S(y,0), NV_Ith_S(y,1), NV_Ith_S(y,2)); fprintf(UFID," %.16e %.16e %.16e %.16e\n", t, NV_Ith_S(y,0), NV_Ith_S(y,1), NV_Ith_S(y,2)); if (flag >= 0) { /* successful solve: update time */ tout += dTout; tout = (tout > Tf) ? Tf : tout; } else { /* unsuccessful solve: break */ fprintf(stderr,"Solver failure, stopping integration\n"); break; } } printf(" -------------------------------------------\n"); fclose(UFID); /* Print some final statistics */ flag = ARKodeGetNumSteps(arkode_mem, &nst); check_flag(&flag, "ARKodeGetNumSteps", 1); flag = ARKodeGetNumStepAttempts(arkode_mem, &nst_a); check_flag(&flag, "ARKodeGetNumStepAttempts", 1); flag = ARKodeGetNumRhsEvals(arkode_mem, &nfe, &nfi); check_flag(&flag, "ARKodeGetNumRhsEvals", 1); flag = ARKodeGetNumLinSolvSetups(arkode_mem, &nsetups); check_flag(&flag, "ARKodeGetNumLinSolvSetups", 1); flag = ARKodeGetNumErrTestFails(arkode_mem, &netf); check_flag(&flag, "ARKodeGetNumErrTestFails", 1); flag = ARKodeGetNumNonlinSolvIters(arkode_mem, &nni); check_flag(&flag, "ARKodeGetNumNonlinSolvIters", 1); flag = ARKodeGetNumNonlinSolvConvFails(arkode_mem, &ncfn); check_flag(&flag, "ARKodeGetNumNonlinSolvConvFails", 1); flag = ARKDlsGetNumJacEvals(arkode_mem, &nje); check_flag(&flag, "ARKDlsGetNumJacEvals", 1); flag = ARKDlsGetNumRhsEvals(arkode_mem, &nfeLS); check_flag(&flag, "ARKDlsGetNumRhsEvals", 1); printf("\nFinal Solver Statistics:\n"); printf(" Internal solver steps = %li (attempted = %li)\n", nst, nst_a); printf(" Total RHS evals: Fe = %li, Fi = %li\n", nfe, nfi); printf(" Total linear solver setups = %li\n", nsetups); printf(" Total RHS evals for setting up the linear system = %li\n", nfeLS); printf(" Total number of Jacobian evaluations = %li\n", nje); printf(" Total number of Newton iterations = %li\n", nni); printf(" Total number of linear solver convergence failures = %li\n", ncfn); printf(" Total number of error test failures = %li\n\n", netf); /* Clean up and return with successful completion */ N_VDestroy_Serial(y); /* Free y vector */ ARKodeFree(&arkode_mem); /* Free integrator memory */ return 0; }
static void PrintFinalStats(void *arkode_mem) { long int lenrw, leniw ; long int lenrwLS, leniwLS; long int nst, nfe, nfi, nsetups, nni, ncfn, netf; long int nli, npe, nps, ncfl, nfeLS; int flag; realtype avdim; flag = ARKodeGetWorkSpace(arkode_mem, &lenrw, &leniw); check_flag(&flag, "ARKodeGetWorkSpace", 1); flag = ARKodeGetNumSteps(arkode_mem, &nst); check_flag(&flag, "ARKodeGetNumSteps", 1); flag = ARKodeGetNumRhsEvals(arkode_mem, &nfe, &nfi); check_flag(&flag, "ARKodeGetNumRhsEvals", 1); flag = ARKodeGetNumLinSolvSetups(arkode_mem, &nsetups); check_flag(&flag, "ARKodeGetNumLinSolvSetups", 1); flag = ARKodeGetNumErrTestFails(arkode_mem, &netf); check_flag(&flag, "ARKodeGetNumErrTestFails", 1); flag = ARKodeGetNumNonlinSolvIters(arkode_mem, &nni); check_flag(&flag, "ARKodeGetNumNonlinSolvIters", 1); flag = ARKodeGetNumNonlinSolvConvFails(arkode_mem, &ncfn); check_flag(&flag, "ARKodeGetNumNonlinSolvConvFails", 1); flag = ARKSpilsGetWorkSpace(arkode_mem, &lenrwLS, &leniwLS); check_flag(&flag, "ARKSpilsGetWorkSpace", 1); flag = ARKSpilsGetNumLinIters(arkode_mem, &nli); check_flag(&flag, "ARKSpilsGetNumLinIters", 1); flag = ARKSpilsGetNumPrecEvals(arkode_mem, &npe); check_flag(&flag, "ARKSpilsGetNumPrecEvals", 1); flag = ARKSpilsGetNumPrecSolves(arkode_mem, &nps); check_flag(&flag, "ARKSpilsGetNumPrecSolves", 1); flag = ARKSpilsGetNumConvFails(arkode_mem, &ncfl); check_flag(&flag, "ARKSpilsGetNumConvFails", 1); flag = ARKSpilsGetNumRhsEvals(arkode_mem, &nfeLS); check_flag(&flag, "ARKSpilsGetNumRhsEvals", 1); printf("\n\n Final statistics for this run:\n\n"); printf(" ARKode real workspace length = %4ld \n", lenrw); printf(" ARKode integer workspace length = %4ld \n", leniw); printf(" ARKSPGMR real workspace length = %4ld \n", lenrwLS); printf(" ARKSPGMR integer workspace length = %4ld \n", leniwLS); printf(" Number of steps = %4ld \n", nst); printf(" Number of f-s (explicit) = %4ld \n", nfe); printf(" Number of f-s (implicit) = %4ld \n", nfi); printf(" Number of f-s (SPGMR) = %4ld \n", nfeLS); printf(" Number of f-s (TOTAL) = %4ld \n", nfe + nfeLS); printf(" Number of setups = %4ld \n", nsetups); printf(" Number of nonlinear iterations = %4ld \n", nni); printf(" Number of linear iterations = %4ld \n", nli); printf(" Number of preconditioner evaluations = %4ld \n", npe); printf(" Number of preconditioner solves = %4ld \n", nps); printf(" Number of error test failures = %4ld \n", netf); printf(" Number of nonlinear conv. failures = %4ld \n", ncfn); printf(" Number of linear convergence failures = %4ld \n", ncfl); avdim = (nni > 0) ? ((realtype)nli)/((realtype)nni) : ZERO; #if defined(SUNDIALS_EXTENDED_PRECISION) printf(" Average Krylov subspace dimension = %.3Lf \n", avdim); #else printf(" Average Krylov subspace dimension = %.3f \n", avdim); #endif printf("\n\n--------------------------------------------------------------"); printf("--------------\n"); printf( "--------------------------------------------------------------"); printf("--------------\n"); }
/* Main Program */ int main() { /* general problem parameters */ realtype T0 = RCONST(0.0); /* initial time */ realtype Tf = RCONST(10.0); /* final time */ int Nt = 100; /* total number of output times */ int Nvar = 3; /* number of solution fields */ UserData udata = NULL; realtype *data; long int N = 201; /* spatial mesh size */ realtype a = 0.6; /* problem parameters */ realtype b = 2.0; realtype du = 0.025; realtype dv = 0.025; realtype dw = 0.025; realtype ep = 1.0e-5; /* stiffness parameter */ realtype reltol = 1.0e-6; /* tolerances */ realtype abstol = 1.0e-10; long int NEQ, i; /* general problem variables */ int flag; /* reusable error-checking flag */ N_Vector y = NULL; /* empty vector for storing solution */ N_Vector umask = NULL; /* empty mask vectors for viewing solution components */ N_Vector vmask = NULL; N_Vector wmask = NULL; void *arkode_mem = NULL; /* empty ARKode memory structure */ realtype pi, t, dTout, tout, u, v, w; FILE *FID, *UFID, *VFID, *WFID; int iout; long int nst, nst_a, nfe, nfi, nsetups, nje, nfeLS, nni, ncfn, netf; /* allocate udata structure */ udata = (UserData) malloc(sizeof(*udata)); if (check_flag((void *) udata, "malloc", 2)) return 1; /* store the inputs in the UserData structure */ udata->N = N; udata->a = a; udata->b = b; udata->du = du; udata->dv = dv; udata->dw = dw; udata->ep = ep; /* set total allocated vector length */ NEQ = Nvar*udata->N; /* Initial problem output */ printf("\n1D Brusselator PDE test problem:\n"); printf(" N = %li, NEQ = %li\n", udata->N, NEQ); printf(" problem parameters: a = %g, b = %g, ep = %g\n", udata->a, udata->b, udata->ep); printf(" diffusion coefficients: du = %g, dv = %g, dw = %g\n", udata->du, udata->dv, udata->dw); printf(" reltol = %.1e, abstol = %.1e\n\n", reltol, abstol); /* Initialize data structures */ y = N_VNew_Serial(NEQ); /* Create serial vector for solution */ if (check_flag((void *)y, "N_VNew_Serial", 0)) return 1; udata->dx = RCONST(1.0)/(N-1); /* set spatial mesh spacing */ data = N_VGetArrayPointer(y); /* Access data array for new NVector y */ if (check_flag((void *)data, "N_VGetArrayPointer", 0)) return 1; umask = N_VNew_Serial(NEQ); /* Create serial vector masks */ if (check_flag((void *)umask, "N_VNew_Serial", 0)) return 1; vmask = N_VNew_Serial(NEQ); if (check_flag((void *)vmask, "N_VNew_Serial", 0)) return 1; wmask = N_VNew_Serial(NEQ); if (check_flag((void *)wmask, "N_VNew_Serial", 0)) return 1; /* Set initial conditions into y */ pi = RCONST(4.0)*atan(RCONST(1.0)); for (i=0; i<N; i++) { data[IDX(i,0)] = a + RCONST(0.1)*sin(pi*i*udata->dx); /* u */ data[IDX(i,1)] = b/a + RCONST(0.1)*sin(pi*i*udata->dx); /* v */ data[IDX(i,2)] = b + RCONST(0.1)*sin(pi*i*udata->dx); /* w */ } /* Set mask array values for each solution component */ N_VConst(0.0, umask); data = N_VGetArrayPointer(umask); if (check_flag((void *)data, "N_VGetArrayPointer", 0)) return 1; for (i=0; i<N; i++) data[IDX(i,0)] = RCONST(1.0); N_VConst(0.0, vmask); data = N_VGetArrayPointer(vmask); if (check_flag((void *)data, "N_VGetArrayPointer", 0)) return 1; for (i=0; i<N; i++) data[IDX(i,1)] = RCONST(1.0); N_VConst(0.0, wmask); data = N_VGetArrayPointer(wmask); if (check_flag((void *)data, "N_VGetArrayPointer", 0)) return 1; for (i=0; i<N; i++) data[IDX(i,2)] = RCONST(1.0); /* Create the solver memory */ arkode_mem = ARKodeCreate(); if (check_flag((void *)arkode_mem, "ARKodeCreate", 0)) return 1; /* Call ARKodeInit to initialize the integrator memory and specify the right-hand side function in y'=f(t,y), the inital time T0, and the initial dependent variable vector y. Note: since this problem is fully implicit, we set f_E to NULL and f_I to f. */ flag = ARKodeInit(arkode_mem, NULL, f, T0, y); if (check_flag(&flag, "ARKodeInit", 1)) return 1; /* Set routines */ flag = ARKodeSetUserData(arkode_mem, (void *) udata); /* Pass udata to user functions */ if (check_flag(&flag, "ARKodeSetUserData", 1)) return 1; flag = ARKodeSStolerances(arkode_mem, reltol, abstol); /* Specify tolerances */ if (check_flag(&flag, "ARKodeSStolerances", 1)) return 1; /* Linear solver specification */ flag = ARKBand(arkode_mem, NEQ, 4, 4); /* Specify the band linear solver */ if (check_flag(&flag, "ARKBand", 1)) return 1; flag = ARKDlsSetBandJacFn(arkode_mem, Jac); /* Set the Jacobian routine */ if (check_flag(&flag, "ARKDlsSetBandJacFn", 1)) return 1; /* output spatial mesh to disk */ FID = fopen("bruss_mesh.txt","w"); for (i=0; i<N; i++) fprintf(FID," %.16e\n", udata->dx*i); fclose(FID); /* Open output streams for results, access data array */ UFID=fopen("bruss_u.txt","w"); VFID=fopen("bruss_v.txt","w"); WFID=fopen("bruss_w.txt","w"); /* output initial condition to disk */ data = N_VGetArrayPointer(y); if (check_flag((void *)data, "N_VGetArrayPointer", 0)) return 1; for (i=0; i<N; i++) fprintf(UFID," %.16e", data[IDX(i,0)]); for (i=0; i<N; i++) fprintf(VFID," %.16e", data[IDX(i,1)]); for (i=0; i<N; i++) fprintf(WFID," %.16e", data[IDX(i,2)]); fprintf(UFID,"\n"); fprintf(VFID,"\n"); fprintf(WFID,"\n"); /* Main time-stepping loop: calls ARKode to perform the integration, then prints results. Stops when the final time has been reached */ t = T0; dTout = (Tf-T0)/Nt; tout = T0+dTout; printf(" t ||u||_rms ||v||_rms ||w||_rms\n"); printf(" ----------------------------------------------\n"); for (iout=0; iout<Nt; iout++) { flag = ARKode(arkode_mem, tout, y, &t, ARK_NORMAL); /* call integrator */ if (check_flag(&flag, "ARKode", 1)) break; u = N_VWL2Norm(y,umask); /* access/print solution statistics */ u = SUNRsqrt(u*u/N); v = N_VWL2Norm(y,vmask); v = SUNRsqrt(v*v/N); w = N_VWL2Norm(y,wmask); w = SUNRsqrt(w*w/N); printf(" %10.6f %10.6f %10.6f %10.6f\n", t, u, v, w); if (flag >= 0) { /* successful solve: update output time */ tout += dTout; tout = (tout > Tf) ? Tf : tout; } else { /* unsuccessful solve: break */ fprintf(stderr,"Solver failure, stopping integration\n"); break; } /* output results to disk */ for (i=0; i<N; i++) fprintf(UFID," %.16e", data[IDX(i,0)]); for (i=0; i<N; i++) fprintf(VFID," %.16e", data[IDX(i,1)]); for (i=0; i<N; i++) fprintf(WFID," %.16e", data[IDX(i,2)]); fprintf(UFID,"\n"); fprintf(VFID,"\n"); fprintf(WFID,"\n"); } printf(" ----------------------------------------------\n"); fclose(UFID); fclose(VFID); fclose(WFID); /* Print some final statistics */ flag = ARKodeGetNumSteps(arkode_mem, &nst); check_flag(&flag, "ARKodeGetNumSteps", 1); flag = ARKodeGetNumStepAttempts(arkode_mem, &nst_a); check_flag(&flag, "ARKodeGetNumStepAttempts", 1); flag = ARKodeGetNumRhsEvals(arkode_mem, &nfe, &nfi); check_flag(&flag, "ARKodeGetNumRhsEvals", 1); flag = ARKodeGetNumLinSolvSetups(arkode_mem, &nsetups); check_flag(&flag, "ARKodeGetNumLinSolvSetups", 1); flag = ARKodeGetNumErrTestFails(arkode_mem, &netf); check_flag(&flag, "ARKodeGetNumErrTestFails", 1); flag = ARKodeGetNumNonlinSolvIters(arkode_mem, &nni); check_flag(&flag, "ARKodeGetNumNonlinSolvIters", 1); flag = ARKodeGetNumNonlinSolvConvFails(arkode_mem, &ncfn); check_flag(&flag, "ARKodeGetNumNonlinSolvConvFails", 1); flag = ARKDlsGetNumJacEvals(arkode_mem, &nje); check_flag(&flag, "ARKDlsGetNumJacEvals", 1); flag = ARKDlsGetNumRhsEvals(arkode_mem, &nfeLS); check_flag(&flag, "ARKDlsGetNumRhsEvals", 1); printf("\nFinal Solver Statistics:\n"); printf(" Internal solver steps = %li (attempted = %li)\n", nst, nst_a); printf(" Total RHS evals: Fe = %li, Fi = %li\n", nfe, nfi); printf(" Total linear solver setups = %li\n", nsetups); printf(" Total RHS evals for setting up the linear system = %li\n", nfeLS); printf(" Total number of Jacobian evaluations = %li\n", nje); printf(" Total number of Newton iterations = %li\n", nni); printf(" Total number of nonlinear solver convergence failures = %li\n", ncfn); printf(" Total number of error test failures = %li\n\n", netf); /* Clean up and return with successful completion */ N_VDestroy_Serial(y); /* Free vectors */ N_VDestroy_Serial(umask); N_VDestroy_Serial(vmask); N_VDestroy_Serial(wmask); free(udata); /* Free user data */ ARKodeFree(&arkode_mem); /* Free integrator memory */ return 0; }
/* Main Program */ int main() { /* general problem parameters */ realtype T0 = RCONST(0.0); /* initial time */ realtype T1 = RCONST(0.4); /* first output time */ realtype TMult = RCONST(10.0); /* output time multiplication factor */ int Nt = 12; /* total number of output times */ long int NEQ = 3; /* number of dependent vars. */ realtype reltol; int rootsfound[2]; long int nst, nst_a, nfe, nfi, nsetups; long int nje, nfeLS, nni, ncfn, netf, nge; int flag, rtflag; /* reusable error-checking flags */ FILE *UFID; realtype t, tout; int iout; /* general problem variables */ N_Vector y = NULL; /* empty vector for storing solution */ N_Vector atols = NULL; /* empty vector for absolute tolerances */ void *arkode_mem = NULL; /* empty ARKode memory structure */ /* set up the initial conditions */ realtype u0 = RCONST(1.0); realtype v0 = RCONST(0.0); realtype w0 = RCONST(0.0); /* Initial problem output */ printf("\nRobertson ODE test problem (with rootfinding):\n"); printf(" initial conditions: u0 = %g, v0 = %g, w0 = %g\n",u0,v0,w0); /* Initialize data structures */ y = N_VNew_Serial(NEQ); /* Create serial vector for solution */ if (check_flag((void *) y, "N_VNew_Serial", 0)) return 1; atols = N_VNew_Serial(NEQ); /* Create serial vector absolute tolerances */ if (check_flag((void *) atols, "N_VNew_Serial", 0)) return 1; NV_Ith_S(y,0) = u0; /* Set initial conditions into y */ NV_Ith_S(y,1) = v0; NV_Ith_S(y,2) = w0; arkode_mem = ARKodeCreate(); /* Create the solver memory */ if (check_flag((void *)arkode_mem, "ARKodeCreate", 0)) return 1; /* Call ARKodeInit to initialize the integrator memory and specify the hand-side side function in y'=f(t,y), the inital time T0, and the initial dependent variable vector y. Note: since this problem is fully implicit, we set f_E to NULL and f_I to f. */ flag = ARKodeInit(arkode_mem, NULL, f, T0, y); if (check_flag(&flag, "ARKodeInit", 1)) return 1; /* Set tolerances */ reltol = RCONST(1.0e-4); NV_Ith_S(atols,0) = RCONST(1.0e-8); NV_Ith_S(atols,1) = RCONST(1.0e-11); NV_Ith_S(atols,2) = RCONST(1.0e-8); /* Set routines */ flag = ARKodeSetMaxErrTestFails(arkode_mem, 20); /* Increase max error test fails */ if (check_flag(&flag, "ARKodeSetMaxErrTestFails", 1)) return 1; flag = ARKodeSetMaxNonlinIters(arkode_mem, 8); /* Increase max nonlinear iterations */ if (check_flag(&flag, "ARKodeSetMaxNonlinIters", 1)) return 1; flag = ARKodeSetNonlinConvCoef(arkode_mem, 1.e-7); /* Update nonlinear solver convergence coeff. */ if (check_flag(&flag, "ARKodeSetNonlinConvCoef", 1)) return 1; flag = ARKodeSetMaxNumSteps(arkode_mem, 100000); /* Increase max number of steps */ if (check_flag(&flag, "ARKodeSetMaxNumSteps", 1)) return 1; flag = ARKodeSVtolerances(arkode_mem, reltol, atols); /* Specify tolerances */ if (check_flag(&flag, "ARKodeSStolerances", 1)) return 1; /* Specify the root-finding function, having 2 equations */ flag = ARKodeRootInit(arkode_mem, 2, g); if (check_flag(&flag, "ARKodeRootInit", 1)) return 1; /* Linear solver specification */ flag = ARKDense(arkode_mem, NEQ); /* Specify dense linear solver */ if (check_flag(&flag, "ARKDense", 1)) return 1; flag = ARKDlsSetDenseJacFn(arkode_mem, Jac); /* Set the Jacobian routine */ if (check_flag(&flag, "ARKDlsSetDenseJacFn", 1)) return 1; /* Open output stream for results, output comment line */ UFID = fopen("solution.txt","w"); fprintf(UFID,"# t u v w\n"); /* output initial condition to disk */ fprintf(UFID," %.16e %.16e %.16e %.16e\n", T0, NV_Ith_S(y,0), NV_Ith_S(y,1), NV_Ith_S(y,2)); /* Main time-stepping loop: calls ARKode to perform the integration, then prints results. Stops when the final time has been reached */ t = T0; printf(" t u v w\n"); printf(" -----------------------------------------------------\n"); printf(" %12.5e %12.5e %12.5e %12.5e\n", t, NV_Ith_S(y,0), NV_Ith_S(y,1), NV_Ith_S(y,2)); tout = T1; iout = 0; while(1) { flag = ARKode(arkode_mem, tout, y, &t, ARK_NORMAL); /* call integrator */ if (check_flag(&flag, "ARKode", 1)) break; printf(" %12.5e %12.5e %12.5e %12.5e\n", t, /* access/print solution */ NV_Ith_S(y,0), NV_Ith_S(y,1), NV_Ith_S(y,2)); fprintf(UFID," %.16e %.16e %.16e %.16e\n", t, NV_Ith_S(y,0), NV_Ith_S(y,1), NV_Ith_S(y,2)); if (flag == ARK_ROOT_RETURN) { /* check if a root was found */ rtflag = ARKodeGetRootInfo(arkode_mem, rootsfound); if (check_flag(&rtflag, "ARKodeGetRootInfo", 1)) return 1; printf(" rootsfound[] = %3d %3d\n", rootsfound[0], rootsfound[1]); } if (flag >= 0) { /* successful solve: update output time */ iout++; tout *= TMult; } else { /* unsuccessful solve: break */ fprintf(stderr,"Solver failure, stopping integration\n"); break; } if (iout == Nt) break; /* stop after enough outputs */ } printf(" -----------------------------------------------------\n"); fclose(UFID); /* Print some final statistics */ flag = ARKodeGetNumSteps(arkode_mem, &nst); check_flag(&flag, "ARKodeGetNumSteps", 1); flag = ARKodeGetNumStepAttempts(arkode_mem, &nst_a); check_flag(&flag, "ARKodeGetNumStepAttempts", 1); flag = ARKodeGetNumRhsEvals(arkode_mem, &nfe, &nfi); check_flag(&flag, "ARKodeGetNumRhsEvals", 1); flag = ARKodeGetNumLinSolvSetups(arkode_mem, &nsetups); check_flag(&flag, "ARKodeGetNumLinSolvSetups", 1); flag = ARKodeGetNumErrTestFails(arkode_mem, &netf); check_flag(&flag, "ARKodeGetNumErrTestFails", 1); flag = ARKodeGetNumNonlinSolvIters(arkode_mem, &nni); check_flag(&flag, "ARKodeGetNumNonlinSolvIters", 1); flag = ARKodeGetNumNonlinSolvConvFails(arkode_mem, &ncfn); check_flag(&flag, "ARKodeGetNumNonlinSolvConvFails", 1); flag = ARKDlsGetNumJacEvals(arkode_mem, &nje); check_flag(&flag, "ARKDlsGetNumJacEvals", 1); flag = ARKDlsGetNumRhsEvals(arkode_mem, &nfeLS); check_flag(&flag, "ARKDlsGetNumRhsEvals", 1); flag = ARKodeGetNumGEvals(arkode_mem, &nge); check_flag(&flag, "ARKodeGetNumGEvals", 1); printf("\nFinal Solver Statistics:\n"); printf(" Internal solver steps = %li (attempted = %li)\n", nst, nst_a); printf(" Total RHS evals: Fe = %li, Fi = %li\n", nfe, nfi); printf(" Total linear solver setups = %li\n", nsetups); printf(" Total RHS evals for setting up the linear system = %li\n", nfeLS); printf(" Total number of Jacobian evaluations = %li\n", nje); printf(" Total number of Newton iterations = %li\n", nni); printf(" Total root-function g evals = %li\n", nge); printf(" Total number of nonlinear solver convergence failures = %li\n", ncfn); printf(" Total number of error test failures = %li\n", netf); /* Clean up and return with successful completion */ N_VDestroy_Serial(y); /* Free y vector */ ARKodeFree(&arkode_mem); /* Free integrator memory */ return 0; }