MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MueLu_BoundaryDetection.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // MueLu: A package for multigrid based preconditioning
4 //
5 // Copyright 2012 NTESS and the MueLu contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef MUELU_BOUNDARYDETECTION_HPP
11 #define MUELU_BOUNDARYDETECTION_HPP
12 
13 #include <cstddef>
14 #include <type_traits>
15 #include "Kokkos_Core.hpp"
16 #if KOKKOS_VERSION >= 40799
17 #include "KokkosKernels_ArithTraits.hpp"
18 #else
19 #include "Kokkos_ArithTraits.hpp"
20 #endif
21 #include "MueLu_LWGraph_kokkos.hpp"
22 #include "MueLu_Utilities.hpp"
23 #include "Teuchos_RCP.hpp"
24 #include "Xpetra_ConfigDefs.hpp"
25 #include "Xpetra_CrsGraph.hpp"
26 #include "Xpetra_MultiVector.hpp"
27 
28 namespace MueLu::BoundaryDetection {
29 
37 template <class local_matrix_type>
39  private:
40  using scalar_type = typename local_matrix_type::value_type;
41  using local_ordinal_type = typename local_matrix_type::ordinal_type;
42  using memory_space = typename local_matrix_type::memory_space;
43 
44 #if KOKKOS_VERSION >= 40799
45  using ATS = KokkosKernels::ArithTraits<scalar_type>;
46 #else
47  using ATS = Kokkos::ArithTraits<scalar_type>;
48 #endif
49  using magnitudeType = typename ATS::magnitudeType;
50  using boundary_nodes_view = Kokkos::View<bool*, memory_space>;
51 
52  local_matrix_type A;
56 
57  public:
58  PointDirichletFunctor(local_matrix_type& A_, boundary_nodes_view boundaryNodes_, magnitudeType dirichletThreshold_, local_ordinal_type dirichletNonzeroThreshold_)
59  : A(A_)
60  , boundaryNodes(boundaryNodes_)
61  , dirichletThreshold(dirichletThreshold_)
62  , dirichletNonzeroThreshold(dirichletNonzeroThreshold_) {}
63 
64  KOKKOS_FORCEINLINE_FUNCTION
65  void operator()(const local_ordinal_type rlid) const {
66  auto row = A.rowConst(rlid);
67  local_ordinal_type nnz = 0;
68  for (local_ordinal_type k = 0; k < row.length; ++k) {
69  local_ordinal_type clid = row.colidx(k);
70  scalar_type val = row.value(k);
71  if ((rlid != static_cast<local_ordinal_type>(clid)) && (ATS::magnitude(val) > dirichletThreshold)) {
72  ++nnz;
73  if (nnz == dirichletNonzeroThreshold) {
74  return;
75  }
76  }
77  }
78  boundaryNodes(rlid) = true;
79  }
80 };
81 
91 template <class local_matrix_type, bool useGreedyDirichlet>
93  private:
94  using scalar_type = typename local_matrix_type::value_type;
95  using local_ordinal_type = typename local_matrix_type::ordinal_type;
96  using memory_space = typename local_matrix_type::memory_space;
97 
98 #if KOKKOS_VERSION >= 40799
99  using ATS = KokkosKernels::ArithTraits<scalar_type>;
100 #else
101  using ATS = Kokkos::ArithTraits<scalar_type>;
102 #endif
103  using magnitudeType = typename ATS::magnitudeType;
104  using boundary_nodes_view = Kokkos::View<bool*, memory_space>;
105 
106  local_matrix_type A;
111 
112  public:
113  VectorDirichletFunctor(local_matrix_type& A_, local_ordinal_type blockSize_, boundary_nodes_view boundaryNodes_, magnitudeType dirichletThreshold_, local_ordinal_type dirichletNonzeroThreshold_)
114  : A(A_)
115  , blockSize(blockSize_)
116  , boundaryNodes(boundaryNodes_)
117  , dirichletThreshold(dirichletThreshold_)
118  , dirichletNonzeroThreshold(dirichletNonzeroThreshold_) {}
119 
120  KOKKOS_FORCEINLINE_FUNCTION
121  void operator()(const local_ordinal_type rblid) const {
122  for (local_ordinal_type rlid = rblid * blockSize; rlid < (rblid + 1) * blockSize; ++rlid) {
123  auto row = A.rowConst(rlid);
124  local_ordinal_type nnz = 0;
125  bool rowIsDirichlet = true;
126  for (local_ordinal_type k = 0; k < row.length; ++k) {
127  auto clid = row.colidx(k);
128  auto val = row.value(k);
129  if ((rlid != static_cast<local_ordinal_type>(clid)) && (ATS::magnitude(val) > dirichletThreshold)) {
130  ++nnz;
131  if (nnz == dirichletNonzeroThreshold) {
132  rowIsDirichlet = false;
133  break;
134  }
135  }
136  }
137  if constexpr (useGreedyDirichlet) {
138  if (rowIsDirichlet) {
139  boundaryNodes(rblid) = true;
140  return;
141  }
142  } else {
143  if (!rowIsDirichlet) {
144  return;
145  }
146  }
147  }
148  if constexpr (!useGreedyDirichlet)
149  boundaryNodes(rblid) = true;
150  }
151 };
152 
160 template <class local_matrix_type>
162  private:
163  using scalar_type = typename local_matrix_type::value_type;
164  using local_ordinal_type = typename local_matrix_type::ordinal_type;
165  using memory_space = typename local_matrix_type::memory_space;
166 
167 #if KOKKOS_VERSION >= 40799
168  using ATS = KokkosKernels::ArithTraits<scalar_type>;
169 #else
170  using ATS = Kokkos::ArithTraits<scalar_type>;
171 #endif
172  using magnitudeType = typename ATS::magnitudeType;
173 #if KOKKOS_VERSION >= 40799
174  using magATS = KokkosKernels::ArithTraits<magnitudeType>;
175 #else
176  using magATS = Kokkos::ArithTraits<magnitudeType>;
177 #endif
178  using boundary_nodes_view = Kokkos::View<bool*, memory_space>;
179 
180  local_matrix_type A;
183 
184  public:
185  RowSumFunctor(local_matrix_type& A_, boundary_nodes_view boundaryNodes_, magnitudeType rowSumTol_)
186  : A(A_)
187  , boundaryNodes(boundaryNodes_)
188  , rowSumTol(rowSumTol_) {}
189 
190  KOKKOS_FORCEINLINE_FUNCTION
191  void operator()(const local_ordinal_type rlid) const {
192  scalar_type rowsum = ATS::zero();
193  scalar_type diagval = ATS::zero();
194  auto row = A.rowConst(rlid);
195  for (local_ordinal_type k = 0; k < row.length; ++k) {
196  auto clid = row.colidx(k);
197  auto val = row.value(k);
198  if (rlid == static_cast<local_ordinal_type>(clid))
199  diagval = val;
200  rowsum += val;
201  }
202  if (ATS::magnitude(rowsum) > ATS::magnitude(diagval) * rowSumTol) {
203  boundaryNodes(rlid) = true;
204  }
205  }
206 };
207 
212 template <class local_matrix_type, class Functor, class... RemainingFunctors>
214  private:
215  using local_ordinal_type = typename local_matrix_type::ordinal_type;
216 
217  Functor functor;
218  BoundaryFunctor<local_matrix_type, RemainingFunctors...> remainingFunctors;
219 
220  public:
221  BoundaryFunctor(local_matrix_type& A_, Functor& functor_, RemainingFunctors&... remainingFunctors_)
222  : functor(functor_)
223  , remainingFunctors(A_, remainingFunctors_...) {}
224 
225  KOKKOS_FUNCTION void operator()(const local_ordinal_type rlid) const {
226  functor(rlid);
227  remainingFunctors(rlid);
228  }
229 };
230 
231 template <class local_matrix_type, class Functor>
232 class BoundaryFunctor<local_matrix_type, Functor> {
233  private:
234  using local_ordinal_type = typename local_matrix_type::ordinal_type;
235 
236  local_matrix_type A;
237  Functor functor;
238 
239  public:
240  BoundaryFunctor(local_matrix_type& A_, Functor& functor_)
241  : A(A_)
242  , functor(functor_) {}
243 
244  KOKKOS_FUNCTION void operator()(const local_ordinal_type rlid) const {
245  functor(rlid);
246  }
247 };
248 
249 } // namespace MueLu::BoundaryDetection
250 
251 #endif
typename local_matrix_type::value_type scalar_type
typename local_matrix_type::memory_space memory_space
typename local_matrix_type::memory_space memory_space
Kokkos::View< bool *, memory_space > boundary_nodes_view
BoundaryFunctor< local_matrix_type, RemainingFunctors...> remainingFunctors
Kokkos::ArithTraits< magnitudeType > magATS
KOKKOS_FUNCTION void operator()(const local_ordinal_type rlid) const
Kokkos::View< bool *, memory_space > boundary_nodes_view
BoundaryFunctor(local_matrix_type &A_, Functor &functor_, RemainingFunctors &...remainingFunctors_)
KOKKOS_FUNCTION void operator()(const local_ordinal_type rlid) const
typename local_matrix_type::value_type scalar_type
typename local_matrix_type::ordinal_type local_ordinal_type
typename local_matrix_type::memory_space memory_space
VectorDirichletFunctor(local_matrix_type &A_, local_ordinal_type blockSize_, boundary_nodes_view boundaryNodes_, magnitudeType dirichletThreshold_, local_ordinal_type dirichletNonzeroThreshold_)
Functor for marking nodes as Dirichlet.
typename local_matrix_type::value_type scalar_type
KOKKOS_FORCEINLINE_FUNCTION void operator()(const local_ordinal_type rblid) const
Kokkos::ArithTraits< scalar_type > ATS
Functor for marking nodes as Dirichlet based on rowsum.
Functor that serially applies sub-functors to rows.
typename local_matrix_type::ordinal_type local_ordinal_type
Kokkos::View< bool *, memory_space > boundary_nodes_view
Functor for marking nodes as Dirichlet in a block operator.
typename local_matrix_type::ordinal_type local_ordinal_type
typename local_matrix_type::ordinal_type local_ordinal_type
KOKKOS_FORCEINLINE_FUNCTION void operator()(const local_ordinal_type rlid) const
RowSumFunctor(local_matrix_type &A_, boundary_nodes_view boundaryNodes_, magnitudeType rowSumTol_)
PointDirichletFunctor(local_matrix_type &A_, boundary_nodes_view boundaryNodes_, magnitudeType dirichletThreshold_, local_ordinal_type dirichletNonzeroThreshold_)
KOKKOS_FORCEINLINE_FUNCTION void operator()(const local_ordinal_type rlid) const