import org.simantics.sysdyn.representation.Sheet;\r
import org.simantics.sysdyn.representation.Stock;\r
import org.simantics.sysdyn.representation.Variable;\r
+import org.simantics.sysdyn.representation.expressions.DelayExpression;\r
+import org.simantics.sysdyn.representation.expressions.IExpression;\r
\r
/**\r
* ModelicaWriter writes Sysdyn model representations (objmap) into Modelica code.\r
*/\r
public class ModelicaWriter {\r
\r
- /**\r
- * Write a collection of configurations into a single Modelica code\r
- * @param isGame \r
- * \r
- * @param Configurations Configurations, one main configuration and possible modules\r
- * @return Complete Modelica code of a model\r
- */\r
- public static String write(Collection<Configuration> _configurations, boolean isGame, String omVersion) {\r
- \r
- ArrayList<Configuration> configurations = new ArrayList<Configuration>(_configurations);\r
- Collections.sort(configurations, new Comparator<Configuration>() {\r
-\r
- boolean uses(Configuration o1, Configuration o2) {\r
- ModuleType type = o2.getModuleType();\r
- if(type == null) return false;\r
- for(IElement e : o1.getElements()) {\r
- if(e instanceof Module) {\r
- Module m = (Module)e;\r
- if(m.getType().equals(type)) {\r
- return true;\r
- }\r
- }\r
- }\r
- return false;\r
- }\r
- \r
+ /**\r
+ * Write a collection of configurations into a single Modelica code\r
+ * @param isGame \r
+ * \r
+ * @param Configurations Configurations, one main configuration and possible modules\r
+ * @return Complete Modelica code of a model\r
+ */\r
+ public static String write(Collection<Configuration> _configurations, boolean isGame, String omVersion) {\r
+\r
+ ArrayList<Configuration> configurations = new ArrayList<Configuration>(_configurations);\r
+ Collections.sort(configurations, new Comparator<Configuration>() {\r
+\r
+ boolean uses(Configuration o1, Configuration o2) {\r
+ ModuleType type = o2.getModuleType();\r
+ if(type == null) return false;\r
+ for(IElement e : o1.getElements()) {\r
+ if(e instanceof Module) {\r
+ Module m = (Module)e;\r
+ if(m.getType().equals(type)) {\r
+ return true;\r
+ }\r
+ }\r
+ }\r
+ return false;\r
+ }\r
+\r
@Override\r
public int compare(Configuration o1, Configuration o2) {\r
- if(uses(o1, o2)) return 1;\r
- else if(uses(o2, o1)) return -1;\r
- else return 0;\r
+ if(uses(o1, o2)) return 1;\r
+ else if(uses(o2, o1)) return -1;\r
+ else return 0;\r
}\r
- \r
+\r
});\r
- \r
- Configuration modelConf = null;\r
- for(Configuration conf : configurations) {\r
- if(conf.getModel() != null) {\r
- modelConf = conf;\r
- }\r
- }\r
- StringBuilder b = new StringBuilder();\r
- \r
- int spreadsheetlocation = b.length();\r
-\r
- String modelName = modelConf.getLabel().replace(" ", "");\r
- b.append("model " + modelName + "\n");\r
-\r
- // Super class for enumerations\r
- b.append("partial class Enumeration_class\n");\r
- b.append(" parameter Integer size;\n");\r
- b.append(" parameter Integer elements[:];\n");\r
- b.append("end Enumeration_class;\n\n");\r
- \r
- \r
- HashSet<String> sheetNames = new HashSet<String>();\r
- for(Sheet sheet : getSpreadSheets(configurations))\r
- sheetNames.add(sheet.getModelicaName());\r
- \r
- // Write all module configurations to the declarations part (first)\r
- for(Configuration conf : configurations) {\r
- conf.setIsGameConfiguration(isGame);\r
- if(!conf.equals(modelConf))\r
- writeConfiguration(conf, sheetNames, b);\r
- }\r
- \r
- // Write model configuration last, so that equations-part does not contain module definitions\r
- modelConf.setIsGameConfiguration(isGame);\r
- writeConfiguration(modelConf, sheetNames, b);\r
- \r
- b.append("end " + modelName + ";\n\n");\r
- \r
- // Insert spreadsheets\r
- if(omVersion != null && omVersion.startsWith("1.9")) {\r
- b.insert(spreadsheetlocation, getGlobalSpreadSheets(configurations));\r
- } else {\r
- b.append(getGlobalSpreadSheets(configurations));\r
- }\r
-\r
- \r
- return b.toString();\r
- }\r
- \r
- /**\r
- * Get all spreadsheets that are found in the model\r
- * @param configurations\r
- * @return\r
- */\r
- private static List<Sheet> getSpreadSheets(Collection<Configuration> configurations) {\r
- for(Configuration conf : configurations) {\r
- if(conf.getModel() != null) {\r
- for(IElement e : conf.getElements()) {\r
- if(e instanceof Book) {\r
- return ((Book)e).getSheets();\r
- }\r
- }\r
- }\r
- }\r
- return Collections.emptyList();\r
- }\r
- \r
- /**\r
- * \r
- */\r
- private static String getGlobalSpreadSheets(Collection<Configuration> configurations) {\r
- StringBuilder sheets = new StringBuilder();\r
- for(Configuration conf : configurations) {\r
- if(conf.getModel() != null) {\r
- for(IElement e : conf.getElements()) {\r
- if(e instanceof Book) {\r
- return ((Book)e).getBook();\r
- }\r
- }\r
- }\r
- }\r
- \r
- return sheets.toString();\r
- }\r
-\r
- /**\r
- * Write a single configuration to a given string builder\r
- * \r
- * @param configuration Model or module configuration\r
- * @param b String builder\r
- */\r
- private static void writeConfiguration(Configuration configuration, HashSet<String> sheetNames, StringBuilder b) {\r
- boolean defTime = true;\r
- String app;\r
- \r
- // Lists for storing different configuration elements\r
- ArrayList<IndependentVariable> variables = new ArrayList<IndependentVariable>();\r
- ArrayList<Input> inputs = new ArrayList<Input>();\r
- ArrayList<Module> modules = new ArrayList<Module>();\r
- ArrayList<Stock> stocks = new ArrayList<Stock>();\r
- ArrayList<Enumeration> enumerations = new ArrayList<Enumeration>();\r
- ArrayList<Dependency> inputDependencies = new ArrayList<Dependency>();\r
- ArrayList<Dependency> outputDependencies = new ArrayList<Dependency>();\r
- HashMap<String, ArrayList<Input>> moduleInputs = new HashMap<String, ArrayList<Input>>();\r
-\r
- // Initialize lists\r
- for(IElement element : configuration.getElements()) {\r
- if(element instanceof IndependentVariable) {\r
- // Normal variable\r
- variables.add((IndependentVariable)element);\r
- if(element instanceof Stock)\r
- // Stock\r
- stocks.add((Stock)element);\r
- } else if (element instanceof Module) {\r
- // Module\r
- Module m = (Module)element; \r
- modules.add(m);\r
- moduleInputs.put(m.getName(), new ArrayList<Input>());\r
- for(IElement e : m.getType().getConfiguration().getElements())\r
- // Inputs inside the module\r
- if(e instanceof Input && !((Input)e).isHeadOfDependency()) {\r
- moduleInputs.get(m.getName()).add((Input)e);\r
- }\r
- } else if (element instanceof Input) {\r
- // Input variables\r
- inputs.add((Input)element);\r
- } else if (element instanceof Enumeration) {\r
- // Enumerations\r
- enumerations.add((Enumeration)element);\r
- } else if (element instanceof Dependency) {\r
- Dependency dependency = (Dependency)element;\r
- if(dependency.getHead() instanceof Module) {\r
- // References given to child modules\r
- outputDependencies.add(dependency);\r
- } else if(dependency.getTail() instanceof Module){\r
- // References from child modules\r
- inputDependencies.add(dependency);\r
- }\r
- }\r
- }\r
- \r
- // Setup input references. (Input, String reference to another variable)\r
- HashMap<Input, String> inputReferences = new HashMap<Input, String>();\r
- setupInputReferences(inputReferences, inputDependencies);\r
- \r
-\r
- // If the configuration is model configuration, use model name. Otherwise, use configuration name.\r
- ModuleType mt = configuration.getModuleType();\r
- \r
- // className == null, if this is a model configuration. model configuration start and end are written in ModelicaWriter.write\r
- String className = mt != null ? (mt.getName().replace(" ", "")) : null;\r
- \r
- if(className != null)\r
- b.append("\nclass ").append(className);\r
- \r
- // Add spreadsheets to all modules and model. Model is "inner" and modules "outer"\r
- String globalStatus = mt != null ? "outer" : "inner";\r
- for(String sheetName : sheetNames)\r
- b.append("\n " + globalStatus + " " + sheetName + "_class" + " "+ sheetName + ";");\r
- \r
- b.append("\n");\r
-\r
-\r
- if(!enumerations.isEmpty()) {\r
- b.append("// Enumeration definitions\n");\r
- for(Enumeration e : enumerations) {\r
- b.append(e.getDeclaration());\r
- }\r
- }\r
-\r
- b.append("// Variable definitions\n");\r
- for(IndependentVariable variable : variables) {\r
- app = variable.getDeclaration();\r
- if (app != null) b.append(app);\r
- }\r
- \r
- if(defTime) {\r
- // Time variable for FMU (game) simulations\r
- if(configuration.isGameConfiguration()) {\r
- if(configuration.getModel() != null)\r
- // Parameter for model root. Values changed in FMU simulator\r
- b.append(" parameter Real time = 0;\n");\r
- else\r
- // Continuous variable for module instances\r
- b.append(" Real time;\n");\r
-\r
- }\r
- }\r
-\r
- if(!modules.isEmpty()) {\r
- b.append("// Module definitions\n");\r
- for(Module m : modules) {\r
- b.append(m.getDeclaration());\r
- }\r
- }\r
-\r
-\r
- // Input definitions\r
- inputDefinitions(b, configuration, inputs, inputReferences);\r
-\r
- boolean initialEquations = false;\r
- for(Stock stock : stocks) {\r
- app = stock.getInitialEquation();\r
- if (app != null) {\r
- if(initialEquations == false) {\r
- initialEquations = true;\r
- b.append("// Initial Equations\n");\r
- b.append("initial equation\n");\r
- }\r
- b.append(app);\r
- }\r
- }\r
-\r
- boolean equation = false;\r
- b.append("// Equations\n");\r
- for(IndependentVariable variable : variables) {\r
- app = variable.getEquation();\r
- if (app != null) {\r
- if(!equation) {\r
- b.append("equation\n");\r
- equation = true;\r
- }\r
- \r
- b.append(app);\r
- }\r
- }\r
- \r
- // If "equation" has not been added but there are still equations to be defined, add "equation"\r
- if(!equation && (!inputReferences.isEmpty() || !outputDependencies.isEmpty() ||\r
- !moduleInputs.isEmpty() || !modules.isEmpty()))\r
- b.append("equation\n");\r
-\r
- // Continous input references\r
- continuousInputReferences(b, inputReferences);\r
- \r
- b.append("// Outputs\n");\r
- for(Dependency dependency : outputDependencies) {\r
- Variable variable = (Variable)dependency.getTail();\r
- Module module = (Module)dependency.getHead();\r
- Input reference = (Input)dependency.refersTo();\r
- if(reference != null && reference.getName() != null && (reference.getVariability() == null || reference.getVariability().isEmpty())) {\r
- b.append(" " + module.getName() + "." + reference.getModelicaName() + " = " + variable.getModelicaName() + ";\n");\r
- moduleInputs.get(module.getName()).remove(reference);\r
- }\r
- }\r
-\r
- b.append("// Default values for inputs in modules\n");\r
- for(String moduleLabel : moduleInputs.keySet()) {\r
- for(Input input : moduleInputs.get(moduleLabel)) {\r
- if(input.getVariability() == null || input.getVariability().isEmpty())\r
- b.append(" " + moduleLabel + "." + input.getModelicaName() + " = " + input.getDefaultInputValue(moduleLabel) + ";\n");\r
- }\r
- }\r
- \r
- if(defTime) {\r
- if(configuration.isGameConfiguration() && !modules.isEmpty()) {\r
- b.append("// Time values for module\n");\r
- for(Module m : modules) {\r
- b.append(" " + m.getName() + ".time = time;\n");\r
- }\r
- }\r
- }\r
-\r
- if(className != null)\r
- b.append("end ").append(className).append(";\n\n");\r
-\r
- }\r
- \r
+\r
+ Configuration modelConf = null;\r
+ for(Configuration conf : configurations) {\r
+ if(conf.getModel() != null) {\r
+ modelConf = conf;\r
+ }\r
+ }\r
+ StringBuilder b = new StringBuilder();\r
+\r
+ int spreadsheetlocation = b.length();\r
+\r
+ String modelName = modelConf.getLabel().replace(" ", "");\r
+ b.append("model " + modelName + "\n");\r
+\r
+ // Super class for enumerations\r
+ b.append("partial class Enumeration_class\n");\r
+ b.append(" parameter Integer size;\n");\r
+ b.append(" parameter Integer elements[:];\n");\r
+ b.append("end Enumeration_class;\n\n");\r
+\r
+ // find out which delays are used in the model and create the\r
+ // necessary classes\r
+ HashSet<Integer> delays = new HashSet<Integer>();\r
+ for (Configuration configuration : configurations) {\r
+ for (IElement element : configuration.getElements()) {\r
+ if (element instanceof IndependentVariable) {\r
+ for (IExpression expression : ((IndependentVariable)element).getExpressions()) {\r
+ if (expression instanceof DelayExpression) {\r
+ delays.add(((DelayExpression)expression).getOrder());\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ for (Integer i : delays) {\r
+ b.append(getDelayClass(i));\r
+ b.append("\n");\r
+ }\r
+\r
+ HashSet<String> sheetNames = new HashSet<String>();\r
+ for(Sheet sheet : getSpreadSheets(configurations))\r
+ sheetNames.add(sheet.getModelicaName());\r
+\r
+ // Write all module configurations to the declarations part (first)\r
+ for(Configuration conf : configurations) {\r
+ conf.setIsGameConfiguration(isGame);\r
+ if(!conf.equals(modelConf))\r
+ writeConfiguration(conf, sheetNames, b);\r
+ }\r
+\r
+ // Write model configuration last, so that equations-part does not contain module definitions\r
+ modelConf.setIsGameConfiguration(isGame);\r
+ writeConfiguration(modelConf, sheetNames, b);\r
+\r
+ b.append("end " + modelName + ";\n\n");\r
+\r
+ // Insert spreadsheets\r
+ if(omVersion != null && omVersion.startsWith("1.9")) {\r
+ b.insert(spreadsheetlocation, getGlobalSpreadSheets(configurations));\r
+ } else {\r
+ b.append(getGlobalSpreadSheets(configurations));\r
+ }\r
+\r
+ return b.toString();\r
+ }\r
+\r
+ /**\r
+ * Get all spreadsheets that are found in the model\r
+ * @param configurations\r
+ * @return\r
+ */\r
+ private static List<Sheet> getSpreadSheets(Collection<Configuration> configurations) {\r
+ for(Configuration conf : configurations) {\r
+ if(conf.getModel() != null) {\r
+ for(IElement e : conf.getElements()) {\r
+ if(e instanceof Book) {\r
+ return ((Book)e).getSheets();\r
+ }\r
+ }\r
+ }\r
+ }\r
+ return Collections.emptyList();\r
+ }\r
+\r
+ /**\r
+ * \r
+ */\r
+ private static String getGlobalSpreadSheets(Collection<Configuration> configurations) {\r
+ StringBuilder sheets = new StringBuilder();\r
+ for(Configuration conf : configurations) {\r
+ if(conf.getModel() != null) {\r
+ for(IElement e : conf.getElements()) {\r
+ if(e instanceof Book) {\r
+ return ((Book)e).getBook();\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return sheets.toString();\r
+ }\r
+\r
/**\r
- * Define continuous input references\r
- * @param b String builder\r
- * @param inputReferences Input references\r
- */\r
- private static void continuousInputReferences(StringBuilder b, HashMap<Input, String> inputReferences) {\r
- b.append("// Inputs\n");\r
- for(Input i : inputReferences.keySet()) {\r
- if(i.getVariability() == null || i.getVariability().isEmpty()) {\r
- // Define only continuous variables here\r
- b.append(" " + i.getModelicaName() + " = " + inputReferences.get(i));\r
- }\r
- }\r
- }\r
-\r
- /**\r
- * Setup input references for all inputs that are defined in child modules\r
- * \r
- * @param inputReferences Map containing the references\r
- * @param inputDependencies List of input dependencies\r
- */\r
- private static void setupInputReferences(HashMap<Input, String> inputReferences, ArrayList<Dependency> inputDependencies) {\r
- for(Dependency dependency : inputDependencies) {\r
- Input input = (Input)dependency.getHead();\r
- Module module = (Module)dependency.getTail();\r
- Variable reference = (Variable)dependency.refersTo();\r
- String expression;\r
- // If reference exists, use reference name. Otherwise, use default value.\r
- if(reference != null && reference.getName() != null)\r
- expression = module.getName() + "." + reference.getModelicaName() + ";\n";\r
-\r
- else\r
- expression = input.getDefaultInputValue() + ";\n";\r
- \r
- inputReferences.put(input, expression);\r
- }\r
- }\r
-\r
- /**\r
- * Build input definitions\r
- * \r
- * @param b String builder\r
- * @param configuration Module configuration\r
- * @param inputs All inputs of this module\r
- * @param inputReferences \r
- */\r
- private static void inputDefinitions(StringBuilder b, Configuration configuration, ArrayList<Input> inputs, HashMap<Input, String> inputReferences) {\r
- if(inputs.isEmpty())\r
- return;\r
- \r
- b.append("// Input definitions\n");\r
- for(Input i : inputs) {\r
- if(i.getVariability() != null && !i.getVariability().isEmpty()) {\r
- // Input is NOT continuous\r
- if(inputReferences.containsKey(i)) {\r
- // Input is defined in a child module\r
- String declaration = i.getDeclaration();\r
- declaration = declaration.substring(0, declaration.length() - 2); // remove ";\n" from the end\r
- b.append(declaration + " = " + inputReferences.get(i));\r
- } else {\r
- // Input is not defined in a child module, use default value\r
- b.append(i.getDeclarationWithValue());\r
- }\r
- } else if(configuration.getModel() != null && !i.isHeadOfDependency()) {\r
- /*\r
- * Input is in the top of the hierarchy, \r
- * and it does not get value from anywhere else.\r
- * => Declare it wit its default value \r
- */\r
- b.append(i.getDeclarationWithValue());\r
- } else {\r
- // Continuous => Parent module takes care of declaring a value for the input\r
- b.append(i.getDeclaration());\r
- }\r
- }\r
- }\r
-\r
- public String escape(String name) {\r
- return name.replace(' ', '_');\r
- }\r
+ * Write a single configuration to a given string builder\r
+ * \r
+ * @param configuration Model or module configuration\r
+ * @param b String builder\r
+ */\r
+ private static void writeConfiguration(Configuration configuration, HashSet<String> sheetNames, StringBuilder b) {\r
+ boolean defTime = true;\r
+ String app;\r
+\r
+ // Lists for storing different configuration elements\r
+ ArrayList<IndependentVariable> variables = new ArrayList<IndependentVariable>();\r
+ ArrayList<Input> inputs = new ArrayList<Input>();\r
+ ArrayList<Module> modules = new ArrayList<Module>();\r
+ ArrayList<Stock> stocks = new ArrayList<Stock>();\r
+ ArrayList<Enumeration> enumerations = new ArrayList<Enumeration>();\r
+ ArrayList<Dependency> inputDependencies = new ArrayList<Dependency>();\r
+ ArrayList<Dependency> outputDependencies = new ArrayList<Dependency>();\r
+ HashMap<String, ArrayList<Input>> moduleInputs = new HashMap<String, ArrayList<Input>>();\r
+\r
+ // Initialize lists\r
+ for(IElement element : configuration.getElements()) {\r
+ if(element instanceof IndependentVariable) {\r
+ // Normal variable\r
+ variables.add((IndependentVariable)element);\r
+ if(element instanceof Stock)\r
+ // Stock\r
+ stocks.add((Stock)element);\r
+ } else if (element instanceof Module) {\r
+ // Module\r
+ Module m = (Module)element; \r
+ modules.add(m);\r
+ moduleInputs.put(m.getName(), new ArrayList<Input>());\r
+ for(IElement e : m.getType().getConfiguration().getElements())\r
+ // Inputs inside the module\r
+ if(e instanceof Input && !((Input)e).isHeadOfDependency()) {\r
+ moduleInputs.get(m.getName()).add((Input)e);\r
+ }\r
+ } else if (element instanceof Input) {\r
+ // Input variables\r
+ inputs.add((Input)element);\r
+ } else if (element instanceof Enumeration) {\r
+ // Enumerations\r
+ enumerations.add((Enumeration)element);\r
+ } else if (element instanceof Dependency) {\r
+ Dependency dependency = (Dependency)element;\r
+ if(dependency.getHead() instanceof Module) {\r
+ // References given to child modules\r
+ outputDependencies.add(dependency);\r
+ } else if(dependency.getTail() instanceof Module){\r
+ // References from child modules\r
+ inputDependencies.add(dependency);\r
+ }\r
+ }\r
+ }\r
+\r
+ // Setup input references. (Input, String reference to another variable)\r
+ HashMap<Input, String> inputReferences = new HashMap<Input, String>();\r
+ setupInputReferences(inputReferences, inputDependencies);\r
+\r
+\r
+ // If the configuration is model configuration, use model name. Otherwise, use configuration name.\r
+ ModuleType mt = configuration.getModuleType();\r
+\r
+ // className == null, if this is a model configuration. model configuration start and end are written in ModelicaWriter.write\r
+ String className = mt != null ? (mt.getName().replace(" ", "")) : null;\r
+\r
+ if(className != null)\r
+ b.append("class "+className+"\n").append(className);\r
+\r
+ // Add spreadsheets to all modules and model. Model is "inner" and modules "outer"\r
+ String globalStatus = mt != null ? "outer" : "inner";\r
+ for(String sheetName : sheetNames)\r
+ b.append(" " + globalStatus + " " + sheetName + "_class" + " "+ sheetName + ";\n");\r
+\r
+ if(!enumerations.isEmpty()) {\r
+ b.append("// Enumeration definitions\n");\r
+ for(Enumeration e : enumerations) {\r
+ b.append(e.getDeclaration());\r
+ }\r
+ }\r
+\r
+ b.append("// Variable definitions\n");\r
+ for(IndependentVariable variable : variables) {\r
+ app = variable.getDeclaration();\r
+ if (app != null) b.append(app);\r
+ }\r
+\r
+ if(defTime) {\r
+ // Time variable for FMU (game) simulations\r
+ if(configuration.isGameConfiguration()) {\r
+ if(configuration.getModel() != null)\r
+ // Parameter for model root. Values changed in FMU simulator\r
+ b.append(" parameter Real time = 0;\n");\r
+ else\r
+ // Continuous variable for module instances\r
+ b.append(" Real time;\n");\r
+\r
+ }\r
+ }\r
+\r
+ if(!modules.isEmpty()) {\r
+ b.append("// Module definitions\n");\r
+ for(Module m : modules) {\r
+ b.append(m.getDeclaration());\r
+ }\r
+ }\r
+\r
+\r
+ // Input definitions\r
+ inputDefinitions(b, configuration, inputs, inputReferences);\r
+\r
+ boolean initialEquations = false;\r
+ for(Stock stock : stocks) {\r
+ app = stock.getInitialEquation();\r
+ if (app != null) {\r
+ if(initialEquations == false) {\r
+ initialEquations = true;\r
+ b.append("// Initial Equations\n");\r
+ b.append("initial equation\n");\r
+ }\r
+ b.append(app);\r
+ }\r
+ }\r
+\r
+ boolean equation = false;\r
+ b.append("// Equations\n");\r
+ for(IndependentVariable variable : variables) {\r
+ app = variable.getEquation();\r
+ if (app != null) {\r
+ if(!equation) {\r
+ b.append("equation\n");\r
+ equation = true;\r
+ }\r
+\r
+ b.append(app);\r
+ }\r
+ }\r
+\r
+ // If "equation" has not been added but there are still equations to be defined, add "equation"\r
+ if(!equation && (!inputReferences.isEmpty() || !outputDependencies.isEmpty() ||\r
+ !moduleInputs.isEmpty() || !modules.isEmpty()))\r
+ b.append("equation\n");\r
+\r
+ // Continuous input references\r
+ continuousInputReferences(b, inputReferences);\r
+\r
+ b.append("// Outputs\n");\r
+ for(Dependency dependency : outputDependencies) {\r
+ Variable variable = (Variable)dependency.getTail();\r
+ Module module = (Module)dependency.getHead();\r
+ Input reference = (Input)dependency.refersTo();\r
+ if(reference != null && reference.getName() != null && (reference.getVariability() == null || reference.getVariability().isEmpty())) {\r
+ b.append(" " + module.getName() + "." + reference.getModelicaName() + " = " + variable.getModelicaName() + ";\n");\r
+ moduleInputs.get(module.getName()).remove(reference);\r
+ }\r
+ }\r
+\r
+ b.append("// Default values for inputs in modules\n");\r
+ for(String moduleLabel : moduleInputs.keySet()) {\r
+ for(Input input : moduleInputs.get(moduleLabel)) {\r
+ if(input.getVariability() == null || input.getVariability().isEmpty())\r
+ b.append(" " + moduleLabel + "." + input.getModelicaName() + " = " + input.getDefaultInputValue(moduleLabel) + ";\n");\r
+ }\r
+ }\r
+\r
+ if(defTime) {\r
+ if(configuration.isGameConfiguration() && !modules.isEmpty()) {\r
+ b.append("// Time values for module\n");\r
+ for(Module m : modules) {\r
+ b.append(" " + m.getName() + ".time = time;\n");\r
+ }\r
+ }\r
+ }\r
+\r
+ if(className != null)\r
+ b.append("end ").append(className).append(";\n\n");\r
+\r
+ }\r
+\r
+ /**\r
+ * Define continuous input references\r
+ * @param b String builder\r
+ * @param inputReferences Input references\r
+ */\r
+ private static void continuousInputReferences(StringBuilder b, HashMap<Input, String> inputReferences) {\r
+ b.append("// Inputs\n");\r
+ for(Input i : inputReferences.keySet()) {\r
+ if(i.getVariability() == null || i.getVariability().isEmpty()) {\r
+ // Define only continuous variables here\r
+ b.append(" " + i.getModelicaName() + " = " + inputReferences.get(i));\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Setup input references for all inputs that are defined in child modules\r
+ * \r
+ * @param inputReferences Map containing the references\r
+ * @param inputDependencies List of input dependencies\r
+ */\r
+ private static void setupInputReferences(HashMap<Input, String> inputReferences, ArrayList<Dependency> inputDependencies) {\r
+ for(Dependency dependency : inputDependencies) {\r
+ Input input = (Input)dependency.getHead();\r
+ Module module = (Module)dependency.getTail();\r
+ Variable reference = (Variable)dependency.refersTo();\r
+ String expression;\r
+ // If reference exists, use reference name. Otherwise, use default value.\r
+ if(reference != null && reference.getName() != null)\r
+ expression = module.getName() + "." + reference.getModelicaName() + ";\n";\r
+\r
+ else\r
+ expression = input.getDefaultInputValue() + ";\n";\r
+\r
+ inputReferences.put(input, expression);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Build input definitions\r
+ * \r
+ * @param b String builder\r
+ * @param configuration Module configuration\r
+ * @param inputs All inputs of this module\r
+ * @param inputReferences \r
+ */\r
+ private static void inputDefinitions(StringBuilder b, Configuration configuration, ArrayList<Input> inputs, HashMap<Input, String> inputReferences) {\r
+ if(inputs.isEmpty())\r
+ return;\r
+\r
+ b.append("// Input definitions\n");\r
+ for(Input i : inputs) {\r
+ if(i.getVariability() != null && !i.getVariability().isEmpty()) {\r
+ // Input is NOT continuous\r
+ if(inputReferences.containsKey(i)) {\r
+ // Input is defined in a child module\r
+ String declaration = i.getDeclaration();\r
+ declaration = declaration.substring(0, declaration.length() - 2); // remove ";\n" from the end\r
+ b.append(declaration + " = " + inputReferences.get(i));\r
+ } else {\r
+ // Input is not defined in a child module, use default value\r
+ b.append(i.getDeclarationWithValue());\r
+ }\r
+ } else if(configuration.getModel() != null && !i.isHeadOfDependency()) {\r
+ /*\r
+ * Input is in the top of the hierarchy, \r
+ * and it does not get value from anywhere else.\r
+ * => Declare it wit its default value \r
+ */\r
+ b.append(i.getDeclarationWithValue());\r
+ } else {\r
+ // Continuous => Parent module takes care of declaring a value for the input\r
+ b.append(i.getDeclaration());\r
+ }\r
+ }\r
+ }\r
+\r
+ public String escape(String name) {\r
+ return name.replace(' ', '_');\r
+ }\r
+ \r
+ public static final String DELAY_TIME = "delayTime";\r
+ public static final String DELAY_INITIAL = "initialValue";\r
+\r
+ private static String getDelayClass(int order) {\r
+ StringBuilder buffer = new StringBuilder();\r
+\r
+ buffer.append("class " + getDelayName(order) + "\n");\r
+\r
+ // variable block\r
+\r
+ // (possibly) continuous auxiliary variable\r
+ buffer.append("\tReal DL;\n");\r
+ // (possibly) continuous delay time\r
+ buffer.append("\tReal " + DELAY_TIME + ";\n");\r
+ // (possibly) continuous initial value\r
+ buffer.append("\tReal " + DELAY_INITIAL + ";\n");\r
+\r
+ // first valve\r
+ buffer.append("\tReal " + getDelayValve(0) + ";\n");\r
+\r
+ // stocks and valves, valves are delayed values of the variable\r
+ for (int i = 1; i <= order; i++) {\r
+ buffer.append("\tReal LV"+i + "(fixed=false);\n");\r
+ buffer.append("\tReal "+ getDelayValve(i) + ";\n");\r
+ }\r
+\r
+ // initial equation block\r
+ buffer.append("initial equation\n");\r
+\r
+ // Each stock gets the same initial value\r
+ for (int i = 1; i <= order; i++) {\r
+ buffer.append("\tLV"+i + " = DL * " + DELAY_INITIAL + ";\n");\r
+ }\r
+\r
+ // equation block\r
+ buffer.append("equation\n");\r
+ \r
+ buffer.append("\tDL = " + DELAY_TIME + " / "+order+";\n");\r
+\r
+ // valves and stocks\r
+ for (int i = 1; i <= order; i++) {\r
+ buffer.append("\tder(LV"+i + ") = - " + getDelayValve(i) + " + " + getDelayValve(i-1) + ";\n");\r
+ buffer.append("\t"+ getDelayValve(i) + " = LV"+i + " / DL;\n");\r
+ }\r
+\r
+ buffer.append("end ");\r
+ buffer.append(getDelayName(order));\r
+ buffer.append(";\n");\r
+\r
+ return buffer.toString();\r
+ }\r
+\r
+ public static String getDelayName(int order) {\r
+ return "order_"+order+"_delay";\r
+ }\r
+ \r
+ public static String getDelayValve(int order) {\r
+ return "delay"+order;\r
+ }\r
\r
}\r