Skip to content

Commit 20e4e7a

Browse files
author
Jens Frenkel
committed
- add error message for division by zero to initial equations
- use c comments - better error message vor pivot.c git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@14718 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
1 parent 9f58e5d commit 20e4e7a

File tree

4 files changed

+46
-26
lines changed

4 files changed

+46
-26
lines changed

Compiler/BackEnd/SimCodeUtil.mo

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1570,6 +1570,7 @@ algorithm
15701570
startValueEquations = List.map(startValueEquations,addDivExpErrorMsgtoSimEqSystem);
15711571
parameterEquations = List.map(parameterEquations,addDivExpErrorMsgtoSimEqSystem);
15721572
removedEquations = List.map(removedEquations,addDivExpErrorMsgtoSimEqSystem);
1573+
initialEquations = List.map(initialEquations,addDivExpErrorMsgtoSimEqSystem);
15731574

15741575
// generate jacobian or linear model matrices
15751576
LinearMatrices = createJacobianLinearCode(symJacs, modelInfo, uniqueEqIndex);

SimulationRuntime/c/math-support/pivot.c

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -33,24 +33,24 @@
3333
/*
3434
find the maximum element below (and including) line/row start
3535
*/
36-
void maxsearch( double *A, modelica_integer start, modelica_integer n_rows, modelica_integer n_cols, modelica_integer *rowInd, modelica_integer *colInd, modelica_integer *maxrow, modelica_integer *maxcol, double *maxabsval)
36+
int maxsearch( double *A, modelica_integer start, modelica_integer n_rows, modelica_integer n_cols, modelica_integer *rowInd, modelica_integer *colInd, modelica_integer *maxrow, modelica_integer *maxcol, double *maxabsval)
3737
{
38-
// temporary variables
38+
/* temporary variables */
3939
modelica_integer row;
4040
modelica_integer col;
4141

42-
// Initialization
42+
/* Initialization */
4343
modelica_integer mrow = -1;
4444
modelica_integer mcol = -1;
4545
double mabsval = 0.0;
4646

47-
// go through all rows and columns
47+
/* go through all rows and columns */
4848
for(row=start; row<n_rows; row++)
4949
{
5050
for(col=start; col<n_cols; col++)
5151
{
5252
double tmp = fabs(get_pivot_matrix_elt(A,row,col));
53-
// Compare element to current maximum
53+
/* Compare element to current maximum */
5454
if (tmp > mabsval)
5555
{
5656
mrow = row;
@@ -60,11 +60,10 @@ void maxsearch( double *A, modelica_integer start, modelica_integer n_rows, mode
6060
}
6161
}
6262

63-
// assert that the matrix is not identical to zero
64-
assert(mrow >= 0);
65-
assert(mcol >= 0);
63+
/* assert that the matrix is not identical to zero */
64+
if ((mrow < 0) || (mcol < 0)) return -1;
6665

67-
// return result
66+
// return result */
6867
*maxrow = mrow;
6968
*maxcol = mcol;
7069
*maxabsval = mabsval;
@@ -78,52 +77,54 @@ rowInd and colInd are vectors of length nrwos and n_cols respectively.
7877
They hold the old (and new) pivoting information, such that
7978
A_pivoted[i,j] = A[rowInd[i], colInd[j]]
8079
*/
81-
void pivot( double *A, modelica_integer n_rows, modelica_integer n_cols, modelica_integer *rowInd, modelica_integer *colInd )
80+
int pivot( double *A, modelica_integer n_rows, modelica_integer n_cols, modelica_integer *rowInd, modelica_integer *colInd )
8281
{
83-
// parameter, determines how much larger an element should be before rows and columns are interchanged
82+
/* parameter, determines how much larger an element should be before rows and columns are interchanged */
8483
const double fac = 1.125; // approved by dymola ;)
8584

86-
// temporary variables
85+
/* temporary variables */
8786
modelica_integer row;
8887
modelica_integer i,j;
8988
modelica_integer maxrow;
9089
modelica_integer maxcol;
9190
double maxabsval;
9291
double pivot;
9392

94-
// go over all pivot elements
93+
/* go over all pivot elements */
9594
for(row=0; row<min(n_rows,n_cols); row++)
9695
{
97-
// get current pivot
96+
/* get current pivot */
9897
pivot = fabs(get_pivot_matrix_elt(A,row,row));
9998

100-
// find the maximum element in matrix
101-
// result is stored in maxrow, maxcol and maxabsval
102-
maxsearch(A, row, n_rows, n_cols, rowInd, colInd, &maxrow, &maxcol, &maxabsval);
99+
/* find the maximum element in matrix
100+
result is stored in maxrow, maxcol and maxabsval */
101+
if (maxsearch(A, row, n_rows, n_cols, rowInd, colInd, &maxrow, &maxcol, &maxabsval) != 0) return -1;
103102

104-
// compare max element and pivot (scaled by fac)
103+
104+
/* compare max element and pivot (scaled by fac) */
105105
if (maxabsval > (fac*pivot))
106106
{
107-
// row interchange
107+
/* row interchange */
108108
swap(rowInd[row], rowInd[maxrow]);
109-
// column interchange
109+
/* column interchange */
110110
swap(colInd[row], colInd[maxcol]);
111111
}
112112

113-
// get pivot (without abs, may have changed because of row/column interchange
113+
/* get pivot (without abs, may have changed because of row/column interchange */
114114
pivot = get_pivot_matrix_elt(A,row,row);
115+
/* internal error, pivot element should never be zero if maxsearch succeeded */
115116
assert(pivot != 0);
116117

117-
// perform one step of Gaussian Elimination
118+
/* perform one step of Gaussian Elimination */
118119
for(i=row+1;i<n_rows;i++)
119120
{
120121
double leader = get_pivot_matrix_elt(A,i,row);
121122
if (leader != 0.0)
122123
{
123124
double scale = -leader/pivot;
124-
// set leader to zero
125+
/* set leader to zero */
125126
set_pivot_matrix_elt(A,i,row, 0.0);
126-
// subtract scaled equation from pivot row from current row
127+
/* subtract scaled equation from pivot row from current row */
127128
for(j=row+1;j<n_cols;j++)
128129
{
129130
double t1 = get_pivot_matrix_elt(A,i,j);
@@ -134,5 +135,7 @@ void pivot( double *A, modelica_integer n_rows, modelica_integer n_cols, modelic
134135
}
135136
}
136137
}
138+
/* all fine */
139+
return 0;
137140
}
138141

SimulationRuntime/c/simulation/solver/stateset.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
#include "stateset.h"
3333
#include "matrix.h"
34+
#include "omc_error.h"
3435

3536
#include <memory.h>
3637

@@ -212,6 +213,7 @@ int comparePivot(modelica_integer *oldPivot, modelica_integer *newPivot, modelic
212213
int stateSelection(DATA *data)
213214
{
214215
long i=0;
216+
long j=0;
215217
int res=0;
216218
/* go troug all state sets*/
217219
for (i=0;i<data->modelData.nStateSets;i++)
@@ -222,7 +224,21 @@ int stateSelection(DATA *data)
222224
getAnalyticalJacobianSet(data,i);
223225
/* call pivoting function to select the states */
224226
memcpy(oldColPivot,set->colPivot,set->nCandidates*sizeof(modelica_integer));
225-
pivot(set->J,set->nDummyStates,set->nCandidates,set->rowPivot,set->colPivot);
227+
if (pivot(set->J,set->nDummyStates,set->nCandidates,set->rowPivot,set->colPivot) != 0)
228+
{
229+
/* error, report the matrix and the time */
230+
for(i=0; i < data->simulationInfo.analyticJacobians[set->jacobianIndex].sizeRows;i++)
231+
{
232+
for(j=0; j < data->simulationInfo.analyticJacobians[set->jacobianIndex].sizeCols;j++)
233+
printf("% .5e ",set->J[i*data->simulationInfo.analyticJacobians[set->jacobianIndex].sizeCols+j]);
234+
printf("\n");
235+
}
236+
for (i=0;i<set->nCandidates;i++)
237+
{
238+
printf("%s\n",set->statescandidates[i]->name);
239+
}
240+
THROW1("Error, singular Jacobian for dynamic state selection at time %f\nUse -lv LOG_DSSJAC to get the Jacobian\n",data->localData[0]->timeValue);
241+
}
226242
/* if we have a new set throw event for reinitialization
227243
and set the A matrix for set.x=A*(states) */
228244
res = comparePivot(oldColPivot,set->colPivot,set->nCandidates,set->nDummyStates,set->nStates,set->A,set->states,set->statescandidates,data);

SimulationRuntime/c/simulation/solver/stateset.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ void initializeStateSetJacobians(DATA *data);
4141
int stateSelection(DATA *data);
4242

4343
/* do pivoting */
44-
extern void pivot( double *A, modelica_integer n_rows, modelica_integer n_cols, modelica_integer *rowInd, modelica_integer *colInd );
44+
extern int pivot( double *A, modelica_integer n_rows, modelica_integer n_cols, modelica_integer *rowInd, modelica_integer *colInd );
4545

4646

4747
#endif /* OMC_STATESET_H */

0 commit comments

Comments
 (0)