MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_CombinePFactory_def.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_COMBINEPFACTORY_DEF_HPP
11#define MUELU_COMBINEPFACTORY_DEF_HPP
12
13#include <stdlib.h>
14#include <iomanip>
15
16#include <Tpetra_ConfigDefs.hpp>
17#include <TpetraCore_ETIHelperMacros.h>
18
19#include <Xpetra_CrsMatrixWrap.hpp>
20#include <Xpetra_ImportFactory.hpp>
21#include <Xpetra_Matrix.hpp>
22#include <Xpetra_MapFactory.hpp>
23#include <Xpetra_MultiVectorFactory.hpp>
24#include <Xpetra_VectorFactory.hpp>
25#include <Tpetra_MultiVector.hpp>
26
27#include <Xpetra_IO.hpp>
28
31
32#include "MueLu_MasterList.hpp"
33#include "MueLu_Monitor.hpp"
34
35namespace MueLu {
36
37template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
39 RCP<ParameterList> validParamList = rcp(new ParameterList());
40 validParamList->setEntry("combine: numBlks", ParameterEntry(1));
41 validParamList->setEntry("combine: useMaxLevels", ParameterEntry(false));
42 validParamList->set<RCP<const FactoryBase>>("A", Teuchos::null, "Generating factory of the matrix A");
43
44 return validParamList;
45}
46
47template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
49 DeclareInput(Level& fineLevel, Level& /* coarseLevel */) const {
50 // Input(fineLevel, "subblock");
51}
52
53template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
55 Level& coarseLevel) const {
56 return BuildP(fineLevel, coarseLevel);
57}
58
59namespace {
60template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
61Teuchos::RCP<Xpetra::CrsMatrixWrap<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
62constructIdentityProlongator(const Teuchos::RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>& map) {
63 using local_matrix_type = typename Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::local_matrix_device_type;
64 using local_graph_type = typename Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::local_graph_device_type;
65 using row_map_type = typename local_matrix_type::row_map_type::non_const_type;
66 using entries_type = typename local_graph_type::entries_type::non_const_type;
67 using values_type = typename local_matrix_type::values_type;
68 using local_scalar_type = typename values_type::value_type;
69
70 LocalOrdinal numLocal = map->getLocalNumElements();
71 row_map_type rowptr("rowptr", numLocal + 1);
72 entries_type colind("colind", numLocal);
73 values_type values("values", numLocal);
74
75 Kokkos::parallel_for(
76 "Setup CRS values for identity prolongator",
77 Kokkos::RangePolicy<LocalOrdinal, typename Node::execution_space>(0, numLocal),
78 KOKKOS_LAMBDA(const LocalOrdinal index) {
79 rowptr(index) = index;
80 colind(index) = index;
81 values(index) = local_scalar_type{1.0};
82 if (index == (numLocal - 1)) {
83 rowptr(numLocal) = numLocal;
84 }
85 });
86
87 auto eye = Xpetra::CrsMatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(map, map, 0);
88 eye->setAllValues(rowptr, colind, values);
89 eye->expertStaticFillComplete(map, map);
90 return Teuchos::make_rcp<Xpetra::CrsMatrixWrap<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(eye);
91}
92} // namespace
93
94template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
96 Level& coarseLevel) const {
97 FactoryMonitor m(*this, "Build", coarseLevel);
98
99 RCP<Matrix> A = Get<RCP<Matrix>>(fineLevel, "A");
100 auto A_blockedCrs = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(A);
101 if (A_blockedCrs != Teuchos::null) {
102 this->BuildPBlocked(fineLevel, coarseLevel);
103 return;
104 }
105
106 const ParameterList& pL = GetParameterList();
107 const LO nBlks = as<LO>(pL.get<int>("combine: numBlks"));
108 const bool useMaxLevels = pL.get<bool>("combine: useMaxLevels");
109
110 // Record all matrices that each define a block in block diagonal comboP
111 // matrix used for PDE/multiblock interpolation. Additionally, count
112 // total number of local rows, nonzeros, coarseDofs, and colDofs.
113
114 Teuchos::ArrayRCP<RCP<Matrix>> arrayOfMatrices(nBlks);
115 size_t nComboRowMap = 0, nnzCombo = 0, nComboColMap = 0, nComboDomMap = 0;
116
117 LO nTotalNumberLocalColMapEntries = 0;
118 Teuchos::ArrayRCP<size_t> DomMapSizePerBlk(nBlks);
119 Teuchos::ArrayRCP<size_t> ColMapSizePerBlk(nBlks);
120 Teuchos::ArrayRCP<size_t> ColMapLocalSizePerBlk(nBlks);
121 Teuchos::ArrayRCP<size_t> ColMapRemoteSizePerBlk(nBlks);
122 Teuchos::ArrayRCP<size_t> ColMapLocalCumulativePerBlk(nBlks + 1); // hardwire 0th entry so that it has the value of 0
123 Teuchos::ArrayRCP<size_t> ColMapRemoteCumulativePerBlk(nBlks + 1); // hardwire 0th entry so that it has the value of 0
124
125 bool anyCoarseGridsRemaining = false;
126
127 if (useMaxLevels) {
128 for (int j = 0; j < nBlks; j++) {
129 std::string blockName = "Psubblock" + Teuchos::toString(j);
130 anyCoarseGridsRemaining |= coarseLevel.IsAvailable(blockName, NoFactory::get());
131 };
132
133 int localAnyCoarseGridsRemaining = anyCoarseGridsRemaining;
134 int globalAnyCoarseGridsRemaining = localAnyCoarseGridsRemaining;
135 Teuchos::reduceAll(*A->getDomainMap()->getComm(), Teuchos::REDUCE_MAX, localAnyCoarseGridsRemaining, Teuchos::ptr(&globalAnyCoarseGridsRemaining));
136
137 anyCoarseGridsRemaining |= globalAnyCoarseGridsRemaining > 0;
138 }
139
140 auto setSubblockProlongator = [&](RCP<Matrix> Psubblock, int j) {
141 arrayOfMatrices[j] = Psubblock;
142 nComboRowMap += Teuchos::as<size_t>((arrayOfMatrices[j])->getRowMap()->getLocalNumElements());
143 DomMapSizePerBlk[j] = Teuchos::as<size_t>((arrayOfMatrices[j])->getDomainMap()->getLocalNumElements());
144 ColMapSizePerBlk[j] = Teuchos::as<size_t>((arrayOfMatrices[j])->getColMap()->getLocalNumElements());
145 nComboDomMap += DomMapSizePerBlk[j];
146 nComboColMap += ColMapSizePerBlk[j];
147 nnzCombo += Teuchos::as<size_t>((arrayOfMatrices[j])->getLocalNumEntries());
148 TEUCHOS_TEST_FOR_EXCEPTION((arrayOfMatrices[j])->getDomainMap()->getIndexBase() != 0, Exceptions::RuntimeError, "interpolation subblocks must use 0 indexbase");
149
150 // figure out how many empty entries in each column map
151 int tempii = 0;
152 for (int i = 0; i < (int)DomMapSizePerBlk[j]; i++) {
153 if ((arrayOfMatrices[j])->getDomainMap()->getGlobalElement(i) == (arrayOfMatrices[j])->getColMap()->getGlobalElement(tempii)) tempii++;
154 }
155 nTotalNumberLocalColMapEntries += tempii;
156 ColMapLocalSizePerBlk[j] = tempii;
157 ColMapRemoteSizePerBlk[j] = ColMapSizePerBlk[j] - ColMapLocalSizePerBlk[j];
158 };
159
160 for (int j = 0; j < nBlks; j++) {
161 std::string blockName = "Psubblock" + Teuchos::toString(j);
162 if (coarseLevel.IsAvailable(blockName, NoFactory::get())) {
163 setSubblockProlongator(coarseLevel.Get<RCP<Matrix>>(blockName, NoFactory::get()), j);
164 } else {
165 std::string subblockOpName = "Operatorsubblock" + Teuchos::toString(j);
166 bool hasOperator = false;
167 if (coarseLevel.IsAvailable(subblockOpName)) {
168 auto A_blk = coarseLevel.Get<RCP<Operator>>(subblockOpName);
169 hasOperator = A_blk != Teuchos::null;
170 }
171
172 if (useMaxLevels && anyCoarseGridsRemaining && hasOperator) {
173 // Use Psubblock = I
174 auto P_id = constructIdentityProlongator<Scalar, LocalOrdinal, GlobalOrdinal, Node>(coarseLevel.Get<RCP<Operator>>(subblockOpName)->getDomainMap());
175 setSubblockProlongator(P_id, j);
176 } else {
177 arrayOfMatrices[j] = Teuchos::null;
178 ColMapLocalSizePerBlk[j] = 0;
179 ColMapRemoteSizePerBlk[j] = 0;
180 }
181 }
182 ColMapLocalCumulativePerBlk[j + 1] = ColMapLocalSizePerBlk[j] + ColMapLocalCumulativePerBlk[j];
183 ColMapRemoteCumulativePerBlk[j + 1] = ColMapRemoteSizePerBlk[j] + ColMapRemoteCumulativePerBlk[j];
184 }
185
186 TEUCHOS_TEST_FOR_EXCEPTION(nComboRowMap != A->getRowMap()->getLocalNumElements(), Exceptions::RuntimeError, "sum of subblock rows != #row's Afine");
187
188 // build up csr arrays for combo block diagonal P
189 Teuchos::ArrayRCP<size_t> comboPRowPtr(nComboRowMap + 1);
190 Teuchos::ArrayRCP<LocalOrdinal> comboPCols(nnzCombo);
191 Teuchos::ArrayRCP<Scalar> comboPVals(nnzCombo);
192
193 size_t nnzCnt = 0, nrowCntFromPrevBlks = 0, ncolCntFromPrevBlks = 0;
194 LO maxNzPerRow = 0;
195 for (int j = 0; j < nBlks; j++) {
196 // grab csr pointers for individual blocks of P
197 if (arrayOfMatrices[j] != Teuchos::null) {
198 Teuchos::ArrayRCP<const size_t> subblockRowPtr((arrayOfMatrices[j])->getLocalNumRows());
199 Teuchos::ArrayRCP<const LocalOrdinal> subblockCols((arrayOfMatrices[j])->getLocalNumEntries());
200 Teuchos::ArrayRCP<const Scalar> subblockVals((arrayOfMatrices[j])->getLocalNumEntries());
201 if ((int)(arrayOfMatrices[j])->getLocalMaxNumRowEntries() > maxNzPerRow) maxNzPerRow = (int)(arrayOfMatrices[j])->getLocalMaxNumRowEntries();
202 Teuchos::RCP<CrsMatrixWrap> subblockwrap = Teuchos::rcp_dynamic_cast<CrsMatrixWrap>((arrayOfMatrices[j]));
203 Teuchos::RCP<CrsMatrix> subblockcrs = subblockwrap->getCrsMatrix();
204 subblockcrs->getAllValues(subblockRowPtr, subblockCols, subblockVals);
205
206 // copy jth block into csr arrays of comboP
207
208 for (decltype(subblockRowPtr.size()) i = 0; i < subblockRowPtr.size() - 1; i++) {
209 size_t rowLength = subblockRowPtr[i + 1] - subblockRowPtr[i];
210 comboPRowPtr[nrowCntFromPrevBlks + i] = nnzCnt;
211 for (size_t k = 0; k < rowLength; k++) {
212 if ((int)subblockCols[k + subblockRowPtr[i]] < (int)ColMapLocalSizePerBlk[j]) {
213 comboPCols[nnzCnt] = subblockCols[k + subblockRowPtr[i]] + ColMapLocalCumulativePerBlk[j];
214 if ((int)comboPCols[nnzCnt] >= (int)ColMapLocalCumulativePerBlk[nBlks]) {
215 printf("ERROR1\n");
216 exit(1);
217 }
218 } else {
219 // Here we subtract off the number of local colmap guys ... so this tell us where we are among ghost unknowns. We then want to stick this ghost after
220 // all the Local guys ... so we add ColMapLocalCumulativePerBlk[nBlks] .... finally we need to account for the fact that other ghost blocks may have already
221 // been handled ... so we then add + ColMapRemoteCumulativePerBlk[j];
222 comboPCols[nnzCnt] = subblockCols[k + subblockRowPtr[i]] - ColMapLocalSizePerBlk[j] + ColMapLocalCumulativePerBlk[nBlks] + ColMapRemoteCumulativePerBlk[j];
223 if ((int)comboPCols[nnzCnt] >= (int)(ColMapLocalCumulativePerBlk[nBlks] + ColMapRemoteCumulativePerBlk[nBlks])) {
224 printf("ERROR2\n");
225 exit(1);
226 }
227 }
228 comboPVals[nnzCnt++] = subblockVals[k + subblockRowPtr[i]];
229 }
230 }
231
232 nrowCntFromPrevBlks += Teuchos::as<size_t>((arrayOfMatrices[j])->getRowMap()->getLocalNumElements());
233 ncolCntFromPrevBlks += DomMapSizePerBlk[j]; // rst: check this
234 }
235 }
236 comboPRowPtr[nComboRowMap] = nnzCnt;
237
238 // Come up with global IDs for the coarse grid maps. We assume that each xxx
239 // block has a minimum GID of 0. Since MueLu is generally creating these
240 // GIDS, this assumption is probably correct, but we'll check it.
241
242 Teuchos::Array<GlobalOrdinal> comboDomainMapGIDs(nComboDomMap);
243 Teuchos::Array<GlobalOrdinal> comboColMapGIDs(nComboColMap);
244
245 LO nTotalNumberRemoteColMapEntries = 0;
246 GlobalOrdinal offset = 0;
247 size_t domainMapIndex = 0;
248 int nComboColIndex = 0;
249 for (int j = 0; j < nBlks; j++) {
250 int nThisBlkColIndex = 0;
251
252 GlobalOrdinal tempMax = 0, maxGID = 0;
253 if (arrayOfMatrices[j] != Teuchos::null) tempMax = (arrayOfMatrices[j])->getDomainMap()->getMaxGlobalIndex();
254 Teuchos::reduceAll(*(A->getDomainMap()->getComm()), Teuchos::REDUCE_MAX, tempMax, Teuchos::ptr(&maxGID));
255
256 if (arrayOfMatrices[j] != Teuchos::null) {
257 TEUCHOS_TEST_FOR_EXCEPTION(arrayOfMatrices[j]->getDomainMap()->getMinAllGlobalIndex() < 0, Exceptions::RuntimeError, "Global ID assumption for domainMap not met within subblock");
258
259 GO priorDomGID = 0;
260 for (size_t c = 0; c < DomMapSizePerBlk[j]; ++c) { // check this
261 // The global ids of jth block are assumed to go between 0 and maxGID_j. So the 1th blocks DomainGIDs should start at maxGID_0+1. The 2nd
262 // block DomainDIGS starts at maxGID_0+1 + maxGID_1 + 1. We use offset to keep track of these starting points.
263 priorDomGID = (arrayOfMatrices[j])->getDomainMap()->getGlobalElement(c);
264 comboDomainMapGIDs[domainMapIndex++] = offset + priorDomGID;
265 if (priorDomGID == (arrayOfMatrices[j])->getColMap()->getGlobalElement(nThisBlkColIndex)) {
266 comboColMapGIDs[nComboColIndex++] = offset + priorDomGID;
267 nThisBlkColIndex++;
268 }
269 }
270
271 for (size_t cc = nThisBlkColIndex; cc < ColMapSizePerBlk[j]; ++cc) {
272 comboColMapGIDs[nTotalNumberLocalColMapEntries + nTotalNumberRemoteColMapEntries++] = offset + (arrayOfMatrices[j])->getColMap()->getGlobalElement(cc);
273 }
274 }
275 offset += maxGID + 1;
276 }
277#ifdef out
278 RCP<const Map> coarseDomainMap = Xpetra::MapFactory<LO, GO, NO>::Build(A->getDomainMap()->lib(), Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(), comboDomainMapGIDs, 0, A->getDomainMap()->getComm());
279 RCP<const Map> coarseColMap = Xpetra::MapFactory<LO, GO, NO>::Build(A->getDomainMap()->lib(), Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(), comboColMapGIDs, 0, A->getDomainMap()->getComm());
280#endif
281
282 RCP<const Map> coarseDomainMap = Xpetra::MapFactory<LO, GO, NO>::Build(A->getDomainMap()->lib(), Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(), comboDomainMapGIDs, 0, A->getRowMap()->getComm());
283 RCP<const Map> coarseColMap = Xpetra::MapFactory<LO, GO, NO>::Build(A->getDomainMap()->lib(), Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(), comboColMapGIDs, 0, A->getRowMap()->getComm());
284
285 Teuchos::RCP<CrsMatrix> comboPCrs = CrsMatrixFactory::Build(A->getRowMap(), coarseColMap, maxNzPerRow);
286 // comboPCrs->getCrsGraph(); //.getRowInfo(6122);
287 // comboPCrs->getRowInfo(6122);
288
289 // Teuchos::RCP<CrsMatrix> comboPCrs = CrsMatrixFactory::Build(A->getRowMap(), coarseColMap,nnzCombo+1000);
290
291 // for (size_t i = 0; i < nComboRowMap; i++) {
292 // printf("FIXME\n"); if (nComboRowMap > 6142) nComboRowMap = 6142;
293 for (size_t i = 0; i < nComboRowMap; i++) {
294 comboPCrs->insertLocalValues(i, comboPCols.view(comboPRowPtr[i], comboPRowPtr[i + 1] - comboPRowPtr[i]),
295 comboPVals.view(comboPRowPtr[i], comboPRowPtr[i + 1] - comboPRowPtr[i]));
296 }
297 comboPCrs->fillComplete(coarseDomainMap, A->getRowMap());
298
299 Teuchos::RCP<Matrix> comboP = Teuchos::rcp(new CrsMatrixWrap(comboPCrs));
300
301 if (!restrictionMode_) {
302 Set(coarseLevel, "P", comboP);
303 } else {
304 RCP<Matrix> R = Utilities::Transpose(*comboP, true);
305 Set(coarseLevel, "R", R);
306 }
307}
308
309template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
311 BuildPBlockedImpl(Level& fineLevel, Level& coarseLevel, std::false_type) const {
312#if defined(HAVE_XPETRA_THYRA) && defined(HAVE_MUELU_THYRA)
313 std::ostringstream oss;
314 oss << "CombinePFactory::BuildPBlocked requires Thyra ETI support for this "
315 "template-parameter combination:\n"
316 << " Scalar = " << Teuchos::TypeNameTraits<Scalar>::name() << '\n'
317 << " LocalOrdinal = " << Teuchos::TypeNameTraits<LocalOrdinal>::name() << '\n'
318 << " GlobalOrdinal = " << Teuchos::TypeNameTraits<GlobalOrdinal>::name() << '\n'
319 << " Node = " << Teuchos::TypeNameTraits<Node>::name() << '\n'
320 << "If your application provides the necessary Thyra ETIs, specialize "
321 "MueLu::Details::has_build_p_blocked_thyra_eti<Scalar,LocalOrdinal,GlobalOrdinal,Node> "
322 "to std::true_type.";
323
324 TEUCHOS_TEST_FOR_EXCEPTION(true, Exceptions::RuntimeError, oss.str());
325#else
326 TEUCHOS_TEST_FOR_EXCEPTION(
328 "CombinePFactory::BuildPBlocked requires Thyra support.");
329#endif
330}
331
332#if defined(HAVE_XPETRA_THYRA) && defined(HAVE_MUELU_THYRA)
333template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
334template <class S,
335 std::enable_if_t<
337 S, LocalOrdinal, GlobalOrdinal, Node>::value,
338 int>>
340 Level& coarseLevel, std::true_type) const {
341 TEUCHOS_TEST_FOR_EXCEPTION(restrictionMode_, Exceptions::RuntimeError, "CombinePFactory::BuildPBlocked does not support restriction mode.");
342 const ParameterList& pL = GetParameterList();
343 const LO nBlks = as<LO>(pL.get<int>("combine: numBlks"));
344 const bool useMaxLevels = pL.get<bool>("combine: useMaxLevels");
345
346 RCP<Matrix> A = Get<RCP<Matrix>>(fineLevel, "A");
347
348 bool anyCoarseGridsRemaining = false;
349
350 if (useMaxLevels) {
351 for (int j = 0; j < nBlks; j++) {
352 std::string blockName = "Psubblock" + Teuchos::toString(j);
353 anyCoarseGridsRemaining |= coarseLevel.IsAvailable(blockName, NoFactory::get());
354 };
355
356 int localAnyCoarseGridsRemaining = anyCoarseGridsRemaining;
357 int globalAnyCoarseGridsRemaining = localAnyCoarseGridsRemaining;
358 Teuchos::reduceAll(*A->getDomainMap()->getComm(), Teuchos::REDUCE_MAX, localAnyCoarseGridsRemaining, Teuchos::ptr(&globalAnyCoarseGridsRemaining));
359
360 anyCoarseGridsRemaining |= globalAnyCoarseGridsRemaining > 0;
361 }
362
363 auto blockProlongator = Teuchos::make_rcp<Thyra::DefaultBlockedLinearOp<Scalar>>();
364 blockProlongator->beginBlockFill(nBlks, nBlks);
365
366 for (int j = 0; j < nBlks; j++) {
367 RCP<Matrix> P_jj;
368
369 std::string blockName = "Psubblock" + Teuchos::toString(j);
370 if (coarseLevel.IsAvailable(blockName, NoFactory::get())) {
371 P_jj = coarseLevel.Get<RCP<Matrix>>(blockName, NoFactory::get());
372 } else if (useMaxLevels && anyCoarseGridsRemaining) {
373 std::string subblockOpName = "Operatorsubblock" + Teuchos::toString(j);
374 P_jj = constructIdentityProlongator<Scalar, LocalOrdinal, GlobalOrdinal, Node>(fineLevel.Get<RCP<Operator>>(subblockOpName)->getDomainMap());
375 }
376
377 RCP<const Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpetra_P_jj = Xpetra::toTpetra(P_jj);
378 auto thyra_P_jj = Thyra::createConstLinearOp(tpetra_P_jj);
379 blockProlongator->setBlock(j, j, thyra_P_jj);
380 }
381
382 blockProlongator->endBlockFill();
383
384 Teuchos::RCP<Matrix> blockedProlongatorXpetra = Teuchos::make_rcp<Xpetra::BlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(blockProlongator, Teuchos::null);
385
386 blockedProlongatorXpetra->fillComplete();
387
388 Set(coarseLevel, "P", blockedProlongatorXpetra);
389}
390#endif
391
392template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
394 Level& coarseLevel) const {
395 BuildPBlockedImpl(
396 fineLevel, coarseLevel,
397 std::integral_constant<bool,
399}
400
401#if defined(HAVE_XPETRA_THYRA) && defined(HAVE_MUELU_THYRA)
402#define MUELU_BUILD_P_BLOCKED_THYRA_ETI_SPEC(S, LO, GO, N) \
403 template <> \
404 struct Details::has_build_p_blocked_thyra_eti<S, LO, GO, N> : std::true_type {};
405
406TPETRA_ETI_MANGLING_TYPEDEFS()
407
408TPETRA_INSTANTIATE_SLGN_NO_ORDINAL_SCALAR(MUELU_BUILD_P_BLOCKED_THYRA_ETI_SPEC)
409
410#undef MUELU_BUILD_P_BLOCKED_THYRA_ETI_SPEC
411#endif
412
413} // namespace MueLu
414
415#define MUELU_COMBINEPFACTORY_SHORT
416#endif // MUELU_COMBINEPFACTORY_DEF_HPP
MueLu::DefaultLocalOrdinal LocalOrdinal
MueLu::DefaultGlobalOrdinal GlobalOrdinal
MueLu::DefaultNode Node
void Build(Level &fineLevel, Level &coarseLevel) const
Build an object with this factory.
void BuildP(Level &fineLevel, Level &coarseLevel) const
Abstract Build method.
void BuildPBlocked(Level &fineLevel, Level &coarseLevel) const
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
void BuildPBlockedImpl(Level &fineLevel, Level &coarseLevel, std::false_type) const
void DeclareInput(Level &fineLevel, Level &coarseLevel) const
Input.
Exception throws to report errors in the internal logical of the program.
Timer to be used in factories. Similar to Monitor but with additional timers.
Class that holds all level-specific information.
bool IsAvailable(const std::string &ename, const FactoryBase *factory=NoFactory::get()) const
Test whether a need's value has been saved.
T & Get(const std::string &ename, const FactoryBase *factory=NoFactory::get())
Get data without decrementing associated storage counter (i.e., read-only access)....
static const NoFactory * get()
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)
Namespace for MueLu classes and methods.
Compile-time trait indicating whether CombinePFactory::BuildPBlocked may use its Thyra-based blocked ...