I want to instantiate a complex model as a parameter in another model and initialize it within the initial equation section, like I am able to do with any Real parameter. For a simple Real parameter I would just write
parameter Real y(fixed = true);
indicating that y
should be computed at initialization time by using initial equations (to be defined...). But I can't do that for a complex model, i.e.
parameter ComplexModel m(fixed = true);
does not compile. Consider for example the following flat model
model FlatModel
parameter Real x = 4;
parameter Real y(fixed = false);
Real z;
// ... + many other model elements
initial equation
y*y = x;
// ... + many other equations
equation
z*z = 4*x;
end FlatModel;
Here the implicit solution y=2 is computed at initialization time whereas the solution z=4 is computed in a time dependent manner (at least in principle, possible optimizations notwithstanding...). But both represent basically the same quadratic relationship, so I want to encapsulate this equation into a separate model (note that not every such equation system is as simple as in this example):
model ComplexModel
Real x(fixed = false);
Real y(fixed = false);
equation
y * y = x;
end ComplexModel;
and try to use it this way:
model RefactoredFlatModel
parameter Real x = 4;
parameter Real y(fixed = false);
Real z;
parameter ComplexModel mStatic;
ComplexModel mDynamic;
initial equation
mStatic.x = x;
y = mStatic.y;
equation
mDynamic.x = 4*x;
z = mDynamic.y;
end RefactoredFlatModel;
But this doesn't seem to work (compiler reports overdertermined system). Checking the model flattened by the compiler shows why:
class FixedTests.RefactoredFlatModel
parameter Real x = 4.0;
parameter Real y(fixed = false);
Real z;
parameter Real mStatic.x(fixed = false);
parameter Real mStatic.y(fixed = false);
Real mDynamic.x(fixed = false);
Real mDynamic.y(fixed = false);
initial equation
mStatic.x = x;
y = mStatic.y;
equation
mStatic.y ^ 2.0 = mStatic.x;
mDynamic.y ^ 2.0 = mDynamic.x;
mDynamic.x = 4.0 * x;
z = mDynamic.y;
end FixedTests.RefactoredFlatModel;
So mStatic.y ^ 2.0 = mStatic.x
is put to the (time dependent) equation section instead of the initial equation section, where I wanted it to be. It is clear that the model is overdetermined because it tries to solve for mStatic.y in time although mStatic.y is a parameter and thus is time invariant.
Is there any way to tell the modelica compiler to turn equations into initial equations for parameter instances? Because otherwise it is not possible to define parameter instances of complex models implicitly.
As of Modelica Specification v3.4, this is invalid Modelica, since the prefix parameter
must not be used with the specialized class model
.
There are some proposals to improve this behavior (and meet your requirement), see https://github.com/modelica/ModelicaSpecification/issues/2311 and its source https://github.com/modelica/ModelicaStandardLibrary/issues/1860.