From da38b3e64f226adbe5b1d811992b0b25c9e0e19f Mon Sep 17 00:00:00 2001 From: Willi Braun Date: Wed, 4 Oct 2017 11:24:05 +0200 Subject: [PATCH] rewrite algebraic system in SimCode --- Compiler/BackEnd/BackendDump.mo | 27 ++ Compiler/SimCode/SimCode.mo | 2 + Compiler/SimCode/SimCodeUtil.mo | 517 +++++++++++++------------------- Compiler/Template/CodegenC.tpl | 126 +++----- Compiler/Template/SimCodeTV.mo | 2 + 5 files changed, 280 insertions(+), 394 deletions(-) diff --git a/Compiler/BackEnd/BackendDump.mo b/Compiler/BackEnd/BackendDump.mo index 09b5307240a..09fb80328c7 100644 --- a/Compiler/BackEnd/BackendDump.mo +++ b/Compiler/BackEnd/BackendDump.mo @@ -2317,6 +2317,33 @@ algorithm end match; end jacobianString; +public function symJacString "dumps a string representation of a jacobian." + input tuple, BackendDAE.SparsePattern, BackendDAE.SparseColoring> jacIn; + output String sOut; +algorithm + sOut := match(jacIn) + local + BackendDAE.BackendDAE dae; + BackendDAE.SymbolicJacobian sJac; + BackendDAE.SparsePattern sparsePattern; + BackendDAE.SparseColoring coloring; + String s; + case((SOME(sJac), sparsePattern, _)) + equation + ((dae,_,_,_,_)) = sJac; + s = "GENERIC JACOBIAN:\n"; + dumpBackendDAE(dae,"Directional Derivatives System"); + dumpSparsityPattern(sparsePattern,"Sparse Pattern"); + then s; + case((NONE(), sparsePattern, _)) + equation + s = "GENERIC JACOBIAN:\n"; + dumpSparsityPattern(sparsePattern,"Sparse Pattern"); + then s; + + end match; +end symJacString; + public function dumpEqnsStr "Helper function to dump." input list eqns; diff --git a/Compiler/SimCode/SimCode.mo b/Compiler/SimCode/SimCode.mo index f7dd8cd0581..0618d693a3f 100644 --- a/Compiler/SimCode/SimCode.mo +++ b/Compiler/SimCode/SimCode.mo @@ -215,6 +215,8 @@ uniontype ModelInfo "Container for metadata about a Modelica model." Integer nClocks; Integer nSubClocks; Boolean hasLargeLinearEquationSystems; // True if model has large linear eq. systems that are crucial for performance. + list linearSystems; + list nonLinearSystems; end MODELINFO; end ModelInfo; diff --git a/Compiler/SimCode/SimCodeUtil.mo b/Compiler/SimCode/SimCodeUtil.mo index 260fee7b60a..86cd8fbfd42 100644 --- a/Compiler/SimCode/SimCodeUtil.mo +++ b/Compiler/SimCode/SimCodeUtil.mo @@ -416,52 +416,46 @@ algorithm initialEquations_lambda0 := List.map(initialEquations_lambda0, addDivExpErrorMsgtoSimEqSystem); removedInitialEquations := List.map(removedInitialEquations, addDivExpErrorMsgtoSimEqSystem); - // update indexNonLinear in SES_NONLINEAR and count + // collect all LinearSystem and NonlinearSystem algebraic system in modelInfo and update + // the corresponding index (indexNonLinear, indexLinear) in SES_NONLINEAR and SES_LINEAR + // Also collect all jacobians SymbolicJacsNLS := {}; - (initialEquations, numberofLinearSys, numberofNonLinearSys, numberofMixedSys, numberOfJacobians, SymbolicJacsTemp) := countandIndexAlgebraicLoops(initialEquations, 0, 0, 0, 0, {}); + (initialEquations, modelInfo, SymbolicJacsTemp) := addAlgebraicLoopsModelInfo(initialEquations, modelInfo); SymbolicJacsNLS := listAppend(SymbolicJacsTemp, SymbolicJacsNLS); - (initialEquations_lambda0, numberofLinearSys, numberofNonLinearSys, numberofMixedSys, numberOfJacobians, SymbolicJacsTemp) := countandIndexAlgebraicLoops(initialEquations_lambda0, numberofLinearSys, numberofNonLinearSys, numberofMixedSys, numberOfJacobians, {}); + (initialEquations_lambda0, modelInfo, SymbolicJacsTemp) := addAlgebraicLoopsModelInfo(initialEquations_lambda0, modelInfo); SymbolicJacsNLS := listAppend(SymbolicJacsTemp, SymbolicJacsNLS); - (parameterEquations, numberofLinearSys, numberofNonLinearSys, numberofMixedSys, numberOfJacobians, SymbolicJacsTemp) := countandIndexAlgebraicLoops(parameterEquations, numberofLinearSys, numberofNonLinearSys, numberofMixedSys, numberOfJacobians, {}); + (parameterEquations, modelInfo, SymbolicJacsTemp) := addAlgebraicLoopsModelInfo(parameterEquations, modelInfo); SymbolicJacsNLS := listAppend(SymbolicJacsTemp, SymbolicJacsNLS); - (allEquations, numberofLinearSys, numberofNonLinearSys, numberofMixedSys, numberOfJacobians, SymbolicJacsTemp) := countandIndexAlgebraicLoops(allEquations, numberofLinearSys, numberofNonLinearSys, numberofMixedSys, numberOfJacobians, {}); + (allEquations, modelInfo, SymbolicJacsTemp) := addAlgebraicLoopsModelInfo(allEquations, modelInfo); SymbolicJacsNLS := listAppend(SymbolicJacsTemp, SymbolicJacsNLS); - (clockedPartitions, numberofLinearSys, numberofNonLinearSys, numberofMixedSys, numberOfJacobians, SymbolicJacsTemp) := countandIndexAlgebraicLoopsClockPartitions(clockedPartitions, numberofLinearSys, numberofNonLinearSys, numberofMixedSys, numberOfJacobians, {}); + (clockedPartitions, modelInfo, SymbolicJacsTemp) := addAlgebraicLoopsClockPartitions(clockedPartitions, modelInfo); SymbolicJacsNLS := listAppend(SymbolicJacsTemp, SymbolicJacsNLS); - (inlineEquations, numberofLinearSys, numberofNonLinearSys, numberofMixedSys, numberOfJacobians, SymbolicJacsTemp) := countandIndexAlgebraicLoops(inlineEquations, numberofLinearSys, numberofNonLinearSys, numberofMixedSys, numberOfJacobians, {}); + (inlineEquations, modelInfo, SymbolicJacsTemp) := addAlgebraicLoopsModelInfo(inlineEquations, modelInfo); SymbolicJacsNLS := listAppend(SymbolicJacsTemp, SymbolicJacsNLS); // collect symbolic jacobians from state selection - (stateSets, SymbolicJacsStateSelect, SymbolicJacsStateSelectInternal, numberofLinearSys, numberofNonLinearSys, numberofMixedSys, numberOfJacobians) := indexStateSets(stateSets, {}, numberofLinearSys, numberofNonLinearSys, numberofMixedSys, numberOfJacobians, {}, {}); + (stateSets, modelInfo, SymbolicJacsStateSelect) := addAlgebraicLoopsModelInfoStateSets(stateSets, modelInfo); - // generate jacobian or linear model matrices + // collect symbolic jacobians in linear loops of the overall jacobians (LinearMatrices, uniqueEqIndex) := createJacobianLinearCode(symJacs, modelInfo, uniqueEqIndex); - + (SymbolicJacs, modelInfo, SymbolicJacsTemp) := addAlgebraicLoopsModelInfoSymJacs(LinearMatrices, modelInfo); + SymbolicJacs := listAppend(SymbolicJacs, SymbolicJacsTemp); + SymbolicJacs := listAppend(SymbolicJacs, SymbolicJacsStateSelect); // collect jacobian equation only for equantion info file - jacobianEquations := collectAllJacobianEquations(LinearMatrices); - - // collect symbolic jacobians in linear loops of the overall jacobians - (_, numberofLinearSys, numberofNonLinearSys, numberofMixedSys, numberOfJacobians, SymbolicJacs) := countandIndexAlgebraicLoops({}, numberofLinearSys, numberofNonLinearSys, numberofMixedSys, numberOfJacobians, LinearMatrices); + jacobianEquations := collectAllJacobianEquations(SymbolicJacs); - jacobianEquations := listAppend(collectAllJacobianEquations(SymbolicJacsStateSelect), jacobianEquations); - SymbolicJacsNLS := listAppend(SymbolicJacsStateSelectInternal, SymbolicJacsNLS); - SymbolicJacsNLS := listAppend(SymbolicJacsStateSelect, SymbolicJacsNLS); - SymbolicJacs := listAppend(SymbolicJacsNLS, SymbolicJacs); + SymbolicJacs := listAppend(listReverse(SymbolicJacsNLS), SymbolicJacs); jacobianSimvars := collectAllJacobianVars(SymbolicJacs); modelInfo := setJacobianVars(jacobianSimvars, modelInfo); seedVars := collectAllSeedVars(SymbolicJacs); modelInfo := setSeedVars(seedVars, modelInfo); execStat("simCode: created linear, non-linear and system jacobian parts"); - // map index also odeEquations and algebraicEquations systemIndexMap := List.fold(allEquations, getSystemIndexMap, arrayCreate(uniqueEqIndex, -1)); odeEquations := List.mapList1_1(odeEquations, setSystemIndexMap, systemIndexMap); algebraicEquations := List.mapList1_1(algebraicEquations, setSystemIndexMap, systemIndexMap); - numberofEqns := uniqueEqIndex; /* This is a *much* better estimate than the guessed number of equations */ - - // create model info - modelInfo := addNumEqnsandNumofSystems(modelInfo, numberofEqns, numberofLinearSys, numberofNonLinearSys, numberofMixedSys, numberOfJacobians); + modelInfo := addNumEqns(modelInfo, uniqueEqIndex /* This is a *much* better estimate than the guessed number of equations */ ); odeEquations := makeEqualLengthLists(odeEquations, Config.noProc()); algebraicEquations := makeEqualLengthLists(algebraicEquations, Config.noProc()); @@ -916,25 +910,17 @@ algorithm modelInfo.vars := vars; end setSeedVars; -protected function addNumEqnsandNumofSystems +protected function addNumEqns input SimCode.ModelInfo modelInfo; input Integer numEqns; - input Integer numLinearSys; - input Integer numNonLinearSys; - input Integer numMixedLinearSys; - input Integer numOfJacobians; output SimCode.ModelInfo omodelInfo = modelInfo; protected SimCode.VarInfo varInfo; algorithm varInfo := omodelInfo.varInfo; varInfo.numEquations := numEqns; - varInfo.numLinearSystems := numLinearSys; - varInfo.numNonLinearSystems := numNonLinearSys; - varInfo.numMixedSystems := numMixedLinearSys; - varInfo.numJacobians := numOfJacobians; omodelInfo.varInfo := varInfo; -end addNumEqnsandNumofSystems; +end addNumEqns; protected function getSystemIndexMap input SimCode.SimEqSystem inEqn; @@ -1036,236 +1022,215 @@ algorithm end match; end setSystemIndexMap; -protected function countandIndexAlgebraicLoops " - counts algebraic loops and updates index of the systems, further all - symbolic jacobians are collected and therefore we also need to seek - for algebraic loops." - input list inEqns; - input Integer inLinearSysIndex; - input Integer inNonLinSysIndex; - input Integer inMixedSysIndex; - input Integer inJacobianIndex; - input list inSymJacs; - output list outEqns; - output Integer outLinearSysIndex; - output Integer outNonLinSysIndex; - output Integer outMixedSysIndex; - output Integer outJacobianIndex; - output list outSymJacs; -algorithm - (outEqns, outSymJacs, outLinearSysIndex, outNonLinSysIndex, outMixedSysIndex, outJacobianIndex) := countandIndexAlgebraicLoopsWork(inEqns, inSymJacs, inLinearSysIndex, inNonLinSysIndex, inMixedSysIndex, inJacobianIndex, {}, {}); -end countandIndexAlgebraicLoops; - -protected function countandIndexAlgebraicLoopsWork " - counts algebraic loops and updates index of the systems, further all - symbolic jacobians are collected and therefore we also need to seek - for algebraic loops." - input list inEqns; - input list inSymJacs; - input Integer inLinearSysIndex; - input Integer inNonLinSysIndex; - input Integer inMixedSysIndex; - input Integer inJacobianIndex; - input list inEqnsAcc; - input list inSymJacsAcc; - output list outEqns; - output list outSymJacs; - output Integer outLinearSysIndex; - output Integer outNonLinSysIndex; - output Integer outMixedSysIndex; - output Integer outJacobianIndex; -algorithm - (outEqns, outSymJacs, outLinearSysIndex, outNonLinSysIndex, outMixedSysIndex, outJacobianIndex) := match(inEqns, inSymJacs, inLinearSysIndex, inNonLinSysIndex, inMixedSysIndex, inJacobianIndex, inEqnsAcc, inSymJacsAcc) - local - Integer index, index2, countLinearSys, countNonLinSys, countMixedSys, countJacobians, nUnknowns, nUnknowns2; - list eqs, eqs2, rest, res, accEqs; - list crefs, crefs2; - SimCode.SimEqSystem eq, cont; - list discVars; - list discEqs; - list symjacs, symjacs2, restSymJacs, accJac; - Option optSymJac; - SimCode.JacobianMatrix symJac, symJac2; - Boolean partOfMixed,partOfMixed2; - list vars,vars2; - list beqs,beqs2; - list> simJac,simJac2; - list sources,sources2; - Boolean homotopySupport, homotopySupport2; - Boolean mixedSystem, mixedSystem2, tornSystem, tornSystem2; +protected function addAlgebraicLoopsModelInfo " +Adds algebraic loops from list of SimEqSystem into ModelInfo +and SimEqSystem equation algebraic system index." + input output list eqns; + input output SimCode.ModelInfo modelInfo; + output list symJacs = {}; +protected + list resEqns = {}; +algorithm + for eqn in eqns loop + eqn := match(eqn) + local + SimCode.NonlinearSystem nlSyst, altNlSyst; + Option optNlSyst; + SimCode.LinearSystem linearSyst, altLinearSyst; + Option optLinearSyst; + SimCode.JacobianMatrix tmpSymJac; + list tmpSymJacs, tmpAdditionalSymJacs; + list eqs; + SimCode.SimEqSystem system; + // nonlinear case + case SimCode.SES_NONLINEAR(nlSystem=nlSyst as SimCode.NONLINEARSYSTEM(), alternativeTearing=optNlSyst) equation + + (nlSyst, modelInfo, symJacs) = updateNonLinearSyst(nlSyst, modelInfo, symJacs); + + // process the alternative system + if isSome(optNlSyst) then + altNlSyst = Util.getOption(optNlSyst); + (altNlSyst, modelInfo, symJacs) = updateNonLinearSyst(altNlSyst, modelInfo, symJacs); + optNlSyst = SOME(altNlSyst); + end if; + system = SimCode.SES_NONLINEAR(nlSyst, optNlSyst); + modelInfo.nonLinearSystems = system::modelInfo.nonLinearSystems; + then system; - case ({}, {}, _, _, _, _, _, _) - then (listReverse(inEqnsAcc), inSymJacsAcc, inLinearSysIndex, inNonLinSysIndex, inMixedSysIndex, inJacobianIndex); + // linear case + case SimCode.SES_LINEAR(lSystem=linearSyst as SimCode.LINEARSYSTEM(), alternativeTearing=optLinearSyst) equation - case ({}, symJac::restSymJacs, _, _, _, _, _, _) - equation - (symJac, countLinearSys, countNonLinSys, countMixedSys, countJacobians, symjacs) = countandIndexAlgebraicLoopsSymJac(symJac, inLinearSysIndex, inNonLinSysIndex, inMixedSysIndex, inJacobianIndex); - symjacs = symJac::listAppend(symjacs,inSymJacsAcc); - (eqs, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork({}, restSymJacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians, inEqnsAcc, symjacs); - then (eqs, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians); + (linearSyst, modelInfo, symJacs) = updateLinearSyst(linearSyst, modelInfo, symJacs); - // No dynamic tearing - case(SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(index, eqs, crefs, _, nUnknowns, NONE(), homotopySupport, mixedSystem, tornSystem), NONE())::rest, _, _, _, _, _, _, _) - equation - (eqs,_, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(eqs, {}, inLinearSysIndex, inNonLinSysIndex+1, inMixedSysIndex, inJacobianIndex, {}, {}); - (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(rest, inSymJacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians, SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(index, eqs, crefs, inNonLinSysIndex, nUnknowns, NONE(), homotopySupport, mixedSystem, tornSystem), NONE())::inEqnsAcc, inSymJacsAcc); - then (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians); + // process the alternative system + if isSome(optLinearSyst) then + altLinearSyst = Util.getOption(optLinearSyst); + (altLinearSyst, modelInfo, symJacs) = updateLinearSyst(altLinearSyst, modelInfo, symJacs); + optLinearSyst = SOME(altLinearSyst); + end if; + system = SimCode.SES_LINEAR(linearSyst, optLinearSyst); + modelInfo.linearSystems = system::modelInfo.linearSystems; + then system; - case(SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(index, eqs, crefs, _, nUnknowns, SOME(symJac as SimCode.JAC_MATRIX(columns={})), homotopySupport, mixedSystem, tornSystem), NONE())::rest, _, _, _, _, _, _, _) - equation - (eqs,_, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(eqs, {}, inLinearSysIndex, inNonLinSysIndex+1, inMixedSysIndex, inJacobianIndex, {}, {}); - (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(rest, inSymJacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians, SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(index, eqs, crefs, inNonLinSysIndex, nUnknowns, SOME(symJac), homotopySupport, mixedSystem, tornSystem), NONE())::inEqnsAcc, inSymJacsAcc); - then (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians); + else eqn; + end match; + resEqns := eqn::resEqns; + end for; + eqns := listReverse(resEqns); +end addAlgebraicLoopsModelInfo; - case(SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(index, eqs, crefs, _, nUnknowns, SOME(symJac), homotopySupport, mixedSystem, tornSystem), NONE())::rest, _, _, _, _, _, _, _) - equation - (eqs, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(eqs, {}, inLinearSysIndex, inNonLinSysIndex+1, inMixedSysIndex, inJacobianIndex, {}, {}); - (symJac, countLinearSys, countNonLinSys, countMixedSys, countJacobians, symjacs) = countandIndexAlgebraicLoopsSymJac(symJac, countLinearSys, countNonLinSys, countMixedSys, countJacobians); - (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(rest, listAppend(symjacs,inSymJacs), countLinearSys, countNonLinSys, countMixedSys, countJacobians, SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(index, eqs, crefs, inNonLinSysIndex, nUnknowns, SOME(symJac), homotopySupport, mixedSystem, tornSystem), NONE())::inEqnsAcc, symJac::inSymJacsAcc); - then (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians); +protected function updateNonLinearSyst +"Helper function of addAlgebraicLoopsModelInfo + Updates nonlinear system indexes" + input output SimCode.NonlinearSystem inSyst = inSyst; + input output SimCode.ModelInfo modelInfo = modelInfo; + input output list allSymJacs = allSymJacs; +protected + SimCode.VarInfo varInfo = modelInfo.varInfo; + list eqs; + SimCode.JacobianMatrix tmpSymJac; + list tmpSymJacs; + constant Boolean debug = false; +algorithm - case (SimCode.SES_LINEAR(SimCode.LINEARSYSTEM(index, partOfMixed, tornSystem, vars, beqs, simJac, eqs, NONE(), sources, _, nUnknowns), NONE())::rest, _, _, _, _, _, _, _) - equation - (eqs,_, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(eqs, {}, inLinearSysIndex+1, inNonLinSysIndex, inMixedSysIndex, inJacobianIndex, {}, {}); - (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(rest, inSymJacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians, SimCode.SES_LINEAR(SimCode.LINEARSYSTEM(index, partOfMixed, tornSystem, vars, beqs, simJac, eqs, NONE(), sources, inLinearSysIndex, nUnknowns), NONE())::inEqnsAcc, inSymJacsAcc); - then (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians); + // set system index and count + inSyst.indexNonLinearSystem := varInfo.numNonLinearSystems; + varInfo.numNonLinearSystems := varInfo.numNonLinearSystems+1; + modelInfo.varInfo := varInfo; + + // collect the jacobian + if isSome(inSyst.jacobianMatrix) then + tmpSymJac := Util.getOption(inSyst.jacobianMatrix); + // add only if the directional derivativ is available and + // not just the sparsty pattern + if not listEmpty(tmpSymJac.columns) then + ({tmpSymJac}, modelInfo, tmpSymJacs) := addAlgebraicLoopsModelInfoSymJacs({tmpSymJac}, modelInfo); + inSyst.jacobianMatrix := SOME(tmpSymJac); + allSymJacs := listAppend(tmpSymJacs, allSymJacs); + allSymJacs := tmpSymJac::allSymJacs; + end if; + end if; - case (SimCode.SES_LINEAR(SimCode.LINEARSYSTEM(index, partOfMixed, tornSystem, vars, beqs, simJac, eqs, SOME(symJac), sources, _, nUnknowns), NONE())::rest, _, _, _, _, _, _, _) - equation - (eqs, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(eqs, {}, inLinearSysIndex+1, inNonLinSysIndex, inMixedSysIndex, inJacobianIndex, {}, {}); - (symJac, countLinearSys, countNonLinSys, countMixedSys, countJacobians, symjacs) = countandIndexAlgebraicLoopsSymJac(symJac, countLinearSys, countNonLinSys, countMixedSys, countJacobians); - (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(rest, listAppend(symjacs,inSymJacs), countLinearSys, countNonLinSys, countMixedSys, countJacobians, SimCode.SES_LINEAR(SimCode.LINEARSYSTEM(index, partOfMixed, tornSystem, vars, beqs, simJac, eqs, SOME(symJac), sources, inLinearSysIndex, nUnknowns), NONE())::inEqnsAcc, symJac::inSymJacsAcc); - then (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians); + // proceed inSyst.eqs + (eqs, modelInfo, tmpSymJacs) := addAlgebraicLoopsModelInfo(inSyst.eqs, modelInfo); + inSyst.eqs := eqs; + allSymJacs := listAppend(tmpSymJacs, allSymJacs); - // Dynamic tearing - case(SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(index, eqs, crefs, _, nUnknowns, NONE(), homotopySupport, mixedSystem, tornSystem), SOME(SimCode.NONLINEARSYSTEM(index2, eqs2, crefs2, _, nUnknowns2, NONE(), homotopySupport2, mixedSystem2, tornSystem2)))::rest, _, _, _, _, _, _, _) - equation - (eqs,_, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(eqs, {}, inLinearSysIndex, inNonLinSysIndex+1, inMixedSysIndex, inJacobianIndex, {}, {}); - (eqs2,_, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(eqs2, {}, countLinearSys, countNonLinSys+1, countMixedSys, countJacobians, {}, {}); - (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(rest, inSymJacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians, SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(index, eqs, crefs, inNonLinSysIndex, nUnknowns, NONE(), homotopySupport, mixedSystem, tornSystem), SOME(SimCode.NONLINEARSYSTEM(index2, eqs2, crefs2, inNonLinSysIndex+1, nUnknowns2, NONE(), homotopySupport2, mixedSystem2, tornSystem2)))::inEqnsAcc, inSymJacsAcc); - then (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians); + if debug then + print("Update nonlinear system " + intString(inSyst.indexNonLinearSystem) + + " collected Jacobians: " + intString(listLength(allSymJacs)) + "\n"); + end if; +end updateNonLinearSyst; - case(SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(index, eqs, crefs, _, nUnknowns, SOME(symJac as SimCode.JAC_MATRIX(columns={})), homotopySupport, mixedSystem, tornSystem), SOME(SimCode.NONLINEARSYSTEM(index2, eqs2, crefs2, _, nUnknowns2, SOME(symJac2 as SimCode.JAC_MATRIX(columns={})), homotopySupport2, mixedSystem2, tornSystem2)))::rest, _, _, _, _, _, _, _) - equation - (eqs,_, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(eqs, {}, inLinearSysIndex, inNonLinSysIndex+1, inMixedSysIndex, inJacobianIndex, {}, {}); - (eqs2,_, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(eqs2, {}, countLinearSys, countNonLinSys+1, countMixedSys, countJacobians, {}, {}); - (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(rest, inSymJacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians, SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(index, eqs, crefs, inNonLinSysIndex, nUnknowns, SOME(symJac), homotopySupport, mixedSystem, tornSystem), SOME(SimCode.NONLINEARSYSTEM(index2, eqs2, crefs2, inNonLinSysIndex+1, nUnknowns2, SOME(symJac2), homotopySupport2, mixedSystem2, tornSystem2)))::inEqnsAcc, inSymJacsAcc); - then (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians); +protected function updateLinearSyst +"Helper function of addAlgebraicLoopsModelInfo + Updates linear system indexes" + input output SimCode.LinearSystem inSyst = inSyst; + input output SimCode.ModelInfo modelInfo = modelInfo; + input output list allSymJacs = allSymJacs; +protected + SimCode.VarInfo varInfo = modelInfo.varInfo; + list eqs; + SimCode.JacobianMatrix tmpSymJac; + list tmpSymJacs; + constant Boolean debug = false; +algorithm - case(SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(index, eqs, crefs, _, nUnknowns, SOME(symJac), homotopySupport, mixedSystem, tornSystem), SOME(SimCode.NONLINEARSYSTEM(index2, eqs2, crefs2, _, nUnknowns2, SOME(symJac2), homotopySupport2, mixedSystem2, tornSystem2)))::rest, _, _, _, _, _, _, _) - equation - (eqs, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(eqs, {}, inLinearSysIndex, inNonLinSysIndex+1, inMixedSysIndex, inJacobianIndex, {}, {}); - (eqs2, symjacs2, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(eqs2, {}, countLinearSys, countNonLinSys+1, countMixedSys, countJacobians, {}, {}); - (symJac, countLinearSys, countNonLinSys, countMixedSys, countJacobians, symjacs) = countandIndexAlgebraicLoopsSymJac(symJac, countLinearSys, countNonLinSys, countMixedSys, countJacobians); - (symJac2, countLinearSys, countNonLinSys, countMixedSys, countJacobians, symjacs2) = countandIndexAlgebraicLoopsSymJac(symJac2, countLinearSys, countNonLinSys, countMixedSys, countJacobians); - (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(rest, listAppend(symjacs2,listAppend(symjacs,inSymJacs)), countLinearSys, countNonLinSys, countMixedSys, countJacobians, SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(index, eqs, crefs, inNonLinSysIndex, nUnknowns, SOME(symJac), homotopySupport, mixedSystem, tornSystem), SOME(SimCode.NONLINEARSYSTEM(index2, eqs2, crefs2, inNonLinSysIndex+1, nUnknowns2, SOME(symJac2), homotopySupport2, mixedSystem2, tornSystem2)))::inEqnsAcc, symJac2::symJac::inSymJacsAcc); - then (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians); + // set system index and count + inSyst.indexLinearSystem := varInfo.numLinearSystems; + varInfo.numLinearSystems := varInfo.numLinearSystems+1; + modelInfo.varInfo := varInfo; + + // collect the jacobian + if isSome(inSyst.jacobianMatrix) then + tmpSymJac := Util.getOption(inSyst.jacobianMatrix); + // add only if the directional derivativ is available and + // not just the sparsty pattern + if not listEmpty(tmpSymJac.columns) then + ({tmpSymJac}, modelInfo, tmpSymJacs) := addAlgebraicLoopsModelInfoSymJacs({tmpSymJac}, modelInfo); + inSyst.jacobianMatrix := SOME(tmpSymJac); + allSymJacs := listAppend(tmpSymJacs, allSymJacs); + allSymJacs := tmpSymJac::allSymJacs; + end if; + end if; - case (SimCode.SES_LINEAR(SimCode.LINEARSYSTEM(index, partOfMixed, tornSystem, vars, beqs, simJac, eqs, NONE(), sources, _, nUnknowns), SOME(SimCode.LINEARSYSTEM(index2, partOfMixed2, tornSystem2, vars2, beqs2, simJac2, eqs2, NONE(), sources2, _, nUnknowns2)))::rest, _, _, _, _, _, _, _) - equation - (eqs,_, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(eqs, {}, inLinearSysIndex+1, inNonLinSysIndex, inMixedSysIndex, inJacobianIndex, {}, {}); - (eqs2,_, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(eqs2, {}, countLinearSys+1, countNonLinSys, countMixedSys, countJacobians, {}, {}); - (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(rest, inSymJacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians, SimCode.SES_LINEAR(SimCode.LINEARSYSTEM(index, partOfMixed, tornSystem, vars, beqs, simJac, eqs, NONE(), sources, inLinearSysIndex, nUnknowns), SOME(SimCode.LINEARSYSTEM(index2, partOfMixed2, tornSystem2, vars2, beqs2, simJac2, eqs2, NONE(), sources2, inLinearSysIndex+1, nUnknowns2)))::inEqnsAcc, inSymJacsAcc); - then (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians); + // proceed inSyst.eqs + (eqs, modelInfo, tmpSymJacs) := addAlgebraicLoopsModelInfo(inSyst.residual, modelInfo); + inSyst.residual := eqs; + allSymJacs := listAppend(tmpSymJacs, allSymJacs); - case (SimCode.SES_LINEAR(SimCode.LINEARSYSTEM(index, partOfMixed, tornSystem, vars, beqs, simJac, eqs, SOME(symJac), sources, _, nUnknowns), SOME(SimCode.LINEARSYSTEM(index2, partOfMixed2, tornSystem2, vars2, beqs2, simJac2, eqs2, SOME(symJac2), sources2, _, nUnknowns2)))::rest, _, _, _, _, _, _, _) - equation - (eqs, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(eqs, {}, inLinearSysIndex+1, inNonLinSysIndex, inMixedSysIndex, inJacobianIndex, {}, {}); - (eqs2, symjacs2, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(eqs2, {}, countLinearSys+1, countNonLinSys, countMixedSys, countJacobians, {}, {}); - (symJac, countLinearSys, countNonLinSys, countMixedSys, countJacobians, symjacs) = countandIndexAlgebraicLoopsSymJac(symJac, countLinearSys, countNonLinSys, countMixedSys, countJacobians); - (symJac2, countLinearSys, countNonLinSys, countMixedSys, countJacobians, symjacs2) = countandIndexAlgebraicLoopsSymJac(symJac2, countLinearSys, countNonLinSys, countMixedSys, countJacobians); - (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(rest, listAppend(symjacs2,listAppend(symjacs,inSymJacs)), countLinearSys, countNonLinSys, countMixedSys, countJacobians, SimCode.SES_LINEAR(SimCode.LINEARSYSTEM(index, partOfMixed, tornSystem, vars, beqs, simJac, eqs, SOME(symJac), sources, inLinearSysIndex, nUnknowns), SOME(SimCode.LINEARSYSTEM(index2, partOfMixed2, tornSystem2, vars2, beqs2, simJac2, eqs2, SOME(symJac2), sources2, inLinearSysIndex+1, nUnknowns2)))::inEqnsAcc, symJac2::symJac::inSymJacsAcc); - then (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians); + if debug then + print("Update linear system " + intString(inSyst.indexLinearSystem) + + " collected Jacobians: " + intString(listLength(allSymJacs)) + "\n"); + end if; +end updateLinearSyst; - case (SimCode.SES_MIXED(index, cont, discVars, discEqs, _)::rest, _, _, _, _, _, _, _) - equation - ({cont}, _, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork({cont}, inSymJacs, inLinearSysIndex, inNonLinSysIndex, inMixedSysIndex, inJacobianIndex, {}, {}); - (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(rest, {}, countLinearSys, countNonLinSys, countMixedSys+1, countJacobians, SimCode.SES_MIXED(index, cont, discVars, discEqs, inMixedSysIndex)::inEqnsAcc, inSymJacsAcc); - then (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians); +protected function addAlgebraicLoopsModelInfoSymJacs " +Adds algebraic loops from list of SimEqSystem into ModelInfo +and SimEqSystem equation algebraic system index." + input output list symjacs; + input output SimCode.ModelInfo modelInfo; + output list outSymJacsInSymJacs = {}; +protected + SimCode.JacobianColumn column; + list eqs; + SimCode.VarInfo varInfo; + list tmpSymJacs; + list outSymJacs = {}; + constant Boolean debug = false; +algorithm + for symjac in symjacs loop + varInfo := modelInfo.varInfo; + symjac.jacobianIndex := varInfo.numJacobians; + varInfo.numJacobians := varInfo.numJacobians + 1; + modelInfo.varInfo := varInfo; + if debug then + print("Collect Jacobian " + symjac.matrixName + " and set index to: " + intString(symjac.jacobianIndex) + "\n"); + end if; + try + column::{} := symjac.columns; + (eqs, modelInfo, tmpSymJacs) := addAlgebraicLoopsModelInfo(column.columnEqns, modelInfo); + outSymJacsInSymJacs := listAppend(tmpSymJacs, outSymJacsInSymJacs); + column.columnEqns := eqs; + symjac.columns := {column}; + outSymJacs := symjac::outSymJacs; + else + outSymJacs := symjac::outSymJacs; + end try; + end for; + symjacs := listReverse(outSymJacs); + outSymJacsInSymJacs := listReverse(outSymJacsInSymJacs); +end addAlgebraicLoopsModelInfoSymJacs; - case (eq::rest, _, _, _, _, _, _, _) - equation - (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(rest, inSymJacs, inLinearSysIndex, inNonLinSysIndex, inMixedSysIndex, inJacobianIndex, eq::inEqnsAcc, inSymJacsAcc); - then (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians); - end match; -end countandIndexAlgebraicLoopsWork; - -protected function countandIndexAlgebraicLoopsSymJac " - helper function to countandIndexAlgebraicLoops" - input SimCode.JacobianMatrix inSymjac; - input Integer inLinearSysIndex; - input Integer inNonLinSysIndex; - input Integer inMixedSysIndex; - input Integer inJacobianIndex; - output SimCode.JacobianMatrix outSymjac; - output Integer outLinearSysIndex; - output Integer outNonLinSysIndex; - output Integer outMixedSysIndex; - output Integer outJacobianIndex; - output list outSymJacs; -protected - list columns; - list vars; - String name; - SimCode.SparsityPattern sparsity,sparsityT; - list> colors; - Integer maxcolor, index, partIdx; -algorithm - SimCode.JAC_MATRIX(columns, vars, name, sparsity, sparsityT, colors, maxcolor, index, partIdx) := inSymjac; - (columns, outLinearSysIndex, outNonLinSysIndex, outMixedSysIndex, outJacobianIndex, outSymJacs) := countandIndexAlgebraicLoopsSymJacColumn(columns, inLinearSysIndex, inNonLinSysIndex, inMixedSysIndex, inJacobianIndex, {}); - outSymjac := SimCode.JAC_MATRIX(columns, vars, name, sparsity, sparsityT, colors, maxcolor, outJacobianIndex, partIdx); - outJacobianIndex := outJacobianIndex + 1; -end countandIndexAlgebraicLoopsSymJac; - -protected function countandIndexAlgebraicLoopsSymJacColumn " - helper function to countandIndexAlgebraicLoops" - input list inSymColumn; - input Integer inLinearSysIndex; - input Integer inNonLinSysIndex; - input Integer inMixedSysIndex; - input Integer inJacobianIndex; - input list inSymJacs; - output list outSymColumn; - output Integer outLinearSysIndex; - output Integer outNonLinSysIndex; - output Integer outMixedSysIndex; - output Integer outJacobianIndex; - output list outSymJacs; -algorithm - (outSymColumn, outLinearSysIndex, outNonLinSysIndex, outMixedSysIndex, outJacobianIndex, outSymJacs) := match(inSymColumn, inLinearSysIndex, inNonLinSysIndex, inMixedSysIndex, inJacobianIndex, inSymJacs) - local - list rest, result, res1; - list eqns, eqns1; - list vars; - Integer nRows; - Integer countLinearSys, countNonLinSys, countMixedSys, countJacobians; - list symJacs; - - case ({}, _, _, _, _, _) - then ({}, inLinearSysIndex, inNonLinSysIndex, inMixedSysIndex, inJacobianIndex, inSymJacs); - - case (SimCode.JAC_COLUMN(eqns, vars, nRows)::rest, _, _, _, _, _) equation - (eqns1, countLinearSys, countNonLinSys, countMixedSys, countJacobians, symJacs) = countandIndexAlgebraicLoops(eqns, inLinearSysIndex, inNonLinSysIndex, inMixedSysIndex, inJacobianIndex, inSymJacs); - (res1, countLinearSys, countNonLinSys, countMixedSys, countJacobians, symJacs) = countandIndexAlgebraicLoopsSymJacColumn(rest, countLinearSys, countNonLinSys, countMixedSys, countJacobians, symJacs); - result = SimCode.JAC_COLUMN(eqns1, vars, nRows)::res1; - then (result, countLinearSys, countNonLinSys, countMixedSys, countJacobians, symJacs); - end match; -end countandIndexAlgebraicLoopsSymJacColumn; +protected function addAlgebraicLoopsModelInfoStateSets +" function to collect jacobians for statesets" + input list inSets; + input SimCode.ModelInfo inModelInfo; + output list outSets = {}; + output SimCode.ModelInfo modelInfo = inModelInfo; + output list outSymJacs = {}; +protected + SimCode.JacobianMatrix symJac; + list tmpSymJacs; +algorithm + for set in inSets loop + ({symJac}, modelInfo, tmpSymJacs) := addAlgebraicLoopsModelInfoSymJacs({set.jacobianMatrix}, modelInfo); + outSymJacs := listAppend(tmpSymJacs, outSymJacs); + set.jacobianMatrix := symJac; + outSymJacs := symJac::outSymJacs; + outSets := set::outSets; + end for; + outSets := listReverse(outSets); + outSymJacs := listReverse(outSymJacs); +end addAlgebraicLoopsModelInfoStateSets; -protected function countandIndexAlgebraicLoopsClockPartitions " +protected function addAlgebraicLoopsClockPartitions " function to process clockPartitions for symbolic jacobians" input list inColockPartition; - input Integer inLinearSysIndex; - input Integer inNonLinSysIndex; - input Integer inMixedSysIndex; - input Integer inJacobianIndex; - input list inSymJacs; + input SimCode.ModelInfo inModelInfo; output list outColockPartition = {}; - output Integer outLinearSysIndex = inLinearSysIndex; - output Integer outNonLinSysIndex = inNonLinSysIndex; - output Integer outMixedSysIndex = inMixedSysIndex; - output Integer outJacobianIndex = inJacobianIndex; - output list outSymJacs = inSymJacs; + output SimCode.ModelInfo modelInfo = inModelInfo; + output list outSymJacs = {}; protected SimCode.SubPartition subPartitionTmp; SimCode.ClockedPartition clockPartitionTmp; @@ -1278,8 +1243,7 @@ algorithm subPartitionsTmp := {}; for subPartion in clockPartion.subPartitions loop clockIndex := clockIndex + 1; - (equations, outLinearSysIndex, outNonLinSysIndex, outMixedSysIndex, outJacobianIndex, tmpJacs) := - countandIndexAlgebraicLoops(subPartion.equations, outLinearSysIndex, outNonLinSysIndex, outMixedSysIndex, outJacobianIndex, {}); + (equations, modelInfo, tmpJacs) := addAlgebraicLoopsModelInfo(subPartion.equations, modelInfo); tmpJacs := list(rewriteJacPartIdx(a,clockIndex) for a in tmpJacs); outSymJacs := listAppend(tmpJacs, outSymJacs); subPartitionTmp := SimCode.SUBPARTITION( @@ -1294,7 +1258,7 @@ algorithm outColockPartition := clockPartitionTmp::outColockPartition; end for; outColockPartition := listReverse(outColockPartition); -end countandIndexAlgebraicLoopsClockPartitions; +end addAlgebraicLoopsClockPartitions; protected function rewriteJacPartIdx input SimCode.JacobianMatrix inJac; @@ -4359,47 +4323,6 @@ algorithm end matchcontinue; end createStateSetsSets; -protected function indexStateSets -" function to collect jacobians for statesets" - input list inSets; - input list inSymJacs; - input Integer iNumLin; - input Integer iNumNonLin; - input Integer iNumMixed; - input Integer iNumJac; - input list inSetsAccum; - input list inSymAccumInternal; - output list outSets; - output list outSymJacs; - output list outSymAccumInternal; - output Integer oNumLin; - output Integer oNumNonLin; - output Integer oNumMixed; - output Integer oNumJac; -algorithm - (outSets, outSymJacs, outSymAccumInternal, oNumLin, oNumNonLin, oNumMixed, oNumJac) := match(inSets, inSymJacs, iNumLin, iNumNonLin, iNumMixed, iNumJac, inSetsAccum, inSymAccumInternal) - local - list sets; - SimCode.StateSet set; - SimCode.JacobianMatrix symJac; - list symJacs, symJacsInternal; - Integer numJac, numLin, numNonLin, numMixed; - Integer index; - Integer nCandidates; - Integer nStates; - list states; - list statescandidates; - DAE.ComponentRef crA; - case ({}, _, _, _, _, _, _, _) then (listReverse(inSetsAccum), listReverse(inSymJacs), inSymAccumInternal, iNumLin, iNumNonLin, iNumMixed, iNumJac); - case((SimCode.SES_STATESET(index=index, nCandidates=nCandidates, nStates=nStates, states=states, statescandidates=statescandidates, crA=crA, jacobianMatrix=symJac))::sets, _, _, _, _, _, _, _) - equation - (symJac, numLin, numNonLin, numMixed, numJac, symJacsInternal) = countandIndexAlgebraicLoopsSymJac(symJac, iNumLin, iNumNonLin, iNumMixed, iNumJac); - outSymAccumInternal = listAppend(inSymAccumInternal, symJacsInternal); - (outSets, outSymJacs, outSymAccumInternal, oNumLin, oNumNonLin, oNumMixed, oNumJac) = indexStateSets(sets, symJac::inSymJacs, numLin, numNonLin, numMixed, numJac, SimCode.SES_STATESET(index, nCandidates, nStates, states, statescandidates, crA, symJac)::inSetsAccum, outSymAccumInternal); - then (outSets, outSymJacs, outSymAccumInternal, oNumLin, oNumNonLin, oNumMixed, oNumJac); - end match; -end indexStateSets; - // ============================================================================= // section to create SimCode symbolic jacobian from BackendDAE.Equations // @@ -6965,7 +6888,7 @@ algorithm if debug then execStat("simCode: hasLargeEquationSystems"); end if; modelInfo := SimCode.MODELINFO(class_, dlow.shared.info.description, directory, varInfo, vars, functions, labels, arrayLength(dlow.shared.partitionsInfo.basePartitions), - arrayLength(dlow.shared.partitionsInfo.subPartitions), hasLargeEqSystems); + arrayLength(dlow.shared.partitionsInfo.subPartitions), hasLargeEqSystems, {}, {}); else Error.addInternalError("createModelInfo failed", sourceInfo()); fail(); @@ -10516,20 +10439,11 @@ protected function collectAllFiles protected SimCode.ModelInfo modelInfo; SimCode.Files files = {} "all the files from SourceInfo and DAE.ELementSource"; - Absyn.Path name; - String description, directory; - SimCode.VarInfo varInfo; - SimCodeVar.SimVars vars; - list functions; - list labels; - Integer nClocks, nSubClocks; - Boolean hasLargeLinearEquationSystems; algorithm if not Config.acceptMetaModelicaGrammar() then modelInfo := outSimCode.modelInfo; - SimCode.MODELINFO(name, description, directory, varInfo, vars, functions, labels, nClocks, nSubClocks, hasLargeLinearEquationSystems) := modelInfo; - files := getFilesFromSimVars(vars, files); - files := getFilesFromFunctions(functions, files); + files := getFilesFromSimVars(modelInfo.vars, files); + files := getFilesFromFunctions(modelInfo.functions, files); files := getFilesFromSimEqSystems( outSimCode.allEquations :: outSimCode.startValueEquations :: outSimCode.nominalValueEquations :: outSimCode.minValueEquations :: outSimCode.maxValueEquations :: outSimCode.parameterEquations :: outSimCode.removedEquations :: outSimCode.algorithmAndEquationAsserts @@ -10538,7 +10452,6 @@ algorithm files := getFilesFromExtObjInfo(outSimCode.extObjInfo, files); files := getFilesFromJacobianMatrixes(outSimCode.jacobianMatrixes, files); files := List.sort(files, greaterFileInfo); - modelInfo := SimCode.MODELINFO(name, description, directory, varInfo, vars, functions, labels, nClocks, nSubClocks, hasLargeLinearEquationSystems); outSimCode.modelInfo := modelInfo; end if; end collectAllFiles; diff --git a/Compiler/Template/CodegenC.tpl b/Compiler/Template/CodegenC.tpl index 63dcdd7e5d4..f97fe3427d2 100644 --- a/Compiler/Template/CodegenC.tpl +++ b/Compiler/Template/CodegenC.tpl @@ -492,9 +492,8 @@ template simulationFile_nls(SimCode simCode) "Non Linear Systems" ::= match simCode - case simCode as SIMCODE(modelInfo=MODELINFO(varInfo=varInfo as VARINFO(__))) then + case simCode as SIMCODE(modelInfo=MODELINFO(varInfo=varInfo as VARINFO(__),nonLinearSystems=nonLinearSystems)) then let modelNamePrefixStr = modelNamePrefix(simCode) - let jacobianbody = ((jacobianMatrixes |> JAC_MATRIX(columns=clst) => (clst |> JAC_COLUMN(columnEqns=cEqns) => functionNonLinearResiduals(cEqns,modelNamePrefixStr);separator="\n") ;separator="\n")) << /* Non Linear Systems */ <%simulationFileHeader(simCode.fileNamePrefix)%> @@ -502,14 +501,9 @@ template simulationFile_nls(SimCode simCode) #if defined(__cplusplus) extern "C" { #endif - <%functionNonLinearResiduals(initialEquations, modelNamePrefixStr)%> - <%functionNonLinearResiduals(initialEquations_lambda0, modelNamePrefixStr)%> - <%functionNonLinearResiduals(parameterEquations,modelNamePrefixStr)%> - <%functionNonLinearResiduals(allEquations,modelNamePrefixStr)%> - <%functionNonLinearResiduals(inlineEquations,modelNamePrefixStr)%> - <%jacobianbody%> + <%functionNonLinearResiduals(nonLinearSystems, modelNamePrefixStr)%> - <%if intGt(varInfo.numNonLinearSystems, 0) then functionInitialNonLinearSystems(initialEquations, initialEquations_lambda0, parameterEquations, allEquations, inlineEquations, jacobianMatrixes, modelNamePrefixStr)%> + <%if intGt(varInfo.numNonLinearSystems, 0) then functionInitialNonLinearSystems(nonLinearSystems, modelNamePrefixStr)%> #if defined(__cplusplus) } @@ -524,7 +518,7 @@ template simulationFile_lsy(SimCode simCode) "Linear Systems" ::= match simCode - case simCode as SIMCODE(modelInfo=MODELINFO(varInfo=varInfo as VARINFO(__))) then + case simCode as SIMCODE(modelInfo=MODELINFO(varInfo=varInfo as VARINFO(__),linearSystems=linearSystems)) then << /* Linear Systems */ <%simulationFileHeader(simCode.fileNamePrefix)%> @@ -533,9 +527,9 @@ template simulationFile_lsy(SimCode simCode) extern "C" { #endif - <%functionSetupLinearSystems(initialEquations, initialEquations_lambda0, parameterEquations, allEquations, inlineEquations, jacobianMatrixes, modelNamePrefix(simCode))%> + <%functionSetupLinearSystems(linearSystems, modelNamePrefix(simCode))%> - <% if intGt(varInfo.numLinearSystems,0) then functionInitialLinearSystems(initialEquations, initialEquations_lambda0, parameterEquations, allEquations, inlineEquations, jacobianMatrixes, modelNamePrefix(simCode))%> + <% if intGt(varInfo.numLinearSystems,0) then functionInitialLinearSystems(linearSystems, modelNamePrefix(simCode))%> #if defined(__cplusplus) } @@ -763,7 +757,7 @@ template simulationFile_jac_header(SimCode simCode) match simCode case simCode as SIMCODE(__) then << - /* Jacobians */ + /* Jacobians <%listLength(jacobianMatrixes)%> */ static const REAL_ATTRIBUTE dummyREAL_ATTRIBUTE = omc_dummyRealAttribute; <%variableDefinitionsJacobians(jacobianMatrixes, modelNamePrefix(simCode))%> <%\n%> @@ -1879,53 +1873,32 @@ template functionSetupMixedSystemsTemp(list allEquations, Text &hea end functionSetupMixedSystemsTemp; -template functionInitialLinearSystems(list initialEquations, list initialEquations_lambda0, list parameterEquations, list allEquations, list inlineEquations, list jacobianMatrixes, String modelNamePrefix) +template functionInitialLinearSystems(list linearSystems, String modelNamePrefix) "Generates functions in simulation file." ::= - let &tempeqns1 = buffer "" - let &tempeqns1 += (initialEquations |> eq => match eq case eq as SES_LINEAR(alternativeTearing = SOME(__)) then 'int <%symbolName(modelNamePrefix,"eqFunction")%>_<%equationIndex(eq)%>(DATA*);' ; separator = "\n") - let &tempeqns2 = buffer "" - let &tempeqns2 += (initialEquations_lambda0 |> eq => match eq case eq as SES_LINEAR(alternativeTearing = SOME(__)) then 'int <%symbolName(modelNamePrefix,"eqFunction")%>_<%equationIndex(eq)%>(DATA*);' ; separator = "\n") - let &tempeqns3 = buffer "" - let &tempeqns3 += (allEquations |> eq => match eq case eq as SES_LINEAR(alternativeTearing = SOME(__)) then 'int <%symbolName(modelNamePrefix,"eqFunction")%>_<%equationIndex(eq)%>(DATA*);' ; separator = "\n") + let &tempeqns = buffer "" + let &tempeqns += (linearSystems |> eq => match eq case eq as SES_LINEAR(alternativeTearing = SOME(__)) then 'int <%symbolName(modelNamePrefix,"eqFunction")%>_<%equationIndex(eq)%>(DATA*);' ; separator = "\n") let &globalConstraintsFunctions = buffer "" - let initbody = functionInitialLinearSystemsTemp(initialEquations, modelNamePrefix, &globalConstraintsFunctions) - let initbody_lambda0 = functionInitialLinearSystemsTemp(initialEquations_lambda0, modelNamePrefix, &globalConstraintsFunctions) - let parambody = functionInitialLinearSystemsTemp(parameterEquations, modelNamePrefix, &globalConstraintsFunctions) - let body = functionInitialLinearSystemsTemp(allEquations, modelNamePrefix, &globalConstraintsFunctions) - let inlinebody = functionInitialLinearSystemsTemp(inlineEquations, modelNamePrefix, &globalConstraintsFunctions) - let jacobianbody = ((jacobianMatrixes |> JAC_MATRIX(columns=clst) => (clst |> JAC_COLUMN(columnEqns=cEqns) => functionInitialLinearSystemsTemp(cEqns, modelNamePrefix, &globalConstraintsFunctions);separator="\n") ;separator="\n")) + let linearbody = functionInitialLinearSystemsTemp(linearSystems, modelNamePrefix, &globalConstraintsFunctions) << /* Prototypes for the strict sets (Dynamic Tearing) */ - <%tempeqns1%> - <%tempeqns2%> - <%tempeqns3%> + <%tempeqns%> /* Global constraints for the casual sets */ <%globalConstraintsFunctions%> /* function initialize linear systems */ void <%symbolName(modelNamePrefix,"initialLinearSystem")%>(int nLinearSystems, LINEAR_SYSTEM_DATA* linearSystemData) { - /* initial linear systems */ - <%initbody%> - /* initial_lambda0 linear systems */ - <%initbody_lambda0%> - /* parameter linear systems */ - <%parambody%> - /* model linear systems */ - <%body%> - /* inline linear systems */ - <%inlinebody%> - /* jacobians linear systems */ - <%jacobianbody%> + /* linear systems */ + <%linearbody%> } >> end functionInitialLinearSystems; -template functionInitialLinearSystemsTemp(list allEquations, String modelNamePrefix, Text &globalConstraintsFunctions) +template functionInitialLinearSystemsTemp(list linearSystems, String modelNamePrefix, Text &globalConstraintsFunctions) "Generates functions in simulation file." ::= - (allEquations |> eqn => (match eqn + (linearSystems |> eqn => (match eqn case eq as SES_MIXED(__) then functionInitialLinearSystemsTemp(fill(eq.cont,1), modelNamePrefix, "") // no dynamic tearing case eq as SES_LINEAR(lSystem=ls as LINEARSYSTEM(__), alternativeTearing=NONE()) then @@ -1949,7 +1922,7 @@ template functionInitialLinearSystemsTemp(list allEquations, String let nnz = listLength(ls.simJac) let generatedJac = match ls.jacobianMatrix case SOME(JAC_MATRIX(matrixName=name)) then '<%symbolName(modelNamePrefix,"functionJac")%><%name%>_column' case NONE() then 'NULL' let initialJac = match ls.jacobianMatrix case SOME(JAC_MATRIX(matrixName=name))then '<%symbolName(modelNamePrefix,"initialAnalyticJacobian")%><%name%>' case NONE() then 'NULL' - let jacIndex = match ls.jacobianMatrix case SOME(JAC_MATRIX(matrixName=name, jacobianIndex=jacindex)) then '<%jacindex%>' case NONE() then '-1' + let jacIndex = match ls.jacobianMatrix case SOME(JAC_MATRIX(matrixName=name, jacobianIndex=jacindex)) then '<%jacindex%> /*jacInx*/' case NONE() then '-1' << assertStreamPrint(NULL, nLinearSystems > <%ls.indexLinearSystem%>, "Internal Error: indexlinearSystem mismatch!"); linearSystemData[<%ls.indexLinearSystem%>].equationIndex = <%ls.index%>; @@ -2051,35 +2024,20 @@ template functionInitialLinearSystemsTemp(list allEquations, String ;separator="\n\n") end functionInitialLinearSystemsTemp; -template functionSetupLinearSystems(list initialEquations, list initialEquations_lambda0, list parameterEquations, list allEquations, list inlineEquations, list jacobianMatrixes, String modelNamePrefix) +template functionSetupLinearSystems(list linearSystems, String modelNamePrefix) "Generates functions in simulation file." ::= - let initbody = functionSetupLinearSystemsTemp(initialEquations, modelNamePrefix) - let initbody_lambda0 = functionSetupLinearSystemsTemp(initialEquations_lambda0, modelNamePrefix) - let parambody = functionSetupLinearSystemsTemp(parameterEquations, modelNamePrefix) - let body = functionSetupLinearSystemsTemp(allEquations, modelNamePrefix) - let inlinebody = functionSetupLinearSystemsTemp(inlineEquations, modelNamePrefix) - let jacobianbody = ((jacobianMatrixes |> JAC_MATRIX(columns=clst) => (clst |> JAC_COLUMN(columnEqns=cEqns) => functionSetupLinearSystemsTemp(cEqns, modelNamePrefix);separator="\n") ;separator="\n")) + let linearbody = functionSetupLinearSystemsTemp(linearSystems, modelNamePrefix) << - /* initial linear systems */ - <%initbody%> - /* initial_lambda0 linear systems */ - <%initbody_lambda0%> - /* parameter linear systems */ - <%parambody%> - /* model linear systems */ - <%body%> - /* inline linear systems */ - <%inlinebody%> - /* jacobians linear systems */ - <%jacobianbody%> + /* linear systems */ + <%linearbody%> >> end functionSetupLinearSystems; -template functionSetupLinearSystemsTemp(list allEquations, String modelNamePrefix) +template functionSetupLinearSystemsTemp(list linearSystems, String modelNamePrefix) "Generates functions in simulation file." ::= - (allEquations |> eqn => (match eqn + (linearSystems |> eqn => (match eqn case eq as SES_MIXED(__) then functionSetupLinearSystemsTemp(fill(eq.cont,1), modelNamePrefix) // no dynamic tearing case eq as SES_LINEAR(lSystem=ls as LINEARSYSTEM(__), alternativeTearing=NONE()) then @@ -2393,47 +2351,31 @@ template functionSetupLinearSystemsTemp(list allEquations, String m ;separator="\n\n") end functionSetupLinearSystemsTemp; -template functionInitialNonLinearSystems(list initialEquations, list initialEquations_lambda0, list parameterEquations, list allEquations, list inlineEquations, list jacobianMatrixes, String modelNamePrefix) +template functionInitialNonLinearSystems(list nonlinearSystems, String modelNamePrefix) "Generates functions in simulation file." ::= - let &tempeqns1 = buffer "" - let &tempeqns1 += (initialEquations |> eq => match eq case eq as SES_NONLINEAR(alternativeTearing = SOME(__)) then 'int <%symbolName(modelNamePrefix,"eqFunction")%>_<%equationIndex(eq)%>(DATA*, threadData_t*);' ; separator = "\n") - let &tempeqns2 = buffer "" - let &tempeqns2 += (initialEquations_lambda0 |> eq => match eq case eq as SES_NONLINEAR(alternativeTearing = SOME(__)) then 'int <%symbolName(modelNamePrefix,"eqFunction")%>_<%equationIndex(eq)%>(DATA*, threadData_t*);' ; separator = "\n") - let &tempeqns3 = buffer "" - let &tempeqns3 += (allEquations |> eq => match eq case eq as SES_NONLINEAR(alternativeTearing = SOME(__)) then 'int <%symbolName(modelNamePrefix,"eqFunction")%>_<%equationIndex(eq)%>(DATA*, threadData_t*);' ; separator = "\n") + let &tempeqns = buffer "" + let &tempeqns += (nonlinearSystems |> eq => match eq case eq as SES_NONLINEAR(alternativeTearing = SOME(__)) then 'int <%symbolName(modelNamePrefix,"eqFunction")%>_<%equationIndex(eq)%>(DATA*, threadData_t*);' ; separator = "\n") let &globalConstraintsFunctions = buffer "" - let initbody = functionInitialNonLinearSystemsTemp(initialEquations, modelNamePrefix,&globalConstraintsFunctions) - let initbody_lambda0 = functionInitialNonLinearSystemsTemp(initialEquations_lambda0, modelNamePrefix,&globalConstraintsFunctions) - let parambody = functionInitialNonLinearSystemsTemp(parameterEquations,modelNamePrefix,&globalConstraintsFunctions) - let equationbody = functionInitialNonLinearSystemsTemp(allEquations,modelNamePrefix,&globalConstraintsFunctions) - let inlineEqnsbody = functionInitialNonLinearSystemsTemp(inlineEquations,modelNamePrefix,&globalConstraintsFunctions) - let jacobianbody = ((jacobianMatrixes |> JAC_MATRIX(columns=clst) => (clst |> JAC_COLUMN(columnEqns=cEqns) => functionInitialNonLinearSystemsTemp(cEqns, modelNamePrefix, &globalConstraintsFunctions);separator="\n") ;separator="\n")) + let nlsbody = functionInitialNonLinearSystemsTemp(nonlinearSystems, modelNamePrefix, &globalConstraintsFunctions) << /* Prototypes for the strict sets (Dynamic Tearing) */ - <%tempeqns1%> - <%tempeqns2%> - <%tempeqns3%> + <%tempeqns%> /* Global constraints for the casual sets */ <%globalConstraintsFunctions%> /* function initialize non-linear systems */ void <%symbolName(modelNamePrefix,"initialNonLinearSystem")%>(int nNonLinearSystems, NONLINEAR_SYSTEM_DATA* nonLinearSystemData) { - <%initbody%> - <%initbody_lambda0%> - <%parambody%> - <%equationbody%> - <%inlineEqnsbody%> - <%jacobianbody%> + <%nlsbody%> } >> end functionInitialNonLinearSystems; -template functionInitialNonLinearSystemsTemp(list allEquations, String modelPrefixName, Text &globalConstraintsFunctions) +template functionInitialNonLinearSystemsTemp(list nonlinearSystems, String modelPrefixName, Text &globalConstraintsFunctions) "Generates functions in simulation file." ::= - (allEquations |> eqn => (match eqn + (nonlinearSystems |> eqn => (match eqn case eq as SES_MIXED(__) then functionInitialNonLinearSystemsTemp(fill(eq.cont,1), modelPrefixName, &globalConstraintsFunctions) // no dynamic tearing case eq as SES_NONLINEAR(nlSystem=nls as NONLINEARSYSTEM(__), alternativeTearing=NONE()) then @@ -2464,7 +2406,7 @@ template generateNonLinearSystemData(NonlinearSystem system, Integer indexStrict let size = listLength(nls.crefs) let generatedJac = match nls.jacobianMatrix case SOME(JAC_MATRIX(columns={},matrixName=name)) then 'NULL' case SOME(JAC_MATRIX(matrixName=name)) then '<%symbolName(modelPrefixName,"functionJac")%><%name%>_column' case NONE() then 'NULL' let initialJac = match nls.jacobianMatrix case SOME(JAC_MATRIX(columns={},matrixName=name)) then 'NULL' case SOME(JAC_MATRIX(matrixName=name)) then '<%symbolName(modelPrefixName,"initialAnalyticJacobian")%><%name%>' case NONE() then 'NULL' - let jacIndex = match nls.jacobianMatrix case SOME(JAC_MATRIX(columns={}, matrixName=name)) then '-1' case SOME(JAC_MATRIX(matrixName=name, jacobianIndex=jacindex)) then '<%jacindex%>' case NONE() then '-1' + let jacIndex = match nls.jacobianMatrix case SOME(JAC_MATRIX(columns={}, matrixName=name)) then '-1' case SOME(JAC_MATRIX(matrixName=name, jacobianIndex=jacindex)) then '<%jacindex%> /*jacInx*/' case NONE() then '-1' let innerSystems = functionInitialNonLinearSystemsTemp(nls.eqs, modelPrefixName, "") let casualCall = if not intEq(indexStrict, 0) then '<%symbolName(modelPrefixName,"eqFunction")%>_<%indexStrict%>' else 'NULL' let constraintsCall = if not intEq(indexStrict, 0) then 'checkConstraints<%nls.index%>' else 'NULL' @@ -2588,10 +2530,10 @@ template createLocalConstraints(SimEqSystem eq) end match end createLocalConstraints; -template functionNonLinearResiduals(list allEquations, String modelNamePrefix) +template functionNonLinearResiduals(list nonlinearSystems, String modelNamePrefix) "Generates functions in simulation file." ::= - (allEquations |> eqn => ( + (nonlinearSystems |> eqn => ( let () = tmpTickReset(0) match eqn case eq as SES_MIXED(__) then functionNonLinearResiduals(fill(eq.cont,1),modelNamePrefix) diff --git a/Compiler/Template/SimCodeTV.mo b/Compiler/Template/SimCodeTV.mo index eaf17ad2e30..0bedc589ad6 100644 --- a/Compiler/Template/SimCodeTV.mo +++ b/Compiler/Template/SimCodeTV.mo @@ -550,6 +550,8 @@ package SimCode list labels; Integer nClocks; Integer nSubClocks; + list linearSystems; + list nonLinearSystems; end MODELINFO; end ModelInfo;