I am attempting to define the parameter of a model (block) as a variable. For example:
Real WallThickness = 0.5;
Real WallConductance = 10*WallThickness;
Modelica.Thermal.HeatTransfer.Components.ThermalConductor TopPanelConductor(G=WallConductance);
I would like to define "G" so that it remains constant throughout the simulation but the coefficient is updated prior to the simulation based on the other variable "WallThickness". When defining the ThermalConductor parameter "G" as a variable in the model, which is being calculated elsewhere, I get the error message:
The variability of the definition equation:
TopPanelConductor.G = WallConductance;
is higher than the declared variability of the variables.
I would like to define the parameters of a model as a variable. This allows me to create parametric definitions as the geometry of the all changes. Is there a way I can make this definition work?
You mean the geometry changes during simulation? If so, you'll have to rewrite the ThermalConductor model to work with a variable G, because a variable cannot be assigned to a parameter. A variable may vary during the course of simulation. A parameter is fixed at the start of simulation, but can be changed from run to run without recompiling the model, which allows for quicker iteration/design work.
Note that you can also calculate a parameter from other parameters that you define, e.g. to calculate a heat transfer coefficient from a given wall thickness (which you vary from simulation run to simulation run).
An alternative to re-writing the component models is to make the parameter study/variation outside the simulation model. There are at least three approaches:
Export your system model as an FMU (Co-simulation). Import it in Python w. PyFmi and write for loops that vary the parameter value for each iteration. See for example http://www.jmodelica.org/assimulo_home/pyfmi_1.0/pyfmi.examples.html. This is not as complicated as it might sound.
Make the parameter variation loop in a Modelica Script (mos file). I don't have much experience with this though.
If you are varying geometrical parameters in order to find an optimum of some kind you can use the Optimization Library which is shipped with Dymola (as of version 2017 FD01).
Using one of the above suggestions you can reuse all the components from MSL out of the box.
Best regards,
Rene Just Nielsen
There is a heirachery for varaibales/parameters that restrict their use. As you are now aware, parameters are not permitted to vary with within the simulations. Thus, you get the error stating that you are trying to define a parameter with a variable value or input variable.
If you need that functionality I would recommend duplicating the ThermalConductor and change the variable type:
parameter Modelica.SIunits.ThermalConductance G
"Constant thermal conductance of material";
to
input Modelica.SIunits.ThermalConductance G
"Constant thermal conductance of material" annotation (Dialog(group=”Input Variables”));
That all there is to it. Note the additional annotation on the input variable. By default inputs do not show up in the parameter GUI. The annotation will permit them to be seen just like parameters (be careful to clearly label it an input variable versus a parameter though!)
There is work underway that has completely redone the Thermal library but is not yet released and the most-straightforward approach would probably try what I have discussed.
Related
I am building a circuit model for a transformer which models the effects of hysteresis. It does so using the Matlab function block on the right, and works successfully when tested in isolation. However, the value of the magnetising inductance Lm depends on calculations requiring the value of Im. But Simulink cannot determine the value of Im without the value of Lm, thus forming an algebraic loop.
However, I have the initial value for the inductance, Lm_initial loaded into the workspace. With this, I should be able to solve for the first Im value, which can be used to determine the next Lm, and so on. However, specifying Lm_initial in the variable inductor's properties doesn't work; Simulink tries to evaluate Lm with the nonexistent 'phi' and 'Im' values rather than trying to solve for an initial Im using the value of the initial inductance.
I have tried solutions involving commenting/uncommenting blocks and implementing further subsystems which activate/deactivate depending on the time step, as well as unit delays, but these run into issues regarding tracking time for calculating the derivatives or output very incorrect/noisy waveforms.
Is there a relatively simple solution for this case? The problem appears as if it'd be relatively simple to solve, but I cannot seem to find a workaround for this.
Transformer Equivalent Model
The exact placement of the unit delay in the loop might be the key here: try to place the unit delay between the [lm] GoTo block and the lm input of your MATLAB function block fcn, that should work. And set the initial condition parameter to Lm_initial.
I would like to apply a cluster algorithm to my data frame, however I have some nominal scaled variables. Consequently, I would like to apply one-hot encoding so that I can also use, for example, k-means clustering. I'm aware, that there are also other and maybe also better algorithms than k-means, however I want to start with this and use the results as benchmark.
There are several possibilities, e.g. the packages Caret and Recipes offer functions for this. However, these require the definition of a target variable, which then no longer appears in the data frame. Although I theoretically have a target variable in my data set, I would rather keep it as a predictor and overweight it, so that the different clusters contain only one instance of the target variable. Consequently, I need to select another variable and specify it as the target variable in the formula interface.
I would therefore like to ask whether it then doesn't matter which variable one takes for this or whether I actually have to take my actual target variable and can still weight it somehow afterwards.
I've also seen a method there no target variable is defined in the formula interface. Is this a recommandable approach or is it preferred to define a target variable?
I would be very happy about an answer!
Many greetings and thanks in advance!
I am building model in Dymola. I have defined the mass of this model as a parameter, because it would be transfered into other moduls and called in them. But the mass should be changing during the simulation in different time intervals. For example, during the first 100 seconds the mass should remain 500kg, and during 100 to 200 sec, a passenger is going to get in, so that a new mass should be calculated including the mass of the passenger. But it has been showed, that "The problem is structurally singular", because to the parameter values have been twice assigned. Could someone give some tips to solve this problem? Thanks a lot.
If you define the mass of your component as an input rather than a parameter then you can change it during simulation by assigning e.g. the output from a TimeTable to it. For example
model Component
input Modelica.SIunits.Mass mass "Passenger dependent mass";
equation
...
end Component;
model systemModel
TimeTable timeTable;
Component component(mass=timeTable.y);
OtherComponent otherComponent(mass=component.mass);
equation
...
end systemModel;
Note that the other components using the mass must also have their internal mass 'parameters' defined as input to allow higher variability than parameters.
Best regards
Rene Just Nielsen
Modelica parameters are defined by the fact, that they don't change over time. Therefore you would need to stop the simulation, change the parameter and restart the simulation (see another question). Given you description I would rather not use this possibility, as it seems your variable is designed to change over time.
A better alternative seems to be defining the mass as a variable. If this is done, you can:
Transfer this variable from one model to the others using interfaces. This could be a bit tedious depending on the amount of classes using the variable.
Use inner/outer (basically global variables) is a feasible concept for this use-case. This concept is used in the MultiBody libraries world model.
With both solutions you will have to modify the original mass model, as m would then have to be a variable instead of a mass.
My initial problem is that I have a continuous transfer function which coefficients change with time.
Currently the TF's coefficients are expressed in function of the block mask parameters. These parameters are tunable, and if I change the value in the mask parameters dialog during a simulation the response seems to react appropriately.
However how can I do just that in the code/block flow? Basically, I
have the block parameter 'maskParam' which is set using the mask
parameters dialog, and in the mask initialization commands:
'param=maskParam'. 'param' is used in the transfer function and I
would like to change it in real time (as param=maskParam*f(t)).
I have already looked around and found relevant solutions but either it's unbelievably complicated; or the only transfer function which we are allowed to modify at runtime is discrete and 1) I would like to avoid z-transforming my quite complex TF (I don't have the control toolbox) 2) The sampling time seems to be fixed.. None uses this "dirty" technique of updating parameters, maybe that's the way around?
To illustrate:
I am assuming that you want to change your sim parameters whilst the simulation is running?
A solution is that you run your simulation for inf period and use/change a workspace variable during the simulation period to make the changes take effect.
for Example:
If you look at the w block, you can set it's value in runtime, by doing this:
set_param('my_model_name/w', 'value', 100); % Will change to 100 immediately
You can do similar things with arrays (i.e. a list of coefficients in your case).
HINT FOR YOU
You are using discrete transfer function block. Try the following:
1) Give your block a name e.g. fcn_1
2) In your script, type set_param('your_model_name/fcn_1', 'numerator', '[1 2]'); This will set the numerator value to [1 2]. Do the same for denominator.
3) You should be able to understand, through this exercise, how to handle the property names etc. so that you can change/get them using set_param/get_param.
I leave you to investigate further.
The short answer is that Simulink blocks are not really designed to do this. By definition, a transfer function is Liner-Time Invariant, meaning its characteristics (read coefficients) do not vary with time.
Having said that, there are some workarounds, such as the ones you mentioned in your question. These are the correct way to approach the problem I'm afraid, other than the set_param method suggested by #ha9u63ar. See also this blog on the subject on the MathWorks web site.
I often have function such as:
sin(a*w*t + p)
where:
w = natural frequency
t = time
a,p = parameters (which I can vary)
As you can see if you want to vary a,p, you can do so via the standard interface but it's not very convenient. So I thought I'd look for a GUI which has a slider for each parameter. Does such a thing exist?
I've never seen one so I thought I'd quickly write one. However, I'm worried that due to lack of time and knowledge of matlab I will cause problems such as generating too many plot commands when the slider is moved instead of just one. Of course I also have the problem that I want to specify a field where the user can specify the function e.g. by typing sin(a*w*t +p) in a text field and then specify what each variable means which I currently don't know how to do (it looks like a parsing task). Can I do this or should I go with a predefined set of functions?
You can find similar projects in Matlab File Exchange as example.
For instance:
Integral Tool
Function Parameter Slider
I didn't have a look at the code but according to the screenshots, it should help you.
Regarding the function input feature, you can use the function eval (with a few checks on the input if you need reliability). If you want to allow any parametric variable, it may be harder.