Changeset d316ab2 in OpenModelica


Ignore:
Timestamp:
2017-01-06T20:35:49+01:00 (7 years ago)
Author:
hudson <openmodelica@…>
Branches:
Added-citation-metadata, maintenance/v1.14, maintenance/v1.15, maintenance/v1.16, maintenance/v1.17, maintenance/v1.18, maintenance/v1.19, maintenance/v1.20, maintenance/v1.21, maintenance/v1.22, maintenance/v1.23, master, omlib-staging
Children:
e7c76f7
Parents:
c2a8668f
git-author:
Rüdiger Franke <rdgfranke@…> (01/06/17 20:35:49)
git-committer:
hudson <openmodelica@…> (01/06/17 20:35:49)
Message:

Add synchronous solver method ExplicitEuler, besides ImplicitEuler

File:
1 edited

Legend:

Unmodified
Added
Removed
  • Compiler/BackEnd/SynchronousFeatures.mo

    r70c74228 rd316ab2  
    189189          subPartition := shared.partitionsInfo.subPartitions[idx];
    190190          solverMethod := BackendDump.optionString(subPartition.clock.solver);
     191          if stringLength(solverMethod) > 7 and substring(solverMethod, 1, 8) == "Explicit" then
     192            if solverMethod <> "ExplicitEuler" then
     193              Error.addCompilerWarning("Solving clocked continuous equations with " +
     194                                       "ExplicitEuler instead of specified " + solverMethod + ". "
     195                                       + "Supporting ExplicitEuler and ImplicitEuler.");
     196            end if;
     197            for i in 1:BackendDAEUtil.equationArraySize(eqs) loop
     198              eq := BackendEquation.equationNth1(eqs, i);
     199              (_, derVars) := BackendEquation.traverseExpsOfEquation(eq, getDerVars1, derVars);
     200            end for;
     201            for i in 1:BackendDAEUtil.equationArraySize(eqs) loop
     202              eq := BackendEquation.equationNth1(eqs, i);
     203              (eq, _) := BackendEquation.traverseExpsOfEquation(eq, shiftDerVars1, derVars);
     204              eqs := BackendEquation.setAtIndex(eqs, i, eq);
     205            end for;
     206          elseif stringLength(solverMethod) > 0 and solverMethod <> "ImplicitEuler" then
     207            Error.addCompilerWarning("Solving clocked continuous equations with " +
     208                                     "ImplicitEuler instead of specified " + solverMethod + ". "
     209                                     + "Supporting ExplicitEuler and ImplicitEuler.");
     210          end if;
    191211          lstEqs := {};
     212          derVars := {};
    192213          for i in 1:BackendDAEUtil.equationArraySize(eqs) loop
    193214            eq := BackendEquation.equationNth1(eqs, i);
    194             (eq, (solverMethod, derVars)) := BackendEquation.traverseExpsOfEquation(eq, applySolverMethod1, (solverMethod, derVars));
     215            (eq, derVars) := BackendEquation.traverseExpsOfEquation(eq, applyEulerMethod1, derVars);
    195216            lstEqs := eq::lstEqs;
    196217          end for;
     
    204225end treatClockedStates;
    205226
    206 protected function applySolverMethod1 "helper to applySolverMethod"
    207   input DAE.Exp inExp;
    208   input tuple<String, list<DAE.ComponentRef>> inTpl;
     227protected function getDerVars1 "helper to getDerVars"
     228  input DAE.Exp inExp;
     229  input list<DAE.ComponentRef> inDerVars;
    209230  output DAE.Exp outExp;
    210   output tuple<String, list<DAE.ComponentRef>> outTpl;
    211 algorithm
    212   (outExp, outTpl) := Expression.traverseExpBottomUp(inExp, applySolverMethod, inTpl);
    213 end applySolverMethod1;
    214 
    215 protected function applySolverMethod
    216 "Apply given solverMethod to convert continous-time to clocked expression.
    217  So far ImplicitEuler, replacing der(x) -> (x - previous(x))/interval().
     231  output list<DAE.ComponentRef> outDerVars;
     232algorithm
     233  (outExp, outDerVars) := Expression.traverseExpBottomUp(inExp, getDerVars, inDerVars);
     234end getDerVars1;
     235
     236protected function getDerVars
     237"Get all crefs that appear in a der() operator.
    218238 author: rfranke"
    219239  input DAE.Exp inExp;
    220   input tuple<String, list<DAE.ComponentRef>> inTpl;
     240  input list<DAE.ComponentRef> inDerVars;
     241  output DAE.Exp outExp = inExp;
     242  output list<DAE.ComponentRef> outDerVars;
     243algorithm
     244  outDerVars := match inExp
     245    local
     246      DAE.ComponentRef x;
     247    case DAE.CALL(path = Absyn.IDENT(name = "der"),
     248                  expLst = {DAE.CREF(componentRef = x)})
     249      then x :: inDerVars;
     250    else inDerVars;
     251  end match;
     252end getDerVars;
     253
     254protected function shiftDerVars1 "helper to shiftDerVars"
     255  input DAE.Exp inExp;
     256  input list<DAE.ComponentRef> inDerVars;
    221257  output DAE.Exp outExp;
    222   output tuple<String, list<DAE.ComponentRef>> outTpl;
    223 algorithm
    224   (outExp, outTpl) := match inExp
     258  output list<DAE.ComponentRef> outDerVars;
     259algorithm
     260  (outExp, outDerVars) := Expression.traverseExpBottomUp(inExp, shiftDerVars, inDerVars);
     261end shiftDerVars1;
     262
     263protected function shiftDerVars
     264"Apply previous() operator to all inDerVars.
     265 author: rfranke"
     266  input DAE.Exp inExp;
     267  input list<DAE.ComponentRef> inDerVars;
     268  output DAE.Exp outExp;
     269  output list<DAE.ComponentRef> outDerVars = inDerVars;
     270algorithm
     271  outExp := match inExp
    225272    local
    226273      List<DAE.Exp> expLst;
     
    229276      DAE.Type ty;
    230277      DAE.Exp exp;
    231       String inSolverMethod, outSolverMethod;
    232       list<DAE.ComponentRef> inDerVars;
     278    // introduce previous()
     279    case DAE.CREF(componentRef = x)
     280      guard ComponentReference.crefInLst(x, inDerVars)
     281      algorithm
     282        exp := DAE.CALL(Absyn.IDENT(name = "previous"), {inExp}, DAE.callAttrBuiltinImpureReal);
     283      then exp;
     284    // check for possibly introduced der(previous())
     285    case DAE.CALL(path = Absyn.IDENT(name = "der"),
     286                  expLst = {DAE.CALL(path = Absyn.IDENT(name = "previous"), expLst = expLst)},
     287                  attr = attr as DAE.CALL_ATTR(ty = ty))
     288      algorithm
     289        exp := DAE.CALL(Absyn.IDENT(name = "der"), expLst, attr);
     290      then exp;
     291    // check for possibly introduced previous(previous())
     292    case DAE.CALL(path = Absyn.IDENT(name = "previous"),
     293                  expLst = {DAE.CALL(path = Absyn.IDENT(name = "previous"), expLst = expLst)},
     294                  attr = attr as DAE.CALL_ATTR(ty = ty))
     295      algorithm
     296        exp := DAE.CALL(Absyn.IDENT(name = "previous"), expLst, attr);
     297      then exp;
     298    // do nothing per default
     299    else inExp;
     300  end match;
     301end shiftDerVars;
     302
     303protected function applyEulerMethod1 "helper to applyEulerMethod"
     304  input DAE.Exp inExp;
     305  input list<DAE.ComponentRef> inDerVars;
     306  output DAE.Exp outExp;
     307  output list<DAE.ComponentRef> outDerVars;
     308algorithm
     309  (outExp, outDerVars) := Expression.traverseExpBottomUp(inExp, applyEulerMethod, inDerVars);
     310end applyEulerMethod1;
     311
     312protected function applyEulerMethod
     313"Convert continous-time to clocked expression by replacing
     314 der(x) -> (x - previous(x)) / interval().
     315 author: rfranke"
     316  input DAE.Exp inExp;
     317  input list<DAE.ComponentRef> inDerVars;
     318  output DAE.Exp outExp;
     319  output list<DAE.ComponentRef> outDerVars;
     320algorithm
     321  (outExp, outDerVars) := match inExp
     322    local
     323      List<DAE.Exp> expLst;
     324      DAE.CallAttributes attr;
     325      DAE.ComponentRef x;
     326      DAE.Type ty;
     327      DAE.Exp exp;
    233328    case DAE.CALL(path = Absyn.IDENT(name = "der"),
    234329                  expLst = expLst as {DAE.CREF(componentRef = x)},
    235330                  attr = attr as DAE.CALL_ATTR(ty = ty))
    236331      algorithm
    237         (inSolverMethod, inDerVars) := inTpl;
    238         outSolverMethod := "ImplicitEuler";
    239332        exp := DAE.CALL(Absyn.IDENT(name = "previous"), expLst, attr);
    240333        exp := DAE.BINARY(DAE.CREF(x, ty), DAE.SUB(DAE.T_REAL_DEFAULT), exp);
     
    242335                          DAE.CALL(Absyn.IDENT(name = "interval"), {},
    243336                                   DAE.callAttrBuiltinImpureReal));
    244         if outSolverMethod <> inSolverMethod then
    245           Error.addCompilerWarning("Solved clocked continuous equations with " +
    246                                    outSolverMethod + " instead of specified " +
    247                                    inSolverMethod + ".");
    248         end if;
    249       then (exp, (outSolverMethod, x :: inDerVars));
    250     else (inExp, inTpl);
    251   end match;
    252 end applySolverMethod;
     337      then (exp, x :: inDerVars);
     338    else (inExp, inDerVars);
     339  end match;
     340end applyEulerMethod;
    253341
    254342protected function markClockedStates
Note: See TracChangeset for help on using the changeset viewer.