Skip to content

Commit

Permalink
[NB] correctly parse records and their children (#11542)
Browse files Browse the repository at this point in the history
- create binding equations from record elements only if the record itself is not bound
  • Loading branch information
kabdelhak committed Nov 9, 2023
1 parent 1655a56 commit cf7557d
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 31 deletions.
23 changes: 22 additions & 1 deletion OMCompiler/Compiler/NBackEnd/Classes/NBVariable.mo
Expand Up @@ -87,7 +87,7 @@ public
constant Variable TIME_VARIABLE = Variable.VARIABLE(NFBuiltin.TIME_CREF, Type.REAL(),
NFBinding.EMPTY_BINDING, NFPrefixes.Visibility.PUBLIC, NFAttributes.DEFAULT_ATTR,
{}, {}, NONE(), SCodeUtil.dummyInfo, BackendExtension.BACKEND_INFO(
VariableKind.TIME(), NFBackendExtension.EMPTY_VAR_ATTR_REAL, NFBackendExtension.EMPTY_ANNOTATIONS, NONE()));
VariableKind.TIME(), NFBackendExtension.EMPTY_VAR_ATTR_REAL, NFBackendExtension.EMPTY_ANNOTATIONS, NONE(), NONE()));

constant String DERIVATIVE_STR = "$DER";
constant String DUMMY_DERIVATIVE_STR = "$dDER";
Expand Down Expand Up @@ -548,6 +548,27 @@ public
Pointer.update(varPointer, var);
end setVarKind;

function setParent
"sets the record parent. only do for record elements!"
input output Pointer<Variable> varPointer;
input Pointer<Variable> parent;
protected
Variable var = Pointer.access(varPointer);
algorithm
var.backendinfo := BackendExtension.BackendInfo.setParent(var.backendinfo, parent);
Pointer.update(varPointer, var);
end setParent;

function getParent
"returns the optional record parent"
input Pointer<Variable> varPointer;
output Option<Pointer<Variable>> parent;
protected
Variable var = Pointer.access(varPointer);
algorithm
parent := var.backendinfo.parent;
end getParent;

function isDummyVariable
"Returns true, if the variable is a dummy variable.
Note: !Only works in the backend, will return true for any variable if used
Expand Down
11 changes: 8 additions & 3 deletions OMCompiler/Compiler/NBackEnd/Classes/NBackendDAE.mo
Expand Up @@ -499,7 +499,7 @@ protected
variables := VariablePointers.map(variables, function Variable.mapExp(fn = function lowerComponentReferenceExp(variables = variables)));

/* lower the records to add children */
records := VariablePointers.map(records, function lowerRecordChildren(variables = variables));
records := VariablePointers.mapPtr(records, function lowerRecordChildren(variables = variables));

