MueLu  Version of the Day
MueLu_SubBlockAFactory_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 /*
47  * MueLu_SubBlockAFactory_def.hpp
48  *
49  * Created on: 02.01.2012
50  * Author: tobias
51  */
52 
53 #ifndef MUELU_SUBBLOCKAFACTORY_DEF_HPP_
54 #define MUELU_SUBBLOCKAFACTORY_DEF_HPP_
55 
56 
58 
59 #include <Xpetra_BlockedCrsMatrix.hpp>
60 #include <Xpetra_CrsMatrix.hpp>
61 #include <Xpetra_CrsMatrixWrap.hpp>
62 #include <Xpetra_MapExtractor.hpp>
63 #include <Xpetra_Matrix.hpp>
64 #include <Xpetra_StridedMapFactory.hpp>
65 
66 #include "MueLu_Level.hpp"
67 #include "MueLu_Monitor.hpp"
68 
69 namespace MueLu {
70 
71  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
73  RCP<ParameterList> validParamList = rcp(new ParameterList());
74 
75  validParamList->set< RCP<const FactoryBase> >("A", MueLu::NoFactory::getRCP(), "Generating factory for A.");
76  validParamList->set< int > ("block row", 0, "Block row of subblock matrix A");
77  validParamList->set< int > ("block col", 0, "Block column of subblock matrix A");
78 
79  return validParamList;
80  }
81 
82  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
84  Input(currentLevel, "A");
85  }
86 
87  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
89  const ParameterList& pL = GetParameterList();
90  size_t row = Teuchos::as<size_t>(pL.get<int>("block row"));
91  size_t col = Teuchos::as<size_t>(pL.get<int>("block col"));
92 
93  RCP<Matrix> Ain = Get<RCP<Matrix> >(currentLevel, "A");
94  RCP<BlockedCrsMatrix> A = rcp_dynamic_cast<BlockedCrsMatrix>(Ain);
95 
96  TEUCHOS_TEST_FOR_EXCEPTION(A.is_null(), Exceptions::BadCast, "Input matrix A is not a BlockedCrsMatrix.");
97  TEUCHOS_TEST_FOR_EXCEPTION(row > A->Rows(), Exceptions::RuntimeError, "row [" << row << "] > A.Rows() [" << A->Rows() << "].");
98  TEUCHOS_TEST_FOR_EXCEPTION(col > A->Cols(), Exceptions::RuntimeError, "col [" << col << "] > A.Cols() [" << A->Cols() << "].");
99 
100  RCP<CrsMatrixWrap> Op = Teuchos::rcp(new CrsMatrixWrap(A->getMatrix(row, col)));
101 
103  // extract striding information from RangeMapExtractor
104 
105  RCP<const MapExtractor> rangeMapExtractor = A->getRangeMapExtractor();
106  RCP<const MapExtractor> domainMapExtractor = A->getDomainMapExtractor();
107 
108  RCP<const Map> rangeMap = rangeMapExtractor ->getMap(row);
109  RCP<const Map> domainMap = domainMapExtractor->getMap(col);
110 
111  RCP<const StridedMap> srangeMap = rcp_dynamic_cast<const StridedMap>(rangeMap);
112  RCP<const StridedMap> sdomainMap = rcp_dynamic_cast<const StridedMap>(domainMap);
113 
114  if (srangeMap.is_null()) {
115  RCP<const Map> fullRangeMap = rangeMapExtractor->getFullMap();
116  RCP<const StridedMap> sFullRangeMap = rcp_dynamic_cast<const StridedMap>(fullRangeMap);
117  TEUCHOS_TEST_FOR_EXCEPTION(sFullRangeMap.is_null(), Exceptions::BadCast, "Full rangeMap is not a strided map.");
118 
119  std::vector<size_t> stridedData = sFullRangeMap->getStridingData();
120  if (stridedData.size() == 1 && row > 0) {
121  // We have block matrices. use striding block information 0
122  srangeMap = StridedMapFactory::Build(rangeMap, stridedData, 0, sFullRangeMap->getOffset());
123 
124  } else {
125  // We have strided matrices. use striding information of the corresponding block
126  srangeMap = StridedMapFactory::Build(rangeMap, stridedData, row, sFullRangeMap->getOffset());
127  }
128  }
129 
130  if (sdomainMap.is_null()) {
131  RCP<const Map> fullDomainMap = domainMapExtractor->getFullMap();
132  RCP<const StridedMap> sFullDomainMap = rcp_dynamic_cast<const StridedMap>(fullDomainMap);
133  TEUCHOS_TEST_FOR_EXCEPTION(sFullDomainMap.is_null(), Exceptions::BadCast, "Full domainMap is not a strided map");
134 
135  std::vector<size_t> stridedData = sFullDomainMap->getStridingData();
136  if (stridedData.size() == 1 && col > 0) {
137  // We have block matrices. use striding block information 0
138  sdomainMap = StridedMapFactory::Build(domainMap, stridedData, 0, sFullDomainMap->getOffset());
139 
140  } else {
141  // We have strided matrices. use striding information of the corresponding block
142  sdomainMap = StridedMapFactory::Build(domainMap, stridedData, col, sFullDomainMap->getOffset());
143  }
144  }
145 
146  TEUCHOS_TEST_FOR_EXCEPTION(srangeMap.is_null(), Exceptions::BadCast, "rangeMap " << row << " is not a strided map.");
147  TEUCHOS_TEST_FOR_EXCEPTION(sdomainMap.is_null(), Exceptions::BadCast, "domainMap " << col << " is not a strided map.");
148 
149  GetOStream(Statistics1) << "A(" << row << "," << col << ") has strided maps:"
150  << "\n range map fixed block size = " << srangeMap ->getFixedBlockSize() << ", strided block id = " << srangeMap ->getStridedBlockId()
151  << "\n domain map fixed block size = " << sdomainMap->getFixedBlockSize() << ", strided block id = " << sdomainMap->getStridedBlockId() << std::endl;
152 
153  if (Op->IsView("stridedMaps") == true)
154  Op->RemoveView("stridedMaps");
155  Op->CreateView("stridedMaps", srangeMap, sdomainMap);
156 
157  TEUCHOS_TEST_FOR_EXCEPTION(Op->IsView("stridedMaps") == false, Exceptions::RuntimeError, "Failed to set \"stridedMaps\" view.");
158 
160 
161  currentLevel.Set("A", rcp_dynamic_cast<Matrix>(Op), this);
162  }
163 
164 } // namespace MueLu
165 
166 #endif /* MUELU_SUBBLOCKAFACTORY_DEF_HPP_ */
Exception indicating invalid cast attempted.
Print more statistics.
Namespace for MueLu classes and methods.
void DeclareInput(Level &currentLevel) const
Specifies the data that this class needs, and the factories that generate that data.
void Build(Level &currentLevel) const
Build an object with this factory.
Class that holds all level-specific information.
Definition: MueLu_Level.hpp:99
RCP< const ParameterList > GetValidParameterList() const
Input.
Exception throws to report errors in the internal logical of the program.
static const RCP< const NoFactory > getRCP()
Static Get() functions.