Is it possible to extend a Modelica connector without redefining "potential" and flow connect equations? - modelica

I have created a simple connector to handle 2D coordinate pairs. The connector includes Real potential variables x and y.
connector Coordinate_2D "2D Coordinate Connector"
Real x;
Real y;
end Coordinate_2D;
I want to extend the connector and create a 3D version like is shown below:
connector Coordinate_3D "Coordinate connector: x,y,z"
extends Coordinate_2D;
Real z;
end Coordinate_3D;
I am able to do this, but it doesn't seem like the connector is really extended. It recognizes that Coordinate_3D contains x, y, and z variables, but it doesn't seem to properly maintain the connector equations for the x and y potential variables.
I created a simple converter class to convert a 2D connector into a 3D connector. I expected that I should be able to simply define the equation for the new variable z and the x and y values would be automatically inferred because the 3D connector is extended from the 2D connector. So I expecteded that I could simply use:
model CoordinateConverter_2D_to_3D "x,y to x,y,z converter"
Real defaultZValue = 0;
equation
coordinate_3D.z = defaultZValue;
end CoordinateConverter_2D_to_3D;
But this does not seem to work. The translator states that variables coordinate_2D.x, coordinate_2D.y, coordinate_3D.x, and coordinate_3D.y are unused so they are removed from the simulation, leaving only 2 equations and 2 unknowns. If rather than translating I use the "Check" option in Dymola, it shows 6 equations and 6 unknowns.
In order to get the behavior I expect, I must manually define the equations for the x and y variables as well:
model CoordinateConverter_2D_to_3D "x,y to x,y,z converter"
Real defaultZValue = 0;
equation
coordinate_3D.x = coordinate_2D.x;
coordinate_3D.y = coordinate_2D.y;
coordinate_3D.z = defaultZValue;
end CoordinateConverter_2D_to_3D;
Is there something that I am missing that would allow the 3D connector equations to be extended from the 2D connector as I expect?
I understand that in this case it is trivial to add the two additional equations, but in my real case I have a more complex connector that includes multiple stream variables, a flow variable, and multiple potential variables. So it would be better to be able to simply extend additional variables to the connector rather than redefining the connector from scratch.
Any help or suggestions are appreciated.
Thanks,
Justin

Related

TIL-library EffCompressor: getInputRotary is structurally singular when Inertia

I am fairly new at working with the TIL-library (v. 3.12.0) in Dymola2022. I am trying to include some inertia in the current compressor models of the TIL-library. To start simple, I choose the EffCompressor as base model. The base model already has following equations using tau and w.
w = 2 PI n
tau = shaftPower / max(w, 1e-6)
The shafpower is calculated based on refrigerant mass flow and enthalpy at inlet and outlet.
If no mechanical port is used n is given a constant value using a model parameter and getInputsRotary.rotaryFlange.phi =0. In this case w is calculated using the first equation and than used to calculate tau using the second.
If a mechanical port is used, w=der(getInputsRotary.rotaryFlange.phi) and tau = getInputsRotary.rotatoryFlange.tau; (These values can be given by use of a RotaryBoundary)
My goal is to impose the inertia of the compressor (by defining its moment of inertia) and as such influence the change of rotational speed. I thus extended this model and added one unknown and 1 equation:
parameter Modelica.Units.SI.Inertia J = 1; (Parameter because I want to insert its value. Random value to test equations)
equation
tau=J*der(w);
The problem is this causes a singularity in the getInputsRotary-model, which only contains a rotational flange (with passes the phi and tau value from the RotaryBoundary).
I do not understand why this model because structurally singular (as I added one unknown and one equation). Defining J as a variable solves the problem with the model check, but gives a singularity error when running the model in a simple tester. Besides, the J should not be variable as it is a compressor property.)
I added the parameter J representing the moment of inertia. This results in a structurally singular problem. Also variants on this, by defining it as a variable, giving it an imposed value or not, etc. give the same problem.
What I would like to happen is that the change in rotational speed of the compressor accounts for the inserted moment of inertia without making the problem structurally singular.
Does anyone know why the problem becomes structurally singular and how I could address this? Thanks in advance!
Instead of modifying equations of a component model out of a library I would always prefer to extend the system model (graphically) by using additional components.
In your case you can easily do that by mixing TIL components with MSL (Modelica Standard Library) components. The mechanical connector from TIL is compatible to Modelica.Mechanics.Rotational components.
Adding inertia would look like that:

Graph a 3D plot given an equation with three variables

I have an equation:
b*cos(alpha) - a*sin(alpha) + b*cos(betta)-a*sin(betta) - b*cos(gamma) + a*sin(gamma) = 0
I want to create a 3D plot of this in Matlab with alpha vs betta vs gamma ( x - y - z ). I don't understand how to represent the equation so it could be plotted. How can I do this?
It is possible to assume that a = b = 1;
You need to understand what you have at hand. What does the equation show? Which form is it written? How does MATLAB plot different type of equations?
Fist, lets try to understand what type of function you have. It has 3 variables, but it equals to zero. A 3 variable equation generally defines a surface in 3D. In your case, this surface is described on its implicit form.
Now, if we look at the documentation of MATLAB, surfaces are generally plotted with surf, but surf needs 3 inputs (x,y,z) and you can not easily isolate your 3 variables.
Ah! but luckily, there is a thing called a search engine, that can gives us hints. Now that we know what kind of equation we have, we might as well use Google (or your favorite search engine) and type "implicit surface plot MATLAB", and that search will return a function called fimplicit3.
I think it seems to work:

