mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Use std::find and added comments
This commit is contained in:
parent
a8e524fc9d
commit
123e3fa89e
@ -238,80 +238,100 @@ namespace bda
|
|||||||
double *Ltmp = new double[Lmat->nnzbs * block_size * block_size];
|
double *Ltmp = new double[Lmat->nnzbs * block_size * block_size];
|
||||||
for (int sweep = 0; sweep < num_sweeps; ++sweep) {
|
for (int sweep = 0; sweep < num_sweeps; ++sweep) {
|
||||||
|
|
||||||
|
// algorithm
|
||||||
|
// for every block in A (LUmat):
|
||||||
|
// if i > j:
|
||||||
|
// Lij = (Aij - sum k=1 to j-1 {Lik*Ukj}) / Ujj
|
||||||
|
// else:
|
||||||
|
// Uij = (Aij - sum k=1 to i-1 {Lik*Ukj})
|
||||||
|
|
||||||
// for every row
|
// for every row
|
||||||
for (int row = 0; row < Nb; row++) {
|
for (int row = 0; row < Nb; row++) {
|
||||||
// update U
|
// update U
|
||||||
|
// Uij = (Aij - sum k=1 to i-1 {Lik*Ukj})
|
||||||
int jColStart = Ut->rowPointers[row];
|
int jColStart = Ut->rowPointers[row];
|
||||||
int jColEnd = Ut->rowPointers[row + 1];
|
int jColEnd = Ut->rowPointers[row + 1];
|
||||||
|
int colU = row; // rename for clarity, next row in Ut means next col in U
|
||||||
// for every block in this row
|
// for every block in this row
|
||||||
for (int ij = jColStart; ij < jColEnd; ij++) {
|
for (int ij = jColStart; ij < jColEnd; ij++) {
|
||||||
int col = Ut->colIndices[ij];
|
int rowU1 = Ut->colIndices[ij]; // actually rowIndices for U
|
||||||
// refine Uij element (or diagonal)
|
// refine Uij element (or diagonal)
|
||||||
int i1 = LUmat->rowPointers[col];
|
int i1 = LUmat->rowPointers[rowU1];
|
||||||
int i2 = LUmat->rowPointers[col+1];
|
int i2 = LUmat->rowPointers[rowU1+1];
|
||||||
int kk = 0;
|
|
||||||
for(kk = i1; kk < i2; ++kk) {
|
// search on row rowU1, find blockIndex in LUmat of block with same col (colU) as Uij
|
||||||
ptrdiff_t c = LUmat->colIndices[kk];
|
// LUmat->nnzValues[kk] is block Aij
|
||||||
if (c >= row) {
|
auto candidate = std::find(LUmat->colIndices + i1, LUmat->colIndices + i2, colU);
|
||||||
break;
|
assert(candidate != LUmat->colIndices + i2);
|
||||||
}
|
auto kk = candidate - LUmat->colIndices;
|
||||||
}
|
|
||||||
double aij[bs*bs];
|
double aij[bs*bs];
|
||||||
|
// copy block to Aij so operations can be done on it without affecting LUmat
|
||||||
memcpy(&aij[0], LUmat->nnzValues + kk * bs * bs, sizeof(double) * bs * bs);
|
memcpy(&aij[0], LUmat->nnzValues + kk * bs * bs, sizeof(double) * bs * bs);
|
||||||
int jk = Lmat->rowPointers[col];
|
|
||||||
int ik = (jk < Lmat->rowPointers[col+1]) ? Lmat->colIndices[jk] : Nb;
|
|
||||||
|
|
||||||
for (int k = jColStart; k < ij; ++k) {
|
int jk = Lmat->rowPointers[rowU1]; // points to row rowU1 in L
|
||||||
int ki = Ut->colIndices[k];
|
// if row rowU1 is empty, skip row
|
||||||
while (ik < ki) {
|
if (jk < Lmat->rowPointers[rowU1+1]) {
|
||||||
++jk;
|
int colL = Lmat->colIndices[jk];
|
||||||
ik = Lmat->colIndices[jk];
|
for (int k = jColStart; k < ij; ++k) {
|
||||||
}
|
int rowU2 = Ut->colIndices[k];
|
||||||
if (ik == ki) {
|
while (colL < rowU2) {
|
||||||
blockMultSub<bs>(&aij[0], Lmat->nnzValues + jk * bs * bs, Ut->nnzValues + k * bs * bs);
|
++jk; // check next block on row rowU1 of L
|
||||||
|
colL = Lmat->colIndices[jk];
|
||||||
|
}
|
||||||
|
if (colL == rowU2) {
|
||||||
|
// Aij -= (Lik * Ukj)
|
||||||
|
blockMultSub<bs>(&aij[0], Lmat->nnzValues + jk * bs * bs, Ut->nnzValues + k * bs * bs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Uij_new = Aij - sum
|
||||||
memcpy(Utmp + ij * bs * bs, &aij[0], sizeof(double) * bs * bs);
|
memcpy(Utmp + ij * bs * bs, &aij[0], sizeof(double) * bs * bs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// update L
|
// update L
|
||||||
|
// Lij = (Aij - sum k=1 to j-1 {Lik*Ukj}) / Ujj
|
||||||
int iRowStart = Lmat->rowPointers[row];
|
int iRowStart = Lmat->rowPointers[row];
|
||||||
int iRowEnd = Lmat->rowPointers[row + 1];
|
int iRowEnd = Lmat->rowPointers[row + 1];
|
||||||
|
|
||||||
for (int ij = iRowStart; ij < iRowEnd; ij++) {
|
for (int ij = iRowStart; ij < iRowEnd; ij++) {
|
||||||
int j = Lmat->colIndices[ij];
|
int j = Lmat->colIndices[ij];
|
||||||
// refine Lij element
|
// refine Lij element
|
||||||
|
// search on row 'row', find blockIndex in LUmat of block with same col (j) as Lij
|
||||||
|
// LUmat->nnzValues[kk] is block Aij
|
||||||
int i1 = LUmat->rowPointers[row];
|
int i1 = LUmat->rowPointers[row];
|
||||||
int i2 = LUmat->rowPointers[row+1];
|
int i2 = LUmat->rowPointers[row+1];
|
||||||
int kk = 0;
|
|
||||||
for(kk = i1; kk < i2; ++kk) {
|
auto candidate = std::find(LUmat->colIndices + i1, LUmat->colIndices + i2, j);
|
||||||
ptrdiff_t c = LUmat->colIndices[kk];
|
assert(candidate != LUmat->colIndices + i2);
|
||||||
if (c >= j) {
|
auto kk = candidate - LUmat->colIndices;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
double aij[bs*bs];
|
double aij[bs*bs];
|
||||||
|
// copy block to Aij so operations can be done on it without affecting LUmat
|
||||||
memcpy(&aij[0], LUmat->nnzValues + kk * bs * bs, sizeof(double) * bs * bs);
|
memcpy(&aij[0], LUmat->nnzValues + kk * bs * bs, sizeof(double) * bs * bs);
|
||||||
int jk = Ut->rowPointers[j];
|
|
||||||
int ik = Ut->colIndices[jk];
|
int jk = Ut->rowPointers[j]; // actually colPointers, jk points to col j in U
|
||||||
|
int rowU = Ut->colIndices[jk]; // actually rowIndices, rowU is the row of block jk
|
||||||
|
// check if L has a matching block where colL == rowU
|
||||||
for (int k = iRowStart; k < ij; ++k) {
|
for (int k = iRowStart; k < ij; ++k) {
|
||||||
int ki = Lmat->colIndices[k];
|
int colL = Lmat->colIndices[k];
|
||||||
while(ik < ki) {
|
while (rowU < colL) {
|
||||||
++jk;
|
++jk; // check next block on col j of U
|
||||||
ik = Ut->colIndices[jk];
|
rowU = Ut->colIndices[jk];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ik == ki) {
|
if (rowU == colL) {
|
||||||
|
// Aij -= (Lik * Ukj)
|
||||||
blockMultSub<bs>(&aij[0], Lmat->nnzValues + k * bs * bs , Ut->nnzValues + jk * bs * bs);
|
blockMultSub<bs>(&aij[0], Lmat->nnzValues + k * bs * bs , Ut->nnzValues + jk * bs * bs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// calculate aij / ujj
|
|
||||||
|
// calculate (Aij - sum) / Ujj
|
||||||
double ujj[bs*bs];
|
double ujj[bs*bs];
|
||||||
inverter(Ut->nnzValues + (Ut->rowPointers[j+1] - 1) * bs * bs, &ujj[0]);
|
inverter(Ut->nnzValues + (Ut->rowPointers[j+1] - 1) * bs * bs, &ujj[0]);
|
||||||
// lij = aij / ujj
|
// Lij_new = (Aij - sum) / Ujj
|
||||||
blockMult<bs>(&aij[0], &ujj[0], Ltmp + ij * bs * bs);
|
blockMult<bs>(&aij[0], &ujj[0], Ltmp + ij * bs * bs);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 1st sweep writes to Ltmp
|
// 1st sweep writes to Ltmp
|
||||||
|
Loading…
Reference in New Issue
Block a user