MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_VariableContainer.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// MueLu: A package for multigrid based preconditioning
4//
5// Copyright 2012 NTESS and the MueLu contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef MUELU_VARIABLECONTAINER_HPP
11#define MUELU_VARIABLECONTAINER_HPP
12
13#include <map>
14
15#include <Teuchos_TypeNameTraits.hpp>
16
17#include <Xpetra_Matrix.hpp>
18#include <Xpetra_Operator.hpp>
19
20#include "MueLu_ConfigDefs.hpp"
21#include "MueLu_BaseClass.hpp"
22
23#include "MueLu_Exceptions.hpp"
25#include "MueLu_KeepType.hpp"
26
27namespace MueLu {
28
38 private:
39 // Motivated by Teuchos_any.hpp
40 class DataBase {
41 public:
42 virtual ~DataBase() = default;
43 virtual const std::type_info& type() const = 0;
44 virtual std::string typeName() const = 0;
45 };
46
47 template <typename T>
48 class Data : public DataBase {
49 public:
50 Data(const T& data)
51 : data_(data) {}
52 const std::type_info& type() const { return typeid(T); }
53 std::string typeName() const { return Teuchos::TypeNameTraits<T>::name(); }
55 };
56
57 template <typename T>
58 struct Getter {
59 static T& get(DataBase* data_, DataBase*& /* datah_ */) {
60 if ((data_ == NULL) || (data_->type() != typeid(T))) // NVR added guard to avoid determining typeName unless we will use it
61 {
62 const std::string typeName = Teuchos::TypeNameTraits<T>::name(); // calls Teuchos::demangleName(), which can be expensive
63 TEUCHOS_TEST_FOR_EXCEPTION(data_ == NULL, Teuchos::bad_any_cast,
64 "Error, cast to type Data<" << typeName << "> failed since the content is NULL");
65
66 TEUCHOS_TEST_FOR_EXCEPTION(data_->type() != typeid(T), Teuchos::bad_any_cast,
67 "Error, cast to type Data<" << typeName << "> failed since the actual underlying type is "
68 "\'"
69 << data_->typeName() << "!");
70 }
71
72 Data<T>* data = dynamic_cast<Data<T>*>(data_);
73 if (!data) // NVR added guard to avoid determining typeName unless we will use it
74 {
75 const std::string typeName = Teuchos::TypeNameTraits<T>::name(); // calls Teuchos::demangleName(), which can be expensive
76 TEUCHOS_TEST_FOR_EXCEPTION(!data, std::logic_error,
77 "Error, cast to type Data<" << typeName << "> failed but should not have and the actual underlying type is "
78 "\'"
79 << data_->typeName() << "! The problem might be related to incompatible RTTI systems in static and shared libraries!");
80 }
81 return data->data_;
82 }
83 };
84
85 template <typename T>
86 struct Checker {
87 static bool check(DataBase* data_, DataBase*& /* datah_ */) {
88 if ((data_ == NULL) || (data_->type() != typeid(T))) // NVR added guard to avoid determining typeName unless we will use it
89 {
90 return false;
91 }
92
93 Data<T>* data = dynamic_cast<Data<T>*>(data_);
94 if (!data) // NVR added guard to avoid determining typeName unless we will use it
95 {
96 return false;
97 }
98 return true;
99 }
100 };
101
102 public:
103 typedef std::map<const FactoryBase*, int> request_container;
104
105 private:
107 mutable DataBase* datah_;
111 int count_;
112
114
115 public:
117
118
121 : data_(NULL)
122 , datah_(NULL)
123 , available_(false)
124 , keep_(false)
125 , count_(0) {}
127 delete data_;
128 data_ = NULL;
129 delete datah_;
130 datah_ = NULL;
131 }
132
134
136
137
139 template <typename T>
140 void SetData(const T& entry) {
141 delete data_;
142 delete datah_;
143 data_ = new Data<T>(entry);
144 datah_ = NULL;
145 available_ = true;
146 }
147
150 template <typename T>
151 const T& GetData() const {
152 return Getter<T>::get(data_, datah_);
153 }
154
157 template <typename T>
158 T& GetData() {
159 return Getter<T>::get(data_, datah_);
160 }
161
164 template <typename T>
165 bool CheckType() {
167 }
168
169 std::string GetTypeName() {
170 if (data_ == NULL)
171 return std::string("");
172 return data_->typeName();
173 }
174
176 // if SetData has been called before
177 bool IsAvailable() const { return available_; }
178
180
182
183
185 void Request(const FactoryBase* reqFactory) {
186 request_container::iterator it = requests_.find(reqFactory);
187 if (it == requests_.end())
188 requests_[reqFactory] = 1;
189 else
190 (it->second)++;
191 count_++; // increment request counter
192 }
193
195 void Release(const FactoryBase* reqFactory) {
196 request_container::iterator it = requests_.find(reqFactory);
197 TEUCHOS_TEST_FOR_EXCEPTION(it == requests_.end(), Exceptions::RuntimeError,
198 "MueLu::VariableContainer::Release(): "
199 "cannot call Release if factory has not been requested before by factory "
200 << reqFactory);
201 if (--(it->second) == 0)
202 requests_.erase(it);
203 count_--;
204 }
205
207 int NumRequests(const FactoryBase* reqFactory) const {
208 request_container::const_iterator it = requests_.find(reqFactory);
209 return (it != requests_.end()) ? it->second : 0;
210 }
211
213 int NumAllRequests() const { return count_; }
214
216 bool IsRequested(const FactoryBase* reqFactory) const { return (NumRequests(reqFactory) > 0); }
217
219 bool IsRequested() const { return (count_ > 0); }
220
221 const request_container& Requests() const { return requests_; }
223
225
226
228 bool IsKept(KeepType keep) const { return keep_ & keep; }
229
231 void AddKeepFlag(KeepType keep = UserData) { keep_ |= keep; }
232
234 void RemoveKeepFlag(KeepType keep = UserData) { keep_ = keep_ & (keep_ ^ keep); }
235
237 KeepType GetKeepFlag() const { return keep_; }
238
240};
241
242template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
243struct VariableContainer::Getter<Teuchos::RCP<Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node> > > {
244 typedef Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node> Operator;
245 typedef Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> Matrix;
246
247 static Teuchos::RCP<Operator>& get(DataBase* data_, DataBase*& datah_) {
248 typedef Teuchos::RCP<Operator> TO;
249 typedef Teuchos::RCP<Matrix> TM;
250
251 if (data_ == NULL) // NVR added guard to avoid unnecessary call to TypeNameTraits<TO>::name(), which calls Teuchos::demangleName(), which can be expensive
252 {
253 TEUCHOS_TEST_FOR_EXCEPTION(data_ == NULL, Teuchos::bad_any_cast,
254 "Error, cast to type Data<" << Teuchos::TypeNameTraits<TO>::name() << "> failed since the content is NULL");
255 }
256 if (data_->type() == typeid(TO)) {
257 Data<TO>* data = dynamic_cast<Data<TO>*>(data_);
258 if (!data) // NVR added guard to avoid unnecessary call to TypeNameTraits<TO>::name(), which calls Teuchos::demangleName(), which can be expensive
259 {
260 TEUCHOS_TEST_FOR_EXCEPTION(!data, std::logic_error,
261 "Error, cast to type Data<" << Teuchos::TypeNameTraits<TO>::name() << "> failed but should not have and the actual underlying type is "
262 "\'"
263 << data_->typeName() << "! The problem might be related to incompatible RTTI systems in static and shared libraries!");
264 }
265 return data->data_;
266 }
267
268 if (data_->type() != typeid(TM)) // NVR added guard to avoid unnecessary call to TypeNameTraits<TO>::name(), which calls Teuchos::demangleName(), which can be expensive
269 {
270 TEUCHOS_TEST_FOR_EXCEPTION(data_->type() != typeid(TM), Teuchos::bad_any_cast,
271 "Error, cast to type Data<" << Teuchos::TypeNameTraits<TM>::name() << "> failed since the actual underlying type is "
272 "\'"
273 << data_->typeName() << "!");
274 }
275 Data<TM>* data = dynamic_cast<Data<TM>*>(data_);
276 if (!data) // NVR added guard to avoid unnecessary call to TypeNameTraits<TO>::name(), which calls Teuchos::demangleName(), which can be expensive
277 {
278 TEUCHOS_TEST_FOR_EXCEPTION(!data, std::logic_error,
279 "Error, cast to type Data<" << Teuchos::TypeNameTraits<TM>::name() << "> failed but should not have and the actual underlying type is "
280 "\'"
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 "\'"
292 << datah_->typeName() << "! The problem might be related to incompatible RTTI systems in static and shared libraries!");
293 }
294 return datah->data_;
295 }
296};
297
298} // namespace MueLu
299
300#endif /* MUELU_VARIABLECONTAINER_HPP */
Base class for MueLu classes.
Exception throws to report errors in the internal logical of the program.
Base class for factories (e.g., R, P, and A_coarse).
virtual std::string typeName() const =0
virtual const std::type_info & type() const =0
const std::type_info & type() const
Class that stores all relevant data for a variable.
bool IsRequested() const
Returns true, if data is requested by at least one factory.
DataBase * data_
the data itself
void RemoveKeepFlag(KeepType keep=UserData)
Removes a keep flag to the flag combination.
bool IsRequested(const FactoryBase *reqFactory) const
Returns true, if data is requested by reqFactory.
void AddKeepFlag(KeepType keep=UserData)
Adds a keep flag to the flag combination.
bool IsAvailable() const
Returns true if data is available, i.e.
void Request(const FactoryBase *reqFactory)
Request data.
KeepType GetKeepFlag() const
Returns the keep flag combination.
void SetData(const T &entry)
Store data in container class and set the "Available" status true.
bool IsKept(KeepType keep) const
Returns true if at least one keep flag is set.
std::map< const FactoryBase *, int > request_container
const request_container & Requests() const
request_container requests_
requesting factories
int count_
number of requests by all factories
int NumAllRequests() const
Returns the number of times the data has been requested.
VariableContainer()
Default constructor.
void Release(const FactoryBase *reqFactory)
Release data.
int NumRequests(const FactoryBase *reqFactory) const
Return the number of times the data has been requested by a specific factory.
Namespace for MueLu classes and methods.
@ UserData
User data are always kept. This flag is set automatically when Level::Set("data", data) is used....
short KeepType
static bool check(DataBase *data_, DataBase *&)
static T & get(DataBase *data_, DataBase *&)