MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MueLu_AmalgamationInfo_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_AmalgamationInfo_def.hpp
48  *
49  * Created on: Mar 28, 2012
50  * Author: wiesner
51  */
52 
53 #ifndef MUELU_AMALGAMATIONINFO_DEF_HPP_
54 #define MUELU_AMALGAMATIONINFO_DEF_HPP_
55 
56 #include <Xpetra_MapFactory.hpp>
57 #include <Xpetra_Vector.hpp>
58 
60 #include "MueLu_Exceptions.hpp"
61 
62 #include "MueLu_Aggregates.hpp"
63 
64 namespace MueLu {
65 
66 template <class LocalOrdinal, class GlobalOrdinal, class Node>
70  Teuchos::ArrayRCP<GlobalOrdinal> &aggToRowMap) const {
71  UnamalgamateAggregates(aggregates.GetMap(),
72  aggregates.GetProcWinner(),
73  aggregates.GetVertex2AggId(),
74  aggregates.GetNumAggregates(),
75  aggStart,
76  aggToRowMap);
77 
78 } // UnamalgamateAggregates
79 
80 template <class LocalOrdinal, class GlobalOrdinal, class Node>
83  const RCP<LOVector> &procWinnerVec,
84  const RCP<LOMultiVector> &vertex2AggIdVec,
85  const GO numAggregates,
87  Teuchos::ArrayRCP<GlobalOrdinal> &aggToRowMap) const {
88  int myPid = nodeMap->getComm()->getRank();
89  Teuchos::ArrayView<const GO> nodeGlobalElts = nodeMap->getLocalElementList();
90  Teuchos::ArrayRCP<LO> procWinner = procWinnerVec->getDataNonConst(0);
91  Teuchos::ArrayRCP<LO> vertex2AggId = vertex2AggIdVec->getDataNonConst(0);
92  const LO size = procWinner.size();
93 
94  std::vector<LO> sizes(numAggregates);
95  if (stridedblocksize_ == 1) {
96  for (LO lnode = 0; lnode < size; ++lnode) {
97  LO myAgg = vertex2AggId[lnode];
98  if (procWinner[lnode] == myPid)
99  sizes[myAgg] += 1;
100  }
101  } else {
102  for (LO lnode = 0; lnode < size; ++lnode) {
103  LO myAgg = vertex2AggId[lnode];
104  if (procWinner[lnode] == myPid) {
105  GO gnodeid = nodeGlobalElts[lnode];
106  for (LocalOrdinal k = 0; k < stridedblocksize_; k++) {
107  GlobalOrdinal gDofIndex = ComputeGlobalDOF(gnodeid, k);
108  if (columnMap_->isNodeGlobalElement(gDofIndex))
109  sizes[myAgg] += 1;
110  }
111  }
112  }
113  }
114  aggStart = ArrayRCP<LO>(numAggregates + 1, 0);
115  aggStart[0] = Teuchos::ScalarTraits<LO>::zero();
116  for (GO i = 0; i < numAggregates; ++i) {
117  aggStart[i + 1] = aggStart[i] + sizes[i];
118  }
119  aggToRowMap = ArrayRCP<GO>(aggStart[numAggregates], 0);
120 
121  // count, how many dofs have been recorded for each aggregate so far
122  Array<LO> numDofs(numAggregates, 0); // empty array with number of Dofs for each aggregate
123 
124  if (stridedblocksize_ == 1) {
125  for (LO lnode = 0; lnode < size; ++lnode) {
126  LO myAgg = vertex2AggId[lnode];
127  if (procWinner[lnode] == myPid) {
128  aggToRowMap[aggStart[myAgg] + numDofs[myAgg]] = ComputeGlobalDOF(nodeGlobalElts[lnode]);
129  ++(numDofs[myAgg]);
130  }
131  }
132  } else {
133  for (LO lnode = 0; lnode < size; ++lnode) {
134  LO myAgg = vertex2AggId[lnode];
135 
136  if (procWinner[lnode] == myPid) {
137  GO gnodeid = nodeGlobalElts[lnode];
138  for (LocalOrdinal k = 0; k < stridedblocksize_; k++) {
139  GlobalOrdinal gDofIndex = ComputeGlobalDOF(gnodeid, k);
140  if (columnMap_->isNodeGlobalElement(gDofIndex)) {
141  aggToRowMap[aggStart[myAgg] + numDofs[myAgg]] = gDofIndex;
142  ++(numDofs[myAgg]);
143  }
144  }
145  }
146  }
147  }
148  // todo plausibility check: entry numDofs[k] == aggToRowMap[k].size()
149 
150 } // UnamalgamateAggregates
151 
152 template <class LocalOrdinal, class GlobalOrdinal, class Node>
155  Teuchos::ArrayRCP<LO> &aggStart,
156  Teuchos::ArrayRCP<LO> &aggToRowMap) const {
157  UnamalgamateAggregatesLO(aggregates.GetMap(),
158  aggregates.GetProcWinner(),
159  aggregates.GetVertex2AggId(),
160  aggregates.GetNumAggregates(),
161  aggStart,
162  aggToRowMap);
163 }
164 
165 template <class LocalOrdinal, class GlobalOrdinal, class Node>
168  const RCP<LOVector> &procWinnerVec,
169  const RCP<LOMultiVector> &vertex2AggIdVec,
170  const GO numAggregates,
171  Teuchos::ArrayRCP<LO> &aggStart,
172  Teuchos::ArrayRCP<LO> &aggToRowMap) const {
173  int myPid = nodeMap->getComm()->getRank();
174  Teuchos::ArrayView<const GO> nodeGlobalElts = nodeMap->getLocalElementList();
175 
176  Teuchos::ArrayRCP<LO> procWinner = procWinnerVec->getDataNonConst(0);
177  Teuchos::ArrayRCP<LO> vertex2AggId = vertex2AggIdVec->getDataNonConst(0);
178 
179  // FIXME: Do we need to compute size here? Or can we use existing?
180  const LO size = procWinner.size();
181 
182  std::vector<LO> sizes(numAggregates);
183  if (stridedblocksize_ == 1) {
184  for (LO lnode = 0; lnode < size; lnode++)
185  if (procWinner[lnode] == myPid)
186  sizes[vertex2AggId[lnode]]++;
187  } else {
188  for (LO lnode = 0; lnode < size; lnode++)
189  if (procWinner[lnode] == myPid) {
190  GO nodeGID = nodeGlobalElts[lnode];
191 
192  for (LO k = 0; k < stridedblocksize_; k++) {
193  GO GID = ComputeGlobalDOF(nodeGID, k);
194  if (columnMap_->isNodeGlobalElement(GID))
195  sizes[vertex2AggId[lnode]]++;
196  }
197  }
198  }
199 
200  aggStart = ArrayRCP<LO>(numAggregates + 1); // FIXME: useless initialization with zeros
201  aggStart[0] = 0;
202  for (GO i = 0; i < numAggregates; i++)
203  aggStart[i + 1] = aggStart[i] + sizes[i];
204 
205  aggToRowMap = ArrayRCP<LO>(aggStart[numAggregates], 0);
206 
207  // count, how many dofs have been recorded for each aggregate so far
208  Array<LO> numDofs(numAggregates, 0); // empty array with number of DOFs for each aggregate
209  if (stridedblocksize_ == 1) {
210  for (LO lnode = 0; lnode < size; ++lnode)
211  if (procWinner[lnode] == myPid) {
212  LO myAgg = vertex2AggId[lnode];
213  aggToRowMap[aggStart[myAgg] + numDofs[myAgg]] = lnode;
214  numDofs[myAgg]++;
215  }
216  } else {
217  for (LO lnode = 0; lnode < size; ++lnode)
218  if (procWinner[lnode] == myPid) {
219  LO myAgg = vertex2AggId[lnode];
220  GO nodeGID = nodeGlobalElts[lnode];
221 
222  for (LO k = 0; k < stridedblocksize_; k++) {
223  GO GID = ComputeGlobalDOF(nodeGID, k);
224  if (columnMap_->isNodeGlobalElement(GID)) {
225  aggToRowMap[aggStart[myAgg] + numDofs[myAgg]] = lnode * stridedblocksize_ + k;
226  numDofs[myAgg]++;
227  }
228  }
229  }
230  }
231  // todo plausibility check: entry numDofs[k] == aggToRowMap[k].size()
232 
233 } // UnamalgamateAggregatesLO
234 
235 template <class LocalOrdinal, class GlobalOrdinal, class Node>
237  const VerbLevel verbLevel) const {
238  if (!(verbLevel & Debug))
239  return;
240 
241  out << "AmalgamationInfo -- Striding information:"
242  << "\n fullBlockSize = " << fullblocksize_
243  << "\n blockID = " << blockid_
244  << "\n stridingOffset = " << nStridedOffset_
245  << "\n stridedBlockSize = " << stridedblocksize_
246  << "\n indexBase = " << indexBase_
247  << std::endl;
248 
249  out << "AmalgamationInfo -- DOFs to nodes mapping:\n"
250  << " Mapping of row DOFs to row nodes:" << *rowTranslation_()
251  << "\n\n Mapping of column DOFs to column nodes:" << *colTranslation_()
252  << std::endl;
253 
254  out << "AmalgamationInfo -- row node map:" << std::endl;
255  nodeRowMap_->describe(out, Teuchos::VERB_EXTREME);
256 
257  out << "AmalgamationInfo -- column node map:" << std::endl;
258  nodeColMap_->describe(out, Teuchos::VERB_EXTREME);
259 }
260 
262 
263 template <class LocalOrdinal, class GlobalOrdinal, class Node>
266  return ComputeUnamalgamatedImportDofMap(aggregates.GetMap());
267 }
268 
269 template <class LocalOrdinal, class GlobalOrdinal, class Node>
272  Teuchos::RCP<std::vector<GO> > myDofGids = Teuchos::rcp(new std::vector<GO>);
273  Teuchos::ArrayView<const GO> gEltList = nodeMap->getLocalElementList();
274  LO nodeElements = Teuchos::as<LO>(nodeMap->getLocalNumElements());
275  if (stridedblocksize_ == 1) {
276  for (LO n = 0; n < nodeElements; n++) {
277  GlobalOrdinal gDofIndex = ComputeGlobalDOF(gEltList[n]);
278  myDofGids->push_back(gDofIndex);
279  }
280  } else {
281  for (LO n = 0; n < nodeElements; n++) {
282  for (LocalOrdinal k = 0; k < stridedblocksize_; k++) {
283  GlobalOrdinal gDofIndex = ComputeGlobalDOF(gEltList[n], k);
284  if (columnMap_->isNodeGlobalElement(gDofIndex))
285  myDofGids->push_back(gDofIndex);
286  }
287  }
288  }
289 
290  Teuchos::ArrayRCP<GO> arr_myDofGids = Teuchos::arcp(myDofGids);
291  Teuchos::RCP<Map> importDofMap = MapFactory::Build(nodeMap->lib(), Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(), arr_myDofGids(), nodeMap->getIndexBase(), nodeMap->getComm());
292  return importDofMap;
293 }
294 
296 
297 template <class LocalOrdinal, class GlobalOrdinal, class Node>
299  ComputeGlobalDOF(GlobalOrdinal const &gNodeID, LocalOrdinal const &k) const {
300  // here, the assumption is, that the node map has the same indexBase as the dof map
301  // this is the node map index base this is the dof map index base
302  GlobalOrdinal gDofIndex = offset_ + (gNodeID - indexBase_) * fullblocksize_ + nStridedOffset_ + k + indexBase_;
303  return gDofIndex;
304 }
305 
306 template <class LocalOrdinal, class GlobalOrdinal, class Node>
308  LocalOrdinal lDofIndex = lNodeID * fullblocksize_ + k;
309  return lDofIndex;
310 }
311 
312 template <class LocalOrdinal, class GlobalOrdinal, class Node>
314  return (ldofID - ldofID % fullblocksize_) / fullblocksize_;
315 }
316 
317 } // namespace MueLu
318 
319 #endif /* MUELU_AMALGAMATIONINFO_DEF_HPP_ */
LO ComputeLocalNode(LocalOrdinal const &ldofID) const
MueLu::DefaultLocalOrdinal LocalOrdinal
const RCP< LOVector > & GetProcWinner() const
Returns constant vector that maps local node IDs to owning processor IDs.
Container class for aggregation information.
KOKKOS_INLINE_FUNCTION LO GetNumAggregates() const
GlobalOrdinal GO
void UnamalgamateAggregates(const Aggregates &aggregates, Teuchos::ArrayRCP< LocalOrdinal > &aggStart, Teuchos::ArrayRCP< GlobalOrdinal > &aggToRowMap) const
UnamalgamateAggregates.
Print additional debugging information.
void UnamalgamateAggregatesLO(const Aggregates &aggregates, Teuchos::ArrayRCP< LocalOrdinal > &aggStart, Teuchos::ArrayRCP< LO > &aggToRowMap) const
const RCP< const Map > GetMap() const
returns (overlapping) map of aggregate/node distribution
LocalOrdinal LO
size_type size() const
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
GO ComputeGlobalDOF(GO const &gNodeID, LO const &k=0) const
ComputeGlobalDOF.
MueLu::DefaultGlobalOrdinal GlobalOrdinal
void print(Teuchos::FancyOStream &out, const VerbLevel verbLevel=Default) const
Print the object with some verbosity level to an FancyOStream object.
Teuchos::RCP< Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > ComputeUnamalgamatedImportDofMap(const Aggregates &aggregates) const
ComputeUnamalgamatedImportDofMap build overlapping dof row map from aggregates needed for overlapping...
const RCP< LOMultiVector > & GetVertex2AggId() const
Returns constant vector that maps local node IDs to local aggregates IDs.
LO ComputeLocalDOF(LocalOrdinal const &lNodeID, LocalOrdinal const &k) const
ComputeLocalDOF return locbal dof id associated with local node id lNodeID and dof index k...