Opened 5 years ago
Last modified 3 years ago
#5813 new defect
Improve selection of start attributes for alias variables
Reported by: | Francesco Casella | Owned by: | Francesco Casella |
---|---|---|---|
Priority: | critical | Milestone: | |
Component: | Backend | Version: | |
Keywords: | Cc: | Karim Adbdelhak, Andreas Heuermann, Adrian Pop, Per Östlund, Philip Hannebohm, adrien.guironnet@…, Rüdiger Franke |
Description (last modified by )
The selection of start attributes in alias variable sets is a crucial issue: oftentimes one element of the alias variable set has a carefully user-selected value, while the other ones have default values. It is of paramount importance that the user-selected value is used by the back-end, e.g. to set up the initial guess of iterative solvers, and that this value is not overridden by other less relevant defaults.
This issue has been well-known in the Modelica community for a long time, and actually brought to Section 8.6.2 of the Modelica specification. However, it seems to me that the criterion put forward there doesn't cover all the cases satisfactorily. This leads to the detection of start value conflicts which aren't really there, or (worse) to the selection of the wrong start values, which is what I am constantly experiencing with steam power plant models.
Consider the following examples
package Aliases type Temperature = Real(start = 300, unit="K"); type Power = Real(unit="W"); connector Port Temperature T; flow Power Q; end Port; model TemperatureSource parameter Temperature Tstart = 320; Temperature T1; Temperature T2(start = 310); Temperature T3(start = Tstart); Port port; equation port.T = T1; T1 = T2; T2 = T3; T1+1e-6*sin(T1) = 300 "Implicit equation on T1"; end TemperatureSource; model PowerSource parameter Temperature Tstart = 320; Port port; Temperature T1; Temperature T2(start = 330); Temperature T3(start = Tstart); equation port.T = T1; T1 = T2; T2 = T3; port.Q - (port.T-300) = sin(time); end PowerSource; model WrappedTemperatureSource parameter Temperature Tstart = 345; Port port; TemperatureSource ts(Tstart = Tstart); equation connect(ts.port, port); end WrappedTemperatureSource; model WrappedPowerSource parameter Temperature Tstart = 345; Port port; PowerSource ps(Tstart = Tstart); equation connect(ps.port, port); end WrappedPowerSource; model System1 TemperatureSource ts; PowerSource ps; equation connect(ts.port,ps.port); end System1; model System2 TemperatureSource ts(Tstart = 350); PowerSource ps; equation connect(ts.port,ps.port); end System2; model System3 TemperatureSource ts(T1(start = 360)); PowerSource ps; equation connect(ts.port,ps.port); end System3; model System4 WrappedTemperatureSource ts(Tstart = 370); PowerSource ps; equation connect(ts.port,ps.port); end System4; model System5 TemperatureSource ts; WrappedPowerSource ps(Tstart = 380); equation connect(ts.port, ps.port); end System5; model System6 WrappedTemperatureSource ts(ts(T1(start = 390))); WrappedPowerSource ps(Tstart = 400); equation connect(ts.port, ps.port); end System6; end Aliases;
At the end of the day, after alias elimination, each of these models has two unknowns: a power flow and a temperature. Everything else are aliases.
As an end-user and library developer, I would like the following start values to be selected for the temperature:
- System1: 320
- System2: 350
- System3: 360
- System4: 370
- System5: 380
- System6: 390
As far as I understand, the current rules of Section 8.6.2 do not guarantee these choices are taken. In fact, with the current 1.16.0-dev version of OMC, I get:
- System1: 330
- System2: 330
- System3: 330
- System4: 330
- System5: 300
- System6: 330
which is never the value I would expect. I haven't checked with Dymola yet, but I suspect the results will be similar.
We should
- figure out rules to guarantee those choices are made
- understand how to collect the relevant information in the frontend and pass it to the backend
- promote a discussion with the MAP-LIB and MAP-LANG projects to standardize the solution
Regarding point 1, I have some loosely formulated requirements, but they need to be formalized into actual rules for the compiler
- type defaults have the lowest priority, they should only be used if there are no other start value specification overriding them
- start values set by modifications when instantiating components should have higher priority than start values set by default binding equations in component declarations
- the priority of start values given by parameters should be determined on the basis of where the actual parameter value is specified
- direct specifications of the start value from the top level of the model to be simulated via nested modifiers should have the precedence over the other start values specified insied the lower-level components
- even in case the parameters are evaluated, the priority information should be computed by the frontend (particularly when evaluating parameters!) and then passed along to the backend, in order to be able to make the correct choices when performing alias elimination
Any ideas/comments?
Attachments (1)
Change History (14)
comment:1 by , 5 years ago
Description: | modified (diff) |
---|
comment:2 by , 5 years ago
Description: | modified (diff) |
---|
by , 5 years ago
Attachment: | Aliases.mo added |
---|
comment:3 by , 5 years ago
Milestone: | Future → 1.16.0 |
---|---|
Priority: | high → critical |
comment:5 by , 5 years ago
Replying to adrpo:
However, I have no idea if this is set properly by the old/new front-ends, one needs to check it.
It's not used by the new frontend, it always just uses the "default" value for DAE.BindingSource when creating the DAE. It does keep track of which scope a binding comes from though, so I think we can check if a start value comes from the declaration by just checking if the component itself is the scope. If that doesn't work for some reason we can just add the information to the bindings themselves. The backend doesn't seem to use this information for anything though.
Edit: I reread what you wrote and realised I'd missed that we also store this information in the DAE.VariableAttribute. That one might be used by the backend, grepping for startOrigin does give a lot of matches in the backend at least.
comment:6 by , 5 years ago
@Karim, @AnHeuermann, it would be good if you could make a quick check of what the DAE.VariableAttribute contains in the six examples I prepared, and see if there is some simple rule that you can provisionally implement that guarantees that most of the values I'd expect are actually selected.
Then, we can see what impact this has on the testsuite ad on the FlexiCaL model. I guess it could be quite positive.
comment:7 by , 5 years ago
Cc: | added |
---|
comment:9 by , 4 years ago
Cc: | added |
---|---|
Component: | *unknown* → Backend |
I am currently working on test cases using the PowerGrids library. It is not yet publicly available, but it will soon be, and I can share it if necessary. Initialization is a crucial issue in that library, and handled systematically according to a fundamental principle which is discussed in this paper: start values are relevant only for variables that influence the Jacobian, i.e. that appear in a nonlinear fashion in the residuals.
In the case of power system models, this principle is very useful to avoid the need of setting start values on each and every variable of each and every model, which would be extremely tedious and make the code unnecessarily cumbersome. In particular, no start values are explicitly set for variables that appear in linear models, such as transmission lines and saturation-less transformers. Even in the case that some start values are computed (e.g. those of port variables, which are always computed in the base OnePortAC
and TwoPortAC
classes), one may not bother to set the power flow parameter values for linear components such as transmission lines or buses, since those values would only affect start attributes of linear variables, that are irrelevant for convergence.
Conversely, models with nonlinear equation are designed so that all variables that appear nonlinearly in them are properly initialized, based on values provided by the power-flow parameters, i.e., voltage magnitude and angle, active and reactive power flows at the component port(s). For those nonlinear components, the power flow parameters are critical, and must be provided correctly.
Unfortunately, alias variable selection is still not up to the task, and it actually leads to generated code for which the initialization problem either does not converge at all, or it does, but in a much longer time than would be reasonable.
At this moment I cannot be more specific because of #5805, which prevents me to inspect the initial values that are actually used in a problem that is taking too long a time to be solved. However, I suspect that in some cases the confidence number criterion (which is not very good, see above) may lead to the selection of the start attribute of a variable appearing linearly in the equation, superseding the start attribute of the nonlinear variable which is most likely the meaningful one.
I need to be more precise in the analysis of my test case, and I'll be able to do that once #5805 is resolved. However, I would propose to introduce a selection heuristic that favours the start attributes of those variables in an alias set that appear nonlinearly in some equations, against those of variables that only appear linearly. This heuristic should probably be made optional at first. If people designed libraries and models according to the criterion of the above-mentioned paper, this would always work, but there may well be some cases where people added a start value on a linear alias, just because the tool at hand picked that variable as representative of the alias set. For sure, this heuristic is crucial for the proper operation of PowerGrids
.
comment:10 by , 4 years ago
Milestone: | 1.17.0 → 1.18.0 |
---|
Retargeted to 1.18.0 because of 1.17.0 timed release.
comment:13 by , 3 years ago
Cc: | added |
---|
@Karim, @rfranke, it seems that some consensus has beeen reached on how to solve this problem. Hans Olsson proposed an amendment to Section 8.6.2 that should give the expected result in all the cases I had in mind.
@rfranke, you can have a look at my examples in ticket MSL #3008 and see if you like my proposed outcomes.
@Karim, if MSL #3019 is merged in, you can implement those rules in the backend. For sure this will eliminate a lot of warnings about conflicting start values, and I guess it will also improve convergence on a lot of examples.
As far as I remember we do have the information on where a binding came from: a type or other origin.
Is the startOrigin present in the variable attributes for each type (Integer, Real, etc)
https://github.com/OpenModelica/OpenModelica/blob/master/OMCompiler/Compiler/FrontEnd/DAE.mo#L482
This could be used to avoid the bindings that come from types.
However, I have no idea if this is set properly by the old/new front-ends, one needs to check it.