Skip to content

Commit

Permalink
- bugfix dynamic state selection
Browse files Browse the repository at this point in the history
git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@14710 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
Jens Frenkel committed Jan 8, 2013
1 parent 366d77f commit 2ba0b38
Show file tree
Hide file tree
Showing 3 changed files with 229 additions and 28 deletions.
58 changes: 54 additions & 4 deletions Compiler/BackEnd/IndexReduction.mo
Expand Up @@ -2197,6 +2197,7 @@ algorithm
BackendDAE.EquationArray eqns;
list<BackendDAE.Equation> cEqnsLst,oEqnLst;
BackendDAE.StateSets stateSets;
DAE.ElementSource source;
case ({},_,_,_,_) then (iSetIndex,iVars,iEqns,iStateSets);
case ((nStates,nStateCandidates,nUnassignedEquations,stateCandidates,cEqnsLst,otherVars,oEqnLst)::rest,_,_,_,_)
equation
Expand All @@ -2222,9 +2223,10 @@ algorithm
((mulAdstates,(_,_))) = BackendDAEUtil.extendArrExp((mulAdstates,(NONE(),false)));
expset = Util.if_(intGt(rang,1),DAE.ARRAY(DAE.T_ARRAY(DAE.T_REAL_DEFAULT,{DAE.DIM_INTEGER(rang)},DAE.emptyTypeSource),true,expcrset),listGet(expcrset,1));
expderset = Util.if_(intGt(rang,1),DAE.ARRAY(DAE.T_ARRAY(DAE.T_REAL_DEFAULT,{DAE.DIM_INTEGER(rang)},DAE.emptyTypeSource),true,expcrdset),listGet(expcrdset,1));
source = DAE.SOURCE(Absyn.INFO("stateselection",false,0,0,0,0,Absyn.dummyTimeStamp),{},{},{},{},{},{});
// set.x = set.A*set.statecandidates
eqn = Util.if_(intGt(rang,1),BackendDAE.ARRAY_EQUATION({rang},expset,mulAstates,DAE.emptyElementSource,false),
BackendDAE.EQUATION(expset,mulAstates,DAE.emptyElementSource,false));
eqn = Util.if_(intGt(rang,1),BackendDAE.ARRAY_EQUATION({rang},expset,mulAstates,source,false),
BackendDAE.EQUATION(expset,mulAstates,source,false));
// der(set.x) = set.A*der(set.candidates)
deqn = Util.if_(intGt(rang,1),BackendDAE.ARRAY_EQUATION({rang},expderset,mulAdstates,DAE.emptyElementSource,false),
BackendDAE.EQUATION(expderset,mulAdstates,DAE.emptyElementSource,false));
Expand Down Expand Up @@ -6136,6 +6138,54 @@ algorithm
end match;
end consArrayUpdate;



