Java tutorial
/* * Copyright (C) 2012 uebb.tu-berlin.de. * * This file is part of modim * * modim is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * modim is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with modim. If not, see <http://www.gnu.org/licenses/>. */ package de.tuberlin.uebb.jdae.simulation; import gnu.trove.map.hash.TObjectDoubleHashMap; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.math3.ode.FirstOrderIntegrator; import org.apache.commons.math3.ode.nonstiff.DormandPrince54Integrator; import org.apache.commons.math3.ode.nonstiff.EulerIntegrator; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import de.tuberlin.uebb.jdae.dae.LoadableModel; import de.tuberlin.uebb.jdae.hlmsl.Equation; import de.tuberlin.uebb.jdae.hlmsl.Unknown; import de.tuberlin.uebb.jdae.llmsl.DataLayout; import de.tuberlin.uebb.jdae.llmsl.ExecutableDAE; import de.tuberlin.uebb.jdae.llmsl.GlobalEquation; import de.tuberlin.uebb.jdae.llmsl.GlobalVariable; import de.tuberlin.uebb.jdae.llmsl.events.ContinuousEvent; import de.tuberlin.uebb.jdae.transformation.Causalisation; import de.tuberlin.uebb.jdae.transformation.InitializationCausalisation; import de.tuberlin.uebb.jdae.transformation.InitializationMatching; import de.tuberlin.uebb.jdae.transformation.Matching; import de.tuberlin.uebb.jdae.transformation.Reduction; /** * Simulation entry point. This class contains a unique * {@link DerivativeCollector} which allows {@link Causalisation} to create an * explicit ODE. The actual calculation is done in a newly allocated * {@link SolvableDAE}. * * @author Christoph Hger <christoph.hoeger@tu-berlin.de> * */ public final class DefaultSimulationRuntime implements SimulationRuntime { public final Logger logger; private int unknowns = 0; private ResultStorage results; public DefaultSimulationRuntime(Logger l) { super(); this.logger = l; logger.setLevel(Level.INFO); } public DefaultSimulationRuntime() { this(Logger.getLogger("simulation")); } /* * (nicht-Javadoc) * * @see * de.tuberlin.uebb.jdae.simulation.ISimulationRuntime#simulateFixedStep * (de.tuberlin.uebb.jdae.dae.SolvableDAE, java.util.Map, double, int) */ @Override public SimulationOptions simulateFixedStep(ExecutableDAE dae, double stop_time, final int steps) { final double stepSize = (stop_time / steps); final FirstOrderIntegrator i = new EulerIntegrator(stepSize); final SimulationOptions options = new SimulationOptions(0.0, stop_time, stepSize * 1e-3, stepSize, stepSize, i, new TObjectDoubleHashMap<Unknown>()); simulate(dae.withOptions(options)); return options; } @Override public SimulationOptions simulateInlineFixedStep(ExecutableDAE dae, double stop_time, final int steps) { final double stepSize = (stop_time / steps); final SimulationOptions options = new SimulationOptions(0.0, stop_time, stepSize * 1e-3, stepSize, stepSize, InlineIntegratorSelection.INLINE_FORWARD_EULER, new TObjectDoubleHashMap<Unknown>()); simulate(dae.withOptions(options)); return options; } /* * (nicht-Javadoc) * * @see * de.tuberlin.uebb.jdae.simulation.ISimulationRuntime#simulateVariableStep * (de.tuberlin.uebb.jdae.dae.SolvableDAE, java.util.Map, double, double, * double, double, double) */ @Override public SimulationOptions simulateVariableStep(ExecutableDAE dae, double stop_time, double minStep, double maxStep, double absoluteTolerance, double relativeTolerance) { final FirstOrderIntegrator i = new DormandPrince54Integrator(minStep, maxStep, absoluteTolerance, relativeTolerance); final SimulationOptions options = new SimulationOptions(0.0, stop_time, absoluteTolerance, minStep, maxStep, i, new TObjectDoubleHashMap<Unknown>()); simulate(dae.withOptions(options)); return options; } @Override public ResultStorage lastResults() { return results; } @Override public void simulate(ExecutableDAE dae) { results = new ResultStorage(dae); final long iStart = System.currentTimeMillis(); final SimulationOptions options = dae.options; dae.initialize(); logger.log(Level.INFO, "Initialization done after: {0}ms", (System.currentTimeMillis() - iStart)); logger.log(Level.INFO, "About to simulate using options: {0}", options); if (options.integrator != null) { options.integrator.clearEventHandlers(); options.integrator.clearStepHandlers(); options.integrator.addStepHandler(results); // TODO: add event Handler } final long start = System.currentTimeMillis(); dae.integrate(results); logger.log(Level.INFO, "Simulation finished after {1} accepted steps, {2} system-evaluations in {0}ms", new Object[] { System.currentTimeMillis() - start, results.results.size(), dae.getEvaluations() }); } @Override public Reduction reduce(final Collection<Equation> equations) { final Reduction reduction = new Reduction(equations); logger.log(Level.INFO, "Reduced system to {0} non-equality equations.", reduction.reduced.size()); return reduction; } @Override public ExecutableDAE causalise(LoadableModel model, SimulationOptions options) { final Reduction reduction = reduce(model.equations()); final Collection<ContinuousEvent> events = model.events(reduction.ctxt); return causalise(reduction, Lists.transform(ImmutableList.copyOf(model.initialEquations()), GlobalEquation.bindFrom(reduction.ctxt)), model.initials(reduction.ctxt), events.toArray(new ContinuousEvent[events.size()]), options); } @Override public ExecutableDAE causalise(Reduction reduction, List<GlobalEquation> initialEquations, Map<GlobalVariable, Double> startValues, ContinuousEvent[] c_events, SimulationOptions options) { final long match_start = System.currentTimeMillis(); final Matching matching = new Matching(reduction, logger); logger.log(Level.INFO, "Matched {0} equations in {1}ms", new Object[] { matching.assignment.length, System.currentTimeMillis() - match_start }); final long causalise_start = System.currentTimeMillis(); final Causalisation causality = new Causalisation(reduction, matching); logger.log(Level.INFO, "Created a causality-relation in {0}ms", new Object[] { System.currentTimeMillis() - causalise_start }); final InitializationMatching iMatching = new InitializationMatching(reduction, causality, matching, initialEquations, startValues, logger); final InitializationCausalisation iCausalisation = new InitializationCausalisation(iMatching, logger); final ExecutableDAE dae = new ExecutableDAE(new DataLayout(causality.layout), causality, iCausalisation, c_events, options); for (Map.Entry<GlobalVariable, Double> e : startValues.entrySet()) { dae.set(e.getKey(), e.getValue()); } return dae; } @Override public Unknown newUnknown(String name) { return new Unknown(name, ++unknowns, 0); } }