Skip to content

Commit

Permalink
Improved handling of inverse algorithms
Browse files Browse the repository at this point in the history
- Discrete variables do no longer appear as iteration variable
- Proper error message for systems that need to have discrete iteration variable
  • Loading branch information
lochel committed Jun 29, 2015
1 parent 70c020c commit 45d0216
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 58 deletions.
3 changes: 1 addition & 2 deletions Compiler/SimCode/SimCode.mo
Expand Up @@ -394,8 +394,7 @@ uniontype SimEqSystem
"this should only occure inside SES_NONLINEAR"
Integer index;
list<DAE.Statement> statements;
list<DAE.ComponentRef> outputCrefs "this are the output crefs of the original algorithm - not of the inverted one";
list<DAE.ComponentRef> knownOutputCrefs "this is a subset of outputCrefs that contain only those that are already known";
list<DAE.ComponentRef> knownOutputCrefs "this is a subset of output crefs of the original algorithm, which are already known";
end SES_INVERSE_ALGORITHM;

record SES_LINEAR
Expand Down
40 changes: 26 additions & 14 deletions Compiler/SimCode/SimCodeUtil.mo
Expand Up @@ -6640,7 +6640,7 @@ algorithm
local
DAE.Algorithm alg;
list<DAE.ComponentRef> solvedVars, algOutVars, knownOutputCrefs;
String message, algStr;
String crefsStr, algStr;
list<DAE.Statement> algStatements;
DAE.ElementSource source;
DAE.Expand crefExpand;
Expand Down Expand Up @@ -6679,15 +6679,27 @@ algorithm
algOutVars = CheckModel.checkAndGetAlgorithmOutputs(alg, source, crefExpand);
knownOutputCrefs = List.setDifference(algOutVars, solvedVars);

//List.filterOnTrue(BackendVariable.varList(knVars),BackendVariable.isRecordVar);
solvedVars = List.map(List.filterOnTrue(vars, BackendVariable.isVarNonDiscrete), BackendVariable.varCref);
solvedVars = List.setDifference(solvedVars, algOutVars);

true = intEq(listLength(solvedVars), listLength(knownOutputCrefs));

DAE.ALGORITHM_STMTS(algStatements) = BackendDAEUtil.collateAlgorithm(alg, NONE());
//then ({SimCode.SES_INVERSE_ALGORITHM(iuniqueEqIndex, algStatements, solvedVars, solvedVars)}, iuniqueEqIndex+1);
then ({SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(iuniqueEqIndex+1, {SimCode.SES_INVERSE_ALGORITHM(iuniqueEqIndex, algStatements, algOutVars, knownOutputCrefs)}, solvedVars, 0, NONE(), false, false, false), NONE())}, iuniqueEqIndex+2);
then ({SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(iuniqueEqIndex+1, {SimCode.SES_INVERSE_ALGORITHM(iuniqueEqIndex, algStatements, knownOutputCrefs)}, solvedVars, 0, NONE(), false, false, false), NONE())}, iuniqueEqIndex+2);

// inverse algorithms
//case (BackendDAE.ALGORITHM(alg=alg, source=source, expand=crefExpand)::_, _) equation
// solvedVars = List.map(vars, BackendVariable.varCref);
// DAE.ALGORITHM_STMTS(algStatements) = BackendDAEUtil.collateAlgorithm(alg, NONE());
//then ({SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(iuniqueEqIndex+1, {SimCode.SES_ALGORITHM(iuniqueEqIndex, algStatements)}, solvedVars, 0, NONE(), false, false, false), NONE())}, iuniqueEqIndex+2);
// Error message, inverse algorithms cannot be solved for discrete variables
case (BackendDAE.ALGORITHM(alg=alg, source=source, expand=crefExpand)::_, _) equation
solvedVars = List.map(vars, BackendVariable.varCref);
algOutVars = CheckModel.checkAndGetAlgorithmOutputs(alg, source, crefExpand);

// The variables solved for must all be part of the output variables of the algorithm.
failure(List.map2AllValue(solvedVars, List.isMemberOnTrue, true, algOutVars, ComponentReference.crefEqualNoStringCompare));

crefsStr = ComponentReference.printComponentRefListStr(solvedVars);
algStr = DAEDump.dumpAlgorithmsStr({DAE.ALGORITHM(alg, source)});
Error.addInternalError("Inverse Algorithm needs to be solved for " + crefsStr + " in\n" + algStr + "Discrete variables are not supported yet.", sourceInfo());
then fail();

// failure
else equation
Expand Down Expand Up @@ -12606,7 +12618,7 @@ algorithm
SimCode.NonlinearSystem nlSystem;
SimCode.SimEqSystem cont;
list<DAE.ComponentRef> conditions;
list<DAE.ComponentRef> crefs, crefs2;
list<DAE.ComponentRef> crefs;
list<DAE.ElementSource> sources;
list<DAE.Exp> beqs;
list<DAE.Statement> stmts;
Expand Down Expand Up @@ -12637,9 +12649,9 @@ algorithm
/* TODO: Me */
then (SimCode.SES_ALGORITHM(index, stmts), a);

