From 446b5c99c4e5d972ee7490e6a170ff5739e50696 Mon Sep 17 00:00:00 2001 From: jkauttio Date: Mon, 8 Sep 2014 14:18:47 +0000 Subject: [PATCH] Improve delay class generation to also take the dimensions of the variable into account in cases where array shorthand expressions are used (does not currently support advanced array operations in expression indices if multiple expressions are defined) fixes #5275 git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@30230 ac1ea38d-2e2b-0410-8846-a27921b304fc --- .../sysdyn/modelica/ModelicaWriter.java | 117 +++++++++++++----- .../sysdyn/representation/Variable.java | 11 ++ .../expressions/DelayExpression.java | 10 +- .../expressions/Expression.java | 6 +- 4 files changed, 110 insertions(+), 34 deletions(-) diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/modelica/ModelicaWriter.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/modelica/ModelicaWriter.java index 29b806a3..87dd09e2 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/modelica/ModelicaWriter.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/modelica/ModelicaWriter.java @@ -99,24 +99,41 @@ public class ModelicaWriter { // find out which delays are used in the model and create the // necessary classes - HashSet delays = new HashSet(); + List generated = new ArrayList(); for (Configuration configuration : configurations) { for (IElement element : configuration.getElements()) { if (element instanceof IndependentVariable) { - for (IExpression expression : ((IndependentVariable)element).getExpressions()) { + IndependentVariable variable = (IndependentVariable)element; + for (IExpression expression : variable.getExpressions()) { if (expression instanceof DelayExpression) { - delays.add(((DelayExpression)expression).getOrder()); + DelayExpression delay = (DelayExpression)expression; + + int order = delay.getOrder(); + int[] dimensions = null; + + // TODO: is it cool to assume an expression is in the array + // shorthand form if the expression does not have an array range + // even though the variable has array indices? (if this + // assumption does not hold DelayExpression must be updated as well) + + if (expression.getArrayRange() == null) { + dimensions = variable.getDimensionArray(); + } + + // create the appropriate delay class if it has not + // been created already + + if (!generated.contains(getDelayName(order, dimensions))) { + b.append(getDelayClass(order, dimensions)); + b.append("\n"); + generated.add(getDelayName(order, dimensions)); + } } } } } } - for (Integer i : delays) { - b.append(getDelayClass(i)); - b.append("\n"); - } - HashSet sheetNames = new HashSet(); for(Sheet sheet : getSpreadSheets(configurations)) sheetNames.add(sheet.getModelicaName()); @@ -445,28 +462,37 @@ public class ModelicaWriter { public static final String DELAY_TIME = "delayTime"; public static final String DELAY_INITIAL = "initialValue"; - - private static String getDelayClass(int order) { + + private static String getDelayClass(int order, int...dimensions) { + boolean array = dimensions != null && dimensions.length > 0; + StringBuilder buffer = new StringBuilder(); - buffer.append("class " + getDelayName(order) + "\n"); + buffer.append("class ").append(getDelayName(order, dimensions)).append("\n"); // variable block // (possibly) continuous auxiliary variable - buffer.append("\tReal DL;\n"); + buffer.append('\t') + .append(getReal("DL")).append(";\n"); // (possibly) continuous delay time - buffer.append("\tReal " + DELAY_TIME + ";\n"); + buffer.append('\t') + .append(getReal(DELAY_TIME)).append(";\n"); // (possibly) continuous initial value - buffer.append("\tReal " + DELAY_INITIAL + ";\n"); + buffer.append('\t') + .append(getReal(DELAY_INITIAL, dimensions)).append(";\n"); // first valve - buffer.append("\tReal " + getDelayValve(0) + ";\n"); + buffer.append('\t') + .append(getReal(getDelayValve(0), dimensions)).append(";\n"); // stocks and valves, valves are delayed values of the variable for (int i = 1; i <= order; i++) { - buffer.append("\tReal LV"+i + "(fixed=false);\n"); - buffer.append("\tReal "+ getDelayValve(i) + ";\n"); + buffer.append('\t') + .append(getReal("LV"+i, dimensions)).append(' ') + .append("(" + (array ? "each " : "") + "fixed=false)").append(";\n"); + buffer.append('\t') + .append(getReal(getDelayValve(i), dimensions)).append(";\n"); } // initial equation block @@ -474,29 +500,64 @@ public class ModelicaWriter { // Each stock gets the same initial value for (int i = 1; i <= order; i++) { - buffer.append("\tLV"+i + " = DL * " + DELAY_INITIAL + ";\n"); + buffer.append('\t') + .append("LV"+i) + .append(" = ") + .append("DL" + (array ? " .* " : " * ") + DELAY_INITIAL) + .append(";\n"); } // equation block buffer.append("equation\n"); - buffer.append("\tDL = " + DELAY_TIME + " / "+order+";\n"); - + buffer.append('\t') + .append("DL") + .append(" = ") + .append(DELAY_TIME +" / " + order) + .append(";\n"); + // valves and stocks for (int i = 1; i <= order; i++) { - buffer.append("\tder(LV"+i + ") = - " + getDelayValve(i) + " + " + getDelayValve(i-1) + ";\n"); - buffer.append("\t"+ getDelayValve(i) + " = LV"+i + " / DL;\n"); + buffer.append('\t') + .append("der(LV"+i + ")") + .append(" = ") + .append("-" + getDelayValve(i) + (array ? " .+ " : " + ") + getDelayValve(i-1)) + .append(";\n"); + buffer.append('\t') + .append(getDelayValve(i)) + .append(" = ") + .append("LV"+i + (array ? " ./ " : " / ") + "DL") + .append(";\n"); } - buffer.append("end "); - buffer.append(getDelayName(order)); - buffer.append(";\n"); + buffer.append("end ").append(getDelayName(order, dimensions)).append(";\n"); return buffer.toString(); } - - public static String getDelayName(int order) { - return "order_"+order+"_delay"; + + private static String getReal(String name, int...dims) { + StringBuilder buffer = new StringBuilder(); + buffer.append("Real ").append(name); + if (dims != null && dims.length > 0) { + buffer.append('['); + for (int i = 0; i < dims.length; i++) { + if (i > 0) buffer.append(','); + buffer.append(dims[i]); + } + buffer.append(']'); + } + return buffer.toString(); + } + + public static String getDelayName(int order, int...dims) { + StringBuilder buffer = new StringBuilder(); + buffer.append("o_").append(order).append('_'); + if (dims != null && dims.length > 0) { + buffer.append("d_"); + for (int dim : dims) buffer.append(dim).append('_'); + } + buffer.append("delay"); + return buffer.toString(); } public static String getDelayValve(int order) { diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Variable.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Variable.java index 997e61db..92b49941 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Variable.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Variable.java @@ -114,6 +114,17 @@ public abstract class Variable implements IElement { return this.arrayIndexes; } + public int[] getDimensionArray() { + if (arrayIndexes == null) + return null; + + int[] dimensions = new int[arrayIndexes.size()]; + for (int i = 0; i < arrayIndexes.size(); i++) { + dimensions[i] = arrayIndexes.get(i).getEnumerationIndexes().size(); + } + return dimensions; + } + /** * * @return Expressions of this variable diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/DelayExpression.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/DelayExpression.java index 4edf3089..6865e112 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/DelayExpression.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/DelayExpression.java @@ -65,7 +65,15 @@ public class DelayExpression extends Expression { @Override public String getDeclarationAddition() { // instantiate the correct delay class for this expression - return "\t" + ModelicaWriter.getDelayName(order) + " " + instance() + ";\n"; + + // TODO: this is not necessary correct, see discussion in delay class + // generation code in ModelicaWriter.java + int[] dimensions = null; + if (getArrayRange() == null) { + dimensions = getParent().getDimensionArray(); + } + + return "\t" + ModelicaWriter.getDelayName(order, dimensions) + " " + instance() + ";\n"; } @Override diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/Expression.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/Expression.java index 48ac5957..98c51a57 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/Expression.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/Expression.java @@ -20,7 +20,6 @@ import org.simantics.sysdyn.SysdynResource; import org.simantics.sysdyn.manager.SysdynModel; import org.simantics.sysdyn.representation.IndependentVariable; import org.simantics.sysdyn.representation.utils.UnitUtils; -import org.simantics.sysdyn.unitParser.TokenMgrError; /** * Abstract class for any expression @@ -68,10 +67,7 @@ public abstract class Expression implements IExpression { @Override public String getArrayRange() { - if(range == null) - return ""; - else - return range; + return range; } @Override -- 2.47.1