Search code examples
instantiationmodelica

Invalid Modelica model works fine when instantiated in another model. Why?


I have 2 Modelica models:

model parent
  child dingus;
equation 
  dingus.a = 37;
  dingus.c = 666;
end parent;

and

model child
  Real a;
  Real b;
  Real c;
equation 
  a^3 + b^3 + c^3 = 1;
end child;

When I check the code, parent checks out okay, but child gives errors about the mismatch of unknowns and equations, as expected. Why does it work in parent, and is there a cleaner, best practice way of implementing this? I want to use child in multiple different parents, and I may want to change how I interface with it so I don't want to overly define it.


Solution

  • Well, it should be clear that child is not balanced since, as you point out, it doesn't have the same number of equations as unknowns. The parent model is ok since it does have the same number of equations as unknowns. It gets one equation from child and provides two of its own. Since there are exactly three variables child.a, child.b and child.c, the whole thing is balanced.

    But the bigger picture issue (which I think is what you are trying to get at) is how to avoid issues where child looks like a "bad" model. A simple solution is:

    model child
      input Real a;
      output Real b;
      input Real c;
    equation 
      a^3 + b^3 + c^3 = 1;
    end child;
    

    This conveys the idea that values for a and c will come from "outside" somewhere.

    To anticipate your next question..."But what happens in cases when I want to specify b and c and solve for a? Surely I don't have to write another model with the same equations and variables but with the input and output qualifiers on different variables?"

    You can use the above model without issues. The reason is that the input and output qualifiers only restrict how things are connected. We aren't actually making any connections, so we are ok. So you can provide equations for an output and solve for an input. While it may seem a little counter intuitive, that is perfectly legal in Modelica. The reason that input and output are useful here is that they implicitly specify how many equations we expect this model itself to provide (the outputs) and how many we expect to come from outside (the inputs). But they don't (and can't) restrict which variables we provide explicit equations for.

    One final note, I suggest you add the equations for an instance of child in the declaration. I seem to recall there were some special rules in Modelica for handling this when determining whether something is balanced. So as far as I recall, the correct way to approach this would be:

    model child
      input Real a;
      input Real b;
      output Real c; // A bit arbitrary which one is output
    equation 
      a^3 + b^3 + c^3 = 1;
    end child;
    
    model parent
      child dingus(a=37, c=666);
    end parent;
    

    In this way, you can treat child as what amounts to a "named equation". Even better, you can make it replaceable which allows you to swap it for others. A typically application of this would be to substitute one equation of state for another or one equilibrium condition for another.

    Hope that helps.