From c485fd59fb1e4ee70138031f01e247e6f1e99414 Mon Sep 17 00:00:00 2001 From: lempinen Date: Mon, 9 Aug 2010 13:12:20 +0000 Subject: [PATCH] Modelica files are recompiled only if the structure of the model is changed. Parameters are set in the init -file and recompiling is not needed when they are changed git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@17037 ac1ea38d-2e2b-0410-8846-a27921b304fc --- .../simantics/modelica/ModelicaManager.java | 138 +++++++++++++---- .../modelica/SimulationLocation.java | 20 +++ .../modelica/data/SimulationResult.java | 12 +- org.simantics.sysdyn/META-INF/MANIFEST.MF | 2 + .../src/org/simantics/sysdyn/Activator.java | 40 +++++ .../simantics/sysdyn/manager/SysdynModel.java | 142 +++++++++++++----- .../expressions/ParameterExpression.java | 6 +- 7 files changed, 290 insertions(+), 70 deletions(-) create mode 100644 org.simantics.modelica/src/org/simantics/modelica/SimulationLocation.java create mode 100644 org.simantics.sysdyn/src/org/simantics/sysdyn/Activator.java diff --git a/org.simantics.modelica/src/org/simantics/modelica/ModelicaManager.java b/org.simantics.modelica/src/org/simantics/modelica/ModelicaManager.java index 198dde1e..15a8cc9a 100644 --- a/org.simantics.modelica/src/org/simantics/modelica/ModelicaManager.java +++ b/org.simantics.modelica/src/org/simantics/modelica/ModelicaManager.java @@ -13,13 +13,18 @@ package org.simantics.modelica; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; +import java.util.HashMap; + import org.simantics.modelica.data.SimulationResult; public class ModelicaManager { + + protected static File getOpenModelicaHome() { String dir = System.getenv("OPENMODELICAHOME"); if(dir == null) @@ -69,23 +74,7 @@ public class ModelicaManager { } } - static class SimulationLocation { - File simulationDir; - File inputFile; - File outputFile; - File initFile; - - public SimulationLocation(File simulationDir, File inputFile, - File outputFile, File initFile) { - this.simulationDir = simulationDir; - this.inputFile = inputFile; - this.outputFile = outputFile; - this.initFile = initFile; - } - } - - protected static SimulationLocation createInputFiles(String modelName, String modelText, Double startTime, Double stopTime, Double tolerance) throws IOException { - File simulationDir = createTempDirectory(); + public static SimulationLocation createInputFiles(File simulationDir, String modelName, String modelText, HashMap inits) throws IOException { modelName = modelName.replace(" ", ""); File modelFile = new File(simulationDir, modelName + ".mo"); File scriptFile = new File(simulationDir, modelName + ".mos"); @@ -99,11 +88,11 @@ public class ModelicaManager { { PrintStream s = new PrintStream(scriptFile); s.println("loadFile(\"" + modelName + ".mo\");"); - s.print("simulate("+modelName+ - ",startTime="+startTime+ - ",stopTime="+stopTime); - if(tolerance != null) { - s.print(",tolerance="+tolerance); + s.print("buildModel("+modelName+ + ",startTime="+inits.get("startTime")+ + ",stopTime="+inits.get("stopTime")); + if(inits.containsKey("tolerance")) { + s.print(",tolerance="+inits.get("tolerance")); } s.print(");\n"); s.close(); @@ -113,15 +102,12 @@ public class ModelicaManager { simulationDir, new File(simulationDir, modelName + ".mos"), new File(simulationDir, modelName + "_res.plt"), - new File(simulationDir, modelName + "_init.txt") + new File(simulationDir, modelName + "_init.txt"), + new File(simulationDir, modelName + ".exe") ); } - public static SimulationResult runModelica(String modelName, String modelText, - IModelicaMonitor monitor, Double startTime, Double stopTime, Double tolerance) throws IOException { - SimulationLocation simulationLocation = - createInputFiles(modelName, modelText, startTime, stopTime, tolerance); - + public static void buildModel(SimulationLocation simulationLocation, IModelicaMonitor monitor) { try { File modelicaHome = getOpenModelicaHome(); File omc = new File(modelicaHome, "bin/omc.exe"); @@ -135,6 +121,26 @@ public class ModelicaManager { .start(); printProcessOutput(process, monitor); + } catch(IOException e) { + e.printStackTrace(); + } + + } + + public static SimulationResult runModelica(SimulationLocation simulationLocation, IModelicaMonitor monitor, HashMap inits) throws IOException { + + try { + + writeInits(simulationLocation, inits); + + Process process = new ProcessBuilder( + simulationLocation.exeFile.getAbsolutePath() + ) + .directory(simulationLocation.simulationDir.getAbsoluteFile()) + .redirectErrorStream(true) + .start(); + printProcessOutput(process, monitor); + SimulationResult result = new SimulationResult(); result.read(simulationLocation.outputFile); result.readInits(simulationLocation.initFile); @@ -143,10 +149,80 @@ public class ModelicaManager { return result; } catch(IOException e) { e.printStackTrace(); - } finally { - recursiveDelete(simulationLocation.simulationDir); - } + } return null; } + private static void writeInits(SimulationLocation simulationLocation, HashMap inits) { + + HashMap initials = new HashMap(); + HashMap order = new HashMap(); + + InputStream is; + try { + is = new FileInputStream(simulationLocation.initFile); + int orderNumber = 0; + while(true) { + String line = getLine(is); + if(line == null) + return; + if(line.isEmpty()) + break; + if(line.contains("//")) { + String[] nn = line.split("//", 2); + String key = nn[1].trim(); + String value = nn[0].trim(); + if(inits.containsKey(key)) { + value = inits.get(key).toString(); + } + initials.put(key, value); + order.put(orderNumber, key); + } + orderNumber++; + } + is.close(); + + PrintStream s = new PrintStream(simulationLocation.initFile); + for(int j = 0; j < orderNumber ; j++) { + String key = order.get(j); + if (key != null) { + s.println(initials.get(key) + " // " + key); + } else { + s.println("0.0"); + } + } + s.close(); + + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + + private static String getLine(InputStream stream) { + if(stream == null) + return null; + StringBuilder b = new StringBuilder(); + try { + while(true) { + int c = stream.read(); + if(c == -1) { + stream = null; + return b.toString(); + } + else if(c == '\n') + return b.toString(); + else if(c == '\r') + ; + else + b.append((char)c); + } + } catch (IOException e) { + return null; + } + + } + } diff --git a/org.simantics.modelica/src/org/simantics/modelica/SimulationLocation.java b/org.simantics.modelica/src/org/simantics/modelica/SimulationLocation.java new file mode 100644 index 00000000..6ed4ffba --- /dev/null +++ b/org.simantics.modelica/src/org/simantics/modelica/SimulationLocation.java @@ -0,0 +1,20 @@ +package org.simantics.modelica; + +import java.io.File; + +public class SimulationLocation { + public File simulationDir; + public File inputFile; + public File outputFile; + public File initFile; + public File exeFile; + + public SimulationLocation(File simulationDir, File inputFile, + File outputFile, File initFile, File exeFile) { + this.simulationDir = simulationDir; + this.inputFile = inputFile; + this.outputFile = outputFile; + this.initFile = initFile; + this.exeFile = exeFile; + } +} \ No newline at end of file diff --git a/org.simantics.modelica/src/org/simantics/modelica/data/SimulationResult.java b/org.simantics.modelica/src/org/simantics/modelica/data/SimulationResult.java index 6b0b4475..6fdd8217 100644 --- a/org.simantics.modelica/src/org/simantics/modelica/data/SimulationResult.java +++ b/org.simantics.modelica/src/org/simantics/modelica/data/SimulationResult.java @@ -58,8 +58,10 @@ public class SimulationResult { } - public void readInits(File file) throws FileNotFoundException { - readInits(new FileInputStream(file)); + public void readInits(File file) throws FileNotFoundException, IOException { + InputStream is = new FileInputStream(file); + readInits(is); + is.close(); } public void readInits(InputStream stream) { @@ -98,8 +100,10 @@ public class SimulationResult { final static Pattern p1 = Pattern.compile("DataSet: ([^ ]*)"); - public void read(File file) throws FileNotFoundException { - read(new FileInputStream(file)); + public void read(File file) throws FileNotFoundException, IOException { + InputStream is = new FileInputStream(file); + read(is); + is.close(); } public void read(InputStream stream) { diff --git a/org.simantics.sysdyn/META-INF/MANIFEST.MF b/org.simantics.sysdyn/META-INF/MANIFEST.MF index 63ce9759..1fe0f848 100644 --- a/org.simantics.sysdyn/META-INF/MANIFEST.MF +++ b/org.simantics.sysdyn/META-INF/MANIFEST.MF @@ -24,3 +24,5 @@ Export-Package: org.simantics.sysdyn, org.simantics.sysdyn.representation.visitors, org.simantics.sysdyn.simulation, org.simantics.sysdyn.tableParser +Bundle-Activator: org.simantics.sysdyn.Activator +Bundle-ActivationPolicy: lazy diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/Activator.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/Activator.java new file mode 100644 index 00000000..71b644e5 --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/Activator.java @@ -0,0 +1,40 @@ +package org.simantics.sysdyn; + +import java.io.File; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Activator implements BundleActivator { + + private static BundleContext bundleContext; + + @Override + public void start(BundleContext context) throws Exception { + bundleContext = context; + File modelsDir = Activator.getBundleContext().getDataFile("models"); + if (!modelsDir.exists()) { + modelsDir.mkdir(); + } + } + + @Override + public void stop(BundleContext context) throws Exception { + File modelsDir = Activator.getBundleContext().getDataFile("models"); + if (modelsDir.exists()) { + recursiveDelete(modelsDir); + } + } + + public static BundleContext getBundleContext() { + return bundleContext; + } + + private static boolean recursiveDelete(File fileOrDir) { + if(fileOrDir.isDirectory()) + for(File innerFile: fileOrDir.listFiles()) + if(!recursiveDelete(innerFile)) + return false; + return fileOrDir.delete(); + } +} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynModel.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynModel.java index c8accfab..ba42c8d8 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynModel.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynModel.java @@ -11,11 +11,14 @@ *******************************************************************************/ package org.simantics.sysdyn.manager; +import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; @@ -28,6 +31,7 @@ import org.simantics.db.common.request.ReadRequest; import org.simantics.db.exception.DatabaseException; import org.simantics.modelica.IModelicaMonitor; import org.simantics.modelica.ModelicaManager; +import org.simantics.modelica.SimulationLocation; import org.simantics.modelica.data.SimulationResult; import org.simantics.objmap.IMapping; import org.simantics.objmap.IMappingListener; @@ -36,11 +40,15 @@ import org.simantics.simulation.experiment.IExperiment; import org.simantics.simulation.model.IModel; import org.simantics.simulation.project.IExperimentActivationListener; import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.Activator; import org.simantics.sysdyn.SysdynResource; import org.simantics.sysdyn.modelica.ModelicaWriter; import org.simantics.sysdyn.representation.Configuration; import org.simantics.sysdyn.representation.IElement; +import org.simantics.sysdyn.representation.IndependentVariable; +import org.simantics.sysdyn.representation.Module; import org.simantics.sysdyn.representation.SysdynSchema; +import org.simantics.sysdyn.representation.expressions.ParameterExpression; /** * Maintains a Java representation of system dynamic model. @@ -49,11 +57,14 @@ import org.simantics.sysdyn.representation.SysdynSchema; public class SysdynModel implements IMappingListener, IModel { Session session; - Resource configurationResource; IMapping mapping; + + Resource configurationResource; Configuration configuration; + Set modules = new HashSet(); + SimulationResult result; SysdynResult sysdynResult; @@ -64,39 +75,43 @@ public class SysdynModel implements IMappingListener, IModel { Map services = new HashMap(); + String previousModelStructure; + + File simulationDir; + void readModules(ReadGraph graph, Resource configResource, Set result) throws DatabaseException { - - if(!result.add(configResource)) return; - - Builtins b = graph.getBuiltins(); - SysdynResource sr = SysdynResource.getInstance(graph); - StructuralResource2 str = StructuralResource2.getInstance(graph); - - for(Resource part : graph.getObjects(configResource, b.ConsistsOf)) { - if(graph.isInstanceOf(part, sr.Module)) { - Resource type = graph.getPossibleType(part, sr.Module); - Resource config = graph.getPossibleObject(type, str.IsDefinedBy); - readModules(graph, config, result); - } - } - + + if(!result.add(configResource)) return; + + Builtins b = graph.getBuiltins(); + SysdynResource sr = SysdynResource.getInstance(graph); + StructuralResource2 str = StructuralResource2.getInstance(graph); + + for(Resource part : graph.getObjects(configResource, b.ConsistsOf)) { + if(graph.isInstanceOf(part, sr.Module)) { + Resource type = graph.getPossibleType(part, sr.Module); + Resource config = graph.getPossibleObject(type, str.IsDefinedBy); + readModules(graph, config, result); + } + } + } - + Set readModules(ReadGraph graph, Resource configResource) throws DatabaseException { - HashSet result = new HashSet(); - readModules(graph, configResource, result); - return result; + HashSet result = new HashSet(); + readModules(graph, configResource, result); + return result; } - + private void createMapping(ReadGraph g) throws DatabaseException { SysdynSchema schema = new SysdynSchema(g); mapping = Mappings.createWithListening(schema); mapping.addMappingListener(SysdynModel.this); configuration = (Configuration)mapping.map(g, configurationResource); for(Resource config : readModules(g, configurationResource)) { - modules.add((Configuration)mapping.map(g, config)); + modules.add((Configuration)mapping.map(g, config)); } - System.out.println("Loaded model with " + modules.size() + " modules."); + System.out.println("Loaded model with " + modules.size() + " modules."); } public SysdynModel(ReadGraph g, Resource configurationResource) { @@ -110,6 +125,24 @@ public class SysdynModel implements IMappingListener, IModel { } sysdynResult = new SysdynResult(); sysdynResult.setResult(new SimulationResult()); + + previousModelStructure = ""; + + File modelsDir = Activator.getBundleContext().getDataFile("models"); + String configName = configuration.getName(); + List files = Arrays.asList(modelsDir.list()); + if (files.contains(configName)) { + int i = 2; + while (files.contains(configName + "_" + i)){ + i++; + } + configName += "_" + i; + } + + simulationDir = Activator.getBundleContext().getDataFile("models/" + configName); + if (!simulationDir.exists()) { + simulationDir.mkdir(); + } } @@ -121,24 +154,48 @@ public class SysdynModel implements IMappingListener, IModel { } public synchronized void simulate(IModelicaMonitor monitor) throws IOException { + try { ModelicaWriter writer = new ModelicaWriter(); //writer.write(configuration); for(Configuration c : modules) { - writer.write(c); + writer.write(c); } - System.out.println("== Modelica == "); - System.out.println(writer.toString()); - System.out.println("== Modelica ends == "); - - result = ModelicaManager.runModelica( + String modelText = writer.toString(); + + HashMap inits = getInits(configuration, ""); + + inits.put("startTime", configuration.startTime); + inits.put("stopTime", configuration.stopTime); + if(configuration.tolerance != null) { + inits.put("tolerance", configuration.tolerance); + } + + + SimulationLocation simulationLocation = ModelicaManager.createInputFiles( + simulationDir, configuration.getName(), writer.toString(), - monitor, - configuration.startTime, - configuration.stopTime, - configuration.tolerance); + inits); + + if (simulationLocation == null || !modelText.equals(previousModelStructure)) { + previousModelStructure = modelText; + System.out.println("== Modelica == "); + System.out.println(writer.toString()); + System.out.println("== Modelica ends == "); + + ModelicaManager.buildModel(simulationLocation, monitor); + + } + + if(simulationLocation != null) + result = ModelicaManager.runModelica( + simulationLocation, + monitor, + inits + ); + sysdynResult.setResult(result); } catch(Exception e) { e.printStackTrace(); @@ -167,7 +224,7 @@ public class SysdynModel implements IMappingListener, IModel { public SimulationResult getSimulationResult() { return result; } - + public SysdynResult getSysdynResult() { return sysdynResult; } @@ -276,4 +333,21 @@ public class SysdynModel implements IMappingListener, IModel { return results; } + private HashMap getInits(Configuration configuration, String prefix) { + HashMap inits = new HashMap(); + for (IElement element : configuration.getElements()) { + if (element instanceof Module) { + Module module = (Module) element; + Configuration conf = module.getType().getConfiguration(); + inits.putAll(getInits(conf, prefix + module.getName() + ".")); + } else if (element instanceof IndependentVariable) { + IndependentVariable variable = (IndependentVariable) element; + if (variable.getExpression() instanceof ParameterExpression) { + inits.put(prefix + variable.getName(), ((ParameterExpression)variable.getExpression()).getValue()); + } + } + } + return inits; + } + } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/ParameterExpression.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/ParameterExpression.java index 6a92d4c1..372dc54c 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/ParameterExpression.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/ParameterExpression.java @@ -25,7 +25,11 @@ public class ParameterExpression extends Expression { public String getDeclaration(IndependentVariable variable) { StringBuilder b = new StringBuilder(); b.append(" parameter " + variable.getType() + " " + variable.getName()); - b.append(" = " + equation + ";\n"); + b.append(" = " + 0.0 + " /* Value read from init file */;\n"); return b.toString(); } + + public double getValue() { + return Double.parseDouble(equation); + } } -- 2.47.1