Search code examples
cmodelicadymola

Minimal working example of returning multiple outputs from an external function in Modelica


My question is similar to this one Is it possible to return multiple values from an external file to Dymola? so here it goes:

How do I return multiple outputs from an external function without using a Record (if that's possible at all)? If it's not possible without using a Record - could you please explain how to do this with a Record? I'm relatively new to using external functions so I could be missing something pretty basic here.

I've written an example model (below) to hopefully give a fuller picture of what I'm trying to achieve.

Thank you in advance for your help with this!

model ExampleMultipleOutputs "Example model to output multiple values"

  parameter Real a = 1 "Example real parameter";
  parameter Integer b = 2 "Example integer parameter";

  Real y1 "Declare output y1";
  Real y2 "Declare output y2";
  Real y3 "Declare output y3";
protected 
  function threeOut "Output three Real values from external function"
    input Real a;
    input Integer b;

    output Real y1 "Output 1";
    output Real y2 "Output 2";
    output Real y3 "Output 3";

  external"C" three_Out(
        a,
        b);
    annotation (
      Include="
        
        void three_Out(double a, int b, double* y1, double* y2, double* y3){
               
            *y1 = a;
            *y2 = b;
            *y3 = a+a;  
        
        }
      ");
  end threeOut;

equation 
    (y1, y2, y3) = threeOut(a=a, b=b);

end ExampleMultipleOutputs;

The compiler message from this example model states that "dsmodel.c(69): error C2198: 'three_Out': too few arguments for call", which makes me think my C code isn't correct, the way I have the function set up is not correct, or all of the above. Highly possible because I don't write C often.


Solution

  • Not sure why this wasn't clicking a couple hours ago, but I found a solution that works. I just had to stare at this previous post for a bit longer. Hopefully this complete example will be helpful for others.

    model ExampleMultipleOutputs "Example model to output multiple values"
    
      parameter Real a = 1 "Example real parameter";
      parameter Integer b = 2 "Example integer parameter";
    
      record recDef
        Real y1 "Declare output y1";
        Real y2 "Declare output y2";
        Real y3 "Declare output y3";
      end recDef;
    
      recDef rec;
    protected 
      function threeOut "Output three real values from external function"
        input Real a;
        input Integer b;
    
        output recDef r;
      external"C" three_Out(a,b,r);
        annotation (
          Include="
          
            struct point{
              double y1;
              double y2;
              double y3;
            };
          
            void three_Out(double a, int b, void* result){
                struct point *pt = result;     
                pt->y1 = a;
                pt->y2 = a+a;  
                pt->y3 = a+a+a; 
            
            };
          ");
      end threeOut;
    
    
    equation 
        rec = threeOut(a=a, b=b);
    
    end ExampleMultipleOutputs;