Archived OpenModelica forums. Posting is disabled.

Alternative forums include GitHub discussions or StackOverflow (make sure to read the Stack Overflow rules; you need to have well-formed questions)


Forgot password? | Forgot username? | Register

No matching function found

No matching function found

Dear community,

for my project I need to implement an function inversion algorithm. The functions are given in the form p=p(T, omega) and I need to solve for omega. This problem can be easily formulated as a root finding problem, which in turn can be solved by Modelica's Math.Nonlinear.solveOneNonlinearEquation - at least so I thought.

When I run the check model command I get the following error code, which does not make any sense to me:

Code:

[C:\\OpenModelica1.9.1Beta2\\lib\\omlibrary\\Modelica 3.2.1\\Math\\Nonlinear.mo:405:3-423:28:writable] Warning: Forcing full instantiation of partial class partialScalarFunction during checkModel.

[D:\\documents\\university\\modelica\\openModelica\\MetalHydrideStorage.mo:44:9-44:136:writable] Error: No matching function found for Modelica.Math.Nonlinear.solveOneNonlinearEquation(function MetalHydrideStorage.Materials.TestModel.material.equilibriumLoadingAdsorptionDummy(s), 0, 0.02, 1e-006)
of type
  .Modelica.Math.Nonlinear.solveOneNonlinearEquation<function>(.MetalHydrideStorage.Materials.TestModel.material.equilibriumLoadingAdsorptionDummy<function>(#Real u) => #Real f, Integer u_min, Real u_max, Real tolerance := 1e-013) => Real in component <NO COMPONENT>
candidates are
  .Modelica.Math.Nonlinear.solveOneNonlinearEquation<function>(.Modelica.Math.Nonlinear.Interfaces.partialScalarFunction<function>(Real u) => Real f, Real u_min, Real u_max, Real tolerance := 1e-013) => Real
Error: Error occurred while flattening model MetalHydrideStorage.Materials.TestModel

As far as I'm concerned those functions should match.

Here's the problematic part of my Modelica code:

Code:


  record State
    SI.Temperature T;
    SI.AbsolutePressure p;
    Real omega;
  end State;
 
replaceable function equilibriumPressureAdsorption
    input State s;
    output SI.Pressure p_eq;
  end equilibriumPressureAdsorption;

  function equilibriumLoadingAdsorption "Uses modelica's root finding algorithm to calculate the equilibrium loading based on the equilibrium pressure function"
    input State s;
    output Real omega_eq;
  algorithm
    omega_eq:=Modelica.Math.Nonlinear.solveOneNonlinearEquation(function equilibriumLoadingAdsorptionDummy(s = s), 0, 0.02, 1e-006);
  end equilibriumLoadingAdsorption;

  function equilibriumLoadingAdsorptionDummy
    extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
    input State s;
  algorithm
    y:=equilibriumPressureAdsorption(State(T = s.T, p = s.p, omega = u)) - s.p;
  end equilibriumLoadingAdsorptionDummy;

I tried all day to find a solution for this error, but no matter what I tried, it didn't go away. Also I could not find any resources for this type of problem.

Does anyone of you have any ideas what might cause this error?

Re: No matching function found

What OpenModelica revision did you run this in? The following works fine for me using r21721:

Code:

model M

  import SI = Modelica.SIunits;
  record State
    SI.Temperature T;
    SI.AbsolutePressure p;
    Real omega;
  end State;

replaceable function equilibriumPressureAdsorption
    input State s;
    output SI.Pressure p_eq;
  end equilibriumPressureAdsorption;

  function equilibriumLoadingAdsorption "Uses modelica's root finding algorithm to calculate the equilibrium loading based on the equilibrium pressure function"
    input State s;
    output Real omega_eq;
  algorithm
    omega_eq:=Modelica.Math.Nonlinear.solveOneNonlinearEquation(function equilibriumLoadingAdsorptionDummy(s = s), 0, 0.02, 1e-006);
  end equilibriumLoadingAdsorption;

  function equilibriumLoadingAdsorptionDummy
    extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
    input State s;
  algorithm
    y:=equilibriumPressureAdsorption(State(T = s.T, p = s.p, omega = u)) - s.p;
  end equilibriumLoadingAdsorptionDummy;

  Real r = equilibriumLoadingAdsorption(State(time,2,3));
  annotation(uses(Modelica(version="3.2.1")));
end M;

Re: No matching function found

Hey sjoelund.se

Thank you for your quick reply.
I downloaded OpenModelica just a couple of days ago so I'm running OpenModelica 1.9.1 Beta2 (r19512), which was the standard download at the openModelica website at the time. Do you think I should use an other version?

BTW: I re-ran your code and it produced the same error as before.

Re: No matching function found

Use the latest nightly build instead; it has many fixes regarding function partial application.

Re: No matching function found

I downloaded the latest nightly (OpenModelica 1.9.1+dev (r21723) (RML version)). The code still does not work - the error message has changed slightly though.

Your code snipped was compiled to:

 Spoiler Show Spoiler Hide Spoiler
 

Code:

 function MetalHydrideStorage.M.State "Automatically generated record constructor for MetalHydrideStorage.M.State"

  input Real T(quantity = "ThermodynamicTemperature", unit = "K", min = 0.0, start = 288.15, nominal = 300.0, displayUnit = "degC");
  input Real p(min = 0.0, nominal = 100000.0, quantity = "Pressure", unit = "Pa", displayUnit = "bar");
  input Real omega;
  output State res;
end MetalHydrideStorage.M.State;

function MetalHydrideStorage.M.equilibriumLoadingAdsorption "Uses modelica's root finding algorithm to calculate the equilibrium loading based on the equilibrium pressure function"
  input MetalHydrideStorage.M.State s;
  output Real omega_eq;
algorithm
  omega_eq := Modelica.Math.Nonlinear.solveOneNonlinearEquation(function MetalHydrideStorage.M.equilibriumLoadingAdsorptionDummy(.MetalHydrideStorage.M.State(#(s.T), #(s.p), #(s.omega))), 0.0, 0.02, 1e-006);
end MetalHydrideStorage.M.equilibriumLoadingAdsorption;

function MetalHydrideStorage.M.equilibriumLoadingAdsorptionDummy
  input Real u "Independent variable";
  output Real y "Dependent variable y=f(u)";
  input MetalHydrideStorage.M.State s;
algorithm
  y := MetalHydrideStorage.M.equilibriumPressureAdsorption(MetalHydrideStorage.M.State(s.T, s.p, u)) - s.p;
end MetalHydrideStorage.M.equilibriumLoadingAdsorptionDummy;

function MetalHydrideStorage.M.equilibriumPressureAdsorption
  input MetalHydrideStorage.M.State s;
  output Real p_eq(quantity = "Pressure", unit = "Pa", displayUnit = "bar");
end MetalHydrideStorage.M.equilibriumPressureAdsorption;

function Modelica.Math.Nonlinear.solveOneNonlinearEquation "Solve f(u) = 0 in a very reliable and efficient way (f(u_min) and f(u_max) must have different signs)"
  input f<function>(#Real u) => #Real f "Function y = f(u); u is computed so that y=0";
  input Real u_min "Lower bound of search interval";
  input Real u_max "Upper bound of search interval";
  input Real tolerance = 1e-013 "Relative tolerance of solution u";
  output Real u "Value of independent variable u so that f(u) = 0";
  protected constant Real eps = 1e-015 "machine epsilon";
  protected Real c "Intermediate point a <= c <= b";
  protected Real d;
  protected Real e "b - a";
  protected Real m;
  protected Real s;
  protected Real p;
  protected Real q;
  protected Real r;
  protected Real tol;
  protected Real fa "= f(a)";
  protected Real fb "= f(b)";
  protected Real fc;
  protected Boolean found = false;
  protected Real a = u_min "Current best minimum interval value";
  protected Real b = u_max "Current best maximum interval value";
algorithm
  fa := unbox(f(#(u_min)));
  fb := unbox(f(#(u_max)));
  fc := fb;
  if fa > 0.0 and fb > 0.0 or fa < 0.0 and fb < 0.0 then
    Modelica.Utilities.Streams.error("The arguments u_min and u_max provided in the function call
        solveOneNonlinearEquation(f,u_min,u_max)
    do not bracket the root of the single non-linear equation 0=f(u):
      u_min  = " + String(u_min, 0, true, 6) + "
    " + "  u_max  = " + String(u_max, 0, true, 6) + "
    " + "  fa = f(u_min) = " + String(fa, 0, true, 6) + "
    " + "  fb = f(u_max) = " + String(fb, 0, true, 6) + "
    " + "fa and fb must have opposite sign which is not the case");
  end if;
  c := a;
  fc := fa;
  e := b - a;
  d := e;
  while not found loop
    if abs(fc) < abs(fb) then
      a := b;
      b := c;
      c := a;
      fa := fb;
      fb := fc;
      fc := fa;
    end if;
    tol := 2e-015 * abs(b) + tolerance;
    m := 0.5 * (c - b);
    if abs(m) <= tol or fb == 0.0 then
      found := true;
      u := b;
    else
      if abs(e) < tol or abs(fa) <= abs(fb) then
        e := m;
        d := e;
      else
        s := fb / fa;
        if a == c then
          p := 2.0 * m * s;
          q := 1.0 - s;
        else
          q := fa / fc;
          r := fb / fc;
          p := s * (2.0 * m * q * (q - r) - (b - a) * (-1.0 + r));
          q := (-1.0 + q) * (-1.0 + r) * (-1.0 + s);
        end if;
        if p > 0.0 then
          q := -q;
        else
          p := -p;
        end if;
        s := e;
        e := d;
        if 2.0 * p < 3.0 * m * q - abs(tol * q) and p < abs(0.5 * s * q) then
          d := p / q;
        else
          e := m;
          d := e;
        end if;
      end if;
      a := b;
      fa := fb;
      b := b + (if abs(d) > tol then d else if m > 0.0 then tol else -tol);
      fb := unbox(f(#(b)));
      if fb > 0.0 and fc > 0.0 or fb < 0.0 and fc < 0.0 then
        c := a;
        fc := fa;
        e := b - a;
        d := e;
      end if;
    end if;
  end while;
end Modelica.Math.Nonlinear.solveOneNonlinearEquation;

function Modelica.Utilities.Streams.error "Print error message and cancel all actions"
  input String string "String to be printed to error message window";

  external "C" ModelicaError(string);
end Modelica.Utilities.Streams.error;

class MetalHydrideStorage.M
  Real r = MetalHydrideStorage.M.equilibriumLoadingAdsorption(MetalHydrideStorage.M.State(time, 2.0, 3.0));
end MetalHydrideStorage.M;

And that's the new error message:

Code:

"[C:/OpenModelica1.9.1Nightly/lib/omlibrary/Modelica 3.2.1/Math/Nonlinear.mo:405:3-423:28:writable] Warning: Forcing full instantiation of partial class partialScalarFunction during checkModel.

[<interactive>:19:5-19:134:writable] Error: Type mismatch for positional argument 1 in Modelica.Math.Nonlinear.solveOneNonlinearEquation(f=function MetalHydrideStorage.M.equilibriumLoadingAdsorptionDummy(.MetalHydrideStorage.M.State(#(s.T), #(s.p), #(s.omega)))). The argument has type:
  .MetalHydrideStorage.M.equilibriumLoadingAdsorptionDummy<function>(#Real u) => #Real
expected type:
  .Modelica.Math.Nonlinear.Interfaces.partialScalarFunction<function>(Real u) => Real
Error: Error occurred while flattening model MetalHydrideStorage.M
"

What does the # mean?

Re: No matching function found

The # is an internal thing for handling calls to function pointers (all values are passed as a void*). The unbox() operation is the inverse.

Can you create a ticket at https://trac.openmodelica.org/OpenModelica/newticket? The problem seems to be related to checkModel() only. Instantiation and simulation works...

Re: No matching function found

Sure I can file a ticket. Although there still seems to be a problem with simulation:

Code:

MetalHydrideStorage.M_functions.o:MetalHydrideStorage.M_functions.c:(.text+0xfa7): undefined reference to `omc_MetalHydrideStorage_M_equilibriumPressureAdsorption'

collect2: ld returned 1 exit status
mingw32-make: *** [omc_main_target] Error 1
Compilation process exited with code 2

Honestly: I've got no clue what those error messages are telling me. I'm really thankful for your help!

Here's the full log - just in case...

 Spoiler Show Spoiler Hide Spoiler
 

Code:

"C:\OpenModelica1.9.1Nightly\\MinGW\bin\mingw32-make.exe" -j4 -f MetalHydrideStorage.M.makefile

gcc   -falign-functions -msse2 -mfpmath=sse     -I"C:/OpenModelica1.9.1Nightly//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME  -c -o MetalHydrideStorage.M.o MetalHydrideStorage.M.c
gcc   -falign-functions -msse2 -mfpmath=sse     -I"C:/OpenModelica1.9.1Nightly//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME  -c -o MetalHydrideStorage.M_functions.o MetalHydrideStorage.M_functions.c
gcc   -falign-functions -msse2 -mfpmath=sse     -I"C:/OpenModelica1.9.1Nightly//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME  -c -o MetalHydrideStorage.M_records.o MetalHydrideStorage.M_records.c
gcc   -falign-functions -msse2 -mfpmath=sse     -I"C:/OpenModelica1.9.1Nightly//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME  -c -o MetalHydrideStorage.M_01exo.o MetalHydrideStorage.M_01exo.c
gcc   -falign-functions -msse2 -mfpmath=sse     -I"C:/OpenModelica1.9.1Nightly//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME  -c -o MetalHydrideStorage.M_02nls.o MetalHydrideStorage.M_02nls.c
gcc   -falign-functions -msse2 -mfpmath=sse     -I"C:/OpenModelica1.9.1Nightly//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME  -c -o MetalHydrideStorage.M_03lsy.o MetalHydrideStorage.M_03lsy.c
gcc   -falign-functions -msse2 -mfpmath=sse     -I"C:/OpenModelica1.9.1Nightly//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME  -c -o MetalHydrideStorage.M_04set.o MetalHydrideStorage.M_04set.c
gcc   -falign-functions -msse2 -mfpmath=sse     -I"C:/OpenModelica1.9.1Nightly//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME  -c -o MetalHydrideStorage.M_05evt.o MetalHydrideStorage.M_05evt.c
gcc   -falign-functions -msse2 -mfpmath=sse     -I"C:/OpenModelica1.9.1Nightly//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME  -c -o MetalHydrideStorage.M_06inz.o MetalHydrideStorage.M_06inz.c
gcc   -falign-functions -msse2 -mfpmath=sse     -I"C:/OpenModelica1.9.1Nightly//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME  -c -o MetalHydrideStorage.M_07dly.o MetalHydrideStorage.M_07dly.c
gcc   -falign-functions -msse2 -mfpmath=sse     -I"C:/OpenModelica1.9.1Nightly//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME  -c -o MetalHydrideStorage.M_08bnd.o MetalHydrideStorage.M_08bnd.c
gcc   -falign-functions -msse2 -mfpmath=sse     -I"C:/OpenModelica1.9.1Nightly//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME  -c -o MetalHydrideStorage.M_09alg.o MetalHydrideStorage.M_09alg.c
gcc   -falign-functions -msse2 -mfpmath=sse     -I"C:/OpenModelica1.9.1Nightly//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME  -c -o MetalHydrideStorage.M_10asr.o MetalHydrideStorage.M_10asr.c
gcc   -falign-functions -msse2 -mfpmath=sse     -I"C:/OpenModelica1.9.1Nightly//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME  -c -o MetalHydrideStorage.M_11mix.o MetalHydrideStorage.M_11mix.c
gcc   -falign-functions -msse2 -mfpmath=sse     -I"C:/OpenModelica1.9.1Nightly//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME  -c -o MetalHydrideStorage.M_12jac.o MetalHydrideStorage.M_12jac.c
gcc   -falign-functions -msse2 -mfpmath=sse     -I"C:/OpenModelica1.9.1Nightly//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME  -c -o MetalHydrideStorage.M_13opt.o MetalHydrideStorage.M_13opt.c
gcc   -falign-functions -msse2 -mfpmath=sse     -I"C:/OpenModelica1.9.1Nightly//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME  -c -o MetalHydrideStorage.M_14lnz.o MetalHydrideStorage.M_14lnz.c
gcc -I. -o MetalHydrideStorage.M.exe MetalHydrideStorage.M.o MetalHydrideStorage.M_functions.o MetalHydrideStorage.M_records.o MetalHydrideStorage.M_01exo.o MetalHydrideStorage.M_02nls.o MetalHydrideStorage.M_03lsy.o MetalHydrideStorage.M_04set.o MetalHydrideStorage.M_05evt.o MetalHydrideStorage.M_06inz.o MetalHydrideStorage.M_07dly.o MetalHydrideStorage.M_08bnd.o MetalHydrideStorage.M_09alg.o MetalHydrideStorage.M_10asr.o MetalHydrideStorage.M_11mix.o MetalHydrideStorage.M_12jac.o MetalHydrideStorage.M_13opt.o MetalHydrideStorage.M_14lnz.o -I"C:/OpenModelica1.9.1Nightly//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME -L"D:/documents/university/modelica/openModelica"  -lModelicaExternalC   -falign-functions -msse2 -mfpmath=sse     -L"D:/documents/university/modelica/openModelica" -L"C:/OpenModelica1.9.1Nightly//lib/omc" -L"C:/OpenModelica1.9.1Nightly//lib" -Wl,--stack,0x2000000,-rpath,"C:/OpenModelica1.9.1Nightly//lib/omc" -Wl,-rpath,"C:/OpenModelica1.9.1Nightly//lib"   -lregex -lexpat -lgc -lpthread -fopenmp -loleaut32  -lSimulationRuntimeC -lgc -lexpat -lregex -static-libgcc -luuid -loleaut32 -lole32 -lws2_32 -lsundials_kinsol -lsundials_nvecserial -lipopt -lcoinmumps -lpthread -lm -lgfortranbegin -lgfortran -lmingw32 -lgcc_eh -lmoldname -lmingwex -lmsvcrt -luser32 -lkernel32 -ladvapi32 -lshell32 -llapack-mingw -lcminpack -ltmglib-mingw -lblas-mingw -lf2c -linteractive -lwsock32 -llis -lstdc++
MetalHydrideStorage.M_functions.o:MetalHydrideStorage.M_functions.c:(.text+0xfa7): undefined reference to `omc_MetalHydrideStorage_M_equilibriumPressureAdsorption'
collect2: ld returned 1 exit status
mingw32-make: *** [omc_main_target] Error 1
Compilation process exited with code 2

Re: No matching function found

I did some experimenting around and stumbled upon a really weird issue.

I took you code and added one of the actual p(T,omega) functions:

Code:

model M

  import SI = Modelica.SIunits;

  record State
    SI.Temperature T;
    SI.AbsolutePressure p;
    Real omega;
  end State;

  function equilibriumPressureAdsorption
    input State s;
    output SI.Pressure p_eq;
  protected
    Real p1, p2;
    constant Real alpha = 0.5;
    constant Real a1 = -4.884, a2 = -2374.7, a3 = 3.4129 * 10 ^ (-3), a4 = 48.816, a5 = -50.404, a6 = 22.711, a7 = -7.9717, a8 = 1.233;
    constant Real b1 = -452.34, b2 = 15.522, b3 = 4.0954, b4 = -1.3222 * 10 ^ (-2), b5 = 1.4406 * 10 ^ (-5);
    Real omega = s.omega * 100;
  algorithm
    p1 := exp(a1 + a2 / s.T + a3 * s.T + a4 * omega ^ alpha + a5 * omega + a6 * omega ^ 2 + a7 * omega ^ 3 + a8 * omega ^ 4);
    p2 := exp(b1 + b2 * omega + b3 * s.T + b4 * s.T ^ 2 + b5 * s.T ^ 3);
    p_eq := p1 + p2;
  end equilibriumPressureAdsorption;

  function equilibriumLoadingAdsorption "Uses modelica's root finding algorithm to calculate the equilibrium loading based on the equilibrium pressure function"
    input State s;
    output Real omega_eq;
  algorithm
    omega_eq := Modelica.Math.Nonlinear.solveOneNonlinearEquation(function equilibriumLoadingAdsorptionDummy(s = s), 0, 0.02, 1e-006);
  end equilibriumLoadingAdsorption;

  function equilibriumLoadingAdsorptionDummy
    extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
    input State s;
  algorithm
    y := equilibriumPressureAdsorption(State(T = s.T, p = s.p, omega = u)) - s.p;
  end equilibriumLoadingAdsorptionDummy;

  Real r = equilibriumLoadingAdsorption(State(time * 100 + 273.15, 50, 0.01));
  Real b = equilibriumPressureAdsorption(State(time * 100 + 273.15, 50, 0.01));
  annotation(uses(Modelica(version = "3.2.1")));
end M;

When I run the code like that it works perfectly. But when I comment the line with Real b = ... it crashes with the same error as in my previous post.

It looks to me like there's something wrong with the compiler- or am I missing something here?

Re: No matching function found

It is something related to the dependency analysis of function calls: unused functions are removed from the C-code. Probably the partially evaluated function call is forgotten.

Re: No matching function found

I think I get it. At least I do have a feasible workaround now. Thank's a lot for your help!
I'll file a ticket for both the checkModel() and the function dependency issue.

There are 0 guests and 0 other users also viewing this topic
You are here: