/* yS0 in row major order */ void ode_solver_init_sens(ode_solver* solver, double* yS0, int lenP, int lenY){ /* change: lenP may now be shorter than P if you dpn't want to * calculate all sensitivities. This is important for the correct * treatment of input parameters, i.e. experimental conditions u * (since we don't require sensitivities with repsect to them). */ int i,flag; int N = solver->odeModel->N; int P = solver->odeModel->P; if (solver->odeModel->vf_sens == 0) { fprintf(stderr,"ode_solver_init_sens: no sensitivities defined for this model.\n"); return; } solver->yS = N_VCloneVectorArrayEmpty_Serial(lenP, solver->y); /* alloc */ double tmp[N]; if(yS0 !=0 ){ if ( (lenY != N) ) { fprintf(stderr,"ode_solver_init_sens: lenY must be equal to %d the number of parameters and variables in the ode model.\n",solver->odeModel->N); return ; } for(i = 0; i < lenP; i++) NV_DATA_S(solver->yS[i]) = &yS0[i*lenY]; } else{ for (i=0; i < N ; i++) tmp[i] = 0.0; for (i = 0; i < lenP; i++) NV_DATA_S(solver->yS[i]) = tmp; } flag = CVodeSensInit1(solver->cvode_mem, lenP, CV_STAGGERED1, solver->odeModel->vf_sens, solver->yS); flag = CVodeSetSensErrCon(solver->cvode_mem, TRUE); flag = CVodeSensEEtolerances(solver->cvode_mem); /* set parameters scale for error corection */ double scale_p[lenP]; for (i=0; i<lenP; i++) { /* order of magnitude can be found from the actual parameter value */ /* if zero then set to the default relative error */ if (solver->params[i] != 0.0){ scale_p[i] = solver->params[i]; } else { scale_p[i] = ODE_SOLVER_REL_ERR; } } flag = CVodeSetSensParams(solver->cvode_mem, solver->params, scale_p, NULL); }
int main(int argc, char *argv[]) { void *cvode_mem; UserData data; realtype t, tout; N_Vector y; int iout, flag, nthreads, nnz; realtype pbar[NS]; int is; N_Vector *yS; booleantype sensi, err_con; int sensi_meth; cvode_mem = NULL; data = NULL; y = NULL; yS = NULL; /* Process arguments */ ProcessArgs(argc, argv, &sensi, &sensi_meth, &err_con); /* User data structure */ data = (UserData) malloc(sizeof *data); if (check_flag((void *)data, "malloc", 2)) return(1); data->p[0] = RCONST(0.04); data->p[1] = RCONST(1.0e4); data->p[2] = RCONST(3.0e7); /* Initial conditions */ y = N_VNew_Serial(NEQ); if (check_flag((void *)y, "N_VNew_Serial", 0)) return(1); Ith(y,1) = Y1; Ith(y,2) = Y2; Ith(y,3) = Y3; /* 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); /* Call CVodeInit to initialize the integrator memory and specify the user's right hand side function in y'=f(t,y), the initial time T0, and the initial dependent variable vector y. */ flag = CVodeInit(cvode_mem, f, T0, y); if (check_flag(&flag, "CVodeInit", 1)) return(1); /* Call CVodeWFtolerances to specify a user-supplied function ewt that sets the multiplicative error weights W_i for use in the weighted RMS norm */ flag = CVodeWFtolerances(cvode_mem, ewt); if (check_flag(&flag, "CVodeSetEwtFn", 1)) return(1); /* Attach user data */ flag = CVodeSetUserData(cvode_mem, data); if (check_flag(&flag, "CVodeSetUserData", 1)) return(1); /* Call CVKLU to specify the CVKLU sparse direct linear solver */ nthreads = 1; /* no. of threads to use when factoring the system*/ nnz = NEQ * NEQ; /* max no. of nonzeros entries in the Jac */ flag = CVSuperLUMT(cvode_mem, nthreads, NEQ, nnz); if (check_flag(&flag, "CVSuperLUMT", 1)) return(1); /* Set the Jacobian routine to Jac (user-supplied) */ flag = CVSlsSetSparseJacFn(cvode_mem, Jac); if (check_flag(&flag, "CVSlsSetSparseJacFn", 1)) return(1); printf("\n3-species chemical kinetics problem\n"); /* Sensitivity-related settings */ if (sensi) { /* Set parameter scaling factor */ pbar[0] = data->p[0]; pbar[1] = data->p[1]; pbar[2] = data->p[2]; /* Set sensitivity initial conditions */ yS = N_VCloneVectorArray_Serial(NS, y); if (check_flag((void *)yS, "N_VCloneVectorArray_Serial", 0)) return(1); for (is=0;is<NS;is++) N_VConst(ZERO, yS[is]); /* Call CVodeSensInit1 to activate forward sensitivity computations and allocate internal memory for COVEDS related to sensitivity calculations. Computes the right-hand sides of the sensitivity ODE, one at a time */ flag = CVodeSensInit1(cvode_mem, NS, sensi_meth, fS, yS); if(check_flag(&flag, "CVodeSensInit", 1)) return(1); /* Call CVodeSensEEtolerances to estimate tolerances for sensitivity variables based on the rolerances supplied for states variables and the scaling factor pbar */ flag = CVodeSensEEtolerances(cvode_mem); if(check_flag(&flag, "CVodeSensEEtolerances", 1)) return(1); /* Set sensitivity analysis optional inputs */ /* Call CVodeSetSensErrCon to specify the error control strategy for sensitivity variables */ flag = CVodeSetSensErrCon(cvode_mem, err_con); if (check_flag(&flag, "CVodeSetSensErrCon", 1)) return(1); /* Call CVodeSetSensParams to specify problem parameter information for sensitivity calculations */ flag = CVodeSetSensParams(cvode_mem, NULL, pbar, NULL); if (check_flag(&flag, "CVodeSetSensParams", 1)) return(1); printf("Sensitivity: YES "); if(sensi_meth == CV_SIMULTANEOUS) printf("( SIMULTANEOUS +"); else if(sensi_meth == CV_STAGGERED) printf("( STAGGERED +"); else printf("( STAGGERED1 +"); if(err_con) printf(" FULL ERROR CONTROL )"); else printf(" PARTIAL ERROR CONTROL )"); } else { printf("Sensitivity: NO "); } /* In loop over output points, call CVode, print results, test for error */ printf("\n\n"); printf("==========================================="); printf("============================\n"); printf(" T Q H NST y1"); printf(" y2 y3 \n"); printf("==========================================="); printf("============================\n"); for (iout=1, tout=T1; iout <= NOUT; iout++, tout *= TMULT) { flag = CVode(cvode_mem, tout, y, &t, CV_NORMAL); if (check_flag(&flag, "CVode", 1)) break; PrintOutput(cvode_mem, t, y); /* Call CVodeGetSens to get the sensitivity solution vector after a successful return from CVode */ if (sensi) { flag = CVodeGetSens(cvode_mem, &t, yS); if (check_flag(&flag, "CVodeGetSens", 1)) break; PrintOutputS(yS); } printf("-----------------------------------------"); printf("------------------------------\n"); } /* Print final statistics */ PrintFinalStats(cvode_mem, sensi); /* Free memory */ N_VDestroy_Serial(y); /* Free y vector */ if (sensi) { N_VDestroyVectorArray_Serial(yS, NS); /* Free yS vector */ } free(data); /* Free user data */ CVodeFree(&cvode_mem); /* Free CVODES memory */ return(0); }
/* creates CVODES forward sensitivity solver structures return 1 => success return 0 => failure */ int IntegratorInstance_createCVODESSolverStructures(integratorInstance_t *engine) { int i, j, flag, neq, ns; realtype *ydata, *abstoldata, *ySdata, *senstoldata; odeModel_t *om = engine->om; cvodeData_t *data = engine->data; cvodeSolver_t *solver = engine->solver; cvodeSettings_t *opt = engine->opt; /* realtype pbar[data->nsens+1]; */ /*int *plist; removed by AMF 8/11/05 realtype *pbar; ASSIGN_NEW_MEMORY_BLOCK(plist, data->nsens+1, int, 0) ASSIGN_NEW_MEMORY_BLOCK(pbar, data->nsens+1, realtype, 0)*/ /***** adding sensitivity specific structures ******/ /** * construct sensitivity related structures */ /* free sensitivity from former runs (changed for non-default cases!) */ ODEModel_freeSensitivity(om); /* if jacobian matrix has been constructed successfully, construct sensitivity matrix dx/dp, sets om->sensitivity to 1 if successful, 0 otherwise */ /*!!! this function will require additional input for non-default case, via sensitivity input settings! !!!*/ if ( om->jacobian ) ODEModel_constructSensitivity(om); else { om->sensitivity = 0; om->jacob_sens = NULL; om->nsens = om->nconst; ASSIGN_NEW_MEMORY_BLOCK(om->index_sens, om->nsens, int, 0); /*!!! non-default case: these values should be passed for other cases !!!*/ for ( i=0; i<om->nsens; i++ ) om->index_sens[i] = om->neq + om->nass + i; } engine->solver->nsens = data->nsens; solver->yS = N_VNewVectorArray_Serial(data->nsens, data->neq); if (check_flag((void *)solver->yS, "N_VNewVectorArray_Serial", 1, stderr)) return(0); /* * (re)initialize ySdata sensitivities */ /* absolute tolerance for sensitivity error control */ solver->senstol = N_VNew_Serial(data->nsens); abstoldata = NV_DATA_S(solver->senstol); for ( j=0; j<data->nsens; j++ ) { abstoldata[j] = 1e-4; ySdata = NV_DATA_S(solver->yS[j]); for ( i=0; i<data->neq; i++ ) ySdata[i] = data->sensitivity[i][j]; } /* * set method */ if ( opt->SensMethod == 0 ) flag =CVodeSensMalloc(solver->cvode_mem,data->nsens, CV_SIMULTANEOUS, solver->yS); else if ( opt->SensMethod == 1 ) flag = CVodeSensMalloc(solver->cvode_mem, data->nsens, CV_STAGGERED, solver->yS); else if ( opt->SensMethod == 2 ) flag = CVodeSensMalloc(solver->cvode_mem, data->nsens, CV_STAGGERED1, solver->yS); if(check_flag(&flag, "CVodeSensMalloc", 1, stderr)) { return 0; /* ERROR HANDLING CODE if failes */ } /* *** set parameter values or R.H.S function fS *****/ /* NOTES: */ /* !!! plist could later be used to specify requested parameters for sens.analysis !!! */ /* was construction of Jacobian and parametric matrix successfull ? */ if ( om->sensitivity && om->jacobian ) { flag = CVodeSetSensRhs1Fn(solver->cvode_mem, fS); if (check_flag(&flag, "CVodeSetSensRhs1Fn", 1, stderr)) { return 0; /* ERROR HANDLING CODE if failes */ } flag = CVodeSetSensFdata(solver->cvode_mem, data); if (check_flag(&flag, "CVodeSetSensFdata", 1, stderr)) { return 0; /* ERROR HANDLING CODE if failes */ } data->p = NULL; } else { ASSIGN_NEW_MEMORY_BLOCK(data->p, data->nsens, realtype, 0); for ( i=0; i<data->nsens; i++ ) { /* data->p is only required if R.H.S. fS cannot be supplied */ /* plist[i] = i+1; */ data->p[i] = data->value[om->index_sens[i]]; /* pbar[i] = abs(data->p[i]); */ /*??? WHAT IS PBAR ???*/ } flag = CVodeSetSensParams(solver->cvode_mem, data->p, NULL, NULL); if (check_flag(&flag, "CVodeSetSensParams", 1, stderr)) { return 0; /* ERROR HANDLING CODE if failes */ } flag = CVodeSetSensRho(solver->cvode_mem, 0.0); /* what is it? */ if (check_flag(&flag, "CVodeSetSensRhs1Fn", 1, stderr)) { /* ERROR HANDLING CODE if failes */ return 0; } } /* CVodeSetSensTolerances(solver->cvode_mem, CV_SS, */ /* solver->reltol, &solver->senstol); */ /* difference FALSE/TRUE ? */ flag = CVodeSetSensErrCon(solver->cvode_mem, FALSE); if (check_flag(&flag, "CVodeSetSensFdata", 1, stderr)) { return 0; /* ERROR HANDLING CODE if failes */ } return 1; /* OK */ }
int main(int argc, char *argv[]) { void *cvode_mem; UserData data; realtype t, tout; N_Vector y; int iout, flag; realtype pbar[NS]; int is; N_Vector *yS; booleantype sensi, err_con; int sensi_meth; cvode_mem = NULL; data = NULL; y = NULL; yS = NULL; /* Process arguments */ ProcessArgs(argc, argv, &sensi, &sensi_meth, &err_con); /* User data structure */ data = (UserData) malloc(sizeof *data); if (check_flag((void *)data, "malloc", 2)) return(1); data->p[0] = RCONST(0.04); data->p[1] = RCONST(1.0e4); data->p[2] = RCONST(3.0e7); /* Initial conditions */ y = N_VNew_Serial(NEQ); if (check_flag((void *)y, "N_VNew_Serial", 0)) return(1); Ith(y,1) = Y1; Ith(y,2) = Y2; Ith(y,3) = Y3; /* Create CVODES object */ cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON); if (check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1); /* Allocate space for CVODES */ flag = CVodeMalloc(cvode_mem, f, T0, y, CV_WF, 0.0, NULL); if (check_flag(&flag, "CVodeMalloc", 1)) return(1); /* Use private function to compute error weights */ flag = CVodeSetEwtFn(cvode_mem, ewt, NULL); if (check_flag(&flag, "CVodeSetEwtFn", 1)) return(1); /* Attach user data */ flag = CVodeSetFdata(cvode_mem, data); if (check_flag(&flag, "CVodeSetFdata", 1)) return(1); /* Attach linear solver */ flag = CVDense(cvode_mem, NEQ); if (check_flag(&flag, "CVDense", 1)) return(1); flag = CVDenseSetJacFn(cvode_mem, Jac, data); if (check_flag(&flag, "CVDenseSetJacFn", 1)) return(1); printf("\n3-species chemical kinetics problem\n"); /* Sensitivity-related settings */ if (sensi) { pbar[0] = data->p[0]; pbar[1] = data->p[1]; pbar[2] = data->p[2]; yS = N_VNewVectorArray_Serial(NS, NEQ); if (check_flag((void *)yS, "N_VNewVectorArray_Serial", 0)) return(1); for (is=0;is<NS;is++) N_VConst(ZERO, yS[is]); flag = CVodeSensMalloc(cvode_mem, NS, sensi_meth, yS); if(check_flag(&flag, "CVodeSensMalloc", 1)) return(1); flag = CVodeSetSensRhs1Fn(cvode_mem, fS); if (check_flag(&flag, "CVodeSetSensRhs1Fn", 1)) return(1); flag = CVodeSetSensErrCon(cvode_mem, err_con); if (check_flag(&flag, "CVodeSetSensFdata", 1)) return(1); flag = CVodeSetSensFdata(cvode_mem, data); if (check_flag(&flag, "CVodeSetSensFdata", 1)) return(1); flag = CVodeSetSensParams(cvode_mem, NULL, pbar, NULL); if (check_flag(&flag, "CVodeSetSensParams", 1)) return(1); printf("Sensitivity: YES "); if(sensi_meth == CV_SIMULTANEOUS) printf("( SIMULTANEOUS +"); else if(sensi_meth == CV_STAGGERED) printf("( STAGGERED +"); else printf("( STAGGERED1 +"); if(err_con) printf(" FULL ERROR CONTROL )"); else printf(" PARTIAL ERROR CONTROL )"); } else { printf("Sensitivity: NO "); } /* In loop over output points, call CVode, print results, test for error */ printf("\n\n"); printf("==================================================="); printf("============================\n"); printf(" T Q H NST y1"); printf(" y2 y3 \n"); printf("==================================================="); printf("============================\n"); for (iout=1, tout=T1; iout <= NOUT; iout++, tout *= TMULT) { flag = CVode(cvode_mem, tout, y, &t, CV_NORMAL); if (check_flag(&flag, "CVode", 1)) break; PrintOutput(cvode_mem, t, y); if (sensi) { flag = CVodeGetSens(cvode_mem, t, yS); if (check_flag(&flag, "CVodeGetSens", 1)) break; PrintOutputS(yS); } printf("-------------------------------------------------"); printf("------------------------------\n"); } /* Print final statistics */ PrintFinalStats(cvode_mem, sensi); /* Free memory */ N_VDestroy_Serial(y); /* Free y vector */ if (sensi) { N_VDestroyVectorArray_Serial(yS, NS); /* Free yS vector */ } free(data); /* Free user data */ CVodeFree(cvode_mem); /* Free CVODES memory */ return(0); }
int main(int argc, char *argv[]) { void *cvode_mem; UserData data; realtype abstol, reltol, t, tout; N_Vector y; int iout, flag; realtype *pbar; int is, *plist; N_Vector *uS; booleantype sensi, err_con; int sensi_meth; pbar = NULL; plist = NULL; uS = NULL; y = NULL; data = NULL; cvode_mem = NULL; /* Process arguments */ ProcessArgs(argc, argv, &sensi, &sensi_meth, &err_con); /* Problem parameters */ data = AllocUserData(); if(check_flag((void *)data, "AllocUserData", 2)) return(1); InitUserData(data); /* Initial states */ y = N_VNew_Serial(NEQ); if(check_flag((void *)y, "N_VNew_Serial", 0)) return(1); SetInitialProfiles(y, data->dx, data->dz); /* Tolerances */ abstol=ATOL; reltol=RTOL; /* Create CVODES object */ cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON); if(check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1); flag = CVodeSetFdata(cvode_mem, data); if(check_flag(&flag, "CVodeSetFdata", 1)) return(1); flag = CVodeSetMaxNumSteps(cvode_mem, 2000); if(check_flag(&flag, "CVodeSetMaxNumSteps", 1)) return(1); /* Allocate CVODES memory */ flag = CVodeMalloc(cvode_mem, f, T0, y, CV_SS, reltol, &abstol); if(check_flag(&flag, "CVodeMalloc", 1)) return(1); /* Attach CVSPGMR linear solver */ flag = CVSpgmr(cvode_mem, PREC_LEFT, 0); if(check_flag(&flag, "CVSpgmr", 1)) return(1); flag = CVSpilsSetPreconditioner(cvode_mem, Precond, PSolve, data); if(check_flag(&flag, "CVSpilsSetPreconditioner", 1)) return(1); printf("\n2-species diurnal advection-diffusion problem\n"); /* Forward sensitivity analysis */ if(sensi) { plist = (int *) malloc(NS * sizeof(int)); if(check_flag((void *)plist, "malloc", 2)) return(1); for(is=0; is<NS; is++) plist[is] = is; pbar = (realtype *) malloc(NS * sizeof(realtype)); if(check_flag((void *)pbar, "malloc", 2)) return(1); for(is=0; is<NS; is++) pbar[is] = data->p[plist[is]]; uS = N_VCloneVectorArray_Serial(NS, y); if(check_flag((void *)uS, "N_VCloneVectorArray_Serial", 0)) return(1); for(is=0;is<NS;is++) N_VConst(ZERO,uS[is]); flag = CVodeSensMalloc(cvode_mem, NS, sensi_meth, uS); if(check_flag(&flag, "CVodeSensMalloc", 1)) return(1); flag = CVodeSetSensErrCon(cvode_mem, err_con); if(check_flag(&flag, "CVodeSetSensErrCon", 1)) return(1); flag = CVodeSetSensRho(cvode_mem, ZERO); if(check_flag(&flag, "CVodeSetSensRho", 1)) return(1); flag = CVodeSetSensParams(cvode_mem, data->p, pbar, plist); if(check_flag(&flag, "CVodeSetSensParams", 1)) return(1); printf("Sensitivity: YES "); if(sensi_meth == CV_SIMULTANEOUS) printf("( SIMULTANEOUS +"); else if(sensi_meth == CV_STAGGERED) printf("( STAGGERED +"); else printf("( STAGGERED1 +"); if(err_con) printf(" FULL ERROR CONTROL )"); else printf(" PARTIAL ERROR CONTROL )"); } else { printf("Sensitivity: NO "); } /* In loop over output points, call CVode, print results, test for error */ printf("\n\n"); printf("========================================================================\n"); printf(" T Q H NST Bottom left Top right \n"); printf("========================================================================\n"); for (iout=1, tout = TWOHR; iout <= NOUT; iout++, tout += TWOHR) { flag = CVode(cvode_mem, tout, y, &t, CV_NORMAL); if(check_flag(&flag, "CVode", 1)) break; PrintOutput(cvode_mem, t, y); if (sensi) { flag = CVodeGetSens(cvode_mem, t, uS); if(check_flag(&flag, "CVodeGetSens", 1)) break; PrintOutputS(uS); } printf("------------------------------------------------------------------------\n"); } /* Print final statistics */ PrintFinalStats(cvode_mem, sensi); /* Free memory */ N_VDestroy_Serial(y); if (sensi) { N_VDestroyVectorArray_Serial(uS, NS); free(pbar); free(plist); } FreeUserData(data); CVodeFree(&cvode_mem); return(0); }
int main(int argc, char *argv[]) { SUNMatrix A; SUNLinearSolver LS; void *cvode_mem; UserData data; realtype t, tout; N_Vector y, constraints; int iout, retval; realtype pbar[NS]; int is; N_Vector *yS; booleantype sensi, err_con; int sensi_meth; cvode_mem = NULL; data = NULL; y = NULL; yS = NULL; A = NULL; LS = NULL; constraints = NULL; /* Process arguments */ ProcessArgs(argc, argv, &sensi, &sensi_meth, &err_con); /* User data structure */ data = (UserData) malloc(sizeof *data); if (check_retval((void *)data, "malloc", 2)) return(1); data->p[0] = RCONST(0.04); data->p[1] = RCONST(1.0e4); data->p[2] = RCONST(3.0e7); /* Initial conditions */ y = N_VNew_Serial(NEQ); if (check_retval((void *)y, "N_VNew_Serial", 0)) return(1); Ith(y,1) = Y1; Ith(y,2) = Y2; Ith(y,3) = Y3; /* Set constraints to all 1's for nonnegative solution values. */ constraints = N_VNew_Serial(NEQ); if(check_retval((void *)constraints, "N_VNew_Serial", 0)) return(1); N_VConst(ONE, constraints); /* Create CVODES object */ cvode_mem = CVodeCreate(CV_BDF); if (check_retval((void *)cvode_mem, "CVodeCreate", 0)) return(1); /* Allocate space for CVODES */ retval = CVodeInit(cvode_mem, f, T0, y); if (check_retval(&retval, "CVodeInit", 1)) return(1); /* Use private function to compute error weights */ retval = CVodeWFtolerances(cvode_mem, ewt); if (check_retval(&retval, "CVodeSetEwtFn", 1)) return(1); /* Attach user data */ retval = CVodeSetUserData(cvode_mem, data); if (check_retval(&retval, "CVodeSetUserData", 1)) return(1); /* Call CVodeSetConstraints to initialize constraints */ retval = CVodeSetConstraints(cvode_mem, constraints); if(check_retval(&retval, "CVodeSetConstraints", 1)) return(1); N_VDestroy(constraints); /* Create dense SUNMatrix */ A = SUNDenseMatrix(NEQ, NEQ); if (check_retval((void *)A, "SUNDenseMatrix", 0)) return(1); /* Create dense SUNLinearSolver */ LS = SUNLinSol_Dense(y, A); if (check_retval((void *)LS, "SUNLinSol_Dense", 0)) return(1); /* Attach the matrix and linear solver */ retval = CVDlsSetLinearSolver(cvode_mem, LS, A); if (check_retval(&retval, "CVDlsSetLinearSolver", 1)) return(1); /* Set the user-supplied Jacobian routine Jac */ retval = CVDlsSetJacFn(cvode_mem, Jac); if (check_retval(&retval, "CVDlsSetJacFn", 1)) return(1); printf("\n3-species chemical kinetics problem\n"); /* Sensitivity-related settings */ if (sensi) { /* Set parameter scaling factor */ pbar[0] = data->p[0]; pbar[1] = data->p[1]; pbar[2] = data->p[2]; /* Set sensitivity initial conditions */ yS = N_VCloneVectorArray(NS, y); if (check_retval((void *)yS, "N_VCloneVectorArray", 0)) return(1); for (is=0;is<NS;is++) N_VConst(ZERO, yS[is]); /* Call CVodeSensInit1 to activate forward sensitivity computations and allocate internal memory for COVEDS related to sensitivity calculations. Computes the right-hand sides of the sensitivity ODE, one at a time */ retval = CVodeSensInit1(cvode_mem, NS, sensi_meth, fS, yS); if(check_retval(&retval, "CVodeSensInit", 1)) return(1); /* Call CVodeSensEEtolerances to estimate tolerances for sensitivity variables based on the rolerances supplied for states variables and the scaling factor pbar */ retval = CVodeSensEEtolerances(cvode_mem); if(check_retval(&retval, "CVodeSensEEtolerances", 1)) return(1); /* Set sensitivity analysis optional inputs */ /* Call CVodeSetSensErrCon to specify the error control strategy for sensitivity variables */ retval = CVodeSetSensErrCon(cvode_mem, err_con); if (check_retval(&retval, "CVodeSetSensErrCon", 1)) return(1); /* Call CVodeSetSensParams to specify problem parameter information for sensitivity calculations */ retval = CVodeSetSensParams(cvode_mem, NULL, pbar, NULL); if (check_retval(&retval, "CVodeSetSensParams", 1)) return(1); printf("Sensitivity: YES "); if(sensi_meth == CV_SIMULTANEOUS) printf("( SIMULTANEOUS +"); else if(sensi_meth == CV_STAGGERED) printf("( STAGGERED +"); else printf("( STAGGERED1 +"); if(err_con) printf(" FULL ERROR CONTROL )"); else printf(" PARTIAL ERROR CONTROL )"); } else { printf("Sensitivity: NO "); } /* In loop over output points, call CVode, print results, test for error */ printf("\n\n"); printf("==========================================="); printf("============================\n"); printf(" T Q H NST y1"); printf(" y2 y3 \n"); printf("==========================================="); printf("============================\n"); for (iout=1, tout=T1; iout <= NOUT; iout++, tout *= TMULT) { retval = CVode(cvode_mem, tout, y, &t, CV_NORMAL); if (check_retval(&retval, "CVode", 1)) break; PrintOutput(cvode_mem, t, y); /* Call CVodeGetSens to get the sensitivity solution vector after a successful return from CVode */ if (sensi) { retval = CVodeGetSens(cvode_mem, &t, yS); if (check_retval(&retval, "CVodeGetSens", 1)) break; PrintOutputS(yS); } printf("-----------------------------------------"); printf("------------------------------\n"); } /* Print final statistics */ PrintFinalStats(cvode_mem, sensi); /* Free memory */ N_VDestroy(y); /* Free y vector */ if (sensi) { N_VDestroyVectorArray(yS, NS); /* Free yS vector */ } free(data); /* Free user data */ CVodeFree(&cvode_mem); /* Free CVODES memory */ SUNLinSolFree(LS); /* Free the linear solver memory */ SUNMatDestroy(A); /* Free the matrix memory */ return(0); }
int main(int argc, char *argv[]) { void *cvode_mem; UserData data; realtype dx, reltol, abstol, t, tout; N_Vector u; int iout, flag; realtype *pbar; int is, *plist; N_Vector *uS; booleantype sensi, err_con; int sensi_meth; cvode_mem = NULL; data = NULL; u = NULL; pbar = NULL; plist = NULL; uS = NULL; /* Process arguments */ ProcessArgs(argc, argv, &sensi, &sensi_meth, &err_con); /* Set user data */ data = (UserData) malloc(sizeof *data); /* Allocate data memory */ if(check_flag((void *)data, "malloc", 2)) return(1); data->p = (realtype *) malloc(NP * sizeof(realtype)); dx = data->dx = XMAX/((realtype)(MX+1)); data->p[0] = RCONST(1.0); data->p[1] = RCONST(0.5); /* Allocate and set initial states */ u = N_VNew_Serial(NEQ); if(check_flag((void *)u, "N_VNew_Serial", 0)) return(1); SetIC(u, dx); /* Set integration tolerances */ reltol = ZERO; abstol = ATOL; /* Create CVODES object */ cvode_mem = CVodeCreate(CV_ADAMS, CV_FUNCTIONAL); if(check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1); flag = CVodeSetUserData(cvode_mem, data); if(check_flag(&flag, "CVodeSetUserData", 1)) return(1); /* Allocate CVODES memory */ flag = CVodeInit(cvode_mem, f, T0, u); if(check_flag(&flag, "CVodeInit", 1)) return(1); flag = CVodeSStolerances(cvode_mem, reltol, abstol); if(check_flag(&flag, "CVodeSStolerances", 1)) return(1); printf("\n1-D advection-diffusion equation, mesh size =%3d\n", MX); /* Sensitivity-related settings */ if(sensi) { plist = (int *) malloc(NS * sizeof(int)); if(check_flag((void *)plist, "malloc", 2)) return(1); for(is=0; is<NS; is++) plist[is] = is; pbar = (realtype *) malloc(NS * sizeof(realtype)); if(check_flag((void *)pbar, "malloc", 2)) return(1); for(is=0; is<NS; is++) pbar[is] = data->p[plist[is]]; uS = N_VCloneVectorArray_Serial(NS, u); if(check_flag((void *)uS, "N_VCloneVectorArray_Serial", 0)) return(1); for(is=0;is<NS;is++) N_VConst(ZERO, uS[is]); flag = CVodeSensInit1(cvode_mem, NS, sensi_meth, NULL, uS); if(check_flag(&flag, "CVodeSensInit1", 1)) return(1); flag = CVodeSensEEtolerances(cvode_mem); if(check_flag(&flag, "CVodeSensEEtolerances", 1)) return(1); flag = CVodeSetSensErrCon(cvode_mem, err_con); if(check_flag(&flag, "CVodeSetSensErrCon", 1)) return(1); flag = CVodeSetSensDQMethod(cvode_mem, CV_CENTERED, ZERO); if(check_flag(&flag, "CVodeSetSensDQMethod", 1)) return(1); flag = CVodeSetSensParams(cvode_mem, data->p, pbar, plist); if(check_flag(&flag, "CVodeSetSensParams", 1)) return(1); printf("Sensitivity: YES "); if(sensi_meth == CV_SIMULTANEOUS) printf("( SIMULTANEOUS +"); else if(sensi_meth == CV_STAGGERED) printf("( STAGGERED +"); else printf("( STAGGERED1 +"); if(err_con) printf(" FULL ERROR CONTROL )"); else printf(" PARTIAL ERROR CONTROL )"); } else { printf("Sensitivity: NO "); } /* In loop over output points, call CVode, print results, test for error */ printf("\n\n"); printf("============================================================\n"); printf(" T Q H NST Max norm \n"); printf("============================================================\n"); 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; PrintOutput(cvode_mem, t, u); if (sensi) { flag = CVodeGetSens(cvode_mem, &t, uS); if(check_flag(&flag, "CVodeGetSens", 1)) break; PrintOutputS(uS); } printf("------------------------------------------------------------\n"); } /* Print final statistics */ PrintFinalStats(cvode_mem, sensi); /* Free memory */ N_VDestroy_Serial(u); if (sensi) { N_VDestroyVectorArray_Serial(uS, NS); free(plist); free(pbar); } free(data); CVodeFree(&cvode_mem); return(0); }
int main(int argc, char *argv[]) { realtype dx, reltol, abstol, t, tout; N_Vector u; UserData data; void *cvode_mem; int iout, flag, my_pe, npes; long int local_N, nperpe, nrem, my_base; realtype *pbar; int is, *plist; N_Vector *uS; booleantype sensi, err_con; int sensi_meth; MPI_Comm comm; u = NULL; data = NULL; cvode_mem = NULL; pbar = NULL; plist = NULL; uS = NULL; /* Get processor number, total number of pe's, and my_pe. */ MPI_Init(&argc, &argv); comm = MPI_COMM_WORLD; MPI_Comm_size(comm, &npes); MPI_Comm_rank(comm, &my_pe); /* Process arguments */ ProcessArgs(argc, argv, my_pe, &sensi, &sensi_meth, &err_con); /* Set local vector length. */ nperpe = NEQ/npes; nrem = NEQ - npes*nperpe; local_N = (my_pe < nrem) ? nperpe+1 : nperpe; my_base = (my_pe < nrem) ? my_pe*local_N : my_pe*nperpe + nrem; /* USER DATA STRUCTURE */ data = (UserData) malloc(sizeof *data); /* Allocate data memory */ data->p = NULL; if(check_flag((void *)data, "malloc", 2, my_pe)) MPI_Abort(comm, 1); data->comm = comm; data->npes = npes; data->my_pe = my_pe; data->p = (realtype *) malloc(NP * sizeof(realtype)); if(check_flag((void *)data->p, "malloc", 2, my_pe)) MPI_Abort(comm, 1); dx = data->dx = XMAX/((realtype)(MX+1)); data->p[0] = RCONST(1.0); data->p[1] = RCONST(0.5); /* INITIAL STATES */ u = N_VNew_Parallel(comm, local_N, NEQ); /* Allocate u vector */ if(check_flag((void *)u, "N_VNew_Parallel", 0, my_pe)) MPI_Abort(comm, 1); SetIC(u, dx, local_N, my_base); /* Initialize u vector */ /* TOLERANCES */ reltol = ZERO; /* Set the tolerances */ abstol = ATOL; /* CVODE_CREATE & CVODE_MALLOC */ cvode_mem = CVodeCreate(CV_ADAMS, CV_FUNCTIONAL); if(check_flag((void *)cvode_mem, "CVodeCreate", 0, my_pe)) MPI_Abort(comm, 1); flag = CVodeSetUserData(cvode_mem, data); if(check_flag(&flag, "CVodeSetUserData", 1, my_pe)) MPI_Abort(comm, 1); flag = CVodeInit(cvode_mem, f, T0, u); if(check_flag(&flag, "CVodeInit", 1, my_pe)) MPI_Abort(comm, 1); flag = CVodeSStolerances(cvode_mem, reltol, abstol); if(check_flag(&flag, "CVodeSStolerances", 1, my_pe)) MPI_Abort(comm, 1); if (my_pe == 0) { printf("\n1-D advection-diffusion equation, mesh size =%3d \n", MX); printf("\nNumber of PEs = %3d \n",npes); } if(sensi) { plist = (int *) malloc(NS * sizeof(int)); if(check_flag((void *)plist, "malloc", 2, my_pe)) MPI_Abort(comm, 1); for(is=0; is<NS; is++) plist[is] = is; /* sensitivity w.r.t. i-th parameter */ pbar = (realtype *) malloc(NS * sizeof(realtype)); if(check_flag((void *)pbar, "malloc", 2, my_pe)) MPI_Abort(comm, 1); for(is=0; is<NS; is++) pbar[is] = data->p[plist[is]]; uS = N_VCloneVectorArray_Parallel(NS, u); if(check_flag((void *)uS, "N_VCloneVectorArray_Parallel", 0, my_pe)) MPI_Abort(comm, 1); for(is=0;is<NS;is++) N_VConst(ZERO,uS[is]); flag = CVodeSensInit1(cvode_mem, NS, sensi_meth, NULL, uS); if(check_flag(&flag, "CVodeSensInit1", 1, my_pe)) MPI_Abort(comm, 1); flag = CVodeSensEEtolerances(cvode_mem); if(check_flag(&flag, "CVodeSensEEtolerances", 1, my_pe)) MPI_Abort(comm, 1); flag = CVodeSetSensErrCon(cvode_mem, err_con); if(check_flag(&flag, "CVodeSetSensErrCon", 1, my_pe)) MPI_Abort(comm, 1); flag = CVodeSetSensDQMethod(cvode_mem, CV_CENTERED, ZERO); if(check_flag(&flag, "CVodeSetSensDQMethod", 1, my_pe)) MPI_Abort(comm, 1); flag = CVodeSetSensParams(cvode_mem, data->p, pbar, plist); if(check_flag(&flag, "CVodeSetSensParams", 1, my_pe)) MPI_Abort(comm, 1); if(my_pe == 0) { printf("Sensitivity: YES "); if(sensi_meth == CV_SIMULTANEOUS) printf("( SIMULTANEOUS +"); else if(sensi_meth == CV_STAGGERED) printf("( STAGGERED +"); else printf("( STAGGERED1 +"); if(err_con) printf(" FULL ERROR CONTROL )"); else printf(" PARTIAL ERROR CONTROL )"); } } else { if(my_pe == 0) printf("Sensitivity: NO "); } /* In loop over output points, call CVode, print results, test for error */ if(my_pe == 0) { printf("\n\n"); printf("============================================================\n"); printf(" T Q H NST Max norm \n"); printf("============================================================\n"); } 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, my_pe)) break; PrintOutput(cvode_mem, my_pe, t, u); if (sensi) { flag = CVodeGetSens(cvode_mem, &t, uS); if(check_flag(&flag, "CVodeGetSens", 1, my_pe)) break; PrintOutputS(my_pe, uS); } if (my_pe == 0) printf("------------------------------------------------------------\n"); } /* Print final statistics */ if (my_pe == 0) PrintFinalStats(cvode_mem, sensi); /* Free memory */ N_VDestroy(u); /* Free the u vector */ if (sensi) N_VDestroyVectorArray(uS, NS); /* Free the uS vectors */ free(data->p); /* Free the p vector */ free(data); /* Free block of UserData */ CVodeFree(&cvode_mem); /* Free the CVODES problem memory */ free(pbar); if(sensi) free(plist); MPI_Finalize(); return(0); }