SBML_ODESOLVER_API cvodeResults_t *IntegratorInstance_createResults(integratorInstance_t *engine) { int i, j, k; cvodeResults_t *results; cvodeSettings_t *opt = engine->opt; cvodeResults_t *iResults = engine->results; if ( !opt->StoreResults || iResults == NULL ) return NULL; results = CvodeResults_create(engine->data, iResults->nout); RETURN_ON_FATALS_WITH(0); results->nout = iResults->nout; for ( i=0; i <=results->nout; i++ ) { results->time[i] = iResults->time[i]; for ( j=0; j < iResults->nvalues; j++ ) results->value[j][i] = iResults->value[j][i]; } if ( iResults->sensitivity != NULL ) { CvodeResults_allocateSens(results, iResults->neq, iResults->nsens, iResults->nout); for ( i=0; i<results->neq; i++ ) for ( j=0; j<results->nsens; ++j ) for ( k=0; k<=results->nout; k++ ) results->sensitivity[i][j][k] = iResults->sensitivity[i][j][k]; } return results; }
/* 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; }
/*!!! 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; }