OpenModelica / OMPython

A Python interface to OpenModelica communicating via CORBA or ZeroMQ
Other
102 stars 59 forks source link

feature request: add warning or error when using linearize() and --daeMode is set #211

Open martinscripts opened 5 months ago

martinscripts commented 5 months ago

Description

I worked with model.linearize() and only got zero-matrices. It took me a while to find out why. Turns out that this happens if the additional translation flag --daeMode is set.

It would be great if there was an error message that tells the user that this doesn't work. It took a while to find out 😺.

Version and OS

arun3688 commented 5 months ago

@martinscripts can you provide your use case for reporting error message, because as far I see even if you get only zero-matrices it means the linearized model is generated, we can report error if the linearized model is not generated, we can report errors if the flags are wrong, but the users must be aware of what flags they are using

martinscripts commented 5 months ago

maybe not an error, but a warning, in that case. my use case is that a warning like "zero matrix generated -- if unintended, check translation flags" or similar would have saved time when searching for the reason that linearization does not work.

For me individually this doesn't matter anymore because I solved it and know it now. But for other users it would be.

And yes, ideally everyone is aware of their settings. But for me, for example, I was not aware that the flag leads to a zero A-Matrix when using linearize().

It's just a suggestion. I think it would be beneficial.

arun3688 commented 5 months ago

@martinscripts do you want to generate warning if all the four matrices A, B, C and D are zero matrices, because it is possible that a matrix can be zero and that might be the expected result

martinscripts commented 5 months ago

I only want to report my experience with this behaviour.

I would leave it to you and the other developers if you want to act on it. You can judge it better than I can.

arun3688 commented 5 months ago

@martinscripts ok , so when linearizing we need to check if the flag --daeMode and regardless of the result, we might warn the users that this flag may cause wrong linearization result

martinscripts commented 5 months ago

@arun3688 yes, I think that would be helpful. Although I am not sure if the A=0 matrix is actually wrong or if I only don't understand the result of linearizing a DAE system properly here.

martinscripts commented 5 months ago

btw, thanks for your work. This is a very useful package. 💐

arun3688 commented 5 months ago

@martinscripts I am not an expert either regarding using the flag --daemode might have different linearization result. @casella can you please comment on this

casella commented 5 months ago

@arun3688 if --daeMode is selected the system is not brought into state-space form by the backend, so the information to get the A,B,C,D matrices of the linearized state-space form is missing.

We need to ensure that an error is generated when the linearize API is called in daeMode. I guess this goes beyond OMPython and is really a backend issue.

@kabdelhak, @phannebohm could you please take care of that?

casella commented 5 months ago

Here is an MWE demonstrating the issue: running this script

loadString("
model M
  input Real u;
  Real x(start = 1, fixed = true);
  output Real y;
equation
  der(x) = y + u;
  y = -2*x^2;
annotation(experiment(StopTime = 0));
end M;
");getErrorString();
// setCommandLineOptions("--daeMode");getErrorString();
linearize(M);getErrorString();

produces the following linearized model, which is correct up to the numerical differentiation approximation

model linearized_model "M"
  parameter Integer n = 1 "number of states";
  parameter Integer m = 1 "number of inputs";
  parameter Integer p = 1 "number of outputs";
  parameter Real x0[n] = {1};
  parameter Real u0[m] = {0};

  parameter Real A[n, n] =
    [-4.000000265312882];

  parameter Real B[n, m] =
    [1.000000001354202];

  parameter Real C[p, n] =
    [-4.000000265312882];

  parameter Real D[p, m] =
    [0];

  Real x[n](start=x0);
  input Real u[m](start=u0);
  output Real y[p];

  Real 'x_x' = x[1];
  Real 'u_u' = u[1];
  Real 'y_y' = y[1];
equation
  der(x) = A * x + B * u;
  y = C * x + D * u;
end linearized_model;

However, if I add --daeMode

loadString("
model M
  input Real u;
  Real x(start = 1, fixed = true);
  output Real y;
equation
  der(x) = y + u;
  y = -2*x^2;
annotation(experiment(StopTime = 0));
end M;
");getErrorString();
setCommandLineOptions("--daeMode");getErrorString();
linearize(M);getErrorString();

I get this result

model linearized_model "M"
  parameter Integer n = 1 "number of states";
  parameter Integer m = 1 "number of inputs";
  parameter Integer p = 1 "number of outputs";
  parameter Real x0[n] = {1};
  parameter Real u0[m] = {0};

  parameter Real A[n, n] =
    [0];

  parameter Real B[n, m] =
    [0];

  parameter Real C[p, n] =
    [0];

  parameter Real D[p, m] =
    [0];

  Real x[n](start=x0);
  input Real u[m](start=u0);
  output Real y[p];

  Real 'x_x' = x[1];
  Real 'u_u' = u[1];
  Real 'y_y' = y[1];
equation
  der(x) = A * x + B * u;
  y = C * x + D * u;
end linearized_model;

which is just plain wrong. Basically, the ABCD matrices are all zero because there is no information to compute them. In this case, I should instead get an error such as

Error: linearization is not available in --daeMode

instead.