MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MueLu_CoarseMapFactory_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_CoarseMapFactory_def.hpp
48  *
49  * Created on: Oct 12, 2012
50  * Author: wiesner
51  */
52 
53 #ifndef MUELU_COARSEMAPFACTORY_DEF_HPP_
54 #define MUELU_COARSEMAPFACTORY_DEF_HPP_
55 
56 #include <Teuchos_Array.hpp>
57 
58 #include <Xpetra_MultiVector.hpp>
59 #include <Xpetra_StridedMapFactory.hpp>
60 
62 #include "MueLu_Level.hpp"
63 #include "MueLu_Aggregates.hpp"
64 #include "MueLu_Monitor.hpp"
65 
66 namespace MueLu {
67 
68 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
70  RCP<ParameterList> validParamList = rcp(new ParameterList());
71 
72  validParamList->set<RCP<const FactoryBase> >("Aggregates", Teuchos::null, "Generating factory for aggregates.");
73  validParamList->set<RCP<const FactoryBase> >("Nullspace", Teuchos::null, "Generating factory for null space.");
74 
75  validParamList->set<std::string>("Striding info", "{}", "Striding information");
76  validParamList->set<LocalOrdinal>("Strided block id", -1, "Strided block id");
77 
78  // Domain GID offsets: list of offset values for domain gids (coarse gids) of tentative prolongator (default = 0).
79  // For each multigrid level we can define a different offset value, ie for the prolongator between
80  // level 0 and level 1 we use the offset entry domainGidOffsets_[0], for the prolongator between
81  // level 1 and level 2 we use domainGidOffsets_[1]...
82  // If the vector domainGidOffsets_ is too short and does not contain a sufficient number of gid offset
83  // values for all levels, a gid offset of 0 is used for all the remaining levels!
84  // The GIDs for the domain dofs of Ptent start with domainGidOffset, are contiguous and distributed
85  // equally over the procs (unless some reordering is done).
86  validParamList->set<std::string>("Domain GID offsets", "{0}", "vector with offsets for GIDs for each level. If no offset GID value is given for the level we use 0 as default.");
87 
88  return validParamList;
89 }
90 
91 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
93  Input(currentLevel, "Aggregates");
94  Input(currentLevel, "Nullspace");
95 }
96 
97 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
99  // store striding map in internal variable
100  stridingInfo_ = stridingInfo;
101 
102  // try to remove string "Striding info" from parameter list to make sure,
103  // that stridingInfo_ is not replaced in the Build call.
104  std::string strStridingInfo;
105  strStridingInfo.clear();
106  SetParameter("Striding info", ParameterEntry(strStridingInfo));
107 }
108 
109 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
111  FactoryMonitor m(*this, "Build", currentLevel);
112 
113  GlobalOrdinal domainGIDOffset = GetDomainGIDOffset(currentLevel);
114  BuildCoarseMap(currentLevel, domainGIDOffset);
115 }
116 
117 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
119  Level& currentLevel, const GlobalOrdinal domainGIDOffset) const {
120  RCP<Aggregates> aggregates = Get<RCP<Aggregates> >(currentLevel, "Aggregates");
121  GlobalOrdinal numAggs = aggregates->GetNumAggregates();
122  RCP<const Map> aggMap = aggregates->GetMap();
123 
124  RCP<MultiVector> nullspace = Get<RCP<MultiVector> >(currentLevel, "Nullspace");
125 
126  const size_t NSDim = nullspace->getNumVectors();
127  RCP<const Teuchos::Comm<int> > comm = aggMap->getComm();
128  const ParameterList& pL = GetParameterList();
129 
130  LocalOrdinal stridedBlockId = pL.get<LocalOrdinal>("Strided block id");
131 
132  // read in stridingInfo from parameter list and fill the internal member variable
133  // read the data only if the parameter "Striding info" exists and is non-empty
134  if (pL.isParameter("Striding info")) {
135  std::string strStridingInfo = pL.get<std::string>("Striding info");
136  if (strStridingInfo.empty() == false) {
137  Teuchos::Array<size_t> arrayVal = Teuchos::fromStringToArray<size_t>(strStridingInfo);
138  stridingInfo_ = Teuchos::createVector(arrayVal);
139  }
140  }
141 
142  CheckForConsistentStridingInformation(stridedBlockId, NSDim);
143 
144  GetOStream(Statistics2) << "domainGIDOffset: " << domainGIDOffset << " block size: " << getFixedBlockSize() << " stridedBlockId: " << stridedBlockId << std::endl;
145 
146  // number of coarse level dofs (fixed by number of aggregates and blocksize data)
147  GlobalOrdinal nCoarseDofs = numAggs * getFixedBlockSize();
148  GlobalOrdinal indexBase = aggMap->getIndexBase();
149 
150  RCP<const Map> coarseMap = StridedMapFactory::Build(aggMap->lib(),
152  nCoarseDofs,
153  indexBase,
154  stridingInfo_,
155  comm,
156  stridedBlockId,
157  domainGIDOffset);
158 
159  Set(currentLevel, "CoarseMap", coarseMap);
160 }
161 
162 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
164  Level& currentLevel) const {
166 
167  std::vector<GlobalOrdinal> domainGidOffsets;
168  domainGidOffsets.clear();
169  const ParameterList& pL = GetParameterList();
170  if (pL.isParameter("Domain GID offsets")) {
171  std::string strDomainGIDs = pL.get<std::string>("Domain GID offsets");
172  if (strDomainGIDs.empty() == false) {
173  Teuchos::Array<GlobalOrdinal> arrayVal = Teuchos::fromStringToArray<GlobalOrdinal>(strDomainGIDs);
174  domainGidOffsets = Teuchos::createVector(arrayVal);
175  if (currentLevel.GetLevelID() < Teuchos::as<int>(domainGidOffsets.size())) {
176  domainGidOffset = domainGidOffsets[currentLevel.GetLevelID()];
177  }
178  }
179  }
180 
181  return domainGidOffset;
182 }
183 
184 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
186  const LocalOrdinal stridedBlockId, const size_t nullspaceDimension) const {
187  // check for consistency of striding information with NSDim and nCoarseDofs
188  if (stridedBlockId == -1) {
189  // this means we have no real strided map but only a block map with constant blockSize "nullspaceDimension"
190  TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo_.size() > 1, Exceptions::RuntimeError, "MueLu::CoarseMapFactory::Build(): stridingInfo_.size() but must be one");
191  stridingInfo_.clear();
192  stridingInfo_.push_back(nullspaceDimension);
193  TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo_.size() != 1, Exceptions::RuntimeError, "MueLu::CoarseMapFactory::Build(): stridingInfo_.size() but must be one");
194 
195  } else {
196  // stridedBlockId > -1, set by user
197  TEUCHOS_TEST_FOR_EXCEPTION(stridedBlockId > Teuchos::as<LO>(stridingInfo_.size() - 1), Exceptions::RuntimeError, "MueLu::CoarseMapFactory::Build(): it is stridingInfo_.size() <= stridedBlockId_. error.");
198  size_t stridedBlockSize = stridingInfo_[stridedBlockId];
199  TEUCHOS_TEST_FOR_EXCEPTION(stridedBlockSize != nullspaceDimension, Exceptions::RuntimeError, "MueLu::CoarseMapFactory::Build(): dimension of strided block != nullspaceDimension. error.");
200  }
201 }
202 
203 } // namespace MueLu
204 
205 #endif /* MUELU_COARSEMAPFACTORY_DEF_HPP_ */
MueLu::DefaultLocalOrdinal LocalOrdinal
KOKKOS_INLINE_FUNCTION LO GetNumAggregates() 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)
const RCP< const Map > GetMap() const
returns (overlapping) map of aggregate/node distribution
virtual void BuildCoarseMap(Level &currentLevel, const GlobalOrdinal domainGIDOffset) const
Build the coarse map using the domain GID offset.
RCP< const ParameterList > GetValidParameterList() const override
Return a const parameter list of valid parameters that setParameterList() will accept.
Print even more statistics.
bool isParameter(const std::string &name) const
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
MueLu::DefaultGlobalOrdinal GlobalOrdinal
Class that holds all level-specific information.
Definition: MueLu_Level.hpp:99
virtual GlobalOrdinal GetDomainGIDOffset(Level &currentLevel) const
Extract domain GID offset from user data.
virtual void CheckForConsistentStridingInformation(LocalOrdinal stridedBlockId, const size_t nullspaceDimension) const
void Build(Level &currentLevel) const override
Build an object with this factory.
virtual void setStridingData(std::vector< size_t > stridingInfo)
setStridingData set striding vector for the domain DOF map (= coarse map), e.g. (2,1) for 2 velocity dofs and 1 pressure dof
int GetLevelID() const
Return level number.
Definition: MueLu_Level.cpp:76
Exception throws to report errors in the internal logical of the program.
void DeclareInput(Level &currentLevel) const override
Specifies the data that this class needs, and the factories that generate that data.