Opened 10 years ago

Closed 10 years ago

Last modified 10 years ago

#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 Adrian Pop)

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 Adrian Pop, 10 years ago

Description: modified (diff)

comment:2 by Martin Sjölund, 10 years ago

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.

comment:3 by Martin Sjölund, 10 years ago

Cc: Willi Braun added
Owner: changed from somebody to Lennart Ochel
Status: newassigned

This seems to be done in RemoveSimpleEquations...

comment:4 by Adrian Pop, 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.

Version 0, edited 10 years ago by Adrian Pop (next)

comment:5 by Adrian Pop, 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:6 by Adrian Pop, 10 years ago

Found the problem and a solution for it and running the testsuite now.

comment:7 by Adrian Pop, 10 years ago

Resolution: fixed
Status: assignedclosed

Fixed in r22463.

comment:8 by Adrian Pop, 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 Adrian Pop, 10 years ago

Milestone: Future1.9.1
Note: See TracTickets for help on using tickets.