MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_ZeroSubBlockAFactory_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_ZEROSUBBLOCKAFACTORY_DEF_HPP_
11#define MUELU_ZEROSUBBLOCKAFACTORY_DEF_HPP_
12
14
15#include <Xpetra_BlockedCrsMatrix.hpp>
16#include <Xpetra_Matrix.hpp>
17#include <Xpetra_MatrixFactory.hpp>
18#include <Xpetra_Vector.hpp>
19#include <Xpetra_VectorFactory.hpp>
20
21#include "MueLu_Level.hpp"
22#include "MueLu_Monitor.hpp"
23
24namespace MueLu {
25
26template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
28 RCP<ParameterList> validParamList = rcp(new ParameterList());
29
30 validParamList->set<RCP<const FactoryBase>>("A", MueLu::NoFactory::getRCP(), "Generating factory for A.");
31
32 validParamList->set<int>("block row", 0, "Block row of subblock in block matrix A");
33 validParamList->set<int>("block col", 0, "Block column of subblock in block matrix A");
34
35 return validParamList;
36}
37
38template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
40 Input(currentLevel, "A");
41}
42
43template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
45 FactoryMonitor m(*this, "Build", currentLevel);
46
47 const ParameterList& pL = GetParameterList();
48 const size_t row = Teuchos::as<size_t>(pL.get<int>("block row"));
49 const size_t col = Teuchos::as<size_t>(pL.get<int>("block col"));
50
51 // Get the blocked input matrix
52 RCP<Matrix> Ain = currentLevel.Get<RCP<Matrix>>("A", this->GetFactory("A").get());
53 RCP<BlockedCrsMatrix> A = rcp_dynamic_cast<BlockedCrsMatrix>(Ain);
54
55 // Perform some basic sanity checks
56 TEUCHOS_TEST_FOR_EXCEPTION(A.is_null(), Exceptions::BadCast, "Input matrix A is not a BlockedCrsMatrix.");
57 TEUCHOS_TEST_FOR_EXCEPTION(row > A->Rows(), Exceptions::RuntimeError, "row [" << row << "] > A.Rows() [" << A->Rows() << "].");
58 TEUCHOS_TEST_FOR_EXCEPTION(col > A->Cols(), Exceptions::RuntimeError, "col [" << col << "] > A.Cols() [" << A->Cols() << "].");
59
60 // strided maps for range and domain map of sub matrix
61 RCP<const StridedMap> stridedRangeMap = Teuchos::null;
62 RCP<const StridedMap> stridedDomainMap = Teuchos::null;
63
64 // extract map information from MapExtractor
65 RCP<const MapExtractor> rangeMapExtractor = A->getRangeMapExtractor();
66 RCP<const MapExtractor> domainMapExtractor = A->getDomainMapExtractor();
67
68 // In case that both user-specified and internal striding information from the submaps
69 // does not contain valid striding information, try to extract it from the global maps
70 // in the map extractor.
71 if (stridedRangeMap.is_null()) {
72 TEUCHOS_TEST_FOR_EXCEPTION(rangeMapExtractor->getMap(row).is_null(), Exceptions::BadCast,
73 "Range map extractor contains non-strided maps in block row " << row << ". This should not be.");
74 stridedRangeMap = rcp_dynamic_cast<const StridedMap>(rangeMapExtractor->getMap(row));
75 }
76
77 if (stridedDomainMap.is_null()) {
78 TEUCHOS_TEST_FOR_EXCEPTION(domainMapExtractor->getMap(row).is_null(), Exceptions::BadCast,
79 "Domain map extractor contains non-strided maps in block row " << row << ". This should not be.");
80 stridedDomainMap = rcp_dynamic_cast<const StridedMap>(domainMapExtractor->getMap(col));
81 }
82
83 TEUCHOS_TEST_FOR_EXCEPTION(stridedRangeMap.is_null(), Exceptions::BadCast, "rangeMap " << row << " is not a strided map.");
84 TEUCHOS_TEST_FOR_EXCEPTION(stridedDomainMap.is_null(), Exceptions::BadCast, "domainMap " << col << " is not a strided map.");
85
86 RCP<Matrix> Op = MatrixFactory::Build(stridedRangeMap, stridedDomainMap, static_cast<size_t>(0));
87 TEUCHOS_ASSERT(!Op.is_null());
88
89 Op->fillComplete(stridedDomainMap, stridedRangeMap);
90 TEUCHOS_ASSERT(Op->isFillComplete());
91
92 GetOStream(Statistics1) << "A(" << row << "," << col << ") is a single block and has strided maps:"
93 << "\n range map fixed block size = " << stridedRangeMap->getFixedBlockSize() << ", strided block id = " << stridedRangeMap->getStridedBlockId()
94 << "\n domain map fixed block size = " << stridedDomainMap->getFixedBlockSize() << ", strided block id = " << stridedDomainMap->getStridedBlockId() << std::endl;
95 GetOStream(Statistics2) << "A(" << row << "," << col << ") has " << Op->getGlobalNumRows() << "x" << Op->getGlobalNumCols() << " rows and columns." << std::endl;
96
97 if (Op->IsView("stridedMaps") == true)
98 Op->RemoveView("stridedMaps");
99 Op->CreateView("stridedMaps", stridedRangeMap, stridedDomainMap);
100
101 currentLevel.Set("A", Op, this);
102}
103
104} // namespace MueLu
105
106#endif /* MUELU_ZEROSUBBLOCKAFACTORY_DEF_HPP_ */
Exception indicating invalid cast attempted.
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.
T & Get(const std::string &ename, const FactoryBase *factory=NoFactory::get())
Get data without decrementing associated storage counter (i.e., read-only access)....
void Set(const std::string &ename, const T &entry, const FactoryBase *factory=NoFactory::get())
static const RCP< const NoFactory > getRCP()
Static Get() functions.
void DeclareInput(Level &currentLevel) const override
Specifies the data that this class needs, and the factories that generate that data.
RCP< const ParameterList > GetValidParameterList() const override
Input.
void Build(Level &currentLevel) const override
Build a zero sub-block object with this factory.
Namespace for MueLu classes and methods.
@ Statistics2
Print even more statistics.
@ Statistics1
Print more statistics.