www.mooseframework.org
TheWarehouse.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #include "TheWarehouse.h"
11 
12 #include "Attributes.h"
13 #include "MooseObject.h"
14 #include "SubProblem.h"
15 #include "GeneralUserObject.h"
17 #include "BlockRestrictable.h"
18 
19 #include <memory>
20 
21 class Storage
22 {
23 public:
24  virtual ~Storage() = default;
25  virtual void add(std::size_t obj_id, std::vector<std::unique_ptr<Attribute>> attribs) = 0;
26  virtual std::vector<std::size_t> query(const std::vector<std::unique_ptr<Attribute>> & conds) = 0;
27  virtual void set(std::size_t obj_id, std::vector<std::unique_ptr<Attribute>> attribs) = 0;
28 };
29 
30 bool
31 operator==(const std::unique_ptr<Attribute> & lhs, const std::unique_ptr<Attribute> & rhs)
32 {
33  return (*lhs) == (*rhs);
34 }
35 
36 Attribute::Attribute(TheWarehouse & w, const std::string name) : _id(w.attribID(name)) {}
37 
38 void
40 {
41 }
42 
43 bool
44 AttribSorted::isMatch(const Attribute & other) const
45 {
46  auto a = dynamic_cast<const AttribSorted *>(&other);
47  return _initd && a && a->_initd && (a->_val == _val);
48 }
49 
50 bool
51 AttribSorted::isEqual(const Attribute & other) const
52 {
53  return isMatch(other);
54 }
55 
56 class VecStore : public Storage
57 {
58 public:
59  virtual void add(std::size_t obj_id, std::vector<std::unique_ptr<Attribute>> attribs) override
60  {
61  std::lock_guard<std::mutex> l(_mutex);
62  if (obj_id != _data.size())
63  throw std::runtime_error("object with id " + std::to_string(obj_id) + " already added");
64  _data.push_back(std::move(attribs));
65  }
66 
67  virtual std::vector<std::size_t>
68  query(const std::vector<std::unique_ptr<Attribute>> & conds) override
69  {
70  std::vector<std::size_t> ids;
71  std::lock_guard<std::mutex> l(_mutex);
72  for (std::size_t i = 0; i < _data.size(); i++)
73  {
74  auto & data = _data[i];
75  bool ismatch = true;
76  for (auto & cond : conds)
77  {
78  if (!data[cond->id()]->isMatch(*cond))
79  {
80  ismatch = false;
81  break;
82  }
83  }
84  if (ismatch)
85  {
86  mooseAssert(std::find(ids.begin(), ids.end(), i) == ids.end(), "Duplicate object");
87  ids.push_back(i);
88  }
89  }
90  return ids;
91  }
92 
93  virtual void set(std::size_t obj_id, std::vector<std::unique_ptr<Attribute>> attribs) override
94  {
95  if (obj_id > _data.size())
96  throw std::runtime_error("unknown object id " + std::to_string(obj_id));
97 
98  std::lock_guard<std::mutex> l(_mutex);
99 
100  auto & dst = _data[obj_id];
101  for (auto & attrib : attribs)
102  dst[attrib->id()] = std::move(attrib);
103  }
104 
105 private:
106  std::mutex _mutex;
107  std::vector<std::vector<std::unique_ptr<Attribute>>> _data;
108 };
109 
110 TheWarehouse::TheWarehouse() : _store(std::make_unique<VecStore>()) {}
112 
113 void isValid(MooseObject * obj);
114 
115 void
116 TheWarehouse::add(std::shared_ptr<MooseObject> obj)
117 {
118  isValid(obj.get());
119 
120  std::size_t obj_id = 0;
121  {
122  std::lock_guard<std::mutex> lock(_obj_mutex);
123 
124  mooseAssert(!_obj_ids.count(obj.get()), obj->typeAndName() + " has already been added");
125 
126  _objects.push_back(obj);
127  obj_id = _objects.size() - 1;
128  _obj_ids[obj.get()] = obj_id;
129 
130  // reset/invalidate the query cache since query results may have been affected by this warehouse
131  // insertion.
132  _obj_cache.clear();
133  _query_cache.clear();
134  }
135 
136  std::vector<std::unique_ptr<Attribute>> attribs;
137  readAttribs(obj.get(), attribs);
138  _store->add(obj_id, std::move(attribs));
139 }
140 
141 void
143 {
144  std::vector<std::unique_ptr<Attribute>> attribs;
145  attribs.push_back(extra.clone());
146  _store->set(_obj_ids[obj], std::move(attribs));
147  // reset/invalidate the query cache since query results may have been affected by this object
148  // attribute modification.
149  _obj_cache.clear();
150  _query_cache.clear();
151 }
152 
153 void
155 {
156  std::vector<std::unique_ptr<Attribute>> attribs;
157  readAttribs(obj, attribs);
158  _store->set(_obj_ids[obj], std::move(attribs));
159  // reset/invalidate the query cache since query results may have been affected by this object
160  // attribute modification.
161  _obj_cache.clear();
162  _query_cache.clear();
163 }
164 
165 int
166 TheWarehouse::prepare(std::vector<std::unique_ptr<Attribute>> conds)
167 {
168  bool sort = false;
169  std::unique_ptr<Attribute> sorted_attrib;
170  if (!conds.empty() && dynamic_cast<AttribSorted *>(conds.back().get()))
171  {
172  sorted_attrib = std::move(conds.back());
173  static const AttribSorted sorted_attrib_true(*this, true);
174  sort = sorted_attrib->isMatch(sorted_attrib_true);
175  // Remove the sorted condition temporarily
176  conds.pop_back();
177  }
178 
179 #ifdef DEBUG
180  for (auto & cond : conds)
181  mooseAssert(!dynamic_cast<AttribSorted *>(cond.get()),
182  "There should be no sorted attributes in this container.");
183 #endif
184 
185  auto obj_ids = _store->query(conds);
186  if (sorted_attrib)
187  conds.push_back(std::move(sorted_attrib));
188 
189  std::lock_guard<std::mutex> lock(_obj_cache_mutex);
190  auto & vec = _obj_cache.emplace_back(obj_ids.size());
191  const auto query_id = _obj_cache.size() - 1;
192  {
193  std::lock_guard<std::mutex> lock(_query_cache_mutex);
194  _query_cache[std::move(conds)] = query_id;
195  }
196 
197  std::lock_guard<std::mutex> o_lock(_obj_mutex);
198  for (const auto i : index_range(obj_ids))
199  {
200  auto obj = _objects[obj_ids[i]].get();
201  mooseAssert(std::find(vec.begin(), vec.end(), obj) == vec.end(), "Duplicate object");
202  vec[i] = obj;
203  }
204 
205  if (sort && !vec.empty() && dynamic_cast<DependencyResolverInterface *>(vec[0]))
206  {
207  std::vector<DependencyResolverInterface *> dependers;
208  for (auto obj : vec)
209  {
210  auto d = dynamic_cast<DependencyResolverInterface *>(obj);
211  if (!d)
212  {
213  dependers.clear();
214  break;
215  }
216  dependers.push_back(d);
217  }
218 
219  try
220  {
222  }
224  {
225  DependencyResolverInterface::cyclicDependencyError<UserObject *>(
226  e, "Cyclic dependency detected in object ordering");
227  }
228 
229  mooseAssert(dependers.size() == vec.size(), "Dependency resolution size mismatch");
230  for (unsigned int i = 0; i < dependers.size(); i++)
231  vec[i] = dynamic_cast<MooseObject *>(dependers[i]);
232  }
233 
234  return query_id;
235 }
236 
237 const std::vector<MooseObject *> &
238 TheWarehouse::query(int query_id)
239 {
240  if (static_cast<std::size_t>(query_id) >= _obj_cache.size())
241  throw std::runtime_error("unknown query id");
242  return _obj_cache[query_id];
243 }
244 
245 std::size_t
246 TheWarehouse::queryID(const std::vector<std::unique_ptr<Attribute>> & conds)
247 {
248  {
249  std::lock_guard<std::mutex> lock(_query_cache_mutex);
250  auto it = _query_cache.find(conds);
251  if (it != _query_cache.end())
252  return it->second;
253  }
254 
255  std::vector<std::unique_ptr<Attribute>> conds_clone;
256  conds_clone.resize(conds.size());
257  for (std::size_t i = 0; i < conds.size(); i++)
258  conds_clone[i] = conds[i]->clone();
259  return prepare(std::move(conds_clone));
260 }
261 
262 std::size_t
263 TheWarehouse::count(const std::vector<std::unique_ptr<Attribute>> & conds)
264 {
265  auto query_id = queryID(conds);
266  std::lock_guard<std::mutex> lock(_obj_cache_mutex);
267  auto & objs = query(query_id);
268  std::size_t count = 0;
269  for (auto obj : objs)
270  if (obj->enabled())
271  count++;
272  return count;
273 }
274 
275 void
277  std::vector<std::unique_ptr<Attribute>> & attribs)
278 {
279  for (auto & ref : _attrib_list)
280  {
281  attribs.emplace_back(ref->clone());
282  attribs.back()->initFrom(obj);
283  }
284 }
285 
286 void
288 {
289  auto blk = dynamic_cast<BlockRestrictable *>(obj);
290  if (!blk)
291  return;
292 
293  // Check variables
294  auto c_ptr = dynamic_cast<Coupleable *>(obj);
295  if (c_ptr)
296  for (MooseVariableFEBase * var : c_ptr->getCoupledMooseVars())
297  blk->checkVariable(*var);
298 
299  const InputParameters & parameters = obj->parameters();
300 
301  SubProblem & problem = *parameters.get<SubProblem *>("_subproblem");
302 
303  THREAD_ID tid = parameters.get<THREAD_ID>("_tid");
304 
305  if (parameters.isParamValid("variable"))
306  {
307  // Try the scalar version first
308  std::string variable_name = parameters.getMooseType("variable");
309  if (variable_name == "")
310  // When using vector variables, we are only going to use the first one in the list at the
311  // interface level...
312  variable_name = parameters.getVecMooseType("variable")[0];
313 
314  blk->checkVariable(problem.getVariable(
316  }
317 }
std::string name(const ElemQuality q)
std::string getMooseType(const std::string &name) const
Utility functions for retrieving one of the MooseTypes variables into the common "string" base class...
std::mutex _obj_cache_mutex
Definition: TheWarehouse.h:535
virtual void add(std::size_t obj_id, std::vector< std::unique_ptr< Attribute >> attribs)=0
std::size_t count(const std::vector< std::unique_ptr< Attribute >> &conds)
count returns the number of objects that match the provided query conditions.
Definition: TheWarehouse.C:263
void isValid(MooseObject *obj)
Definition: TheWarehouse.C:287
Attribute is an abstract class that can be implemented in order to track custom metadata about MooseO...
Definition: TheWarehouse.h:50
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
Combine two vector parameters into a single vector of pairs.
void add(std::shared_ptr< MooseObject > obj)
add adds a new object to the warehouse and stores attributes/metadata about it for running queries/fi...
Definition: TheWarehouse.C:116
This attribute describes sorting state.
Definition: TheWarehouse.h:112
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
This class provides an interface for common operations on field variables of both FE and FV types wit...
virtual void add(std::size_t obj_id, std::vector< std::unique_ptr< Attribute >> attribs) override
Definition: TheWarehouse.C:59
Attribute(TheWarehouse &w, const std::string name)
Constructs/initializes a new attribute with the specified name for use in warehouse w...
Definition: TheWarehouse.C:36
virtual bool isEqual(const Attribute &other) const override
isEqual returns true if the meta-data stored in this attribute is identical to that stored in other...
Definition: TheWarehouse.C:51
std::vector< std::vector< std::unique_ptr< Attribute > > > _data
Definition: TheWarehouse.C:107
std::mutex _query_cache_mutex
Definition: TheWarehouse.h:534
std::vector< std::shared_ptr< MooseObject > > _objects
Definition: TheWarehouse.h:519
Every object that can be built by the factory should be derived from this class.
Definition: MooseObject.h:33
std::unique_ptr< Storage > _store
Definition: TheWarehouse.h:518
virtual ~Storage()=default
void readAttribs(const MooseObject *obj, std::vector< std::unique_ptr< Attribute >> &attribs)
Definition: TheWarehouse.C:276
std::size_t queryID(const std::vector< std::unique_ptr< Attribute >> &conds)
Definition: TheWarehouse.C:246
TheWarehouse is a container for MooseObjects that allows querying/filtering over various customizeabl...
Definition: TheWarehouse.h:185
virtual bool isMatch(const Attribute &other) const override
isMatch returns true if the meta-data stored in this attribute is equivalent to that stored in other...
Definition: TheWarehouse.C:44
virtual std::vector< std::size_t > query(const std::vector< std::unique_ptr< Attribute >> &conds)=0
int prepare(std::vector< std::unique_ptr< Attribute >> conds)
prepares a query and returns an associated query_id (i.e. for use with the query function).
Definition: TheWarehouse.C:166
std::unordered_map< std::vector< std::unique_ptr< Attribute > >, int > _query_cache
Definition: TheWarehouse.h:528
std::mutex _obj_mutex
Definition: TheWarehouse.h:533
virtual const MooseVariableFieldBase & getVariable(const THREAD_ID tid, const std::string &var_name, Moose::VarKindType expected_var_type=Moose::VarKindType::VAR_ANY, Moose::VarFieldType expected_var_field_type=Moose::VarFieldType::VAR_FIELD_ANY) const =0
Returns the variable reference for requested variable which must be of the expected_var_type (Nonline...
virtual std::vector< std::size_t > query(const std::vector< std::unique_ptr< Attribute >> &conds) override
Definition: TheWarehouse.C:68
std::unordered_map< MooseObject *, std::size_t > _obj_ids
Definition: TheWarehouse.h:520
void update(MooseObject *obj)
update updates the metadata/attribute-info stored for the given object obj that must already exists i...
Definition: TheWarehouse.C:154
Interface for objects that needs coupling capabilities.
Definition: Coupleable.h:44
static void sort(typename std::vector< T > &vector)
Given a vector, sort using the getRequested/SuppliedItems sets.
Generic class for solving transient nonlinear problems.
Definition: SubProblem.h:75
Query query()
query creates and returns an initialized a query object for querying objects from the warehouse...
Definition: TheWarehouse.h:466
bool operator==(const std::unique_ptr< Attribute > &lhs, const std::unique_ptr< Attribute > &rhs)
TheWarehouse uses this operator function for indexing and caching queries.
Definition: TheWarehouse.C:31
An interface that restricts an object to subdomains via the &#39;blocks&#39; input parameter.
Interface for sorting dependent vectors of objects.
const InputParameters & parameters() const
Get the parameters of the object.
virtual void initFrom(const MooseObject *obj) override
initFrom reads and stores the desired meta-data from obj for later matching comparisons.
Definition: TheWarehouse.C:39
std::mutex _mutex
Definition: TheWarehouse.C:106
std::vector< std::string > getVecMooseType(const std::string &name) const
auto index_range(const T &sizable)
std::vector< std::unique_ptr< Attribute > > _attrib_list
Definition: TheWarehouse.h:531
std::vector< std::vector< MooseObject * > > _obj_cache
Definition: TheWarehouse.h:524
unsigned int THREAD_ID
Definition: MooseTypes.h:198
virtual std::unique_ptr< Attribute > clone() const =0
clone creates and returns and identical (deep) copy of this attribute - i.e.
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another, i.e.