From: lempinen Date: Fri, 17 May 2013 09:05:55 +0000 (+0000) Subject: Eliminated the need to build separate full modelica code file for models (OMC versio... X-Git-Tag: 1.8.1~307 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=a9ba862ba747d99f5c8840629000cb21cd493ced;p=simantics%2Fsysdyn.git Eliminated the need to build separate full modelica code file for models (OMC version 1.9 ->). Instead, the experiment creates full modelica structure directly to memory and it is created only once per simulation. (fixes #3968) git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@27422 ac1ea38d-2e2b-0410-8846-a27921b304fc --- diff --git a/org.simantics.modelica/src/org/simantics/modelica/ModelicaManager.java b/org.simantics.modelica/src/org/simantics/modelica/ModelicaManager.java index 2de275d8..e0eaa210 100644 --- a/org.simantics.modelica/src/org/simantics/modelica/ModelicaManager.java +++ b/org.simantics.modelica/src/org/simantics/modelica/ModelicaManager.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintStream; +import java.io.Reader; import java.net.URL; import java.net.URLDecoder; import java.util.ArrayList; @@ -45,7 +46,7 @@ import javax.xml.xpath.XPathFactory; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.preferences.DefaultScope; +import org.eclipse.core.runtime.preferences.ConfigurationScope; import org.eclipse.core.runtime.preferences.IScopeContext; import org.osgi.framework.Bundle; import org.osgi.service.prefs.Preferences; @@ -100,7 +101,7 @@ public class ModelicaManager { public static File getModelicaHome() { // Try preferences - IScopeContext context = DefaultScope.INSTANCE; + IScopeContext context = ConfigurationScope.INSTANCE; Preferences node = context.getNode(Activator.PLUGIN_ID); String omHomePath = node.get(OpenModelicaPreferences.OM_HOME, null); if(omHomePath != null) { @@ -205,8 +206,14 @@ public class ModelicaManager { BufferedReader in = new BufferedReader(r); StringBuilder output = new StringBuilder(); String line; - while ((line = in.readLine()) != null) + boolean first = true; + while ((line = in.readLine()) != null) { + if(!first) + output.append(System.getProperty("line.separator")); + first = false; + output.append(line); + } return output.toString(); } catch (Exception e) { // exception thrown System.err.println("getProcessOutput failed!"); @@ -457,7 +464,6 @@ public class ModelicaManager { ArrayList parameters = new ArrayList(); parameters.add(simulationLocation.mosFile.getAbsolutePath()); runOMC(simulationLocation.simulationDir, simulationLocation.omcHome, monitor, parameters); - createFullMo(simulationLocation, monitor); if(!simulationLocation.executableFile.isFile()) // If .exe file was not created, something went wrong @@ -551,15 +557,23 @@ public class ModelicaManager { String version = experimentParameters.get(OMC_VERSION); if(version == null) version = getOMCVersion(simulationLocation.omcHome); - if(version.startsWith("1.9")) { + + Double versionNumber = 1.9; + try { + versionNumber = Double.parseDouble(version.substring(0,3)); + } catch (NumberFormatException e) {} + + if(versionNumber < 1.9) { + writeInits(simulationLocation, experimentParameters, null); + } else { // Handled in experiment if(parameterChanges.size() == 1) { commands.add("-override"); commands.add(parameterChanges.keySet().iterator().next() + "=" + parameterChanges.values().iterator().next()); - } else + } else { + // FIXME: if you change 1 parameter AND some experiment parameters, only the parameter change takes effect updateInitFile(simulationLocation, experimentParameters, parameterChanges); - } else { - writeInits(simulationLocation, experimentParameters, monitor); + } } } @@ -593,35 +607,49 @@ public class ModelicaManager { } return null; } + + public static String getFlatModelText(SimulationLocation simulationLocation, IModelicaMonitor monitor, List additionalPaths) { + + ArrayList commands = new ArrayList(); + File omHome = getModelicaHome(); + commands.add(omHome + "\\bin\\omc.exe"); + String path = simulationLocation.mosFile.getAbsolutePath(); + path = path.substring(0, path.length() - 1); + commands.add(path); + + for(String additionalPath : additionalPaths) { + commands.add(additionalPath); + } + + ProcessBuilder processBuilder = new ProcessBuilder(commands) + .redirectErrorStream(true).directory(simulationLocation.simulationDir); + + Map env = processBuilder.environment(); + env.put("OPENMODELICAHOME", omHome.getAbsolutePath()); + + // Start the building process + try { + Process process = processBuilder.start(); + return getProcessOutput(process); + } catch (IOException e) { + e.printStackTrace(); + } + + return null; + } + /** - * Get all parameter variables and their values from the full model description - * @param simulationLocation - * @param monitor - * @return + * Get all parameter variables and their values from model. Model text is + * provided in a Reader. + * @param reader Reader containing model text + * @return all parameters and their values */ - public static HashMap getFullModelParameters(SimulationLocation simulationLocation, IModelicaMonitor monitor) { + public static HashMap getModelParameters(Reader reader) { HashMap result = new HashMap(); try { - ArrayList commands = new ArrayList(); - File omHome = getModelicaHome(); - commands.add(omHome + "\\bin\\omc.exe"); - commands.add(simulationLocation.fullModel.getAbsolutePath()); - - // Create the build process - ProcessBuilder processBuilder = new ProcessBuilder(commands) - .redirectErrorStream(true); - - Map env = processBuilder.environment(); - env.put("OPENMODELICAHOME", omHome.getAbsolutePath()); - - // Start the building process - Process process = processBuilder.start(); - - InputStream lsOut = process.getInputStream(); - InputStreamReader r = new InputStreamReader(lsOut); - BufferedReader in = new BufferedReader(r); + BufferedReader in = new BufferedReader(reader); String line; String name; String value; @@ -637,18 +665,13 @@ public class ModelicaManager { } } in.close(); - r.close(); - lsOut.close(); - - process.waitFor(); } catch (IOException e) { - - } catch (InterruptedException e) { e.printStackTrace(); } return result; } + /** * Updates inits.xml with the latest values. This is not needed if the model structure * has changed. When model structure is changed, the model is compiled and a new xml is @@ -664,16 +687,10 @@ public class ModelicaManager { try { // Create the full model code into one file - ArrayList parameters = new ArrayList(); - parameters.add(simulationLocation.fullMosFile.getAbsolutePath()); - - Process process = runOMC(simulationLocation.simulationDir, simulationLocation.omcHome, null, parameters); - process.waitFor(); - - trimExtraFromFullModel(simulationLocation); + createFullMo(simulationLocation, null); // Create simulation files from the full description - parameters.clear(); + ArrayList parameters = new ArrayList(); parameters.add("+s"); parameters.add(simulationLocation.fullModel.getAbsolutePath()); 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 46433abd..97a59806 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynExperiment.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynExperiment.java @@ -85,7 +85,8 @@ public class SysdynExperiment extends Experiment implements IDynamicExperiment, protected String experimentName; protected static String omcVersion = null; - + protected static String omcHome = null; + public static SysdynExperiment INSTANCE; public SysdynExperiment(Resource experiment, Resource model) { @@ -252,13 +253,11 @@ public class SysdynExperiment extends Experiment implements IDynamicExperiment, * @param modelText * @param monitor */ - protected void buildModel(SimulationLocation simulationLocation, String modelText, IModelicaMonitor monitor) { + protected void buildModel(SimulationLocation simulationLocation, IModelicaMonitor monitor) { try { simulationLocation.executableFile.delete(); - previousModelStructure = modelText; ModelicaManager.buildModel(simulationLocation, monitor); - previousParameters = ModelicaManager.getFullModelParameters(simulationLocation, monitor); } catch (ModelicaException e) { if(e.getMessage() != null) monitor.message(e.getMessage()); @@ -451,8 +450,14 @@ public class SysdynExperiment extends Experiment implements IDynamicExperiment, canceled = false; progressMonitor.subTask("Write modelica classes"); - // Write Modelica files - String modelText = getModelicaCode(monitor, false, getOpenModelicaVersion()); + File home = ModelicaManager.getModelicaHome(); + if (omcHome == null || !home.getAbsolutePath().equals(omcHome)) { + omcVersion = ModelicaManager.getOMCVersion(home); + omcHome = home.getAbsolutePath(); + } + + // Get Modelica code + String modelText = getModelicaCode(monitor, false, omcVersion); if(modelText == null) return; progressMonitor.worked(1); @@ -460,47 +465,47 @@ public class SysdynExperiment extends Experiment implements IDynamicExperiment, // Write initial files and add init-parameters progressMonitor.subTask("Write simulation files"); HashMap experimentParameters = getExperimentParameters(monitor); - + // add loadFile script to load all related functions and function libraries String additionalScript = getAdditionalScripts(); - + // Create simulation files SimulationLocation simulationLocation = createSimulationFiles(sysdynModel, modelText, experimentParameters, additionalScript, false); progressMonitor.worked(1); - + // Build the model and store previous model structure and inits that affect the building // If there is no exe file OR the model structure has not changed, no need to build - boolean structureChanged = hasStructureChanged(modelText); + String flatModelText = ModelicaManager.getFlatModelText(simulationLocation, monitor, FunctionUtils.getLibraryPathsForModelica(this)); + + boolean structureChanged = hasStructureChanged(flatModelText); if (!simulationLocation.executableFile.isFile() || structureChanged) { progressMonitor.subTask("Build model"); - buildModel(simulationLocation, modelText, monitor); + previousModelStructure = flatModelText; + StringReader reader = new StringReader(previousModelStructure); + previousParameters = ModelicaManager.getModelParameters(reader); + reader.close(); } // Add changed parameters in case that structure has not changed HashMap changes = structureChanged ? null : new HashMap(); - if (omcVersion == null) { - omcVersion = ModelicaManager.getOMCVersion(simulationLocation.omcHome); - } if(!structureChanged && previousParameters != null && omcVersion.startsWith("1.9")) { - try { - ModelicaManager.createFullMo(simulationLocation, monitor); - HashMap newParameters = ModelicaManager.getFullModelParameters(simulationLocation, monitor); + StringReader reader = new StringReader(flatModelText); + HashMap newParameters = ModelicaManager.getModelParameters(reader); + reader.close(); for(String key : previousParameters.keySet()) { if(!previousParameters.get(key).equals(newParameters.get(key))) { changes.put(key, newParameters.get(key)); } } previousParameters = newParameters; - } catch (ModelicaException e) { - e.printStackTrace(); - } } progressMonitor.worked(1); - + if(simulationLocation != null && !canceled) { // Simulate the model runModelica(simulationLocation, modelText, monitor, progressMonitor, experimentParameters, changes); } + if(canceled) simulate(false); process = null; @@ -561,9 +566,7 @@ public class SysdynExperiment extends Experiment implements IDynamicExperiment, while (c != null && p != null) { // if the lines are the same, no need for further examination if(!c.equals(p)) { - if( - c.contains("parameter") && c.contains("/* Actual value read from init file */") && - p.contains("parameter") && p.contains("/* Actual value read from init file */")) { + if(c.contains("parameter") && p.contains("parameter")) { /* * The line is a parameter definition. * In this case only what is before '=' matters diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynGameExperiment.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynGameExperiment.java index b64c5265..00bc3b70 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynGameExperiment.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynGameExperiment.java @@ -206,7 +206,7 @@ public class SysdynGameExperiment extends SysdynExperiment { // If there is no exe file OR the model structure has not changed, no need to build if (fmu == null && (!simulationLocation.executableFile.isFile() || hasStructureChanged(modelText))) { progressMonitor.subTask("Build model"); - buildModel(simulationLocation, modelText, monitor); + buildModel(simulationLocation, monitor); previousModelStructure = modelText; saveModelFmu(simulationLocation); diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynSensitivityAnalysisExperiment.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynSensitivityAnalysisExperiment.java index 0d3d096b..588efe25 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynSensitivityAnalysisExperiment.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynSensitivityAnalysisExperiment.java @@ -311,4 +311,31 @@ public class SysdynSensitivityAnalysisExperiment extends SysdynExperiment { } + + @Override + public synchronized void simulate(IModelicaMonitor monitor, IProgressMonitor progressMonitor) throws IOException { + + File home = ModelicaManager.getModelicaHome(); + if (omcHome == null || !home.getAbsolutePath().equals(omcHome)) { + omcVersion = ModelicaManager.getOMCVersion(home); + omcHome = home.getAbsolutePath(); + } + + // Make sure that omc version is 1.9 or higher. + // Builtin version during this change is 1.9 beta 4 + if(omcVersion != null) { + try { + double v = Double.parseDouble(omcVersion.substring(0, 3)); + if(v < 1.9) { + monitor.message("Error: Sensitivity analysis requires OMC version >= 1.9 \n" + + "Current version is " + omcVersion +"\n" + + "Change version from Window->Preferences->Modelica"); + simulate(false); + return; + } + } catch (NumberFormatException e) {} + } + + super.simulate(monitor, progressMonitor); + } }