/* creates CVODES structures and fills cvodeSolver return 1 => success return 0 => failure */ int IntegratorInstance_createIDASolverStructures(integratorInstance_t *engine) { int i, flag, neq, nalg; realtype *ydata, *abstoldata, *dydata; odeModel_t *om = engine->om; cvodeData_t *data = engine->data; cvodeSolver_t *solver = engine->solver; cvodeSettings_t *opt = engine->opt; neq = engine->om->neq; /* number of ODEs */ nalg = engine->om->nalg; /* number of algebraic constraints */ /* construct jacobian, if wanted and not yet existing */ if ( opt->UseJacobian && om->jacob == NULL ) /* reset UseJacobian option, depending on success */ engine->UseJacobian = ODEModel_constructJacobian(om); else if ( !opt->UseJacobian ) { /* free jacobian from former runs (not necessary, frees also unsuccessful jacobians from former runs ) */ ODEModel_freeJacobian(om); SolverError_error(WARNING_ERROR_TYPE, SOLVER_ERROR_MODEL_NOT_SIMPLIFIED, "Jacobian matrix construction skipped."); engine->UseJacobian = om->jacobian; } /* construct algebraic `Jacobian' (or do that in constructJacobian */ /* CVODESolverStructures from former runs must be freed */ if ( engine->run > 1 ) IntegratorInstance_freeIDASolverStructures(engine); /* * Allocate y, abstol vectors */ solver->y = N_VNew_Serial(neq + nalg); CVODE_HANDLE_ERROR((void *)solver->y, "N_VNew_Serial for vector y", 0); solver->dy = N_VNew_Serial(neq + nalg); CVODE_HANDLE_ERROR((void *)solver->dy, "N_VNew_Serial for vector dy", 0); solver->abstol = N_VNew_Serial(neq + nalg); CVODE_HANDLE_ERROR((void *)solver->abstol, "N_VNew_Serial for vector abstol", 0); /* * Initialize y, abstol vectors */ ydata = NV_DATA_S(solver->y); abstoldata = NV_DATA_S(solver->abstol); dydata = NV_DATA_S(solver->dy); for ( i=0; i<neq; i++ ) { /* Set initial value vector components of y and y' */ ydata[i] = data->value[i]; /* Set absolute tolerance vector components, currently the same absolute error is used for all y */ abstoldata[i] = opt->Error; dydata[i] = evaluateAST(om->ode[i], data); } /* set initial value vector components for algebraic rule variables */ /* scalar relative tolerance: the same for all y */ solver->reltol = opt->RError; /* * Call IDACreate to create the solver memory: * */ solver->cvode_mem = IDACreate(); CVODE_HANDLE_ERROR((void *)(solver->cvode_mem), "IDACreate", 0); /* * Call IDAInit to initialize the integrator memory: * * cvode_mem pointer to the CVode memory block returned by CVodeCreate * fRes user's right hand side function * t0 initial value of time * y the dependent variable vector * dy the ODE value vector */ flag = IDAInit(solver->cvode_mem, fRes, solver->t0, solver->y, solver->dy); CVODE_HANDLE_ERROR(&flag, "IDAInit", 1); /* * specify scalar relative and vector absolute tolerances * reltol the scalar relative tolerance * abstol pointer to the absolute tolerance vector */ flag = IDASVtolerances(solver->cvode_mem, solver->reltol, solver->abstol); CVODE_HANDLE_ERROR(&flag, "IDASVtolerances", 1); /* * Link the main integrator with data for right-hand side function */ flag = IDASetUserData(solver->cvode_mem, engine->data); CVODE_HANDLE_ERROR(&flag, "IDASetUserData", 1); /* * Link the main integrator with the IDADENSE linear solver */ flag = IDADense(solver->cvode_mem, neq); CVODE_HANDLE_ERROR(&flag, "IDADense", 1); /* * Set the routine used by the IDADense linear solver * to approximate the Jacobian matrix to ... */ if ( opt->UseJacobian == 1 ) { /* ... user-supplied routine JacRes : put JacRes instead of NULL when working */ flag = IDADlsSetDenseJacFn(solver->cvode_mem, JacRes); CVODE_HANDLE_ERROR(&flag, "IDADlsSetDenseJacFn", 1); } return 1; /* OK */ }
void interactive() { char *sbmlFilename; char *select; int quit; SBMLDocument_t *d = NULL; Model_t *m = NULL; odeModel_t *om = NULL; cvodeData_t * data = NULL; integratorInstance_t *ii = NULL; cvodeSettings_t *set = NULL; printf("\n\nWelcome to the simple SBML ODE solver.\n"); printf("You have entered the interactive mode.\n"); printf("All other commandline options have been ignored.\n"); printf("Have fun!\n\n"); initializeOptions(); /* reset steady state */ Opt.SteadyState = 0; /* activate printing of results to XMGrace */ Opt.Xmgrace = 1; /* activate printing integrator messages */ Opt.PrintMessage = 1; /* deactivate on the fly printing of results */ Opt.PrintOnTheFly = 0; sbmlFilename = concat(Opt.ModelPath, Opt.ModelFile); if ( (d = parseModelWithArguments(sbmlFilename)) == 0 ) { Warn(stderr, "%s:%d interactive(): Can't parse Model >%s<", __FILE__, __LINE__, sbmlFilename); d = loadFile(); } /* load models and default settings */ m = SBMLDocument_getModel(d); om = ODEModel_create(m); set = CvodeSettings_create(); SolverError_dumpAndClearErrors(); quit = 0; data = NULL; while ( quit == 0 ) { printf("\n"); printf("Press (h) for instructions or (q) to quit.\n"); printf("> "); select = get_line( stdin ); select = util_trim(select); printf("\n"); if( strcmp(select,"l") == 0 ) { /* free all existing structures */ if ( om != NULL ) ODEModel_free(data->model); if ( d != NULL ) SBMLDocument_free(d); if ( ii != NULL ) IntegratorInstance_free(ii); /* load a new file */ d = loadFile(); /* load new models */ m = SBMLDocument_getModel(d); om = ODEModel_create(m); SolverError_dumpAndClearErrors(); } if(strcmp(select,"h")==0) printMenu(); if(strcmp(select,"s")==0) printModel(m, stdout); if(strcmp(select,"c")==0) printSpecies(m, stdout); if(strcmp(select,"r")==0) printReactions(m, stdout); if(strcmp(select,"o")==0) printODEs(om, stdout); /* integrate interface functions, asks for time and printsteps */ if(strcmp(select,"i")==0){ ii = callIntegrator(om, set); SolverError_dumpAndClearErrors(); } if(strcmp(select,"x")==0){ if ( Opt.Xmgrace == 1 ) { Opt.Xmgrace = 0; printf(" Printing results to stdout\n"); } else if ( Opt.Xmgrace == 0 ) { Opt.Xmgrace = 1; printf(" Printing results to XMGrace\n"); } } if(strcmp(select,"st")==0) printConcentrationTimeCourse(ii->data, stdout); if(strcmp(select,"jt")==0) printJacobianTimeCourse(ii->data, stdout); if(strcmp(select,"ot")==0) printOdeTimeCourse(ii->data, stdout); if(strcmp(select,"rt")==0) printReactionTimeCourse(ii->data, m, stdout); if(strcmp(select,"xp")==0) printPhase(ii->data); if(strcmp(select,"set")==0) setValues(m); if(strcmp(select,"ss")==0){ if ( Opt.SteadyState == 1 ) { Opt.SteadyState = 0; printf(" Not checking for steady states during integration.\n"); } else if ( Opt.SteadyState == 0 ) { Opt.SteadyState = 1; printf(" Checking for steady states during integration.\n"); } } if(strcmp(select,"uj")==0){ if ( Opt.Jacobian == 1 ) { Opt.Jacobian = 0; printf(" Using CVODE's internal approximation\n"); printf(" of the jacobian matrix for integration\n"); } else if ( Opt.Jacobian == 0 ) { Opt.Jacobian = 1; printf(" Using automatically generated\n"); printf(" jacobian matrix for integration\n"); } } if(strcmp(select,"gf")==0) setFormat(); if(strcmp(select,"rg")==0) { drawModel(m, sbmlFilename, Opt.GvFormat); SolverError_dumpAndClearErrors(); } if(strcmp(select,"jg")==0){ if ( ii == NULL ) { data = CvodeData_create(om); CvodeData_initialize(data, set, om, 0); drawJacoby(data, sbmlFilename, Opt.GvFormat); SolverError_dumpAndClearErrors(); CvodeData_free(data); } else { drawJacoby(ii->data, sbmlFilename, Opt.GvFormat); SolverError_dumpAndClearErrors(); } } if(strcmp(select,"j")==0) { if ( om->jacob == NULL ) ODEModel_constructJacobian(om); printJacobian(om, stdout); } if(strcmp(select,"q")==0) quit = 1; } if ( ii != NULL ) IntegratorInstance_free(ii); if ( om != NULL ) ODEModel_free(om); SBMLDocument_free(d); SolverError_dumpAndClearErrors(); printf("\n\nGood Bye. Thx for using.\n\n"); }
int main(void) { char *formula; variableIndex_t *vi = NULL; variableIndex_t *vj = NULL; const ASTNode_t *f = NULL; cvodeData_t *data = NULL; cvodeSettings_t *set; integratorInstance_t *iI; /* first load an SBML model and directly construct the internal odeModel from it */ odeModel_t *odeModel = ODEModel_createFromFile("MAPK.xml"); if ( ODEModel_constructJacobian(odeModel) && ODEModel_getNeq(odeModel) ) { printf("\n\nSuccessfully constructed the jacobian matrix J\n\n"); printf("We might be interested in the `sparsity' of J,\n"); printf("... we can just evaluate the jacobian entries:\n\n"); /* we need cvodeData for evaluating formulas */ data = CvodeData_create(odeModel); /* ! IMPORTANT : initialize values */ CvodeData_initializeValues(data); printf("Jacobian with initial conditions:\n"); printJacobian(odeModel, data); /* we must free this cvodeData structure */ CvodeData_free(data); printf("Does it change after integration?\n\n"); /* creating settings and integrate */ set = CvodeSettings_create(); CvodeSettings_setTime(set, 1000, 1); iI = IntegratorInstance_create(odeModel, set); IntegratorInstance_integrate(iI); /* get cvodeData from integratorInstance, it contains the values at the last time point, and just do the same as above */ data = IntegratorInstance_getData(iI); printf("Jacobian at time %g:\n", IntegratorInstance_getTime(iI)); printJacobian(odeModel, data); printf("J[6,4] changed its sign. Let's take a look at the equations:\n\n"); vi = ODEModel_getOdeVariableIndex(odeModel, 6); vj = ODEModel_getOdeVariableIndex(odeModel, 4); f = ODEModel_getOde(odeModel, vi); formula = SBML_formulaToString(f); printf("The ODE d%s/dt = \n%s \n\n", ODEModel_getVariableName(odeModel, vi), formula); free(formula); f = ODEModel_getJacobianEntry(odeModel, vi, vj); formula = SBML_formulaToString(f); printf("The jacobian entry (d%s/dt)/d%s = \n%s \n\n", ODEModel_getVariableName(odeModel, vi), ODEModel_getVariableName(odeModel, vj), formula); free(formula); VariableIndex_free(vi); VariableIndex_free(vj); printf("MAPK_P is both a substrate and a product of MKK_PP "); printf("in different reactions.\nTherefor the corresponding "); printf("entry in the jacobian can change its sign, depending "); printf("on concentrations!\n"); /* finally draw a `species interaction graph' of the jacobian' */ drawJacoby(data, "jacobian", "gif"); printf("Take a look at jacobian interaction graph in"); printf("file jacobian_jm.gif that has just been constructed.\n"); printf("If you have compiled w/o graphviz, you just have a textfile"); printf(" jacobian.dot\n"); printf("Thx and good bye!\n"); /* note that this cvodeData MUST NOT be freed, it stays with and will be freed together with integratorInstance */ IntegratorInstance_free(iI); CvodeSettings_free(set); } else { SolverError_dumpAndClearErrors(); printf("Sorry, for this system we couldn't generate the Jacobian.\n"); printf("Integration can still be run with internal approximation.\n"); } ODEModel_free(odeModel); return 1; }