]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
Update parameter change handling in OpenModelica experiments to avoid forgetting...
authorjkauttio <jkauttio@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Tue, 21 Apr 2015 13:41:41 +0000 (13:41 +0000)
committerjkauttio <jkauttio@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Tue, 21 Apr 2015 13:41:41 +0000 (13:41 +0000)
fixes #5776

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

org.simantics.modelica/src/org/simantics/modelica/ModelicaManager.java
org.simantics.modelica/src/org/simantics/modelica/data/DataSet.java
org.simantics.sysdyn/src/org/simantics/sysdyn/manager/OldSysdynExperiment.java
org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynGameExperiment.java
org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynModel.java
org.simantics.sysdyn/src/org/simantics/sysdyn/solver/InternalSolver.java

index 09cd5adbe27fed94a9351a6d6f1717317efe5a6c..77656b8ef73336b053a1dcda3e955ec4e90f9a16 100644 (file)
@@ -17,7 +17,6 @@ import java.io.File;
 import java.io.FileInputStream;\r
 import java.io.FileNotFoundException;\r
 import java.io.FileWriter;\r
-import java.io.FilenameFilter;\r
 import java.io.IOException;\r
 import java.io.InputStream;\r
 import java.io.InputStreamReader;\r
@@ -50,7 +49,6 @@ import org.osgi.service.prefs.Preferences;
 import org.simantics.modelica.preferences.OpenModelicaPreferences;\r
 import org.w3c.dom.Document;\r
 import org.w3c.dom.Node;\r
