MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MueLu_AggregateQualityEstimateFactory_def.hpp
Go to the documentation of this file.
1 // @HEADER
2 //
3 // ***********************************************************************
4 //
5 // MueLu: A package for multigrid based preconditioning
6 // Copyright 2012 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact
39 // Jonathan Hu (jhu@sandia.gov)
40 // Andrey Prokopenko (aprokop@sandia.gov)
41 // Ray Tuminaro (rstumin@sandia.gov)
42 //
43 // ***********************************************************************
44 //
45 // @HEADER
46 #ifndef MUELU_AGGREGATEQUALITYESTIMATEFACTORY_DEF_HPP
47 #define MUELU_AGGREGATEQUALITYESTIMATEFACTORY_DEF_HPP
48 #include <iomanip>
50 
51 #include "MueLu_Level.hpp"
52 
54 #include <Teuchos_LAPACK.hpp>
55 
57 #include <Xpetra_IO.hpp>
58 #include "MueLu_MasterList.hpp"
59 #include "MueLu_Monitor.hpp"
60 #include "MueLu_Utilities.hpp"
61 
62 #include <vector>
63 
64 namespace MueLu {
65 
66 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
68 
69 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
71 
72 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
74  Input(currentLevel, "A");
75  Input(currentLevel, "Aggregates");
76  Input(currentLevel, "CoarseMap");
77 }
78 
79 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
81  RCP<ParameterList> validParamList = rcp(new ParameterList());
82 
83 #define SET_VALID_ENTRY(name) validParamList->setEntry(name, MasterList::getEntry(name))
84  SET_VALID_ENTRY("aggregate qualities: good aggregate threshold");
85  SET_VALID_ENTRY("aggregate qualities: file output");
86  SET_VALID_ENTRY("aggregate qualities: file base");
87  SET_VALID_ENTRY("aggregate qualities: check symmetry");
88  SET_VALID_ENTRY("aggregate qualities: algorithm");
89  SET_VALID_ENTRY("aggregate qualities: zero threshold");
90  SET_VALID_ENTRY("aggregate qualities: percentiles");
91  SET_VALID_ENTRY("aggregate qualities: mode");
92 
93 #undef SET_VALID_ENTRY
94 
95  validParamList->set<RCP<const FactoryBase>>("A", Teuchos::null, "Generating factory of the matrix A");
96  validParamList->set<RCP<const FactoryBase>>("Aggregates", Teuchos::null, "Generating factory of the aggregates");
97  validParamList->set<RCP<const FactoryBase>>("CoarseMap", Teuchos::null, "Generating factory of the coarse map");
98 
99  return validParamList;
100 }
101 
102 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
104  FactoryMonitor m(*this, "Build", currentLevel);
105 
106  RCP<Matrix> A = Get<RCP<Matrix>>(currentLevel, "A");
107  RCP<Aggregates> aggregates = Get<RCP<Aggregates>>(currentLevel, "Aggregates");
108 
109  RCP<const Map> map = Get<RCP<const Map>>(currentLevel, "CoarseMap");
110 
111  assert(!aggregates->AggregatesCrossProcessors());
112  ParameterList pL = GetParameterList();
113  std::string mode = pL.get<std::string>("aggregate qualities: mode");
114  GetOStream(Statistics1) << "AggregateQuality: mode " << mode << std::endl;
115 
117  if (mode == "eigenvalue" || mode == "both") {
119  ComputeAggregateQualities(A, aggregates, aggregate_qualities);
120  OutputAggQualities(currentLevel, aggregate_qualities);
121  }
122  if (mode == "size" || mode == "both") {
124  ComputeAggregateSizes(A, aggregates, aggregate_sizes);
125  Set(currentLevel, "AggregateSizes", aggregate_sizes);
126  OutputAggSizes(currentLevel, aggregate_sizes);
127  }
128  Set(currentLevel, "AggregateQualities", aggregate_qualities);
129 }
130 
131 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
133  // Reorder local aggregate information into a format amenable to computing
134  // per-aggregate quantities. Specifically, we compute a format
135  // similar to compressed sparse row format for sparse matrices in which
136  // we store all the local vertices in a single array in blocks corresponding
137  // to aggregates. (This array is aggSortedVertices.) We then store a second
138  // array (aggsToIndices) whose k-th element stores the index of the first
139  // vertex in aggregate k in the array aggSortedVertices.
140 
141  const LO LO_ZERO = Teuchos::OrdinalTraits<LO>::zero();
142  const LO LO_ONE = Teuchos::OrdinalTraits<LO>::one();
143 
144  LO numAggs = aggs->GetNumAggregates();
145  aggSizes = aggs->ComputeAggregateSizesArrayRCP();
146 
147  aggsToIndices = ArrayRCP<LO>(numAggs + LO_ONE, LO_ZERO);
148 
149  for (LO i = 0; i < numAggs; ++i) {
150  aggsToIndices[i + LO_ONE] = aggsToIndices[i] + aggSizes[i];
151  }
152 
153  const RCP<LOMultiVector> vertex2AggId = aggs->GetVertex2AggId();
154  const ArrayRCP<const LO> vertex2AggIdData = vertex2AggId->getData(0);
155 
156  LO numNodes = vertex2AggId->getLocalLength();
157  aggSortedVertices = ArrayRCP<LO>(numNodes, -LO_ONE);
158  std::vector<LO> vertexInsertionIndexByAgg(numNodes, LO_ZERO);
159 
160  for (LO i = 0; i < numNodes; ++i) {
161  LO aggId = vertex2AggIdData[i];
162  if (aggId < 0 || aggId >= numAggs) continue;
163 
164  aggSortedVertices[aggsToIndices[aggId] + vertexInsertionIndexByAgg[aggId]] = i;
165  vertexInsertionIndexByAgg[aggId]++;
166  }
167 }
168 
169 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
171  const SC SCALAR_ONE = Teuchos::ScalarTraits<SC>::one();
172  const SC SCALAR_TWO = SCALAR_ONE + SCALAR_ONE;
173 
174  const LO LO_ZERO = Teuchos::OrdinalTraits<LO>::zero();
175  const LO LO_ONE = Teuchos::OrdinalTraits<LO>::one();
176 
177  using MT = magnitudeType;
178  const MT MT_ZERO = Teuchos::ScalarTraits<MT>::zero();
179  const MT MT_ONE = Teuchos::ScalarTraits<MT>::one();
180  ParameterList pL = GetParameterList();
181 
182  RCP<const Matrix> AT = A;
183 
184  // Algorithm check
185  std::string algostr = pL.get<std::string>("aggregate qualities: algorithm");
186  MT zeroThreshold = Teuchos::as<MT>(pL.get<double>("aggregate qualities: zero threshold"));
187  enum AggAlgo { ALG_FORWARD = 0,
188  ALG_REVERSE };
189  AggAlgo algo;
190  if (algostr == "forward") {
191  algo = ALG_FORWARD;
192  GetOStream(Statistics1) << "AggregateQuality: Using 'forward' algorithm" << std::endl;
193  } else if (algostr == "reverse") {
194  algo = ALG_REVERSE;
195  GetOStream(Statistics1) << "AggregateQuality: Using 'reverse' algorithm" << std::endl;
196  } else {
197  TEUCHOS_TEST_FOR_EXCEPTION(1, Exceptions::RuntimeError, "\"algorithm\" must be one of (forward|reverse)");
198  }
199 
200  bool check_symmetry = pL.get<bool>("aggregate qualities: check symmetry");
201  if (check_symmetry) {
202  RCP<MultiVector> x = MultiVectorFactory::Build(A->getMap(), 1, false);
203  x->Xpetra_randomize();
204 
205  RCP<MultiVector> tmp = MultiVectorFactory::Build(A->getMap(), 1, false);
206 
207  A->apply(*x, *tmp, Teuchos::NO_TRANS); // tmp now stores A*x
208  A->apply(*x, *tmp, Teuchos::TRANS, -SCALAR_ONE, SCALAR_ONE); // tmp now stores A*x - A^T*x
209 
210  Array<magnitudeType> tmp_norm(1);
211  tmp->norm2(tmp_norm());
212 
213  Array<magnitudeType> x_norm(1);
214  tmp->norm2(x_norm());
215 
216  if (tmp_norm[0] > 1e-10 * x_norm[0]) {
217  std::string transpose_string = "transpose";
218  RCP<ParameterList> whatever;
219  AT = Utilities::Transpose(*rcp_const_cast<Matrix>(A), true, transpose_string, whatever);
220 
221  assert(A->getMap()->isSameAs(*(AT->getMap())));
222  }
223  }
224 
225  // Reorder local aggregate information into a format amenable to computing
226  // per-aggregate quantities. Specifically, we compute a format
227  // similar to compressed sparse row format for sparse matrices in which
228  // we store all the local vertices in a single array in blocks corresponding
229  // to aggregates. (This array is aggSortedVertices.) We then store a second
230  // array (aggsToIndices) whose k-th element stores the index of the first
231  // vertex in aggregate k in the array aggSortedVertices.
232 
233  ArrayRCP<LO> aggSortedVertices, aggsToIndices, aggSizes;
234  ConvertAggregatesData(aggs, aggSortedVertices, aggsToIndices, aggSizes);
235 
236  LO numAggs = aggs->GetNumAggregates();
237 
238  // Compute the per-aggregate quality estimate
239 
240  typedef Teuchos::SerialDenseMatrix<LO, MT> DenseMatrix;
241  typedef Teuchos::SerialDenseVector<LO, MT> DenseVector;
242 
243  ArrayView<const LO> rowIndices;
244  ArrayView<const SC> rowValues;
245  ArrayView<const SC> colValues;
246  Teuchos::LAPACK<LO, MT> myLapack;
247 
248  // Iterate over each aggregate to compute the quality estimate
249  for (LO aggId = LO_ZERO; aggId < numAggs; ++aggId) {
250  LO aggSize = aggSizes[aggId];
251  DenseMatrix A_aggPart(aggSize, aggSize, true);
252  DenseVector offDiagonalAbsoluteSums(aggSize, true);
253 
254  // Iterate over each node in the aggregate
255  for (LO idx = LO_ZERO; idx < aggSize; ++idx) {
256  LO nodeId = aggSortedVertices[idx + aggsToIndices[aggId]];
257  A->getLocalRowView(nodeId, rowIndices, rowValues);
258  AT->getLocalRowView(nodeId, rowIndices, colValues);
259 
260  // Iterate over each element in the row corresponding to the current node
261  for (LO elem = LO_ZERO; elem < rowIndices.size(); ++elem) {
262  LO nodeId2 = rowIndices[elem];
263  SC val = (rowValues[elem] + colValues[elem]) / SCALAR_TWO;
264 
265  LO idxInAgg = -LO_ONE; // -1 if element is not in aggregate
266 
267  // Check whether the element belongs in the aggregate. If it does
268  // find, its index. Otherwise, add it's value to the off diagonal
269  // sums
270  for (LO idx2 = LO_ZERO; idx2 < aggSize; ++idx2) {
271  if (aggSortedVertices[idx2 + aggsToIndices[aggId]] == nodeId2) {
272  // Element does belong to aggregate
273  idxInAgg = idx2;
274  break;
275  }
276  }
277 
278  if (idxInAgg == -LO_ONE) { // Element does not belong to aggregate
279 
280  offDiagonalAbsoluteSums[idx] += Teuchos::ScalarTraits<SC>::magnitude(val);
281 
282  } else { // Element does belong to aggregate
283 
284  A_aggPart(idx, idxInAgg) = Teuchos::ScalarTraits<SC>::real(val);
285  }
286  }
287  }
288 
289  // Construct a diagonal matrix consisting of the diagonal
290  // of A_aggPart
291  DenseMatrix A_aggPartDiagonal(aggSize, aggSize, true);
292  MT diag_sum = MT_ZERO;
293  for (int i = 0; i < aggSize; ++i) {
294  A_aggPartDiagonal(i, i) = Teuchos::ScalarTraits<SC>::real(A_aggPart(i, i));
295  diag_sum += Teuchos::ScalarTraits<SC>::real(A_aggPart(i, i));
296  }
297 
298  DenseMatrix ones(aggSize, aggSize, false);
299  ones.putScalar(MT_ONE);
300 
301  // Compute matrix on top of generalized Rayleigh quotient
302  // topMatrix = A_aggPartDiagonal - A_aggPartDiagonal*ones*A_aggPartDiagonal/diag_sum;
303  DenseMatrix tmp(aggSize, aggSize, false);
304  DenseMatrix topMatrix(A_aggPartDiagonal);
305 
306  tmp.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, MT_ONE, ones, A_aggPartDiagonal, MT_ZERO);
307  topMatrix.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, -MT_ONE / diag_sum, A_aggPartDiagonal, tmp, MT_ONE);
308 
309  // Compute matrix on bottom of generalized Rayleigh quotient
310  DenseMatrix bottomMatrix(A_aggPart);
311  MT matrixNorm = A_aggPart.normInf();
312 
313  // Forward mode: Include a small perturbation to the bottom matrix to make it nonsingular
314  const MT boost = (algo == ALG_FORWARD) ? (-1e4 * Teuchos::ScalarTraits<MT>::eps() * matrixNorm) : MT_ZERO;
315 
316  for (int i = 0; i < aggSize; ++i) {
317  bottomMatrix(i, i) -= offDiagonalAbsoluteSums(i) + boost;
318  }
319 
320  // Compute generalized eigenvalues
321  LO sdim, info;
322  DenseVector alpha_real(aggSize, false);
323  DenseVector alpha_imag(aggSize, false);
324  DenseVector beta(aggSize, false);
325 
326  DenseVector workArray(14 * (aggSize + 1), false);
327 
328  LO(*ptr2func)
329  (MT*, MT*, MT*);
330  ptr2func = NULL;
331  LO* bwork = NULL;
332  MT* vl = NULL;
333  MT* vr = NULL;
334 
335  const char compute_flag = 'N';
336  if (algo == ALG_FORWARD) {
337  // Forward: Solve the generalized eigenvalue problem as is
338  myLapack.GGES(compute_flag, compute_flag, compute_flag, ptr2func, aggSize,
339  topMatrix.values(), aggSize, bottomMatrix.values(), aggSize, &sdim,
340  alpha_real.values(), alpha_imag.values(), beta.values(), vl, aggSize,
341  vr, aggSize, workArray.values(), workArray.length(), bwork,
342  &info);
343  TEUCHOS_ASSERT(info == LO_ZERO);
344 
345  MT maxEigenVal = MT_ZERO;
346  for (int i = LO_ZERO; i < aggSize; ++i) {
347  // NOTE: In theory, the eigenvalues should be nearly real
348  // TEUCHOS_ASSERT(fabs(alpha_imag[i]) <= 1e-8*fabs(alpha_real[i])); // Eigenvalues should be nearly real
349  maxEigenVal = std::max(maxEigenVal, alpha_real[i] / beta[i]);
350  }
351 
352  (agg_qualities->getDataNonConst(0))[aggId] = (MT_ONE + MT_ONE) * maxEigenVal;
353  } else {
354  // Reverse: Swap the top and bottom matrices for the generalized eigenvalue problem
355  // This is trickier, since we need to grab the smallest non-zero eigenvalue and invert it.
356  myLapack.GGES(compute_flag, compute_flag, compute_flag, ptr2func, aggSize,
357  bottomMatrix.values(), aggSize, topMatrix.values(), aggSize, &sdim,
358  alpha_real.values(), alpha_imag.values(), beta.values(), vl, aggSize,
359  vr, aggSize, workArray.values(), workArray.length(), bwork,
360  &info);
361 
362  TEUCHOS_ASSERT(info == LO_ZERO);
363 
364  MT minEigenVal = MT_ZERO;
365 
366  for (int i = LO_ZERO; i < aggSize; ++i) {
367  MT ev = alpha_real[i] / beta[i];
368  if (ev > zeroThreshold) {
369  if (minEigenVal == MT_ZERO)
370  minEigenVal = ev;
371  else
372  minEigenVal = std::min(minEigenVal, ev);
373  }
374  }
375  if (minEigenVal == MT_ZERO)
376  (agg_qualities->getDataNonConst(0))[aggId] = Teuchos::ScalarTraits<MT>::rmax();
377  else
378  (agg_qualities->getDataNonConst(0))[aggId] = (MT_ONE + MT_ONE) / minEigenVal;
379  }
380  } // end aggId loop
381 }
382 
383 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
385  ParameterList pL = GetParameterList();
386 
387  magnitudeType good_agg_thresh = Teuchos::as<magnitudeType>(pL.get<double>("aggregate qualities: good aggregate threshold"));
388  using MT = magnitudeType;
389 
390  ArrayRCP<const MT> data = agg_qualities->getData(0);
391 
392  LO num_bad_aggs = 0;
393  MT worst_agg = 0.0;
394 
395  MT mean_bad_agg = 0.0;
396  MT mean_good_agg = 0.0;
397 
398  for (size_t i = 0; i < agg_qualities->getLocalLength(); ++i) {
399  if (data[i] > good_agg_thresh) {
400  num_bad_aggs++;
401  mean_bad_agg += data[i];
402  } else {
403  mean_good_agg += data[i];
404  }
405  worst_agg = std::max(worst_agg, data[i]);
406  }
407 
408  if (num_bad_aggs > 0) mean_bad_agg /= num_bad_aggs;
409  mean_good_agg /= agg_qualities->getLocalLength() - num_bad_aggs;
410 
411  if (num_bad_aggs == 0) {
412  GetOStream(Statistics1) << "All aggregates passed the quality measure. Worst aggregate had quality " << worst_agg << ". Mean aggregate quality " << mean_good_agg << "." << std::endl;
413  } else {
414  GetOStream(Statistics1) << num_bad_aggs << " out of " << agg_qualities->getLocalLength() << " did not pass the quality measure. Worst aggregate had quality " << worst_agg << ". "
415  << "Mean bad aggregate quality " << mean_bad_agg << ". Mean good aggregate quality " << mean_good_agg << "." << std::endl;
416  }
417 
418  if (pL.get<bool>("aggregate qualities: file output")) {
419  std::string filename = pL.get<std::string>("aggregate qualities: file base") + "." + std::to_string(level.GetLevelID());
420  Xpetra::IO<magnitudeType, LO, GO, Node>::Write(filename, *agg_qualities);
421  }
422 
423  {
424  const auto n = size_t(agg_qualities->getLocalLength());
425 
426  std::vector<MT> tmp;
427  tmp.reserve(n);
428 
429  for (size_t i = 0; i < n; ++i) {
430  tmp.push_back(data[i]);
431  }
432 
433  std::sort(tmp.begin(), tmp.end());
434 
435  Teuchos::ArrayView<const double> percents = pL.get<Teuchos::Array<double>>("aggregate qualities: percentiles")();
436 
437  GetOStream(Statistics1) << "AGG QUALITY HEADER : | LEVEL | TOTAL |";
438  for (auto percent : percents) {
439  GetOStream(Statistics1) << std::fixed << std::setprecision(4) << 100.0 * percent << "% |";
440  }
441  GetOStream(Statistics1) << std::endl;
442 
443  GetOStream(Statistics1) << "AGG QUALITY PERCENTILES: | " << level.GetLevelID() << " | " << n << "|";
444  for (auto percent : percents) {
445  size_t i = size_t(n * percent);
446  i = i < n ? i : n - 1u;
447  i = i > 0u ? i : 0u;
448  GetOStream(Statistics1) << std::fixed << std::setprecision(4) << tmp[i] << " |";
449  }
450  GetOStream(Statistics1) << std::endl;
451  }
452 }
453 
454 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
456  ArrayRCP<LO> aggSortedVertices, aggsToIndices, aggSizes;
457  ConvertAggregatesData(aggs, aggSortedVertices, aggsToIndices, aggSizes);
458 
459  // Iterate over each node in the aggregate
460  auto data = agg_sizes->getDataNonConst(0);
461  for (LO i = 0; i < (LO)aggSizes.size(); i++)
462  data[i] = aggSizes[i];
463 }
464 
465 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
467  ParameterList pL = GetParameterList();
468  using MT = magnitudeType;
469 
470  ArrayRCP<const LO> data = agg_sizes->getData(0);
471 
472  if (pL.get<bool>("aggregate qualities: file output")) {
473  std::string filename = pL.get<std::string>("aggregate qualities: file base") + ".sizes." + std::to_string(level.GetLevelID());
474  Xpetra::IO<LO, LO, GO, Node>::Write(filename, *agg_sizes);
475  }
476 
477  {
478  size_t n = (size_t)agg_sizes->getLocalLength();
479 
480  std::vector<MT> tmp;
481  tmp.reserve(n);
482 
483  for (size_t i = 0; i < n; ++i) {
484  tmp.push_back(Teuchos::as<MT>(data[i]));
485  }
486 
487  std::sort(tmp.begin(), tmp.end());
488 
489  Teuchos::ArrayView<const double> percents = pL.get<Teuchos::Array<double>>("aggregate qualities: percentiles")();
490 
491  GetOStream(Statistics1) << "AGG SIZE HEADER : | LEVEL | TOTAL |";
492  for (auto percent : percents) {
493  GetOStream(Statistics1) << std::fixed << std::setprecision(4) << 100.0 * percent << "% |";
494  }
495  GetOStream(Statistics1) << std::endl;
496 
497  GetOStream(Statistics1) << "AGG SIZE PERCENTILES: | " << level.GetLevelID() << " | " << n << "|";
498  for (auto percent : percents) {
499  size_t i = size_t(n * percent);
500  i = i < n ? i : n - 1u;
501  i = i > 0u ? i : 0u;
502  GetOStream(Statistics1) << std::fixed << std::setprecision(4) << tmp[i] << " |";
503  }
504  GetOStream(Statistics1) << std::endl;
505  }
506 }
507 
508 } // namespace MueLu
509 
510 #endif // MUELU_AGGREGATEQUALITYESTIMATE_DEF_HPP
void OutputAggQualities(const Level &level, RCP< const Xpetra::MultiVector< magnitudeType, LO, GO, Node >> agg_qualities) const
static Teuchos::RCP< MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > Build(const Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node >> &map, size_t NumVectors, bool zeroOut=true)
KOKKOS_INLINE_FUNCTION LO GetNumAggregates() const
void ComputeAggregateSizes(RCP< const Matrix > A, RCP< const Aggregates > aggs, RCP< LocalOrdinalVector > agg_sizes) const
T & get(const std::string &name, T def_value)
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
Timer to be used in factories. Similar to Monitor but with additional timers.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
static void Write(const std::string &fileName, const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > &M)
static magnitudeType real(T a)
Print more statistics.
size_type size() const
LocalOrdinal LO
#define SET_VALID_ENTRY(name)
size_type size() const
void DeclareInput(Level &currentLevel) const
Specifies the data that this class needs, and the factories that generate that data.
void GGES(const char &JOBVL, const char &JOBVR, const char &SORT, OrdinalType &(*ptr2func)(ScalarType *, ScalarType *, ScalarType *), const OrdinalType &n, ScalarType *A, const OrdinalType &lda, ScalarType *B, const OrdinalType &ldb, OrdinalType *sdim, MagnitudeType *ALPHAR, MagnitudeType *ALPHAI, MagnitudeType *BETA, ScalarType *VL, const OrdinalType &ldvl, ScalarType *VR, const OrdinalType &ldvr, ScalarType *WORK, const OrdinalType &lwork, OrdinalType *BWORK, OrdinalType *info) const
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Class that holds all level-specific information.
Definition: MueLu_Level.hpp:99
static RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > Transpose(Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &Op, bool optimizeTranspose=false, const std::string &label=std::string(), const Teuchos::RCP< Teuchos::ParameterList > &params=Teuchos::null)
Teuchos::ArrayRCP< LocalOrdinal > ComputeAggregateSizesArrayRCP(bool forceRecompute=false) const
Compute sizes of aggregates.
void ComputeAggregateQualities(RCP< const Matrix > A, RCP< const Aggregates > aggs, RCP< Xpetra::MultiVector< magnitudeType, LO, GO, Node >> agg_qualities) const
const RCP< LOMultiVector > & GetVertex2AggId() const
Returns constant vector that maps local node IDs to local aggregates IDs.
void OutputAggSizes(const Level &level, RCP< const LocalOrdinalVector > agg_sizes) const
static RCP< Vector > Build(const Teuchos::RCP< const Map > &map, bool zeroOut=true)
static magnitudeType magnitude(T a)
void Build(Level &currentLevel) const
Build aggregate quality esimates with this factory.
Scalar SC
static void ConvertAggregatesData(RCP< const Aggregates > aggs, ArrayRCP< LO > &aggSortedVertices, ArrayRCP< LO > &aggsToIndices, ArrayRCP< LO > &aggSizes)
Build aggregate quality esimates with this factory.
int GetLevelID() const
Return level number.
Definition: MueLu_Level.cpp:76
Exception throws to report errors in the internal logical of the program.
#define TEUCHOS_ASSERT(assertion_test)
Teuchos::ScalarTraits< Scalar >::magnitudeType magnitudeType