Skip to content
This repository has been archived by the owner on May 18, 2019. It is now read-only.

Commit

Permalink
attempt to fix Codegen issue of inverse algorithms
Browse files Browse the repository at this point in the history
see ticket:4568

 - expand all crefs
 - use only solved vars as residuals variables

Belonging to [master]:
  - #1926
  • Loading branch information
Willi Braun authored and OpenModelica-Hudson committed Feb 28, 2018
1 parent 46705f7 commit f06fb14
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 6 deletions.
26 changes: 23 additions & 3 deletions Compiler/SimCode/SimCodeUtil.mo
Expand Up @@ -6175,6 +6175,7 @@ algorithm
list<DAE.Statement> algStatements;
DAE.ElementSource source;
DAE.Expand crefExpand;
constant Boolean debug = false;

// normal call
case (BackendDAE.ALGORITHM(alg=alg, source = source, expand=crefExpand)::_, false) equation
Expand Down Expand Up @@ -6205,16 +6206,35 @@ algorithm
then ({SimCode.SES_ALGORITHM(iuniqueEqIndex, algStatements)}, iuniqueEqIndex+1);

// inverse algorithms
case (BackendDAE.ALGORITHM(alg=alg, source=source, expand=crefExpand)::_, _) equation
case (BackendDAE.ALGORITHM(alg=alg as DAE.ALGORITHM_STMTS(algStatements), source=source, expand=crefExpand)::_, _) equation
if debug then
print("createSingleAlgorithmCode -> \n");
BackendDump.dumpAlgorithms({DAE.ALGORITHM_STMTS(algStatements)}, 0);
end if;

// get and expand the searched variables
solvedVars = List.map(vars, BackendVariable.varCref);
solvedVars = List.unionList(List.map1(solvedVars, ComponentReference.expandCref, true));

// get and expand all other variables
algOutVars = CheckModel.checkAndGetAlgorithmOutputs(alg, source, crefExpand);
algOutVars = List.unionList(List.map1(algOutVars, ComponentReference.expandCref, true));

// the remaining quantity of all out vars to the solved vars
knownOutputCrefs = List.setDifference(algOutVars, solvedVars);

//Why do we need to filter the discrete variables?
//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));
if debug then
BackendDump.debugStrCrefLstStr("algOutVars : ", algOutVars, ", ", "\n");
BackendDump.debugStrCrefLstStr("filtered solvedVars: ", solvedVars, ", ", "\n");
BackendDump.debugStrCrefLstStr("knownOutputCrefs : ", knownOutputCrefs, ", ", "\n");
end if;

//Why should we have the same amount of solved vars and know vars?
//true = intEq(listLength(solvedVars), listLength(knownOutputCrefs));

DAE.ALGORITHM_STMTS(algStatements) = BackendDAEUtil.collateAlgorithm(alg, NONE());
then ({SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(iuniqueEqIndex+1, {SimCode.SES_INVERSE_ALGORITHM(iuniqueEqIndex, algStatements, knownOutputCrefs)}, solvedVars, 0, listLength(vars), NONE(), false, false, false), NONE())}, iuniqueEqIndex+2);
Expand Down
7 changes: 6 additions & 1 deletion Compiler/Template/CodegenC.tpl
Expand Up @@ -2675,7 +2675,12 @@ match system
;separator="\n")
let body = match nls.eqs
case (alg as SES_INVERSE_ALGORITHM(__))::{} then
(alg.knownOutputCrefs |> cr hasindex i0 => 'res[<%i0%>] = OLD_<%i0%> - <%cref(cr)%>;' ;separator="\n")
let init = (nls.crefs |> cr hasindex i0 => 'res[<%i0%>] = 0;' ;separator="\n")
let known = (alg.knownOutputCrefs |> cr hasindex i0 => 'res[(int)fmod(<%i0%>, <%listLength(nls.crefs)%>)] += pow(OLD_<%i0%> - <%cref(cr)%>, 2);' ;separator="\n")
<<
<%init%>
<%known%>
>>
else
(nls.eqs |> eq2 as SES_RESIDUAL(__) hasindex i0 =>
let &preExp = buffer ""
Expand Down
8 changes: 6 additions & 2 deletions SimulationRuntime/c/simulation/solver/nonlinearSystem.c
Expand Up @@ -807,15 +807,19 @@ int solveNLS(DATA *data, threadData_t *threadData, int sysNumber)
success = nonlinsys->strictTearingFunctionCall(data, threadData);
if (success){
success=2;
/* update iteration variables of the casual set*/
nonlinsys->getIterationVars(data, nonlinsys->nlsx);
}
}

if (!success) {
nonlinsys->solverData = mixedSolverData->hybridData;
success = solveHybrd(data, threadData, sysNumber);
}

/* update iteration variables of nonlinsys->nlsx */
if (success){
nonlinsys->getIterationVars(data, nonlinsys->nlsx);
}

nonlinsys->solverData = mixedSolverData;
break;
#endif
Expand Down

0 comments on commit f06fb14

Please sign in to comment.