modelica / ModelicaStandardLibrary

Free (standard conforming) library to model mechanical (1D/3D), electrical (analog, digital, machines), magnetic, thermal, fluid, control systems and hierarchical state machines. Also numerical functions and functions for strings, files and streams are included.
https://doc.modelica.org
BSD 3-Clause "New" or "Revised" License
466 stars 166 forks source link

Initial values for polyphase inductor currents etc. #4457

Open ceraolo opened 3 weeks ago

ceraolo commented 3 weeks ago

Good modelica models have initial values defined, otherwise the results can be depending on the used tool and the assumptions it makes on those inital values.

When creating electric circuits, the most common state variables whose initial values are to be set are capacitor voltages and inductor currents. Modelica.Electrical.Analog.Basic capacitors allow setting initial voltages, and inductors intial currents.

Unfortunately the same does not occur with Modelica.Electrical.Polyphase capacitors and inductors. Maybe one can set initial values for a polyphase inductor through modifiers, but this, if possible, is tricky. Personally, I could not find a way, at least in a three-wire circuit for which only two of the three currents must be set.

It seems to me that polyphase inductors and capacitors, and the other polyphase components having state variables, should have a way to set initial values from their masks, similar to their single phase counterparts.

casella commented 3 weeks ago

@AHaumer, @christiankral what do you think?

AHaumer commented 3 weeks ago

Lets investigate the polyphase inductor, the capacitor can be treated analogous. The number of phases m can be choosen by the user. We have available the currents i[m] through the component. You have situations in which you are allowed to define all m initial currents (star-point connected), but if the star-point is not connected the sum of the m currents is zero and you are allowed to define only m-1 initial currents. How do you handle that? You can set only all m initial values at once. @ceraolo please give me a suggestion. You have to consider not only the trivial case where the m or m-1 currents are initialized to be zero, maybe you want to initialize them with m or m-1 different initial values. Even if we try to motivate the tool to present an initialization menu: Dymola 2024x doesn't do that, OM 1.23.1 does so. But you can only initialize all m currents together (yes with different initial values) but either all of them fixed=true or all of them fixed=false. How do you handle the condition star-point not connected? @HansOlsson Do you have a suggestion from the language point-of-view? IMHO the only way to handle that is to write initial equations: `model Inductor

extends Modelica.Electrical.Polyphase.Basic.Inductor(i(start=zeros(m)));

initial equation

//i[m] = zeros(m);

i[1:m-1]=zeros(m-1);

