Skip to content

Commit

Permalink
- Evaluate constant linear equation systems in SimCode (wrong place, …
Browse files Browse the repository at this point in the history
…but that's where it currentlt fits)

git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@8940 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed May 11, 2011
1 parent f4688aa commit ba57249
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 8 deletions.
38 changes: 38 additions & 0 deletions Compiler/BackEnd/BackendDAEOptimize.mo
Expand Up @@ -56,6 +56,7 @@ protected import BackendEquation;
protected import BackendVarTransform;
protected import BackendVariable;
protected import Builtin;
protected import Ceval;
protected import ClassInf;
protected import ComponentReference;
protected import DAEUtil;
Expand Down Expand Up @@ -3512,6 +3513,43 @@ algorithm
end matchcontinue;
end splitComps;

public function evaluateConstantJacobian
"Evaluate a constant jacobian so we can solve a linear system during runtime"
input Integer size;
input list<tuple<Integer,Integer,BackendDAE.Equation>> jac;
output list<list<Real>> vals;
protected
array<array<Real>> valarr;
array<Real> tmp;
list<array<Real>> tmp2;
list<Real> rs;
algorithm
rs := Util.listFill(0.0,size);
tmp := listArray(rs);
tmp2 := Util.listMap(Util.listFill(tmp,size),arrayCopy);
valarr := listArray(tmp2);
Util.listMap01(jac,valarr,evaluateConstantJacobian2);
tmp2 := arrayList(valarr);
vals := Util.listMap(tmp2,arrayList);
end evaluateConstantJacobian;

protected function evaluateConstantJacobian2
input tuple<Integer,Integer,BackendDAE.Equation> jac;
input array<array<Real>> vals;
algorithm
_ := match (jac,vals)
local
DAE.Exp exp;
Integer i1,i2;
Real r;
case ((i1,i2,BackendDAE.RESIDUAL_EQUATION(exp=exp)),vals)
equation
Values.REAL(r) = Ceval.cevalSimple(exp);
_ = arrayUpdate(arrayGet(vals,i1),i2,r);
then ();
end match;
end evaluateConstantJacobian2;

protected function solveEquations
" function: solveEquations
try to solve the equations"
Expand Down
74 changes: 67 additions & 7 deletions Compiler/BackEnd/SimCode.mo
Expand Up @@ -4554,7 +4554,6 @@ algorithm
equations_;
case (_,_,_,_,_,_,_,_)
equation
print("Failure: ...\n");
Error.addMessage(Error.INTERNAL_ERROR, {"createOdeSystem failed"});
then
fail();
Expand Down Expand Up @@ -4769,8 +4768,10 @@ algorithm
list<tuple<Integer, Integer, BackendDAE.Equation>> jac;
list<tuple<Integer, Integer, SimEqSystem>> simJac;
array<BackendDAE.MultiDimEquation> arrayEqs;
Integer index;
Integer index,linInfo;
array< .DAE.Algorithm> algorithms;
list<list<Real>> jacVals;
list<Real> rhsVals,solvedVals;
BackendDAE.ExternalObjectClasses eoc;
BackendDAE.AliasVariables ave;

Expand All @@ -4793,12 +4794,19 @@ algorithm
// constant jacobians. Linear system of equations (A x = b) where
// A and b are constants. TODO: implement symbolic gaussian elimination
// here. Currently uses dgesv as for next case
case (mixedEvent,genDiscrete,skipDiscInAlgorithm,(d as BackendDAE.DAE(orderedEqs = eqn)),SOME(jac),BackendDAE.JAC_CONSTANT(),block_,helpVarInfo)
case (mixedEvent,genDiscrete,skipDiscInAlgorithm,(d as BackendDAE.DAE(orderedVars = v,knownVars = kv,orderedEqs = eqn, arrayEqs = arrayEqs)),SOME(jac),BackendDAE.JAC_CONSTANT(),block_,helpVarInfo)
equation
eqn_size = BackendDAEUtil.equationSize(eqn);
// NOTE: Not impl. yet, use time_varying...
equations_ = createOdeSystem2(mixedEvent, genDiscrete, skipDiscInAlgorithm, d, SOME(jac),
BackendDAE.JAC_TIME_VARYING(), block_,helpVarInfo);
((simVars,_)) = BackendVariable.traverseBackendDAEVars(v,traversingdlowvarToSimvar,({},kv));
simVars = listReverse(simVars);
((_,_,_,beqs)) = BackendEquation.traverseBackendDAEEqns(eqn,dlowEqToExp,(v,arrayEqs,{},{}));
beqs = listReverse(beqs);
rhsVals = ValuesUtil.valueReals(Util.listMap(beqs,Ceval.cevalSimple));
jacVals = BackendDAEOptimize.evaluateConstantJacobian(listLength(simVars),jac);
(solvedVals,linInfo) = System.solveLinearSystem(jacVals,rhsVals);
checkLinearSystem(linInfo,simVars,jacVals,rhsVals);
// TODO: Move these to known vars :/ This is done in the wrong phase of the compiler... Also, if done as an optimization module, we can optimize more!
equations_ = Util.listThreadMap(simVars,solvedVals,generateSolvedEquation);
then
equations_;

Expand Down Expand Up @@ -4868,6 +4876,50 @@ algorithm
end matchcontinue;
end createOdeSystem2;

protected function checkLinearSystem
input Integer info;
input list<SimVar> vars;
input list<list<Real>> jac;
input list<Real> rhs;
algorithm
_ := matchcontinue (info,vars,jac,rhs)
local
String infoStr,syst,varnames,varname,rhsStr,jacStr;
case (0,_,_,_) then ();
case (info,vars,jac,rhs)
equation
true = info > 0;
varname = varName(listGet(vars,info));
infoStr = intString(info);
varnames = Util.stringDelimitList(Util.listMap(vars,varName)," ;\n ");
rhsStr = Util.stringDelimitList(Util.listMap(rhs, realString)," ;\n ");
jacStr = Util.stringDelimitList(Util.listMap1(Util.listListMap(jac,realString),Util.stringDelimitList," , ")," ;\n ");
syst = stringAppendList({"\n[\n ", jacStr, "\n]\n *\n[\n ",varnames,"\n]\n =\n[\n ",rhsStr,"\n]"});
Error.addMessage(Error.LINEAR_SYSTEM_SINGULAR, {syst,infoStr,varname});
then fail();
case (info,vars,jac,rhs)
equation
true = info < 0;
varnames = Util.stringDelimitList(Util.listMap(vars,varName)," ; ");
rhsStr = Util.stringDelimitList(Util.listMap(rhs, realString)," ; ");
jacStr = Util.stringDelimitList(Util.listMap1(Util.listListMap(jac,realString),Util.stringDelimitList," , ")," ; ");
syst = stringAppendList({"[", jacStr, "] * [",varnames,"] = [",rhsStr,"]"});
Error.addMessage(Error.LINEAR_SYSTEM_INVALID, {"LAPACK/dgesv",syst});
then fail();
end matchcontinue;
end checkLinearSystem;

protected function generateSolvedEquation
input SimVar var;
input Real val;
output SimEqSystem eq;
protected
DAE.ComponentRef name;
algorithm
SIMVAR(name=name) := var;
eq := SES_SIMPLE_ASSIGN(name,DAE.RCONST(val),DAE.emptyElementSource);
end generateSolvedEquation;

protected function replaceDerOpInEquationList
"Replaces all der(cref) with $DER.cref in a list of equations."
input list<BackendDAE.Equation> inEqns;
Expand Down Expand Up @@ -11360,7 +11412,15 @@ algorithm str := matchcontinue(vf)
end matchcontinue;
end dumpVarInfo;


protected function varName
input SimVar var;
output String name;
protected
DAE.ComponentRef cr;
algorithm
SIMVAR(name=cr) := var;
name := ComponentReference.printComponentRefStr(cr);
end varName;



Expand Down
8 changes: 8 additions & 0 deletions Compiler/FrontEnd/Ceval.mo
Expand Up @@ -6339,5 +6339,13 @@ algorithm
end match;
end backpatchArrayReduction3;

public function cevalSimple
"A simple expression does not need cache, etc"
input DAE.Exp exp;
output Values.Value val;
algorithm
(_,val,_) := ceval(Env.emptyCache(),{},exp,false,NONE(),NONE(),MSG());
end cevalSimple;

end Ceval;

6 changes: 5 additions & 1 deletion Compiler/Script/CevalScript.mo
Expand Up @@ -808,7 +808,10 @@ algorithm
then
(cache,ret_val,st_1);

case (cache,env,"translateModelCPP",{Values.CODE(Absyn.C_TYPENAME(className)),Values.STRING(filenameprefix)},st,msg)
case (cache,env,"translateModel",_,st,msg)
then (cache,Values.STRING("There were errors during translation. Use getErrorString() to see them."),st);

case (cache,env,"translateModelCPP",{Values.CODE(Absyn.C_TYPENAME(className)),Values.STRING(filenameprefix)},st,msg)
equation
(cache,ret_val,st_1,_,_,_,_) = translateModelCPP(cache,env, className, st, filenameprefix,true,NONE());
then
Expand Down Expand Up @@ -1997,6 +2000,7 @@ algorithm
SimCode.translateModel(cache,env,className,st,fileNamePrefix,addDummy,inSimSettingsOpt);
then
(cache,outValMsg,st,indexed_dlow,libs,file_dir,resultValues);

end match;
end translateModel;

Expand Down
4 changes: 4 additions & 0 deletions Compiler/Util/Error.mo
Expand Up @@ -290,6 +290,8 @@ public constant ErrorID EXTERNAL_FUNCTION_RESULT_NOT_VAR=176;
public constant ErrorID EXTERNAL_FUNCTION_RESULT_ARRAY_TYPE=177;
public constant ErrorID INVALID_REDECLARE=178;
public constant ErrorID INVALID_TYPE_PREFIX=179;
public constant ErrorID LINEAR_SYSTEM_INVALID=180;
public constant ErrorID LINEAR_SYSTEM_SINGULAR=181;

public constant ErrorID UNBOUND_PARAMETER_WITH_START_VALUE_WARNING=499;
public constant ErrorID UNBOUND_PARAMETER_WARNING=500;
Expand Down Expand Up @@ -775,6 +777,8 @@ protected constant list<tuple<Integer, MessageType, Severity, String>> errorTabl
(EXTERNAL_FUNCTION_RESULT_NOT_CREF,TRANSLATION(),ERROR(),"The lhs (result) of the external function declaration is not a component reference: %s"),
(EXTERNAL_FUNCTION_RESULT_NOT_VAR,TRANSLATION(),ERROR(),"The lhs (result) of the external function declaration is not a variable"),
(EXTERNAL_FUNCTION_RESULT_ARRAY_TYPE,TRANSLATION(),ERROR(),"The lhs (result) of the external function declaration has array type (%s), but this is not allowed in the specification. You need to pass it as an input to the function (preferably also with a size()-expression to avoid out-of-bounds errors in the external call)."),
(LINEAR_SYSTEM_INVALID,SYMBOLIC(),ERROR(),"Linear solver (%s) returned invalid input for linear system %s."),
(LINEAR_SYSTEM_SINGULAR,SYMBOLIC(),ERROR(),"When solving linear system %1\n U(%2,%2) = 0.0, which means system is singular for variable %3."),

(COMPILER_NOTIFICATION,TRANSLATION(),NOTIFICATION(),"%s"),
(COMPILER_WARNING,TRANSLATION(),WARNING(),"%s"),
Expand Down

0 comments on commit ba57249

Please sign in to comment.