static void printJacobian(odeModel_t *odeModel, cvodeData_t *data) { int i, j; const ASTNode_t *f = NULL; printf("i\\j "); for ( j=0; j<ODEModel_getNeq(odeModel); j++ ) printf("%d ", j); printf("\n"); for ( i=0; i<ODEModel_getNeq(odeModel); i++ ) { printf("%d ", i); for ( j=0; j<ODEModel_getNeq(odeModel); j++ ) { f = ODEModel_getJacobianIJEntry(odeModel, i, j); /* now let's see wether the entry is positive or negative at this point */ if ( evaluateAST((ASTNode_t *)f, data) < 0 ) printf("- "); if ( evaluateAST((ASTNode_t *)f, data) > 0 ) printf("+ "); if ( evaluateAST((ASTNode_t *)f, data) == 0 ) printf("0 "); } printf("\n\n"); } printf("\n"); }
static printSensiMatrix(odeModel_t *odeModel, cvodeData_t *data) { int i, j; const ASTNode_t *f = NULL; char *formula; /* first, get the number of equations of the ODE system */ int neq = ODEModel_getNeq(odeModel); printf("i\\j "); for ( j=0; j<ODEModel_getNsens(odeModel); j++ ) printf("%d ", j); printf("\n"); for ( i=0; i<ODEModel_getNeq(odeModel); i++ ) { printf("%d ", i); for ( j=0; j<ODEModel_getNsens(odeModel); j++ ) { f = ODEModel_getSensIJEntry(odeModel, i, j); /* now let's see wether the entry is positive or negative at this point */ if ( evaluateAST((ASTNode_t *)f, data) < 0 ) printf("- "); if ( evaluateAST((ASTNode_t *)f, data) > 0 ) printf("+ "); if ( evaluateAST((ASTNode_t *)f, data) == 0 ) printf("0 "); } printf("\n\n"); } printf("\n"); }
int main (void) { cvodeSettings_t *options = CvodeSettings_createWithTime(10000, 1000); odeModel_t *odemodel = ODEModel_createFromFile("MAPK.xml"); integratorInstance_t *ii = IntegratorInstance_create(odemodel, options); ASTNode_t *f = SBML_parseFormula("MAPK_PP"); ASTNode_t *f2 = SBML_parseFormula("MAPK + MAPK_P"); ASTNode_t *f3 = SBML_parseFormula("MAPK + MAPK_P + MAPK_PP"); cvodeData_t *data = IntegratorInstance_getData(ii); while( ! IntegratorInstance_timeCourseCompleted(ii) ) if ( IntegratorInstance_integrateOneStep(ii ) ) { printf(" active MAPK concentration at time %g:\t%7.3f\n", IntegratorInstance_getTime(ii), evaluateAST(f, data)); printf("inactive MAPK concentration at time %g:\t%7.3f\n", IntegratorInstance_getTime(ii), evaluateAST(f2, data)); printf(" total:\t%7.3f\n\n", evaluateAST(f3, data)); } else break; SolverError_dump(); ODEModel_free(odemodel); IntegratorInstance_free(ii); ASTNode_free(f); ASTNode_free(f2); return (EXIT_SUCCESS); }
static void printSensiMatrix(odeSense_t *os, cvodeData_t *data) { int i, j; const ASTNode_t *f = NULL; printf("i\\j "); for ( j=0; j<ODESense_getNsens(os); j++ ) printf("%d ", j); printf("\n"); for ( i=0; i<ODESense_getNeq(os); i++ ) { printf("%d ", i); for ( j=0; j<ODESense_getNsens(os); j++ ) { f = ODESense_getSensIJEntry(os, i, j); /* now let's see wether the entry is positive or negative at this point */ if ( evaluateAST((ASTNode_t *)f, data) < 0 ) printf("- "); if ( evaluateAST((ASTNode_t *)f, data) > 0 ) printf("+ "); if ( evaluateAST((ASTNode_t *)f, data) == 0 ) printf("0 "); } printf("\n\n"); } printf("\n"); }
int IntegratorInstance_updateData(integratorInstance_t *engine) { int i, flag = 1; cvodeSolver_t *solver = engine->solver; cvodeData_t *data = engine->data; cvodeSettings_t *opt = engine->opt; cvodeResults_t *results = engine->results; odeModel_t *om = engine->om; /* update rest of cvodeData_t **/ data->currenttime = solver->t; for ( i=0; i<om->nass; i++ ) data->value[om->neq+i] = evaluateAST(om->assignment[i], data); /* check for event triggers and evaluate the triggered events' assignments; stop integration if requested by cvodeSettings */ if ( IntegratorInstance_checkTrigger(engine) ) { /* recalculate assignments - they may be dependent on event assignment results */ for ( i=0; i<om->nass; i++ ) data->value[om->neq+i] = evaluateAST(om->assignment[i], data); if (opt->HaltOnEvent) flag = 0; /* stop integration */ } /* store results */ if (opt->StoreResults) { results->nout = solver->iout; results->time[solver->iout] = solver->t; for ( i=0; i<data->nvalues; i++ ) results->value[i][solver->iout] = data->value[i]; } /* check for steady state if requested by cvodeSettings and stop integration if an approximate steady state is found */ if ( opt->SteadyState == 1 ) if ( IntegratorInstance_checkSteadyState(engine) ) flag = 0; /* stop integration */ /* increase integration step counter */ solver->iout++; /* ... and set next output time */ if ( opt->Indefinitely ) solver->tout += opt->Time; else if ( solver->iout <= solver->nout ) solver->tout = opt->TimePoints[solver->iout]; return flag; }
static int drawJacobyTxt(cvodeData_t *data, char *file) { int i, j; char filename[WORDSIZE]; FILE *f; sprintf(filename, "%s.dot", file); f = fopen(filename, "w"); fprintf(f ,"digraph jacoby {\n"); fprintf(f ,"overlap=scale;\n"); if ( Model_isSetName(data->model->m) ) fprintf(f ,"label=\"%s at time %g\";\n", Model_getName(data->model->m), data->currenttime); else if ( Model_isSetId(data->model->m) ) fprintf(f ,"label=\"%s at time %g\";\n", Model_getId(data->model->m), data->currenttime); else fprintf(f ,"label=\"at time %g\";\n", data->currenttime); /* Set edges from species A to species B if the corresponding entry in the jacobian ((d[B]/dt)/d[A]) is not '0'. Set edge color 'red' and arrowhead 'tee' if negative. */ for ( i=0; i<data->model->neq; i++ ) { for ( j=0; j<data->model->neq; j++ ) { if ( evaluateAST(data->model->jacob[i][j], data) != 0 ) { fprintf(f ,"%s->%s [label=\"%g\" ", data->model->names[j], data->model->names[i], evaluateAST(data->model->jacob[i][j], data)); if ( evaluateAST(data->model->jacob[i][j], data) < 0 ) fprintf(f ,"arrowhead=tee color=red];\n"); else fprintf(f ,"];\n"); } } } for ( i=0; i<data->model->neq; i++ ) { fprintf(f ,"%s [label=\"%s\"];", data->model->names[i], data->model->names[i]); } fprintf(f, "}\n"); return 1; }
SBML_ODESOLVER_API int IntegratorInstance_checkTrigger(integratorInstance_t *engine) { int i, j, fired; ASTNode_t *trigger, *assignment; Event_t *e; EventAssignment_t *ea; variableIndex_t *vi; cvodeSettings_t *opt = engine->opt; cvodeData_t *data = engine->data; odeModel_t *om = engine->om; fired = 0; for ( i=0; i<Model_getNumEvents(om->simple); i++ ) { e = Model_getEvent(om->simple, i); trigger = (ASTNode_t *) Event_getTrigger(e); if ( data->trigger[i] == 0 && evaluateAST(trigger, data) ) { if (opt->HaltOnEvent) SolverError_error(ERROR_ERROR_TYPE, SOLVER_ERROR_EVENT_TRIGGER_FIRED, "Event Trigger %d (%s) fired at time %g. " "Aborting simulation.", i, SBML_formulaToString(trigger), data->currenttime); /* removed AMF 08/11/05 else SolverError_error(WARNING_ERROR_TYPE, SOLVER_ERROR_EVENT_TRIGGER_FIRED, "Event Trigger %d (%s) fired at time %g. ", i, SBML_formulaToString(trigger), data->currenttime); */ fired++; data->trigger[i] = 1; for ( j=0; j<Event_getNumEventAssignments(e); j++ ) { ea = Event_getEventAssignment(e, j); assignment = (ASTNode_t *) EventAssignment_getMath(ea); vi = ODEModel_getVariableIndex(om, EventAssignment_getVariable(ea)); IntegratorInstance_setVariableValue(engine, vi, evaluateAST(assignment, data)); VariableIndex_free(vi); } } else { data->trigger[i] = 0; } } return fired; }
void printDeterminantTimeCourse(cvodeData_t *data, ASTNode_t *det, FILE *f) { int i,j; cvodeResults_t *results; if ( data == NULL || data->results == NULL ) { Warn(stderr, "No results, please integrate first.\n"); return; } if ( Opt.PrintMessage ) fprintf(stderr, "\nPrinting time course of det(j).\n\n"); results = data->results; fprintf(f, "#t det(j)\n"); fprintf(f, "##DETERMINANT OF THE JACOBIAN MATRIX\n"); for ( i = 0; i<=results->nout; i++ ) { fprintf(f, "%g ", results->time[i]); data->currenttime = results->time[i]; for ( j=0; j<data->model->neq; j++ ) { data->value[j] = results->value[j][i]; } fprintf(f, "%g\n", evaluateAST(det, data)); } fprintf(f, "##DETERMINANT OF THE JACOBIAN MATRIX\n"); fprintf(f, "#t det(j)\n"); fflush(f); }
SBML_ODESOLVER_API void CvodeData_initializeValues(cvodeData_t *data) { int i; odeModel_t *om = data->model; /* First, fill cvodeData_t structure with data from the derived SBML model */ /* get initial values (these come directly from SBML model) */ for ( i=0; i<data->nvalues; i++ ) data->value[i] = om->values[i]; /* set current time to 0 */ data->currenttime = 0.0; /* Then execute complete rule set: initial and normal assignment rules ! */ for ( i=0; i<(om->nass + om->ninitAss); i++ ) { nonzeroElem_t *ordered = om->initAssignmentOrder[i]; int idx = ordered->i; if ( idx == -1 ) idx = ordered->j; data->value[idx] = evaluateAST(ordered->ij, data); } data->allRulesUpdated = 1; /* ADJOINT */ /* Zeroing initial adjoint values */ if ( data->adjvalue != NULL ) for ( i=0; i<data->neq; i++ ) data->adjvalue[i] = 0.0; }
SBML_ODESOLVER_API void CvodeData_initializeValues(cvodeData_t *data) { int i; Parameter_t *p; Species_t *s; Compartment_t *c; odeModel_t *om = data->model; Model_t *ode = om->simple; /* First, fill cvodeData_t structure with data from the derived SBML model */ for ( i=0; i<data->nvalues; i++ ) { if ( (s = Model_getSpeciesById(ode, om->names[i])) ) data->value[i] = Species_getInitialConcentration(s); else if ( (c = Model_getCompartmentById(ode, om->names[i])) ) data->value[i] = Compartment_getSize(c); else if ((p = Model_getParameterById(ode, om->names[i])) ) data->value[i] = Parameter_getValue(p); } /* initialize assigned parameters */ for ( i=0; i<om->nass; i++ ) data->value[om->neq+i] = evaluateAST(om->assignment[i],data); /* set current time to 0 */ data->currenttime = 0.0; }
void printOdeTimeCourse(cvodeData_t *data, FILE *f) { int i,j; cvodeResults_t *results; if ( data == NULL || data->results == NULL ) { Warn(stderr, "No results, please integrate first.\n"); return; } #if USE_GRACE if ( Opt.Xmgrace == 1 ) { printXMGOdeTimeCourse(data); return; } #endif results = data->results; if ( Opt.PrintMessage ) fprintf(stderr, "\nPrinting time course of the ODEs.\n\n"); fprintf(f, "#t "); for (i=0; i<data->model->neq; i++ ) { fprintf(f, "%s ", data->model->names[i]); } fprintf(f, "\n"); fprintf(f, "##ODE VALUES\n"); for ( i=0; i<=results->nout; ++i ) { fprintf(f, "%g ", results->time[i]); data->currenttime = results->time[i]; for ( j=0; j<data->model->neq; j++ ) { data->value[j] = results->value[j][i]; fprintf(f, "%g ", evaluateAST(data->model->ode[j],data)); } fprintf(f, "\n"); } fprintf(f, "##ODE VALUES\n"); fprintf(f, "#t "); for ( i=0; i<data->model->neq; i++ ) { fprintf(f, "%s ", data->model->names[i]); } fprintf(f, "\n"); fflush(f); #if !USE_GRACE if ( Opt.Xmgrace == 1 ) { fprintf(stderr, "odeSolver has been compiled without XMGRACE functionality.\n"); fprintf(stderr, "The requested data have been printed to stdout instead.\n"); } #endif }
static int JacRes(int N, realtype t, realtype cj, N_Vector y, N_Vector dy, N_Vector resvec, DlsMat J, void *jac_data, N_Vector tempv1, N_Vector tempv2, N_Vector tempv3) { int i, j; realtype *ydata; cvodeData_t *data; data = (cvodeData_t *) jac_data; ydata = NV_DATA_S(y); /* update ODE variables from CVODE */ for ( i=0; i<data->model->neq; i++ ) { data->value[i] = ydata[i]; } /* update algebraic constraint defined variables */ /* update assignment rules */ for ( i=0; i<data->model->nass; i++ ) { data->value[data->model->neq+i] = evaluateAST(data->model->assignment[i],data); } /* update time */ data->currenttime = t; /* evaluate Jacobian*/ for ( i=0; i<data->model->neq; i++ ) { for ( j=0; j<data->model->neq; j++ ) { DENSE_ELEM(J,i,j) = evaluateAST(data->model->jacob[i][j], data); if ( i == j ) DENSE_ELEM(J, i, j) -= cj; } } for ( i=0; i<data->model->nalg; i++ ) for ( j=0; j<data->model->nalg; j++ ) DENSE_ELEM(J,i,j) = 1.; /* algebraic jacobian here!! */ return (0); }
/* NOTE: provisional steady state finding! */ SBML_ODESOLVER_API int IntegratorInstance_checkSteadyState(integratorInstance_t *engine) { int i; double dy_mean, dy_var, dy_std; cvodeData_t *data = engine->data; odeModel_t *om = engine->om; /* calculate the mean and standard deviation of rates of change and store in cvodeData_t * */ dy_mean = 0.0; dy_var = 0.0; dy_std = 0.0; for ( i=0; i<om->neq; i++ ) { dy_mean += fabs(evaluateAST(om->ode[i],data)); } dy_mean = dy_mean / om->neq; for ( i=0; i<om->neq; i++ ) { dy_var += MySQR(evaluateAST(om->ode[i],data) - dy_mean); } dy_var = dy_var / (om->neq -1); dy_std = MySQRT(dy_var); /* stop integrator if mean + std of rates of change are lower than 1e-11 */ if ( (dy_mean + dy_std) < 1e-11 ) { data->steadystate = 1; SolverError_error(WARNING_ERROR_TYPE, SOLVER_MESSAGE_STEADYSTATE_FOUND, "Steady state found. " "Simulation aborted at %g seconds. " "Mean of rates: %g, std %g", data->currenttime, dy_mean, dy_std); return(1) ; } else { data->steadystate = 0; return(0); } }
static int fRes(realtype t, N_Vector y, N_Vector dy, N_Vector r, void *f_data) { int i; realtype *ydata, *dydata, *resdata; cvodeData_t *data; data = (cvodeData_t *) f_data; ydata = NV_DATA_S(y); dydata = NV_DATA_S(dy); resdata = NV_DATA_S(r); /* update ODE variables from CVODE */ for ( i=0; i<data->model->neq; i++ ) data->value[i] = ydata[i]; /* update algebraic constraint defined variables */ /* update assignment rules */ for ( i=0; i<data->model->nass; i++ ) data->value[data->model->neq+i] = evaluateAST(data->model->assignment[i],data); /* update time */ data->currenttime = t; /* evaluate residual functions: for available ODEs: 0 = dY/dt - dY/dt for algebraicRules: 0 = algebraic rule */ for ( i=0; i<data->model->neq; i++ ) resdata[i] = evaluateAST(data->model->ode[i],data) - dydata[i]; for ( i=0 ; i<data->model->nalg; i++ ) resdata[i] = evaluateAST(data->model->algebraic[i],data); return 0; }
static void fS(int Ns, realtype t, N_Vector y, N_Vector ydot, int iS, N_Vector yS, N_Vector ySdot, void *fS_data, N_Vector tmp1, N_Vector tmp2) { int i, j; realtype *ydata, *ySdata, *dySdata; cvodeData_t *data; data = (cvodeData_t *) fS_data; ydata = NV_DATA_S(y); ySdata = NV_DATA_S(yS); dySdata = NV_DATA_S(ySdot); /* update ODE variables from CVODE */ for ( i=0; i<data->model->neq; i++ ) { data->value[i] = ydata[i]; } /* update assignment rules */ for ( i=0; i<data->model->nass; i++ ) { data->value[data->model->neq+i] = evaluateAST(data->model->assignment[i],data); } /* update time */ data->currenttime = t; /* evaluate parametric `jacobian' */ for(i=0; i<data->model->neq; i++) { dySdata[i] = 0; for (j=0; j<data->model->neq; j++) { dySdata[i] += evaluateAST(data->model->jacob[i][j], data) * ySdata[j]; } dySdata[i] += evaluateAST(data->model->jacob_sens[i][iS], data); } }
/* initialize cvodeData from cvodeSettings and odeModel (could be separated in to functions to further support modularity and independence of data structures */ int CvodeData_initialize(cvodeData_t *data, cvodeSettings_t *opt, odeModel_t *om) { int i, j; /* data now also depends on cvodeSettings */ data->opt = opt; /* initialize values */ CvodeData_initializeValues(data); /* set current time */ data->currenttime = opt->TimePoints[0]; /* update assigned parameters, in case they depend on new time */ for ( i=0; i<om->nass; i++ ) data->value[om->neq+i] = evaluateAST(om->assignment[i],data); /* Then, check if formulas can be evaluated, and cvodeData_t * contains all necessary variables: evaluateAST(ASTNode_t *f, ,data) will ask the user for a value, if a a variable is unknown */ for ( i=0; i<om->neq; i++ ) evaluateAST(om->ode[i], data); /* create structures for sensitivity analysis */ if ( opt->Sensitivity ) { /* the following can later be called with numbers from sensitivity Settings inputs */ if ( data->sensitivity == NULL ) { CvodeData_allocateSens(data, om->neq, om->nconst); RETURN_ON_FATALS_WITH(0); } /* (re)set to 0.0 initial value */ for ( i=0; i<om->neq; i++ ) { for ( j=0; j<om->nsens; j++ ) { data->sensitivity[i][j] = 0.0; } } } /* Now we should have all variables, and can allocate the results structure, where the time series will be stored ... */ /* allow results only for finite integrations */ opt->StoreResults = !opt->Indefinitely && opt->StoreResults; /* free former results */ if ( data->results != NULL ) CvodeResults_free(data->results); /* create new results if required */ if ( opt->StoreResults ) { data->results = CvodeResults_create(data, opt->PrintStep); RETURN_ON_FATALS_WITH(0); if ( opt->Sensitivity ) { CvodeResults_allocateSens(data->results, om->neq, om->nconst, opt->PrintStep); /* write initial values for sensitivity */ for ( i=0; i<data->results->neq; i++ ) for ( j=0; j<data->results->nsens; ++j ) data->results->sensitivity[i][j][0] = data->sensitivity[i][j]; } RETURN_ON_FATALS_WITH(0); } return 1; }
SBML_ODESOLVER_API double evaluateAST(ASTNode_t *n, cvodeData_t *data) { int i, j, childnum; int found, datafound; int true; time_series_t *ts=data->model->time_series; double findtol=1e-5; ASTNodeType_t type; /* ASTNode_t **child; */ /* value* are for intermediate values. */ double value1, value2, value3, result; if ( n == NULL ) { SolverError_error(FATAL_ERROR_TYPE, SOLVER_ERROR_AST_UNKNOWN_NODE_TYPE, "evaluateAST: empty Abstract Syntax Tree (AST)."); return (0); } if ( ASTNode_isUnknown(n) ) { SolverError_error(FATAL_ERROR_TYPE, SOLVER_ERROR_AST_UNKNOWN_NODE_TYPE, "evaluateAST: unknown ASTNode type"); } result = 0; childnum = ASTNode_getNumChildren(n); type = ASTNode_getType(n); switch(type) { case AST_INTEGER: result = (double) ASTNode_getInteger(n); break; case AST_REAL: result = ASTNode_getReal(n); break; case AST_REAL_E: result = ASTNode_getReal(n); break; case AST_RATIONAL: result = ASTNode_getReal(n) ; break; case AST_NAME: /** VARIABLES: find the value of the variable in the data->value array. SOSlib's extension to libSBML's AST allows to add the index of the variable in this array to AST_NAME (ASTIndexName). If the ASTNode is not indexed, its array index is searched via the data->model->names array, which corresponds to the data->value array. For nodes with name `Time' or `time' the data->currenttime is returned. If no value is found a fatal error is produced. */ found = 0; if ( ASTNode_isSetIndex(n) ) { if ( ASTNode_isSetData(n) ) { /* if continuous data is observed, obtain interpolated result */ if ( (data->model->discrete_observation_data != 1) || (data->model->compute_vector_v != 1) ) { result = call(ASTNode_getIndex(n), data->currenttime, ts); } else /* if discrete data is observed, simply obtain value from time_series */ { datafound = 0; i = data->TimeSeriesIndex; if ( fabs(data->currenttime - ts->time[i]) < findtol ) { result = ts->data[ASTNode_getIndex(n)][i]; datafound++; } if ( datafound != 1) { SolverError_error(FATAL_ERROR_TYPE, SOLVER_ERROR_AST_EVALUATION_FAILED_DISCRETE_DATA, "use of discrete time series data failed; none or several time points matching current time"); result = 0; /* break; */ } else found = 1; } } else { /* majority case: just return the according value from data->values from the index stored by SOSlib ASTIndexNameNode sub-class of libSBML's ASTNode */ result = data->value[ASTNode_getIndex(n)]; } found++; } if ( found == 0 ) { for ( j=0; j<data->nvalues; j++ ) { if ( (strcmp(ASTNode_getName(n),data->model->names[j]) == 0) ) { result = data->value[j]; found++; } } } if ( found == 0 ) { SolverError_error(FATAL_ERROR_TYPE, SOLVER_ERROR_AST_EVALUATION_FAILED_MISSING_VALUE, "No value found for AST_NAME %s . Defaults to Zero " "to avoid program crash", ASTNode_getName(n)); result = 0; } break; case AST_FUNCTION_DELAY: SolverError_error(FATAL_ERROR_TYPE, SOLVER_ERROR_AST_EVALUATION_FAILED_DELAY, "Solving ODEs with Delay is not implemented. " "Defaults to 0 to avoid program crash"); result = 0.0; break; case AST_NAME_TIME: result = (double) data->currenttime; break; case AST_CONSTANT_E: /** exp(1) is used to adjust exponentiale to machine precision */ result = exp(1.); break; case AST_CONSTANT_FALSE: result = 0.0; break; case AST_CONSTANT_PI: /** pi = 4 * atan 1 is used to adjust Pi to machine precision */ result = 4.*atan(1.); break; case AST_CONSTANT_TRUE: result = 1.0; break; case AST_PLUS: result = 0.0; for ( i=0; i<childnum; i++) result += evaluateAST(child(n,i),data); break; case AST_MINUS: if ( childnum<2 ) result = - (evaluateAST(child(n,0),data)); else result = evaluateAST(child(n,0),data) - evaluateAST(child(n,1),data); break; case AST_TIMES: result = 1.0; for ( i=0; i<childnum; i++) { result *= evaluateAST(child(n,i),data); if (result == 0.0) break; /* small optimization by skipping the rest of children */ } break; case AST_DIVIDE: result = evaluateAST(child(n,0),data) / evaluateAST(child(n,1),data); break; case AST_POWER: result = pow(evaluateAST(child(n,0),data),evaluateAST(child(n,1),data)); break; case AST_LAMBDA: SolverError_error(FATAL_ERROR_TYPE, SOLVER_ERROR_AST_EVALUATION_FAILED_LAMBDA, "Lambda can only be used in SBML function definitions." " Defaults to 0 to avoid program crash"); result = 0.0; break; /** FUNCTIONS: */ case AST_FUNCTION: /** Evaluate external functions, if it was set with setUserDefinedFunction */ if ( UsrDefFunc == NULL ) { SolverError_error(FATAL_ERROR_TYPE, SOLVER_ERROR_AST_EVALUATION_FAILED_FUNCTION, "The function %s() has not been defined " "in the SBML input model or as an externally " "supplied function. Defaults to 0 to avoid " "program crash", ASTNode_getName(n)); result = 0.0; } else { double *func_vals = NULL; ASSIGN_NEW_MEMORY_BLOCK(func_vals, childnum+1, double, 0); for ( i=0; i<childnum; i++ ) func_vals[i] = evaluateAST(child(n,i), data); result = UsrDefFunc((char *)ASTNode_getName(n), childnum, func_vals); free(func_vals); } break; case AST_FUNCTION_ABS: result = fabs(evaluateAST(child(n,0),data)); break; case AST_FUNCTION_ARCCOS: result = acos(evaluateAST(child(n,0),data)) ; break; case AST_FUNCTION_ARCCOSH: result = aCosh(evaluateAST(child(n,0),data)); break; case AST_FUNCTION_ARCCOT: /** arccot x = arctan (1 / x) */ result = atan(1./ evaluateAST(child(n,0),data)); break; case AST_FUNCTION_ARCCOTH: /** arccoth x = 1/2 * ln((x+1)/(x-1)) */ value1 = evaluateAST(child(n,0),data); result = log((value1 + 1) / (value1 - 1))/2; break; case AST_FUNCTION_ARCCSC: /** arccsc(x) = Arctan(1 / sqrt((x - 1)(x + 1))) */ value1 = evaluateAST(child(n,0),data); result = atan(1/sqrt((value1-1)*(value1+1))); break; case AST_FUNCTION_ARCCSCH: /** arccsch(x) = ln((1/x) + sqrt((1/(x*x)) + 1)) */ value1 = evaluateAST(child(n,0),data); result = log(1/value1 + sqrt(1/(value1*value1)+1)); break; case AST_FUNCTION_ARCSEC: /** arcsec(x) = arccos(1/x) */ result = acos(1/evaluateAST(child(n,0),data)); break; case AST_FUNCTION_ARCSECH: /* arcsech(x) = arccosh(1/x) */ result = aCosh( 1. / evaluateAST(child(n,0),data)); break; case AST_FUNCTION_ARCSIN: result = asin(evaluateAST(child(n,0),data)); break; case AST_FUNCTION_ARCSINH: result = aSinh(evaluateAST(child(n,0),data)); break; case AST_FUNCTION_ARCTAN: result = atan(evaluateAST(child(n,0),data)); break; case AST_FUNCTION_ARCTANH: result = aTanh(evaluateAST(child(n,0),data)); break; case AST_FUNCTION_CEILING: result = ceil(evaluateAST(child(n,0),data)); break; case AST_FUNCTION_COS: result = cos(evaluateAST(child(n,0),data)); break; case AST_FUNCTION_COSH: result = cosh(evaluateAST(child(n,0),data)); break; case AST_FUNCTION_COT: /** cot x = 1 / tan x */ result = (1./tan(evaluateAST(child(n,0),data))); break; case AST_FUNCTION_COTH: /** coth x = cosh x / sinh x */ result = 1/tanh(evaluateAST(child(n,0),data)); break; case AST_FUNCTION_CSC: /** csc x = 1 / sin x */ result = (1./sin(evaluateAST(child(n,0),data))); break; case AST_FUNCTION_CSCH: /** csch x = 1 / sinh x */ result = (1./sinh(evaluateAST(child(n,0),data))); break; case AST_FUNCTION_EXP: result = exp(evaluateAST(child(n,0),data)); break; case AST_FUNCTION_FACTORIAL: { int j; value1 = evaluateAST(child(n,0),data); j = floor(value1); if ( value1 != j ) SolverError_error(FATAL_ERROR_TYPE, SOLVER_ERROR_AST_EVALUATION_FAILED_FLOAT_FACTORIAL, "The factorial is only implemented." "for integer values. The floor value of the " "passed float is used for calculation!"); for(result=1;j>1;--j) result *= j; } break; case AST_FUNCTION_FLOOR: result = floor(evaluateAST(child(n,0),data)); break; case AST_FUNCTION_LN: result = log(evaluateAST(child(n,0),data)); break; case AST_FUNCTION_LOG: /** log(x,y) = log10(y)/log10(x) (where x is the base) */ result = log10(evaluateAST(child(n,1),data)) / log10(evaluateAST(child(n,0),data)); break; case AST_FUNCTION_PIECEWISE: /** Piecewise: */ found = 0; /** Go through n pieces with 2 AST children for each piece, */ for ( i=0; i<(childnum-1); i=i+2 ) { if ( evaluateAST(child(n, i+1), data) ) { found++; result = evaluateAST(child(n, i), data); } } /** odd number of AST children: if no piece was true, otherwise remains */ /* i should be equal to childnum for even number piecewise AST and equal to childnum-1 for odd numbered piecewise ASTs */ if ( i == childnum-1 && found == 0 ) { found++; result = evaluateAST(child(n, i), data); } if ( found == 0 ) SolverError_error(FATAL_ERROR_TYPE, SOLVER_ERROR_AST_EVALUATION_FAILED_PIECEWISE, "Piecewise function failed; no true piece"); if ( found > 1 ) SolverError_error(FATAL_ERROR_TYPE, SOLVER_ERROR_AST_EVALUATION_FAILED_PIECEWISE, "Piecewise function failed; several true pieces"); break; case AST_FUNCTION_POWER: result = pow(evaluateAST(child(n,0),data),evaluateAST(child(n,1),data)); break; case AST_FUNCTION_ROOT: /*!!! ALSO do this in compiled code */ value1 = evaluateAST(child(n,1),data); value2 = evaluateAST(child(n,0),data); value3 = floor(value2); /* for odd root degrees, negative numbers are OK */ if ( value2 == value3 ) /* check whether degree is integer */ { if ( (value1 < 0) && ((int)value2 % 2 != 0) ) result = - pow(fabs(value1), 1./value2); else result = pow(value1, 1./value2); } else result = pow(value1, 1./value2); break; case AST_FUNCTION_SEC: /** sec x = 1 / cos x */ result = 1./cos(evaluateAST(child(n,0),data)); break; case AST_FUNCTION_SECH: /** sech x = 1 / cosh x */ result = 1./cosh(evaluateAST(child(n,0),data)); break; case AST_FUNCTION_SIN: result = sin(evaluateAST(child(n,0),data)); break; case AST_FUNCTION_SINH: result = sinh(evaluateAST(child(n,0),data)); break; case AST_FUNCTION_TAN: result = tan(evaluateAST(child(n,0),data)); break; case AST_FUNCTION_TANH: result = tanh(evaluateAST(child(n,0),data)); break; case AST_LOGICAL_AND: /** AND: all children must be true */ true = 0; for ( i=0; i<childnum; i++ ) true += evaluateAST(child(n,i),data); if ( true == childnum ) result = 1.0; else result = 0.0; break; case AST_LOGICAL_NOT: result = (double) (!(evaluateAST(child(n,0),data))); break; case AST_LOGICAL_OR: /** OR: at least one child must be true */ true = 0; for ( i=0; i<childnum; i++ ) true += evaluateAST(child(n,i),data); if ( true > 0 ) result = 1.0; else result = 0.0; break; case AST_LOGICAL_XOR: /* n-ary: true if an odd number of children is true */ true = 0; for ( i=0; i<childnum; i++ ) true += evaluateAST(child(n,i),data); if ( true % 2 != 0 ) result = 1.0; else result = 0.0; break; /* !!! check n-ary definitions for relational operators !!! */ case AST_RELATIONAL_EQ: /** n-ary: all children must be equal */ result = 1.0; if (childnum <= 1) break; value1 = evaluateAST(child(n,0),data); for ( i=1; i<childnum; i++ ) if ( value1 != evaluateAST(child(n,i),data) ) { result = 0.0; break; } break; case AST_RELATIONAL_GEQ: /** n-ary: each child must be greater than or equal to the following */ result = 1.0; if (childnum <= 1) break; value2 = evaluateAST(child(n,0),data); for ( i=1; i<childnum; i++ ) { value1 = value2; value2 = evaluateAST(child(n,i),data); if (value1 < value2) { result = 0.0; break; } } break; case AST_RELATIONAL_GT: /** n-ary: each child must be greater than the following */ result = 1.0; if (childnum <= 1) break; value2 = evaluateAST(child(n,0),data); for ( i=1; i<childnum; i++ ) { value1 = value2; value2 = evaluateAST(child(n,i),data); if (value1 <= value2) { result = 0.0; break; } } break; case AST_RELATIONAL_LEQ: /** n-ary: each child must be lower than or equal to the following */ result = 1.0; if (childnum <= 1) break; value2 = evaluateAST(child(n,0),data); for ( i=1; i<childnum; i++ ) { value1 = value2; value2 = evaluateAST(child(n,i),data); if (value1 > value2) { result = 0.0; break; } } break; case AST_RELATIONAL_LT : /* n-ary: each child must be lower than the following */ result = 1.0; if (childnum <= 1) break; value2 = evaluateAST(child(n,0),data); for ( i=1; i<childnum; i++ ) { value1 = value2; value2 = evaluateAST(child(n,i),data); if (value1 >= value2) { result = 0.0; break; } } break; case AST_RELATIONAL_NEQ: /* binary "not equal" */ result = (evaluateAST(child(n, 0), data) != evaluateAST(child(n, 1), data)); break; default: SolverError_error(FATAL_ERROR_TYPE, SOLVER_ERROR_AST_UNKNOWN_NODE_TYPE, "evaluateAST: unknown ASTNode type: %d", type); result = 0; break; } return result; }
static int printXMGJacobianTimeCourse ( cvodeData_t *data ) { int i, j, k, n; double maxY; double minY; double result; cvodeResults_t *results; maxY = 0.0; minY = 0.0; fprintf(stderr, "Printing time development of the jacobian matrix to XMGrace!\n"); results = data->results; if ( openXMGrace(data) > 0 ) { fprintf(stderr, "Error: Couldn't open XMGrace\n"); return 1; } GracePrintf("yaxis label \"%s\"", "jacobian matrix value"); if ( Model_isSetName(data->model->m) ) GracePrintf("subtitle \"%s, %s\"", Model_getName(data->model->m), "jacobian matrix time course"); else if ( Model_isSetId(data->model->m) ) GracePrintf("subtitle \"%s, %s\"", Model_getId(data->model->m), "jacobian matrix time course"); else GracePrintf("subtitle \"model has no name, %s/id\"", "jacobian matrix time course"); /* print legend */ n = 1; for ( i=0; i<data->model->neq; i++ ) { for ( j=0; j<data->model->neq; j++ ) { GracePrintf("g0.s%d legend \"%s / %s\"\n", n, data->model->names[i], data->model->names[j]); n++; } } GracePrintf("legend 1.155, 0.85"); GracePrintf("legend font 8"); GracePrintf("legend char size 0.6"); /* evaluate jacobian matrix for each time point and print to XMGrace */ for ( k = 0; k<=results->nout; k++ ) { n = 1; data->currenttime = results->time[i]; for ( i=0; i<data->model->neq; i++ ) { /* set specie values to values at time[k] */ data->value[i] = results->value[i][k]; for ( j=0; j<data->model->neq; j++ ) { result = evaluateAST(data->model->jacob[i][j], data); if ( result > maxY ) { maxY = result; GracePrintf("world ymax %g", 1.25*maxY); } if ( result < minY ) { minY = result; GracePrintf("world ymin %g", 1.25*minY); } GracePrintf("g0.s%d point %g, %g", n, results->time[k], result); n++; } } /* if ( k%10 == 0 ) { GracePrintf("yaxis tick major %g", 1.25*(fabs(maxY)+fabs(minY))/10); GracePrintf("redraw"); } */ } GracePrintf("yaxis tick major %g", 1.25*(fabs(maxY)+fabs(minY))/10); GracePrintf("redraw"); closeXMGrace(data, "jac"); return 0; }
SBML_ODESOLVER_API int drawJacoby(cvodeData_t *data, char *file, char *format) { #if !USE_GRAPHVIZ SolverError_error( WARNING_ERROR_TYPE, SOLVER_ERROR_NO_GRAPHVIZ, "odeSolver has been compiled without GRAPHIZ functionality. ", "Graphs are printed to stdout in the graphviz' .dot format."); drawJacobyTxt(data, file); #else int i, j; GVC_t *gvc; Agraph_t *g; Agnode_t *r; Agnode_t *s; Agedge_t *e; Agsym_t *a; char name[WORDSIZE]; char label[WORDSIZE]; char *output[3]; char *command = "dot"; char *formatopt; char *outfile; /* setting name of outfile */ ASSIGN_NEW_MEMORY_BLOCK(outfile, strlen(file)+ strlen(format)+7, char, 0); sprintf(outfile, "-o%s_jm.%s", file, format); /* setting output format */ ASSIGN_NEW_MEMORY_BLOCK(formatopt, strlen(format)+3, char, 0); sprintf(formatopt, "-T%s", format); /* construct command-line */ output[0] = command; output[1] = formatopt; output[2] = outfile; output[3] = NULL; /* set up renderer context */ gvc = (GVC_t *) gvContext(); #if GRAPHVIZ_MAJOR_VERSION == 2 && GRAPHVIZ_MINOR_VERSION < 4 dotneato_initialize(gvc, 3, output); #elif GRAPHVIZ_MAJOR_VERSION == 2 && GRAPHVIZ_MINOR_VERSION == 4 parse_args(gvc, 3, output); #elif GRAPHVIZ_MAJOR_VERSION == 2 && GRAPHVIZ_MINOR_VERSION >= 6 || GRAPHVIZ_MAJOR_VERSION >= 3 gvParseArgs(gvc, 3, output); #endif g = agopen("G", AGDIGRAPH); /* avoid overlapping nodes, for graph embedding by neato */ a = agraphattr(g, "overlap", ""); agxset(g, a->index, "scale"); /* set graph label */ if ( Model_isSetName(data->model->m) ) sprintf(label, "%s at time %g", Model_getName(data->model->m), data->currenttime); else if ( Model_isSetId(data->model->m) ) sprintf(label, "%s at time %g", Model_getId(data->model->m), data->currenttime); else sprintf(label, "label=\"at time %g\";\n", data->currenttime); a = agraphattr(g, "label", ""); agxset(g, a->index, label); /* Set edges from species A to species B if the corresponding entry in the jacobian ((d[B]/dt)/d[A]) is not '0'. Set edge color 'red' and arrowhead 'tee' if negative. */ for ( i=0; i<data->model->neq; i++ ) { for ( j=0; j<data->model->neq; j++ ) { if ( evaluateAST(data->model->jacob[i][j], data) != 0 ) { sprintf(name, "%s", data->model->names[j]); r = agnode(g,name); agset(r, "label", data->model->names[j]); sprintf(label, "%s.htm", data->model->names[j]); a = agnodeattr(g, "URL", ""); agxset(r, a->index, label); sprintf(name,"%s", data->model->names[i]); s = agnode(g,name); agset(s, "label", data->model->names[i]); sprintf(label, "%s.htm", data->model->names[i]); a = agnodeattr(g, "URL", ""); agxset(s, a->index, label); e = agedge(g,r,s); a = agedgeattr(g, "label", ""); sprintf(name, "%g", evaluateAST(data->model->jacob[i][j], data)); agxset (e, a->index, name); if ( evaluateAST(data->model->jacob[i][j], data) < 0 ) { a = agedgeattr(g, "arrowhead", ""); agxset(e, a->index, "tee"); a = agedgeattr(g, "color", ""); agxset(e, a->index, "red"); } } } } /* Compute a layout */ #if GRAPHVIZ_MAJOR_VERSION == 2 && GRAPHVIZ_MINOR_VERSION <= 2 gvBindContext(gvc, g); dot_layout(g); #elif GRAPHVIZ_MAJOR_VERSION == 2 && GRAPHVIZ_MINOR_VERSION == 4 gvlayout_layout(gvc, g); #elif GRAPHVIZ_MAJOR_VERSION == 2 && GRAPHVIZ_MINOR_VERSION >= 6 || GRAPHVIZ_MAJOR_VERSION >= 3 gvLayoutJobs(gvc, g); #endif /* Write the graph according to -T and -o options */ #if GRAPHVIZ_MAJOR_VERSION == 2 && GRAPHVIZ_MINOR_VERSION <= 2 dotneato_write(gvc); #elif GRAPHVIZ_MAJOR_VERSION == 2 && GRAPHVIZ_MINOR_VERSION == 4 emit_jobs(gvc, g); #elif GRAPHVIZ_MAJOR_VERSION == 2 && GRAPHVIZ_MINOR_VERSION >= 6 || GRAPHVIZ_MAJOR_VERSION >= 3 gvRenderJobs(gvc, g); #endif /* Clean out layout data */ #if GRAPHVIZ_MAJOR_VERSION == 2 && GRAPHVIZ_MINOR_VERSION <= 2 dot_cleanup(g); #elif GRAPHVIZ_MAJOR_VERSION == 2 && GRAPHVIZ_MINOR_VERSION == 4 gvlayout_cleanup(gvc, g); #elif GRAPHVIZ_MAJOR_VERSION == 2 && GRAPHVIZ_MINOR_VERSION >= 6 || GRAPHVIZ_MAJOR_VERSION >= 3 gvFreeLayout(gvc, g); #endif /* Free graph structures */ #if GRAPHVIZ_MAJOR_VERSION == 2 && GRAPHVIZ_MINOR_VERSION <= 2 dot_cleanup(g); #endif agclose(g); /* Clean up output file and errors */ #if GRAPHVIZ_MAJOR_VERSION == 2 && GRAPHVIZ_MINOR_VERSION <= 2 gvFREEcontext(gvc); dotneato_eof(gvc); #elif GRAPHVIZ_MAJOR_VERSION == 2 && GRAPHVIZ_MINOR_VERSION == 4 dotneato_terminate(gvc); #elif (GRAPHVIZ_MAJOR_VERSION == 2 && GRAPHVIZ_MINOR_VERSION >= 6) || GRAPHVIZ_MAJOR_VERSION >= 3 gvFreeContext(gvc); #endif xfree(formatopt); xfree(outfile); #endif return 1; }
/* 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 */ }
/*!!! TODO : clarify if this function can be called when the solver time is other than 0, and how it relates to CvodeData_initializeValues -> handling of initialAssignments !!!*/ int CvodeData_initialize(cvodeData_t *data, cvodeSettings_t *opt, odeModel_t *om, int keepValues) { int i; /* data now also depends on cvodeSettings */ data->opt = opt; /* if discrete data is used via settings */ if ( opt->observation_data_type == 1 ) om->discrete_observation_data=1; else om->discrete_observation_data=0; /* initialize values from odeModel */ if ( !keepValues ) CvodeData_initializeValues(data); /* reset steadystate flag */ data->steadystate = 0; /* set current time : WHEN NOT 0 ?? */ if ( opt->Indefinitely ) data->currenttime = 0; else data->currenttime = opt->TimePoints[0]; /* update assigned parameters, in case they depend on new time */ /* WHY ONLY IF TIME != 0 ?? */ if ( data->currenttime != 0.0 ) { for ( i=0; i< (om->nass); i++ ) { nonzeroElem_t *ordered = om->assignmentOrder[i]; data->value[ordered->i] = evaluateAST(ordered->ij, data); } data->allRulesUpdated = 1; } /* Then, check if formulas can be evaluated, and cvodeData_t * contains all necessary variables: evaluateAST(ASTNode_t *f, ,data) will ask the user for a value, if a a variable is unknown */ for ( i=0; i<om->neq; i++ ) evaluateAST(om->ode[i], data); /* evaluate event triggers and set flags with their initial state */ for ( i=0; i<data->nevents; i++ ) data->trigger[i] = evaluateAST(om->event[i], data); /* RESULTS: Now we should have all variables, and can allocate the results structure, where the time series will be stored ... */ /* free former results */ if ( data->results != NULL ) CvodeResults_free(data->results); /* allow results only for finite integrations */ /* this is the only place where options structure is changed internally! StoreResults is overruled by Indefinitely */ opt->StoreResults = !opt->Indefinitely && opt->StoreResults; /* create new results if required */ if ( opt->StoreResults ) { data->results = CvodeResults_create(data, opt->PrintStep); if ( data->results == NULL ) return 0; } return 1; }
static int printXMGOdeTimeCourse(cvodeData_t *data) { int i, j, n; double maxY; double minY; double result; cvodeResults_t *results; maxY = 0.01; minY = 0.0; fprintf(stderr, "Printing time development of the ODEs (rates) to XMGrace!\n"); results = data->results; if ( openXMGrace(data) > 0 ) { fprintf(stderr, "Error: Couldn't open XMGrace\n"); return 1; } GracePrintf("yaxis label \"%s\"", "ODE values"); if ( Model_isSetName(data->model->m) ) GracePrintf("subtitle \"%s, %s\"", Model_getName(data->model->m), "ODEs time course"); else if ( Model_isSetId(data->model->m) ) GracePrintf("subtitle \"%s, %s\"", Model_getId(data->model->m), "ODEs time course"); else GracePrintf("subtitle \"model has no name/id, %s\"", "ODEs time course"); /* print legend */ if ( printXMGLegend(data, data->model->neq) > 0 ){ fprintf(stderr, "Warning: Couldn't print legend\n"); return 1; } /* evaluate ODE at each time point and print to XMGrace */ for ( i=0; i<=results->nout; ++i ) { n = 1; data->currenttime = results->time[i]; for ( j=0; j<data->model->neq; j++ ) { data->value[j] = results->value[j][i]; } for ( j=0; j<data->model->neq; j++ ) { result = evaluateAST(data->model->ode[j],data); if ( result > maxY ) { maxY = result; GracePrintf("world ymax %g", 1.25*maxY); } if ( result < minY ) { minY = result; GracePrintf("world ymin %g", 1.25*minY); } GracePrintf("g0.s%d point %g, %g", n, results->time[i], result); n++; } /* if ( i%10 == 0 ) { GracePrintf("yaxis tick major %g", 1.25*(fabs(maxY)+fabs(minY))/10); GracePrintf("redraw"); } */ } GracePrintf("yaxis tick major %g", 1.25*(fabs(maxY)+fabs(minY))/10); GracePrintf("redraw"); closeXMGrace(data, "rates"); return 0; }
void printJacobianTimeCourse(cvodeData_t *data, FILE *f) { int i, j, k; cvodeResults_t *results; if ( data == NULL || data->results == NULL ) { Warn(stderr, "No results, please integrate first.\n"); return; } #if USE_GRACE if ( Opt.Xmgrace == 1 ) { printXMGJacobianTimeCourse(data); return; } #endif results = data->results; if ( Opt.PrintMessage ) fprintf(stderr, "Printing time course of the jacobian matrix.\n\n"); fprintf(f, "#t "); for ( i=0; i<data->model->neq; i++ ) { for ( j=0; j<data->model->neq; j++ ) { fprintf(f, "%s ", data->model->names[j]); } } fprintf(f, "\n"); fprintf(f, "##JACOBIAN MATRIX VALUES\n"); for ( k = 0; k<=results->nout; k++ ) { fprintf(f, "%g ", results->time[k]); data->currenttime = results->time[k]; for ( i=0; i<data->model->neq; i++ ) { data->value[i] = results->value[i][k]; } for ( i=0; i<data->model->neq; i++ ) { for ( j=0; j<data->model->neq; j++ ) { fprintf(f, "%g ", evaluateAST(data->model->jacob[i][j], data)); } } fprintf(f, "\n"); } fprintf(f, "##JACOBIAN MATRIX VALUES\n"); fprintf(f, "#t "); for ( i=0; i<data->model->neq; i++ ) { for ( j=0; j<data->model->neq; j++ ) { fprintf(f, "%s ", data->model->names[j]); } } fprintf(f, "\n"); fflush(f); #if !USE_GRACE if ( Opt.Xmgrace == 1 ) { fprintf(stderr, "odeSolver has been compiled without XMGRACE functionality.\n"); fprintf(stderr, "The requested data have been printed to stdout instead.\n"); } #endif }
static int printXMGReactionTimeCourse ( cvodeData_t *data ) { int i, j, k, n; double maxY, minY, result; Model_t *m; Reaction_t *r; KineticLaw_t *kl; ASTNode_t **kls; odeModel_t *om = data->model; cvodeResults_t *results = data->results; maxY = 0.0; minY = 0.0; fprintf(stderr, "Printing time development of reaction fluxes to XMGrace!\n"); if ( om->m == NULL ) { fprintf(stderr, "Error: No reaction model availabe\n"); return 1; } else m = om->m; if ( openXMGrace(data) > 0 ) { fprintf(stderr, "Error: Couldn't open XMGrace\n"); return 1; } GracePrintf("yaxis label \"%s\"", "flux [substance/time]"); if ( Model_isSetName(m) ) GracePrintf("subtitle \"%s, %s\"", Model_getName(m), "reaction flux time courses"); else if ( Model_isSetId(m) ) GracePrintf("subtitle \"%s, %s\"", Model_getId(m), "reaction flux time courses"); else GracePrintf("subtitle \"model has no name, %s/id\"", "reaction flux time courses"); /* print legend */ for ( i=0; i<Model_getNumReactions(m); i++ ) { r = Model_getReaction(m, i); if ( Reaction_isSetName(r) ) GracePrintf("g0.s%d legend \"%s: %s \"\n", i+1, Reaction_getId(r), Reaction_getName(r)); else GracePrintf("g0.s%d legend \"%s \"\n", i+1, Reaction_getId(r)); } GracePrintf("legend 1.155, 0.85"); GracePrintf("legend font 8"); GracePrintf("legend char size 0.6"); if(!(kls = (ASTNode_t **)calloc(Model_getNumReactions(m), sizeof(ASTNode_t *)))) fprintf(stderr, "failed!\n"); for ( i=0; i<Model_getNumReactions(m); i++ ) { r = Model_getReaction(m, i); kl = Reaction_getKineticLaw(r); kls[i] = copyAST(KineticLaw_getMath(kl)); AST_replaceNameByParameters(kls[i], KineticLaw_getListOfParameters(kl)); AST_replaceConstants(m, kls[i]); } /* evaluate flux for each time point and print to XMGrace */ for ( i=0; i<=results->nout; i++ ) { n = 1; /* set time and variable values to values at time[k] */ data->currenttime = results->time[i]; for ( j=0; j<data->model->neq; j++ ) data->value[j] = results->value[j][i]; /* evaluate kinetic law expressions */ for ( j=0; j<Model_getNumReactions(m); j++ ) { result = evaluateAST(kls[j], data); if ( result > maxY ) { maxY = result; GracePrintf("world ymax %g", 1.25*maxY); } if ( result < minY ) { minY = result; GracePrintf("world ymin %g", 1.25*minY); } GracePrintf("g0.s%d point %g, %g", n, results->time[i], result); n++; } } GracePrintf("yaxis tick major %g", 1.25*(fabs(maxY)+fabs(minY))/10); GracePrintf("redraw"); closeXMGrace(data, "flux"); /* free temporary ASTNodes */ for ( i=0; i<Model_getNumReactions(m); i++ ) ASTNode_free(kls[i]); free(kls); return 0; }
void printReactionTimeCourse(cvodeData_t *data, Model_t *m, FILE *f) { int i, j; cvodeResults_t *results; Reaction_t *r; KineticLaw_t *kl; ASTNode_t **kls; if ( data == NULL || data->results == NULL ) { Warn(stderr, "No results, please integrate first.\n"); return; } #if USE_GRACE if ( Opt.Xmgrace == 1 ) { printXMGReactionTimeCourse(data); return; } #endif results = data->results; if ( Opt.PrintMessage ) fprintf(stderr, "\nPrinting time course of the reactions (kinetic laws).\n\n"); if(!(kls = (ASTNode_t **)calloc(Model_getNumReactions(m), sizeof(ASTNode_t *)))) { fprintf(stderr, "failed!\n"); } fprintf(f, "#t "); for ( i=0; i<Model_getNumReactions(m); i++ ) { r = Model_getReaction(m, i); kl = Reaction_getKineticLaw(r); kls[i] = copyAST(KineticLaw_getMath(kl)); AST_replaceNameByParameters(kls[i], KineticLaw_getListOfParameters(kl)); AST_replaceConstants(m, kls[i]); fprintf(f, "%s ", Reaction_getId(r)); } fprintf(f, "\n"); fprintf(f, "##REACTION RATES\n"); for ( i=0; i<=results->nout; ++i ) { fprintf(f, "%g ", results->time[i]); data->currenttime = results->time[i]; for ( j=0; j<data->model->neq; j++ ) { data->value[j] = results->value[j][i]; } for ( j=0; j<Model_getNumReactions(m); j++ ) { fprintf(f, "%g ", evaluateAST(kls[j], data)); } fprintf(f, "\n"); } fprintf(f, "##REACTION RATES\n"); fprintf(f, "#t "); for ( i=0; i<Model_getNumReactions(m); i++ ) { r = Model_getReaction(m, i); fprintf(f, "%s ", Reaction_getId(r)); ASTNode_free(kls[i]); } free(kls); fprintf(f, "\n"); fflush(f); #if !USE_GRACE if ( Opt.Xmgrace == 1 ) { fprintf(stderr, "odeSolver has been compiled without XMGRACE functionality.\n"); fprintf(stderr, "The requested data have been printed to stdout instead.\n"); } #endif }