I would like to place a "System" component in my simulation (similar to Modelica.Fluid.System and Modelica.Mechanics.MultiBody.World) from which all other components can access the Medium package, in order to set the working fluid only once for the entire flowsheet. My System is defined as follows:
model System annotation(defaultAttributes="inner");
replaceable package Medium = Modelica.Media.Interfaces.PartialMedium
annotation(choicesAllMatching=true);
parameter Modelica.SIunits.Temperature T_amb=293.15;
// ...
equation
// empty
end System;
I have referenced the System in other components using outer System system;, and I can thus access all variables/parameters contained therein, e.g. system.T_amb. However, trying to pull the Medium package like this does not work:
model MixingVolume
outer System system;
package Medium = system.Medium;
// ...
equation
// ...
end MixingVolume;
I get a message saying the base class "system.Medium" is missing. (This is re-translated from an extremely poor German translation within CATIA V6's Modelica environment that I am doomed to use - perhaps the original message would have been more informative.) What am I doing wrong? I am puzzled because this...
model MixingVolume
outer System system;
Constant Integer nXi = system.Medium.nXi; // number of independent mass fractions
// ...
equation
// ...
end MixingVolume;
...works fine, so MixingVolume does see the system.Medium component. Any clues? Many thanks for any help.
You cannot access packages inside components via dot notation.
If the first name is a component reference after dot only a component
reference or a function can follow. Read the Modelica Specification:
https://www.modelica.org/documents/ModelicaSpec32Revision2.pdf.
It could be a bug in the tool if system.Medium.nXi is allowed.
Related
I’m quite noob in Modelica language and I’d appreciate any help about this simple issue. I’d like to know if it’s possible to write variables name (that depends on a submodel) as a function of other variable in order to shorten the general code. Here there is an example about what I’d like to do.
I’m considering a top-level model that includes three identical submodels (OpenTank) of the Standard Modelica Library (tank1,tank2 and tank3). I’d like to know if it’s possible to call the variable (“level”) inside the submodels from the top-level model using a loop like this way (example code is attached) or something similar instead of repeating the code three times (I’m really interested in setting this operation in the top-level model)
What would you advise me to do? Thanks in advance!
model threeTanks
Modelica.Fluid.Vessels.OpenTank tank1;
Modelica.Fluid.Vessels.OpenTank tank2;
Modelica.Fluid.Vessels.OpenTank tank3;
equation
for i in 1:3 loop
tank(i).level= /* … */;
end for;
end threeTanks;
You would need a component iterator, which is proposed in Modelica Change Proposal MCP-0021 Component Iterators. But it is not available yet and nothing has changed since 2016 if I read it correct, so don't expect to get that soon.
With the current Modelica language version (specified in Modelica Language Specification 3.5), you must use literal names when you refer to components.
(In Modelica, there is nothing like eval which you might know from other languages.)
So either go for Rene Just Nielsens solution and use vectorized tanks.
This works, but in the graphical view you will have only one tank. The parameter window will then accept vectors and the tank connectors will be vectorized as well.
If you don't want that, you can also instantiate your tanks as you did and manually specify the component names over which you want to iterate:
for item in {tank1, tank2, tank3} loop
item.level= /* … */;
end for;
The question is also what you want to achieve. The tank already has equations to compute the level, so it's unlikely that you want to set it.
Maybe you want to gather all levels at top in one variable. You could do that by adding this line:
Modelica.Units.SI.Length levels[3] = {item.level for item in {tank1, tank2, tank3}};
Similar to the answer to the post (Modelica - Is it possible to set name of a variable as the value of another variable?) you can declare an array of components like this:
model threeTanks
Modelica.Fluid.Vessels.OpenTank[3] tank;
equation
for i in 1:3 loop
tank[i].level= /* … */;
end for;
end threeTanks;
I'm making the interface package which can input the parameters of the models in the simulation loop.
To connect between the interface package and the simulation model, I used the Controlbus from the Standard Modelica Library Ver. 3.2.2.
Checking model was Okay, but if i simulate the model, the error like the picture below popped up.
And here's the equation related to this model
Omega_e = Omega_d * N_t[N];
Alpha_d = der(Omega_d);
To solve the differential equation, i think the solver need a specific parameter of N_t.
So i put the parameters from the interface model and sent the parameters using the Controlbus component in the Standard Modelica Library.
As in the picture above, i definitely put the parameters.
(Specific values of the parameters are deleted because it's a confidential)
I can't find what is the problem of this error.
Please help me guys.
Thank you very much.
Based on the incomplete model it's a bit tricky to say what happened, but:
Sending parameters through the control-bus (or a connector in general) is a bit complicated and not that encouraged.
It should be possible by declaring the "computed parameter" as parameter Integer N(fixed=false); initial equation N=myBus.N;, and don't have it as parameter in the connector.
If you don't declare it as parameter Dymola will try (and fail) to differentiate it.
If you declare it as parameter in the connector it will not be propagated (as connecting two parameters lead to an assertion).
I am using Thermal Power Library from Modelon. There is a condenser component in the Thermal Power Library which is used for the modeling of power plants.
The default heat transfer area for the wall_2 in the condenser component is 0.8*A_heat_tot, the variable of A_heat_tot is an inner variable in the condenser component, but when I try to use this variable, there is an error showing that this variable isn’t defined.
My question is that If I can use the inner variable directly. If not, how should I use it?
Short answer: You need to address the variable with its full path, i.e. wall_2.A_heat_tot.
A_heat_tot is define in StandardWall and can thus be referred to directly inside the class. However, when you are making changes to A_heat from outside the instance of StandardWall (i.e. outside wall_2) you must point to the origin of A_heat_tot since it is otherwise not known in the scope from which you are trying to use it.
Likewise, if you are making the modification in you simulation model (Preheater_Model_Validation2) you must use the full path, i.e. hex.wall_2.A_heat = hex.A_heat_tot
By the way, this has nothing to do with the inner qualifier in the Modelica language.
I'm porting a large Simulink model from Simulink R2010a → R2017b.
The main model is basically a glue-layer for many interwoven reference models. My objective is to generate a standalone executable out of this main model using Coder.
Parameter tunability in this context is not done via the Signals and Parameters section on the Optimization tab in the Model Configuration Parameters dialog (as is the case in stand-alone models), but rather, via constructing Simulink.Parameter objects in the base workspace, and referencing those in the respective referenced models, or in their respective model workspaces.
Now, AFAIK, in R2010a it was enough to set
new_parameter.RTWInfo.StorageClass = 'Auto';
new_parameter.RTWInfo.CustomStorageClass = 'Define';
to make the parameter non-tunable and convert it into a #define in the generated code. In R2017b, this is no longer allowed; the StorageClass must be 'Custom' if you set a non-empty CustomStorageClass:
new_parameter.CoderInfo.StorageClass = 'Custom'; % <- can't be 'Auto'
new_parameter.CoderInfo.CustomStorageClass = 'Define';
But apparently, this does not make the parameter non-tunable:
Warning: Parameter 'OutPortSampleTime' of '[...]/Rate Transition1' is non-tunable but refers to tunable variables (Simulation_compiletimeConstant (base workspace))
I can't find anything in the R2017b documentation on making parameters non-tunable, programatically; I can only find how to do it in stand-alone models via the dialog, but that's not what I want here.
Can anyone point me in the right direction?
NOTE: Back in the day, Simulink Coder was called Real-Time Workshop (well, Real-time Workshop split into Coder and several other things), hence the difference RTWInfo vs. CoderInfo. Note that RTWInfo still works in R2017b, but issues a warning and gets converted into Coderinfo automatically.
In generated code it should appear as #define, the way you specified it.
https://www.mathworks.com/help/rtw/ug/choose-a-built-in-storage-class-for-controlling-data-representation-in-the-generated-code.html
Btw, yes, it's a bit confusing, because in m-file you specify CustomStorageClass = 'Define';, in GUI you specify Storage class as Define (custom), but in documentation they say Storage Class as Defined.
I am not sure why warning about tunability shows up.
I am using some components from the Modelica Standard Library (MSL) in my simulations. These components each have some parameters. For example, Modelica.Fluid.Sources.MassFlowSource_T has a parameter m_flow. Usually, parameters can be changed between simulation runs without re-compilation. This is not the case for m_flow, because it has an annotation(Evaluate=true), so it is used for symbolic processing.
Is it possible to change the annotations of parameters at instantiation? I tried the following, but it didn't work.
Modelica.Fluid.Sources.MassFlowSource_T source2(
redeclare package Medium = Medium2,
nPorts=1,
m_flow=22.17 annotation(Evaluate=false));
Of course there are workarounds, like making a copy first and changing the annotation there or using use_m_flow_in=true and a constant source block.
As far as I know this is not possible with current Modelica Specification.
Some tools might support it if you extend MassFlowSource_T:
model MassFlowSource_T_2
extends Modelica.Fluid.Sources.MassFlowSource_T;
// declare m_flow here again with annotation(Evaluate=false);
end MassFlowSource_T_2;
use MassFlowSource_T_2 when you declare source2.
There is some work in progress to extend the way annotations are specified/handled
but it will be a while until it makes it into the Modelica Specification:
https://trac.modelica.org/Modelica/ticket/1293 (not open to the public yet).