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  public:
70 
71 
74 
76  virtual ~TwoLevelFactoryBase() {}
77 
79 
81 
82 
88  virtual void DeclareInput(Level& fineLevel, Level& coarseLevel) const = 0;
89 
91  virtual void CallDeclareInput(Level& requestedLevel) const {
92  if (requestedLevel.GetPreviousLevel() == Teuchos::null) {
93  std::ostringstream errStr;
94  errStr << "LevelID = " << requestedLevel.GetLevelID();
95  throw Exceptions::DependencyError(errStr.str());
96  }
97  DeclareInput(*requestedLevel.GetPreviousLevel(), requestedLevel);
98  }
99 
101 
103 
104 
106  virtual void Build(Level& fineLevel, Level& coarseLevel) const = 0;
107 
109  virtual void CallBuild(Level& requestedLevel) const {
110  int levelID = requestedLevel.GetLevelID();
111 
112 #ifdef HAVE_MUELU_DEBUG
113  // We cannot call Build method twice for the same level, but we can call it multiple times for different levels
114  TEUCHOS_TEST_FOR_EXCEPTION((multipleCallCheck_ == ENABLED) && (multipleCallCheckGlobal_ == ENABLED) && (lastLevelID_ == levelID),
116  this->ShortClassName() << "::Build() called twice for the same level (levelID=" << levelID
117  << "). This is likely due to a configuration error, or calling hierarchy setup multiple times "
118  << "without resetting debug info through FactoryManager::ResetDebugData().");
119  if (multipleCallCheck_ == FIRSTCALL)
120  multipleCallCheck_ = ENABLED;
121 
122  lastLevelID_ = levelID;
123 #endif
124  TEUCHOS_TEST_FOR_EXCEPTION(requestedLevel.GetPreviousLevel() == Teuchos::null, Exceptions::RuntimeError, "LevelID = " << levelID);
125 
126  RCP<const Teuchos::Comm<int> > comm = requestedLevel.GetComm();
127  if (comm.is_null()) {
128  // Some factories are called before we constructed Ac, and therefore,
129  // before we set the level communicator. For such factories we can get
130  // the comm from the previous level, as all processes go there
131  RCP<Level>& prevLevel = requestedLevel.GetPreviousLevel();
132  if (!prevLevel.is_null())
133  comm = prevLevel->GetComm();
134  }
135 
136  int oldRank = -1;
137  if (!comm.is_null())
138  oldRank = SetProcRankVerbose(comm->getRank());
139 
140  // Synchronization timer
141  std::string syncTimer = this->ShortClassName() + ": Build sync (level=" + toString(requestedLevel.GetLevelID()) + ")";
142  if (this->timerSync_ && !comm.is_null()) {
143  TimeMonitor timer(*this, syncTimer);
144  comm->barrier();
145  }
146 
147  Build(*requestedLevel.GetPreviousLevel(), requestedLevel);
148 
149  if (this->timerSync_ && !comm.is_null()) {
150  TimeMonitor timer(*this, syncTimer);
151  comm->barrier();
152  }
153 
154  if (IsPrint(Test1))
155  GetOStream(Test1) << *RemoveFactoriesFromList(GetParameterList()) << std::endl;
156  else
157  RemoveFactoriesFromList(GetParameterList())->print(GetOStream(Test0), Teuchos::ParameterList::PrintOptions().indent(0).showFlags(true).showDefault(false));
158 
159  if (oldRank != -1)
160  SetProcRankVerbose(oldRank);
161  }
162 
164 
165 }; // class TwoLevelFactoryBase
166 
167 } // namespace MueLu
168 
169 #define MUELU_TWOLEVELFACTORY_SHORT
170 #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.
Print factory calls.
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
bool IsPrint(MsgType type, int thisProcRankOnly=-1) const
Find out whether we need to print out information for a specific message type.
virtual ~TwoLevelFactoryBase()
Destructor.
virtual void Build(Level &fineLevel, Level &coarseLevel) const =0
Build an object with this factory.
Print used parameters.
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