Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standardized annotations to select iteration variables and residuals #3578

Open
casella opened this issue Sep 26, 2024 · 13 comments
Open

Standardized annotations to select iteration variables and residuals #3578

casella opened this issue Sep 26, 2024 · 13 comments
Milestone

Comments

@casella
Copy link
Collaborator

casella commented Sep 26, 2024

Discussions about suggesting tearing variables in Modelica models have been carried out in the community around the late 2000's, in particular within the Modelica.Fluid group. Unfortunately, no consensus materialized back then. I now have some hard evidence that suggests we should introduce such a feature in the language.

Together with @matteodepascali, we recently developed an equation-based model of a solide-oxide fuel cell, which is then used for the modelling of an innovative type oxy-combution, CCUS power plant. The model of the fuel cell is publicly available on the https://github.com/looms-polimi/SOFCPoliMi repo and works both in Dymola and OpenModelica.

The steady-state initialization of that model proved to be a particularly hard problem, because of the strongly nonlinear equations related to energy balances, chemical reactions and electro-chemical reactions, including exponential Arrhenius-type terms. We eventually managed to successfully solve that problem by extensive use of homotopy. However, that was not enough, due to the fact that the medium models are given declaratively as implicit equations, not by functions as in Modelica.Media.

As expert thermo-fluid system modellers know very well, pressures, temperatures and compositions are the best candidates as tearing variables for models using ideal or real gas models, since most fluid properties can be computed explicitly starting from those variables. When we ran the model in Dymola, the tearing heuristics contained in there were good enough to figure that out automatically. Unfortunately, OpenModelica's tearing heuristics were not so good, so some strong components of the initialization problems got other variables as iteration variables such as density or specific volume, which was not a good choice and caused the iterative Newton solvers to fail miserably.

Now, OpenModelica has a vendor annotation __OpenModelica_tearingSelect, which works in the same spirit as the stateSelect attribute, and allows us modellers to tell the tool what we know well, i.e., that temperatures, pressures, compositions and currents (there is a fuel cell involved) make very good tearing variables. That worked quite well: those variables were chosen and lo and behold, Newton's algorithms converged happily.

My argument here is that tearingSelect need not be a vendor-specific annotation for several good reasons.

  1. As discussed above, expert modellers often know what are the best tearing variables, so there should be a way to convey this information to the Modelica tool, as in the cases of state selection, inlining, compile-time parameter evaluation, etc.
  2. Not being able to do so places an unnecessary burden on the shoulder of the tool developers, in order to successfully run a given model. As it is well-known, selection of tearing variables is an NP-complete problem for which good heuristics are required. Of course it's nice if a given tool figures them out automatically in previously unchartered territories, but there is no need to reinvent the wheel every time if good choices have been well known for ages.
  3. There could be cases in which the modeller has access to expert knowledge that the tool is not aware of, because it is not explicitly or implicitly conveyed by the Modelica code, e.g. about some functions being more nonlinear than others or having certain orders of magnitude; in these cases, tearingSelect attributes or annotations would the only way to convey that information to the tool
  4. Last, but not least, the indication of preferences for tearing variables is not a tool-specific issue to be handle by vendor annotations; it rather involves the inherent mathematical structure of the model, and the knowlegde thereof by the modeller.

In the reported SOFC case, tools other than OpenModelica may also actually benefit from such indication. BTW, I would invite other tool vendors to try it out themselves.

For all these reasons, I would suggest to introduce a tearingSelect attribute or annotation in Modelica, with the same values as stateSelect: TearingSelect.always, TearingSelect.prefer, TearingSelect.default, TearingSelect.avoid, TearingSelect.never. This would allow the modeller to propose the tool to use/not use certain variables as tearing variables, in case they are involved in implicit systems of equations and tearing is used to solve them.

I am not sure whether this would better be an annotation or attribute. I'm slightly in favour of attributes, because the aim and scope of tearingSelect is very similar to stateSelect, which is also an attribute. In both cases, the user is proposing to use certain variables as a starting point for computations that will become "more explicit" if they are used. Also, it would make it easily modifiable when extending or instantiating models.

Before starting a formal MCP process, I'd like to hear some feedback from the community, both from tool vendors and model developers.