public function splitEqnsinConstraintAndOther
"function: splitEqnsinConstraintAndOther
author: Frenkel TUD 2013-01
splitt the list of set equations in constrained equations and other equations"
input list<BackendDAE.Var> inVarLst;
input list<BackendDAE.Equation> inEqnsLst;
input BackendDAE.Shared shared;
output list<BackendDAE.Equation> outCEqnsLst;
output list<BackendDAE.Equation> outOEqnsLst;
protected
list<BackendDAE.Equation> eqnslst;
BackendDAE.Variables vars;
BackendDAE.EquationArray eqns;
BackendDAE.EqSystem syst;
BackendDAE.AdjacencyMatrixEnhanced me;
array<list<Integer>> mapEqnIncRow;
array<Integer> mapIncRowEqn;
BackendDAE.IncidenceMatrix m;
Integer ne,nv;
array<Integer> vec1,vec2;
list<Integer> unassigned,assigned;
algorithm
vars := BackendVariable.listVar1(inVarLst);
(eqnslst,_) := BackendDAEOptimize.getScalarArrayEqns(inEqnsLst,{},false);
eqns := BackendEquation.listEquation(eqnslst);
syst := BackendDAE.EQSYSTEM(vars,eqns,NONE(),NONE(),BackendDAE.NO_MATCHING(),{});
(me,_,mapEqnIncRow,mapIncRowEqn) := BackendDAEUtil.getAdjacencyMatrixEnhancedScalar(syst, shared);
m := incidenceMatrixfromEnhanced2(me,vars);
// match the equations, umatched are constrained equations
nv := BackendVariable.varsSize(vars);
ne := BackendDAEUtil.equationSize(eqns);
vec1 := arrayCreate(nv,-1);
vec2 := arrayCreate(ne,-1);
Matching.matchingExternalsetIncidenceMatrix(nv,ne,m);
BackendDAEEXT.matching(nv,ne,5,-1,1.0,1);
BackendDAEEXT.getAssignment(vec2,vec1);
unassigned := Matching.getUnassigned(ne, vec2, {});
assigned := Matching.getAssigned(ne, vec2, {});
unassigned := List.map1r(unassigned,arrayGet,mapIncRowEqn);
unassigned := List.uniqueIntN(unassigned, ne);
outCEqnsLst := BackendEquation.getEqns(unassigned, eqns);
assigned := List.map1r(assigned,arrayGet,mapIncRowEqn);
assigned := List.uniqueIntN(assigned, ne);
outOEqnsLst := BackendEquation.getEqns(assigned, eqns);
end splitEqnsinConstraintAndOther;

