public static SampleValue Equilibrate(Env env, Symbol outSymbol, SampleValue inSample, Noise noise, double fortime, Netlist netlist, Style style) { inSample.CheckConsumed(style); // we will consume it later, but we need to check now double initialTime = 0.0; double finalTime = fortime; string sampleName = (outSymbol.Raw() == "vessel") ? "" : "Sample " + inSample.FormatSymbol(style); KChartHandler.ChartClear(sampleName, "s", "M", style); List <SpeciesValue> inSpecies = inSample.stateMap.species; State initialState = inSample.stateMap.state; if ((noise == Noise.None) && initialState.lna) { initialState = new State(initialState.size, lna: false).InitMeans(initialState.MeanVector()); } if ((noise != Noise.None) && !initialState.lna) { initialState = new State(initialState.size, lna: true).InitMeans(initialState.MeanVector()); } List <ReactionValue> reactions = inSample.RelevantReactions(netlist, style); CRN crn = new CRN(inSample, reactions, precomputeLNA: (noise != Noise.None) && KControls.precomputeLNA); KChartHandler.SetMeanFlowDictionary(crn.MeanFlowDictionary(), style); // List<ReportEntry> reports = netlist.Reports(inSpecies); List <ReportEntry> reports = inSample.RelevantReports(style); Exec.lastExecution.lastCRN = crn; KGui.gui.GuiOutputSetText(crn.FormatNice(style)); Exec.lastExecution.ResetGraphCache(); Func <double, double, Vector, Func <double, Vector, Vector>, IEnumerable <SolPoint> > Solver; if (KControls.solver == "GearBDF") { Solver = Ode.GearBDF; } else if (KControls.solver == "RK547M") { Solver = Ode.RK547M; } else { throw new Error("No solver"); } Func <double, Vector, Vector> Flux; if (noise != Noise.None) { Flux = (t, x) => crn.LNAFlux(t, x, style); } else { Flux = (t, x) => crn.Flux(t, x, style); } bool nonTrivialSolution = (inSpecies.Count > 0) && // we don't want to run on the empty species list: Oslo crashes (!crn.Trivial(style)) && // we don't want to run trivial ODEs: some Oslo solvers hang on very small stepping finalTime > 0; // we don't want to run when fortime==0 // INTEGRATE (double lastTime, State lastState) = Integrate(Solver, initialState, initialTime, finalTime, Flux, inSample, reports, noise, nonTrivialSolution, style); if (lastState == null) { lastState = initialState.Clone(); } lastState = lastState.Positive(); List <SpeciesValue> outSpecies = new List <SpeciesValue> { }; foreach (SpeciesValue sp in inSpecies) { outSpecies.Add(sp); // the species list may be destructively modified (added to) later in the new sample } SampleValue outSample = new SampleValue(outSymbol, new StateMap(outSymbol, outSpecies, lastState), new NumberValue(inSample.Volume()), new NumberValue(inSample.Temperature()), produced: true); outSample.AddReports(inSample.RelevantReports(style)); foreach (ReportEntry report in reports) { // an equilibrate may pick up the reports of a previous equilibrate, so we reassign the report even if it has already been assigned // this does not really affect lexical binding because a second report with the same name will get a new symbol // P.S. this was changed so that an equilibrate no longer picks up reports of previous equilibrate, so the issue should not arise if (report.timecourse != null) { env.AssignValue(report.timecourse, KChartHandler.ToTimecourse(report.timecourse, report.flow, style), reassign: true); } } inSample.Consume(reactions, lastTime, lastState, netlist, style); return(outSample); }