@@ -64,7 +64,8 @@ case SIMCODE(modelInfo=modelInfo as MODELINFO(__)) then
64
64
let &extraFuncs = buffer "" /*BUFD*/
65
65
let &extraFuncsDecl = buffer "" /*BUFD*/
66
66
let cpp = CodegenCpp.translateModel(simCode)
67
- let()= textFile(fmuModelWrapperFile(simCode, extraFuncs, extraFuncsDecl, "",guid, FMUVersion), 'OMCpp<%fileNamePrefix%>FMU.cpp')
67
+ let()= textFile(fmuModelHeaderFile(simCode, extraFuncs, extraFuncsDecl, "",guid, FMUVersion), 'OMCpp<%fileNamePrefix%>FMU.h')
68
+ let()= textFile(fmuModelCppFile(simCode, extraFuncs, extraFuncsDecl, "",guid, FMUVersion), 'OMCpp<%fileNamePrefix%>FMU.cpp')
68
69
let()= textFile(fmuModelDescriptionFileCpp(simCode, extraFuncs, extraFuncsDecl, "", guid, FMUVersion, FMUType), 'modelDescription.xml')
69
70
let()= textFile(fmudeffile(simCode, FMUVersion), '<%fileNamePrefix%>.def')
70
71
let()= textFile(fmuMakefile(target,simCode, extraFuncs, extraFuncsDecl, "", FMUVersion), '<%fileNamePrefix%>_FMU.makefile')
@@ -135,17 +136,51 @@ case SIMCODE(modelInfo = MODELINFO(varInfo = vi as VARINFO(__), vars = SIMVARS(s
135
136
>>
136
137
end fmiModelDescriptionAttributesCpp;
137
138
138
- template fmuModelWrapperFile(SimCode simCode,Text& extraFuncs,Text& extraFuncsDecl,Text extraFuncsNamespace, String guid, String FMUVersion)
139
- "Generates code for ModelDescription file for FMU target."
139
+ template fmuModelHeaderFile(SimCode simCode,Text& extraFuncs,Text& extraFuncsDecl,Text extraFuncsNamespace, String guid, String FMUVersion)
140
+ "Generates declaration for FMU target."
141
+ ::=
142
+ match simCode
143
+ case SIMCODE(modelInfo=MODELINFO(__)) then
144
+ let modelIdentifier = lastIdentOfPath(modelInfo.name)
145
+ //let modelIdentifier = System.stringReplace(dotPath(modelInfo.name), ".", "_")
146
+ <<
147
+ // declaration for Cpp FMU target
148
+ #include "OMCpp<%fileNamePrefix%>Extension.h"
149
+
150
+ class <%modelIdentifier%>FMU: public <%modelIdentifier%>Extension {
151
+ public:
152
+ // constructor
153
+ <% modelIdentifier%> FMU(IGlobalSettings* globalSettings,
154
+ boost::shared_ptr< IAlgLoopSolverFactory> nonLinSolverFactory,
155
+ boost::shared_ptr< ISimData> simData);
156
+
157
+ // getters for given value references
158
+ virtual void getReal(const unsigned int vr[], int nvr, double value[]);
159
+ virtual void getInteger(const unsigned int vr[], int nvr, int value[]);
160
+ virtual void getBoolean(const unsigned int vr[], int nvr, int value[]);
161
+ virtual void getString(const unsigned int vr[], int nvr, string value[]);
162
+
163
+ // setters for given value references
164
+ virtual void setReal(const unsigned int vr[], int nvr, const double value[]);
165
+ virtual void setInteger(const unsigned int vr[], int nvr, const int value[]);
166
+ virtual void setBoolean(const unsigned int vr[], int nvr, const int value[]);
167
+ virtual void setString(const unsigned int vr[], int nvr, const string value[]);
168
+ } ;
169
+ >>
170
+ end fmuModelHeaderFile;
171
+
172
+ template fmuModelCppFile(SimCode simCode,Text& extraFuncs,Text& extraFuncsDecl,Text extraFuncsNamespace, String guid, String FMUVersion)
173
+ "Generates code for FMU target."
140
174
::=
141
175
match simCode
142
176
case SIMCODE(modelInfo=MODELINFO(__)) then
143
177
let modelName = dotPath(modelInfo.name)
144
178
let modelShortName = lastIdentOfPath(modelInfo.name)
145
- let modelIdentifier = System.stringReplace(modelName, ".", "_")
179
+ //let modelIdentifier = System.stringReplace(modelName, ".", "_")
180
+ let modelIdentifier = modelShortName
146
181
<<
147
182
// define model identifier and unique id
148
- #define MODEL_IDENTIFIER <%modelShortName %>
183
+ #define MODEL_IDENTIFIER <%modelIdentifier %>
149
184
#define MODEL_GUID "{ <% guid%> } "
150
185
151
186
#include <Core /Modelica.h >
@@ -158,7 +193,7 @@ case SIMCODE(modelInfo=MODELINFO(__)) then
158
193
#include <Solver /IAlgLoopSolver.h >
159
194
#include <System /IAlgLoopSolverFactory.h >
160
195
#include <SimController /ISimData.h >
161
- #include "OMCpp<%fileNamePrefix%>Extension .h"
196
+ #include "OMCpp<%fileNamePrefix%>FMU .h"
162
197
163
198
<%ModelDefineData(modelInfo)%>
164
199
#define NUMBER_OF_EVENT_INDICATORS <%zerocrosslength(simCode, extraFuncs ,extraFuncsDecl, extraFuncsNamespace)%>
@@ -167,20 +202,30 @@ case SIMCODE(modelInfo=MODELINFO(__)) then
167
202
'#include "FMU2/FMU2Wrapper.cpp"'
168
203
else
169
204
'#include "FMU/FMUWrapper.cpp"'%>
170
-
171
205
<%if isFMIVersion20(FMUVersion) then
172
206
'#include "FMU2/FMU2Interface.cpp"'
173
207
else
174
208
'#include "FMU/FMULibInterface.cpp"'%>
175
209
176
- #if 0
177
- <%setDefaultStartValues(modelInfo)%>
178
- <%setStartValues(modelInfo)%>
179
- <%setExternalFunction(modelInfo)%>
180
- #endif
210
+ // constructor
211
+ <%modelIdentifier%>FMU::<%modelIdentifier%>FMU(IGlobalSettings* globalSettings,
212
+ boost::shared_ptr<IAlgLoopSolverFactory > nonLinSolverFactory,
213
+ boost::shared_ptr<ISimData > simData):
214
+ PreVariables(<%getPreVarsCount(simCode)%>),
215
+ <%modelIdentifier%>(globalSettings, nonLinSolverFactory, simData),
216
+ <%modelIdentifier%>Extension(globalSettings, nonLinSolverFactory, simData) {
217
+ }
181
218
219
+ // getters
220
+ <%accessFunctions(simCode, "get", modelIdentifier, modelInfo)%>
221
+ // setters
222
+ <%accessFunctions(simCode, "set", modelIdentifier, modelInfo)%>
182
223
>>
183
- end fmuModelWrapperFile;
224
+ // TODO:
225
+ // <%setDefaultStartValues(modelInfo)%>
226
+ // <%setStartValues(modelInfo)%>
227
+ // <%setExternalFunction(modelInfo)%>
228
+ end fmuModelCppFile;
184
229
185
230
template ModelDefineData(ModelInfo modelInfo)
186
231
"Generates global data in simulation file."
@@ -371,6 +416,118 @@ template setExternalFunctionSwitch(Function fn)
371
416
>>
372
417
end setExternalFunctionSwitch;
373
418
419
+ template accessFunctions(SimCode simCode, String direction, String modelIdentifier, ModelInfo modelInfo)
420
+ "Generates getters and setters for Real, Integer, Boolean, and String."
421
+ ::=
422
+ match modelInfo
423
+ case MODELINFO(vars=SIMVARS(__)) then
424
+ <<
425
+ <%accessRealFunction(simCode, direction, modelIdentifier, modelInfo)%>
426
+ <%accessVarsFunction(simCode, direction, modelIdentifier, "Integer", "int", vars.intAlgVars, vars.intParamVars, vars.intAliasVars)%>
427
+ <%accessVarsFunction(simCode, direction, modelIdentifier, "Boolean", "int", vars.boolAlgVars, vars.boolParamVars, vars.boolAliasVars)%>
428
+ <%accessVarsFunction(simCode, direction, modelIdentifier, "String", "string", vars.stringAlgVars, vars.stringParamVars, vars.stringAliasVars)%>
429
+ >>
430
+ end accessFunctions;
431
+
432
+ template accessRealFunction(SimCode simCode, String direction, String modelIdentifier, ModelInfo modelInfo)
433
+ "Generates getReal and setReal functions."
434
+ ::=
435
+ match modelInfo
436
+ case MODELINFO(vars=SIMVARS(__), varInfo=VARINFO(numStateVars=numStateVars, numAlgVars=numAlgVars, numDiscreteReal=numDiscreteReal, numParams=numParams)) then
437
+ let qualifier = if stringEq(direction, "set") then "const"
438
+ let statesOffset = intMul(2, stringInt(numFMUStateVars(vars.stateVars)))
439
+ <<
440
+ void <%modelIdentifier%>FMU::<%direction%>Real(const unsigned int vr[], int nvr, <%qualifier%> double value[]) {
441
+ for (int i = 0; i < nvr; i++)
442
+ switch (vr[i]) {
443
+ <% vars.stateVars |> var => accessVecVar(direction, var, 0, " __z" ); separator= " \n " %>
444
+ <% vars.derivativeVars |> var => accessVecVar(direction, var, numStateVars, " __zDot" ); separator= " \n " %>
445
+ <% accessVars(simCode, direction, vars.algVars, stringInt(statesOffset))%>
446
+ <% accessVars(simCode, direction, vars.discreteAlgVars, intAdd(stringInt(statesOffset), numAlgVars))%>
447
+ <% accessVars(simCode, direction, vars.paramVars, intAdd(intAdd(stringInt(statesOffset), numAlgVars), numDiscreteReal))%>
448
+ <% accessVars(simCode, direction, vars.aliasVars, intAdd(intAdd(intAdd(stringInt(statesOffset), numAlgVars), numDiscreteReal), numParams))%>
449
+ default :
450
+ std::ostringstream message;
451
+ message << " <%direction%>Real with wrong value reference " << vr[i];
452
+ throw std::invalid_argument(message.str());
453
+ }
454
+ }
455
+
456
+ >>
457
+ end accessRealFunction;
458
+
459
+ template numFMUStateVars(list<SimVar > stateVars)
460
+ "Return number of states without dummy state"
461
+ ::=
462
+ if intGt(listLength(stateVars), 1) then listLength(stateVars) else (stateVars |> var => match var case SIMVAR(__) then if stringEq(crefStr(name), "$dummy") then 0 else 1)
463
+ end numFMUStateVars;
464
+
465
+ template accessVarsFunction(SimCode simCode, String direction, String modelIdentifier, String typeName, String typeImpl, list<SimVar > algVars, list<SimVar > paramVars, list<SimVar > aliasVars)
466
+ "Generates get<%typeName%> and set<%typeName%> functions."
467
+ ::=
468
+ let qualifier = if stringEq(direction, "set") then "const"
469
+ <<
470
+ void <%modelIdentifier%>FMU::<%direction%><%typeName%>(const unsigned int vr[], int nvr, <%qualifier%> <%typeImpl%> value[]) {
471
+ for (int i = 0; i < nvr; i++)
472
+ switch (vr[i]) {
473
+ <% accessVars(simCode, direction, algVars, 0)%>
474
+ <% accessVars(simCode, direction, paramVars, listLength(algVars))%>
475
+ <% accessVars(simCode, direction, aliasVars, intAdd(listLength(algVars), listLength(paramVars)))%>
476
+ default :
477
+ std::ostringstream message;
478
+ message << " <%direction%><%typeName%> with wrong value reference " << vr[i];
479
+ throw std::invalid_argument(message.str());
480
+ }
481
+ }
482
+
483
+ >>
484
+ end accessVarsFunction;
485
+
486
+ template accessVars(SimCode simCode, String direction, list<SimVar > varsList, Integer offset)
487
+ "Generates list of case statements in get functions of Cpp file."
488
+ ::=
489
+ <<
490
+ <%varsList |> var => accessVar(simCode, direction, var, offset); separator="\n"%>
491
+ >>
492
+ end accessVars;
493
+
494
+ template accessVar(SimCode simCode, String direction, SimVar simVar, Integer offset)
495
+ "Generates code for accessing variables in Cpp file for FMU target."
496
+ ::=
497
+ match simVar
498
+ case SIMVAR(__) then
499
+ let description = if comment then '// <%comment%>'
500
+ let varname = cref1(name, simCode, "", "", "", contextOther, "", "", false)
501
+ if stringEq(direction, "get") then
502
+ <<
503
+ case <%intAdd(offset, index)%>: value[i] = <%varname%>; break; <%description%>
504
+ >>
505
+ else
506
+ <<
507
+ case <%intAdd(offset, index)%>: <%varname%> = value[i]; break; <%description%>
508
+ >>
509
+ end accessVar;
510
+
511
+ template accessVecVar(String direction, SimVar simVar, Integer offset, String vecName)
512
+ "Generates code for accessing vector variables, neglecting $dummy states."
513
+ ::=
514
+ match simVar
515
+ case SIMVAR(__) then
516
+ let description = if comment then '// <%comment%>'
517
+ if stringEq(crefStr(name), "$dummy") then
518
+ <<> >
519
+ else if stringEq(crefStr(name), "der($dummy)") then
520
+ <<> >
521
+ else if stringEq(direction, "get") then
522
+ <<
523
+ case <%intAdd(offset, index)%>: value[i] = <%vecName%>[<%index%>]; break; <%description%>
524
+ >>
525
+ else
526
+ <<
527
+ case <%intAdd(offset, index)%>: <%vecName%>[<%index%>] = value[i]; break; <%description%>
528
+ >>
529
+ end accessVecVar;
530
+
374
531
template getPlatformString2(String platform, String fileNamePrefix, String dirExtra, String libsPos1, String libsPos2, String omhome)
375
532
"returns compilation commands for the platform. "
376
533
::=
0 commit comments