]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
Implement a basic error reporting system for the new solver interface.
authorjkauttio <jkauttio@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Tue, 19 Nov 2013 12:58:37 +0000 (12:58 +0000)
committerjkauttio <jkauttio@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Tue, 19 Nov 2013 12:58:37 +0000 (12:58 +0000)
fixes #4513

git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@28326 ac1ea38d-2e2b-0410-8846-a27921b304fc

org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynExperiment.java
org.simantics.sysdyn/src/org/simantics/sysdyn/representation/IndependentVariable.java
org.simantics.sysdyn/src/org/simantics/sysdyn/solver/ISolver.java
org.simantics.sysdyn/src/org/simantics/sysdyn/solver/InternalSolver.java
org.simantics.sysdyn/src/org/simantics/sysdyn/solver/SimulationJob.java [deleted file]
org.simantics.sysdyn/src/org/simantics/sysdyn/solver/SysdynSimulationJob.java [new file with mode: 0644]

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