/*****************************************
calculation of the determinant of a square matrix .
*****************************************/
Expand Down Expand Up @@ -6689,9 +6739,9 @@ algorithm
crset := Debug.bcallret3(intGt(setsize,1),List.map1r,range, ComponentReference.subscriptCrefWithInt, crstates,{crstates});
oSetVars := List.map4(crset,generateVar,BackendDAE.STATE(1),DAE.T_REAL_DEFAULT,{},NONE());
oSetVars := List.map1(oSetVars,BackendVariable.setVarFixed,false);
tp := Util.if_(intGt(setsize,1),DAE.T_ARRAY(DAE.T_INTEGER_DEFAULT,{DAE.DIM_INTEGER(nStates),DAE.DIM_INTEGER(setsize)}, DAE.emptyTypeSource),
tp := Util.if_(intGt(setsize,1),DAE.T_ARRAY(DAE.T_INTEGER_DEFAULT,{DAE.DIM_INTEGER(setsize),DAE.DIM_INTEGER(nStates)}, DAE.emptyTypeSource),
DAE.T_ARRAY(DAE.T_INTEGER_DEFAULT,{DAE.DIM_INTEGER(nStates)}, DAE.emptyTypeSource));
realtp := Util.if_(intGt(setsize,1),DAE.T_ARRAY(DAE.T_REAL_DEFAULT,{DAE.DIM_INTEGER(nStates),DAE.DIM_INTEGER(setsize)}, DAE.emptyTypeSource),
realtp := Util.if_(intGt(setsize,1),DAE.T_ARRAY(DAE.T_REAL_DEFAULT,{DAE.DIM_INTEGER(setsize),DAE.DIM_INTEGER(nStates)}, DAE.emptyTypeSource),
DAE.T_ARRAY(DAE.T_REAL_DEFAULT,{DAE.DIM_INTEGER(nStates)}, DAE.emptyTypeSource));
ocrA := ComponentReference.joinCrefs(set,ComponentReference.makeCrefIdent("A",tp,{}));
oAVars := generateArrayVar(ocrA,BackendDAE.VARIABLE(),tp,NONE());
Expand Down
11 changes: 8 additions & 3 deletions Compiler/BackEnd/Matching.mo
Expand Up @@ -6552,12 +6552,17 @@ protected
DAE.ElementSource source;
Absyn.Info info;
array<Integer> mapIncRowEqn;
BackendDAE.EqSystem syst;
algorithm
// BackendDump.printEqSystem(isyst);
// BackendDump.dumpMatching(inAssignments1);
// BackendDump.dumpMatching(inAssignments2);
(_,_,_,mapIncRowEqn,_) := inArg;
n := BackendDAEUtil.systemSize(isyst);
// for debugging
/* BackendDump.printEqSystem(isyst);
BackendDump.dumpMatching(inAssignments1);
BackendDump.dumpMatching(inAssignments2);
syst := BackendDAEUtil.setEqSystemMatching(isyst, BackendDAE.MATCHING(inAssignments1,inAssignments2,{}));
IndexReduction.dumpSystemGraphML(syst,ishared,NONE(),"SingularSystem" +& intString(n) +& ".graphml");
*/
// get from scalar eqns indexes the indexes in the equation array
unmatched := List.select1(List.flatten(eqns),intLe,n);
unmatched1 := List.map1r(unmatched,arrayGet,mapIncRowEqn);
Expand Down
188 changes: 167 additions & 21 deletions Compiler/BackEnd/SimCodeUtil.mo
Expand Up @@ -82,6 +82,7 @@ protected import ExpressionSimplify;
protected import ExpressionSolve;
protected import Flags;
protected import HashSet;
protected import IndexReduction;
protected import Initialization;
protected import Inline;
protected import InlineSolver;
Expand Down Expand Up @@ -1893,15 +1894,14 @@ algorithm
equation
funcs = BackendDAEUtil.getFunctions(shared);
(syst,_,_) = BackendDAEUtil.getIncidenceMatrixfromOption(syst, BackendDAE.ABSOLUTE(),SOME(funcs));
stateeqnsmark = arrayCreate(BackendDAEUtil.equationArraySizeDAE(syst), 0);
stateeqnsmark = arrayCreate(BackendDAEUtil.equationArraySizeDAE(syst), 0);
stateeqnsmark = BackendDAEUtil.markStateEquations(syst, stateeqnsmark, ass1);
(odeEquations1,algebraicEquations1,allEquations1,uniqueEqIndex,tempvars) = createEquationsForSystem1(stateeqnsmark, syst, shared, comps, helpVarInfo,iuniqueEqIndex,itempvars);
odeEquations = odeEquations1::odeEquations;
algebraicEquations = listAppend(algebraicEquations,algebraicEquations1);
allEquations = listAppend(allEquations,allEquations1);
(uniqueEqIndex,odeEquations,algebraicEquations,allEquations,tempvars) = createEquationsForSystems(systs,shared,helpVarInfo,uniqueEqIndex,odeEquations,algebraicEquations,allEquations,tempvars);
then (uniqueEqIndex,odeEquations,algebraicEquations,allEquations,tempvars);

end match;
end createEquationsForSystems;

Expand Down Expand Up @@ -4198,17 +4198,16 @@ algorithm
tuple<list<SimCode.SimEqSystem>,Integer,list<SimCode.SimVar>> tpl;
list<SimCode.StateSet> equations;
Integer uniqueEqIndex,numStateSets;
list<SimCode.SimVar> tempvars;
DAE.FunctionTree functree;
list<SimCode.SimVar> tempvars;
BackendDAE.StrongComponents comps;
// no stateSet
case (BackendDAE.EQSYSTEM(stateSets={}),_) then (isyst,sharedChanged);
// sets
case (BackendDAE.EQSYSTEM(orderedVars=vars,orderedEqs=eqns,m=m,mT=mT,matching=matching,stateSets=stateSets),
case (BackendDAE.EQSYSTEM(orderedVars=vars,orderedEqs=eqns,m=m,mT=mT,matching=matching as BackendDAE.MATCHING(comps=comps),stateSets=stateSets),
(shared,(equations,uniqueEqIndex,tempvars,numStateSets)))
equation
knvars = BackendVariable.daeKnVars(shared);
functree = BackendDAEUtil.getFunctions(shared);
(vars,equations,uniqueEqIndex,tempvars,numStateSets) = createStateSetsSets(stateSets,vars,knvars,functree,equations,uniqueEqIndex,tempvars,numStateSets);

(vars,equations,uniqueEqIndex,tempvars,numStateSets) = createStateSetsSets(stateSets,vars,eqns,shared,comps,equations,uniqueEqIndex,tempvars,numStateSets);
then
(BackendDAE.EQSYSTEM(vars,eqns,m,mT,matching,stateSets),(shared,(equations,uniqueEqIndex,tempvars,numStateSets)));
end match;
Expand All @@ -4217,8 +4216,9 @@ end createStateSetsSystem;
protected function createStateSetsSets
input BackendDAE.StateSets iStateSets;
input BackendDAE.Variables iVars;
input BackendDAE.Variables knVars;
input DAE.FunctionTree functree;
input BackendDAE.EquationArray iEqns;
input BackendDAE.Shared shared;
input BackendDAE.StrongComponents comps;
input list<SimCode.StateSet> iEquations;
input Integer iuniqueEqIndex;
input list<SimCode.SimVar> itempvars;
Expand All @@ -4230,25 +4230,77 @@ protected function createStateSetsSets
output Integer oNumStateSets;
algorithm
(oVars,oEquations,ouniqueEqIndex,otempvars,oNumStateSets) :=
matchcontinue(iStateSets,iVars,knVars,functree,iEquations,iuniqueEqIndex,itempvars,iNumStateSets)
matchcontinue(iStateSets,iVars,iEqns,shared,comps,iEquations,iuniqueEqIndex,itempvars,iNumStateSets)
local
DAE.FunctionTree functree;
BackendDAE.StateSets sets;
Integer rang,numStateSets,nCandidates;
Integer rang,numStateSets,nCandidates,index;
list<DAE.ComponentRef> crset;
DAE.ComponentRef crA,crJ;
BackendDAE.Variables vars;
list<BackendDAE.Var> aVars,statevars,dstatesvars,varJ;
list<BackendDAE.Equation> ceqns,oeqns;
BackendDAE.Variables vars,knVars;
list<BackendDAE.Var> aVars,statevars,dstatesvars,varJ,compvars;
list<BackendDAE.Equation> ceqns,oeqns,compeqns;
list<DAE.ComponentRef> crstates;
SimCode.JacobianMatrix jacobianMatrix;
list<SimCode.StateSet> simequations;
list<SimCode.SimVar> tempvars;
Integer uniqueEqIndex;
BackendDAE.Variables diffVars,ovars;
BackendDAE.EquationArray eqnsarr,oeqnsarr;
case({},_,_,_,_,_,_,_) then (iVars,iEquations,iuniqueEqIndex,itempvars,iNumStateSets);
case(BackendDAE.STATESET(rang=rang,state=crset,crA=crA,varA=aVars,statescandidates=statevars,ovars=dstatesvars,eqns=ceqns,oeqns=oeqns,crJ=crJ,varJ=varJ)::sets,_,_,_,_,_,_,_)
BackendDAE.EquationArray eqnsarr,oeqnsarr;
HashSet.HashSet hs;
array<Boolean> marked;
case({},_,_,_,_,_,_,_,_) then (iVars,iEquations,iuniqueEqIndex,itempvars,iNumStateSets);

case(BackendDAE.STATESET(rang=rang,state=crset,crA=crA,varA=aVars,statescandidates=statevars,ovars=dstatesvars,crJ=crJ,varJ=varJ)::sets,_,_,_,_,_,_,_,_)
equation
knVars = BackendVariable.daeKnVars(shared);
functree = BackendDAEUtil.getFunctions(shared);
// get state names
crstates = List.map(statevars,BackendVariable.varCref);
marked = arrayCreate(BackendVariable.varsSize(iVars),false);
// get Equations for Jac from the strong component
marked = List.fold1(crstates,markSetStates,iVars,marked);
(compeqns,compvars) = getStateSetCompVarEqns(comps,marked,iEqns,iVars,{},{});
// remove the state set equation
compeqns = List.select(compeqns, removeStateSetEqn);
// remove the state candidates to geht the other vars
hs = List.fold(crstates,BaseHashSet.add,HashSet.emptyHashSet());
compvars = List.select1(compvars, removeStateSetStates,hs);
// match the equations to get the residual equations
(ceqns,oeqns) = IndexReduction.splitEqnsinConstraintAndOther(compvars,compeqns,shared);
// add vars for A
vars = BackendVariable.addVars(aVars,iVars);
// change state vars to ders
compvars = List.map(compvars,transformXToXd);
// replace der in equations
ceqns = replaceDerOpInEquationList(ceqns);
oeqns = replaceDerOpInEquationList(oeqns);
// convert ceqns to res[..] = lhs-rhs
ceqns = createResidualSetEquations(ceqns,crJ,1,intGt(listLength(ceqns),1),{});
// get first a element for varinfo
crA = ComponentReference.subscriptCrefWithInt(crA,1);
crA = Debug.bcallret2(intGt(listLength(crset),1),ComponentReference.subscriptCrefWithInt,crA,1,crA);
// number of states
nCandidates = listLength(statevars);

// create symbolic jacobian for simulation
//oeqnsarr = BackendEquation.listEquation(oeqns);
//eqnsarr = BackendEquation.listEquation(ceqns);
//diffVars = BackendVariable.listVar1(statevars);
//ovars = BackendVariable.listVar1(dstatesvars);
//(SOME(jacobianMatrix),uniqueEqIndex,tempvars) = createSymbolicSimulationJacobian(diffVars, knVars, eqnsarr, oeqnsarr, ovars, functree, vars, "StateSetJac", iuniqueEqIndex,itempvars);

// create symbolic jacobian for simulation
(jacobianMatrix,uniqueEqIndex,tempvars) = createSymbolicSimulationJacobianSet(statevars, knVars, varJ, ceqns, compvars, oeqns, vars, functree, iuniqueEqIndex,itempvars);
// next set
(vars,simequations,uniqueEqIndex,tempvars,numStateSets) = createStateSetsSets(sets,vars,iEqns,shared,comps,SimCode.SES_STATESET(iuniqueEqIndex,nCandidates,rang,crset,crstates,crA,jacobianMatrix)::iEquations,uniqueEqIndex,tempvars,iNumStateSets+1);
then
(vars,simequations,uniqueEqIndex,tempvars,numStateSets);

case(BackendDAE.STATESET(rang=rang,state=crset,crA=crA,varA=aVars,statescandidates=statevars,ovars=dstatesvars,eqns=ceqns,oeqns=oeqns,crJ=crJ,varJ=varJ)::sets,_,_,_,_,_,_,_,_)
equation
knVars = BackendVariable.daeKnVars(shared);
functree = BackendDAEUtil.getFunctions(shared);
// ToDo: get Equations for Jac from the strong component with crset equation
// add vars for A
vars = BackendVariable.addVars(aVars,iVars);
Expand All @@ -4275,12 +4327,106 @@ algorithm
// create symbolic jacobian for simulation
(jacobianMatrix,uniqueEqIndex,tempvars) = createSymbolicSimulationJacobianSet(statevars, knVars, varJ, ceqns, dstatesvars, oeqns, vars, functree, iuniqueEqIndex,itempvars);
// next set
(vars,simequations,uniqueEqIndex,tempvars,numStateSets) = createStateSetsSets(sets,vars,knVars,functree,SimCode.SES_STATESET(iuniqueEqIndex,nCandidates,rang,crset,crstates,crA,jacobianMatrix)::iEquations,uniqueEqIndex,tempvars,iNumStateSets+1);
(vars,simequations,uniqueEqIndex,tempvars,numStateSets) = createStateSetsSets(sets,vars,iEqns,shared,comps,SimCode.SES_STATESET(iuniqueEqIndex,nCandidates,rang,crset,crstates,crA,jacobianMatrix)::iEquations,uniqueEqIndex,tempvars,iNumStateSets+1);
then
(vars,simequations,uniqueEqIndex,tempvars,numStateSets);
end matchcontinue;
end createStateSetsSets;

protected function markSetStates
input DAE.ComponentRef inCr;
input BackendDAE.Variables iVars;
input array<Boolean> iMark;
output array<Boolean> oMark;
protected
Integer index;
algorithm
(_,{index}) := BackendVariable.getVar(inCr, iVars);
oMark := arrayUpdate(iMark,index,true);
end markSetStates;

protected function removeStateSetStates
input BackendDAE.Var inVar;
input HashSet.HashSet hs;
output Boolean b;
algorithm
b := not BaseHashSet.has(BackendVariable.varCref(inVar),hs);
end removeStateSetStates;

protected function removeStateSetEqn
input BackendDAE.Equation inEqn;
output Boolean b;
algorithm
b := match(inEqn)
case BackendDAE.ARRAY_EQUATION(source=DAE.SOURCE(info=Absyn.INFO(fileName="stateselection"))) then false;
case BackendDAE.EQUATION(source=DAE.SOURCE(info=Absyn.INFO(fileName="stateselection"))) then false;
else then true;
end match;
end removeStateSetEqn;

protected function foundMarked
input list<Integer> ilst;
input array<Boolean> marked;
output Boolean found;
algorithm
found := match(ilst,marked)
local
Boolean b;
Integer i;
list<Integer> rest;
case ({},_) then false;
case (i::rest,_)
equation
b = marked[i];
b = Debug.bcallret2(not b,foundMarked,rest,marked,b);
then
b;
end match;
end foundMarked;

protected function getStateSetCompVarEqns
"function: getEquationAndSolvedVar
author: Frenkel TUD 2013-01
Retrieves the equation and the variable for a state set"
input BackendDAE.StrongComponents inComp;
input array<Boolean> marked;
input BackendDAE.EquationArray inEquationArray;
input BackendDAE.Variables inVariables;
input list<BackendDAE.Equation> inEquations;
input list<BackendDAE.Var> inVars;
output list<BackendDAE.Equation> outEquations;
output list<BackendDAE.Var> outVars;
algorithm
(outEquations,outVars):=
matchcontinue (inComp,marked,inEquationArray,inVariables,inEquations,inVars)
local
list<Integer> elst,vlst,indxlst;
list<BackendDAE.Equation> eqnlst;
list<BackendDAE.Var> varlst;
BackendDAE.StrongComponent comp;
list<tuple<Integer,list<Integer>>> eqnvartpllst;
BackendDAE.StrongComponents rest,acc;
Boolean b1,b2;
case ({},_,_,_,_,_) then (inEquations,inVars);
case (comp::rest,_,_,_,_,_)
equation
(elst,vlst) = BackendDAETransform.getEquationAndSolvedVarIndxes(comp);
true = foundMarked(vlst,marked);
eqnlst = BackendEquation.getEqns(elst,inEquationArray);
varlst = List.map1r(vlst, BackendVariable.getVarAt, inVariables);
eqnlst = listAppend(eqnlst,inEquations);
varlst = listAppend(varlst,inVars);
(eqnlst,varlst) = getStateSetCompVarEqns(rest,marked,inEquationArray,inVariables,eqnlst,varlst);
then
(eqnlst,varlst);
case (_::rest,_,_,_,_,_)
equation
(eqnlst,varlst) = getStateSetCompVarEqns(rest,marked,inEquationArray,inVariables,inEquations,inVars);
then
(eqnlst,varlst);
end matchcontinue;
end getStateSetCompVarEqns;

protected function createSymbolicSimulationJacobianSet
"fuction createSymbolicSimulationJacobian
function creates a symbolic jacobian column for
Expand Down Expand Up @@ -4355,8 +4501,8 @@ algorithm
knvars = BackendVariable.removeCrefs(otherVarsLstComRefs,knvars);
knvars = BackendVariable.mergeVariables(knvars,allvars);

Debug.fcall(Flags.JAC_DUMP2, print, "\n---+++ known variables +++---\n");
Debug.fcall(Flags.JAC_DUMP2, BackendDump.printVariables, inKnVars);
//Debug.fcall(Flags.JAC_DUMP2, print, "\n---+++ known variables +++---\n");
//Debug.fcall(Flags.JAC_DUMP2, BackendDump.printVariables, inKnVars);

residualVarsLst = inResVars;

Expand Down

0 comments on commit 2ba0b38

Please sign in to comment.