MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MueLu_DistanceLaplacianDropping.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_DISTANCELAPLACIANDROPPING_HPP
11 #define MUELU_DISTANCELAPLACIANDROPPING_HPP
12 
13 #include "Kokkos_Macros.hpp"
14 #include "KokkosBatched_LU_Decl.hpp"
15 #include "KokkosBatched_LU_Serial_Impl.hpp"
16 #include "KokkosBatched_Trsv_Decl.hpp"
17 #include "KokkosBatched_Trsv_Serial_Impl.hpp"
18 #include "MueLu_DroppingCommon.hpp"
19 #include "Kokkos_Core.hpp"
20 #include "Kokkos_ArithTraits.hpp"
21 #include "Teuchos_RCP.hpp"
22 #include "Xpetra_Matrix.hpp"
23 #include "Xpetra_MultiVector.hpp"
24 #include "Xpetra_MultiVectorFactory.hpp"
25 
26 namespace MueLu::DistanceLaplacian {
27 
32 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
34  private:
36  using local_matrix_type = typename matrix_type::local_matrix_type;
37  using scalar_type = typename local_matrix_type::value_type;
39  using ATS = Kokkos::ArithTraits<scalar_type>;
40  using impl_scalar_type = typename ATS::val_type;
41  using implATS = Kokkos::ArithTraits<impl_scalar_type>;
42  using magnitudeType = typename implATS::magnitudeType;
43  using magATS = Kokkos::ArithTraits<magnitudeType>;
45  using local_coords_type = typename coords_type::dual_view_type_const::t_dev;
46 
49 
52 
53  public:
55  coordsMV = coords_;
56  auto importer = A.getCrsGraph()->getImporter();
57  if (!importer.is_null()) {
59  ghostedCoordsMV->doImport(*coordsMV, *importer, Xpetra::INSERT);
60  coords = coordsMV->getLocalViewDevice(Xpetra::Access::ReadOnly);
61  ghostedCoords = ghostedCoordsMV->getLocalViewDevice(Xpetra::Access::ReadOnly);
62  } else {
63  coords = coordsMV->getLocalViewDevice(Xpetra::Access::ReadOnly);
65  }
66  }
67 
68  KOKKOS_FORCEINLINE_FUNCTION
70  magnitudeType d = magATS::zero();
71  magnitudeType s;
72  for (size_t j = 0; j < coords.extent(1); ++j) {
73  s = coords(row, j) - ghostedCoords(col, j);
74  d += s * s;
75  }
76  return d;
77  }
78 };
79 
80 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
82  private:
84  using local_matrix_type = typename matrix_type::local_matrix_type;
85  using scalar_type = typename local_matrix_type::value_type;
87  using ATS = Kokkos::ArithTraits<scalar_type>;
88  using impl_scalar_type = typename ATS::val_type;
89  using implATS = Kokkos::ArithTraits<impl_scalar_type>;
90  using magnitudeType = typename implATS::magnitudeType;
91  using magATS = Kokkos::ArithTraits<magnitudeType>;
93  using local_coords_type = typename coords_type::dual_view_type_const::t_dev;
95  using local_material_type = typename material_type::dual_view_type_const::t_dev;
96 
99 
102 
105 
108 
109  public:
111  coordsMV = coords_;
112  materialMV = material_;
113  auto importer = A.getCrsGraph()->getImporter();
114  if (!importer.is_null()) {
116  ghostedCoordsMV->doImport(*coordsMV, *importer, Xpetra::INSERT);
117  coords = coordsMV->getLocalViewDevice(Xpetra::Access::ReadOnly);
118  ghostedCoords = ghostedCoordsMV->getLocalViewDevice(Xpetra::Access::ReadOnly);
119 
121  ghostedMaterialMV->doImport(*materialMV, *importer, Xpetra::INSERT);
122  material = materialMV->getLocalViewDevice(Xpetra::Access::ReadOnly);
123  ghostedMaterial = ghostedMaterialMV->getLocalViewDevice(Xpetra::Access::ReadOnly);
124  } else {
125  coords = coordsMV->getLocalViewDevice(Xpetra::Access::ReadOnly);
127 
128  material = materialMV->getLocalViewDevice(Xpetra::Access::ReadOnly);
130  }
131  }
132 
133  KOKKOS_INLINE_FUNCTION
135  // || x_row - x_col ||_S^2
136  // where
137  // S = 1/material(row) * Identity
138  magnitudeType d = magATS::zero();
139  magnitudeType d_row = magATS::zero();
140  magnitudeType d_col = magATS::zero();
141  magnitudeType s;
142 
143  for (size_t j = 0; j < coords.extent(1); ++j) {
144  s = coords(row, j) - ghostedCoords(col, j);
145  d += s * s;
146  }
147 
148  d_row = d / implATS::magnitude(ghostedMaterial(row, 0));
149  d_col = d / implATS::magnitude(ghostedMaterial(col, 0));
150 
151  return Kokkos::max(d_row, d_col);
152  }
153 };
154 
155 template <class local_ordinal_type, class material_vector_type, class material_matrix_type>
157  private:
158  material_vector_type material_vector;
159  material_matrix_type material_matrix;
160 
161  public:
162  TensorInversion(material_vector_type& material_vector_, material_matrix_type& material_matrix_)
163  : material_vector(material_vector_)
164  , material_matrix(material_matrix_) {}
165 
166  KOKKOS_FORCEINLINE_FUNCTION
167  void operator()(local_ordinal_type i) const {
168  for (size_t j = 0; j < material_matrix.extent(1); ++j) {
169  for (size_t k = 0; k < material_matrix.extent(2); ++k) {
170  material_matrix(i, j, k) = material_vector(i, j * material_matrix.extent(1) + k);
171  }
172  }
173  auto matrix_material = Kokkos::subview(material_matrix, i, Kokkos::ALL(), Kokkos::ALL());
174  KokkosBatched::SerialLU<KokkosBatched::Algo::LU::Unblocked>::invoke(matrix_material);
175  }
176 };
177 
178 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
180  private:
182  using local_matrix_type = typename matrix_type::local_matrix_type;
183  using scalar_type = typename local_matrix_type::value_type;
185  using ATS = Kokkos::ArithTraits<scalar_type>;
186  using impl_scalar_type = typename ATS::val_type;
187  using implATS = Kokkos::ArithTraits<impl_scalar_type>;
188  using magnitudeType = typename implATS::magnitudeType;
189  using magATS = Kokkos::ArithTraits<magnitudeType>;
191  using local_coords_type = typename coords_type::dual_view_type_const::t_dev;
193  using memory_space = typename local_matrix_type::memory_space;
194 
195  using local_material_type = Kokkos::View<impl_scalar_type***, memory_space>;
196  using local_dist_type = Kokkos::View<impl_scalar_type**, memory_space>;
197 
200 
203 
205 
207 
208  const scalar_type one = ATS::one();
209 
210  public:
212  coordsMV = coords_;
213 
214  auto importer = A.getCrsGraph()->getImporter();
215  if (!importer.is_null()) {
217  ghostedCoordsMV->doImport(*coordsMV, *importer, Xpetra::INSERT);
218  coords = coordsMV->getLocalViewDevice(Xpetra::Access::ReadOnly);
219  ghostedCoords = ghostedCoordsMV->getLocalViewDevice(Xpetra::Access::ReadOnly);
220  } else {
221  coords = coordsMV->getLocalViewDevice(Xpetra::Access::ReadOnly);
223  }
224 
225  {
226  Teuchos::RCP<material_type> ghostedMaterial;
227  if (!importer.is_null()) {
228  ghostedMaterial = Xpetra::MultiVectorFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(importer->getTargetMap(), material_->getNumVectors());
229  ghostedMaterial->doImport(*material_, *importer, Xpetra::INSERT);
230  } else {
231  ghostedMaterial = material_;
232  }
233 
234  using execution_space = typename Node::execution_space;
235  using range_type = Kokkos::RangePolicy<LocalOrdinal, execution_space>;
236 
237  local_ordinal_type dim = std::sqrt(material_->getNumVectors());
238  auto lclMaterial = ghostedMaterial->getLocalViewDevice(Xpetra::Access::ReadOnly);
239  material = local_material_type("material", lclMaterial.extent(0), dim, dim);
240  lcl_dist = local_dist_type("material", lclMaterial.extent(0), dim);
242  Kokkos::parallel_for("MueLu:TensorMaterialDistanceFunctor::inversion", range_type(0, lclMaterial.extent(0)), functor);
243  }
244  }
245 
246  KOKKOS_INLINE_FUNCTION
248  // || x_row - x_col ||_S^2
249  // where
250  // S = inv(material(col))
251 
252  // row material
253  impl_scalar_type d_row = implATS::zero();
254  {
255  auto matrix_row_material = Kokkos::subview(material, row, Kokkos::ALL(), Kokkos::ALL());
256  auto dist = Kokkos::subview(lcl_dist, row, Kokkos::ALL());
257 
258  for (size_t j = 0; j < coords.extent(1); ++j) {
259  dist(j) = coords(row, j) - ghostedCoords(col, j);
260  }
261 
262  KokkosBatched::SerialTrsv<KokkosBatched::Uplo::Lower, KokkosBatched::Trans::NoTranspose, KokkosBatched::Diag::Unit, KokkosBatched::Algo::Trsv::Unblocked>::invoke(one, matrix_row_material, dist);
263  KokkosBatched::SerialTrsv<KokkosBatched::Uplo::Upper, KokkosBatched::Trans::NoTranspose, KokkosBatched::Diag::NonUnit, KokkosBatched::Algo::Trsv::Unblocked>::invoke(one, matrix_row_material, dist);
264 
265  for (size_t j = 0; j < coords.extent(1); ++j) {
266  d_row += dist(j) * (coords(row, j) - ghostedCoords(col, j));
267  }
268  }
269 
270  // column material
271  impl_scalar_type d_col = implATS::zero();
272  {
273  auto matrix_col_material = Kokkos::subview(material, col, Kokkos::ALL(), Kokkos::ALL());
274  auto dist = Kokkos::subview(lcl_dist, row, Kokkos::ALL());
275 
276  for (size_t j = 0; j < coords.extent(1); ++j) {
277  dist(j) = coords(row, j) - ghostedCoords(col, j);
278  }
279 
280  KokkosBatched::SerialTrsv<KokkosBatched::Uplo::Lower, KokkosBatched::Trans::NoTranspose, KokkosBatched::Diag::Unit, KokkosBatched::Algo::Trsv::Unblocked>::invoke(one, matrix_col_material, dist);
281  KokkosBatched::SerialTrsv<KokkosBatched::Uplo::Upper, KokkosBatched::Trans::NoTranspose, KokkosBatched::Diag::NonUnit, KokkosBatched::Algo::Trsv::Unblocked>::invoke(one, matrix_col_material, dist);
282 
283  for (size_t j = 0; j < coords.extent(1); ++j) {
284  d_col += dist(j) * (coords(row, j) - ghostedCoords(col, j));
285  }
286  }
287 
288  return Kokkos::max(implATS::magnitude(d_row), implATS::magnitude(d_col));
289  }
290 };
291 
295 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node, class DistanceFunctorType>
298  DistanceFunctorType& distFunctor) {
299  using scalar_type = Scalar;
300  using local_ordinal_type = LocalOrdinal;
301  using global_ordinal_type = GlobalOrdinal;
302  using node_type = Node;
303  using ATS = Kokkos::ArithTraits<scalar_type>;
304  using impl_scalar_type = typename ATS::val_type;
305  using implATS = Kokkos::ArithTraits<impl_scalar_type>;
306  using magnitudeType = typename implATS::magnitudeType;
307  using execution_space = typename Node::execution_space;
308  using range_type = Kokkos::RangePolicy<LocalOrdinal, execution_space>;
309 
311  {
312  auto lclA = A.getLocalMatrixDevice();
313  auto lclDiag = diag->getLocalViewDevice(Xpetra::Access::OverwriteAll);
314 
315  Kokkos::parallel_for(
316  "MueLu:CoalesceDropF:Build:scalar_filter:laplacian_diag",
317  range_type(0, lclA.numRows()),
318  KOKKOS_LAMBDA(const local_ordinal_type& row) {
319  auto rowView = lclA.rowConst(row);
320  auto length = rowView.length;
321 
322  magnitudeType d;
323  impl_scalar_type d2 = implATS::zero();
324  bool haveAddedToDiag = false;
325  for (local_ordinal_type colID = 0; colID < length; colID++) {
326  auto col = rowView.colidx(colID);
327  if (row != col) {
328  d = distFunctor.distance2(row, col);
329  d2 += implATS::one() / d;
330  haveAddedToDiag = true;
331  }
332  }
333 
334  // Deal with the situation where boundary conditions have only been enforced on rows, but not on columns.
335  // We enforce dropping of these entries by assigning a very large number to the diagonal entries corresponding to BCs.
336  lclDiag(row, 0) = !haveAddedToDiag ? implATS::squareroot(implATS::rmax()) : d2;
337  });
338  }
339  auto importer = A.getCrsGraph()->getImporter();
340  if (!importer.is_null()) {
342  ghostedDiag->doImport(*diag, *importer, Xpetra::INSERT);
343  return ghostedDiag;
344  } else {
345  return diag;
346  }
347 }
348 
349 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node, class DistanceFunctorType>
352  DistanceFunctorType& distFunctor) {
353  using scalar_type = Scalar;
354  using local_ordinal_type = LocalOrdinal;
355  using global_ordinal_type = GlobalOrdinal;
356  using node_type = Node;
357  using ATS = Kokkos::ArithTraits<scalar_type>;
358  using impl_scalar_type = typename ATS::val_type;
359  using implATS = Kokkos::ArithTraits<impl_scalar_type>;
360  using magnitudeType = typename implATS::magnitudeType;
361  using execution_space = typename Node::execution_space;
362  using range_type = Kokkos::RangePolicy<LocalOrdinal, execution_space>;
363  using mATS = Kokkos::ArithTraits<magnitudeType>;
364 
366  {
367  auto lclA = A.getLocalMatrixDevice();
368  auto lclDiag = diag->getLocalViewDevice(Xpetra::Access::OverwriteAll);
369 
370  Kokkos::parallel_for(
371  "MueLu:CoalesceDropF:Build:scalar_filter:laplacian_diag",
372  range_type(0, lclA.numRows()),
373  KOKKOS_LAMBDA(const local_ordinal_type& row) {
374  auto rowView = lclA.rowConst(row);
375  auto length = rowView.length;
376 
377  impl_scalar_type mymax = implATS::zero();
378  magnitudeType d;
379  impl_scalar_type d2;
380  for (local_ordinal_type colID = 0; colID < length; colID++) {
381  auto col = rowView.colidx(colID);
382  if (row != col) {
383  d = distFunctor.distance2(row, col);
384  d2 = implATS::one() / d;
385  if (implATS::magnitude(mymax) < -implATS::magnitude(d2))
386  mymax = -implATS::magnitude(d2);
387  }
388  }
389  lclDiag(row, 0) = mymax;
390  });
391  }
392  auto importer = A.getCrsGraph()->getImporter();
393  if (!importer.is_null()) {
395  ghostedDiag->doImport(*diag, *importer, Xpetra::INSERT);
396  return ghostedDiag;
397  } else {
398  return diag;
399  }
400 }
401 
412 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node, class DistanceFunctorType, Misc::StrengthMeasure measure>
413 class DropFunctor {
414  public:
416  using local_matrix_type = typename matrix_type::local_matrix_type;
417  using scalar_type = typename local_matrix_type::value_type;
418  using local_ordinal_type = typename local_matrix_type::ordinal_type;
419  using memory_space = typename local_matrix_type::memory_space;
421  using diag_view_type = typename Kokkos::DualView<const scalar_type*, Kokkos::LayoutStride, typename Node::device_type, Kokkos::MemoryUnmanaged>::t_dev;
422 
423  using results_view = Kokkos::View<DecisionType*, memory_space>;
424 
425  using ATS = Kokkos::ArithTraits<scalar_type>;
426  using magnitudeType = typename ATS::magnitudeType;
427  using boundary_nodes_view = Kokkos::View<const bool*, memory_space>;
428  using mATS = Kokkos::ArithTraits<magnitudeType>;
429 
430  private:
434  diag_view_type diag; // corresponds to overlapped diagonal
435  DistanceFunctorType dist2;
437  const scalar_type one = ATS::one();
438 
439  public:
440  DropFunctor(matrix_type& A_, magnitudeType threshold, DistanceFunctorType& dist2_, results_view& results_)
441  : A(A_.getLocalMatrixDevice())
442  , eps(threshold)
443  , dist2(dist2_)
444  , results(results_) {
445  if constexpr ((measure == Misc::SmoothedAggregationMeasure) || (measure == Misc::SignedSmoothedAggregationMeasure)) {
446  diagVec = getDiagonal(A_, dist2);
447  auto lclDiag2d = diagVec->getLocalViewDevice(Xpetra::Access::ReadOnly);
448  diag = Kokkos::subview(lclDiag2d, Kokkos::ALL(), 0);
449  } else if constexpr (measure == Misc::SignedRugeStuebenMeasure) {
451  auto lclDiag2d = diagVec->getLocalViewDevice(Xpetra::Access::ReadOnly);
452  diag = Kokkos::subview(lclDiag2d, Kokkos::ALL(), 0);
453  }
454  }
455 
456  KOKKOS_FORCEINLINE_FUNCTION
457  void operator()(local_ordinal_type rlid) const {
458  auto row = A.rowConst(rlid);
459  const size_t offset = A.graph.row_map(rlid);
460  for (local_ordinal_type k = 0; k < row.length; ++k) {
461  auto clid = row.colidx(k);
462 
463  scalar_type val;
464  if (rlid != clid) {
465  val = one / dist2.distance2(rlid, clid);
466  } else {
467  val = diag(rlid);
468  }
469 
470  if constexpr (measure == Misc::SmoothedAggregationMeasure) {
471  auto aiiajj = ATS::magnitude(diag(rlid)) * ATS::magnitude(diag(clid)); // |a_ii|*|a_jj|
472  auto aij2 = ATS::magnitude(val) * ATS::magnitude(val); // |a_ij|^2
473 
474  results(offset + k) = Kokkos::max((aij2 <= eps * eps * aiiajj) ? DROP : KEEP,
475  results(offset + k));
476  } else if constexpr (measure == Misc::SignedRugeStuebenMeasure) {
477  auto neg_aij = -ATS::real(val);
478  auto max_neg_aik = eps * ATS::real(diag(rlid));
479  results(offset + k) = Kokkos::max((neg_aij <= max_neg_aik) ? DROP : KEEP,
480  results(offset + k));
481  } else if constexpr (measure == Misc::SignedSmoothedAggregationMeasure) {
482  auto aiiajj = ATS::magnitude(diag(rlid)) * ATS::magnitude(diag(clid)); // |a_ii|*|a_jj|
483  const bool is_nonpositive = ATS::real(val) <= mATS::zero();
484  magnitudeType aij2 = ATS::magnitude(val) * ATS::magnitude(val); // |a_ij|^2
485  // + |a_ij|^2, if a_ij < 0, - |a_ij|^2 if a_ij >=0
486  if (is_nonpositive)
487  aij2 = -aij2;
488  results(offset + k) = Kokkos::max((aij2 <= eps * eps * aiiajj) ? DROP : KEEP,
489  results(offset + k));
490  }
491  }
492  }
493 };
494 
495 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node, class DistanceFunctorType, Misc::StrengthMeasure measure>
497  public:
499  using local_matrix_type = typename matrix_type::local_matrix_type;
500  using scalar_type = typename local_matrix_type::value_type;
501  using local_ordinal_type = typename local_matrix_type::ordinal_type;
502  using memory_space = typename local_matrix_type::memory_space;
503  using block_indices_view_type = Kokkos::View<local_ordinal_type*, memory_space>;
505  using diag_view_type = typename Kokkos::DualView<const scalar_type*, Kokkos::LayoutStride, typename Node::device_type, Kokkos::MemoryUnmanaged>::t_dev;
506 
507  using results_view = Kokkos::View<DecisionType*, memory_space>;
508 
509  using ATS = Kokkos::ArithTraits<scalar_type>;
510  using magnitudeType = typename ATS::magnitudeType;
511  using boundary_nodes_view = Kokkos::View<const bool*, memory_space>;
512  using mATS = Kokkos::ArithTraits<magnitudeType>;
513 
514  private:
518  diag_view_type diag; // corresponds to overlapped diagonal
519  DistanceFunctorType dist2;
523  const scalar_type one = ATS::one();
524 
525  public:
526  VectorDropFunctor(matrix_type& A_, matrix_type& mergedA_, magnitudeType threshold, DistanceFunctorType& dist2_, results_view& results_, block_indices_view_type point_to_block_, block_indices_view_type ghosted_point_to_block_)
527  : A(A_.getLocalMatrixDevice())
528  , eps(threshold)
529  , dist2(dist2_)
530  , results(results_)
531  , point_to_block(point_to_block_)
532  , ghosted_point_to_block(ghosted_point_to_block_) {
533  if constexpr ((measure == Misc::SmoothedAggregationMeasure) || (measure == Misc::SignedSmoothedAggregationMeasure)) {
534  diagVec = getDiagonal(mergedA_, dist2);
535  auto lclDiag2d = diagVec->getLocalViewDevice(Xpetra::Access::ReadOnly);
536  diag = Kokkos::subview(lclDiag2d, Kokkos::ALL(), 0);
537  } else if (measure == Misc::SignedRugeStuebenMeasure) {
539  auto lclDiag2d = diagVec->getLocalViewDevice(Xpetra::Access::ReadOnly);
540  diag = Kokkos::subview(lclDiag2d, Kokkos::ALL(), 0);
541  }
542  }
543 
544  KOKKOS_FORCEINLINE_FUNCTION
545  void operator()(local_ordinal_type rlid) const {
546  auto brlid = point_to_block(rlid);
547  auto row = A.rowConst(rlid);
548  const size_t offset = A.graph.row_map(rlid);
549  for (local_ordinal_type k = 0; k < row.length; ++k) {
550  auto clid = row.colidx(k);
551  auto bclid = ghosted_point_to_block(clid);
552 
553  scalar_type val;
554  if (brlid != bclid) {
555  val = one / dist2.distance2(brlid, bclid);
556  } else {
557  val = diag(brlid);
558  }
559 
560  if constexpr (measure == Misc::SmoothedAggregationMeasure) {
561  auto aiiajj = ATS::magnitude(diag(brlid)) * ATS::magnitude(diag(bclid)); // |a_ii|*|a_jj|
562  auto aij2 = ATS::magnitude(val) * ATS::magnitude(val); // |a_ij|^2
563 
564  results(offset + k) = Kokkos::max((aij2 <= eps * eps * aiiajj) ? DROP : KEEP,
565  results(offset + k));
566  } else if constexpr (measure == Misc::SignedRugeStuebenMeasure) {
567  auto neg_aij = -ATS::real(val);
568  auto max_neg_aik = eps * ATS::real(diag(brlid));
569  results(offset + k) = Kokkos::max((neg_aij <= max_neg_aik) ? DROP : KEEP,
570  results(offset + k));
571  } else if constexpr (measure == Misc::SignedSmoothedAggregationMeasure) {
572  auto aiiajj = ATS::magnitude(diag(brlid)) * ATS::magnitude(diag(bclid)); // |a_ii|*|a_jj|
573  const bool is_nonpositive = ATS::real(val) <= mATS::zero();
574  magnitudeType aij2 = ATS::magnitude(val) * ATS::magnitude(val); // |a_ij|^2
575  // + |a_ij|^2, if a_ij < 0, - |a_ij|^2 if a_ij >=0
576  if (is_nonpositive)
577  aij2 = -aij2;
578  results(offset + k) = Kokkos::max((aij2 <= eps * eps * aiiajj) ? DROP : KEEP,
579  results(offset + k));
580  }
581  }
582  }
583 };
584 
585 // helper function to allow partial template deduction
586 template <Misc::StrengthMeasure measure, class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node, class DistanceFunctorType>
589  DistanceFunctorType& dist2_,
591  auto functor = DropFunctor<Scalar, LocalOrdinal, GlobalOrdinal, Node, DistanceFunctorType, measure>(A_, threshold, dist2_, results_);
592  return functor;
593 }
594 
595 template <Misc::StrengthMeasure measure, class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node, class DistanceFunctorType>
599  DistanceFunctorType& dist2_,
603  auto functor = VectorDropFunctor<Scalar, LocalOrdinal, GlobalOrdinal, Node, DistanceFunctorType, measure>(A_, mergedA_, threshold, dist2_, results_, point_to_block_, ghosted_point_to_block_);
604  return functor;
605 }
606 
607 } // namespace MueLu::DistanceLaplacian
608 
609 #endif
Drops entries the unscaled distance Laplacian.
typename material_type::dual_view_type_const::t_dev local_material_type
MueLu::DefaultLocalOrdinal LocalOrdinal
UnweightedDistanceFunctor(matrix_type &A, Teuchos::RCP< coords_type > &coords_)
Kokkos::View< local_ordinal_type *, memory_space > block_indices_view_type
static Teuchos::RCP< MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > Build(const Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node >> &map, size_t NumVectors, bool zeroOut=true)
typename coords_type::dual_view_type_const::t_dev local_coords_type
typename local_matrix_type::memory_space memory_space
typename Kokkos::DualView< const scalar_type *, Kokkos::LayoutStride, typename Node::device_type, Kokkos::MemoryUnmanaged >::t_dev diag_view_type
typename coords_type::dual_view_type_const::t_dev local_coords_type
KOKKOS_INLINE_FUNCTION magnitudeType distance2(const local_ordinal_type row, const local_ordinal_type col) const
KOKKOS_INLINE_FUNCTION magnitudeType distance2(const local_ordinal_type row, const local_ordinal_type col) const
Teuchos::RCP< Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > getMaxMinusOffDiagonal(Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A, DistanceFunctorType &distFunctor)
Kokkos::View< DecisionType *, memory_space > results_view
MueLu::DefaultNode Node
typename local_matrix_type::ordinal_type local_ordinal_type
Kokkos::View< const bool *, memory_space > boundary_nodes_view
DropFunctor(matrix_type &A_, magnitudeType threshold, DistanceFunctorType &dist2_, results_view &results_)
virtual void doImport(const DistObject< Scalar, LocalOrdinal, GlobalOrdinal, Node > &source, const Import< LocalOrdinal, GlobalOrdinal, Node > &importer, CombineMode CM)=0
TensorMaterialDistanceFunctor(matrix_type &A, Teuchos::RCP< coords_type > &coords_, Teuchos::RCP< material_type > &material_)
KOKKOS_FORCEINLINE_FUNCTION void operator()(local_ordinal_type rlid) const
Kokkos::View< DecisionType *, memory_space > results_view
MueLu::DefaultScalar Scalar
MueLu::DefaultGlobalOrdinal GlobalOrdinal
TensorInversion(material_vector_type &material_vector_, material_matrix_type &material_matrix_)
typename local_matrix_type::value_type scalar_type
typename Kokkos::DualView< const scalar_type *, Kokkos::LayoutStride, typename Node::device_type, Kokkos::MemoryUnmanaged >::t_dev diag_view_type
typename matrix_type::local_matrix_type local_matrix_type
typename coords_type::dual_view_type_const::t_dev local_coords_type
auto make_drop_functor(Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A_, typename DropFunctor< Scalar, LocalOrdinal, GlobalOrdinal, Node, DistanceFunctorType, measure >::magnitudeType threshold, DistanceFunctorType &dist2_, typename DropFunctor< Scalar, LocalOrdinal, GlobalOrdinal, Node, DistanceFunctorType, measure >::results_view &results_)
ScalarMaterialDistanceFunctor(matrix_type &A, Teuchos::RCP< coords_type > &coords_, Teuchos::RCP< material_type > &material_)
Kokkos::View< const bool *, memory_space > boundary_nodes_view
KOKKOS_FORCEINLINE_FUNCTION magnitudeType distance2(const local_ordinal_type row, const local_ordinal_type col) const
Kokkos::View< impl_scalar_type **, memory_space > local_dist_type
virtual RCP< const CrsGraph > getCrsGraph() const =0
KOKKOS_FORCEINLINE_FUNCTION void operator()(local_ordinal_type rlid) const
VectorDropFunctor(matrix_type &A_, matrix_type &mergedA_, magnitudeType threshold, DistanceFunctorType &dist2_, results_view &results_, block_indices_view_type point_to_block_, block_indices_view_type ghosted_point_to_block_)
typename local_matrix_type::ordinal_type local_ordinal_type
KOKKOS_FORCEINLINE_FUNCTION void operator()(local_ordinal_type i) const
Teuchos::RCP< Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > getDiagonal(Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A, DistanceFunctorType &distFunctor)
Kokkos::View< impl_scalar_type ***, memory_space > local_material_type
virtual size_t getNumVectors() const =0
typename local_matrix_type::memory_space memory_space
auto make_vector_drop_functor(Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A_, Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &mergedA_, typename VectorDropFunctor< Scalar, LocalOrdinal, GlobalOrdinal, Node, DistanceFunctorType, measure >::magnitudeType threshold, DistanceFunctorType &dist2_, typename VectorDropFunctor< Scalar, LocalOrdinal, GlobalOrdinal, Node, DistanceFunctorType, measure >::results_view &results_, typename VectorDropFunctor< Scalar, LocalOrdinal, GlobalOrdinal, Node, DistanceFunctorType, measure >::block_indices_view_type point_to_block_, typename VectorDropFunctor< Scalar, LocalOrdinal, GlobalOrdinal, Node, DistanceFunctorType, measure >::block_indices_view_type ghosted_point_to_block_)
typename matrix_type::local_matrix_type local_matrix_type