Warning " X is rank deficient to within machine precision" problem

I am trying to build a multiple linear regression in MATLAB with 20 predictors, which are categorical with 4 levels each. I am using the function "regress", like this (these are not the actual variables):
X = [ones(size(x1)) x1 x2 x3...x20];
[b,bint,r,rint] = regress(Y, X);
Before this, I transformed the vectors x1,x2...x20 in categorical variables with dummyvar.
I get this error and a lot of 0's in the b coefficients and this error:
Warning: X is rank deficient to within machine precision.
In the dummyvar documentation it is mentioned:
To use the dummy variables in a regression model, you must either delete a column (to create a reference group) or fit a regression model with no intercept term.
I tried not using the intercept ones(size(x1)) and I get the same error.
I would appreciate any input on how to solve this.
Try to simplify the problem down to the minimum working example, and then post that here, so we can reproduce it and help you through. See https://en.wikipedia.org/wiki/Rank_(linear_algebra)
for examples of rank deficiency.

Using single variables in Simulink

I'm brand new to Simulink, but I have a lot of programming experience, so I'm not used to thinking about problems in the Simulink mindset. Either I'm missing something very obvious or something very deep.
I'd like to implement a simple model of a linear sliding table according to the following equations:
v = model input = table velocity
dt = simulation timestep
x = internal displacement variable = initially zero
x at current timestep = (x at last timestep) + v*dt
In C or C++ I would declare a variable x and update it explicitly, but I can't figure out how to implement this kind of persistent state variable in Simulink. My model is a discrete time model with a fixed timestep.
I know I can read variables set in the MATLAB workspace- is the right approach here to read/write to the matlab workspace once per simulation step? If so, how do I do that? If not, what's the "Simulink way" of doing this?
Thanks.
Edit 1 in response to comment:
The code I would write in MATLAB for the above task would be the following, with x and dt declared in the MATLAB workspace, and then the update() function called once per timestep. The function updates the variable in the MATLAB workspace and returns the new value as well for convenience.
function xNew = update( v )
global x;
global dt;
x = x + v*dt;
xNew = x;
end
Edit 2: What I'm really trying to achieve is a simple simulation and experimentation with feedback PID control, but I have zero experience in control theory other than some things I've picked up here and there along the way. I'm just trying to come up with a simple, representative problem for me to play around with. I've attached a picture of my model below. The table is displacement-controlled with the target displacement being the sine wave.
Essentially my question is about implementing the highlighted "Motor Model" block.
Memory like this is implemented using the Unit Delay block ( or the Integrator block if working in continuous time). In the diagram below there needs to be a MATLAB Workspace variable called dt (for the Gain block to work) and the Sample Time of the Unit Delay block also needs to be set to be dt.
Under almost no circumstance is writing to the Workspace at each time step the right approach when using Simulink.

solve trig equation over boundary

Firstly, I'm sure a simple answer exists for this, maybe I'm just not wording it right in searching for an answer online.
I'm trying to solve an equation that looks like this:
a*x*cot(a*x) == b
Where a and b are constants. Using
solve(a*x*cot(a*x) == b, x)
I'm getting a result I know is wrong (with the values I'm using for the constants, I'm getting like -227, and it should be something around +160.) I plotted it up in Mathematica as two separate functions, and they do cross each other right around there, but since the cot part is periodic, they do so many times.
I want to constrain Matlab's search for the solution to a specific interval, such as 0 to 200; how do I do that?
I'm pretty new to Matlab (rather more experienced in Mathematica).
You can specify the bounds on x using fzero with only two requirements
The function must be in a "residual" form (i.e., r(x) = 0)
The residual values at the two bounds must have opposite sign (this guarantees that a root exists within the interval for continuous functions).
So we re-write the function in residual form:
r = #(x) a*x*cot(a*x) - b;
define the interval
% These are just random numbers; the actual bounds should come
% from the graph the ensures r has different signs a xL and xR
xL = 150;
xR = 170;
and solve
x = fzero(r,[xL,xR]);
I see you were trying to use the Symbolic Toolbox for a solution, but since the equation is a non-linear combination of a polynomial and a trigonometric function, there is more than likely no closed form solution. So I differed to a non-linear, numeric root-finder.
I tried some values and it seems solve returns a numeric solution. This is the documented behaviour if no analytic solution is found.
In this case, you may directly call the numeric solver with a matching start value
vpasolve(a*x*cot(a*x) == b, x,160)
It's not exactly what you asked for, but using your reading from the plot as a start value should do it.