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