@MartinOtter, @mtiller, @HildingElmqvist, @DagBruck, @HansOlsson, @maltelenz, @henrikt-ma, @kabdelhak, @phannebohm, @bernhardbachmann, @gkurzbach, @eshmoylova, @hubertus65, @arunkumar-narasimhan, @thorade, @GallLeo, @wischhusen feel free to comment on that or forward this proposal to interested colleagues for their comments.

@henrikt-ma
Copy link
Collaborator

Unfortunately SOFCPoliMi is rejected by System Modeler, so I can't evaluate how well our tearing works for these equation systems. It's a pity, because I would really have been interested in the result. Please let me know if you would like to sort out with us whether this is a problem with the System Modeler, the library, or the specification.

Anyway, I think we need to be very careful before giving users a chance to badly mess up their libraries by having tearingSelect attributes defined all over the place, introduced ages ago for some equation system appearing in a model nobody cares about anymore. Such attributes could really do damage to the tool logics we have today that work so well in so many cases.

This reminds me of the countless times I have seen libraries being destroyed by a stateSelect situation getting out of control. Sure, there are cases where stateSelect is used "properly" by a skilled modeler, but it is not a feature without downsides.

In one way, I am particularly afraid of TearingSelect.always and TearingSelect.never, due to the damage they could cause if when the equation system structure is changed. On the other hand, TearingSelect.always and TearingSelect.never would be the easiest ones to implement, as they would completely overrule existing heuristics instead of needing to be integrated in more balanced ways.

It should also be noted that tearing should already take start value prioritization into consideration. Are you sure that it is not by more careful selection of where to provide – as well as where not to provide – start-attributes that the OpenModelica tearing should be helped finding good solutions?

@thorade
Copy link
Contributor

thorade commented Sep 27, 2024

Modelon also has vendor annotations to select iteration variables and residual equations. A description of the syntax can be seen here:

I will ping the compiler team about this thread

@casella
Copy link
Collaborator Author

casella commented Sep 27, 2024

Unfortunately SOFCPoliMi is rejected by System Modeler, so I can't evaluate how well our tearing works for these equation systems. It's a pity, because I would really have been interested in the result. Please let me know if you would like to sort out with us whether this is a problem with the System Modeler, the library, or the specification.

I guess this may have been because of a some bogus HideResults annotations that a) used a parameter instead of a literal true or false constant, as mandated by the specification, and b) used an undefined parameter name. Both Dymola and OMC ignored that (OMC with a warning) and carried along, maybe System Modeller just stops there.

@henrikt-ma, I removed those annotations from the library, please try again. Happy to help if there are other issues, of course I'm interesting at having these tests running in as many tools as possible.

@casella
Copy link
Collaborator Author

casella commented Sep 27, 2024

Modelon also has vendor annotations to select iteration variables and residual equations.

Good to hear, so we already have 2 tools that do exactly the same thing with vendor annotations. Good argument in favour of standardizing it 😃

@HansOlsson
Copy link
Collaborator

Modelon also has vendor annotations to select iteration variables and residual equations.

Good to hear, so we already have 2 tools that do exactly the same thing with vendor annotations. Good argument in favour of standardizing it 😃

As far as I understand the 2 tools do different things (and not exactly the same thing):

OpenModelica has the possibility to influence the tearing-priority for variables, whereas Modelon's Optimica Toolkit has the possibility to select matching residuals and tearing-variables.

These are different things with different impacts (including different possibilities for misuse), and one of the issues is that what is easy to understand for users in terms of modifying tearing isn't necessarily the thing that works well in practice. (In particular whether you should select which variables to tear, or which ones to keep.)

Additionally a number of other issues impact tearing, so even if both had just changed priority it is not clear that it would have had the same result.

And I'm pleased that Dymola did the right thing without the need for hand-holding; but will, of course, try to make it better.

@casella
Copy link
Collaborator Author

casella commented Sep 27, 2024

Sure, things are a bit more complicated than what I wrote 😅 . As usual, we should try (if possible) to find some common ground.

From that point of view, it would be interesting to me to first understand how tools other than Dymola and OMC can handle my test model, which I found particularly tough to handle, and if a generic indication to prefer (maybe setting TearingSelect.always was a bit too strong) those variables helps in general. If that is the case, then I guess it will be reasonable to standardize this.

I understand very well that selecting some variables as tearing variables makes it easier to compute torn equations that are explicit in them. Conversely, I was not aware of the fact that some models benefit from specific tearing variable-residual pairings. Is there any publicly available document that shows some example of that?