end Inductor;`

ceraolo commented 2 weeks ago

Lets investigate the polyphase inductor, the capacitor can be treated analogous. The number of phases m can be choosen by the user. We have available the currents i[m] through the component. You have situations in which you are allowed to define all m initial currents (star-point connected), but if the star-point is not connected the sum of the m currents is zero and you are allowed to define only m-1 initial currents. How do you handle that? You can set only all m initial values at once. @ceraolo please give me a suggestion.

What I propose is to give users the possibility to set initial currents, possibly using a way such as the obtainable flexibility is lower than having individual Electrical.Analog inductors. So we can give up:

  1. allowing for a m-phase m-wire system users to choose which of the m initial currents are set (one must be left unset, since it will be set by the software as the opposite of the sum of all the currents that are set). Therefore, I agree to your proposal of leaving unset the last m-th current in this case
  2. allowing users to decide whether the initial values are all fixed or not: individual choice not possible).

So, in a three-phase system the user will be allowed to set a vector of 3 or two currents. In the first case it is expected that current can flow through neutral (i.e. we have a 3-phase, 4-wire system), and therefore for t=0 the three currents are independent states. In the second case, the code should automatically set the third current to the opposite of the sum of the two set currents.

Obviously the user can mistakenly fix m currents for a m-wire m-phase system (e.g. 3 currents for a three-wire three-phase system), resulting in an overdimensioned initial system of equations. This is what already occurs if the user implements the same three-phase system with Analog.Basic components. I mean, I would leave as modeler responsibility (not a tool responsibility at the time of evaluating user input) to decide how many (m or m-1) inductor currents need to be initilalised, depending on the system architecture (whether there is the physical possibility of non-zero neutral current or not). In case of user mistake, tools will intervene at compiling time, finding that the initial system of equations is overdetermined.

To summarise. The GUI would propt the user for a vector of intial currents and a unique flag for these values being fixed=true or not. The number of current values the tool is expected to receive (I mean, the size of the provided vector of initial currents) will be m or m-1. In case it is m-1 it will assume i[m]=sum(i[k], k in 1:m-1).

AHaumer commented 2 weeks ago

In MSL we try to keep the models as general as possible without restricting the freedom of usage. I still doubt that we can cover all possible cases without restriction and without confusing the user:

In the first case (m wires, no neutral) I wouldn't initialize one (may be the last) current to -sum(all other initial currents), this easily leads to numerical problems. We have to leave this up to the tool.

Specifying an array of initial currents i0[m-1] or i0[m] looks clumsy compared to the initialization menu presented automatically due to the alias variable.

We should also take care of the following facts:

I'm not sure whether we don't forget a special case which is not covered by the solution. What's about polyphase inductors used as subcomponents in transformers, machines, lines, .... So why not leave it to the user to initialize the currents with initial equations? The user should know his system and therefore also know how to initialize the whole system.

ceraolo commented 2 weeks ago

In MSL we try to keep the models as general as possible without restricting the freedom of usage. I still doubt that we can cover all possible cases without restriction and without confusing the user:

I understand this. Two notes:

So, any "restriction" in Polyphase is not restriction in general since we have individual components from Analog.Basic. Whenever Polyphase usage tends to become tricky, there is for the user this fallback option.

In reality, in the first version of my message I intended to propose a solution that allowed users to choose the wires to which to set initial values (the remaining to be computed by the tool). It was easy-peasy also from the GUI point of view. Later I thought that it was overkill, for me.

This solution involved the user to input two arrays, one with the currents, the other with the indexes. the array would have m or m-1 elements: the tool will act correspondingly. It was still user's responsibility to decide whether to select m-sized arrays or m-1.

My position is that there must be a balance between generality and ease of use. That's why I finally resorted to propose that the balance current be always the m-th.

But I'm not against the other way that I myself initially conceived.

casella commented 2 days ago

As a general comment, I think that for consistency reasons, the Polyphase components should be usable as much as possible in the same way as the the regular, single-phase components, that have been around for 20+ years without anybody complaining.

If I double-click on an instance of Modelica.Electrical.Analog.Basic.Inductor with any Modelica tool, I get a parameter dialog with one field for the L parameter and one field where I can change the start attribute from the default value of 0 and I can additional set the fixed attribute.

If I double-click on an instance of Modelica.Electrical.Polyphase.Basic.Inductor, I get fields to set the number of phases and the array of inductances of each phase, but no provisions for initialization. The model is implemented by connecting an array of regular inductors between the two ports, so setting these values manually in the source code is quite tricky, as you need to figure out the implementation first, and then to apply array (or each) modifiers to a subcomponent, e.g.:

Modelica.Electrical.Polyphase.Basic.Inductor myInductor1(inductor(i(each start = 1, each fixed = true)));
Modelica.Electrical.Polyphase.Basic.Inductor myInductor2(inductor(i(start = {1, 2, 3}, fixed = {true, true, false}));

This goes against the principle of encapsulation, I think one should be able to use the polyphase inductor without the need to understand how it is implemented. In any case, writing that code is tricky and unnecessarily unconfortable for beginners, that would just like to use the GUI without delving into the intricacies of Modelica syntax and lots of silly parentheses 😃.

So, I'd say that we need to provide some infrastructure that allows to set the start and fixed attribute of none, m-1, or m currents easily in the parameter input window of the polyphase inductor. Advanced users could also write initial equations (in that case the fixed attribute should be set to false) but we shouldn't force beginners to do that, if they simply want to set some initial value. Again, writing syntactically correct Modelica code in such cases involving arrays is not entirely trivial.

If we agree on this requirement, I see two ways of implementing it.

1. Using the GUI to set fixed/start attributes

This is the way that requires minimal intervention on the MSL source code. Inside Modelica.Electrical.Polyphase.Basic.Inductor we can define the following alias variable:

  Modelica.Units.SI.Current i[m](start = fill(0, m), fixed = fill({false, m}) = inductor.i;

The GUI will see this variable with start and fixed modifiers and automatically generate the fields in the parameter input window to change them, as it already happens with the single-phase inductor. This is maximally flexible, as the user can provide any combination of start values and decide which phases should be fixed and which should not. Last, but not least, if the default values are kept, then the behaviour is the same that we have now, so it would be backwards compatible.

If this feature is used, fixed = true attributes will generate the corresponding initial equations, while the start attributes set on the three-phase component modifier should have higher priority than the default bindings set in the underlying inductor[3] array, according to the rules of MLS Sec. 8.6.2, so they should be used as guess values in case one wants to write non-trivial initial equations (e.g. steady-state)

2. Definining parameters to set fixed/start attributes

Alternatively, we could define parameters in Modelica.Electrical.Polyphase.Basic.Inductor, such as i_start and i_fixed, then propagate them to the inductor array implementation, e.g.

  Modelica.Units.SI.Current i_start[m] = fill(0, m) annotation(group = "Initialization");
  Boolean i_fixed = fill(false, m) annotation(group = "Initialization");
  ...
  Modelica.Electrical.Analog.Basic.Inductor inductor[m](start = i_start, fixed = i_fixed, L = L);
  ...

In principle we should make the modifiers on the inductor array final, but this would break backwards compatibility if someone actually set the initial values by appling modifers to them, so I'd leave the as non-final.

Decision

I am personally in favour of the first solution, because it needs less code and is more consistent with the single-phase components. But I'd like to hear your opinion.