TIL-library EffCompressor: getInputRotary is structurally singular when Inertia - modelica

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:

Related

First order Modelica model with null time constant

I'd like to figure out whether it's possible (and semantically legal) in Modelica to simulate a model of a first-order transfer function, with a time constant equal to zero (T below). I'm using OpenModelica 1.15.0~dev-48-g3656b95, but I'm asking the question in a general Modelica context.
My context is experimenting Model Order Reduction on Modelica models, which brings me to try to use the Modelica.Blocks.Continuous.FirstOrder with a sometimes null time constant. However, to make the discussion simpler, here is the flat model I'm working on (a simplification and adaptation of the standard FirstOrder block):
model FirstOrderZero
import Modelica.SIunits;
Real u "input";
Real y "output";
parameter Real k(unit="1")=1 "Gain";
constant SIunits.Time T=0 "Time Constant";
equation
u = 1;
der(y) = (k*u - y)/T;
end FirstOrderZero;
I understand that the way Modelica tools operate a symbolic equation analysis, the time constant T should be constant rather than a parameter. Indeed, for T=0, the differential equation gets degenerated into an algebraic equation y = k*u. Unless the Modelica simulation tool can generate different code pathways for different values of T (which I think no Modelica tool does, except maybe Modia in the future?), the fact that T is null or not should be decided at the beginning of the equation analysis.
What I don't understand is why the above model fails to simulate ("division by zero at time 0 [...] where divisor expression is 0.0" with OM 1.15 dev) whereas it works when the last equation is rewritten as:
T*der(y) = (k*u - y);
I would assume that the symbolic equation analysis should reformulate the equation automatically? (I can see with OM Transformational Debugger that the equation becomes der(y) = (k - y)/0.0 which, of course, breaks at simulation).
Or perhaps, is it syntactically illegal to write Modelica equations with a division by a null constant?
Variability of T
If the time constant T is constant, a parameter, or maybe a (discrete) variable depends on what you want to do.
the value of constants gets fixed during translation
parameters can be changed after translation (so before a simulation is started), but not during simulation
discrete variables can change their value during simulation, but only at event instances
continuous variables can change their value during simulation
See 4.4.4 Component Variability Prefixes discrete, parameter, constant in the Modelica Specification 3.4 for details.
For first order elements you usually use a transfer function that will not change during simulation, but the user should be able to set the value of T. Therefore parameter would be the natural choice.
Why your simulation fails
By using a constant for T, the Modelica tool can optimize your equations more than it can when you use a parameter. And depending on how you write your equations, you will end up with a different optimized equation.
For constant T=0 your original model reduces to
model FirstOrderZero
Real u, y;
parameter Real k=1;
equation
u = 1;
der(y) = (k*u - y)/0;
end FirstOrderZero;
To solve y its derivative der(y) is needed - but it can not be computed, as a division by zero always occurs.
In the second case with T*der(y) = (k*u - y); your model reduces to
model FirstOrderZero
Real u, y;
parameter Real k=1;
equation
u = 1;
0 * der(y) = (k*u - y);
end FirstOrderZero;
The equation 0 * der(y) = (k*u - y) results in 0 = (k*u - y) and therefore y = k*u. There is no division by zero and the model can be simulated.
You see, even though Modelica is an acausal language, it can matter how you write your equations.
What you can do
A first order element with T=0 is not a first order element anymore, but only a proportional gain. To model that, use the block Modelica.Blocks.Continuous.TransferFunction.
If T is not zero, parametrize it like this:
Modelica.Blocks.Continuous.TransferFunction transferFunction(b={k}, a={T,1})
and if its zero use
Modelica.Blocks.Continuous.TransferFunction transferFunction(b={k}, a={1})

How can we model independent noise for every output dimension of a multi-output GP in GPflow?

