physicsmodelingmodelicaopenmodelica

Modelica: Pass a record based on a record interface to a function


I am trying to create a function which takes a record (CrossSection) as input. However, the passed record is derived from a record interface. It can be one of different available CrossSections. Defined like this:

package CrossSections  
  partial record CrossSection
    constant String name="Generic";
    parameter SI.Area area "cross sectional area";
  end CrossSection;

  record Circle
    extends CrossSection(name="Circle",    
      final area = (d/2)^2*Modelica.Constants.pi);
    parameter Modelica.Units.SI.Diameter d "Diameter of the cross section";  
  end Circle;
  
  record Rectangle
    parameter SI.Length a,b;
    extends CrossSection(name="Rectangle",
      final area = a*b);
  end Rectangle;
end CrossSections

Now my function would look something like this. Dependent on the passed CrossSection shape, different calculations shall be performed.

function foo
  input CrossSections.CrossSection cs;
  
  output Real o1;
  algorithm
    if Modelica.Utilities.Strings.isEqual("Circle", cs.name) then
      o1 := cs.area*3;
    elseif Modelica.Utilities.Strings.isEqual("Rectangle", cs.name) then
      o1 := cs.area*2;
    else
      o1 := cs.area*5;
    end if;
    return;
end foo;

However, in this scenario I get the error: Component 'cs' has partial type 'CrossSection'.

Also, changing the input to replaceable input... does not seem to do the trick.

How can one pass a record based on its interface?


Solution

  • You can create a local function and redeclare the input with the record you want to use:

      model Example
        Real r;
      protected 
        function local_foo = foo(redeclare input CrossSections.Circle cs);
      equation 
        r = local_foo(Circle(d=1));
      end Example;