MueLu  Version of the Day
MueLu_VariableContainer.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_VARIABLECONTAINER_HPP
47 #define MUELU_VARIABLECONTAINER_HPP
48 
49 #include <map>
50 
51 #include <Teuchos_TypeNameTraits.hpp>
52 
53 #include <Xpetra_Matrix.hpp>
54 #include <Xpetra_Operator.hpp>
55 
56 #include "MueLu_ConfigDefs.hpp"
57 #include "MueLu_BaseClass.hpp"
58 
59 #include "MueLu_Exceptions.hpp"
61 #include "MueLu_KeepType.hpp"
62 
63 namespace MueLu {
64 
73  class VariableContainer : public BaseClass {
74  private:
75  // Motivated by Teuchos_any.hpp
76  class DataBase {
77  public:
78  virtual ~DataBase() {}
79  virtual const std::type_info& type() const = 0;
80  virtual std::string typeName() const = 0;
81  };
82 
83  template<typename T>
84  class Data : public DataBase {
85  public:
86  Data(const T& data) : data_(data) {}
87  const std::type_info& type() const { return typeid(T); }
88  std::string typeName() const { return Teuchos::TypeNameTraits<T>::name(); }
89  T data_;
90  };
91 
92  template<typename T>
93  struct Getter {
94  static T& get(DataBase* data_, DataBase*& datah_) {
95  if ((data_ == NULL) || (data_->type() != typeid(T))) // NVR added guard to avoid determining typeName unless we will use it
96  {
97  const std::string typeName = Teuchos::TypeNameTraits<T>::name(); // calls Teuchos::demangleName(), which can be expensive
98  TEUCHOS_TEST_FOR_EXCEPTION(data_ == NULL, Teuchos::bad_any_cast,
99  "Error, cast to type Data<" << typeName << "> failed since the content is NULL");
100 
101  TEUCHOS_TEST_FOR_EXCEPTION(data_->type() != typeid(T), Teuchos::bad_any_cast,
102  "Error, cast to type Data<" << typeName << "> failed since the actual underlying type is "
103  "\'" << data_->typeName() << "!");
104  }
105 
106  Data<T>* data = dynamic_cast<Data<T>*>(data_);
107  if (!data) // NVR added guard to avoid determining typeName unless we will use it
108  {
109  const std::string typeName = Teuchos::TypeNameTraits<T>::name(); // calls Teuchos::demangleName(), which can be expensive
110  TEUCHOS_TEST_FOR_EXCEPTION(!data, std::logic_error,
111  "Error, cast to type Data<" << typeName << "> failed but should not have and the actual underlying type is "
112  "\'" << data_->typeName() << "! The problem might be related to incompatible RTTI systems in static and shared libraries!");
113  }
114  return data->data_;
115  }
116  };
117 
118 
119  public:
120  typedef std::map<const FactoryBase*,int> request_container;
121 
122  private:
124  mutable
126  bool available_;
129  int count_;
130 
132 
133  public:
135 
136 
138  VariableContainer() : data_(NULL), datah_(NULL), available_(false), keep_(false), count_(0) { }
140  delete data_; data_ = NULL;
141  delete datah_; datah_ = NULL;
142  }
143 
145 
147 
148 
150  template<typename T>
151  void SetData(const T& entry) {
152  delete data_;
153  delete datah_;
154  data_ = new Data<T>(entry);
155  datah_ = NULL;
156  available_ = true;
157  }
158 
161  template<typename T>
162  const T& GetData() const {
163  return Getter<T>::get(data_, datah_);
164  }
165 
168  template<typename T>
169  T& GetData() {
170  return Getter<T>::get(data_, datah_);
171  }
172 
173  std::string GetTypeName() {
174  if (data_ == NULL)
175  return std::string("");
176  return data_->typeName();
177  }
178 
180  // if SetData has been called before
181  bool IsAvailable() const { return available_; }
182 
184 
186 
187 
189  void Request(const FactoryBase* reqFactory) {
190  request_container::iterator it = requests_.find(reqFactory);
191  if (it == requests_.end())
192  requests_[reqFactory] = 1;
193  else
194  (it->second)++;
195  count_++; // increment request counter
196  }
197 
199  void Release(const FactoryBase* reqFactory) {
200  request_container::iterator it = requests_.find(reqFactory);
201  TEUCHOS_TEST_FOR_EXCEPTION(it == requests_.end(), Exceptions::RuntimeError, "MueLu::VariableContainer::Release(): "
202  "cannot call Release if factory has not been requested before by factory " << reqFactory);
203  if (--(it->second) == 0)
204  requests_.erase(it);
205  count_--;
206  }
207 
209  int NumRequests(const FactoryBase* reqFactory) const {
210  request_container::const_iterator it = requests_.find(reqFactory);
211  return (it != requests_.end()) ? it->second : 0;
212  }
213 
215  int NumAllRequests() const { return count_; }
216 
218  bool IsRequested(const FactoryBase* reqFactory) const { return (NumRequests(reqFactory) > 0); }
219 
221  bool IsRequested() const { return (count_ > 0); }
222 
223  const request_container& Requests() const { return requests_; }
225 
227 
228 
230  bool IsKept(KeepType keep) const { return keep_ & keep; }
231 
233  void AddKeepFlag(KeepType keep = UserData) { keep_ |= keep; }
234 
236  void RemoveKeepFlag(KeepType keep = UserData) { keep_ = keep_ & (keep_ ^ keep); }
237 
239  KeepType GetKeepFlag() const { return keep_; }
240 
242  };
243 
244 
245  template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
246  struct VariableContainer::Getter<Teuchos::RCP<Xpetra::Operator<Scalar,LocalOrdinal,GlobalOrdinal,Node> > > {
247  typedef Xpetra::Operator<Scalar,LocalOrdinal,GlobalOrdinal,Node> Operator;
248  typedef Xpetra::Matrix <Scalar,LocalOrdinal,GlobalOrdinal,Node> Matrix;
249 
250  static Teuchos::RCP<Operator>& get(DataBase* data_, DataBase*& datah_) {
251  typedef Teuchos::RCP<Operator> TO;
252  typedef Teuchos::RCP<Matrix> TM;
253 
254  if (data_ == NULL) // NVR added guard to avoid unnecessary call to TypeNameTraits<TO>::name(), which calls Teuchos::demangleName(), which can be expensive
255  {
256  TEUCHOS_TEST_FOR_EXCEPTION(data_ == NULL, Teuchos::bad_any_cast,
257  "Error, cast to type Data<" << Teuchos::TypeNameTraits<TO>::name() << "> failed since the content is NULL");
258  }
259  if (data_->type() == typeid(TO)) {
260  Data<TO>* data = dynamic_cast<Data<TO>*>(data_);
261  if (!data) // NVR added guard to avoid unnecessary call to TypeNameTraits<TO>::name(), which calls Teuchos::demangleName(), which can be expensive
262  {
263  TEUCHOS_TEST_FOR_EXCEPTION(!data, std::logic_error,
264  "Error, cast to type Data<" << Teuchos::TypeNameTraits<TO>::name() << "> failed but should not have and the actual underlying type is "
265  "\'" << data_->typeName() << "! The problem might be related to incompatible RTTI systems in static and shared libraries!");
266  }
267  return data->data_;
268  }
269 
270  if (data_->type() != typeid(TM)) // NVR added guard to avoid unnecessary call to TypeNameTraits<TO>::name(), which calls Teuchos::demangleName(), which can be expensive
271  {
272  TEUCHOS_TEST_FOR_EXCEPTION(data_->type() != typeid(TM), Teuchos::bad_any_cast,
273  "Error, cast to type Data<" << Teuchos::TypeNameTraits<TM>::name() << "> failed since the actual underlying type is "
274  "\'" << data_->typeName() << "!");
275  }
276  Data<TM>* data = dynamic_cast<Data<TM>*>(data_);
277  if (!data) // NVR added guard to avoid unnecessary call to TypeNameTraits<TO>::name(), which calls Teuchos::demangleName(), which can be expensive
278  {
279  TEUCHOS_TEST_FOR_EXCEPTION(!data, std::logic_error,
280  "Error, cast to type Data<" << Teuchos::TypeNameTraits<TM>::name() << "> failed but should not have and the actual underlying type is "
281  "\'" << data_->typeName() << "! The problem might be related to incompatible RTTI systems in static and shared libraries!");
282  }
283  if (datah_ == NULL)
284  datah_ = new Data<TO>(Teuchos::rcp_dynamic_cast<Operator>(data->data_));
285  Data<TO>* datah = dynamic_cast<Data<TO>*>(datah_);
286 
287  if (!datah) // NVR added guard to avoid unnecessary call to TypeNameTraits<TO>::name(), which calls Teuchos::demangleName(), which can be expensive
288  {
289  TEUCHOS_TEST_FOR_EXCEPTION(!datah, std::logic_error,
290  "Error, cast to type Data<" << Teuchos::TypeNameTraits<TO>::name() << "> failed but should not have and the actual underlying type is "
291  "\'" << datah_->typeName() << "! The problem might be related to incompatible RTTI systems in static and shared libraries!");
292  }
293  return datah->data_;
294  }
295  };
296 
297 }
298 
299 #endif /* MUELU_VARIABLECONTAINER_HPP */
MueLu_ConfigDefs.hpp
MueLu::VariableContainer::GetTypeName
std::string GetTypeName()
Definition: MueLu_VariableContainer.hpp:173
MueLu::VariableContainer::data_
DataBase * data_
the data itself
Definition: MueLu_VariableContainer.hpp:123
MueLu::KeepType
short KeepType
Definition: MueLu_KeepType.hpp:63
MueLu::VariableContainer::IsKept
bool IsKept(KeepType keep) const
Returns true if at least one keep flag is set.
Definition: MueLu_VariableContainer.hpp:230
MueLu::VariableContainer::Data::Data
Data(const T &data)
Definition: MueLu_VariableContainer.hpp:86
MueLu::VariableContainer::Data
Definition: MueLu_VariableContainer.hpp:84
MueLu::VariableContainer::RemoveKeepFlag
void RemoveKeepFlag(KeepType keep=UserData)
Removes a keep flag to the flag combination.
Definition: MueLu_VariableContainer.hpp:236
MueLu_KeepType.hpp
MueLu::VariableContainer::Getter< Teuchos::RCP< Xpetra::Operator< Scalar, LocalOrdinal, GlobalOrdinal, Node > > >::get
static Teuchos::RCP< Operator > & get(DataBase *data_, DataBase *&datah_)
Definition: MueLu_VariableContainer.hpp:250
MueLu::VariableContainer::Release
void Release(const FactoryBase *reqFactory)
Release data.
Definition: MueLu_VariableContainer.hpp:199
MueLu::VariableContainer::~VariableContainer
~VariableContainer()
Definition: MueLu_VariableContainer.hpp:139
MueLu::VariableContainer::GetData
T & GetData()
Definition: MueLu_VariableContainer.hpp:169
MueLu::VariableContainer::keep_
KeepType keep_
keep flag
Definition: MueLu_VariableContainer.hpp:128
MueLu::VariableContainer::NumAllRequests
int NumAllRequests() const
Returns the number of times the data has been requested.
Definition: MueLu_VariableContainer.hpp:215
MueLu::VariableContainer::Data::type
const std::type_info & type() const
Definition: MueLu_VariableContainer.hpp:87
MueLu::UserData
User data are always kept. This flag is set automatically when Level::Set("data", data) is used....
Definition: MueLu_KeepType.hpp:54
MueLu::VariableContainer::SetData
void SetData(const T &entry)
Store data in container class and set the "Available" status true.
Definition: MueLu_VariableContainer.hpp:151
MueLu
Namespace for MueLu classes and methods.
Definition: MueLu_BrickAggregationFactory_decl.hpp:76
MueLu::VariableContainer::GetData
const T & GetData() const
Definition: MueLu_VariableContainer.hpp:162
MueLu::VariableContainer::available_
bool available_
is data available?
Definition: MueLu_VariableContainer.hpp:127
MueLu::BaseClass
Base class for MueLu classes.
Definition: MueLu_BaseClass.hpp:61
MueLu::VariableContainer::datah_
DataBase * datah_
Definition: MueLu_VariableContainer.hpp:125
MueLu::VariableContainer::IsRequested
bool IsRequested(const FactoryBase *reqFactory) const
Returns true, if data is requested by reqFactory.
Definition: MueLu_VariableContainer.hpp:218
MueLu::VariableContainer::Data::typeName
std::string typeName() const
Definition: MueLu_VariableContainer.hpp:88
MueLu::VariableContainer::NumRequests
int NumRequests(const FactoryBase *reqFactory) const
Return the number of times the data has been requested by a specific factory.
Definition: MueLu_VariableContainer.hpp:209
MueLu::VariableContainer::Getter< Teuchos::RCP< Xpetra::Operator< Scalar, LocalOrdinal, GlobalOrdinal, Node > > >::Matrix
Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > Matrix
Definition: MueLu_VariableContainer.hpp:248
MueLu::VariableContainer::Request
void Request(const FactoryBase *reqFactory)
Request data.
Definition: MueLu_VariableContainer.hpp:189
MueLu::VariableContainer::count_
int count_
number of requests by all factories
Definition: MueLu_VariableContainer.hpp:129
MueLu_Exceptions.hpp
MueLu::Exceptions::RuntimeError
Exception throws to report errors in the internal logical of the program.
Definition: MueLu_Exceptions.hpp:70
MueLu::VariableContainer::Getter
Definition: MueLu_VariableContainer.hpp:93
MueLu::VariableContainer::DataBase::typeName
virtual std::string typeName() const =0
MueLu::VariableContainer::DataBase::~DataBase
virtual ~DataBase()
Definition: MueLu_VariableContainer.hpp:78
MueLu::VariableContainer::Requests
const request_container & Requests() const
Definition: MueLu_VariableContainer.hpp:223
MueLu::FactoryBase
Base class for factories (e.g., R, P, and A_coarse).
Definition: MueLu_FactoryBase.hpp:60
MueLu::VariableContainer::request_container
std::map< const FactoryBase *, int > request_container
Definition: MueLu_VariableContainer.hpp:120
MueLu::VariableContainer::Data::data_
T data_
Definition: MueLu_VariableContainer.hpp:89
MueLu::VariableContainer::GetKeepFlag
KeepType GetKeepFlag() const
Returns the keep flag combination.
Definition: MueLu_VariableContainer.hpp:239
MueLu::VariableContainer::Getter< Teuchos::RCP< Xpetra::Operator< Scalar, LocalOrdinal, GlobalOrdinal, Node > > >::Operator
Xpetra::Operator< Scalar, LocalOrdinal, GlobalOrdinal, Node > Operator
Definition: MueLu_VariableContainer.hpp:247
MueLu_FactoryBase_fwd.hpp
MueLu::VariableContainer::requests_
request_container requests_
requesting factories
Definition: MueLu_VariableContainer.hpp:131
MueLu::VariableContainer::IsRequested
bool IsRequested() const
Returns true, if data is requested by at least one factory.
Definition: MueLu_VariableContainer.hpp:221
MueLu::VariableContainer::Getter::get
static T & get(DataBase *data_, DataBase *&datah_)
Definition: MueLu_VariableContainer.hpp:94
MueLu::VariableContainer
Class that stores all relevant data for a variable.
Definition: MueLu_VariableContainer.hpp:73
MueLu::VariableContainer::DataBase::type
virtual const std::type_info & type() const =0
Teuchos
MueLu::VariableContainer::IsAvailable
bool IsAvailable() const
Returns true if data is available, i.e.
Definition: MueLu_VariableContainer.hpp:181
MueLu::VariableContainer::VariableContainer
VariableContainer()
Default constructor.
Definition: MueLu_VariableContainer.hpp:138
MueLu::VariableContainer::DataBase
Definition: MueLu_VariableContainer.hpp:76
MueLu_BaseClass.hpp
MueLu::VariableContainer::AddKeepFlag
void AddKeepFlag(KeepType keep=UserData)
Adds a keep flag to the flag combination.
Definition: MueLu_VariableContainer.hpp:233