https://mooseframework.inl.gov
Loading...
Searching...
No Matches
TheWarehouse.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
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
22{
23public:
24 virtual ~WarehouseStorage() = 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
30bool
31operator==(const std::unique_ptr<Attribute> & lhs, const std::unique_ptr<Attribute> & rhs)
32{
33 return (*lhs) == (*rhs);
34}
35
36Attribute::Attribute(TheWarehouse & w, const std::string name) : _id(w.attribID(name)) {}
37
38void
42
43bool
44AttribSorted::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
50bool
51AttribSorted::isEqual(const Attribute & other) const
52{
53 return isMatch(other);
54}
55
57{
58public:
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
105private:
106 std::mutex _mutex;
107 std::vector<std::vector<std::unique_ptr<Attribute>>> _data;
108};
109
110TheWarehouse::TheWarehouse() : _store(std::make_unique<VecStore>()) {}
112
113void isValid(MooseObject * obj);
114
115void
116TheWarehouse::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
141void
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
153void
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
165int
166TheWarehouse::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<MooseObject *>(
226 e,
227 "Cyclic dependency detected in object ordering",
229 {
230 auto * moose_obj = dynamic_cast<MooseObject *>(obj);
231 mooseAssert(moose_obj, "Failed to cast dependency object to MooseObject");
232 return moose_obj->name();
233 });
234 }
235
236 mooseAssert(dependers.size() == vec.size(), "Dependency resolution size mismatch");
237 for (unsigned int i = 0; i < dependers.size(); i++)
238 vec[i] = dynamic_cast<MooseObject *>(dependers[i]);
239 }
240
241 return query_id;
242}
243
244const std::vector<MooseObject *> &
246{
247 if (static_cast<std::size_t>(query_id) >= _obj_cache.size())
248 throw std::runtime_error("unknown query id");
249 return _obj_cache[query_id];
250}
251
252std::size_t
253TheWarehouse::queryID(const std::vector<std::unique_ptr<Attribute>> & conds)
254{
255 {
256 std::lock_guard<std::mutex> lock(_query_cache_mutex);
257 auto it = _query_cache.find(conds);
258 if (it != _query_cache.end())
259 return it->second;
260 }
261
262 std::vector<std::unique_ptr<Attribute>> conds_clone;
263 conds_clone.resize(conds.size());
264 for (std::size_t i = 0; i < conds.size(); i++)
265 conds_clone[i] = conds[i]->clone();
266 return prepare(std::move(conds_clone));
267}
268
269std::size_t
270TheWarehouse::count(const std::vector<std::unique_ptr<Attribute>> & conds)
271{
272 auto query_id = queryID(conds);
273 std::lock_guard<std::mutex> lock(_obj_cache_mutex);
274 auto & objs = query(query_id);
275 std::size_t count = 0;
276 for (auto obj : objs)
277 if (obj->enabled())
278 count++;
279 return count;
280}
281
282void
284 std::vector<std::unique_ptr<Attribute>> & attribs)
285{
286 for (auto & ref : _attrib_list)
287 {
288 attribs.emplace_back(ref->clone());
289 attribs.back()->initFrom(obj);
290 }
291}
292
293void
295{
296 auto blk = dynamic_cast<BlockRestrictable *>(obj);
297 if (!blk)
298 return;
299
300 // Check variables
301 auto c_ptr = dynamic_cast<Coupleable *>(obj);
302 if (c_ptr)
303 for (MooseVariableFEBase * var : c_ptr->getCoupledMooseVars())
304 blk->checkVariable(*var);
305
306 const InputParameters & parameters = obj->parameters();
307
308 SubProblem & problem = *parameters.get<SubProblem *>("_subproblem");
309
310 THREAD_ID tid = parameters.get<THREAD_ID>("_tid");
311
312 if (parameters.isParamValid("variable"))
313 {
314 // Try the scalar version first
315 std::string variable_name = parameters.getMooseType("variable");
316 if (variable_name == "")
317 // When using vector variables, we are only going to use the first one in the list at the
318 // interface level...
319 variable_name = parameters.getVecMooseType("variable")[0];
320
321 blk->checkVariable(problem.getVariable(
323 }
324}
unsigned int THREAD_ID
Definition MooseTypes.h:237
unsigned int count
Definition MortarUtils.C:53
bool operator==(const std::unique_ptr< Attribute > &lhs, const std::unique_ptr< Attribute > &rhs)
TheWarehouse uses this operator function for indexing and caching queries.
void isValid(MooseObject *obj)
This attribute describes sorting state.
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.
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.
virtual void initFrom(const MooseObject *obj) override
initFrom reads and stores the desired meta-data from obj for later matching comparisons.
Attribute is an abstract class that can be implemented in order to track custom metadata about MooseO...
Attribute(TheWarehouse &w, const std::string name)
Constructs/initializes a new attribute with the specified name for use in warehouse w.
virtual std::unique_ptr< Attribute > clone() const =0
clone creates and returns and identical (deep) copy of this attribute - i.e.
An interface that restricts an object to subdomains via the 'blocks' input parameter.
Interface for objects that needs coupling capabilities.
Definition Coupleable.h:53
Interface for sorting dependent vectors of objects.
static void sort(typename std::vector< T > &vector)
Given a vector, sort using the getRequested/SuppliedItems sets.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
std::string getMooseType(const std::string &name) const
Utility functions for retrieving one of the MooseTypes variables into the common "string" base class.
std::vector< std::string > getVecMooseType(const std::string &name) const
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.
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another,...
const InputParameters & parameters() const
Get the parameters of the object.
Definition MooseBase.h:131
Every object that can be built by the factory should be derived from this class.
Definition MooseObject.h:31
This class provides an interface for common operations on field variables of both FE and FV types wit...
Generic class for solving transient nonlinear problems.
Definition SubProblem.h:79
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...
TheWarehouse is a container for MooseObjects that allows querying/filtering over various customizeabl...
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).
std::mutex _query_cache_mutex
std::mutex _obj_mutex
Query query()
query creates and returns an initialized a query object for querying objects from the warehouse.
std::vector< std::shared_ptr< MooseObject > > _objects
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...
std::size_t count(const std::vector< std::unique_ptr< Attribute > > &conds)
count returns the number of objects that match the provided query conditions.
std::unordered_map< MooseObject *, std::size_t > _obj_ids
void readAttribs(const MooseObject *obj, std::vector< std::unique_ptr< Attribute > > &attribs)
void update(MooseObject *obj)
update updates the metadata/attribute-info stored for the given object obj that must already exists i...
std::vector< std::vector< MooseObject * > > _obj_cache
std::unique_ptr< WarehouseStorage > _store
std::mutex _obj_cache_mutex
std::unordered_map< std::vector< std::unique_ptr< Attribute > >, int > _query_cache
std::size_t queryID(const std::vector< std::unique_ptr< Attribute > > &conds)
std::vector< std::unique_ptr< Attribute > > _attrib_list
virtual void set(std::size_t obj_id, std::vector< std::unique_ptr< Attribute > > attribs) override
virtual void add(std::size_t obj_id, std::vector< std::unique_ptr< Attribute > > attribs) override
virtual std::vector< std::size_t > query(const std::vector< std::unique_ptr< Attribute > > &conds) override
std::vector< std::vector< std::unique_ptr< Attribute > > > _data
std::mutex _mutex
virtual void set(std::size_t obj_id, std::vector< std::unique_ptr< Attribute > > attribs)=0
virtual std::vector< std::size_t > query(const std::vector< std::unique_ptr< Attribute > > &conds)=0
virtual ~WarehouseStorage()=default
virtual void add(std::size_t obj_id, std::vector< std::unique_ptr< Attribute > > attribs)=0
@ VAR_FIELD_ANY
Definition MooseTypes.h:781
@ VAR_ANY
Definition MooseTypes.h:772