From bad031dbe216999c7a104ad6e9a072e3ac46a9df Mon Sep 17 00:00:00 2001 From: jkauttio Date: Tue, 19 Nov 2013 12:58:37 +0000 Subject: [PATCH] Implement a basic error reporting system for the new solver interface. fixes #4513 git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@28326 ac1ea38d-2e2b-0410-8846-a27921b304fc --- .../sysdyn/manager/SysdynExperiment.java | 70 +++---------- .../representation/IndependentVariable.java | 2 +- .../org/simantics/sysdyn/solver/ISolver.java | 9 +- .../sysdyn/solver/InternalSolver.java | 27 ++---- .../sysdyn/solver/SimulationJob.java | 32 ------ .../sysdyn/solver/SysdynSimulationJob.java | 97 +++++++++++++++++++ 6 files changed, 122 insertions(+), 115 deletions(-) delete mode 100644 org.simantics.sysdyn/src/org/simantics/sysdyn/solver/SimulationJob.java create mode 100644 org.simantics.sysdyn/src/org/simantics/sysdyn/solver/SysdynSimulationJob.java diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynExperiment.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynExperiment.java index 78685a17..4fbae4f4 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynExperiment.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynExperiment.java @@ -42,10 +42,7 @@ import org.simantics.simulation.experiment.IExperimentListener; import org.simantics.simulation.ontology.SimulationResource; import org.simantics.sysdyn.Activator; import org.simantics.sysdyn.adapter.VariableValueSubscription; -import org.simantics.sysdyn.solver.ISolverMonitor; -import org.simantics.sysdyn.solver.ISolver; -import org.simantics.sysdyn.solver.InternalSolver; -import org.simantics.sysdyn.solver.SimulationJob; +import org.simantics.sysdyn.solver.SysdynSimulationJob; import org.simantics.sysdyn.solver.SolverSettings; import org.simantics.sysdyn.solver.SolverSettings.SolverType; @@ -55,7 +52,7 @@ public class SysdynExperiment extends Experiment implements IDynamicExperiment, private Session session; private Runnable modificationListener; - private SysdynModel sysdynModel; + public SysdynModel sysdynModel; private boolean toggled = false; @SuppressWarnings("rawtypes") @@ -68,15 +65,12 @@ public class SysdynExperiment extends Experiment implements IDynamicExperiment, private ExperimentState sysdynExperimentState; private SysdynResult result; - - private ISolver solver; private String experimentName; private File experimentDir; public SysdynExperiment(Resource experiment, Resource model) { super(experiment, model); - this.solver = null; this.experimentName = "Experiment"; this.experimentDir = null; } @@ -151,7 +145,7 @@ public class SysdynExperiment extends Experiment implements IDynamicExperiment, public void simulate(boolean enabled) { // TODO: add state checks if (enabled) { - SimulationJob job = new SimulationJob(sysdynModel.getConfiguration().getLabel(), this); + SysdynSimulationJob job = new SysdynSimulationJob(sysdynModel.getConfiguration().getLabel(), this); job.schedule(); } } @@ -306,6 +300,7 @@ public class SysdynExperiment extends Experiment implements IDynamicExperiment, * @param activate The active-state of this experiment */ protected void toggleActivation(ReadGraph graph, final boolean activate) { + // TODO: does not work correctly, the experiment can appear inactive even when it is actually active VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class); final Session session = graph.getSession(); session.asyncRequest(new WriteRequest(support.getWorkspacePersistent("experiments")) { @@ -318,6 +313,7 @@ public class SysdynExperiment extends Experiment implements IDynamicExperiment, @Override public void perform(WriteGraph graph) throws DatabaseException { SimulationResource SIMU = SimulationResource.getInstance(graph); + System.err.println("CHANGE ACTIVE STATE OF EXPERIMENT"); if(activate) graph.claim(experiment, SIMU.IsActive, experiment); else @@ -387,7 +383,7 @@ public class SysdynExperiment extends Experiment implements IDynamicExperiment, */ public void resultsChanged() { long time = System.nanoTime(); - if(time - previousVariableUpdateTime > 10000000) { + if (time - previousVariableUpdateTime > 10000000) { updateSubscriptions(); previousVariableUpdateTime = time; } @@ -424,53 +420,8 @@ public class SysdynExperiment extends Experiment implements IDynamicExperiment, public void rewindTo(double time) { throw new UnsupportedOperationException(); } - - // simulation stuff - - public int simulationSteps() { - return 5; - } - - public void simulate(ISolverMonitor solverMonitor, IProgressMonitor progressMonitor) { - progressMonitor.subTask("selecting solver..."); - - SolverType preferenceType = SolverSettings.getSelectedSolverType(); - if (solver == null || !solver.getType().equals(preferenceType)) { - switch(preferenceType) { - case INTERNAL: - this.solver = new InternalSolver(this, sysdynModel, solverMonitor); - break; - case OPENMODELICA: - System.err.println("please reload the experiment"); - return; - default: - // should not happen - return; - } - } - - progressMonitor.worked(1); - progressMonitor.subTask("generating model..."); - - solver.initialize(); - - progressMonitor.worked(1); - progressMonitor.subTask("building model..."); - - solver.buildModel(); - - progressMonitor.worked(1); - progressMonitor.subTask("running solver..."); - - solver.runSolver(); - - progressMonitor.worked(1); - progressMonitor.subTask("getting results..."); - - solver.updateResults(); - - progressMonitor.worked(1); - } + + // TODO: clean this up a bit maybe? public File getExperimentDir() { @@ -491,6 +442,11 @@ public class SysdynExperiment extends Experiment implements IDynamicExperiment, return experimentDir; } + + public SolverType getSolverType() { + // should be defined in experiment properties (similarly to other experiment types) + return SolverSettings.getSelectedSolverType(); + } } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/IndependentVariable.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/IndependentVariable.java index bef05db0..d61abcf0 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/IndependentVariable.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/IndependentVariable.java @@ -137,7 +137,7 @@ public abstract class IndependentVariable extends Variable { * @return equations or null */ protected String getVariableEquation() { - if(this.expressions == null) + if(this.expressions == null || this.expressions.isEmpty()) return null; ArrayList expressions = getExpressions(); diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/ISolver.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/ISolver.java index a55bf3d4..d52a67c7 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/ISolver.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/ISolver.java @@ -4,9 +4,10 @@ import org.simantics.sysdyn.solver.SolverSettings.SolverType; public interface ISolver { - public void initialize(); - public void buildModel(); - public void runSolver(); - public void updateResults(); + public void initialize() throws Exception; + public void buildModel() throws Exception; + public void runSolver() throws Exception; + public void updateResults() throws Exception; public SolverType getType(); + } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/InternalSolver.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/InternalSolver.java index db1f4eb9..4c00a72e 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/InternalSolver.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/InternalSolver.java @@ -2,7 +2,6 @@ package org.simantics.sysdyn.solver; import java.util.HashMap; -import org.simantics.db.exception.DatabaseException; import org.simantics.modelica.ModelicaManager; import org.simantics.modelica.SimulationLocation; import org.simantics.sysdyn.manager.FunctionUtils; @@ -46,16 +45,7 @@ public class InternalSolver implements ISolver { } @Override - public void initialize() { - // TODO: is this really really necessary? - try { - model.update(); - } - catch (DatabaseException e) { - e.printStackTrace(); - return; - } - + public void initialize() throws Exception { String omVersion = ModelicaManager.getDefaultOMVersion(); String modelContent = ModelicaWriter.write(model.getModules(), false, omVersion); @@ -89,18 +79,13 @@ public class InternalSolver implements ISolver { } @Override - public void buildModel() { + public void buildModel() throws Exception { String flat = ModelicaManager.getFlatModelText(location, monitor, FunctionUtils.getLibraryPathsForModelica(experiment)); - try { - solver.prepare(flat); - } - catch (Exception e) { - e.printStackTrace(); - } + solver.prepare(flat); } @Override - public void runSolver() { + public void runSolver() throws Exception { // the number of result intervals in the simulation (account for initial values) int count = (int)((stop - start) / interval) + 1; // the number of steps in one result interval @@ -110,7 +95,7 @@ public class InternalSolver implements ISolver { double[] times = new double[count]; // a map containing values of all variables for each interval HashMap values = new HashMap(); - // initilize the temporary data structures + // initialize the temporary data structures times[0] = start; HashMap tmp = solver.values(); for (String key : tmp.keySet()) { @@ -137,7 +122,7 @@ public class InternalSolver implements ISolver { } @Override - public void updateResults() { + public void updateResults() throws Exception { InternalSolverResult result = new InternalSolverResult(null, results); experiment.setCurrentResult(result); experiment.resultsChanged(); diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/SimulationJob.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/SimulationJob.java deleted file mode 100644 index d05a27ee..00000000 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/SimulationJob.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.simantics.sysdyn.solver; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; -import org.simantics.sysdyn.manager.SysdynConsole; -import org.simantics.sysdyn.manager.SysdynExperiment; - -public class SimulationJob extends Job { - - private String name; - private SysdynExperiment experiment; - - public SimulationJob(String name, SysdynExperiment experiment) { - super(name); - this.name = name; - this.experiment = experiment; - } - - @Override - protected IStatus run(IProgressMonitor monitor) { - monitor.beginTask("simulate "+name, experiment.simulationSteps()); - - this.experiment.simulate(SysdynConsole.INSTANCE, monitor); - - monitor.done(); - - return Status.OK_STATUS; - } - -} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/SysdynSimulationJob.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/SysdynSimulationJob.java new file mode 100644 index 00000000..9c804322 --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/SysdynSimulationJob.java @@ -0,0 +1,97 @@ +package org.simantics.sysdyn.solver; + +import gnu.trove.map.TObjectIntMap; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.simantics.db.exception.DatabaseException; +import org.simantics.Simantics; +import org.simantics.issues.Severity; +import org.simantics.issues.common.CountModelIssuesBySeverity; +import org.simantics.sysdyn.manager.SysdynConsole; +import org.simantics.sysdyn.manager.SysdynExperiment; +import org.simantics.sysdyn.solver.SolverSettings.SolverType; + +public class SysdynSimulationJob extends Job { + + private static final String pluginId = "unknown"; + + protected String name; + protected SysdynExperiment experiment; + protected ISolver solver; + + public SysdynSimulationJob(String name, SysdynExperiment experiment) { + super(name); + this.name = name; + this.experiment = experiment; + this.solver = null; + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + monitor.beginTask("Simulate " + name, 4); + + // model update is necessary as it upgrades the isStructureModifier + // flag, could possibly be done differently if avoiding the graph + // operation is desired + try { + experiment.sysdynModel.update(); + } + catch (DatabaseException e) { + return new Status(Status.ERROR, pluginId, "Could not update model", e); + } + + // do not simulate if there are errors in the model + try { + TObjectIntMap severeties = + Simantics.sync(new CountModelIssuesBySeverity(experiment.getModel(), true, Severity.ERROR)); + if (severeties.get(Severity.ERROR) > 0) { + return new Status(Status.ERROR, pluginId, "There are unresolved errors in the model"); + } + } + catch (DatabaseException e) { + return new Status(Status.ERROR, pluginId, "Could not obtain issue count from model", e); + } + + SolverType type = experiment.getSolverType(); + // if the solver has not been created yet or the type of the solver + // has changed, a new solver must be created + if (solver == null || !solver.getType().equals(type)) { + if (SolverType.INTERNAL.equals(type)) { + solver = new InternalSolver(experiment, experiment.sysdynModel, SysdynConsole.INSTANCE); + } + else if (SolverType.OPENMODELICA.equals(type)) { + return new Status(Status.ERROR, pluginId, "The experiment should be reloaded"); + } + } + + // TODO: this should be broken down + + try { + monitor.subTask("generating model..."); + solver.initialize(); + monitor.worked(1); + + monitor.subTask("building model..."); + solver.buildModel(); + monitor.worked(1); + + monitor.subTask("running solver..."); + solver.runSolver(); + monitor.worked(1); + + monitor.subTask("getting results..."); + solver.updateResults(); + monitor.worked(1); + } + catch (Exception e) { + return new Status(Status.ERROR, pluginId, "Simulation failed", e); + } + + monitor.done(); + return Status.OK_STATUS; + } + +} -- 2.47.1