Search code examples
modelingmodelicaopenmodelica

No corresponding inner declaration found for (Modelica inner/outer)


I have recently started using Modelica (OpenModelica) as a modeling tool and I am facing a problem regarding the use of inner/outer functionalities. I am trying to create an environment model containing values for ambient temperature and pressure, so that other models can use this values. I have tried to do so with inner and outer keywords but I keep receiving the following warning:

No corresponding 'inner' declaration found for component .Real component.T0 declared as 'outer '. The existing 'inner' components are: .Real ambient.T0; defined in scope: Test.Ambient. Check if you have not misspelled the 'outer' component name. Please declare an 'inner' component with the same name in the top scope. Continuing flattening by only considering the 'outer' component declaration.

Below these lines you can see a simplification of the code I am trying.

The three models below these lines are contained in a package named Test.

The model for ambient in which a temperature T0 is defined as inner:

within Test;

    model Ambient

        inner Real T0;

        equation
            T0 = 300;

end Ambient;

The model of a component that tries to call T0 via outer operator:

within Test;

model Component

    Real T;
    outer Real T0;
    parameter Real k = 2;

    equation
        T = k * time + T0;

end Component;

Both models ambient and component are dragged and dropped in the combined model:

within Test;

model System
  Test.Ambient ambient annotation(
    Placement(visible = true, transformation(origin = {-30, 30}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Test.Component component annotation(
    Placement(visible = true, transformation(origin = {30, -10}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
equation

end System;

When running System I get the aforementioned warning. Also, there is one variable more than equations (which makes sense since it is not being able to connect Component.T0 with Ambient T0)


Solution

  • Your use-case seems pretty similar to what is done in Modelica.Mechanics.MultiBody and Modelica.Fluid. In both cases, there is a class that contains all the "global" properties of the system, called world or system respectively.

    Therefore your class Ambient should defined to be an inner class. This is then accessed by an outer statement to re-use values from it. What would be possible when using your code, is to access T0 from models within Ambient. Judging from your example code this is not what you want...

    Applying the technique used in the MSL to your example, would result in the following code:

    package Test
    model Ambient
        inner Real T0;
      equation
        T0 = 300;
        annotation(defaultComponentPrefixes="inner");
    end Ambient;
    
    model Component
        Real T;
        Real T0 = ambient.T0;
        parameter Real k = 2;
      protected
        outer Test.Ambient ambient;
      equation
        T = k * time + T0;
    end Component;
    
    model System
      inner Test.Ambient ambient;
      Test.Component component;   
    end System;
    
    end Test;
    

    Some comments:

    • Accessing the variables with the outer statement is done in the protected part of the model, just to prevent to have the same variables multiple times in the result.
    • The defaultComponentPrefixes annotation ensures, that the model has the prefix inner in case a graphical instance is created (as it is shown in the model System).