Skip to content

Commit

Permalink
Fix forward declaration of C++ Functions in FMU export
Browse files Browse the repository at this point in the history
The functions may be accessed from closures,
see also new solveOneNonlinearEquationTest.
So far this only worked for simulations.
  • Loading branch information
rfranke committed Apr 19, 2023
1 parent 9796055 commit 364fdb4
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 4 deletions.
1 change: 0 additions & 1 deletion OMCompiler/Compiler/Template/CodegenCpp.tpl
Expand Up @@ -6543,7 +6543,6 @@ case SIMCODE(modelInfo=MODELINFO(__), extObjInfo=EXTOBJINFO(__)) then
#define BASECLASS ExtendedSystem
#endif
//Forward declaration to speed-up the compilation process
class Functions;
class EventHandling;
class DiscreteEvents;
<%algloopForwardDeclaration(listAppend(listAppend(allEquations, initialEquations), getClockedEquations(getSubPartitions(clockedPartitions))), simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace)%>
Expand Down
1 change: 0 additions & 1 deletion OMCompiler/Compiler/Template/CodegenCppOld.tpl
Expand Up @@ -6770,7 +6770,6 @@ case SIMCODE(modelInfo=MODELINFO(__), extObjInfo=EXTOBJINFO(__)) then
#include <Core/System/SystemDefaultImplementation.h>

//Forward declaration to speed-up the compilation process
class Functions;
class EventHandling;
class DiscreteEvents;
<%algloopForwardDeclaration(listAppend(listAppend(allEquations, initialEquations), getClockedEquations(getSubPartitions(clockedPartitions))), simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace)%>
Expand Down
4 changes: 3 additions & 1 deletion OMCompiler/Compiler/Template/CodegenFMUCpp.tpl
Expand Up @@ -111,13 +111,15 @@ template fmuCalcHelperMainfile(SimCode simCode)
#include <Core/Utils/extension/logger.hpp>

#include "OMCpp<%fileNamePrefix%>Types.h"
#include "OMCpp<%fileNamePrefix%>.h"
#include "OMCpp<%fileNamePrefix%>Functions.h"
#include "OMCpp<%fileNamePrefix%>.h"

#include "OMCpp<%fileNamePrefix%>Jacobian.h"
#include "OMCpp<%fileNamePrefix%>Mixed.h"
#include "OMCpp<%fileNamePrefix%>StateSelection.h"
#include "OMCpp<%fileNamePrefix%>WriteOutput.h"
#include "OMCpp<%fileNamePrefix%>Initialize.h"

#include "OMCpp<%fileNamePrefix%>FMU.h"

#include "OMCpp<%fileNamePrefix%>AlgLoopMain.cpp"
Expand Down
4 changes: 3 additions & 1 deletion OMCompiler/Compiler/Template/CodegenFMUCppOld.tpl
Expand Up @@ -110,13 +110,15 @@ template fmuCalcHelperMainfile(SimCode simCode)
#include <Core/Utils/extension/logger.hpp>

#include "OMCpp<%fileNamePrefix%>Types.h"
#include "OMCpp<%fileNamePrefix%>.h"
#include "OMCpp<%fileNamePrefix%>Functions.h"
#include "OMCpp<%fileNamePrefix%>.h"

#include "OMCpp<%fileNamePrefix%>Jacobian.h"
#include "OMCpp<%fileNamePrefix%>Mixed.h"
#include "OMCpp<%fileNamePrefix%>StateSelection.h"
#include "OMCpp<%fileNamePrefix%>WriteOutput.h"
#include "OMCpp<%fileNamePrefix%>Initialize.h"

#include "OMCpp<%fileNamePrefix%>FMU.h"

#include "OMCpp<%fileNamePrefix%>AlgLoopMain.cpp"
Expand Down
1 change: 1 addition & 0 deletions testsuite/openmodelica/cppruntime/Makefile
Expand Up @@ -27,6 +27,7 @@ functionPointerTest.mos \
recordTupleReturnTest.mos \
RefArrayDim2.mos \
solveTest.mos \
solveOneNonlinearEquationTest.mos \
testArrayEquations.mos \
testMatrixIO.mos \
testMatrixState.mos \
Expand Down
Expand Up @@ -3,6 +3,7 @@ TEST = ../../../../../rtest -v

TESTFILES = \
DIC_FMU2_CPP.mos \
solveOneNonlinearEquationTest.mos \
testArrayEquations.mos \
testFMU2MatrixIO.mos \
testModelDescription.mos \
Expand Down
@@ -0,0 +1,82 @@
// name: solveOneNonlinearEquationTest
// keywords: closure
// status: correct
// teardown_command: rm -f *SolveOneNonlinearEquationTest*

setCommandLineOptions("+simCodeTarget=Cpp");