case (SimCode.SES_INVERSE_ALGORITHM(index, stmts, crefs, crefs2), _, a)
case (SimCode.SES_INVERSE_ALGORITHM(index, stmts, crefs), _, a)
/* TODO: Me */
then (SimCode.SES_INVERSE_ALGORITHM(index, stmts, crefs, crefs2), a);
then (SimCode.SES_INVERSE_ALGORITHM(index, stmts, crefs), a);

case (SimCode.SES_LINEAR(lSystem, alternativeTearingL), _, a)
/* TODO: Me */
Expand Down Expand Up @@ -14452,7 +14464,7 @@ algorithm
SimCode.SimEqSystem simEqSys;
list<DAE.Exp> expLst;
list<DAE.Statement> stmts;
list<DAE.ComponentRef> crefs, crefs2;
list<DAE.ComponentRef> crefs;
list<DAE.ElementSource> sources;
list<SimCode.SimEqSystem> simEqSysLst,elsebranch;
list<SimCodeVar.SimVar> simVars;
Expand Down Expand Up @@ -14481,8 +14493,8 @@ algorithm
case(SimCode.SES_ALGORITHM(statements=stmts), _) equation
simEqSys = SimCode.SES_ALGORITHM(idx,stmts);
then simEqSys;
case(SimCode.SES_INVERSE_ALGORITHM(statements=stmts, outputCrefs=crefs, knownOutputCrefs=crefs2), _) equation
simEqSys = SimCode.SES_INVERSE_ALGORITHM(idx, stmts, crefs, crefs2);
case(SimCode.SES_INVERSE_ALGORITHM(statements=stmts, knownOutputCrefs=crefs), _) equation
simEqSys = SimCode.SES_INVERSE_ALGORITHM(idx, stmts, crefs);
then simEqSys;
case(SimCode.SES_LINEAR(SimCode.LINEARSYSTEM(partOfMixed=pom,vars=simVars,beqs=expLst,sources=sources,simJac=simJac,residual=simEqSysLst,jacobianMatrix=jac,indexLinearSystem=idxLS)),_)
equation
Expand Down
54 changes: 14 additions & 40 deletions Compiler/Template/CodegenC.tpl
Expand Up @@ -2099,7 +2099,7 @@ template functionNonLinearResiduals(list<SimEqSystem> allEquations, String model
let innerEqs = functionNonLinearResiduals(nls.eqs,modelNamePrefix)
let backupOutputs = match nls.eqs
case (alg as SES_INVERSE_ALGORITHM(__))::{} then
let body = (alg.outputCrefs |> cr =>
let body = (alg.knownOutputCrefs |> cr =>
let &varDecls += '<%crefType(cr)%> $OLD_<%cref(cr)%>;<%\n%>'
'$OLD_<%cref(cr)%> = <%cref(cr)%>;'
;separator="\n")
Expand All @@ -2116,37 +2116,19 @@ template functionNonLinearResiduals(list<SimEqSystem> allEquations, String model
>>
let xlocs = (nls.crefs |> cr hasindex i0 => '<%cref(cr)%> = xloc[<%i0%>];' ;separator="\n")
let body_initializeStaticNLSData = (nls.crefs |> cr hasindex i0 =>
match crefType(cr)
case "modelica_real" then
<<
/* static nls data for <%cref(cr)%> */
nlsData->nominal[i] = $P$ATTRIBUTE<%cref(cr)%>.nominal;
nlsData->min[i] = $P$ATTRIBUTE<%cref(cr)%>.min;
nlsData->max[i++] = $P$ATTRIBUTE<%cref(cr)%>.max;
>>
case "modelica_integer" then
<<
/* FIX ME */
/* static nls data for <%cref(cr)%> */
nlsData->nominal[i] = 1;
nlsData->min[i] = $P$ATTRIBUTE<%cref(cr)%>.min;
nlsData->max[i++] = $P$ATTRIBUTE<%cref(cr)%>.max;
>>
else
<<
/* FIX ME */
/* static nls data for <%cref(cr)%> */
nlsData->nominal[i] = 1;
nlsData->min[i] = 0;
nlsData->max[i++] = 1;
>>
<<
/* static nls data for <%cref(cr)%> */
nlsData->nominal[i] = $P$ATTRIBUTE<%cref(cr)%>.nominal;
nlsData->min[i] = $P$ATTRIBUTE<%cref(cr)%>.min;
nlsData->max[i++] = $P$ATTRIBUTE<%cref(cr)%>.max;
>>
;separator="\n")
let prebody = (nls.eqs |> eq2 =>
functionExtraResidualsPreBody(eq2, &varDecls, &tmp, modelNamePrefix)
;separator="\n")
let body = match nls.eqs
case (alg as SES_INVERSE_ALGORITHM(__))::{} then
(alg.outputCrefs |> cr hasindex i0 => 'res[<%i0%>] = $OLD_<%cref(cr)%> - <%cref(cr)%>;' ;separator="\n")
(alg.knownOutputCrefs |> cr hasindex i0 => 'res[<%i0%>] = $OLD_<%cref(cr)%> - <%cref(cr)%>;' ;separator="\n")
else
(nls.eqs |> eq2 as SES_RESIDUAL(__) hasindex i0 =>
let &preExp = buffer ""
Expand Down Expand Up @@ -4424,19 +4406,11 @@ template equationNonlinear(SimEqSystem eq, Context context, Text &varDecls, Stri
/* extrapolate data */
<%nls.crefs |> name hasindex i0 =>
let namestr = cref(name)
match crefType(name)
case "modelica_boolean" then
<<
data->simulationInfo.nonlinearSystemData[<%nls.indexNonLinearSystem%>].nlsx[<%i0%>] = <%namestr%>;
data->simulationInfo.nonlinearSystemData[<%nls.indexNonLinearSystem%>].nlsxOld[<%i0%>] = _<%namestr%>(1) /*old1*/;
data->simulationInfo.nonlinearSystemData[<%nls.indexNonLinearSystem%>].nlsxExtrapolation[<%i0%>] = extraPolate(data, _<%namestr%>(1) /*old1*/, _<%namestr%>(2) /*old2*/, 0.0, 1.0);
>>
else
<<
data->simulationInfo.nonlinearSystemData[<%nls.indexNonLinearSystem%>].nlsx[<%i0%>] = <%namestr%>;
data->simulationInfo.nonlinearSystemData[<%nls.indexNonLinearSystem%>].nlsxOld[<%i0%>] = _<%namestr%>(1) /*old1*/;
data->simulationInfo.nonlinearSystemData[<%nls.indexNonLinearSystem%>].nlsxExtrapolation[<%i0%>] = extraPolate(data, _<%namestr%>(1) /*old1*/, _<%namestr%>(2) /*old2*/, $P$ATTRIBUTE<%namestr%>.min, $P$ATTRIBUTE<%namestr%>.max);
>>
<<
data->simulationInfo.nonlinearSystemData[<%nls.indexNonLinearSystem%>].nlsx[<%i0%>] = <%namestr%>;
data->simulationInfo.nonlinearSystemData[<%nls.indexNonLinearSystem%>].nlsxOld[<%i0%>] = _<%namestr%>(1) /*old1*/;
data->simulationInfo.nonlinearSystemData[<%nls.indexNonLinearSystem%>].nlsxExtrapolation[<%i0%>] = extraPolate(data, _<%namestr%>(1) /*old1*/, _<%namestr%>(2) /*old2*/, $P$ATTRIBUTE<%namestr%>.min, $P$ATTRIBUTE<%namestr%>.max);
>>
;separator="\n"%>
retValue = solve_nonlinear_system(data, <%nls.indexNonLinearSystem%>);
/* check if solution process was sucessful */
Expand Down Expand Up @@ -4471,7 +4445,7 @@ template equationNonlinear(SimEqSystem eq, Context context, Text &varDecls, Stri
<<
data->simulationInfo.nonlinearSystemData[<%nls.indexNonLinearSystem%>].nlsx[<%i0%>] = <%namestr%>;
data->simulationInfo.nonlinearSystemData[<%nls.indexNonLinearSystem%>].nlsxOld[<%i0%>] = _<%namestr%>(1) /*old1*/;
data->simulationInfo.nonlinearSystemData[<%nls.indexNonLinearSystem%>].nlsxExtrapolation[<%i0%>] = extraPolate(data, _<%namestr%>(1) /*old1*/, _<%namestr%>(2) /*old2*/,$P$ATTRIBUTE<%namestr%>.min, $P$ATTRIBUTE<%namestr%>.max);
data->simulationInfo.nonlinearSystemData[<%nls.indexNonLinearSystem%>].nlsxExtrapolation[<%i0%>] = extraPolate(data, _<%namestr%>(1) /*old1*/, _<%namestr%>(2) /*old2*/, $P$ATTRIBUTE<%namestr%>.min, $P$ATTRIBUTE<%namestr%>.max);
>>
;separator="\n"%>
retValue = solve_nonlinear_system(data, <%nls.indexNonLinearSystem%>);
Expand Down
3 changes: 1 addition & 2 deletions Compiler/Template/SimCodeTV.mo
Expand Up @@ -452,8 +452,7 @@ package SimCode
"this should only occure inside SES_NONLINEAR"
Integer index;
list<DAE.Statement> statements;
list<DAE.ComponentRef> outputCrefs "this are the output crefs of the original algorithm - not of the inverted one";
list<DAE.ComponentRef> knownOutputCrefs "this is a subset of outputCrefs that contain only those that are already known";
list<DAE.ComponentRef> knownOutputCrefs "this is a subset of output crefs of the original algorithm, which are already known";
end SES_INVERSE_ALGORITHM;

record SES_LINEAR
Expand Down

0 comments on commit 45d0216

Please sign in to comment.