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
\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
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
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
* @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
@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
*/\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
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
\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
* @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
\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
\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
}\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
}\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
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
}\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
+++ /dev/null
-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
--- /dev/null
+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