loadModel(Modelica, {"3.2.3"});
loadString("
model SolveOneNonlinearEquationTest
\"Modelica.Media.Examples.SolveOneNonlinearEquation with input\"
import Modelica.Utilities.Streams.print;
extends Modelica.Icons.Example;

parameter Real y_zero = 0.5 \"Desired value of A*sin(w*x)\";
parameter Real x_min = -1.7 \"Minimum value of x_zero\";
parameter Real x_max = 1.7 \"Maximum value of x_zero\";
input Real A(start = 1) \"Amplitude of sine\";
input Real w(start = 1) \"Angular frequency of sine\";
Real x_zero \"y_zero = A*sin(w*x_zero)\";

function f_nonlinear \"Define sine as non-linear equation to be solved\"
extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
input Real A = 1 \"Amplitude of sine\";
input Real w = 1 \"Angular frequency of sine\";
input Real s = 0 \"Shift of sine\";
algorithm
y := A*Modelica.Math.sin(w*u) + s;
end f_nonlinear;

equation
x_zero = Modelica.Math.Nonlinear.solveOneNonlinearEquation(
function f_nonlinear(A=A, w=w, s=-y_zero), x_min, x_max);
annotation (experiment(StopTime=0));
end SolveOneNonlinearEquationTest;
");
getErrorString();

translateModelFMU(SolveOneNonlinearEquationTest, version = "2.0"); getErrorString();
loadModel(Modelica, {"3.2.3"}); getErrorString();
importFMU("SolveOneNonlinearEquationTest.fmu"); getErrorString();
loadFile("SolveOneNonlinearEquationTest_me_FMU.mo"); getErrorString();

setCommandLineOptions("--simCodeTarget=C"); getErrorString();
simulate(SolveOneNonlinearEquationTest_me_FMU, simflags="-override=A=1,w=1,stopTime=0.0"); getErrorString();

val(A, 0);
val(w, 0);
val(x_zero, 0);
getErrorString();

// Result:
// true
// true
// true
// ""
// "SolveOneNonlinearEquationTest.fmu"
// ""
// true
// ""
// "SolveOneNonlinearEquationTest_me_FMU.mo"
// ""
// true
// ""
// true
// ""
// record SimulationResult
// resultFile = "SolveOneNonlinearEquationTest_me_FMU_res.mat",
// simulationOptions = "startTime = 0.0, stopTime = 0.0, numberOfIntervals = 500, tolerance = 1e-06, method = 'dassl', fileNamePrefix = 'SolveOneNonlinearEquationTest_me_FMU', options = '', outputFormat = 'mat', variableFilter = '.*', cflags = '', simflags = '-override=A=1,w=1,stopTime=0.0'",
// messages = "LOG_STDOUT | warning | Start or stop time was overwritten, but no new integrator step size was provided.
// | | info | | Re-calculating step size for 500 intervals.
// | | | | | Add `stepSize=<value>` to `-override=` or override file to silence this warning.
// LOG_SUCCESS | info | The initialization finished successfully without homotopy method.
// LOG_SUCCESS | info | The simulation finished successfully.
// "
// end SimulationResult;
// ""
// 1.0
// 1.0
// 0.5235987755982987
// ""
// endResult
@@ -0,0 +1,59 @@
// name: solveOneNonlinearEquationTest
// keywords: closure
// status: correct
// teardown_command: rm -f *SolveOneNonlinearEquationTest*

setCommandLineOptions("+simCodeTarget=Cpp");

loadModel(Modelica, {"3.2.3"});
loadString("
model SolveOneNonlinearEquationTest
\"Modelica.Media.Examples.SolveOneNonlinearEquation with input\"
import Modelica.Utilities.Streams.print;
extends Modelica.Icons.Example;

parameter Real y_zero = 0.5 \"Desired value of A*sin(w*x)\";
parameter Real x_min = -1.7 \"Minimum value of x_zero\";
parameter Real x_max = 1.7 \"Maximum value of x_zero\";
input Real A(start = 1) \"Amplitude of sine\";
input Real w(start = 1) \"Angular frequency of sine\";
Real x_zero \"y_zero = A*sin(w*x_zero)\";

function f_nonlinear \"Define sine as non-linear equation to be solved\"
extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
input Real A = 1 \"Amplitude of sine\";
input Real w = 1 \"Angular frequency of sine\";
input Real s = 0 \"Shift of sine\";
algorithm
y := A*Modelica.Math.sin(w*u) + s;
end f_nonlinear;

equation
x_zero = Modelica.Math.Nonlinear.solveOneNonlinearEquation(
function f_nonlinear(A=A, w=w, s=-y_zero), x_min, x_max);
annotation (experiment(StopTime=0));
end SolveOneNonlinearEquationTest;
");
getErrorString();

simulate(SolveOneNonlinearEquationTest);
val(A, 0);
val(w, 0);
val(x_zero, 0);
getErrorString();

// Result:
// true
// true
// true
// ""
// record SimulationResult
// resultFile = "SolveOneNonlinearEquationTest_res.mat",
// simulationOptions = "startTime = 0.0, stopTime = 0.0, numberOfIntervals = 500, tolerance = 1e-06, method = 'dassl', fileNamePrefix = 'SolveOneNonlinearEquationTest', options = '', outputFormat = 'mat', variableFilter = '.*', cflags = '', simflags = ''",
// messages = ""
// end SimulationResult;
// 1.0
// 1.0
// 0.5235987755982987
// ""
// endResult

0 comments on commit 364fdb4

Please sign in to comment.