mirror of
				https://github.com/OPM/opm-simulators.git
				synced 2025-02-25 18:55:30 -06:00 
			
		
		
		
	Merge pull request #402 from atgeirr/interleaved-matrix
Move forming interleaved matrix to own function
This commit is contained in:
		| @@ -105,53 +105,21 @@ namespace Opm | |||||||
|             eqs[phase] = eqs[phase] * matbalscale[phase]; |             eqs[phase] = eqs[phase] * matbalscale[phase]; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         // Find sparsity structure as union of basic block sparsity structures, |  | ||||||
|         // corresponding to the jacobians with respect to pressure. |  | ||||||
|         // Use addition to get to the union structure. |  | ||||||
|         Eigen::SparseMatrix<double> structure = eqs[0].derivative()[0]; |  | ||||||
|         for (int phase = 0; phase < np; ++phase) { |  | ||||||
|             structure += eqs[phase].derivative()[0]; |  | ||||||
|         } |  | ||||||
|         Eigen::SparseMatrix<double, Eigen::RowMajor> s = structure; |  | ||||||
|  |  | ||||||
|         // Form modified system. |         // Form modified system. | ||||||
|         Eigen::SparseMatrix<double, Eigen::RowMajor> A; |         Eigen::SparseMatrix<double, Eigen::RowMajor> A; | ||||||
|         V b; |         V b; | ||||||
|         formEllipticSystem(np, eqs, A, b); |         formEllipticSystem(np, eqs, A, b); | ||||||
|  |  | ||||||
|         // Create ISTL matrix with interleaved rows and columns (block structured). |         // Create ISTL matrix with interleaved rows and columns (block structured). | ||||||
|         assert(np == 3); |         Mat istlA; | ||||||
|         Mat istlA(s.rows(), s.cols(), s.nonZeros(), Mat::row_wise); |         formInterleavedSystem(eqs, A, istlA); | ||||||
|         const int* ia = s.outerIndexPtr(); |  | ||||||
|         const int* ja = s.innerIndexPtr(); |  | ||||||
|         for (Mat::CreateIterator row = istlA.createbegin(); row != istlA.createend(); ++row) { |  | ||||||
|             int ri = row.index(); |  | ||||||
|             for (int i = ia[ri]; i < ia[ri + 1]; ++i) { |  | ||||||
|                 row.insert(ja[i]); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         const int size = s.rows(); |  | ||||||
|         Span span[3] = { Span(size, 1, 0), |  | ||||||
|                          Span(size, 1, size), |  | ||||||
|                          Span(size, 1, 2*size) }; |  | ||||||
|         for (int row = 0; row < size; ++row) { |  | ||||||
|             for (int col_ix = ia[row]; col_ix < ia[row + 1]; ++col_ix) { |  | ||||||
|                 const int col = ja[col_ix]; |  | ||||||
|                 MatrixBlockType block; |  | ||||||
|                 for (int p1 = 0; p1 < np; ++p1) { |  | ||||||
|                     for (int p2 = 0; p2 < np; ++p2) { |  | ||||||
|                         block[p1][p2] = A.coeff(span[p1][row], span[p2][col]); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 istlA[row][col] = block; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         // Solve reduced system. |         // Solve reduced system. | ||||||
|         SolutionVector dx(SolutionVector::Zero(b.size())); |         SolutionVector dx(SolutionVector::Zero(b.size())); | ||||||
|  |  | ||||||
|         // Right hand side. |         // Right hand side. | ||||||
|         Vector istlb(istlA.N()); |         const int size = istlA.N(); | ||||||
|  |         Vector istlb(size); | ||||||
|         for (int i = 0; i < size; ++i) { |         for (int i = 0; i < size; ++i) { | ||||||
|             istlb[i][0] = b(i); |             istlb[i][0] = b(i); | ||||||
|             istlb[i][1] = b(size + i); |             istlb[i][1] = b(size + i); | ||||||
| @@ -216,6 +184,55 @@ namespace Opm | |||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     void NewtonIterationBlackoilInterleaved::formInterleavedSystem(const std::vector<ADB>& eqs, | ||||||
|  |                                                                    const Eigen::SparseMatrix<double, Eigen::RowMajor>& A, | ||||||
|  |                                                                    Mat& istlA) const | ||||||
|  |     { | ||||||
|  |         const int np = eqs.size(); | ||||||
|  |  | ||||||
|  |         // Find sparsity structure as union of basic block sparsity structures, | ||||||
|  |         // corresponding to the jacobians with respect to pressure. | ||||||
|  |         // Use addition to get to the union structure. | ||||||
|  |         Eigen::SparseMatrix<double> structure = eqs[0].derivative()[0]; | ||||||
|  |         for (int phase = 0; phase < np; ++phase) { | ||||||
|  |             structure += eqs[phase].derivative()[0]; | ||||||
|  |         } | ||||||
|  |         Eigen::SparseMatrix<double, Eigen::RowMajor> s = structure; | ||||||
|  |  | ||||||
|  |         // Create ISTL matrix with interleaved rows and columns (block structured). | ||||||
|  |         assert(np == 3); | ||||||
|  |         istlA.setSize(s.rows(), s.cols(), s.nonZeros()); | ||||||
|  |         istlA.setBuildMode(Mat::row_wise); | ||||||
|  |         const int* ia = s.outerIndexPtr(); | ||||||
|  |         const int* ja = s.innerIndexPtr(); | ||||||
|  |         for (Mat::CreateIterator row = istlA.createbegin(); row != istlA.createend(); ++row) { | ||||||
|  |             int ri = row.index(); | ||||||
|  |             for (int i = ia[ri]; i < ia[ri + 1]; ++i) { | ||||||
|  |                 row.insert(ja[i]); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         const int size = s.rows(); | ||||||
|  |         Span span[3] = { Span(size, 1, 0), | ||||||
|  |                          Span(size, 1, size), | ||||||
|  |                          Span(size, 1, 2*size) }; | ||||||
|  |         for (int row = 0; row < size; ++row) { | ||||||
|  |             for (int col_ix = ia[row]; col_ix < ia[row + 1]; ++col_ix) { | ||||||
|  |                 const int col = ja[col_ix]; | ||||||
|  |                 MatrixBlockType block; | ||||||
|  |                 for (int p1 = 0; p1 < np; ++p1) { | ||||||
|  |                     for (int p2 = 0; p2 < np; ++p2) { | ||||||
|  |                         block[p1][p2] = A.coeff(span[p1][row], span[p2][col]); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 istlA[row][col] = block; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     const boost::any& NewtonIterationBlackoilInterleaved::parallelInformation() const |     const boost::any& NewtonIterationBlackoilInterleaved::parallelInformation() const | ||||||
|     { |     { | ||||||
|         return parallelInformation_; |         return parallelInformation_; | ||||||
|   | |||||||
| @@ -155,6 +155,10 @@ namespace Opm | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         void formInterleavedSystem(const std::vector<LinearisedBlackoilResidual::ADB>& eqs, | ||||||
|  |                                    const Eigen::SparseMatrix<double, Eigen::RowMajor>& A, | ||||||
|  |                                    Mat& istlA) const; | ||||||
|  |  | ||||||
|         mutable int iterations_; |         mutable int iterations_; | ||||||
|         boost::any parallelInformation_; |         boost::any parallelInformation_; | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user