MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MueLu_TwoLevelFactoryBase.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_TWOLEVELFACTORY_HPP
47 #define MUELU_TWOLEVELFACTORY_HPP
48 
49 #include "MueLu_ConfigDefs.hpp"
50 
51 #include "MueLu_Factory.hpp"
52 #include "MueLu_Level.hpp"
53 #include "MueLu_TimeMonitor.hpp"
54 #include "MueLu_Utilities.hpp"
55 
56 namespace MueLu {
57 
67  class TwoLevelFactoryBase : public Factory {
68 
69  public:
70 
72 
73 
76 
79  { }
80 
82 
84 
85 
91  virtual void DeclareInput(Level &fineLevel, Level &coarseLevel) const = 0;
92 
94  virtual void CallDeclareInput(Level & requestedLevel) const {
95  if (requestedLevel.GetPreviousLevel() == Teuchos::null) {
96  std::ostringstream errStr;
97  errStr << "LevelID = " << requestedLevel.GetLevelID();
98  throw Exceptions::DependencyError(errStr.str());
99  }
100  DeclareInput(*requestedLevel.GetPreviousLevel(), requestedLevel);
101  }
102 
104 
106 
107 
108 
110  virtual void Build(Level & fineLevel, Level & coarseLevel) const = 0;
111 
113  virtual void CallBuild(Level& requestedLevel) const {
114  int levelID = requestedLevel.GetLevelID();
115 
116 #ifdef HAVE_MUELU_DEBUG
117  // We cannot call Build method twice for the same level, but we can call it multiple times for different levels
118  TEUCHOS_TEST_FOR_EXCEPTION((multipleCallCheck_ == ENABLED) && (multipleCallCheckGlobal_ == ENABLED) && (lastLevelID_ == levelID),
120  this->ShortClassName() << "::Build() called twice for the same level (levelID=" << levelID
121  << "). This is likely due to a configuration error, or calling hierarchy setup multiple times "
122  << "without resetting debug info through FactoryManager::ResetDebugData().");
123  if (multipleCallCheck_ == FIRSTCALL)
124  multipleCallCheck_ = ENABLED;
125 
126  lastLevelID_ = levelID;
127 #endif
128  TEUCHOS_TEST_FOR_EXCEPTION(requestedLevel.GetPreviousLevel() == Teuchos::null, Exceptions::RuntimeError, "LevelID = " << levelID);
129 
130  RCP<const Teuchos::Comm<int> > comm = requestedLevel.GetComm();
131  if (comm.is_null()) {
132  // Some factories are called before we constructed Ac, and therefore,
133  // before we set the level communicator. For such factories we can get
134  // the comm from the previous level, as all processes go there
135  RCP<Level>& prevLevel = requestedLevel.GetPreviousLevel();
136  if (!prevLevel.is_null())
137  comm = prevLevel->GetComm();
138  }
139 
140  int oldRank = -1;
141  if (!comm.is_null())
142  oldRank = SetProcRankVerbose(comm->getRank());
143 
144  // Synchronization timer
145  std::string syncTimer = this->ShortClassName() + ": Build sync (level=" + toString(requestedLevel.GetLevelID()) + ")";
146  if (this->timerSync_ && !comm.is_null()) {
147  TimeMonitor timer(*this, syncTimer);
148  comm->barrier();
149  }
150 
151  Build(*requestedLevel.GetPreviousLevel(), requestedLevel);
152 
153  if (this->timerSync_ && !comm.is_null()) {
154  TimeMonitor timer(*this, syncTimer);
155  comm->barrier();
156  }
157 
158  GetOStream(Test) << *RemoveFactoriesFromList(GetParameterList()) << std::endl;
159 
160  if (oldRank != -1)
161  SetProcRankVerbose(oldRank);
162  }
163 
165 
166  }; //class TwoLevelFactoryBase
167 
168 
169 } //namespace MueLu
170 
171 #define MUELU_TWOLEVELFACTORY_SHORT
172 #endif //ifndef MUELU_TWOLEVELFACTORY_HPP
virtual const Teuchos::ParameterList & GetParameterList() const
RCP< Level > & GetPreviousLevel()
Previous level.
Teuchos::FancyOStream & GetOStream(MsgType type, int thisProcRankOnly=0) const
Get an output stream for outputting the input message type.
std::string toString(const T &what)
Little helper function to convert non-string types to strings.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Base class for factories that use two levels (fineLevel and coarseLevel).
virtual void CallBuild(Level &requestedLevel) const
Integrates Teuchos::TimeMonitor with MueLu verbosity system.
virtual std::string ShortClassName() const
Return the class name of the object, without template parameters and without namespace.
Class that holds all level-specific information.
Definition: MueLu_Level.hpp:99
virtual ~TwoLevelFactoryBase()
Destructor.
virtual void Build(Level &fineLevel, Level &coarseLevel) const =0
Build an object with this factory.
int SetProcRankVerbose(int procRank) const
Set proc rank used for printing.
virtual void CallDeclareInput(Level &requestedLevel) const
int GetLevelID() const
Return level number.
Definition: MueLu_Level.cpp:76
Exception throws to report errors in the internal logical of the program.
RCP< const Teuchos::Comm< int > > GetComm() const
virtual void DeclareInput(Level &fineLevel, Level &coarseLevel) const =0
Input.
Exception throws to report data dependency problems between factories.
bool is_null() const