@@ -188,10 +188,31 @@ algorithm
188188 BackendDAE . CLOCKED_PARTITION (idx) := syst. partitionKind;
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 ;
197218 syst. orderedEqs := BackendEquation . listEquation(listReverse(lstEqs));
@@ -203,53 +224,120 @@ algorithm
203224 outSysts := listReverse(outSysts);
204225end treatClockedStates;
205226
206- protected function applySolverMethod1 "helper to applySolverMethod "
227+ protected function getDerVars1 "helper to getDerVars "
207228 input DAE . Exp inExp;
208- input tuple < String , list< DAE . ComponentRef >> inTpl ;
229+ input list< DAE . ComponentRef > inDerVars ;
209230 output DAE . Exp outExp;
210- output tuple < String , list< DAE . ComponentRef >> outTpl ;
231+ output list< DAE . ComponentRef > outDerVars ;
211232algorithm
212- (outExp, outTpl ) := Expression . traverseExpBottomUp(inExp, applySolverMethod, inTpl );
213- end applySolverMethod1 ;
233+ (outExp, outDerVars ) := Expression . traverseExpBottomUp(inExp, getDerVars, inDerVars );
234+ end getDerVars1 ;
214235
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().
236+ protected 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;
243+ algorithm
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;
252+ end getDerVars;
253+
254+ protected 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 ;
258+ output list< DAE . ComponentRef > outDerVars ;
223259algorithm
224- (outExp, outTpl) := match inExp
260+ (outExp, outDerVars) := Expression . traverseExpBottomUp(inExp, shiftDerVars, inDerVars);
261+ end shiftDerVars1;
262+
263+ protected 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;
270+ algorithm
271+ outExp := match inExp
272+ local
273+ List < DAE . Exp > expLst;
274+ DAE . CallAttributes attr;
275+ DAE . ComponentRef x;
276+ DAE . Type ty;
277+ DAE . Exp exp;
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;
301+ end shiftDerVars;
302+
303+ protected 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;
308+ algorithm
309+ (outExp, outDerVars) := Expression . traverseExpBottomUp(inExp, applyEulerMethod, inDerVars);
310+ end applyEulerMethod1;
311+
312+ protected 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;
320+ algorithm
321+ (outExp, outDerVars) := match inExp
225322 local
226323 List < DAE . Exp > expLst;
227324 DAE . CallAttributes attr;
228325 DAE . ComponentRef x;
229326 DAE . Type ty;
230327 DAE . Exp exp;
231- String inSolverMethod, outSolverMethod;
232- list< DAE . ComponentRef > inDerVars;
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);
241334 exp := DAE . BINARY (exp, DAE . DIV (DAE . T_REAL_DEFAULT ),
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);
337+ then (exp, x :: inDerVars);
338+ else (inExp, inDerVars);
251339 end match;
252- end applySolverMethod ;
340+ end applyEulerMethod ;
253341
254342protected function markClockedStates
255343"Collect discrete states and mark them for further processing.
0 commit comments