Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
block_lu.h
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Stokhos Package
4 //
5 // Copyright 2009 NTESS and the Stokhos contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 /*
11  * Copyright 2008-2009 NVIDIA Corporation
12  *
13  * Licensed under the Apache License, Version 2.0 (the "License");
14  * you may not use this file except in compliance with the License.
15  * You may obtain a copy of the License at
16  *
17  * http://www.apache.org/licenses/LICENSE-2.0
18  *
19  * Unless required by applicable law or agreed to in writing, software
20  * distributed under the License is distributed on an "AS IS" BASIS,
21  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22  * See the License for the specific language governing permissions and
23  * limitations under the License.
24  */
25 
26 #pragma once
27 
28 #include <cusp/array1d.h>
29 #include <cusp/array2d.h>
30 #include <cusp/linear_operator.h>
31 
32 #include <cmath>
33 
34 namespace cusp
35 {
36 namespace detail
37 {
38 
39 template <typename IndexType, typename ValueType, typename MemorySpace, typename OrientationA>
40 int block_lu_factor(cusp::array2d<ValueType,MemorySpace,OrientationA>& A,
41  cusp::array1d<IndexType,MemorySpace>& pivot)
42 {
43  const int n = A.num_rows;
44 
45  // For each row and column, k = 0, ..., n-1,
46  for (int k = 0; k < n; k++)
47  {
48  // find the pivot row
49  pivot[k] = k;
50  ValueType max = std::fabs(A(k,k));
51 
52  for (int j = k + 1; j < n; j++)
53  {
54  if (max < std::fabs(A(j,k)))
55  {
56  max = std::fabs(A(j,k));
57  pivot[k] = j;
58  }
59  }
60 
61  // and if the pivot row differs from the current row, then
62  // interchange the two rows.
63  if (pivot[k] != k)
64  for (int j = 0; j < n; j++)
65  std::swap(A(k,j), A(pivot[k],j));
66 
67  // and if the matrix is singular, return error
68  if (A(k,k) == 0.0)
69  return -1;
70 
71  // otherwise find the lower triangular matrix elements for column k.
72  for (int i = k + 1; i < n; i++)
73  A(i,k) /= A(k,k);
74 
75  // update remaining matrix
76  for (int i = k + 1; i < n; i++)
77  for (int j = k + 1; j < n; j++)
78  A(i,j) -= A(i,k) * A(k,j);
79  }
80  return 0;
81 }
82 
83 
84 //LU solve for multiple right hand sides
85 template <typename IndexType, typename ValueType, typename MemorySpace,
86  typename OrientationA, typename OrientationB>
87 int block_lu_solve(const cusp::array2d<ValueType,MemorySpace,OrientationA>& A,
88  const cusp::array1d<IndexType,MemorySpace>& pivot,
89  const cusp::array2d<ValueType,MemorySpace,OrientationB>& b,
90  cusp::array2d<ValueType,MemorySpace,OrientationB>& x,
91  cusp::array2d_format)
92 {
93  const int n = A.num_rows;
94  const int numRHS = b.num_cols;
95  // copy rhs to x
96  x = b;
97  // Solve the linear equation Lx = b for x, where L is a lower triangular matrix
98 
99  for (int k = 0; k < n; k++)
100  {
101  if (pivot[k] != k){//swap row k of x with row pivot[k]
102  for (int j = 0; j < numRHS; j++)
103  std::swap(x(k,j),x(pivot[k],j));
104  }
105 
106  for (int i = 0; i < k; i++){
107  for (int j = 0; j< numRHS; j++)
108  x(k,j) -= A(k,i) * x(i,j);
109  }
110  }
111 
112  // Solve the linear equation Ux = y, where y is the solution
113  // obtained above of Lx = b and U is an upper triangular matrix.
114  for (int k = n - 1; k >= 0; k--)
115  {
116  for (int j = 0; j< numRHS; j++){
117  for (int i = k + 1; i < n; i++){
118  x(k, j) -= A(k,i) * x(i, j);
119  }
120  if (A(k,k) == 0)
121  return -1;
122  x(k,j) /= A(k,k);
123  }
124 
125  }
126  return 0;
127 }
128 
129 
130 
131 
132 template <typename ValueType, typename MemorySpace>
133 class block_lu_solver : public cusp::linear_operator<ValueType,MemorySpace>
134 {
135  cusp::array2d<ValueType,cusp::host_memory> lu;
136  cusp::array1d<int,cusp::host_memory> pivot;
137 
138 public:
139  block_lu_solver() : linear_operator<ValueType,MemorySpace>() {}
140 
141  template <typename MatrixType>
142  block_lu_solver(const MatrixType& A) :
143  linear_operator<ValueType,MemorySpace>(A.num_rows, A.num_cols, A.num_entries)
144  {
145  CUSP_PROFILE_SCOPED();
146 
147  lu = A;
148  pivot.resize(A.num_rows);
150  }
151 
152  template <typename VectorType1, typename VectorType2>
153  void operator()(const VectorType1& b, VectorType2& x) const
154  {
155  CUSP_PROFILE_SCOPED();
156  block_lu_solve(lu, pivot, b, x, typename VectorType2::format());
157  }
158 };
159 
160 } // end namespace detail
161 } // end namespace cusp
KOKKOS_INLINE_FUNCTION PCE< Storage > fabs(const PCE< Storage > &a)
int block_lu_solve(const cusp::array2d< ValueType, MemorySpace, OrientationA > &A, const cusp::array1d< IndexType, MemorySpace > &pivot, const cusp::array2d< ValueType, MemorySpace, OrientationB > &b, cusp::array2d< ValueType, MemorySpace, OrientationB > &x, cusp::array2d_format)
Definition: block_lu.h:87
int block_lu_factor(cusp::array2d< ValueType, MemorySpace, OrientationA > &A, cusp::array1d< IndexType, MemorySpace > &pivot)
Definition: block_lu.h:40
cusp::array2d< ValueType, cusp::host_memory > lu
Definition: block_lu.h:135
KOKKOS_INLINE_FUNCTION PCE< Storage > max(const typename PCE< Storage >::value_type &a, const PCE< Storage > &b)
void operator()(const VectorType1 &b, VectorType2 &x) const
Definition: block_lu.h:153
block_lu_solver(const MatrixType &A)
Definition: block_lu.h:142
cusp::array1d< int, cusp::host_memory > pivot
Definition: block_lu.h:136
int n