From: jkauttio Date: Fri, 25 Apr 2014 12:58:29 +0000 (+0000) Subject: Fix enumeration handling for delay and stock expressions X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=39fa3bd964b9e74d19ed987f93d1162d5cb1e217;p=simantics%2Fsysdyn.git Fix enumeration handling for delay and stock expressions fixes #4840 git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/branches/dev-jkauttio@29354 ac1ea38d-2e2b-0410-8846-a27921b304fc --- diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/IndependentVariable.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/IndependentVariable.java index d61abcf0..3c0decd6 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/IndependentVariable.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/IndependentVariable.java @@ -63,12 +63,11 @@ public abstract class IndependentVariable extends Variable { // ;\n sb.append(";\n"); - + // Possible additions to expressions. e.g. helper classes and variables if(getExpressions() != null) { - String addition; for(IExpression e : getExpressions()) { - addition = e.getDeclarationAddition(); + String addition = e.getDeclarationAddition(); if(addition != null) sb.append(addition); } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Stock.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Stock.java index efa2f2db..54c1d29d 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Stock.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Stock.java @@ -62,8 +62,8 @@ public class Stock extends IndependentVariable { if (Variability.getVariability(this) == Variability.CONTINUOUS) { // start parameter is not used, everything needs to be fixed=false if(getArrayIndexes() != null && !getArrayIndexes().isEmpty()) - each = "each"; - return " " + getType() + " " + getModelicaName() + getRange() + "(" + each + " fixed=false);\n"; + each = "each "; + return " " + getType() + " " + getModelicaName() + getRange() + "(" + each + "fixed=false);\n"; } else { // Start parameter is used. Parameter guarantees that there is only one expression. StockExpression e = (StockExpression)getExpressions().get(0); @@ -71,9 +71,9 @@ public class Stock extends IndependentVariable { initialEquation = SheetFormatUtils.reformatSheetReferences(this, initialEquation); if(getArrayIndexes() != null && !getArrayIndexes().isEmpty()) - each = "each"; - + each = "each "; + // TODO: there is probably a bug with startvalue here return " " + getType() + " " + @@ -81,11 +81,11 @@ public class Stock extends IndependentVariable { getRange() + "(" + (e.getStartValue() != null ? each : "") + - " start=" + + "start=" + initialEquation + ", " + each + - " fixed=true);\n"; + "fixed=true);\n"; } } 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 6409704b..4edf3089 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 @@ -16,8 +16,7 @@ import org.simantics.objmap.annotations.GraphType; import org.simantics.objmap.annotations.RelatedValue; import org.simantics.sysdyn.SysdynResource; import org.simantics.sysdyn.manager.SysdynModel; -import org.simantics.sysdyn.representation.IndependentVariable; -import org.simantics.sysdyn.representation.Variability; +import org.simantics.sysdyn.modelica.ModelicaWriter; import org.simantics.sysdyn.representation.utils.FormatUtils; import org.simantics.sysdyn.representation.utils.IndexUtils; import org.simantics.sysdyn.representation.utils.UnitUtils; @@ -51,234 +50,97 @@ import org.simantics.sysdyn.representation.utils.UnitUtils; @GraphType(SysdynResource.URIs.DelayExpression) public class DelayExpression extends Expression { - @RelatedValue(SysdynResource.URIs.DelayExpression_initialValue) - private String initialValue; - - @RelatedValue(SysdynResource.URIs.DelayExpression_delayTime) - private String delayTime; - - @RelatedValue(SysdynResource.URIs.DelayExpression_order) - private Integer order; - - @RelatedValue(SysdynResource.URIs.DelayExpression_expression) - private String equation; - - @Override - public String getDeclarationAddition() { - String delayTime = FormatUtils.replaceWhitespace(this.delayTime); - delayTime = FormatUtils.formatExpressionForModelica(parent, delayTime); - String initialValue = FormatUtils.replaceWhitespace(this.initialValue); - initialValue = FormatUtils.formatExpressionForModelica(parent, initialValue); - Variability delayTimeVariability = Variability.getVariability((IndependentVariable)parent, delayTime); - Variability initialVariability = Variability.CONTINUOUS; - if(initialValue != null && initialValue.length() > 0) { - /* - * By default, initial value variability is continuous. - * If initial value has been set, it can be some other. - */ - initialVariability = Variability.getVariability(parent, initialValue); - } - - - StringBuilder declaration = new StringBuilder(); - - String range = parent.getRange(); - - // Delay declaration - declaration.append(" " + parent.getModelicaName() + "_delayClass " + parent.getModelicaName() + "_delayClass_instance"); - - // Change enumeration sizes from the delay class. Supports overridden enumerations in modules. - if(range.length() > 0 || !initialVariability.equals(Variability.CONTINUOUS) || !delayTimeVariability.equals(Variability.CONTINUOUS)) { - declaration.append("("); - - boolean started = false; - if(range.length() > 0) { - started = true; - String[] ranges = range.substring(1, range.length() - 1).split(","); - for(int i = 0; i < ranges.length; i++ ) { - String r = ranges[i]; - declaration.append(r.replace(".size", "size") + " = " + r); - if(i < ranges.length - 1) { - declaration.append(", "); - } - } - } - - // If initial value is not continuous, it is set in the module declaration - if(!initialVariability.equals(Variability.CONTINUOUS)) { - if(started) - declaration.append(", "); - started = true; - declaration.append("initialValue = " + initialValue); - } - - // If delay time is not continuous, it is set in the module declaration - if(!delayTimeVariability.equals(Variability.CONTINUOUS)) { - if(started) - declaration.append(", "); - declaration.append("delayTime = " + delayTime); - } - - declaration.append(")"); - } - declaration.append(";\n"); - - // Write the delay class - declaration.append(getDelayClass(range, order)); - return declaration.toString(); - } - - /** - * Creates a class that is used to implement the delay. Class contains - * a basic delay structure with "stocks and flows". The number of - * stocks and flows is determined by the order of the delay - * - * @param variable The variable for which the delay is created - * @param range Array range - * @param n Order of the delay - * @return - */ - private String getDelayClass(String range, int n) { - StringBuilder sb = new StringBuilder(); - - sb.append("class " + parent.getModelicaName() + "_delayClass\n"); - - // Enumeration sizes as parameters. Sizes correspond the enumeration sizes of variable - if(range.length() > 0) { - range = range.replaceAll(".size", "size"); - for(String r : range.substring(1, range.length() - 1).split(",")) { - sb.append("\t parameter Integer " + r + ";\n"); - } - } - - String delayTime = FormatUtils.replaceWhitespace(this.delayTime); - String dt = FormatUtils.formatExpressionForModelica(parent,delayTime); - Variability delayTimeVariability = Variability.getVariability(parent, dt); - if(!delayTimeVariability.equals(Variability.CONTINUOUS)) { - // Auxiliary variable - sb.append("\t" + delayTimeVariability.getText() + " Real" + range + " DL = delayTime/" + n + ";\n"); - // Delay time - sb.append("\t" + delayTimeVariability.getText() + " Real" + range + " delayTime;\n"); - } else { - // Continuous auxiliary variable - sb.append("\tReal" + range + " DL;\n"); - // Continuous delay time - sb.append("\tReal" + range + " delayTime;\n"); - } - - - // Get initial value variability - Variability initialValueVariability = Variability.CONTINUOUS; - String initEquation = FormatUtils.replaceWhitespace(this.initialValue); - initEquation = FormatUtils.formatExpressionForModelica(parent, initEquation); - if(initialValue != null && initialValue.length() > 0) { - initialValueVariability = Variability.getVariability(parent, initEquation); - } - - // Declare initial value (continuous or other) - String ivv = !initialValueVariability.equals(Variability.CONTINUOUS) ? initialValueVariability.getText() + " " : ""; - sb.append("\t" + ivv + "Real" + range + " initialValue;\n"); - - // First valve - sb.append("\tReal" + range + " delay0;\n"); - - // Stocks and valves. Valves are the delayed values of the variable - for(int i = 1; i <= n; i++) { - if(initialValueVariability.equals(Variability.CONTINUOUS) || delayTimeVariability.equals(Variability.CONTINUOUS)) - // Continuous initial value or delay time - sb.append("\tReal" + range + " LV" + i + "(" + (range.length() > 0 ? "each " : "") + "fixed=false);\n"); - else - // initial value and delay time are not continuous - sb.append("\tReal" + range + " LV" + i + - "(" + (range.length() > 0 ? "each " : "") + "fixed=true, start=initialValue " + (range.isEmpty() ? "*" : ".*") + " DL);\n"); - sb.append("\tReal" + range + " delay" + i + ";\n"); - } - - // If initial value or delay time are continuous, use initial equation block - if(initialValueVariability.equals(Variability.CONTINUOUS) || delayTimeVariability.equals(Variability.CONTINUOUS)) { - sb.append("initial equation\n"); - - // Each stock gets the same initial value - for(int i = 1; i <= n; i++) - sb.append("\tLV" + i +" = DL " + (range.isEmpty() ? "*" : ".*") + " initialValue;\n"); - } - - // Equation block - sb.append("equation\n"); - - if(delayTimeVariability.equals(Variability.CONTINUOUS)) - sb.append("\tDL = delayTime/" + n + ";\n"); - - // Valves and stocks - for(int i = 1; i <= n; i++) { - sb.append("\tder(LV" + i + ") = - delay" + i + " + delay" + (i - 1) + ";\n"); - sb.append("\tdelay" + i + " = LV" + i + " " + (range.isEmpty() ? "/" : "./") + "DL;\n"); - } - - sb.append("end " + parent.getModelicaName() + "_delayClass;\n"); - return sb.toString(); - } - - @Override - public String getEquation() { - StringBuilder sb = new StringBuilder(); - - String equation = FormatUtils.replaceWhitespace(this.equation); - equation = FormatUtils.formatExpressionForModelica(parent, equation); - String delayTime = FormatUtils.replaceWhitespace(this.delayTime); - delayTime = FormatUtils.formatExpressionForModelica(parent, delayTime); - String initialValue = FormatUtils.replaceWhitespace(this.initialValue); - initialValue = FormatUtils.formatExpressionForModelica(parent, initialValue); - - // First "valve" in the delay - sb.append(" " + parent.getModelicaName() + "_delayClass_instance.delay0 = " + equation + ";\n"); - - // Delay time (if continuous) - Variability delayTimeVariability = Variability.getVariability(parent, delayTime); - if(delayTimeVariability.equals(Variability.CONTINUOUS)) { - sb.append(" " + parent.getModelicaName() + "_delayClass_instance.delayTime = " + delayTime + ";\n"); - } - - // Initial value - if(initialValue == null || initialValue.length() == 0) { - // No initial value set, use delay0 (the first "valve") - sb.append(" " + parent.getModelicaName() + "_delayClass_instance.initialValue = " + parent.getModelicaName() + "_delayClass_instance.delay0;\n"); - } else { - // Continuous initial value - Variability initialVariability = Variability.getVariability(parent, initialValue); - if(initialVariability.equals(Variability.CONTINUOUS)) { - sb.append(" " + parent.getModelicaName() + "_delayClass_instance.initialValue = " + initialValue + ";\n"); - } - } - - // The value of the actual variable - String range = IndexUtils.rangeToIndexes(parent, this.getArrayRange()); - sb.append(" " + parent.getModelicaName() + (range.equals("[:]") ? "" : range) + " = " + parent.getModelicaName() + "_delayClass_instance.delay" + order + ";\n"); - return sb.toString(); - } - - @Override - public String getExpression() { - return "This + is + not + a + parameter + at + any + time"; - } - - @Override - public String getModelicaExpression() { - return getExpression(); - } - - @Override - public String validateUnits(ReadGraph graph, SysdynModel model) { - if(parent.getUnit() == null) - return "Unit not defined for " + parent.getName(); - - String result = UnitUtils.matchUnits(graph, model, parent.getParentConfiguration(), parent.getUnit(), equation); - if(result == null) - result = UnitUtils.matchUnits(graph, model, parent.getParentConfiguration(), parent.getUnit(), initialValue); - if(result == null) - result = UnitUtils.matchUnits(graph, model, parent.getParentConfiguration(), UnitUtils.getTimeUnit(graph, model), delayTime); - - return result; - } + @RelatedValue(SysdynResource.URIs.DelayExpression_initialValue) + private String initialValue; + + @RelatedValue(SysdynResource.URIs.DelayExpression_delayTime) + private String delayTime; + + @RelatedValue(SysdynResource.URIs.DelayExpression_order) + private Integer order; + + @RelatedValue(SysdynResource.URIs.DelayExpression_expression) + private String equation; + + @Override + public String getDeclarationAddition() { + // instantiate the correct delay class for this expression + return "\t" + ModelicaWriter.getDelayName(order) + " " + instance() + ";\n"; + } + + @Override + public String getEquation() { + StringBuilder sb = new StringBuilder(); + + String equation = FormatUtils.replaceWhitespace(this.equation); + equation = FormatUtils.formatExpressionForModelica(parent, equation); + String delayTime = FormatUtils.replaceWhitespace(this.delayTime); + delayTime = FormatUtils.formatExpressionForModelica(parent, delayTime); + String initialValue = FormatUtils.replaceWhitespace(this.initialValue); + initialValue = FormatUtils.formatExpressionForModelica(parent, initialValue); + + sb.append("\t" + instance() + "." + ModelicaWriter.getDelayValve(0) + " = " + equation + ";\n"); + + sb.append("\t" + instance() + "." + ModelicaWriter.DELAY_TIME + " = " + delayTime + ";\n"); + + sb.append("\t" + instance() + "." + ModelicaWriter.DELAY_INITIAL + " = "); + if (initialValue != null && !initialValue.isEmpty()) { + sb.append(initialValue); + } + else { + // if an initial value is not set, use the value of the first valve + sb.append(instance() + "." + ModelicaWriter.getDelayValve(0)); + } + sb.append(";\n"); + + // set the value of the variable + String range = IndexUtils.rangeToIndexes(parent, getArrayRange()); + // TODO: this variable name thing here (and in other expressions) is a hack and should be fixed + sb.append("\t" + parent.getModelicaName() + (range.equals("[:]") ? "" : range) + " = " + + instance() + "." + ModelicaWriter.getDelayValve(order) + ";\n"); + + return sb.toString(); + } + + @Override + public String getExpression() { + return "This + is + not + a + parameter + at + any + time"; + } + + @Override + public String getModelicaExpression() { + return getExpression(); + } + + @Override + public String validateUnits(ReadGraph graph, SysdynModel model) { + if(parent.getUnit() == null) + return "Unit not defined for " + parent.getName(); + + String result = UnitUtils.matchUnits(graph, model, parent.getParentConfiguration(), parent.getUnit(), equation); + if(result == null) + result = UnitUtils.matchUnits(graph, model, parent.getParentConfiguration(), parent.getUnit(), initialValue); + if(result == null) + result = UnitUtils.matchUnits(graph, model, parent.getParentConfiguration(), UnitUtils.getTimeUnit(graph, model), delayTime); + + return result; + } + + public int getOrder() { + return order; + } + + private String instance() { + // construct an identifier for this expression based on the array + // indices if necessary + String identifier; + if (getArrayRange() != null && !getArrayRange().isEmpty()) { + identifier = IndexUtils.rangeToIndexes(parent, getArrayRange()).replaceAll("[\\[\\]{},]", "_"); + } + else { + identifier = "_"; + } + return parent.getModelicaName() + identifier + "instance"; + } } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/IExpression.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/IExpression.java index 94a119ce..58de03cc 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/IExpression.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/IExpression.java @@ -27,22 +27,18 @@ public interface IExpression { /** * Get any possible additions to variable declaration. - * - * @param variable Declared independent variable * @return additions or null */ String getDeclarationAddition(); /** * Initial value for this variable and expression - * @param variable IndependentVariable * @return initial value or null */ String getInitialEquation(); /** * Get the actual equation of this expression - * @param variable IndependentVariable * @return equation or null */ String getEquation(); @@ -55,8 +51,7 @@ public interface IExpression { /** * Get the plain (possibly unformatted) expression from this expression. (type variable = EXPRESSION ;\n) - * @param variable - * @return + * @return */ String getExpression(); diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/ParameterExpression.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/ParameterExpression.java index 6723be47..5385212f 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/ParameterExpression.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/ParameterExpression.java @@ -40,11 +40,6 @@ public class ParameterExpression extends Expression { String equation = FormatUtils.replaceWhitespace(this.equation); return equation + " /* Actual value read from init file */"; } - - @Override - public String getDeclarationAddition() { - return ""; - } /** 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 95a3a5bd..a6efc5e2 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 @@ -71,7 +71,7 @@ public class StockExpression extends Expression { // Stock equation is always der(Stock) StringBuilder b = new StringBuilder(); b.append(" der(") - .append(modelicaEquation ? parent.getModelicaName() : parent.getName() + range) + .append(parent.getModelicaName() + (range.equals("[:]") ? "" : range)) .append(") = "); if (integralEquation != null) { @@ -193,7 +193,7 @@ public class StockExpression extends Expression { try { value = Double.parseDouble(initialEquation); } catch(NumberFormatException e1) { - + return null; } } } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/WithLookupExpression.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/WithLookupExpression.java index 27c09439..82acd991 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/WithLookupExpression.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/WithLookupExpression.java @@ -164,14 +164,14 @@ public class WithLookupExpression extends Expression { DefaultXYDataset dataset = new DefaultXYDataset(); dataset.addSeries("lookup", new double[][] {y, x}); JFreeChart chart = ChartFactory.createXYLineChart( - "", // chart title - "", // domain axis label - "", // range axis label - dataset, // data + "", // chart title + "", // domain axis label + "", // range axis label + dataset, // data PlotOrientation.HORIZONTAL, // Orientation - false, // include legend - false, // tooltips - false // urls + false, // include legend + false, // tooltips + false // urls ); StringWriter writer = new StringWriter(); diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/RepresentationUtils.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/RepresentationUtils.java index 09a9a202..6c5e3542 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/RepresentationUtils.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/RepresentationUtils.java @@ -31,7 +31,6 @@ import org.simantics.sysdyn.representation.Variable; public class RepresentationUtils { - /** * Returns true, if there is an active experiment and the active experiment * is a game experiment @@ -60,26 +59,26 @@ public class RepresentationUtils { * @return */ public static boolean isPartOfGameExperiment(Variable variable) { - Configuration conf = variable.getParentConfiguration(); - if(conf != null) - return conf.isGameConfiguration(); - else - return false; + Configuration conf = variable.getParentConfiguration(); + if(conf != null) + return conf.isGameConfiguration(); + else + return false; } - + /** - * Find out if a module is part of a game configuration. (This means that the module is a - * part of a game experiment) - * @param variable - * @return - */ - public static boolean isPartOfGameExperiment(Module module) { - Configuration conf = module.getParentConfiguration(); - if(conf != null) - return conf.isGameConfiguration(); - else - return false; - } + * Find out if a module is part of a game configuration. (This means that the module is a + * part of a game experiment) + * @param variable + * @return + */ + public static boolean isPartOfGameExperiment(Module module) { + Configuration conf = module.getParentConfiguration(); + if(conf != null) + return conf.isGameConfiguration(); + else + return false; + } /** @@ -138,18 +137,18 @@ public class RepresentationUtils { if(v.getName().equals(variable.getName())) { return null;// Reference to self. } else { - if(Variability.PARAMETER.equals(Variability.getVariability(v, false, null))) { - return v; - } else { - return null; - } - - /* + if(Variability.PARAMETER.equals(Variability.getVariability(v, false, null))) { + return v; + } else { + return null; + } + + /* if(v.getExpressions() == null || v.getExpressions().getExpressions().size() > 1) return null; - + IExpression e = v.getExpressions().getExpressions().get(0); - + if(e instanceof ParameterExpression) return v; */ @@ -162,36 +161,36 @@ public class RepresentationUtils { public static Variable getVariable(Configuration configuration, String name) { - Configuration conf = configuration; - // This function seems to be used with both whitespaced and - // underscored versions of the variable name. - String whitespacedName = name.replace('_', ' '); - String[] components = whitespacedName.split("\\."); - - for(String component : components) { - - Configuration newConf = null; - - for(IElement element : conf.getElements()) { - if(element instanceof Variable) { - Variable variable = (Variable) element; - if(variable.getName().equals(component)) { - return variable; - } - } else if(element instanceof Module) { - Module m = (Module)element; - if(m.getName().equals(component)) { - newConf = m.getType().getConfiguration(); - } - } - } - - // If variable or configuration has not been found, return null - if(newConf == null) - return null; - } - - return null; + Configuration conf = configuration; + // This function seems to be used with both whitespaced and + // underscored versions of the variable name. + String whitespacedName = name.replace('_', ' '); + String[] components = whitespacedName.split("\\."); + + for(String component : components) { + + Configuration newConf = null; + + for(IElement element : conf.getElements()) { + if(element instanceof Variable) { + Variable variable = (Variable) element; + if(variable.getName().equals(component)) { + return variable; + } + } else if(element instanceof Module) { + Module m = (Module)element; + if(m.getName().equals(component)) { + newConf = m.getType().getConfiguration(); + } + } + } + + // If variable or configuration has not been found, return null + if(newConf == null) + return null; + } + + return null; } }