diff --git a/OMCompiler/Compiler/NBackEnd/Classes/NBVariable.mo b/OMCompiler/Compiler/NBackEnd/Classes/NBVariable.mo index 368362dd773..293fb13db06 100644 --- a/OMCompiler/Compiler/NBackEnd/Classes/NBVariable.mo +++ b/OMCompiler/Compiler/NBackEnd/Classes/NBVariable.mo @@ -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"; @@ -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 varPointer; + input Pointer 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 varPointer; + output Option> 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 diff --git a/OMCompiler/Compiler/NBackEnd/Classes/NBackendDAE.mo b/OMCompiler/Compiler/NBackEnd/Classes/NBackendDAE.mo index 97693475800..2e754507cfa 100644 --- a/OMCompiler/Compiler/NBackEnd/Classes/NBackendDAE.mo +++ b/OMCompiler/Compiler/NBackEnd/Classes/NBackendDAE.mo @@ -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, @@ -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; @@ -599,8 +599,10 @@ protected end collectVariableBindingIterators; function lowerRecordChildren - input output Variable var; + input Pointer var_ptr; input VariablePointers variables; + protected + Variable var = Pointer.access(var_ptr); algorithm var := match var local @@ -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 diff --git a/OMCompiler/Compiler/NBackEnd/Modules/2_Pre/NBBindings.mo b/OMCompiler/Compiler/NBackEnd/Modules/2_Pre/NBBindings.mo index b973d051994..d9c5dd9d1a9 100644 --- a/OMCompiler/Compiler/NBackEnd/Modules/2_Pre/NBBindings.mo +++ b/OMCompiler/Compiler/NBackEnd/Modules/2_Pre/NBBindings.mo @@ -57,17 +57,27 @@ public list> binding_cont = {} "list of created continuous binding equations"; list> binding_disc = {} "list of created discrete binding equations"; list> binding_rec = {} "list of created record binding equations"; + Pointer 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; diff --git a/OMCompiler/Compiler/NFFrontEnd/NFBackendExtension.mo b/OMCompiler/Compiler/NFFrontEnd/NFBackendExtension.mo index 40b9482d9d7..d37885d12f0 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFBackendExtension.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFBackendExtension.mo @@ -70,6 +70,7 @@ public VariableAttributes attributes "values on built-in attributes"; Annotations annotations "values on annotations (vendor specific)"; Option> pre_post "Pointer (var->pre) or (pre-> var) if existent."; + Option> parent "record parent if it is part of a record."; end BACKEND_INFO; function toString @@ -102,6 +103,13 @@ public binfo.varKind := varKind; end setVarKind; + function setParent + input output BackendInfo binfo; + input Pointer parent; + algorithm + binfo.parent := SOME(parent); + end setParent; + function setPrePost input output BackendInfo binfo; input Option> pre_post; @@ -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; diff --git a/OMCompiler/Compiler/NFFrontEnd/NFComponentRef.mo b/OMCompiler/Compiler/NFFrontEnd/NFComponentRef.mo index f3bd0153c38..99f20fe3205 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFComponentRef.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFComponentRef.mo @@ -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; diff --git a/OMCompiler/Compiler/NFFrontEnd/NFVariable.mo b/OMCompiler/Compiler/NFFrontEnd/NFVariable.mo index f23ac67632f..42dd210f851 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFVariable.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFVariable.mo @@ -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 = diff --git a/testsuite/simulation/modelica/NBackend/records/ComplexTest.mos b/testsuite/simulation/modelica/NBackend/records/ComplexTest.mos index 2a551433cc7..107765e6fb4 100644 --- a/testsuite/simulation/modelica/NBackend/records/ComplexTest.mos +++ b/testsuite/simulation/modelica/NBackend/records/ComplexTest.mos @@ -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(); @@ -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 @@ -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