I'm creating a pipe model in OpenModelica using the method of characteristics. The method is currently working, but the results are displayed as single variables stored in several arrays. The arrays store variables as H_array[T,N] (head) where T is time and N is space.
I would like to view the results as a plot (shown in the image below on the right hand side) with head H on the y-axis and time T on the x-axis in the "Plotting" tab in OpenModelica, but as previously mentioned, the results are displayed as single variables as shown below. More specifically, I would like to look at a certain place (meaning N), say N=3, and observe how H_array[k,3] for k=2:T vary on the y-axis as a function of time T on the x-axis.
I'm expecting to observe a (semi)square pressure pulse as seen on the right side of the picture below. I know how to pick out every element with N=3 and put them in a separate array, but I do not know how to continuously display the values as a function of time. Can this be done with a derivative function in some way? Any tips?
Related
I have a matrix (type:double) of size 106 x 103. The matrix represents European gridded temperature data for one timestep (a day).
For every day, I want to calculate the degree days (thermal time) for a species, based on the temperature recorded for each 'cell' (i,j element) in the matrix using a formula that I have coded in Matlab based on a sinewave approach.
So, ultimately, what I want to do is being able to apply a calculation to my matrix, that will provide individual output for each grid cell (i,j element) dependent on the temperature data that is recorded there.
I could do this with a loop, but I have to accumulate these degree days for multiple years, so I would prefer to find a way of applying the calculation to each element in a daily matrix simultaneously (and then looping through the days (matrices)).
From what I have read, you can use a cellfun if your matrix is a cell array (mine is not).
Then I was also looking at the bsxfun option, but it seems like the functions are just standard functions..like mean, max etc.
So now, I'm looking at using arrayfun in conjunction with a function I create from my algorithm to calculate degree days.
I have been trying to write a test function but Matlab keeps throwing up the same error:
I type:
function output=degreedays(x)
and Matlab throws back:
Error: Function definitions are not permitted in this context.
Can someone tell me what I'm doing wrong? Why is it not accepting the declaration of the function name?
MATLAB does not allow you to define named functions like this at the command line. You need to place your function definition in a file. MATLAB then can call that function by the name of the file - so in your case, put your function definition in a file called degreedays.m.
See the doc for more: https://uk.mathworks.com/help/matlab/matlab_prog/create-functions-in-files.html .
I'm trying to model the respective processes of an internal combustion engine. My current modelling approach is to have different sub functions which model the different processes.
Within each sub function is a Level 2 S-Function which solves the ODEs to give the in cylinder state (pressure, temperature, etc).
The problem that I'm having is that each sub function is enabled depending on the current crank angle which is computed from the current timestep in Simulink. The first process works fine as I manually set the initial values, but then I can't pass the latest in-cylinder state (the output from the first sub function) to the second sub function to use as the initial conditions (it insists on using the initial values I set at the beginning of the simulation).
Is there any way round this? Currently I'm going along a path of global data stores, but haven't had any joy so far.
There are a lot of different ways to solve this problem.
I'll show some of them as examples.
You can create additive output with Unit dalay block like this:
So you can get value of your crank angle from previous timestep and USE IT in formula for solving you equations.
Also you can use some code like this:
if (t == 0)
% equations with your initial values
sred = 0;
else
% equations with other values
y = uOld + myCoeef;
end
Another idea: sometimes I use persistent variables in Matlab function to save values of some variable from previous step. But I think it makes calculation slower.
One more idea - if you have Stateflow you can create chart with two states: first for initial moment with your coefficient and second to solve new equations.
If I understood you in wrong way you can show your code and we'll offer some new ideas!
P.S. Example of my using of S-Function:
My S-Function needs 2 values: Q is calculated in simulink at every step, ro is initial I took from big matrix I loaded from workspace in table and took necessary value depending of time.
So there is no any initial values in S-Function - all needed values I transmit into it from simulink!
how to use the "from workspace block in simulink" ?
I have tried using the from workspace block by given 10*2 matrix as input. it is appending some extra data along the data I have given .
and I have such 3 such blocks and want to know how I merge them.
Read the documentation. Simulink is time-based so the data in your From Workspace block must be as a function of time. Does your 10 x 2 matrix represent a signal as a function of time? If so, it needs to be as follows:
A two-dimensional matrix:
The first element of each matrix row is a
time stamp.
The rest of each row is a scalar or vector of signal
values.
The leftmost element of each row is the time stamp of the
value(s) in the rest of the row.
10 values isn't very much, it's likely that Simulink will need additional data points at intermediate times, if you have the Interpolate Data check box ticked. If not, "the current output equals the output at the most recent time for which data exists".
I think you may have a misunderstanding of the variables intended to be read by the FromWorkspace block.
The block expects a time series defining the value at various points in the simulation.
The From Workspace block help should point you in the right direction on this. Mathworks Help Documentation
I believe that something like the following would work for you:
>> WorkspaceVar.time=0;
>> WorkspaceVar.signals.values=zeros(10,2)
>> WorkspaceVar.signals.dimensions = [10,2]
I am trying to simulate throw of the ball under angles using simulink. I'm able to simulate it for one angle but I would like to simulate it using loop. This is what I want to do in simulink using FOR :
for i=-5:10:85
Here is picture of my simulink:
If I understand your question correctly, you essentially want to rerun your simulation multiple times for different values of the constant Degrees. Instead of using a For Iterator, you may be able to achieve effectively the same result by using vector operations. That is to say, change the value of the constant Degrees from being a scalar value to instead being a vector (in this particular case just set its value to be [5:10:85]). The outputs of your Simulink model (ie the x and y results) should now be vectors corresponding to the various Degree values.
Put all the blocks into the for-iterator subsystem. The For Iterator block will output the current iteration, you can use that index (which starts at 0/1) to cycle the angle from -5 to 85 (try to hook the For Iterator block up to a Gain and Sum block). At each iteration, all the blocks in the for-iterator subsystem will run, and the output of the For Iterator block will increment by one.
The previous solution to make the angles a vector will also work.
Using MATLAB's for reference page, I'd rewrite your line as:
for i=5:10:85
...
end
I want to plot a piecewise function, but I don't want any gaps to appear
at the junctures, for example:
t=[1:8784];
b=(26.045792 + 13.075558*sin(0.0008531214*t - 2.7773943)).*((heaviside(t-2184))-(heaviside(t-7440)));
plot(b,'r','LineWidth', 1.5);grid on
there should not be any gaps appearing in
the plot between the three intervals , but they do.
I want the graph to be continueous without gaps.
Any suggestions on how to achieve that.
Thanks in advance.
EDIT
Actually, my aim is to find the carrier function colored by yellow in the figure below. I divide the whole interval into 3 intervals: 1-constant 2-sinusoidal 3- constant, then I want to find the overall function from the these three functions
Of course there are "gaps". The composite function is identically zero for all t<2184, and for all t>7440. The relationships can only be non-zero inside of that interval. And you have not chosen a function that is zero at the endpoints, so how can you expect there not to be "gaps"?
What values does your function take on at the endpoints of the interval?
>> t = [2184 7440];
>> (26.045792 + 13.075558*sin(0.0008531214*t - 2.7773943))
ans =
15.689 20.616
So look at the hat function part of this. I'll be lazy and use ezplot.
>> ezplot(#(t) ((heaviside(t-2184))-(heaviside(t-7440))),[0,8784])
Now, combine this, multiplying it by a trig piece, and of course the result is identically zero outside of that domain.
>> ezplot(#(t) (26.045792 + 13.075558*sin(0.0008531214*t - 2.7773943)).*((heaviside(t-2184))-(heaviside(t-7440))),[0,8784])
But if your goal is some sort of continuous function across the two chosen points in the hat function, you need to chose the trig part such that it is zero at those same two points. Mathematics is not spelled mathemagics. Wishing that you get a continuous function will not make it so.
So is your real question how to chose that internal piece (segment) as one such that the final result is continuous? If so, then we need to know why you have chosen the arbitrary constants in there. Surely these numbers, {26.045792, 13.075558, 0.0008531214, 2.7773943} all must have some significance to you. And if they are important, then how can we possibly make the result a continuous function?
Perhaps, and I'm just guessing here, you want some other result out of this, such that the function is not identically zero outside of those bounds. Perhaps you wish to extrapolate as a constant function outside of those points. But to help you, you must help us.