- Index
- » Programming
- » Modelica Language
- » Cumulative of time variables
Cumulative of time variables
Cumulative of time variables
I am new to modelica so apologies if this is a simple request. I am manipulating a series of y values derived from a time table and need to plot the value of their total as well as the values themselves. How can I create this cumulative value that corresponds to the time interval?
For example if I have a series of values 1,3,5,2,7 how can I generate their cumulative values 1,4,9,11,18?
Many thanks
Re: Cumulative of time variables
Remember that variables in Modelica are generally continuous. So, they have to have a value between the points you listed below. One way to do something similar to what you want is to just add an integrator. But, then the range between the values will matter to the output. So, make sure that it does what you want. If you just use timeTable it uses a linear fit between each point. An option is then to sample every time period of interest, for example every second, and then integrate that value. Here is a quick example with those two different methods:
Code:
model IntegrateTest
Modelica.Blocks.Continuous.Integrator integrator1 annotation(Placement(visible = true, transformation(origin = {4, 24}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Blocks.Sources.TimeTable timeTable1(table = [0, 1; 1, 3; 2, 5; 3, 2; 4, 7; 5, 0; 8, 0]) annotation(Placement(visible = true, transformation(origin = {-46, 26}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Blocks.Discrete.Sampler sampler1(samplePeriod = 1) annotation(Placement(visible = true, transformation(origin = {-18, -18}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Blocks.Continuous.Integrator integrator2 annotation(Placement(visible = true, transformation(origin = {30, -20}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
equation
connect(timeTable1.y, sampler1.u) annotation(Line(points = {{-35, 26}, {-32, 26}, {-32, -8}, {-48, -8}, {-48, -18}, {-30, -18}, {-30, -18}}, color = {0, 0, 127}));
connect(timeTable1.y, integrator1.u) annotation(Line(points = {{-35, 26}, {-20, 26}, {-20, 24}, {-10, 24}}, color = {0, 0, 127}));
connect(sampler1.y, integrator2.u) annotation(Line(points = {{-7, -18}, {6, -18}, {6, -20}, {18, -20}, {18, -20}}, color = {0, 0, 127}));
annotation(Icon(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {2, 2})), Diagram(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {2, 2})));
end IntegrateTest;
- dersh
- 66 Posts
Re: Cumulative of time variables
Many thanks for this - the only issue I am now facing is that the integral always plots from 0. Is there any way I can get it to start from the first value in the table. Otherwise it is not truly cumulative.
I appreciate your help.
Re: Cumulative of time variables
You can just set y_start of the integrator to the value that you want to start with.
- dersh
- 66 Posts
Re: Cumulative of time variables
Hi.Thanks again and sorry to be a pain. I understand how y_start works with a fixed value but can I use the first time dependent variable value? It will vary so I cannot give it a value but I cannot work out the syntax to specify the input value at time =1.
For example if I have 10 samples u(time=1), u(time=2),.......u(time=10) I want to end up with u(time=1 + u(time=2)+........u(time=10)
Hope that makes sense. Again - any help appreciated.
thanks
Re: Cumulative of time variables
First off, remember that the data is considered essentially continuous. That means that at time 1.5 it has to have a value. It seems that you are trying to care about the data at each transition. That said, my suggestion above seems to do what you want, but does it with a 1 second lag. So, one option would be to move your data 1 second "earlier" and then you would get your expected results.
- dersh
- 66 Posts
Re: Cumulative of time variables
Hi yes. I hear what you are saying. Basically I have a series on monthly production figures which are definitive for that month. Naturally there has to be a transition at say month 3.5 between month 3 and 4. The problem is that the cumulative value at end of month 1 is less than the value for the month itself. The attached plot illustrates the monthly values in blue and the total in red. Doesnt make sense over the early part of the timescale but probably don to the integration itself. Moving the origin is not going to help as we have to start from 0 in month 0. Any ideas?
Re: Cumulative of time variables
I think that this version should do what you seem to want. Take a look at the output of timeTable1 versus the output of sumChange1:
Code:
model IntegrateTest
Modelica.Blocks.Continuous.Integrator integrator1 annotation(Placement(visible = true, transformation(origin = {4, 24}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Blocks.Sources.TimeTable timeTable1(table = [0, 1; 1, 3; 2, 5; 3, 2; 4, 7; 5, 0; 8, 0]) annotation(Placement(visible = true, transformation(origin = {-46, 26}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Blocks.Discrete.Sampler sampler1(samplePeriod = 1) annotation(Placement(visible = true, transformation(origin = {-18, -18}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Blocks.Continuous.Integrator integrator2 annotation(Placement(visible = true, transformation(origin = {30, -20}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
model SumChange
extends Modelica.Blocks.Interfaces.SISO;
equation
when {not u == pre(u), initial()} then
y = pre(y) + u;
end when;
annotation(Icon(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {2, 2})), Diagram(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {2, 2})));
end SumChange;
SumChange sumChange1 annotation(Placement(visible = true, transformation(origin = {4, -54}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
equation
connect(sampler1.y, sumChange1.u) annotation(Line(points = {{-7, -18}, {0, -18}, {0, -36}, {-24, -36}, {-24, -54}, {-10, -54}, {-10, -54}}, color = {0, 0, 127}));
connect(sampler1.y, integrator2.u) annotation(Line(points = {{-7, -18}, {6, -18}, {6, -20}, {18, -20}}, color = {0, 0, 127}));
connect(timeTable1.y, sampler1.u) annotation(Line(points = {{-35, 26}, {-32, 26}, {-32, -8}, {-48, -8}, {-48, -18}, {-30, -18}, {-30, -18}}, color = {0, 0, 127}));
connect(timeTable1.y, integrator1.u) annotation(Line(points = {{-35, 26}, {-20, 26}, {-20, 24}, {-10, 24}}, color = {0, 0, 127}));
annotation(Icon(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {2, 2})), Diagram(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {2, 2})), experiment(StartTime = 0, StopTime = 10, Tolerance = 1e-6, Interval = 0.02));
end IntegrateTest;
- dersh
- 66 Posts
Re: Cumulative of time variables
Hi,
I think we are getting close but I get the following error both in OMEdit and Dymola:
Check of IntegrateTest:
It is not allowed to use pre for a continuous time variable outside a when clause:
pre(sumChange1.u)
The when-condition must be a discrete expression:
when not (sumChange1.u == pre(sumChange1.u)) then
sumChange1.y = pre(sumChange1.y)+sumChange1.u;
end when;
Error detected in
when not (sumChange1.u == pre(sumChange1.u)) then
sumChange1.y = pre(sumChange1.y)+sumChange1.u;
end when;
Errors detected in model.
Check aborted.
ERROR: 2 errors were found
Any suggestions?
Re: Cumulative of time variables
What version of OMEdit are you using? I am asking because the code I proposed works fine for me. So, there is a bug in my version or your version. Right now I am running 1.9.4~dev-9. I don't know why your version, and Dymola claim it is an error, while my new version of OMEdit seems to accept it fine.
This might work for you instead:
Code:
model IntegrateTest
Modelica.Blocks.Sources.TimeTable timeTable1(table = [0, 1; 1, 3; 2, 5; 3, 2; 4, 7; 5, 0; 8, 0]) annotation(Placement(visible = true, transformation(origin = {-46, 26}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
model SumChange
extends Modelica.Blocks.Interfaces.SISO;
equation
when {not u == pre(u), initial()} then
y = pre(y) + u;
end when;
annotation(Icon(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {2, 2})), Diagram(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {2, 2})));
end SumChange;
model SumTime
extends Modelica.Blocks.Interfaces.SISO;
Boolean sampleTrigger;
parameter Modelica.SIunits.Time samplePeriod = 1.0;
equation
sampleTrigger = sample(0, samplePeriod);
when sampleTrigger then
y = pre(y) + u;
end when;
annotation(Icon(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {2, 2})), Diagram(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {2, 2})));
end SumTime;
SumTime sumTime1 annotation(Placement(visible = true, transformation(origin = {-8, 68}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
equation
connect(timeTable1.y, sumTime1.u) annotation(Line(points = {{-35, 26}, {-30, 26}, {-30, 68}, {-20, 68}, {-20, 68}}, color = {0, 0, 127}));
annotation(Icon(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {2, 2})), Diagram(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {2, 2})), experiment(StartTime = 0, StopTime = 10, Tolerance = 1e-6, Interval = 0.02));
end IntegrateTest;
- dersh
- 66 Posts
Re: Cumulative of time variables
It looks like my use of pre(), in my earlier version, works in OM, but is outside the Modelica spec. See:
pre() operator
Determine min max
Determine min max
And an answer here that does solve the problem:
Detect change
However, using pre, or the version in the link above, would actually miss any months that happened to have the same values, since there would be no change. While sampling, as in my prior answers, will get every change (assuming that you have data for every month, and set the correct sampling interval)
- dersh
- 66 Posts
Re: Cumulative of time variables
It looks like my use of pre(), in my earlier version, works in OM, but is outside the Modelica spec. See:
pre() operator
Determine min max
Determine min max
And an answer here that does solve the problem:
Detect change
However, using pre, or the version in the link above, would actually miss any months that happened to have the same values, since there would be no change. While sampling, as in my prior answers, will get every change (assuming that you have data for every month, and set the correct sampling interval)
- dersh
- 66 Posts
- Index
- » Programming
- » Modelica Language
- » Cumulative of time variables