/* create variable data */
variableData := BVariable.VAR_DATA_SIM(variables, unknowns, knowns, initials, auxiliaries, aliasVars, nonTrivialAlias,
Expand All @@ -522,7 +522,7 @@ protected
var.backendinfo := match var.backendinfo
case BackendExtension.BACKEND_INFO(varKind = BackendExtension.FRONTEND_DUMMY()) algorithm
(varKind, attributes) := lowerVariableKind(Variable.variability(var), attributes, var.ty);
then BackendExtension.BACKEND_INFO(varKind, attributes, annotations, NONE());
then BackendExtension.BACKEND_INFO(varKind, attributes, annotations, NONE(), NONE());
else BackendExtension.BackendInfo.setAttributes(var.backendinfo, attributes, annotations);
end match;

Expand Down Expand Up @@ -599,8 +599,10 @@ protected
end collectVariableBindingIterators;

function lowerRecordChildren
input output Variable var;
input Pointer<Variable> var_ptr;
input VariablePointers variables;
protected
Variable var = Pointer.access(var_ptr);
algorithm
var := match var
local
Expand All @@ -609,11 +611,14 @@ protected
case Variable.VARIABLE(backendinfo = binfo as BackendExtension.BACKEND_INFO(varKind = varKind as BackendExtension.RECORD())) algorithm
// kabdelhak: why is this list reversed in the frontend? doesnt match input order
varKind.children := listReverse(list(VariablePointers.getVarSafe(variables, ComponentRef.stripSubscriptsAll(child.name)) for child in var.children));
// set parent for all children
varKind.children := list(BVariable.setParent(child, var_ptr) for child in varKind.children);
binfo.varKind := varKind;
var.backendinfo := binfo;
then var;
else var;
end match;
Pointer.update(var_ptr, var);
end lowerRecordChildren;

function lowerEquationData
Expand Down
22 changes: 16 additions & 6 deletions OMCompiler/Compiler/NBackEnd/Modules/2_Pre/NBBindings.mo
Expand Up @@ -57,17 +57,27 @@ public
list<Pointer<Equation>> binding_cont = {} "list of created continuous binding equations";
list<Pointer<Equation>> binding_disc = {} "list of created discrete binding equations";
list<Pointer<Equation>> binding_rec = {} "list of created record binding equations";
Pointer<Variable> parent "optional record parent";
Boolean skip_record_element "true if this variable is part of an array and the array variable is bound";

case BackendDAE.MAIN(varData = varData as VarData.VAR_DATA_SIM(), eqData = eqData as EqData.EQ_DATA_SIM())
algorithm
// create continuous and discrete binding equations
// do not create bindings for record children! they are bound off their record variables
bound_vars := list(var for var guard(BVariable.isBound(var) and not Variable.isComplexChild(Pointer.access(var))) in VariablePointers.toList(varData.unknowns));
bound_vars := list(var for var guard(BVariable.isBound(var)) in VariablePointers.toList(varData.unknowns));

for var in bound_vars loop
if BVariable.isContinuous(var) then
binding_cont := Equation.generateBindingEquation(var, eqData.uniqueIndex, false) :: binding_cont;
else
binding_disc := Equation.generateBindingEquation(var, eqData.uniqueIndex, false) :: binding_disc;
// do not create bindings for record children with bound parents! they are bound off their record variables
skip_record_element := match BVariable.getParent(var)
case SOME(parent) then BVariable.isBound(parent);
else false;
end match;

if not skip_record_element then
if BVariable.isContinuous(var) then
binding_cont := Equation.generateBindingEquation(var, eqData.uniqueIndex, false) :: binding_cont;
else
binding_disc := Equation.generateBindingEquation(var, eqData.uniqueIndex, false) :: binding_disc;
end if;
end if;
end for;

Expand Down
12 changes: 10 additions & 2 deletions OMCompiler/Compiler/NFFrontEnd/NFBackendExtension.mo
Expand Up @@ -70,6 +70,7 @@ public
VariableAttributes attributes "values on built-in attributes";
Annotations annotations "values on annotations (vendor specific)";
Option<Pointer<Variable>> pre_post "Pointer (var->pre) or (pre-> var) if existent.";
Option<Pointer<Variable>> parent "record parent if it is part of a record.";
end BACKEND_INFO;

function toString
Expand Down Expand Up @@ -102,6 +103,13 @@ public
binfo.varKind := varKind;
end setVarKind;

function setParent
input output BackendInfo binfo;
input Pointer<Variable> parent;
algorithm
binfo.parent := SOME(parent);
end setParent;

function setPrePost
input output BackendInfo binfo;
input Option<Pointer<Variable>> pre_post;
Expand Down Expand Up @@ -144,12 +152,12 @@ public
case VariableKind.FRONTEND_DUMMY() then List.fill(binfo, length);
else algorithm
scalar_attributes := VariableAttributes.scalarize(binfo.attributes, length);
then list(BACKEND_INFO(binfo.varKind, attr, binfo.annotations, binfo.pre_post) for attr in scalar_attributes);
then list(BACKEND_INFO(binfo.varKind, attr, binfo.annotations, binfo.pre_post, binfo.parent) for attr in scalar_attributes);
end match;
end scalarize;
end BackendInfo;

constant BackendInfo DUMMY_BACKEND_INFO = BACKEND_INFO(FRONTEND_DUMMY(), EMPTY_VAR_ATTR_REAL, EMPTY_ANNOTATIONS, NONE());
constant BackendInfo DUMMY_BACKEND_INFO = BACKEND_INFO(FRONTEND_DUMMY(), EMPTY_VAR_ATTR_REAL, EMPTY_ANNOTATIONS, NONE(), NONE());

uniontype VariableKind
record TIME end TIME;
Expand Down
12 changes: 0 additions & 12 deletions OMCompiler/Compiler/NFFrontEnd/NFComponentRef.mo
Expand Up @@ -1717,18 +1717,6 @@ public
end match;
end isComplexArray2;

function isComplexChild
"returns true if any of the crefs sub crefs are of type complex.
Note: also returns true for the record cref itself"
input ComponentRef cref;
output Boolean b;
algorithm
b := match cref
case CREF() then Type.isComplex(cref.ty) or isComplexChild(cref.restCref);
else false;
end match;
end isComplexChild;

function containsExp
input ComponentRef cref;
input ContainsPred func;
Expand Down
7 changes: 0 additions & 7 deletions OMCompiler/Compiler/NFFrontEnd/NFVariable.mo
Expand Up @@ -224,13 +224,6 @@ public
output Boolean b = Type.isComplexArray(var.ty);
end isComplexArray;

function isComplexChild
"returns true if any of the crefs sub crefs are of type complex.
Note: also returns true for the record cref itself"
input Variable var;
output Boolean b = ComponentRef.isComplexChild(var.name);
end isComplexChild;

function isStructural
input Variable variable;
output Boolean structural =
Expand Down
39 changes: 39 additions & 0 deletions testsuite/simulation/modelica/NBackend/records/ComplexTest.mos
Expand Up @@ -97,6 +97,12 @@ package ComplexTestNB
Q = 0.2 + 0.1*time;
v*Modelica.ComplexMath.conj(i) = Complex(P, Q);
end T09;

model T10
Real a = 1;
Real b = 1;
Complex z(re = a, im = b);
end T10;
end ComplexTestNB;
"); getErrorString();

Expand All @@ -111,6 +117,7 @@ simulate(ComplexTestNB.T06); getErrorString();
simulate(ComplexTestNB.T07); getErrorString();
simulate(ComplexTestNB.T08); getErrorString();
simulate(ComplexTestNB.T09); getErrorString();
simulate(ComplexTestNB.T10); getErrorString();

// Result:
// true
Expand Down Expand Up @@ -374,4 +381,36 @@ simulate(ComplexTestNB.T09); getErrorString();
// "
// end SimulationResult;
// ""
// Created Continuous Binding Equations (4):
// *******************************************
// [SCAL] (1) z.re = a ($RES_BND_3)
// [SCAL] (1) z.im = b ($RES_BND_2)
// [SCAL] (1) b = 1.0 ($RES_BND_1)
// [SCAL] (1) a = 1.0 ($RES_BND_0)
//
// Created Discrete Binding Equations (0):
// *****************************************
//
//
// Created Record Binding Equations (0):
// ***************************************
//
//
// Created Parameter Binding Equations (2):
// ******************************************
// [SCAL] (1) z.re = 1.0 ($RES_BND_5)
// [SCAL] (1) z.im = 1.0 ($RES_BND_4)
//
// Created Record Parameter Binding Equations (0):
// *************************************************
//
//
// record SimulationResult
// resultFile = "ComplexTestNB.T10_res.mat",
// simulationOptions = "startTime = 0.0, stopTime = 1.0, numberOfIntervals = 500, tolerance = 1e-6, method = 'dassl', fileNamePrefix = 'ComplexTestNB.T10', options = '', outputFormat = 'mat', variableFilter = '.*', cflags = '', simflags = ''",
// messages = "LOG_SUCCESS | info | The initialization finished successfully without homotopy method.
// LOG_SUCCESS | info | The simulation finished successfully.
// "
// end SimulationResult;
// ""
// endResult

0 comments on commit cf7557d

Please sign in to comment.