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

Commit 1df8a4a

Browse files
Willi BraunOpenModelica-Hudson
authored andcommitted
added kinsol/klu solver support with sparsity
- reimplemented kinsol interface - enable sparsity generation for non-linear algebraic loops - enable usage of klu with nlsLS
1 parent ff3d39d commit 1df8a4a

File tree

12 files changed

+731
-232
lines changed

12 files changed

+731
-232
lines changed

Compiler/BackEnd/BackendDAEOptimize.mo

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1917,6 +1917,8 @@ algorithm
19171917
case BackendDAE.EMPTY_JACOBIAN()
19181918
then -1;
19191919
/* TODO: implement/check for GENERIC_JACOBIAN */
1920+
case BackendDAE.GENERIC_JACOBIAN(jacobian=NONE())
1921+
then -1;
19201922
case BackendDAE.GENERIC_JACOBIAN(jacobian=SOME((_,_,vars1,vars2,_)))
19211923
guard
19221924
listLength(vars1) == listLength(vars2)

Compiler/BackEnd/SymbolicJacobian.mo

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2390,9 +2390,9 @@ protected
23902390
Boolean b1, b2;
23912391
algorithm
23922392
if not Flags.isSet(Flags.FORCE_NLS_ANALYTIC_JACOBIAN) then
2393-
try // might fail because of algorithms TODO: fix it!
2393+
try // this might fail because of algorithms TODO: fix it!
23942394
(b1, _) := BackendEquation.traverseExpsOfEquationList_WithStop(inResidualEqns, traverserhasEqnNonDiffParts, ({}, true, false));
2395-
(b2, _) := BackendEquation.traverseExpsOfEquationList_WithStop(inOtherEqns, traverserhasEqnNonDiffParts, ({}, true, false));
2395+
(b2, _) := BackendEquation.traverseExpsOfEquationList_WithStop(inOtherEqns, traverserhasEqnNonDiffParts, ({}, true, false));
23962396
if not (b1 and b2) then
23972397
if Flags.isSet(Flags.FAILTRACE) then
23982398
Debug.traceln("Skip symbolic jacobian for non-linear system " + name + "\n");

Compiler/Template/CodegenC.tpl

