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(size_t obj_id, std::vector<std::unique_ptr<Attribute>> attribs) = 0;
26  virtual std::vector<size_t> query(const std::vector<std::unique_ptr<Attribute>> & conds) = 0;
27  virtual void set(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 class VecStore : public Storage
39 {
40 public:
41  virtual void add(size_t obj_id, std::vector<std::unique_ptr<Attribute>> attribs) override
42  {
43  std::lock_guard<std::mutex> l(_mutex);
44  if (obj_id != _data.size())
45  throw std::runtime_error("object with id " + std::to_string(obj_id) + " already added");
46  _data.push_back(std::move(attribs));
47  }
48 
49  virtual std::vector<size_t> query(const std::vector<std::unique_ptr<Attribute>> & conds) override
50  {
51  std::vector<size_t> ids;
52  std::lock_guard<std::mutex> l(_mutex);
53  for (size_t i = 0; i < _data.size(); i++)
54  {
55  auto & data = _data[i];
56  bool ismatch = true;
57  for (auto & cond : conds)
58  {
59  if (!data[cond->id()]->isMatch(*cond))
60  {
61  ismatch = false;
62  break;
63  }
64  }
65  if (ismatch)
66  ids.push_back(i);
67  }
68  return ids;
69  }
70 
71  virtual void set(size_t obj_id, std::vector<std::unique_ptr<Attribute>> attribs) override
72  {
73  if (obj_id > _data.size())
74  throw std::runtime_error("unknown object id " + std::to_string(obj_id));
75 
76  std::lock_guard<std::mutex> l(_mutex);
77 
78  auto & dst = _data[obj_id];
79  for (auto & attrib : attribs)
80  dst[attrib->id()] = std::move(attrib);
81  }
82 
83 private:
84  std::mutex _mutex;
85  std::vector<std::vector<std::unique_ptr<Attribute>>> _data;
86 };
87 
90 
91 void isValid(MooseObject * obj);
92 
93 void
94 TheWarehouse::add(std::shared_ptr<MooseObject> obj, const std::string & system)
95 {
96  isValid(obj.get());
97 
98  size_t obj_id = 0;
99  {
100  std::lock_guard<std::mutex> lock(_obj_mutex);
101  _objects.push_back(obj);
102  obj_id = _objects.size() - 1;
103  _obj_ids[obj.get()] = obj_id;
104 
105  // reset/invalidate the query cache since query results may have been affected by this warehouse
106  // insertion.
107  _obj_cache.clear();
108  _query_cache.clear();
109  }
110 
111  std::vector<std::unique_ptr<Attribute>> attribs;
112  readAttribs(obj.get(), system, attribs);
113  _store->add(obj_id, std::move(attribs));
114 }
115 
116 void
118 {
119  std::vector<std::unique_ptr<Attribute>> attribs;
120  attribs.push_back(extra.clone());
121  _store->set(_obj_ids[obj], std::move(attribs));
122  // reset/invalidate the query cache since query results may have been affected by this object
123  // attribute modification.
124  _obj_cache.clear();
125  _query_cache.clear();
126 }
127 
128 void
130 {
131  std::vector<std::unique_ptr<Attribute>> attribs;
132  readAttribs(obj, "", attribs);
133  _store->set(_obj_ids[obj], std::move(attribs));
134  // reset/invalidate the query cache since query results may have been affected by this object
135  // attribute modification.
136  _obj_cache.clear();
137  _query_cache.clear();
138 }
139 
140 int
141 TheWarehouse::prepare(std::vector<std::unique_ptr<Attribute>> conds)
142 {
143  auto obj_ids = _store->query(conds);
144 
145  std::lock_guard<std::mutex> lock(_obj_cache_mutex);
146  _obj_cache.push_back({});
147  auto query_id = _obj_cache.size() - 1;
148  auto & vec = _obj_cache.back();
149  {
150  std::lock_guard<std::mutex> lock(_query_cache_mutex);
151  _query_cache[std::move(conds)] = query_id;
152  }
153 
154  std::lock_guard<std::mutex> o_lock(_obj_mutex);
155  for (auto & id : obj_ids)
156  vec.push_back(_objects[id].get());
157 
158  if (!vec.empty() && dynamic_cast<DependencyResolverInterface *>(vec[0]))
159  {
160  std::vector<DependencyResolverInterface *> dependers;
161  for (auto obj : vec)
162  {
163  auto d = dynamic_cast<DependencyResolverInterface *>(obj);
164  if (!d)
165  {
166  dependers.clear();
167  break;
168  }
169  dependers.push_back(d);
170  }
171 
172  try
173  {
175  }
177  {
178  DependencyResolverInterface::cyclicDependencyError<GeneralUserObject *>(
179  e, "Cyclic dependency detected in object ordering");
180  }
181 
182  for (unsigned int i = 0; i < dependers.size(); i++)
183  vec[i] = dynamic_cast<MooseObject *>(dependers[i]);
184  }
185 
186  return query_id;
187 }
188 
189 const std::vector<MooseObject *> &
190 TheWarehouse::query(int query_id)
191 {
192  if (static_cast<size_t>(query_id) >= _obj_cache.size())
193  throw std::runtime_error("unknown query id");
194  return _obj_cache[query_id];
195 }
196 
197 size_t
198 TheWarehouse::queryID(const std::vector<std::unique_ptr<Attribute>> & conds)
199 {
200  {
201  std::lock_guard<std::mutex> lock(_query_cache_mutex);
202  auto it = _query_cache.find(conds);
203  if (it != _query_cache.end())
204  return it->second;
205  }
206 
207  std::vector<std::unique_ptr<Attribute>> conds_clone;
208  conds_clone.resize(conds.size());
209  for (size_t i = 0; i < conds.size(); i++)
210  conds_clone[i] = conds[i]->clone();
211  return prepare(std::move(conds_clone));
212 }
213 
214 size_t
215 TheWarehouse::count(const std::vector<std::unique_ptr<Attribute>> & conds)
216 {
217  auto query_id = queryID(conds);
218  std::lock_guard<std::mutex> lock(_obj_cache_mutex);
219  auto & objs = query(query_id);
220  size_t count = 0;
221  for (auto obj : objs)
222  if (obj->enabled())
223  count++;
224  return count;
225 }
226 
227 void
229  const std::string & system,
230  std::vector<std::unique_ptr<Attribute>> & attribs)
231 {
232  std::unique_ptr<AttribSystem> sys;
233  if (!system.empty())
234  sys.reset(new AttribSystem(*this, system));
235  for (auto & ref : _attrib_list)
236  {
237  if (sys && (ref->id() == sys->id()))
238  {
239  attribs.push_back(std::move(sys));
240  continue;
241  }
242 
243  attribs.emplace_back(ref->clone());
244  attribs.back()->initFrom(obj);
245  }
246 }
247 
248 void
250 {
251  auto blk = dynamic_cast<BlockRestrictable *>(obj);
252  if (!blk)
253  return;
254 
255  // Check variables
256  auto c_ptr = dynamic_cast<Coupleable *>(obj);
257  if (c_ptr)
258  for (MooseVariableFEBase * var : c_ptr->getCoupledMooseVars())
259  blk->checkVariable(*var);
260 
261  const InputParameters & parameters = obj->parameters();
262 
263  SubProblem & problem = *parameters.get<SubProblem *>("_subproblem");
264 
265  THREAD_ID tid = parameters.get<THREAD_ID>("_tid");
266 
267  if (parameters.isParamValid("variable"))
268  {
269  // Try the scalar version first
270  std::string variable_name = parameters.getMooseType("variable");
271  if (variable_name == "")
272  // When using vector variables, we are only going to use the first one in the list at the
273  // interface level...
274  variable_name = parameters.getVecMooseType("variable")[0];
275 
276  blk->checkVariable(problem.getVariable(
278  }
279 }
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:304
void isValid(MooseObject *obj)
Definition: TheWarehouse.C:249
Attribute is an abstract class that can be implemented in order to track custom metadata about MooseO...
Definition: TheWarehouse.h:31
virtual MooseVariableFEBase & getVariable(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)=0
Returns the variable reference for requested variable which must be of the expected_var_type (Nonline...
virtual std::vector< size_t > query(const std::vector< std::unique_ptr< Attribute >> &conds)=0
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
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
std::vector< std::vector< std::unique_ptr< Attribute > > > _data
Definition: TheWarehouse.C:85
std::mutex _query_cache_mutex
Definition: TheWarehouse.h:303
size_t queryID(const std::vector< std::unique_ptr< Attribute >> &conds)
Definition: TheWarehouse.C:198
nl system()
virtual void add(size_t obj_id, std::vector< std::unique_ptr< Attribute >> attribs) override
Definition: TheWarehouse.C:41
std::vector< std::shared_ptr< MooseObject > > _objects
Definition: TheWarehouse.h:288
Every object that can be built by the factory should be derived from this class.
Definition: MooseObject.h:42
const InputParameters & parameters() const
Get the parameters of the object.
Definition: MooseObject.h:65
std::unique_ptr< Storage > _store
Definition: TheWarehouse.h:287
virtual void add(size_t obj_id, std::vector< std::unique_ptr< Attribute >> attribs)=0
virtual ~Storage()=default
TheWarehouse is a container for MooseObjects that allows querying/filtering over various customizeabl...
Definition: TheWarehouse.h:119
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:141
std::unordered_map< std::vector< std::unique_ptr< Attribute > >, int > _query_cache
Definition: TheWarehouse.h:297
std::mutex _obj_mutex
Definition: TheWarehouse.h:302
std::unordered_map< MooseObject *, size_t > _obj_ids
Definition: TheWarehouse.h:289
virtual std::vector< size_t > query(const std::vector< std::unique_ptr< Attribute >> &conds) override
Definition: TheWarehouse.C:49
void update(MooseObject *obj)
update updates the metadata/attribute-info stored for the given object obj that must already exists i...
Definition: TheWarehouse.C:129
Interface for objects that needs coupling capabilities.
Definition: Coupleable.h:62
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:59
Query query()
query creates and returns an initialized a query object for querying objects from the warehouse...
Definition: TheWarehouse.h:239
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
void readAttribs(const MooseObject *obj, const std::string &system, std::vector< std::unique_ptr< Attribute >> &attribs)
Definition: TheWarehouse.C:228
An interface that restricts an object to subdomains via the &#39;blocks&#39; input parameter.
void add(std::shared_ptr< MooseObject > obj, const std::string &system)
add adds a new object to the warehouse and stores attributes/metadata about it for running queries/fi...
Definition: TheWarehouse.C:94
Interface for sorting dependent vectors of objects.
std::mutex _mutex
Definition: TheWarehouse.C:84
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:215
std::vector< std::string > getVecMooseType(const std::string &name) const
std::vector< std::unique_ptr< Attribute > > _attrib_list
Definition: TheWarehouse.h:300
std::vector< std::vector< MooseObject * > > _obj_cache
Definition: TheWarehouse.h:293
unsigned int THREAD_ID
Definition: MooseTypes.h:161
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.