MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_MHDRAPFactory_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#ifndef MUELU_MHDRAPFACTORY_DEF_HPP
47#define MUELU_MHDRAPFACTORY_DEF_HPP
48
49#include <sstream>
50
51#include <Xpetra_Map.hpp>
52#include <Xpetra_MapFactory.hpp>
53#include <Xpetra_Matrix.hpp>
54#include <Xpetra_CrsMatrixWrap.hpp>
55#include <Xpetra_Vector.hpp>
56#include <Xpetra_VectorFactory.hpp>
57
59#include "MueLu_Monitor.hpp"
60
61namespace MueLu {
62
63 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
66
67 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
69
70 if (implicitTranspose_ == false)
71 {
72 Input(coarseLevel, "R" );
73 Input(coarseLevel, "RV");
74 Input(coarseLevel, "RP");
75 Input(coarseLevel, "RM");
76 }
77
78 Input(fineLevel, "A" );
79 Input(fineLevel, "A00");
80 Input(fineLevel, "A01");
81 Input(fineLevel, "A02");
82 Input(fineLevel, "A10");
83 Input(fineLevel, "A11");
84 Input(fineLevel, "A12");
85 Input(fineLevel, "A20");
86 Input(fineLevel, "A21");
87 Input(fineLevel, "A22");
88
89 Input(coarseLevel, "P" );
90 Input(coarseLevel, "PV");
91 Input(coarseLevel, "PP");
92 Input(coarseLevel, "PM");
93
94 }
95
96 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
97 void MHDRAPFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(Level &fineLevel, Level &coarseLevel) const { // FIXME make fineLevel const
98 {
99 FactoryMonitor m(*this, "Computing Ac", coarseLevel);
100
101 //
102 // Inputs: A, P
103 //
104
105 //DEBUG
106 //Teuchos::FancyOStream fout(*GetOStream(Runtime1));
107 //coarseLevel.print(fout,Teuchos::VERB_HIGH);
108
109
110 RCP<Matrix> A = Get< RCP<Matrix> >(fineLevel, "A" );
111 RCP<Matrix> A00 = Get< RCP<Matrix> >(fineLevel, "A00");
112 RCP<Matrix> A01 = Get< RCP<Matrix> >(fineLevel, "A01");
113 RCP<Matrix> A02 = Get< RCP<Matrix> >(fineLevel, "A02");
114 RCP<Matrix> A10 = Get< RCP<Matrix> >(fineLevel, "A10");
115 RCP<Matrix> A11 = Get< RCP<Matrix> >(fineLevel, "A11");
116 RCP<Matrix> A12 = Get< RCP<Matrix> >(fineLevel, "A12");
117 RCP<Matrix> A20 = Get< RCP<Matrix> >(fineLevel, "A20");
118 RCP<Matrix> A21 = Get< RCP<Matrix> >(fineLevel, "A21");
119 RCP<Matrix> A22 = Get< RCP<Matrix> >(fineLevel, "A22");
120
121 RCP<Matrix> P = Get< RCP<Matrix> >(coarseLevel, "P" );
122 RCP<Matrix> PV = Get< RCP<Matrix> >(coarseLevel, "PV");
123 RCP<Matrix> PP = Get< RCP<Matrix> >(coarseLevel, "PP");
124 RCP<Matrix> PM = Get< RCP<Matrix> >(coarseLevel, "PM");
125
126 //
127 // Build Ac = RAP
128 //
129
130 RCP<Matrix> AP;
131 RCP<Matrix> AP00;
132 RCP<Matrix> AP01;
133 RCP<Matrix> AP02;
134 RCP<Matrix> AP10;
135 RCP<Matrix> AP11;
136 RCP<Matrix> AP12;
137 RCP<Matrix> AP20;
138 RCP<Matrix> AP21;
139 RCP<Matrix> AP22;
140
141 {
142 SubFactoryMonitor subM(*this, "MxM: A x P", coarseLevel);
143
144 AP = Utils::Multiply(*A , false, *P , false, AP, GetOStream(Statistics2));
145 AP00 = Utils::Multiply(*A00, false, *PV, false, AP00, GetOStream(Statistics2));
146 AP01 = Utils::Multiply(*A01, false, *PP, false, AP01, GetOStream(Statistics2));
147 AP02 = Utils::Multiply(*A02, false, *PM, false, AP02, GetOStream(Statistics2));
148 AP10 = Utils::Multiply(*A10, false, *PV, false, AP10, GetOStream(Statistics2));
149 AP11 = Utils::Multiply(*A11, false, *PP, false, AP11, GetOStream(Statistics2));
150 AP12 = Utils::Multiply(*A12, false, *PM, false, AP12, GetOStream(Statistics2));
151 AP20 = Utils::Multiply(*A20, false, *PV, false, AP20, GetOStream(Statistics2));
152 AP21 = Utils::Multiply(*A21, false, *PP, false, AP21, GetOStream(Statistics2));
153 AP22 = Utils::Multiply(*A22, false, *PM, false, AP22, GetOStream(Statistics2));
154 }
155
156 RCP<Matrix> Ac;
157 RCP<Matrix> Ac00;
158 RCP<Matrix> Ac01;
159 RCP<Matrix> Ac02;
160 RCP<Matrix> Ac10;
161 RCP<Matrix> Ac11;
162 RCP<Matrix> Ac12;
163 RCP<Matrix> Ac20;
164 RCP<Matrix> Ac21;
165 RCP<Matrix> Ac22;
166
168 {
169 SubFactoryMonitor m2(*this, "MxM: P' x (AP) (implicit)", coarseLevel);
170
171 Ac = Utils::Multiply(*P , true, *AP , false, Ac, GetOStream(Statistics2));
172 Ac00 = Utils::Multiply(*PV, true, *AP00, false, Ac00, GetOStream(Statistics2));
173 Ac01 = Utils::Multiply(*PV, true, *AP01, false, Ac01, GetOStream(Statistics2));
174 Ac02 = Utils::Multiply(*PV, true, *AP02, false, Ac02, GetOStream(Statistics2));
175 Ac10 = Utils::Multiply(*PP, true, *AP10, false, Ac10, GetOStream(Statistics2));
176 Ac11 = Utils::Multiply(*PP, true, *AP11, false, Ac11, GetOStream(Statistics2));
177 Ac12 = Utils::Multiply(*PP, true, *AP12, false, Ac12, GetOStream(Statistics2));
178 Ac20 = Utils::Multiply(*PM, true, *AP20, false, Ac20, GetOStream(Statistics2));
179 Ac21 = Utils::Multiply(*PM, true, *AP21, false, Ac21, GetOStream(Statistics2));
180 Ac22 = Utils::Multiply(*PM, true, *AP22, false, Ac22, GetOStream(Statistics2));
181
182 }
183 else
184 {
185
186 SubFactoryMonitor m2(*this, "MxM: R x (AP) (explicit)", coarseLevel);
187
188 RCP<Matrix> R = Get< RCP<Matrix> >(coarseLevel, "R" );
189 RCP<Matrix> RV = Get< RCP<Matrix> >(coarseLevel, "RV");
190 RCP<Matrix> RP = Get< RCP<Matrix> >(coarseLevel, "RP");
191 RCP<Matrix> RM = Get< RCP<Matrix> >(coarseLevel, "RM");
192
193 Ac = Utils::Multiply(*R , false, *AP , false, Ac, GetOStream(Statistics2));
194 Ac00 = Utils::Multiply(*RV, false, *AP00, false, Ac00, GetOStream(Statistics2));
195 Ac01 = Utils::Multiply(*RV, false, *AP01, false, Ac01, GetOStream(Statistics2));
196 Ac02 = Utils::Multiply(*RV, false, *AP02, false, Ac02, GetOStream(Statistics2));
197 Ac10 = Utils::Multiply(*RP, false, *AP10, false, Ac10, GetOStream(Statistics2));
198 Ac11 = Utils::Multiply(*RP, false, *AP11, false, Ac11, GetOStream(Statistics2));
199 Ac12 = Utils::Multiply(*RP, false, *AP12, false, Ac12, GetOStream(Statistics2));
200 Ac20 = Utils::Multiply(*RM, false, *AP20, false, Ac20, GetOStream(Statistics2));
201 Ac21 = Utils::Multiply(*RM, false, *AP21, false, Ac21, GetOStream(Statistics2));
202 Ac22 = Utils::Multiply(*RM, false, *AP22, false, Ac22, GetOStream(Statistics2));
203
204 }
205 // FINISHED MAKING COARSE BLOCKS
206
207 Set(coarseLevel, "A" , Ac );
208 Set(coarseLevel, "A00", Ac00);
209 Set(coarseLevel, "A01", Ac01);
210 Set(coarseLevel, "A02", Ac02);
211 Set(coarseLevel, "A10", Ac10);
212 Set(coarseLevel, "A11", Ac11);
213 Set(coarseLevel, "A12", Ac12);
214 Set(coarseLevel, "A20", Ac20);
215 Set(coarseLevel, "A21", Ac21);
216 Set(coarseLevel, "A22", Ac22);
217
218
219 }
220
221
222 }
223
224
225/*
226 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
227 std::string MHDRAPFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::PerfUtils::PrintMatrixInfo(const Matrix & Ac, const std::string & msgTag) {
228 std::stringstream ss(std::stringstream::out);
229 ss << msgTag
230 << " # global rows = " << Ac.getGlobalNumRows()
231 << ", estim. global nnz = " << Ac.getGlobalNumEntries()
232 << std::endl;
233 return ss.str();
234 }
235*/
236
237 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
238 std::string MHDRAPFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::PrintLoadBalancingInfo(const Matrix & Ac, const std::string & msgTag) {
239 std::stringstream ss(std::stringstream::out);
240
241 // TODO: provide a option to skip this (to avoid global communication)
242 // TODO: skip if nproc == 1
243
244 //nonzero imbalance
245 size_t numMyNnz = Ac.getLocalNumEntries();
246 GO maxNnz, minNnz;
247 RCP<const Teuchos::Comm<int> > comm = Ac.getRowMap()->getComm();
248 MueLu_maxAll(comm,(GO)numMyNnz,maxNnz);
249 //min nnz over all proc (disallow any processors with 0 nnz)
250 MueLu_minAll(comm, (GO)((numMyNnz > 0) ? numMyNnz : maxNnz), minNnz);
251 double imbalance = ((double) maxNnz) / minNnz;
252
253 size_t numMyRows = Ac.getLocalNumRows();
254 //Check whether Ac is spread over more than one process.
255 GO numActiveProcesses=0;
256 MueLu_sumAll(comm, (GO)((numMyRows > 0) ? 1 : 0), numActiveProcesses);
257
258 //min, max, and avg # rows per proc
259 GO minNumRows, maxNumRows;
260 double avgNumRows;
261 MueLu_maxAll(comm, (GO)numMyRows, maxNumRows);
262 MueLu_minAll(comm, (GO)((numMyRows > 0) ? numMyRows : maxNumRows), minNumRows);
263 assert(numActiveProcesses > 0);
264 avgNumRows = Ac.getGlobalNumRows() / numActiveProcesses;
265
266 ss << msgTag << " # processes with rows = " << numActiveProcesses << std::endl;
267 ss << msgTag << " min # rows per proc = " << minNumRows << ", max # rows per proc = " << maxNumRows << ", avg # rows per proc = " << avgNumRows << std::endl;
268 ss << msgTag << " nonzero imbalance = " << imbalance << std::endl;
269
270 return ss.str();
271 }
272
273
274} //namespace MueLu
275
276#define MUELU_MHDRAPFACTORY_SHORT
277#endif // MUELU_MHDRAPFACTORY_DEF_HPP
278
#define MueLu_maxAll(rcpComm, in, out)
#define MueLu_sumAll(rcpComm, in, out)
#define MueLu_minAll(rcpComm, in, out)
Timer to be used in factories. Similar to Monitor but with additional timers.
void Input(Level &level, const std::string &varName) const
T Get(Level &level, const std::string &varName) const
void Set(Level &level, const std::string &varName, const T &data) const
Class that holds all level-specific information.
void Build(Level &fineLevel, Level &coarseLevel) const
Build an object with this factory.
static std::string PrintLoadBalancingInfo(const Matrix &Ac, const std::string &msgTag)
bool implicitTranspose_
If true, the action of the restriction operator action is implicitly defined by the transpose of the ...
void DeclareInput(Level &fineLevel, Level &coarseLevel) const
Input.
Timer to be used in factories. Similar to SubMonitor but adds a timer level by level.
Teuchos::FancyOStream & GetOStream(MsgType type, int thisProcRankOnly=0) const
Get an output stream for outputting the input message type.
Namespace for MueLu classes and methods.
@ Statistics2
Print even more statistics.