Redeclare model with "outer" parameters

Viewed 112

I tried redeclare model that contain global (outer) parameter. Here simple example of my code:

package tests

model M0
  inner parameter Real a = 1;
end M0;
 
model M1
  extends tests.M0;
  replaceable tests.M3 c;
end M1;

model M2
  outer constant Real a;
end M2;

model M3
  extends tests.M2;
  Real b;
equation
  b = a;
end M3;

model M4
  extends tests.M2;
  Real b2;
  equation
  b2 = a;
end M4;


model test1
  tests.M1 X;
end test1;

model test2
  tests.M1 X(redeclare each tests.M4 c);
end test2;


end tests;

Test1 works fine, but with test2 I have warning An inner declaration for outer component a could not be found and was automatically generated. Without "inner/outer" all works fine. The warning occurs even if M3 and model M4 have identically code

model M3 // and M4
  outer constant Real a;
  Real b;
  equation
  b = a;
end M3;

or if redeclare the same model

model test3
  tests.M1 X(redeclare tests.M3 c);
end test3;

I am using OM 1.18

2 Answers

The issue seems to be that b is defined in M3 but not in M4. Modifying M4 to

model M4
  extends tests.M2;
  Real b, b2;
equation 
  b = a;
  b2 = a;
end M4;

or

model M4
  extends tests.M2;
  Real b;
equation 
  b = a;
end M4;

removes the respective warnings in Dymola.

This comes down to plug-compatibility, which in this example means, that every public variable in M3 must be present in M4 as well.

As plug-compatibility only refers to public variables, defining b to be protected in M3 should also resolve the issue:

model M3
  extends tests.M2;
protected 
  Real b;
equation 
  b = a;
end M3;

Note: I didn't test it with OpenModelica...

Your code works in Dymola, even though there is one issue:

In M0 you declared a as a parameter

inner parameter Real a = 1;

But in M2 you are looking for a constant

outer constant Real a;

Both tools don't care much about that fact, which seems strange.

In OpenModelica I guess you have hit a bug. You are using inner/outer in an uncommon way. Changing your setup to a more common style with the inner variable defined in a top-level-component (now named World) works:

package tests

model World
  inner parameter Real a = 1;
end World;

model M1
  replaceable tests.M3 c;
end M1;

model M2
  outer World w;
  parameter Real a = w.a;
end M2;

model M3
  extends tests.M2;
  Real b;
equation 
  b = a;
end M3;

model M4
  extends tests.M2;
  Real b2;
equation 
  b2 = a;
end M4;

model test1
  inner World w;
  tests.M1 X;
end test1;

model test2
  inner World w;
  tests.M1 X(redeclare each tests.M4 c);
end test2;

end tests;
Related