Skip to content

Suport Modelica Standard Tables #117

@AnHeuermann

Description

@AnHeuermann

Is your feature request related to a problem? Please describe.

Currently around 37 models from the MSL are failing with an error about missing functions for Modelica Standard Tables. These functions are especially difficult, since they involve function calls to external C functions like ModelicaStandardTables_CombiTimeTable_minimumTime, ModelicaStandardTables_CombiTimeTable_maximumTime or ModelicaStandardTables_CombiTimeTable_nextTimeEvent.

Describe the solution you’d like

There are two options:

a) Use https://github.com/OpenModelica/OMRuntimeExternalC.jl
b) Implement it directly in BaseModelica.jl.

For b) BaseModelica.jl needs to:

  1. Collect which C functions are needed and where the C sources / compiled libraries are located. E.g. the following Base Modelica specifies function ModelicaStandardTables_CombiTimeTable_minimumTime:

    function 'Modelica.Blocks.Tables.Internal.getTimeTableTmin' "Return minimum abscissa value of 1-dim. table where first column is time"
        input 'Modelica.Blocks.Types.ExternalCombiTimeTable' 'tableID';
        output Real 'timeMin';
      external "C" 'timeMin' = ModelicaStandardTables_CombiTimeTable_minimumTime('tableID') annotation(Library = {"ModelicaStandardTables", "ModelicaIO", "ModelicaMatIO", "zlib"}, LibraryDirectory = "modelica://Modelica/Resources/Library");
      end 'Modelica.Blocks.Tables.Internal.getTimeTableTmin';
  2. Compile the C sources into a shared library or have a precompiled version of shared library ModelicaStandardTables for the target system. OpenModelica uses a pre-compiled version of libModelicaStandardTables.so (or DLL, or static lib) that gets shipped with the installer, located in e.g. lib/x86_64-linux-gnu/omc/ffi/libModelicaStandardTables.so. But compiling libModelicaStandardTables isn't hard.

    run(`gcc -O2 -shared -fPIC -o libModelicaStandardTables.so ModelicaStandardTables.c`)
  3. Load the library

    using Libdl
    const libModelicaStandardTables = Libdl.dlopen("path/to/libModelicaStandardTables.so")
  4. Create Julia wrappers for all C functions needed by the model. E.g. for ModelicaStandardTables_CombiTimeTable_minimumTime:

    function ModelicaStandardTables_CombiTimeTable_minimumTime(tableID::Ptr{Cvoid})::Float64
        ccall(
            Libdl.dlsym(libModelicaStandardTables, :ModelicaStandardTables),
            Cdouble,        # return type: double
            (Ptr{Cvoid},),  # argument types: void*
            tableID         # argument value
        )
    end

Simple example

Here is a simpler example with a very basic external C function:

//! base 0.1.0
package 'ExponentialGrowth'
  function 'mult' "Multiply two doubles via external C function"
    input Real 'a';
    input Real 'b';
    output Real 'result';
  external "C" 'result' = mult('a', 'b') annotation(Library = {"mult"});
  end 'mult';

  model 'ExponentialGrowth' "dy/dt = p * y — exponential growth using external C mult"
    parameter Real 'p' = 0.5 "Growth rate";
    Real 'y'(start = 1.0) "State variable";
  equation
    der('y') = 'mult'('p', 'y');
  end 'ExponentialGrowth';
end 'ExponentialGrowth';

mult.c

double mult(double a, double b) {
    return a * b;
}

Additional context

Sub-issue of #24.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions