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