-import org.xml.sax.InputSource;\r
 import org.xml.sax.SAXException;\r
 \r
 /**\r
@@ -69,26 +67,6 @@ public class ModelicaManager {
 \r
        public static final String OMC_VERSION = "OMC_VERSION"; \r
        public static final String RESULT_FILE_NAME = "RESULT_FILE_NAME"; \r
-\r
-       /**\r
-        * Get operating system type\r
-        * \r
-        * @return OSType\r
-        */\r
-       private static OSType getOSType() {\r
-               String osName = System.getProperty("os.name").toLowerCase();\r
-               \r
-               if (osName.startsWith("mac os x"))\r
-                       return OSType.APPLE;\r
-               else if (osName.startsWith("linux"))\r
-                       return OSType.LINUX;\r
-               else if (osName.startsWith("sun"))\r
-                       return OSType.SUN;\r
-               else if (osName.startsWith("windows"))\r
-                       return OSType.WINDOWS;\r
-               \r
-               return OSType.UNKNOWN;\r
-       }\r
        \r
        private static boolean onWindows() {\r
                return System.getProperty("os.name").toLowerCase().startsWith("windows");\r
@@ -163,15 +141,8 @@ public class ModelicaManager {
        }\r
        \r
        public static boolean isOldOMVersion() {\r
-               try {\r
-                       double version = Double.parseDouble(getOMVersion(getOMHome()).substring(0, 3));\r
-                       return version < 1.9;\r
-               }\r
-               catch (NumberFormatException e) {\r
-                       // if the version string could not be parsed, assume that the \r
-                       // version sufficiently new\r
-                       return false;\r
-               }\r
+               // TODO: old versions are not supported anymore so any checks for them should be removed\r
+               return false;\r
        }\r
        \r
        /**\r
@@ -303,7 +274,7 @@ public class ModelicaManager {
                thread.run();\r
        }\r
 \r
-       public static SimulationLocation createSimulationLocation(File modelDir, String modelName, String modelContent, File omHome, boolean isOldOMVersion) {          \r
+       public static SimulationLocation createSimulationLocation(File modelDir, String modelName, String modelContent) {               \r
                if (!modelDir.isDirectory()) {\r
                        return null;\r
                }\r
@@ -328,7 +299,7 @@ public class ModelicaManager {
                }\r
                \r
                // full model files are (apparently) only needed for old parameter comparison routines\r
-               if (isOldOMVersion) {\r
+               if (isOldOMVersion()) {\r
                        location.fullModelDir = new File(location.getModelDir(), "fullModel");\r
                        if (!location.fullModelDir.isDirectory()) {\r
                                location.fullModelDir.mkdir();\r
@@ -337,7 +308,7 @@ public class ModelicaManager {
                        location.fullModelScriptFile = new File(location.fullModelDir, location.getModelName() + "_full.mos");\r
                }\r
                \r
-               location.omHome = omHome;\r
+               location.omHome = getOMHome();\r
                \r
                return location;\r
        }\r
@@ -532,43 +503,14 @@ public class ModelicaManager {
         */\r
        public static Process runModelica(SimulationLocation location, IModelicaMonitor monitor, HashMap<String, String> experimentParameters, HashMap<String, String> parameterChanges) throws IOException {\r
                ArrayList<String> commands = new ArrayList<String>();\r
-               try {\r
-                       if(experimentParameters.get(RESULT_FILE_NAME) != null) {\r
-                               commands.add("-r="+experimentParameters.get(RESULT_FILE_NAME));\r
-                       }\r
-\r
-                       // Write new initial values (parameters). No need to update xml if structure has changed. In that case also xml is up-to-date\r
-                       if(parameterChanges != null) {\r
-                               String version = experimentParameters.get(OMC_VERSION);\r
-                               // TODO: clean up\r
-                               if(version == null)\r
-                                       version = getOMVersion(location.omHome);\r
-\r
-                               Double versionNumber = 1.9;\r
-                               try {\r
-                                       versionNumber = Double.parseDouble(version.substring(0,3));\r
-                               } catch (NumberFormatException e) {}\r
-\r
-                               if(versionNumber < 1.9) {\r
-                                       writeInits(location, experimentParameters, null);\r
-                               } else {\r
-                                       // Handled in experiment\r
-                                       if(parameterChanges.size() == 1) {\r
-                                               commands.add("-override");\r
-                                               commands.add(parameterChanges.keySet().iterator().next() + "=" + parameterChanges.values().iterator().next());\r
-                                       } else {\r
-                                               // FIXME: if you change 1 parameter AND some experiment parameters, only the parameter change takes effect\r
-                                               updateInitFile(location, experimentParameters, parameterChanges);\r
-                                       }\r
-                               }\r
-\r
-                       }\r
-                       \r
-               }\r
-               catch (Exception e) {\r
-                       e.printStackTrace();\r
+               \r
+               if(experimentParameters.get(RESULT_FILE_NAME) != null) {\r
+                       commands.add("-r="+experimentParameters.get(RESULT_FILE_NAME));\r
                }\r
                \r
+               // update parameter changes\r
+               updateInitFile(location, experimentParameters, parameterChanges);\r
+               \r
                // Commands to String[]\r
                String[] commandString = new String[commands.size()];\r
                for (int i = 0; i < commands.size(); ++i)\r
@@ -623,142 +565,14 @@ public class ModelicaManager {
                return result;\r
        }\r
 \r
-\r
-       /**\r
-        * Updates inits.xml with the latest values. This is not needed if the model structure\r
-        * has changed. When model structure is changed, the model is compiled and a new xml is \r
-        * created.\r
-        * \r
-        * Works with version 1.8.1 and previous versions. 1.9 version does not support this, since\r
-        * the init.xml file format has been changed. With 1.9, use updateInitFile()\r
-        * \r
-        * @param simulationLocation Location of the model\r
-        * @param monitor \r
-        */\r
-       private static void writeInits(SimulationLocation simulationLocation, HashMap<String, String> experimentParameters, IModelicaMonitor monitor) {\r
-\r
-               try {\r
-                       // Create the full model code into one file\r
-                       buildFullModel(simulationLocation, null);\r
-\r
-                       // Create simulation files from the full description\r
-                       ArrayList<String> parameters = new ArrayList<String>();\r
-                       parameters.add("-s");\r
-                       parameters.add(simulationLocation.fullModelFile.getAbsolutePath());\r
-\r
-                       Process process = runOMC(simulationLocation.omHome, simulationLocation.fullModelDir, "-s", simulationLocation.fullModelFile.getAbsolutePath());\r
-\r
-                       process.waitFor();\r
-\r
-                       // Find the new init file\r
-                       FilenameFilter initFilter = new FilenameFilter() {\r
-                               @Override\r
-                               public boolean accept(File dir, String name) {\r
-                                       if(name.endsWith("_init.xml"))\r
-                                               return true;\r
-                                       else\r
-                                               return false;\r
-                               }\r
-                       };\r
-\r
-                       File initFile = null;\r
-                       for(File f : simulationLocation.fullModelDir.listFiles(initFilter)) {\r
-                               initFile = f;\r
-                               break;\r
-                       }\r
-\r
-                       if(initFile != null && initFile.isFile()) {\r
-                               // Replace original init contents with the new contents\r
-                               replaceInitFileContents(simulationLocation.initFile.getAbsolutePath(), initFile.getAbsolutePath(), experimentParameters);\r
-                       }\r
-\r
-               } catch (ModelicaException e) {\r
-                       e.printStackTrace();\r
-               } catch (InterruptedException e) {\r
-                       e.printStackTrace();\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Replaces variable and experiment information from oldFile with contents of newFile.\r
-        * \r
-        * The file is not simply replaced because guid must match with guid in created exe.\r
-        * \r
-        * @param oldFile old init.xml\r
-        * @param newFile new init.xml\r
-        */\r
-       private static void replaceInitFileContents(String oldFile, String newFile, HashMap<String, String> experimentParameters) {\r
-               try {\r
-                       XPath xpath = XPathFactory.newInstance().newXPath();\r
-\r
-                       Document oldInit = DocumentBuilderFactory.newInstance()\r
-                                       .newDocumentBuilder().parse(new InputSource(oldFile));\r
-                       Document newInit = DocumentBuilderFactory.newInstance()\r
-                                       .newDocumentBuilder().parse(new InputSource(newFile));\r
-\r
-                       // Find the original model description. This will be modified\r
-                       Node oldModelDescription = (Node)xpath.evaluate("fmiModelDescription", oldInit, XPathConstants.NODE);\r
-\r
-                       //\r
-                       // VARIABLES\r
-                       //\r
-                       // First, remove old model variables\r
-                       Node oldModelVariables = (Node)xpath.evaluate("fmiModelDescription/ModelVariables", oldInit, XPathConstants.NODE);\r
-                       \r
-                       oldModelDescription.removeChild(oldModelVariables);\r
-\r
-                       // Second, find variables in the new model description\r
-                       Node newModelVariables = (Node)xpath.evaluate("fmiModelDescription/ModelVariables", newInit, XPathConstants.NODE);\r
-\r
-                       // Import new variables to old xml\r
-                       Node importedModelVariables = oldInit.importNode(newModelVariables, true);\r
-                       oldModelDescription.appendChild(importedModelVariables);\r
-\r
-                       //\r
-                       // EXPERIMENT PARAMETERS\r
-                       //\r
-                       for(String key : experimentParameters.keySet()) {\r
-                               // Find parameter\r
-                               Node parameter = (Node)xpath.evaluate\r
-                                               ("fmiModelDescription/DefaultExperiment/@" + key,\r
-                                                               oldInit, \r
-                                                               XPathConstants.NODE);\r
-\r
-                               if(parameter != null) {\r
-                                       // Change parameter value\r
-                                       parameter.setNodeValue(experimentParameters.get(key));\r
-                               }\r
-                       }\r
-\r
-                       // Write transformed init.xml\r
-                       Transformer xformer = TransformerFactory.newInstance().newTransformer();\r
-                       xformer.transform(new DOMSource(oldInit), new StreamResult(new File(oldFile)));\r
-\r
-               } catch (SAXException e) {\r
-                       e.printStackTrace();\r
-               } catch (IOException e) {\r
-                       e.printStackTrace();\r
-               } catch (ParserConfigurationException e) {\r
-                       e.printStackTrace();\r
-               } catch (XPathExpressionException e) {\r
-                       e.printStackTrace();\r
-               } catch (TransformerConfigurationException e) {\r
-                       e.printStackTrace();\r
-               } catch (TransformerFactoryConfigurationError e) {\r
-                       e.printStackTrace();\r
-               } catch (TransformerException e) {\r
-                       e.printStackTrace();\r
-               }\r
-       }\r
-\r
        /**\r
         * Updates init file contents with the given experiment and variable changes.\r
         * \r
         * @param simulationLocation Location of simulation files\r
         * @param experimentParameters Experiment parameters\r
-        * @param changes Parameter variable changes\r
+        * @param parameterChanges Parameter variable changes\r
         */\r
-       public static void updateInitFile(SimulationLocation simulationLocation, HashMap<String, String> experimentParameters, HashMap<String, String> changes) {\r
+       public static void updateInitFile(SimulationLocation simulationLocation, HashMap<String, String> experimentParameters, HashMap<String, String> parameterChanges) {\r
                try {\r
                        XPath xpath = XPathFactory.newInstance().newXPath();\r
 \r
@@ -784,13 +598,13 @@ public class ModelicaManager {
                        //\r
                        // PARAMETER VARIABLES\r
                        //\r
-                       for(String name : changes.keySet()) {\r
+                       for(String name : parameterChanges.keySet()) {\r
                                Node node = (Node)xpath.evaluate\r
                                                ("//fmiModelDescription/ModelVariables/ScalarVariable[@name='" + name + "']/Real/@start",\r
                                                                init, \r
                                                                XPathConstants.NODE);\r
                                if(node != null) {\r
-                                       node.setNodeValue(changes.get(name));\r
+                                       node.setNodeValue(parameterChanges.get(name));\r
                                }\r
                        } \r
 \r
index f373b988443333ae4b6a7feec47292f1a8499617..ff5b332bb476766f4fe935408fd367daea7fbd3c 100644 (file)
@@ -29,7 +29,7 @@ public class DataSet {
     /**\r
      * Normalize simulation results according to the given parameters by\r
      * removing extra simulation steps that are not located at the expected\r
-     * intervals. This is mostly useful when Open Modelica decides to perform\r
+     * intervals. This is mostly useful when OpenModelica decides to perform\r
      * extra simulation steps that cause misalignments when simulation results\r
      * from several runs with different parameters are combined in sensitivity\r
      * analysis experiments.\r
@@ -42,9 +42,9 @@ public class DataSet {
        // TODO: this makes implicit assumptions about the values, probably not kosher\r
        int size = (int)Math.round((stopTime - startTime) / timeStep) + 1;\r
        if (times.length < size) {\r
-               // if the ogirinal data has less time steps than requested, there is no need\r
+               // if the original data has less time steps than requested, there is no need\r
                // to filter anything. generally this happens when the value of the variable\r
-               // does not change during the simulation, in which case Open Modelica\r
+               // does not change during the simulation, in which case OpenModelica\r
                // simply stores the value once.\r
                return;\r
        }\r
index 3fbd472cfc72edd1067ca3539423406009d03b14..a0cb37d295b3658d7b5574842acda9363f277b0b 100644 (file)
@@ -78,8 +78,7 @@ public class OldSysdynExperiment extends SysdynExperiment {
     @SuppressWarnings("rawtypes")\r
     protected volatile VariableValueSubscription[]     variableValueSubscriptionsSnapshot = null;\r
 \r
-    protected String                                                           previousModelStructure;\r
-    protected HashMap<String, String>               previousParameters;\r
+    protected HashMap<String, String>               defaultParameters;\r
     protected Process                                                          process;\r
     protected boolean                                                          canceled = false;\r
     protected ExperimentState                       sysdynExperimentState;\r
@@ -309,8 +308,7 @@ public class OldSysdynExperiment extends SysdynExperiment {
                 monitor.message(e.getMessage());\r
             monitor.showConsole();\r
             canceled = true;\r
-            previousModelStructure = "";\r
-            previousParameters = null;\r
+            defaultParameters = null;\r
         }\r
     }\r
 \r
@@ -319,13 +317,13 @@ public class OldSysdynExperiment extends SysdynExperiment {
      * @param structureChanged \r
      * @throws IOException\r
      */\r
-    protected void runModelica(SimulationLocation simulationLocation, IModelicaMonitor monitor, IProgressMonitor progressMonitor, HashMap<String, String> experimentParameters, HashMap<String, String> changes) throws IOException {\r
+    protected void runModelica(SimulationLocation simulationLocation, IModelicaMonitor monitor, IProgressMonitor progressMonitor, HashMap<String, String> experimentParameters, HashMap<String, String> parameterChanges) throws IOException {\r
         progressMonitor.subTask("Simulate model");\r
         process = ModelicaManager.runModelica(\r
                 simulationLocation,\r
                 monitor,\r
                 experimentParameters, \r
-                changes\r
+                parameterChanges\r
                 );\r
         ModelicaManager.printProcessOutput(process, monitor);\r
 \r
@@ -434,7 +432,7 @@ public class OldSysdynExperiment extends SysdynExperiment {
         FunctionUtils.updateFunctionFilesForExperiment(this);\r
 \r
 \r
-        SimulationLocation location = ModelicaManager.createSimulationLocation(simulationDir, sysdynModel.getConfiguration().getLabel(), modelText, ModelicaManager.getOMHome(), ModelicaManager.isOldOMVersion());\r
+        SimulationLocation location = ModelicaManager.createSimulationLocation(simulationDir, sysdynModel.getConfiguration().getLabel(), modelText);\r
         if (fmu) {\r
                ModelicaManager.createFMUSimulationScripts(location, inits, additionalScript);\r
         }\r
@@ -535,32 +533,31 @@ public class OldSysdynExperiment extends SysdynExperiment {
         // Build the model and store previous model structure and inits that affect the building\r
         // If there is no exe file OR the model structure has not changed, no need to build\r
         String flatModelText = ModelicaManager.getFlatModelText(simulationLocation, monitor, FunctionUtils.getLibraryPathsForModelica(this));\r
+        \r
         boolean structureChanged = sysdynModel.isStructureModified();\r
         \r
         if (!simulationLocation.executableFile.isFile() || structureChanged) {\r
             progressMonitor.subTask("Build model");\r
-            previousModelStructure = flatModelText;\r
-            previousParameters = ModelicaManager.getModelParameters(previousModelStructure);\r
+            defaultParameters = ModelicaManager.getModelParameters(flatModelText);\r
             \r
             buildModel(simulationLocation, monitor);\r
         }\r
         \r
         // Add changed parameters in case that structure has not changed\r
-        HashMap<String, String> changes = structureChanged ? null : new HashMap<String, String>();\r
-        if(!structureChanged && previousParameters != null && omcVersion.startsWith("1.9")) {\r
-                HashMap<String, String> newParameters = ModelicaManager.getModelParameters(flatModelText);\r
-                for(String key : previousParameters.keySet()) {\r
-                    if(!previousParameters.get(key).equals(newParameters.get(key))) {\r
-                        changes.put(key, newParameters.get(key));\r
+        HashMap<String, String> parameterChanges = new HashMap<String, String>();\r
+        if(!structureChanged && defaultParameters != null) {\r
+                HashMap<String, String> currentParameters = ModelicaManager.getModelParameters(flatModelText);\r
+                for(String key : defaultParameters.keySet()) {\r
+                    if(!defaultParameters.get(key).equals(currentParameters.get(key))) {\r
+                        parameterChanges.put(key, currentParameters.get(key));\r
                     }\r
                 }\r
-                previousParameters = newParameters;\r
         }\r
         progressMonitor.worked(1);\r
         \r
         if(simulationLocation != null && !canceled) {\r
             // Simulate the model\r
-            runModelica(simulationLocation, monitor, progressMonitor, experimentParameters, changes);\r
+            runModelica(simulationLocation, monitor, progressMonitor, experimentParameters, parameterChanges);\r
         }\r
         \r
         if(canceled)\r
@@ -592,68 +589,6 @@ public class OldSysdynExperiment extends SysdynExperiment {
         return omVersion;\r
     }\r
 \r
-\r
-    /**\r
-     * Method that compares given modelText and inits to previous model and inits\r
-     * @param modelText Textual representation of a model (Modelica code)\r
-     * @param inits map of init parameters\r
-     * @return true if the model has changed, false otherwise\r
-     */\r
-//    protected boolean hasStructureChanged(String modelText) {\r
-//\r
-//        if(previousModelStructure == null)\r
-//            return true;\r
-//\r
-//        // Then compare the actual model structure\r
-//        BufferedReader current = new BufferedReader(\r
-//                new StringReader(modelText));\r
-//        BufferedReader previous = new BufferedReader(\r
-//                new StringReader(previousModelStructure));\r
-//\r
-//        String c, p;\r
-//        try {\r
-//            // Read both current and previous model texts at the same time\r
-//            c = current.readLine();\r
-//            p = previous.readLine();\r
-//\r
-//            while (c != null && p != null) {\r
-//                // if the lines are the same, no need for further examination\r
-//                if(!c.equals(p)) {\r
-//                    if(c.contains("parameter") && p.contains("parameter")) {\r
-//                        /*\r
-//                         *  The line is a parameter definition.\r
-//                         *  In this case only what is before '=' matters\r
-//                         * \r
-//                         *  parameter Real Var = 1;\r
-//                         *     is structurally same as\r
-//                         *  parameter Real Var = 2;\r
-//                         */\r
-//                        int i = c.indexOf("=");\r
-//                        if(!c.substring(0, i).equals(p.substring(0, i))) {\r
-//                            // different parameter definition\r
-//                            return true;\r
-//                        }\r
-//                    } else {\r
-//                        // other than a line containing parameters differs\r
-//                        return true;\r
-//                    }\r
-//                }\r
-//                c = current.readLine();\r
-//                p = previous.readLine();\r
-//            }\r
-//\r
-//            if((c == null && p != null) || (c != null && p == null)) {\r
-//                // different lengths\r
-//                return true;\r
-//            }\r
-//\r
-//        } catch(IOException e) {\r
-//            // Something went wrong in the comparison, it is safer to say that the structure has changed\r
-//            return true;\r
-//        }\r
-//        return false;\r
-//    }\r
-\r
     /**\r
      * Destroy an ongoing simulation process\r
      */\r
index e4f589ac61b3d310813b9480632d8bcd2279df76..288bb1bf5d6a38f6656484a3b1de9bb6695c95ae 100644 (file)
@@ -12,7 +12,6 @@
 package org.simantics.sysdyn.manager;\r
 \r
 import gnu.trove.list.array.TDoubleArrayList;\r
-import gnu.trove.map.hash.THashMap;\r
 \r
 import java.io.File;\r
 import java.io.FileInputStream;\r
@@ -145,7 +144,6 @@ public class SysdynGameExperiment extends SysdynGameExperimentBase {
                if (fmu == null && (!isValidFMU(simulationLocation.executableFile) || sysdynModel.isStructureModified())) {\r
                        progressMonitor.subTask("Build model");\r
                        buildModel(simulationLocation, monitor);\r
-                       previousModelStructure = modelText;\r
                        \r
                        saveModelFmu(simulationLocation);\r
                }\r
index 891983bae245ca60214f3de9c605423c906f7acd..fedac97a249a1e00f20725430472216fd8a0fe92 100644 (file)
@@ -278,7 +278,7 @@ public class SysdynModel implements IModel, IMappingListener, VariableSubscripti
         if(mapping.isDomainModified()) {\r
             try {\r
                 Collection<Object> updated = mapping.updateRange(graph);\r
-\r
+                \r
                 for(Object o : updated) {\r
                     if(o instanceof Model) {\r
                         continue;\r
index 846f3701db919ffbdb1ed2fb235dc080c1e43beb..782285d868216816e2217778832500f18871218b 100644 (file)
@@ -70,7 +70,7 @@ public class InternalSolver implements ISolver {
                FunctionUtils.updateFunctionFilesForExperiment(experiment);\r
 \r
                location = ModelicaManager.createSimulationLocation(experiment.getExperimentDir(), \r
-                               model.getConfiguration().getLabel(), modelContent, null, false);\r
+                               model.getConfiguration().getLabel(), modelContent);\r
                \r
                solver.setStep(step);\r
                solver.setStart(start);\r