Say I have a problem having D outputs with isotopic data, I would like to use independent noise for each output dimension of a multi-output GP model (Intrinsic Coregionalisation Model) in gpflow, which is the most general case like:
I have seen some example of using multi-output GPs in GPflow, like this notebook and this question
However, it seems for the GPR model class in gpflow, the likelihood variance ($\Sigma$) is still one number instead of D numbers even if a product kernel (i.e. Kernel * Coregionalization) is specified.
Is there any way to achieve that?
Just like you can augment X with a column that designates for each data point (row) which output it relates to (the column is specified by the active_dims keyword argument to the Coregion kernel; note that it is zero-based indexing), you can augment Y with a column to specify different likelihoods (the SwitchedLikelihood is hard-coded to require the index to be in the last column of Y) - there is an example (Demo 2) in the varying noise notebook in the GPflow tutorials. You just have to combine the two, use a Coregion kernel and a SwitchedLikelihood, and augment both X and Y with the same column indicating outputs!
However, as plain GPR only works with a Gaussian likelihood, the GPR model has been hard-coded for a Gaussian likelihood. It would certainly be possible to write a version of it that can deal with different Gaussian likelihoods for the different outputs, but you would have to do it all manually in the _build_likelihood method of a new model (incorporating the stitching code from the SwitchedLikelihood).
It would be much easier to simply use a VGP model that can handle any likelihood - for Gaussian likelihoods the optimisation problem is very simple and should be easy to optimise using ScipyOptimizer.

Solving static equations (or systems thereof)

I wanted to do the following in Modelica: in a specific model I have several parameters h and I want to deduce some time independent values k from them by solving a set of implicit equations between the parameters and the other values. Since the equations are implicit by nature, I cannot simply assign an expression, I rather have to let the solver find the solution.
Since the parameters are constant, I want to be able to solve the equations only once at the beginning, before the actual time integration of the rest of the system (e.g. a differential equation that contains k as a coefficient) takes place.
See the following example of what I would like to be able to write:
model ConstantTest
parameter Real h = 2;
const Real k;
initial equation
k*k=h; // just an example of an implicit equation, which in this simple case could also be written explicitly
end ConstantTest;
But this fails because a "constant" in Modelica is not only constant in the sense of having vanishing time derivative, but it is also already immutable at the time when the initial equations are being solved. So the solver complains that it cannot solve the initial equation 0 = 2, which is because it is assuming that k invariably equals 0.
Of course I can just make k a variable, but then I have to tell the solver explicitly that k has vanishing time derivative (amounting to it being practically "constant" in the naive physical sense):
model ConstantTest
parameter Real h = 2;
Real k;
initial equation
k*k=h;
equation
der(k) = 0;
end ConstantTest;
This works, but it is somewhat odd because the solver has to solve a trivial differential equation at every time step in order to do basically nothing at all to k. And that would be a waste of computational resources.
Is there any way to solve static implicit equations with Modelica without introducing "time evolution overhead"?
I guess you could do this:
model ConstantTest
parameter Real h = 2;
parameter Real k(fixed=false);
initial equation
k*k=h;
end ConstantTest;
k will be computed at initialization.
I think the best way to define these kinds of systems is:
model ConstantTest
parameter Real h = 2;
Real k;
equation
2*k=h;
end ConstantTest;
Which OpenModelica will put in an initial section and solve only once. I would consider OpenModelica's behaviour for your system a bug since it's solving a time-independent equation multiple times.

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

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

how to use Partial derivative in modelica?

If i have to use a partial derivative in modelica, how can that be used. I am not sure if partial derivative can be solved in modelica but i would like to know, if it can be used then, how should it be implemented.
There are two different potential "partial derivatives" you might want. One is the partial derivative with respect to spatial variables (if you are interested in solving PDEs) or you might want the partial derivative of an expression with respect to a simulation variable.
But it doesn't matter, because you cannot express either of these in Modelica.
If your motivation is to solve PDEs, then I'm afraid you will simply have to process the spatial aspects in your models (using some kind of discretization, weak formulation, etc) so that the resulting equations are simple ODEs.
If you want to compute the derivative of expressions with respect to variables other than time, the question would be ... why? I'm hard pressed to think of an application where this is really necessary. But if you can explain your use case, I could comment further on how to handle it.
I've discretized PDE systems for solution in Modelica: heat equation, wave equation, PDEs from double-pipe heat exchangers, PDEs from water hammer to model pressure surges in pipelines etc
At a simple level, you can replace the spatial derivative with a central difference approximation, and then generate the entire set of ODEs with a for loop. For example. here's a Modelica code snippet for a simple discretization of the heat equation.
parameter Real L = 1 "Length";
parameter Integer n = 50 "Number of sections";
parameter Real alpha = 1;
Real dL = L/n "Section length";
Real[n] u(each start = 0);
equations
u[1] = 273; //boundary condition
u[n] =0; //boundary condition
for i in 2:n-1 loop
der(u[i]) = alpha * (u[i+1] - 2 * u[i] + u[i-1]) / dL^2;
end for;
This is just a simple example entered from the top of my head, so excuse any mistakes.
Do you have a specific example or application?