Lines changed: 65 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -2488,20 +2488,24 @@ template functionNonLinearResiduals(list<SimEqSystem> allEquations, String model
24882488
alternativeTearing=NONE()) then
24892489
let residualFunction = generateNonLinearResidualFunction(nls, modelNamePrefix)
24902490
let indexName = 'NLS<%nls.index%>'
2491-
let bodyStaticData = generateStaticInitialDataWithSparse(nls.crefs, indexName, 'NONLINEAR_SYSTEM_DATA',sparsePattern,colorList,maxColor)
2491+
let sparseData = generateStaticSparseData(indexName, 'NONLINEAR_SYSTEM_DATA', sparsePattern, colorList, maxColor)
2492+
let bodyStaticData = generateStaticInitialData(nls.crefs, indexName, 'NONLINEAR_SYSTEM_DATA')
24922493
let updateIterationVars = getIterationVars(nls.crefs, indexName)
24932494
<<
24942495
<%residualFunction%>
2496+
<%sparseData%>
24952497
<%bodyStaticData%>
24962498
<%updateIterationVars%>
24972499
>>
24982500
case eq as SES_NONLINEAR(nlSystem=nls as NONLINEARSYSTEM(__),alternativeTearing=NONE()) then
24992501
let residualFunction = generateNonLinearResidualFunction(nls, modelNamePrefix)
25002502
let indexName = 'NLS<%nls.index%>'
2503+
let sparseData = generateStaticEmptySparseData(indexName, 'NONLINEAR_SYSTEM_DATA')
25012504
let bodyStaticData = generateStaticInitialData(nls.crefs, indexName, 'NONLINEAR_SYSTEM_DATA')
25022505
let updateIterationVars = getIterationVars(nls.crefs, indexName)
25032506
<<
25042507
<%residualFunction%>
2508+
<%sparseData%>
25052509
<%bodyStaticData%>
25062510
<%updateIterationVars%>
25072511
>>
@@ -2514,20 +2518,24 @@ template functionNonLinearResiduals(list<SimEqSystem> allEquations, String model
25142518
// for strict tearing set
25152519
let residualFunction = generateNonLinearResidualFunction(nls, modelNamePrefix)
25162520
let indexName = 'NLS<%nls.index%>'
2517-
let bodyStaticData = generateStaticInitialDataWithSparse(nls.crefs, indexName, 'NONLINEAR_SYSTEM_DATA',sparsePattern,colorList,maxColor)
2521+
let sparseData = generateStaticSparseData(indexName, 'NONLINEAR_SYSTEM_DATA', sparsePattern, colorList, maxColor)
2522+
let bodyStaticData = generateStaticInitialData(nls.crefs, indexName, 'NONLINEAR_SYSTEM_DATA')
25182523
let updateIterationVars = getIterationVars(nls.crefs, indexName)
25192524
let residualFunctionStrict = generateNonLinearResidualFunction(at, modelNamePrefix)
25202525
let indexName = 'NLS<%at.index%>'
2521-
let bodyStaticDataStrict = generateStaticInitialDataWithSparse(at.crefs, indexName, 'NONLINEAR_SYSTEM_DATA',sparsePattern2,colorList2,maxColor2)
2526+
let sparseDataStrict = generateStaticSparseData(indexName, 'NONLINEAR_SYSTEM_DATA', sparsePattern, colorList, maxColor)
2527+
let bodyStaticDataStrict = generateStaticInitialData(nls.crefs, indexName, 'NONLINEAR_SYSTEM_DATA')
25222528
let updateIterationVarsStrict = getIterationVars(nls.crefs, indexName)
25232529
<<
25242530
/* start dynamic tearing sets */
25252531
/* causal tearing set */
25262532
<%residualFunction%>
2533+
<%sparseData%>
25272534
<%bodyStaticData%>
25282535
<%updateIterationVars%>
25292536
/* strict tearing set */
25302537
<%residualFunctionStrict%>
2538+
<%sparseDataStrict%>
25312539
<%bodyStaticDataStrict%>
25322540
<%updateIterationVarsStrict%>
25332541
/* end dynamic tearing sets */
@@ -2538,20 +2546,24 @@ template functionNonLinearResiduals(list<SimEqSystem> allEquations, String model
25382546
// for strict tearing set
25392547
let residualFunction = generateNonLinearResidualFunction(nls, modelNamePrefix)
25402548
let indexName = 'NLS<%nls.index%>'
2549+
let sparseData = generateStaticEmptySparseData(indexName, 'NONLINEAR_SYSTEM_DATA')
25412550
let bodyStaticData = generateStaticInitialData(nls.crefs, indexName, 'NONLINEAR_SYSTEM_DATA')
25422551
let updateIterationVars = getIterationVars(nls.crefs, indexName)
25432552
let residualFunctionStrict = generateNonLinearResidualFunction(at, modelNamePrefix)
25442553
let indexName = 'NLS<%at.index%>'
2554+
let sparseDataStrict = generateStaticEmptySparseData(indexName, 'NONLINEAR_SYSTEM_DATA')
25452555
let bodyStaticDataStrict = generateStaticInitialData(at.crefs, indexName, 'NONLINEAR_SYSTEM_DATA')
25462556
let updateIterationVarsStrict = getIterationVars(nls.crefs, indexName)
25472557
<<
25482558
/* start dynamic tearing sets */
25492559
/* causal tearing set */
25502560
<%residualFunction%>
2561+
<%sparseData%>
25512562
<%bodyStaticData%>
25522563
<%updateIterationVars%>
25532564
/* strict tearing set */
25542565
<%residualFunctionStrict%>
2566+
<%sparseDataStrict%>
25552567
<%bodyStaticDataStrict%>
25562568
<%updateIterationVarsStrict%>
25572569
/* end dynamic tearing sets */
@@ -2633,87 +2645,67 @@ match system
26332645
>>
26342646
end generateNonLinearResidualFunction;
26352647

2636-
template generateStaticSparsePattern(list<tuple<Integer,list<Integer>>> sparsepattern, list<list<Integer>> colorList, Integer maxColor, Text &defintions)
2637-
"template generateStaticSparsePattern
2648+
template generateStaticEmptySparseData(String indexName, String systemType)
2649+
"template generateStaticEmptySparseData
2650+
This template generates source code for functions that initialize the sparse-pattern."
2651+
::=
2652+
<<
2653+
void initializeSparsePattern<%indexName%>(<%systemType%>* inSysData)
2654+
{
2655+
/* no sparsity pattern available */
2656+
inSysData->isPatternAvailable = 0;
2657+
}
2658+
>>
2659+
end generateStaticEmptySparseData;
2660+
2661+
template generateStaticSparseData(String indexName, String systemType, list<tuple<Integer,list<Integer>>> sparsepattern, list<list<Integer>> colorList, Integer maxColor)
2662+
"template generateStaticSparseData
26382663
This template generates source code for functions that initialize the sparse-pattern."
26392664
::=
26402665
match sparsepattern
2641-
case {} then <<>>
2666+
case {} then
2667+
<<
2668+
void initializeSparsePattern<%indexName%>(<%systemType%>* inSysData)
2669+
{
2670+
/* no sparsity pattern available */
2671+
inSysData->isPatternAvailable = 0;
2672+
}
2673+
>>
26422674
case _ then
26432675
let sp_size_index = lengthListElements(unzipSecond(sparsepattern))
26442676
let sizeleadindex = listLength(sparsepattern)
2645-
let leadindex = (sparsepattern |> (i, indexes) =>
2646-
<<
2647-
<%listLength(indexes)%>
2648-
>>
2649-
;separator=",")
2650-
let indexElems = ( sparsepattern |> (i, indexes) hasindex index0 =>
2651-
( indexes |> indexrow =>
2652-
<<
2653-
<%indexrow%>
2654-
>>
2655-
;separator=",")
2656-
;separator=",")
2657-
let colorArray = (colorList |> (indexes) hasindex index0 =>
2658-
let colorCol = ( indexes |> i_index =>
2659-
<<sysData->sparsePattern.colorCols[<%i_index%>] = <%intAdd(index0,1)%>;>>
2660-
;separator="\n")
2661-
'<%colorCol%>'
2662-
;separator="\n")
2663-
let &defintions += (
2677+
let colPtr = genSPCRSPtr(listLength(sparsepattern), sparsepattern, "colPtrIndex")
2678+
let rowIndex = genSPCRSRows(lengthListElements(unzipSecond(sparsepattern)), sparsepattern, "rowIndex")
2679+
let colorString = genSPColors(colorList, "inSysData->sparsePattern.colorCols")
26642680
<<
2665-
const int tmp[<%sizeleadindex%>] = {<%leadindex%>};
2666-
const int tmpElem[<%sp_size_index%>] = {<%indexElems%>};
2667-
>>)
2668-
<<
2669-
sysData->sparsePattern.leadindex = (unsigned int*) malloc(<%sizeleadindex%>*sizeof(int));
2670-
sysData->sparsePattern.index = (unsigned int*) malloc(<%sp_size_index%>*sizeof(int));
2671-
sysData->sparsePattern.numberOfNoneZeros = <%sp_size_index%>;
2672-
sysData->sparsePattern.colorCols = (unsigned int*) malloc(<%sizeleadindex%>*sizeof(int));
2673-
sysData->sparsePattern.maxColors = <%maxColor%>;
2681+
void initializeSparsePattern<%indexName%>(<%systemType%>* inSysData)
2682+
{
2683+
int i=0;
2684+
<%colPtr%>
2685+
<%rowIndex%>
2686+
/* sparsity pattern available */
2687+
inSysData->isPatternAvailable = 'T';
2688+
inSysData->sparsePattern.leadindex = (unsigned int*) malloc((<%sizeleadindex%>+1)*sizeof(int));
2689+
inSysData->sparsePattern.index = (unsigned int*) malloc(<%sp_size_index%>*sizeof(int));
2690+
inSysData->sparsePattern.numberOfNoneZeros = <%sp_size_index%>;
2691+
inSysData->sparsePattern.colorCols = (unsigned int*) malloc(<%sizeleadindex%>*sizeof(int));
2692+
inSysData->sparsePattern.maxColors = <%maxColor%>;
26742693
2675-
/* write lead index of compressed sparse column */
2676-
memcpy(sysData->sparsePattern.leadindex, tmp, <%sizeleadindex%>*sizeof(int));
2694+
/* write lead index of compressed sparse column */
2695+
memcpy( inSysData->sparsePattern.leadindex, colPtrIndex, (<%sizeleadindex%>+1)*sizeof(int));
26772696
2678-
for(i=1;i<<%sizeleadindex%>;++i)
2679-
sysData->sparsePattern.leadindex[i] += sysData->sparsePattern.leadindex[i-1];
2697+
for(i=1;i<<%sizeleadindex%>+1;++i)
2698+
inSysData->sparsePattern.leadindex[i] += inSysData->sparsePattern.leadindex[i-1];
26802699
2681-
/* call sparse index */
2682-
memcpy(sysData->sparsePattern.index, tmpElem, <%sp_size_index%>*sizeof(int));
2700+
/* call sparse index */
2701+
memcpy(inSysData->sparsePattern.index, rowIndex, <%sp_size_index%>*sizeof(int));
26832702
2684-
/* write color array */
2685-
<%colorArray%>
2703+
/* write color array */
2704+
<%colorString%>
2705+
}
26862706
>>
26872707
end match
2688-
end generateStaticSparsePattern;
2689-
2690-
template generateStaticInitialDataWithSparse(list<ComponentRef> crefs, String indexName, String systemType, list<tuple<Integer,list<Integer>>> sparsepattern, list<list<Integer>> colorList, Integer maxColor)
2691-
"Generates initial function for nonlinear loops."
2692-
::=
2693-
let bodyStaticData = (crefs |> cr hasindex i0 =>
2694-
<<
2695-
/* static nls data for <%crefStrNoUnderscore(cr)%> */
2696-
sysData->nominal[i] = <%crefAttributes(cr)%>.nominal;
2697-
sysData->min[i] = <%crefAttributes(cr)%>.min;
2698-
sysData->max[i++] = <%crefAttributes(cr)%>.max;
2699-
>>
2700-
;separator="\n")
2701-
let defintions = ""
2702-
let sparseBody = generateStaticSparsePattern(sparsepattern, colorList, maxColor, &defintions)
2703-
<<
2704-
2705-
void initializeStaticData<%indexName%>(void *inData, threadData_t *threadData, void *inSystemData)
2706-
{
2707-
DATA* data = (DATA*) inData;
2708-
<%systemType%>* sysData = (<%systemType%>*) inSystemData;
2709-
<%defintions%>
2710-
int i=0;
2711-
<%bodyStaticData%>
2712-
i=0;
2713-
<%sparseBody%>
2714-
}
2715-
>>
2716-
end generateStaticInitialDataWithSparse;
2708+
end generateStaticSparseData;
27172709

27182710
template generateStaticInitialData(list<ComponentRef> crefs, String indexName, String systemType)
27192711
"Generates initial function for nonlinear loops."
@@ -2733,6 +2725,8 @@ template generateStaticInitialData(list<ComponentRef> crefs, String indexName, S
27332725
<%systemType%>* sysData = (<%systemType%>*) inSystemData;
27342726
int i=0;
27352727
<%bodyStaticData%>
2728+
/* initial sparse pattern */
2729+
initializeSparsePattern<%indexName%>(sysData);
27362730
}
27372731
>>
27382732
end generateStaticInitialData;

Compiler/Template/CodegenCpp.tpl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6213,6 +6213,23 @@ case SIMCODE(modelInfo = MODELINFO(__)) then
62136213
let modelName = lastIdentOfPath(modelInfo.name)
62146214

62156215
match eq
6216+
/* in case only sparsity pattern is available handle for now as empty */
6217+
case SES_NONLINEAR(nlSystem = nls as NONLINEARSYSTEM(jacobianMatrix = SOME(({},_,_,_,_,_,_)))) then
6218+
<<
6219+
6220+
const matrix_t& <%modelName%>Algloop<%nls.index%>::getSystemMatrix()
6221+
{
6222+
// return empty matrix to indicate that no symbolic Jacobian is available
6223+
static matrix_t empty(0, 0);
6224+
return empty;
6225+
}
6226+
6227+
const sparsematrix_t& <%modelName%>Algloop<%nls.index%>::getSystemSparseMatrix()
6228+
{
6229+
throw ModelicaSimulationError(MATH_FUNCTION, "Sparse symbolic Jacobian is not suported yet");
6230+
}
6231+
>>
6232+
62166233
case SES_NONLINEAR(nlSystem = nls as NONLINEARSYSTEM(jacobianMatrix = SOME((_,_,_,_,_,_,index)))) then
62176234
<<
62186235

0 commit comments

Comments
 (0)