- Index
- » Programming
- » Modelica Language
- » No matching function found
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;
- sjoelund.se
- 1700 Posts
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.
- sjoelund.se
- 1700 Posts
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:
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;
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...
- sjoelund.se
- 1700 Posts
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...
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.
- sjoelund.se
- 1700 Posts
- Index
- » Programming
- » Modelica Language
- » No matching function found