connect to a slice of an array of connectors - modelica

I have an array of connectors, and I want to connect another, smaller array of similar connectors, to a slice of this connector array. Example with a an array of x connectors, b an array of y connectors, x < y:
connect(a[:], b[1:x]); // works fine
connect(a[:], b[2:x+1]); // gives an error
The error I get in the second case (when checking the model in Dymola 2012) says:
Error: Failed to expand connect(a[:], b[2:x+1])
Is this a language or tool limitation? And is there a workaround (besides using for loops to connect each individual connector)?

That must be a tool limitation because the specification says:
Subscripts in a connector reference shall be parameter expressions or the special operator “:”.
The only workaround I can think of is a for-equation or the more obvious: filing a bug report to the Dymola team. I will do the same for OpenModelica (it generates equations, but the wrong ones).

I think we need more code here to understand what is going on. I don't see any apparent limitation in Dymola. For example, the following code works fine in Dymola 2012 FD01:
model SlicedConnectors
parameter Integer n(start=5);
Modelica.Blocks.Interfaces.RealInput a[n];
Modelica.Blocks.Interfaces.RealOutput b[2*n];
equation
connect(a[:],b[1:n]);
connect(a[:],b[(n+1):(2*n)]);
end SlicedConnectors;
So it doesn't seem to be slicing itself that is the issue but probably something more complicated (something about the specific connectors, variability of sizing, etc).

Related

Why the parameters can't be recognized between the models connected by the Controlbus component in Dymola/Modelica?

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).

What's the purpose of 'coder' in matlab?

I was seeing the built-in function estimateFundamentalMatrix and it looks like as follows
function r = checkOutputClassStrings(list, value)
potentialMatch = validatestring(value, list, ...
'estimateFundamentalMatrix', 'OutputClass');
coder.internal.errorIf(~strcmpi(value, potentialMatch), ...
'vision:estimateFundamentalMatrix:invalidOutputClassString');
r = 1;
I was curious about the coder.internal.errorIf function. I guessed that coder is a system object that shows internal states of a function, but I don't know exactly.
coder is a package that is part of the MATLAB Coder product.
MATLAB Coder allows you to convert a subset of the MATLAB language into C code - the C code can then subsequently be incorporated into wider C applications, or brought back into MATLAB via the MEX interface, or delivered to an embedded device. When using MATLAB Coder, you will include commands from the coder package within your MATLAB code - they typically have no effect on the code when it is run within MATLAB, but when converting to C code they help you to control the way it is converted, by adding additional information necessary to help with the conversion (for example, by controlling the inlining of a function, or specifying that a for-loop should be unrolled).
Some toolboxes, including the Computer Vision Toolbox that contains the code snippet you refer to, explicitly support the use of MATLAB Coder to generate C code from them, in that they make sure to only use the subset of the MATLAB language that is convertible into C, and they include coder commands to help optimise their conversion into C.
The command you're seeing here says that, when converting the MATLAB code into C, it should include an explicit check in the C code to compare value with potentialMatch, and exit with an error if they don't match.
(I'll be honest - I'm not entirely sure why this is necessary. As far as I can see, if the code has got past the validatestrings statement, then by definition it should always pass the test in the subsequent statement. Seems a bit redundant to me, but maybe I'm overlooking some detail).
I'm just formalising the answer I gave in the comments...
The coder.internal.errorIf is exactly what the name suggests. It's an internal command to conditionally issue an error.
The strcmpi function performs a case insensitive string compare, and returns a Boolean (true/false) value.
The tilde (~) negates the result of the call to strcmpi.
So the line you're curious about is somewhat equivalent to this on the surface:
% Use strcmpi for case insensitive string comparison
if ~strcmpi(value, potentialMatch)
% When using 'error', the string must be specified along with the message identifier.
% The errorIf command was leveraging the in-built 'message' catalog.
% In this case I've lifted the error message from calling the original errorIf command.
error('vision:estimateFundamentalMatrix:invalidOutputClassString', ...
'Expected OutputClass to be ''double'' or ''single''');
end
The code.internal.errorIf command is, as pointed out in other answers and comments, a different construct than the common error command, which allows MATLAB to optimise C code generation (hence why it is in the coder package).
For more coder-specific details, see Sam's answer.

Error "Function 'subsindex' is not defined for values of class 'embedded.fi'." When Changing Matlab Version

I have a struct 'ss' in Matlab that has a number of fields that are all zero'd in the beginning.
Declarations:
ss = struct;
ss.angle_spit = zeros(ais,his,tis,2);
ss.angle_neck = zeros(ais,his,tis,2);
I then go into a for loop and each iteration I update these values like such.
ss.angle_spit(ai,hi,fi,ti,1) = angle_spit_d;
ss.angle_spit(ai,hi,fi,ti,2) = angle_spit_u;
I was running this code on Matlab version R2015a with no errors, however, when I started to run it on a different computer running R2012a it gives me the error
"Error using subsindex
Function 'subsindex' is not defined for values of class 'embedded.fi'.
Error in spit_additup_11a_for12long3_fixqs (line 409)
ss.angle_spit(ai,hi,fi,ti,1) = angle_spit_d;"
My understanding is that I am trying to index the struct and that is not a possibility in 2012 and it is in 2015. Am I correct in assuming this, and if so, how would you go about changing the code to support this in 2012? Would you just create many more fields for the struct? Thank You.
I think the problem is that you are creating an index variable called fi and it's being confused with the function fi from the Fixed-Point Designer. When you try to use it as an index into the structure field ss.angle_spit, it throws the given error. The version-dependence of the error is more likely a dependence on whether the Fixed-Point Designer is included with your installation or not.
Try renaming fi to something else. I would expect that to fix the problem.
On a broader note, you should avoid giving variables the same name as an existing function, since it can either shadow that function or lead to strange behavior like you're seeing. As such, you should also rename your structure variable, since ss is already an existing function.

How to pass heatPorts.T to DynamicPipe flowModel?

In the implementation of a flow models that function with Modelica Standard Library DynamicPipe (or a similar model that builds from PartialTwoPortFlow) there are examples of flow models that take place in an environment with heat transfer that requires wall properties (e.g., heatPorts.T and/or heatPorts.Q_flow) in order to calculate the pressure drop.
For example, a pressure drop model may need to calculate a new visocisty or Prandtl number based on the medium pressure and the wall temperature to capture cooling/heating effects, etc.
The heat transfer model obtains properties of the medium via passing the "states" however there is no existing connection in DynamicPipe or PartialTwoPortFlow that goes the other way.
I've tried numerous variations of ideas and have had no success, including creating a new PartialTwoPortFlow that contains all the heat transfer calls that exist in DynamicPipe.
I hesitate to post this question as I am surprised I am having so much difficulty with this and would not be surprised to find a straight forward solution. Nevertheless I need this ability and curious if others have already solved this issue as I am running short on ideas.
So my questions is:
What is a proper/efficient means of passing the heatPorts.T values to the flowModel?
For those familiar with the MSL Fluids library and more specifically the Pipe models provided, this answer should (hopefully) make sense.
Aside:
It seems the dynamic pipe could be improved a little bit by not restricting the heat transfer area to the perimeter x lengths and instead introduce a parameter (e.g., heatTransferArea) that would permit the user to define it and default to perimeter x lengths. See below
parameter SI.Area heatTransferArea = perimeter*lengths "Total heat transfer area";
HeatTransfer heatTransfer(
...
final surfaceAreas=heatTransferArea , //perimeter*lengths <- replaced
...
End Aside:
In order to communicate heatPorts.T to the flowModel and to not have errors when I checked each of the models I had to do the following:
Make an "input" in the flowModel for Ts_w. Not parameter (take a look at how mediums.state is passed)! Might have to do some finagling with it like "diameters" (see DetailedPipeFlow) to make it be used how you think it's going to be used.
Duplicate PartialTwoPortFlow and add the final Ts_w = Ts_wFM to flowModel. Additionally define the variable SI.Temperature[nFM+1] Ts_wFM in PartialTwoPortFlow and establish definitions similar to statesFM in the equation section.
This will require adding a HeatPorts model to be added.
Duplicate DynamicPipe and change the extension to the new PartialTwoPortFlow. Set use_HeatTransfer to true (as I've set it up this has to be true now for this to work which isn't ideal but manageable). Might be good to make it a final parameter so it can't be changed.
Don't forget to connect heatPorts to the heatports added in step 2.
I believe that this capture a quick version of how I was able to get the wall temperature passed to the flowModel. Perhaps there is a more elegant way but I though this was pretty serviceable. I now simply have one more Partial model and one more pipe model called PartialTwoPort_wTemp and GenericDynamicPipe (I also incorporated my surfaceArea correction in the new pipe).

Accessing variable by string name

I need to load experimental data into scicoslab, a (pretty badly designed) clone fork of scilab which happens to support graphical modeling. The documentation on the web is pretty poor, but it's reasonably similar to scilab and octave.
The data I need to process is contained into a certain number of text files: Data_005, Data_010, …, Data_100. Each of them can be loaded using the -ascii flag for the loadmatfile command.
The problem comes from the fact that loadmatfile("foo", "-ascii") loads the file foo.mat into a variable named foo. In order to to cycle on the data files, I would need to do something like:
for i = [5:5:100]
name = sprintf("Data_%02d", i);
loadmatfile(name, "-ascii");
x = read_var_from_name(name);
do_something(x);
end
where what I search for is a builtin read_var_from_name which would allow me to access the internal symbol table by string.
Do you know if there exist a similar function?
Notes:
There's no way of overriding this behavior if your file is in ascii format;
In this phase I could also use octave (no graphical modelling is involved), although it behaves in the same way.
>> foo = 3.14; name = 'foo'; eval(name)
foo =
3.1400
The above works in MATLAB, and Scilab's documentation says it also has an eval function. Not sure if I understood you correctly, though.
#arne.b has a good answer.
In your case you can also do that in matlab:
a=load('filename.mat')
x=a.('variable_name')
lets go through your points one by one:
"ScicosLab, a (pretty badly designed) clone of Scilab" This in my opinion is an inaccurate way of introducing the software. ScicosLab is not a clone of Scilab but a fork of it. The team behind ScicosLab (INRIA) are the ones who made scocos (now called xcos in Scilab development line). At some point (from Scilab v4) the Scilab team decided to move away from Tcl/tk towards Java, but the SciccosLab/scicos team departed, keep using the language (Tcl) and it's graphical user interface design package (tk). Giving the ScocosLab community the credit that the whole Scilab documentation and support is not very good in general. :) (more about Scilab and the forks here)
Regarding the technical question I'm not sure what you are trying to achieve here, Scilab/ScicosLab still have the eval function which basically does what you want. However this function is to be deprecated in favor of evstr. There is also the execstr function which worth studying.
The loadmatfile, as far as I have understood, "tries" to load the variables defined in a MATLAB .mat file (MATLAB's proprietary tabular format) into the Scilab workspace. For example if there is a variable foo it will "try" to create the variable foo and loads its value from the MATLAB script. Check this example. I would create a variable x(i) = foo in the for loop. again your question is not completely clear.
As a side note maybe you could consider exporting your data as CSV instead of .mat files.