Reputation: 1084
I work with finding a good way to divide code in two parts: a general library and and application code, The examples I work with usually contain liquids and I want to make the general library independent of the number of components in the liquid. The idea is that the application code set the liquid medium used and then import equipment from the general library and adapt these equipment to the actual medium.
The example below is a very concise example that illustrate one way to do this division of code. Here I let value nc of number of components be undefined in the partial package MediumBase. Later when the EquipmentLib is adapted to the actual Medium then nc get a value. This is what I mean with “delay” setting of structural parameter. The code works well in both JModelica and OpenModelica.
package DEMO_v30
// Author: Jan Peter Axelsson
// ---------------------------------------------------------------------------------------------
// Interfaces
// ---------------------------------------------------------------------------------------------
import Modelica.Blocks.Interfaces.RealInput;
import Modelica.Blocks.Interfaces.RealOutput;
partial package MediumBase
constant Integer nc "Number of components";
replaceable type Concentration = Real[nc] "Component conc";
end MediumBase;
package Medium3
extends MediumBase (nc=3);
end Medium3;
// ---------------------------------------------------------------------------------------------
// Equipment dependent on the medium
// ---------------------------------------------------------------------------------------------
package EquipmentLib
replaceable package Medium = MediumBase // formal parameter - EquipmentLib
constrainedby MediumBase;
model ReactorType
parameter Medium.Concentration c_0 = ones(Medium.nc) "Initial component conc";
Medium.Concentration c (start=c_0, each fixed=true) "Component conc";
equation
for i in 1:Medium.nc loop
der(c[i]) = -c[i];
end for;
end ReactorType;
end EquipmentLib;
// ---------------------------------------------------------------------------------------------
// Adaptation of package Equipment to Medium3
// ---------------------------------------------------------------------------------------------
package Equipment
import DEMO_v30.EquipmentLib;
extends EquipmentLib(redeclare package Medium=Medium3);
end Equipment;
// ---------------------------------------------------------------------------------------------
// Examples of systems
// ---------------------------------------------------------------------------------------------
model Test
Equipment.ReactorType reactor;
end Test;
end DEMO_v30;
In slightly larger examples with the same code structure I get some problems though:
The message does not make sense to me since nc is known at compile time, at the level of where EquipmentLib is adapted. This problem can actually be resolved by givning nc in MediumBase a “dummy” value nc=1 in Medium Base, and then that nc get changed during compilation to the value provided when EquipmentLib is adapted.
So my questions are:
If needed I can provide the larger example, but I think that here might be a more general answer.
Upvotes: 2
Views: 199
Reputation: 1084
I have now got confirmed that my posted code is indeed sound and for a partial package (or model) you can define variables that has no values or vectors with undetermined size, provided they at compilation time are completely defined. The more complex code with similar structure that gave problem I mentioned, is now also solved. The code works on both JModelica 2.14 and OpenModelica 1.16 nightly build ...b48. Interestingly the code does not work on version 1.15 or earlier. Thanks to my contact at Modelon, Markus Olsson!
Upvotes: 0
Reputation: 697
1) In theory i understand what you mean, but the modelica language standard requires every model (besides connectors and partial models) to be valid on their own. This seems to not be relevant for your case since you defined a partial package, the problem here is that you defined an array in the same scope that structurally depends on this variable. Therefore i would strongly recommend to provide a default value that can be checked for.
2) I actually cannot reproduce the problem. With OpenModelica everything runs fine even for nc=10000
. Slow but it works (We are working on making array/vector stuff faster in the future). I am working with the nightly build (OpenModelica 1.16.0~dev-102-g5c1a023).
3) See 1). Generally i can just add that you should use the Check Model (Single check mark on green circle top middle) on very component individually to check if everything you do is modelica language conform. You can also use the instantiate button right next to it to look at the flat model that will be generated from your code.
Furthermore i would recommend using the compilation flag -d=newInst
(providing you work on one of the newer versions). That uses the new instantiation which is stricter on modelica specification and far more efficient.
Upvotes: 0