#4237 closed defect (fixed)
Bad treatment of algebraic loops in synchronous models
Reported by: | Rüdiger Franke | Owned by: | Willi Braun |
---|---|---|---|
Priority: | high | Milestone: | 1.13.0 |
Component: | Backend | Version: | v1.12.0 |
Keywords: | Cc: | Willi Braun, Bernhard Thiele, Patrick Täuber |
Description (last modified by )
PR1391 along with commit d32ecb make ControlledMixingUnit
work by applying index reduction and appropriately implementing ExplicitEuler
, respectively.
Some more issues show up when replacing ExplicitEuler
with ImplicitEuler
, introducing algebraic loops. See the following example:
model ControlledMixingUnit2 extends Modelica_Synchronous.Examples.Systems.ControlledMixingUnit( periodicClock1(solverMethod="ImplicitEuler")); end ControlledMixingUnit2;
No Jacobians and no ModelStructure are generated!
Moreover, there is a linear torn system of dimension 1 -- shouldn't this be solved analytically?
Last but not least, the C runtime does not generate code for algebraic loops in clocked partitions.
Change History (20)
comment:1 by , 8 years ago
Description: | modified (diff) |
---|
comment:2 by , 8 years ago
Cc: | added |
---|
comment:3 by , 8 years ago
Owner: | changed from | to
---|---|
Status: | new → accepted |
Actually they are generated, but currently not processed by SimCodeUtil.
comment:4 by , 8 years ago
Replying to rfranke:
PR1391 along with commit d32ecb make
ControlledMixingUnit
work by applying index reduction and appropriately implementingExplicitEuler
, respectively.
Some more issues show up when replacing
ExplicitEuler
withImplicitEuler
, introducing algebraic loops. See the following example:
model ControlledMixingUnit2 extends Modelica_Synchronous.Examples.Systems.ControlledMixingUnit( periodicClock1(solverMethod="ImplicitEuler")); end ControlledMixingUnit2;No Jacobians and no ModelStructure are generated!
Moreover, there is a linear torn system of dimension 1 -- shouldn't this be solved analytically?
Last but not least, the C runtime does not generate code for algebraic loops in clocked partitions.
The Jacobians are now also generated at SimCode phase see commit 07d95e.
Now the generated code fails, because of unknown identifier:
error: use of undeclared identifier 'clockIndex'
How it is set in the clock partition equations?
Where is this value stored currently?
follow-up: 8 comment:5 by , 8 years ago
clockIndex is generated during code generation -- the index of the clocked partition / equation system. It is used to generate code for operators like interval()
, looking up the interval of a given clock.
follow-up: 7 comment:6 by , 8 years ago
Btw. you will also need to merge PR1391 to treat the high-index problem in the clocked partition.
comment:7 by , 8 years ago
comment:8 by , 8 years ago
Replying to rfranke:
clockIndex is generated during code generation -- the index of the clocked partition / equation system. It is used to generate code for operators like
interval()
, looking up the interval of a given clock.
Okay, is it possible to evaluate this index while compile time?
comment:9 by , 8 years ago
So far things like interval
are treated during code generation, along with event processing. The Cpp runtime generates a variable
const int clockIndex = <%index%>;
into each function that contains code for a clocked partition -- not yet in the Jacobian code.
Your new commit 07d95e loops through the clocked partitions. Would it be possible to store the iteration counter as one based clockIndex
in the Jacobian?
follow-up: 11 comment:10 by , 8 years ago
It appears painful to add something to a Jacibian, because it is defined as tuple, i.e. would require changes at many places. Alternatively the Jacobian vars can be added to the already existing SimCode.crefToClockIndexHT
-- e.g. used for clockIndex to modelDescription.xml.
This patch extends your commit 07d95e.
It works with an addition to the code generation like: Generate Jacobians for clocked partitions in Cpp runtime
-
SimCodeUtil.mo
old new 187 187 SimCode.HashTableCrefToSimVar crefToSimVarHT; 188 188 SimCodeFunction.MakefileParams makefileParams; 189 189 SimCode.ModelInfo modelInfo; 190 HashTable.HashTable crefToClockIndexHT ;190 HashTable.HashTable crefToClockIndexHT = HashTable.emptyHashTable(); 191 191 array<Integer> systemIndexMap; 192 192 list<BackendDAE.EqSystem> clockedSysts, contSysts; 193 193 //list<BackendDAE.Equation> paramAsserts, remEqLst; … … 384 384 SymbolicJacsNLS := listAppend(SymbolicJacsTemp, SymbolicJacsNLS); 385 385 (allEquations, numberofLinearSys, numberofNonLinearSys, numberofMixedSys, numberOfJacobians, SymbolicJacsTemp) := countandIndexAlgebraicLoops(allEquations, numberofLinearSys, numberofNonLinearSys, numberofMixedSys, numberOfJacobians, {}); 386 386 SymbolicJacsNLS := listAppend(SymbolicJacsTemp, SymbolicJacsNLS); 387 (clockedPartitions, numberofLinearSys, numberofNonLinearSys, numberofMixedSys, numberOfJacobians, SymbolicJacsTemp ) := countandIndexAlgebraicLoopsClockPartitions(clockedPartitions, numberofLinearSys, numberofNonLinearSys, numberofMixedSys, numberOfJacobians, {});387 (clockedPartitions, numberofLinearSys, numberofNonLinearSys, numberofMixedSys, numberOfJacobians, SymbolicJacsTemp, crefToClockIndexHT) := countandIndexAlgebraicLoopsClockPartitions(clockedPartitions, numberofLinearSys, numberofNonLinearSys, numberofMixedSys, numberOfJacobians, {}, crefToClockIndexHT); 388 388 SymbolicJacsNLS := listAppend(SymbolicJacsTemp, SymbolicJacsNLS); 389 389 390 390 // collect symbolic jacobians from state selection … … 472 472 //BaseHashTable.dumpHashTable(varToArrayIndexMapping); 473 473 //print("END MAPPING\n\n"); 474 474 475 (crefToClockIndexHT, _) := List.fold(inBackendDAE.eqs, collectClockedVars, ( HashTable.emptyHashTable(), 1));475 (crefToClockIndexHT, _) := List.fold(inBackendDAE.eqs, collectClockedVars, (crefToClockIndexHT, 1)); 476 476 477 477 simCode := SimCode.SIMCODE(modelInfo, 478 478 {}, // Set by the traversal below... … … 1200 1200 input Integer inMixedSysIndex; 1201 1201 input Integer inJacobianIndex; 1202 1202 input list<SimCode.JacobianMatrix> inSymJacs; 1203 input HashTable.HashTable inClkHT; 1203 1204 output list<SimCode.ClockedPartition> outColockPartition = {}; 1204 1205 output Integer outLinearSysIndex = inLinearSysIndex; 1205 1206 output Integer outNonLinSysIndex = inNonLinSysIndex; 1206 1207 output Integer outMixedSysIndex = inMixedSysIndex; 1207 1208 output Integer outJacobianIndex = inJacobianIndex; 1208 1209 output list<SimCode.JacobianMatrix> outSymJacs = inSymJacs; 1210 output HashTable.HashTable outClkHT = inClkHT; 1209 1211 protected 1210 1212 SimCode.SubPartition subPartitionTmp; 1211 1213 SimCode.ClockedPartition clockPartitionTmp; 1212 1214 list<SimCode.SubPartition> subPartitionsTmp; 1213 1215 list<SimCode.SimEqSystem> equations; 1216 SimCode.JacobianMatrix symJac; 1217 list<SimCode.JacobianColumn> columns; 1218 list<SimCodeVar.SimVar> simVars; 1219 Integer firstJacIdx, clockIndex = 0; 1214 1220 algorithm 1215 1221 for clockPartion in inColockPartition loop 1216 1222 subPartitionsTmp := {}; 1217 1223 for subPartion in clockPartion.subPartitions loop 1224 clockIndex := clockIndex + 1; 1225 firstJacIdx := listLength(outSymJacs) + 1; 1218 1226 (equations, outLinearSysIndex, outNonLinSysIndex, outMixedSysIndex, outJacobianIndex, outSymJacs) := 1219 1227 countandIndexAlgebraicLoops(subPartion.equations, outLinearSysIndex, outNonLinSysIndex, outMixedSysIndex, outJacobianIndex, outSymJacs); 1228 // add jac vars with clockIndex to outClkHT 1229 for i in firstJacIdx:listLength(outSymJacs) loop 1230 symJac := listGet(outSymJacs, i); 1231 (columns, simVars, _, _, _, _, _) := symJac; 1232 for simVar in simVars loop 1233 outClkHT := BaseHashTable.add((simVar.name, clockIndex), outClkHT); 1234 end for; 1235 for column in columns loop 1236 (_, simVars, _) := column; 1237 for simVar in simVars loop 1238 outClkHT := BaseHashTable.add((simVar.name, clockIndex), outClkHT); 1239 end for; 1240 end for; 1241 end for; 1220 1242 subPartitionTmp := SimCode.SUBPARTITION( 1221 1243 subPartion.vars, 1222 1244 equations,
comment:11 by , 8 years ago
Replying to rfranke:
It appears painful to add something to a Jacobian, because it is defined as tuple, i.e. would require changes at many places. Alternatively the Jacobian vars can be added to the already existing
SimCode.crefToClockIndexHT
-- e.g. used for clockIndex to modelDescription.xml.
True, therefor I started on Friday to rewrite them into records and add the clockIndex to the jacobian record, I'll add this later the day.
Since the clockIndex is a partition index, it's better to store it once in the jacobian, are you prefer your solution with the variables?
comment:12 by , 8 years ago
A Jacobian record with member clockIndex would of course be preferred. The variables need the clockIndex if they appear in modelDescription.xml. Once the clockIndex is available in the Jacobian, a separate function could transfer that info to crefToClockIndexHT on demand.
follow-up: 14 comment:13 by , 8 years ago
In PR1439 the jacobian got partition index support.
In the c-runtime we the function "firstTick()" is not found in the jacobians.
@lochel Where is this defined?
comment:14 by , 8 years ago
Replying to wbraun:
In the c-runtime we the function "firstTick()" is not found in the jacobians.
@lochel Where is this defined?
MCP-0024
follow-up: 16 comment:15 by , 8 years ago
With fixing ticket:4237: Support of clockPartitions in jacobians the example ControlledMixingUnit2
gets clock indices 1, 2 and 3. It should only be 1. Moreover, continuous-time models get a clockIndex 3, which is wrong -- it should be 0 if appearing at all in non-synchronous model code.
comment:16 by , 8 years ago
Replying to rfranke:
With fixing ticket:4237: Support of clockPartitions in jacobians the example
ControlledMixingUnit2
gets clock indices 1, 2 and 3. It should only be 1. Moreover, continuous-time models get a clockIndex 3, which is wrong -- it should be 0 if appearing at all in non-synchronous model code.
Okay, should be fixed with PR1442.
comment:17 by , 7 years ago
Milestone: | 1.12.0 → 1.13.0 |
---|
Milestone moved to 1.13.0 due to 1.12.0 already being released.
comment:19 by , 7 years ago
Resolution: | → fixed |
---|---|
Status: | accepted → closed |
Yes, this ticket can be closed.
Just opened the new ticket #4783 about a new issue.
Moreover, the FMI ModelStructure is still missing for clocked partitions. Will open a new ticket as well -- don't we already have another ticket for this?
Patrick, can you please have a look at the torn system?