Multiscale Universal Interface  2.0
A Concurrent Framework for Coupling Heterogeneous Solvers
preconditioner_ilu.h
Go to the documentation of this file.
1 /*****************************************************************************
2 * Multiscale Universal Interface Code Coupling Library *
3 * *
4 * Copyright (C) 2023 W. Liu *
5 * *
6 * This software is jointly licensed under the Apache License, Version 2.0 *
7 * and the GNU General Public License version 3, you may use it according *
8 * to either. *
9 * *
10 * ** Apache License, version 2.0 ** *
11 * *
12 * Licensed under the Apache License, Version 2.0 (the "License"); *
13 * you may not use this file except in compliance with the License. *
14 * You may obtain a copy of the License at *
15 * *
16 * http://www.apache.org/licenses/LICENSE-2.0 *
17 * *
18 * Unless required by applicable law or agreed to in writing, software *
19 * distributed under the License is distributed on an "AS IS" BASIS, *
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
21 * See the License for the specific language governing permissions and *
22 * limitations under the License. *
23 * *
24 * ** GNU General Public License, version 3 ** *
25 * *
26 * This program is free software: you can redistribute it and/or modify *
27 * it under the terms of the GNU General Public License as published by *
28 * the Free Software Foundation, either version 3 of the License, or *
29 * (at your option) any later version. *
30 * *
31 * This program is distributed in the hope that it will be useful, *
32 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
33 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
34 * GNU General Public License for more details. *
35 * *
36 * You should have received a copy of the GNU General Public License *
37 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
38 *****************************************************************************/
39 
47 #ifndef MUI_PRECONDITIONER_ILU_H_
48 #define MUI_PRECONDITIONER_ILU_H_
49 
50 namespace mui {
51 namespace linalg {
52 
53 // Constructor
54 template<typename ITYPE, typename VTYPE>
56  // Initialize Lower and Upper triangular matrices
57  L_.resize(A.get_rows(), A.get_cols());
58  U_.resize(A.get_rows(), A.get_cols());
59 
60  // Perform the Incomplete LU factorisation
61  for (ITYPE i = 0; i < A.get_rows(); ++i) {
62  // Copy the diagonal element
63  L_.set_value(i, i, A.get_value(i, i));
64  U_.set_value(i, i, static_cast<VTYPE>(1.0));
65 
66  for (ITYPE j = 0; j < A.get_cols(); ++j) {
67  if (j < i) {
68  // Copy the lower triangular elements
69  L_.set_value(i, j, A.get_value(i, j));
70  } else if (j > i) {
71  // Copy the upper triangular elements
72  U_.set_value(i, j, A.get_value(i, j));
73  }
74  }
75 
76  // Perform the forward substitution step
77  for (ITYPE j1 = 0; j1 < L_.get_cols(); ++j1) {
78  if (j1 < i) {
79  for (ITYPE j2 = 0; j2 < U_.get_cols(); ++j2) {
80  if (j2 > j1) {
81  L_.set_value(i, j2, (L_.get_value(i, j2) - (L_.get_value(i, j1) * U_.get_value(j1, j2))));
82  }
83  }
84  }
85  }
86 
87  // Perform the backward substitution step
88  for (ITYPE j1 = 0; j1 < U_.get_cols(); ++j1) {
89  if (j1 > i) {
90  for (ITYPE j2 = 0; j2 < L_.get_cols(); ++j2) {
91  if (j2 < j1) {
92  U_.set_value(i, j2, (U_.get_value(i, j2) / L_.get_value(j1, j1)));
93  }
94  }
95  }
96  }
97  }
98 }
99 
100 // Destructor
101 template<typename ITYPE, typename VTYPE>
103  // Deallocate the memory for the lower triangular matrix
104  L_.set_zero();
105  U_.set_zero();
106 }
107 
108 // Member function on preconditioner apply
109 template<typename ITYPE, typename VTYPE>
111  assert((x.get_cols()==1) &&
112  "MUI Error [preconditioner_ilu.h]: apply only works for column vectors");
115 
116  // Perform the forward substitution step
117  for (ITYPE i = 0; i < x.get_rows(); ++i) {
118  VTYPE sum = 0;
119  for (ITYPE j = 0; j < L_.get_cols(); ++j) {
120  if (j < i) {
121  sum += L_.get_value(i, j) * y.get_value(j,0);
122  }
123  }
124  y.set_value(i,0,(x.get_value(i,0)-sum));
125  }
126 
127  // Perform the backward substitution step
128  for (ITYPE i = x.get_rows() - 1; i >= 0; i--) {
129  VTYPE sum = 0;
130  for (ITYPE j = 0; j < U_.get_cols(); ++j) {
131  if (j > i) {
132  sum += U_.get_value(i, j) * z.get_value(j,0);
133  }
134  }
135  z.set_value(i,0,((y.get_value(i,0) - sum) / L_.get_value(i, i)));
136  }
137  return z;
138 }
139 
140 } // linalg
141 } // mui
142 
143 #endif /* MUI_PRECONDITIONER_ILU_H_ */
incomplete_lu_preconditioner(const sparse_matrix< ITYPE, VTYPE > &)
Definition: preconditioner_ilu.h:55
sparse_matrix< ITYPE, VTYPE > apply(const sparse_matrix< ITYPE, VTYPE > &)
Definition: preconditioner_ilu.h:110
~incomplete_lu_preconditioner()
Definition: preconditioner_ilu.h:102
Definition: matrix.h:61
ITYPE get_rows() const
Definition: matrix_io_info.h:579
void set_value(ITYPE, ITYPE, VTYPE, bool=true)
Definition: matrix_manipulation.h:292
VTYPE get_value(ITYPE, ITYPE) const
Definition: matrix_io_info.h:523
ITYPE get_cols() const
Definition: matrix_io_info.h:585
Definition: comm.h:54
SCALAR sum(vexpr< E, SCALAR, D > const &u)
Definition: point.h:362