#2837 closed defect (fixed)
Wrong code generation for model
Reported by: | Adrian Pop | Owned by: | Lennart Ochel |
---|---|---|---|
Priority: | high | Milestone: | 1.9.1 |
Component: | Backend | Version: | trunk |
Keywords: | Cc: | Willi Braun |
Description (last modified by )
This pattern is not properly supported in the back-end or code generation:
model ArrayModel function lift input Real x; input Real y; output Real[1] z; algorithm z := {x}; end lift; parameter Real x = 10; Real z[1]; equation z = lift(x, 0.0); end ArrayModel;
We get:
ArrayModel_06inz.c: In function 'ArrayModel_eqFunction_1': ArrayModel_06inz.c:71: error: incompatible types when assigning to type 'modelica_real' from type 'real_array_t'
and codegen looks like:
/* equation index: 1 type: SIMPLE_ASSIGN z[1] = (ArrayModel.lift(x, 0.0) - z) ./ {1.0} */ void ArrayModel_eqFunction_1(DATA *data) { const int equationIndexes[2] = {1,1}; TRACE_PUSH real_array tmp0; real_array_create(&tmp0, ((modelica_real*)&($Pz)), 1, 1); $Pz$lB1$rB = div_alloc_real_array(sub_alloc_real_array(omc_ArrayModel_lift(threadData, $Px, 0.0), tmp0), _OMC_LIT0); TRACE_POP }
Which seems rather wrong.
This kind of pattern is used in the PowerSystems library.
Change History (9)
comment:1 by , 10 years ago
Description: | modified (diff) |
---|
comment:2 by , 10 years ago
comment:3 by , 10 years ago
Cc: | added |
---|---|
Owner: | changed from | to
Status: | new → assigned |
This seems to be done in RemoveSimpleEquations...
comment:4 by , 10 years ago
Seems to go like this in RemoveSimpleEquations.solveTimeIndependentAcausal:
// try to solve the equation cre = Expression.crefExp(cr); (es, {}) = ExpressionSolve.solve(lhs, rhs, cre);
and after this es
is that weird expression: (lift(x, 0.0) - z)/1
.
So actually this seems to happen in ExpressionSolve.solve, not RemoveSimpleEquations.
comment:5 by , 10 years ago
The problem is that:
cre is DAE.CREF(DAE.CREF_IDENT(z, T_ARRAY, subscript[1]), T_REAL)
and
lhs is DAE.CREF(DAE.CREF_IDENT(z, T_ARRAY, nosubs), T_ARRAY)
and because of that ExpressionSolve doesn't get it that it should solve it directly:
z = lift(x, 00)
as
true = ComponentReference.crefEqual(cr, cr1);
does not succeed.
And then it uses Newton iteration to solve it :)
comment:8 by , 10 years ago
Lennart, could you have a quick look at my fix for this bug as I'm not 100% sure is the best way to do it. It seems some system sizes have grown after my fix (EngineV6 and some others). Maybe we could to how it was done previously if the Backend variable cref is an array and how i do it now if is a simple type.
comment:9 by , 10 years ago
Milestone: | Future → 1.9.1 |
---|
This is very weird indeed. First, why is a division by 1.0 not removed in simplify? Second, why is the subtraction by z introduced? It would only be valid if 0.0 was on the rhs and we were solving a NLS.