/* Copyright 2019 Equinor ASA This file is part of the Open Porous Media project (OPM). OPM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OPM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OPM. If not, see . */ #include #include #include using bda::BlockedMatrix; namespace bda { /*Sort a row of matrix elements from a blocked CSR-format.*/ template void sortBlockedRow(int *colIndices, double *data, int left, int right) { const unsigned int bs = block_size; int l = left; int r = right; int middle = colIndices[(l + r) >> 1]; double lDatum[bs * bs]; do { while (colIndices[l] < middle) l++; while (colIndices[r] > middle) r--; if (l <= r) { int lColIndex = colIndices[l]; colIndices[l] = colIndices[r]; colIndices[r] = lColIndex; memcpy(lDatum, data + l * bs * bs, sizeof(double) * bs * bs); memcpy(data + l * bs * bs, data + r * bs * bs, sizeof(double) * bs * bs); memcpy(data + r * bs * bs, lDatum, sizeof(double) * bs * bs); l++; r--; } } while (l < r); if (left < r) sortBlockedRow(colIndices, data, left, r); if (right > l) sortBlockedRow(colIndices, data, l, right); } // LUMat->nnzValues[ik] = LUMat->nnzValues[ik] - (pivot * LUMat->nnzValues[jk]) in ilu decomposition // a = a - (b * c) template void blockMultSub(double *a, double *b, double *c) { for (unsigned int row = 0; row < block_size; row++) { for (unsigned int col = 0; col < block_size; col++) { double temp = 0.0; for (unsigned int k = 0; k < block_size; k++) { temp += b[block_size * row + k] * c[block_size * k + col]; } a[block_size * row + col] -= temp; } } } /*Perform a 3x3 matrix-matrix multiplicationj on two blocks*/ template void blockMult(double *mat1, double *mat2, double *resMat) { for (unsigned int row = 0; row < block_size; row++) { for (unsigned int col = 0; col < block_size; col++) { double temp = 0; for (unsigned int k = 0; k < block_size; k++) { temp += mat1[block_size * row + k] * mat2[block_size * k + col]; } resMat[block_size * row + col] = temp; } } } #define INSTANTIATE_BDA_FUNCTIONS(n) \ template void sortBlockedRow(int *, double *, int, int); \ template void blockMultSub(double *, double *, double *); \ template void blockMult(double *, double *, double *); \ INSTANTIATE_BDA_FUNCTIONS(1); INSTANTIATE_BDA_FUNCTIONS(2); INSTANTIATE_BDA_FUNCTIONS(3); INSTANTIATE_BDA_FUNCTIONS(4); #undef INSTANTIATE_BDA_FUNCTIONS } // end namespace bda