]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
fixed start values for stocks, if no variables are used in initial equations
authorlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Tue, 15 Nov 2011 08:05:10 +0000 (08:05 +0000)
committerlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Tue, 15 Nov 2011 08:05:10 +0000 (08:05 +0000)
git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@23257 ac1ea38d-2e2b-0410-8846-a27921b304fc

org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/StockExpression.java

index 1cf1512d09bd626f4711cffa9921f601afd29c2d..32608c3b7c9c276508efb5c1ed87425fbcccf183 100644 (file)
@@ -31,6 +31,12 @@ import org.simantics.sysdyn.representation.Valve;
 import org.simantics.sysdyn.representation.utils.FormatUtils;\r
 import org.simantics.sysdyn.representation.utils.IndexUtils;\r
 \r
+/**\r
+ * Class representing a stock expression in a variable\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
 @GraphType("http://www.simantics.org/Sysdyn-1.1/StockExpression")\r
 public class StockExpression extends Expression {\r
 \r
@@ -39,11 +45,14 @@ public class StockExpression extends Expression {
 \r
     @Override\r
     public String getDeclaration(IndependentVariable variable) {\r
-//        Double value = getStartValue(variable);\r
+        \r
+        // See if the start parameter is used Stock(start = x, fixed = y) \r
         String value = null;\r
         if(useStartValue(variable))\r
             value = FormatUtils.formatExpressionForModelica(variable, initialEquation);\r
         \r
+        \r
+        // Build the enumeration indexes, if there are enumerations. Stock[enumIndexes, enum2Indexes, ...]\r
        ArrayIndexes ai = variable.getArrayIndexes();\r
        ArrayList<Enumeration> enumerations = null;\r
        if(ai != null) \r
@@ -64,25 +73,43 @@ public class StockExpression extends Expression {
                range = sb.toString();\r
        }\r
         \r
-       String each = "";\r
+        String each = "";\r
+       // each is required when a single value is used for all dimensions e.g. Stock[30](each start = 0)  \r
         if (value == null) {\r
+            // start parameter is not used, everything needs to be fixed=false\r
             if(ai != null && !ai.getEnumerations().isEmpty())\r
                 each = "each";\r
             return "    " + variable.getType() + " " + variable.getName() + range + "(" + each + " fixed=false);\n";\r
         } else {\r
-            if(ai != null && !ai.getEnumerations().isEmpty() && getStartValue(variable) != null)\r
-                each = "each";\r
-            return "    " + variable.getType() + " " + variable.getName() + range + "(" + each+ " start=" + value + "," + each + " fixed=true);\n";\r
+            // start parameter is used\r
+            \r
+            if(getStartValue(variable) != null) {\r
+                // a single number is used as the initial equation -> (each start, each fixed) if there are dimensions\r
+                if(ai != null && !ai.getEnumerations().isEmpty())\r
+                    each = "each";\r
+                return "    " + variable.getType() + " " + variable.getName() + range + "(" + each+ " start=" + value + ", " + each + " fixed=true);\n";\r
+            } else {\r
+                // a function or array constructor {.., .., ..} is used as the initial equation -> (start, each fixed) if there are dimensions\r
+                if(ai != null && !ai.getEnumerations().isEmpty())\r
+                    each = "each";\r
+                return "    " + variable.getType() + " " + variable.getName() + range + "(start=" + value + ", " + each + " fixed=true);\n";\r
+            }\r
         }\r
     }\r
 \r
     @Override\r
     public String getEquation(IndependentVariable variable) {\r
+        \r
+        // Build range e.g. Stock[2,3]\r
        String range = IndexUtils.rangeToIndexes(variable, this.getArrayRange());\r
+       \r
+       // Stock equation is always der(Stock)\r
         StringBuilder b = new StringBuilder();\r
         b.append("    der(")\r
         .append(variable.getName() + range)\r
         .append(") =");\r
+        \r
+        // Stock equation is formed automatically using incoming and outgoing flows (actually the nearest valves in those flows)\r
         ArrayList<Valve> incoming = ((Stock)variable).getIncomingValves();\r
         ArrayList<Valve> outgoing = ((Stock)variable).getOutgoingValves();\r
         if(incoming.isEmpty() && outgoing.isEmpty()) {\r
@@ -105,6 +132,7 @@ public class StockExpression extends Expression {
             }\r
 \r
         } else {\r
+            // incoming valves add and outgoing valves reduce the stock\r
             for(Valve valve : outgoing)\r
                 b.append("\n        - ").append(valve.getName() + range);\r
             for(Valve valve : incoming)\r
@@ -119,17 +147,25 @@ public class StockExpression extends Expression {
      * @return\r
      */\r
     private boolean useStartValue(IndependentVariable variable) {\r
+        // If no variables are used in the equation, start value is used\r
+        \r
+        // First the equation is formatted and parsed\r
         String equation = FormatUtils.formatExpressionForModelica(variable, initialEquation);\r
         ExpressionParser parser = new ExpressionParser(new StringReader(equation));\r
         try {\r
             parser.expr();\r
             if(parser.getReferences().isEmpty()) {\r
+                // if equation did not contain any references, start value is used\r
                 return true;\r
             } else {\r
+                // Check if references are references to sheets. \r
+                // Sheet references are allowed, since sheets contain only constants\r
                 boolean found = false;\r
                 Set<String> references = parser.getReferences().keySet();\r
+                \r
+                // Go through each reference\r
                 for(String reference : references) {\r
-                    // We only need the first element to know that it is a Sheet\r
+                    // We only need the first element to know that it is a Sheet (SheetName.CellOrRange)\r
                     reference = reference.split("\\.")[0]; \r
                     found = false;\r
                     for(IElement element : variable.getParentConfiguration().getElements()) {\r
@@ -144,6 +180,8 @@ public class StockExpression extends Expression {
                         if(found)\r
                             break;\r
                     }\r
+                    \r
+                    // If there was no sheet for this reference name, return false\r
                     if(!found)\r
                         return false;\r
                 }\r
@@ -155,23 +193,24 @@ public class StockExpression extends Expression {
 \r
     @Override\r
     public String getInitialEquation(IndependentVariable variable) {\r
-//     try {\r
-//             Double.parseDouble(initialEquation);\r
-//             return null;\r
-//     } catch (Exception e){\r
-//             // Has an initial equation\r
-//     } \r
+        // if start value is used, no initial equation is returned\r
         if(useStartValue(variable))\r
             return null;\r
+        // format the initial equation for modelica execution \r
         String equation = FormatUtils.formatExpressionForModelica(variable, initialEquation);\r
        String range = IndexUtils.rangeToIndexes(variable, this.getArrayRange());\r
        if(range == null)\r
                range = "";\r
        return "    " + variable.getName() + range + " = " + equation + ";\n";\r
-\r
     }\r
     \r
     \r
+    /**\r
+     * Return Double representation of the initial equation for given variable\r
+     * \r
+     * @param variable\r
+     * @return Double representing the initial equation or null if initial equation is not a double\r
+     */\r
     private Double getStartValue(IndependentVariable variable) {\r
        Double value = null;\r
        ArrayList<IExpression> expressions = variable.getExpressions().getExpressions();\r