int main() { M_Env machEnv; realtype abstol, reltol, t, tout, ropt[OPT_SIZE]; long int iopt[OPT_SIZE]; N_Vector y; UserData data; CVBandPreData bpdata; void *cvode_mem; int ml, mu, iout, flag, jpre; /* Initialize serial machine environment */ machEnv = M_EnvInit_Serial(NEQ); /* Allocate and initialize y, and set problem data and tolerances */ y = N_VNew(NEQ, machEnv); data = (UserData) malloc(sizeof *data); InitUserData(data); SetInitialProfiles(y, data->dx, data->dz); abstol = ATOL; reltol = RTOL; /* Call CVodeMalloc to initialize CVODE: NEQ is the problem size = number of equations f is the user's right hand side function in y'=f(t,y) T0 is the initial time y is the initial dependent variable vector BDF specifies the Backward Differentiation Formula NEWTON specifies a Newton iteration SS specifies scalar relative and absolute tolerances &reltol and &abstol are pointers to the scalar tolerances data is the pointer to the user-defined block of coefficients FALSE indicates there are no optional inputs in iopt and ropt iopt and ropt arrays communicate optional integer and real input/output A pointer to CVODE problem memory is returned and stored in cvode_mem. */ cvode_mem = CVodeMalloc(NEQ, f, T0, y, BDF, NEWTON, SS, &reltol, &abstol, data, NULL, FALSE, iopt, ropt, machEnv); if (cvode_mem == NULL) { printf("CVodeMalloc failed."); return(1); } /* Call CVBandPreAlloc to initialize band preconditioner */ ml = mu = 2; bpdata = CVBandPreAlloc (NEQ, f, data, mu, ml, cvode_mem); /* Call CVSpgmr to specify the CVODE linear solver CVSPGMR with left preconditioning, modified Gram-Schmidt orthogonalization, default values for the maximum Krylov dimension maxl and the tolerance parameter delt, preconditioner setup and solve routines CVBandPrecond and CVBandPSolve, the pointer to the user-defined block data, and NULL for the user jtimes routine and Jacobian data pointer. */ flag = CVSpgmr(cvode_mem, LEFT, MODIFIED_GS, 0, 0.0, CVBandPrecond, CVBandPSolve, bpdata, NULL, NULL); if (flag != SUCCESS) { printf("CVSpgmr failed."); return(1); } printf("2-species diurnal advection-diffusion problem, %d by %d mesh\n", MX, MZ); printf("SPGMR solver; band preconditioner; mu = %d, ml = %d\n\n", mu, ml); /* Loop over jpre (= LEFT, RIGHT), and solve the problem */ for (jpre = LEFT; jpre <= RIGHT; jpre++) { /* On second run, re-initialize y, CVODE, CVBANDPRE, and CVSPGMR */ if (jpre == RIGHT) { SetInitialProfiles(y, data->dx, data->dz); flag = CVReInit(cvode_mem, f, T0, y, BDF, NEWTON, SS, &reltol, &abstol, data, NULL, FALSE, iopt, ropt, machEnv); if (flag != SUCCESS) { printf("CVReInit failed."); return(1); } flag = CVReInitBandPre(bpdata, NEQ, f, data, mu, ml); flag = CVReInitSpgmr(cvode_mem, jpre, MODIFIED_GS, 0, 0.0, CVBandPrecond, CVBandPSolve, bpdata, NULL, NULL); if (flag != SUCCESS) { printf("CVReInitSpgmr failed."); return(1); } printf("\n\n-------------------------------------------------------"); printf("------------\n"); } printf("\n\nPreconditioner type is: jpre = %s\n\n", (jpre == LEFT) ? "LEFT" : "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, y, &t, NORMAL); PrintOutput(iopt, ropt, y, t); if (flag != SUCCESS) { printf("CVode failed, flag = %d.\n", flag); break; } } /* Print final statistics */ PrintFinalStats(iopt); } /* End of jpre loop */ /* Free memory */ N_VFree(y); free(data); CVBandPreFree(bpdata); CVodeFree(cvode_mem); M_EnvFree_Serial(machEnv); return(0); }
/* Main Function */ int main(int argc, char *argv[]) { char *filename = "shalehills"; /* Input file name prefix */ char *StateFile; /* Output file name string */ char *FluxFile; char *ETISFile; char *QFile; Model_Data mData; /* Model Data */ Control_Data cData; /* Solver Control Data */ N_Vector CV_Y; /* State Variables Vector */ M_Env machEnv; /* Machine Environments */ realtype ropt[OPT_SIZE]; /* Optional real type and integer type */ long int iopt[OPT_SIZE]; /* vecter for Message Passing to solver */ void *cvode_mem; /* Model Data Pointer */ int flag; /* flag to test return value */ FILE *res_state_file; /* Output file for States */ FILE *res_flux_file; /* Output file for Flux */ FILE *res_etis_file; /* Output file for ET and IS */ FILE *res_q_file; int N; /* Problem size */ int i; /* loop index */ realtype t; /* simulation time */ realtype NextPtr, StepSize; /* stress period & step size */ clock_t start, end_r, end_s; /* system clock at points */ realtype cputime_r, cputime_s; /* for duration in realtype */ /* allocate memory for model data structure */ mData = (Model_Data)malloc(sizeof *mData); start = clock(); /* get user specified file name in command line */ if(argc >= 2) { filename = (char *)malloc(strlen(argv[1])*sizeof(char)); strcpy(filename, argv[1]); } printf("\nBelt up! PIHM 1.0 is starting ... \n"); /* read in 7 input files with "filename" as prefix */ read_alloc(filename, mData, &cData); /* problem size */ N = 3*mData->NumEle + mData->NumRiv; /* initial machine environment variable */ machEnv = M_EnvInit_Serial(N); /* initial state variable depending on machine*/ CV_Y = N_VNew(N, machEnv); /* initialize mode data structure */ initialize(filename, mData, &cData, CV_Y); if(cData.Debug == 1) {PrintModelData(mData);} end_r = clock(); cputime_r = (end_r - start)/(realtype)CLOCKS_PER_SEC; printf("\nSolving ODE system ... \n"); /* initial control parameter for CVODE solver. Otherwise the default value by C could cause problems. */ for(i=0; i<OPT_SIZE; i++) { ropt[i] = 0.0; iopt[i] = 0; } /* set user specified control parameter */ ropt[H0] = cData.InitStep; ropt[HMAX] = cData.MaxStep; /* allocate memory for solver */ cvode_mem = CVodeMalloc(N, f, cData.StartTime, CV_Y, BDF, NEWTON, SS, &cData.reltol, &cData.abstol, mData, NULL, TRUE, iopt, ropt, machEnv); if(cvode_mem == NULL) {printf("CVodeMalloc failed. \n"); return(1);} if(cData.Solver == 1) { /* using dense direct solver */ flag = CVDense(cvode_mem, NULL, NULL); if(flag != SUCCESS) {printf("CVDense failed. \n"); return(1);} } else if(cData.Solver == 2) { /* using iterative solver */ flag = CVSpgmr(cvode_mem, NONE, cData.GSType, cData.MaxK, cData.delt, NULL, NULL, mData, NULL, NULL); if (flag != SUCCESS) {printf("CVSpgmr failed."); return(1);} } /*allocate and copy to get output file name */ StateFile = (char *)malloc((strlen(filename)+4)*sizeof(char)); strcpy(StateFile, filename); FluxFile = (char *)malloc((strlen(filename)+5)*sizeof(char)); strcpy(FluxFile, filename); ETISFile = (char *)malloc((strlen(filename)+5)*sizeof(char)); strcpy(ETISFile, filename); QFile = (char *)malloc((strlen(filename)+2)*sizeof(char)); strcpy(QFile, filename); /* open output file */ if (cData.res_out == 1) {res_state_file = fopen(strcat(StateFile, ".res"), "w");} if (cData.flux_out == 1) {res_flux_file = fopen(strcat(FluxFile, ".flux"), "w");} if (cData.etis_out == 1) {res_etis_file = fopen(strcat(ETISFile, ".etis"), "w");} if (cData.q_out == 1) {res_q_file = fopen(strcat(QFile, ".q"), "w");} /* print header of output file */ if (cData.res_out == 1) {FPrintYheader(res_state_file, mData);} if (cData.etis_out == 1) {FPrintETISheader(res_etis_file, mData);} if (cData.q_out == 1) {FPrintETISheader(res_q_file, mData);} printf("\n"); /* set start time */ t = cData.StartTime; /* start solver in loops */ for(i=0; i<cData.NumSteps; i++) { /* prompt information in non-verbose mode */ if (cData.Verbose != 1) { printf(" Running: %-4.1f%% ... ", (100*(i+1)/((realtype) cData.NumSteps))); fflush(stdout); } /* inner loops to next output points with ET step size control */ while(t < cData.Tout[i+1]) { if (t + cData.ETStep >= cData.Tout[i+1]) { NextPtr = cData.Tout[i+1]; } else { NextPtr = t + cData.ETStep; } StepSize = NextPtr - t; /* calculate Interception Storage */ calIS(t, StepSize, mData); /* solving ODE system */ flag = CVode(cvode_mem, NextPtr, CV_Y, &t, NORMAL); /* calculate ET and adjust states variables*/ calET(t, StepSize, CV_Y, mData); } if(cData.Verbose == 1) {PrintVerbose(i, t, iopt, ropt);} /* uncomment it if user need it verbose mode */ /* if(cData.Verbose == 1) {PrintY(mData, CV_Y, t);} */ /* print out results to files at every output time */ if (cData.res_out == 1) {FPrintY(mData, CV_Y, t, res_state_file);} if (cData.flux_out == 1) {FPrintFlux(mData, t, res_flux_file);} if (cData.etis_out == 1) {FPrintETIS(mData, t, res_etis_file);} if (cData.q_out == 1) {FPrintQ(mData, t, res_q_file);} if (cData.Verbose != 1) {printf("\r");} if(flag != SUCCESS) {printf("CVode failed, flag = %d. \n", flag); return(flag);} /* clear buffer */ fflush(stdout); } /* free memory */ /* N_VFree(CV_Y); CVodeFree(cvode_mem); M_EnvFree_Serial(machEnv); */ /* capture time */ end_s = clock(); cputime_s = (end_s - end_r)/(realtype)CLOCKS_PER_SEC; /* print out simulation statistics */ PrintFarewell(cData, iopt, ropt, cputime_r, cputime_s); if (cData.res_out == 1) {FPrintFarewell(cData, res_state_file, iopt, ropt, cputime_r, cputime_s);} /* close output files */ if (cData.res_out == 1) {fclose(res_state_file);} if (cData.flux_out == 1) {fclose(res_flux_file);} if (cData.etis_out == 1) {fclose(res_etis_file);} if (cData.q_out == 1) {fclose(res_q_file);} free(mData); return 0; }