BTW, what I understood from @phannebohm is that it may be more or less difficult to prefer (or avoid) certain variables as iteration variables, depending on how the tearing strategy is conceived. Maybe other tool developers can comment on that.

@hubertus65
Copy link
Member

Thanks, @casella, for bringing this up. We (Modelon) can speak with several years of experience with this, implemented this in a number of libraries, and I can say that the method works very well for us, and our customers. Problems that fail in other tools solve quickly and robustly with proper tearing annotations. That said: it is not trivial to use them correctly, but for library developers, they are great. In typical scenarios, they are not needed, and non-trivial to use for end users. I see this as an enabler for system-level steady-state design, not just initialization. That said: Not all models that are good or even great models for dynamic simulation are also the most useful models for steady-state design. BTW, I discussed this recently with @dzimmer, who has written papers about this in the past, and would also like to drive this discussion forward.

@hubertus65
Copy link
Member

BTW: I suggest to rename the issue to something else than the OM annotation, that coveres the general issue, such as: "Standardized annotations to select iteration variables and residuals "

@dzimmer
Copy link

dzimmer commented Sep 29, 2024

From a modeling point of view. It is good practice when the modeler can suggest a pair of a tearing variable and a matching residual. This is to some degree expressing a physical meaning. For instance:

  • tearing: acceleration, residual force -> means that the acceleration is expected to influence this force
  • tearing: mass flow rate, residual pressure -> meaning the mass flow rate is expected to influence the pressure response

If done so, the provision of this information can also lead to better diagnostics.

@HansOlsson
Copy link
Collaborator

From a modeling point of view. It is good practice when the modeler can suggest a pair of a tearing variable and a matching residual. This is to some degree expressing a physical meaning. For instance:

  • tearing: acceleration, residual force -> means that the acceleration is expected to influence this force
  • tearing: mass flow rate, residual pressure -> meaning the mass flow rate is expected to influence the pressure response

If done so, the provision of this information can also lead to better diagnostics.

I can understand that it can be helpful, and that's why I thought it important to highlight the difference w.r.t. just having tearing-select. However, I think more analysis is needed - in particular how often it is needed, how to detect misuse and whether some other (unknown) alternative would be better.

@HansOlsson
Copy link
Collaborator

BTW: I suggest to rename the issue to something else than the OM annotation, that coveres the general issue, such as: "Standardized annotations to select iteration variables and residuals "

Agreed (or create new issue).
I would prefer a more general: "Standardized way to select iteration variables and residuals "
Whether it uses annotations or some other mechanisms isn't set in stone.

@casella casella changed the title Introduce tearingSelect attribute/annotation Standardized annotations to select iteration variables and residuals Sep 30, 2024
@casella
Copy link
Collaborator Author

casella commented Sep 30, 2024

Problems that fail in other tools solve quickly and robustly with proper tearing annotations.

Good to hear.

That said: it is not trivial to use them correctly, but for library developers, they are great.

Same as stateSelect, which is obviously not something for the faint-hearted and only to be used where absolutely necessary.

I see this as an enabler for system-level steady-state design, not just initialization.

Sure.

That said: Not all models that are good or even great models for dynamic simulation are also the most useful models for steady-state design.

Agreed, though I see this point as orthogonal to the need of having means to steer the tearing selection mechanism. BTW, we did something along these lines in the forthcoming 2.0.0 version of the PowerGrids library, where we automatically build an embedded power flow model with simple static components and then use the results to initialize proper start values for the actual steady-state problem.

BTW, I discussed this recently with @dzimmer, who has written papers about this in the past, and would also like to drive this discussion forward.

Maybe we can have a short discussion next week in Hamburg? This seems like a very nice case of the need of coordinating MAP-Lang and MAP-Lib 😃

@HansOlsson HansOlsson added this to the 2024-October milestone Oct 1, 2024
@HansOlsson
Copy link
Collaborator

BTW: I checked the references (searching for something else) and found "Methods for Tearing Systems of Equations in Object-Oriented Modeling" by H. Elmqvist and M. Otter, from (ESM'94) (European Simulation Multiconference 1994), which used residue(x)=f(x) to introduce both a tearing variable and a residue equation (that may still work in Dymola).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants