For a simple model in Dymola, the Start attribute works to provide initial conditions for the DOE equations, like the following examples.
model QuiescentModelUsingStart "Find steady-state solutions to LotkaVolterra equations"
parameter Real alpha=0.1 "Reproduction rate of prey";
parameter Real beta=0.02 "Mortality rate of predator per prey";
parameter Real gamma=0.4 "Mortality rate of predator";
parameter Real delta=0.02 "Reproduction rate of predator per prey";
Real x(start=10) "Prey population";
Real y(start=10) "Predator population";
initial equation
der(x) = 0;
der(y) = 0;
equation
der(x) = x*(alpha-beta*y);
der(y) = y*(delta*x-gamma);
end QuiescentModelUsingStart;
But for the complicated model like a power plant model, which is a strong nonlinear model, it is a lot more complicated.
Based on the Modelica by example(https://mbe.modelica.university/behavior/equations/variables/), the start attribute may also be used as an initial guess if the variable has been chosen as an iteration variable.
So, what is the process of initializing a model in Dymola? Would Dymola take the "equation" part into consideration during initialization, and set the derivate as zero, so it could Find the Steady-State as Initial Conditions?
Or Dymola just uses the "start attributes" and "initial equation" part to get a group of initial values?
How should I ensure that the initialization values I use could make up a steady-state?
Probably an excerpt from the Modelica Language Specification describes what you are looking for:
Before any operation is carried out with a Modelica model [e.g., simulation or linearization], initialization takes place to assign consistent values for all variables present in the model. During this phase, also the derivatives, der(..), and the pre-variables, pre(..), are interpreted as unknown algebraic variables. The initialization uses all equations and algorithms that are utilized in the intended operation [such as simulation or linearization].
This is the first part of Section 8.6, which is about three pages and should give you a pretty good insight on what happens during initialization. It also discusses the start attribute with fixed=true/false.
Related
I want to adjust the mass flow rate of a pump by using similarities laws so if I want to head and flow rate equation. I need to use old value and new value of head so that I can calculate new value of mass flow rate.
Can anybody tell me how can I write this in program in OpenModellica.
Generally Modelica is not designed to access "old values" of a continuous variable, as this is usually not necessary to model physical behavior. For discrete events there is the pre() operator, for clocks previous() but none of them is useful in continuous modeling.
What is common in continuous modeling, is to have relations based on the derivative der() of a variable, but not "old values". Personally I would double-check if you really need an old value or if that is just a form of abstraction chosen due to limitations of other software...
Still you can use the delay() operator as shown below to delay a signal by a fixed or a variable amount of time.
model DelayExample
Real x, y_fix, y_var;
equation
x = time;
y_fix = delay(x, 100e-3);
y_var = delay(x, min(time/2,0.2), 0.2);
end DelayExample;
The result is the following:
If you want to do use graphical modeling, you can use blocks from Modelica.Blocks.Nonlinear, namely
Modelica.Blocks.Nonlinear.FixedDelay
Modelica.Blocks.Nonlinear.PadeDelay
Modelica.Blocks.Nonlinear.VariableDelay
Modelica modeling is the first principle modeling, so how to test the model and set an effective benchmark is important, for example, I could design a fluid network as my wish, but when building a dynamic simulation model, I need to know the detailed geometry structure and parameters to set up every piece of my model. Usually, I would build a steady-state model with simple energy and mass conservation laws, then design every piece of equipment based on the corresponding design manual, but when I put every dynamic component together, when simulation till steady-state, the result is different from the steady-state model more or less. So I was wondering if I should modify my workflow to make the dynamic model agree with the steady-state model. Any suggestions are welcome.
#dymola #modelica
To my understanding of the question, your parameter values are fixed and physically known. I would attempt the following approach as a heuristic to identify the (few) component(s) that one needs to carefully investigate in order to understand how they influence or violates the assumed first principles.
This is just as a first trial and it could be subject to further improvement and fine-tuning.
Consider the set of significant set of variables xd(p,t) \in R^n and parameters p. Note that p also includes significant start values. p in R^m includes only the set of additional parameters not available in the steady state model.
Denote the corresponding variables of the steady state model by x_s
Denote a time point where the dynamic model is "numerically" in "semi-" steady-state by t*
Consider the function C(xd(p,t*),xs) = ||D||^2 with D = xd(p,t*) - xs
It could be beneficial to describe C as a vector rather than a single valued function.
Compute the partial derivatives of C w.t. p expressed in terms of dxd/dp, i.e.
dC/dp = d[D^T D]/dp
= d[(x_d-x_s)^T (x_d - x_s)]/dp
= (dx_d/dp)^T D + ...
Consider scaling the above function, i.e. dC/dp * p/C (avoid expected numerical issues via some epsilon-tricks)
Here you get a ranking of most significant parameters which are causing the apparent differences. The hopefully few number of components including these parameters could be the ones causing such violation.
If this still does not help, may be due to expected high correlation among parameters, I would go further and consider a dummy parameter identification problem, out of which a more rigorous ranking of significant model parameters can be obtained.
If the Modelica language had capabilities for expressing dynamic parameter sensitivities, all the above computation can be easily carried out as a single Modelica model (with a slightly modified formulation).
For instance, if we had something like der(x,p) corresponding to dx/dp, one could simply state
dcdp = der(C,p)
An alternative approach is proposed via the DerXP library
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.
I have a battery model in Modelica. PNet is the value of power flowing through battery (PNet is positive for charging and negative for discharging). This oscillates based on a load. I want to calculate the number of cycles that the battery is put through and also the depth of discharge comin in from each of these cycles.
This is a pretty generic question so my answer will be rather generic as well. Also it is not clear to me, what you are referring to as a cycle. Wikipedia mentions deep and shallow discharge and there are some others as well.
Some general note: In Modelica the when statement is useful for counting. You can read through Section 8.3.5 of the Modelica Language Specification to get full information on this.
The below examples computes how often the variable PNet turns positive, which should respond to the number of shallow cycles above. Some description for the model:
The model noiseSource computes a random number which is then filtered by a first order (PT1) element to compute PNet. The filter should likely be skipped in the original example, it is only there to smooth the trajectory a bit.
The code in the when statement is executed once at the time when the condition turns true, which enables the counting.
The pre statement accesses the value of cycles right before the when statement got active, which enables counting how often the condition occurred.
The start=0 in cycles(start=0) sets the starting value for the variable cycles, which is necessary as you cannot use cycles = 0 as this would generate an equation for cycles, which is not what you want.
The inner model globalSeed is necessary for the noiseSource to work.
Here is the actual code:
model CycleCounter
inner Modelica.Blocks.Noise.GlobalSeed globalSeed;
Modelica.Blocks.Noise.NormalNoise noiseSource;
parameter Modelica.SIunits.Time T = 1e-3 "Time constant of PT1 element to filter random signal to compute PNet";
Integer cycles(start=0) "Counts the number of ";
Real PNet "Random value";
equation
der(PNet) = (noiseSource.y - PNet)/T;
when PNet > 0 then
cycles = pre(cycles)+1;
end when;
annotation (uses(Modelica(version="3.2.3")));
end CycleCounter;
And the result from simulating in Dymola:
I've had to create the Simulink Diagram after this picture:
My answer is this one:
I've gave some values to a, b and c (like 3, 4 and 5), but when I try to run it, it gives me the following warning:
Warning: The model 'ex2_2' does not have continuous states, hence Simulink is using the
solver 'VariableStepDiscrete' instead of solver 'ode45'. You can disable this diagnostic by
explicitly specifying a discrete solver in the solver tab of the Configuration Parameters
dialog, or by setting the 'Automatic solver parameter selection' diagnostic to 'none' in the
Diagnostics tab of the Configuration Parameters dialog
Warning: 'ex2_2/Unit Delay' is discrete, yet is inheriting a continuous sample time; consider
replacing unit delay with a memory block. When a unit delay block inherits continuous sample
time, its behavior is the same as the memory block. Unit delay block's time delay will not be
fixed and could change with each time step. This might be unexpected behavior. Normally, a
unit delay block uses discrete sample time. You can disable this diagnostic by setting the
'Discrete used as continuous' diagnostic to 'none' in the Sample Time group on the
Diagnostics pane of the Configuration Parameters dialog box. "
and the output (scope) it's just a step signal...
I don't know where I'm wrong here.
You've built the model correctly, but did not configure it correctly.
When running the model as-is, what will happen is the following:
The Step block is a continuous-time source by default (it's Sample Time setting is 0).
Simulink sees that the Step is connected to the Unit delay block, which is guaranteed to have constant output during minor steps (unlike Memory blocks)
According to the documentation on sample times:
[...] Simulink sets [Fixed-in-Minor step] as either an inherited sample time or as an alteration to a user specification of 0 (continuous). This setting is equivalent to, and therefore converted to, the fastest discrete rate when you use a fixed-step solver.
Continuous sample time degrades to Fixed-in-Minor-Step rather than Discrete-time in the context of Variable-step solvers. Variable step size is used to speed up simulations (larger steps are taken when accuracy allows it), but requires trickery to compute, for example, the exact time at which the step triggers (the "Enable zero-crossing detection" tick box in the Step block's options). So, Simulink's best way forward in this particular situation is to convert the sample time of the Step block into Fixed-in-Minor-Step, which is propagated forward and inherited by all other blocks in the model.
This is usually an awkward type of sample time, which is effectively not continuous-time, but still seen by all blocks as such. Therefore, the inherently discrete-time Unit delay will complain about being driven by a continuous-time signal (your 2nd warning), and Simulink itself will complain about the complete lack of "real" continuous-time blocks anywhere, while being instructed to use a continuous-time solver, ode45 (your 1st warning).
As usual in software development: it's always best to be explicit, about everything. In this case, the simplest way out of this is to explicitly specify a discrete-time, fixed-step solver in the model configuration dialog. That way, the continuous-time from the step will be automatically converted into discrete-time for the Unit delay.
The block diagram you want to implement is a discrete-time system. Since there are no Ordinary Differential Equations (ODE) but only their discrete counterpart (Finite-differences equations), you do not need an ODE solver as the warning 1 points out.
In discrete-time systems you have to specify your sample time in order to approach to a continuous-time representation where every single instant t is built up by the discrete integer n and its progressions (n+1, n+2, and so on) as t = nT where T is your sample time; Simulink basically expects that you respect this kind of logic, then asks for a sample time. By default Simulink sets it variable which may lead the result "out of track". This is what the warning 2 points out.
Solution: In the 'Model Configuration Parameters' menu, at the Solver tab, set 'Fixed-Step' as Type. The pane will change with a field related to the sample-time (Fixed-step size); set then a Sample time in seconds different than "auto" (e.g. 0.01). This will solve the warning 2. Still in the Solver menu, set also 'Discrete (no continuous states)' instead of any other useless solver. This will solve the warning 1.