www.mooseframework.org
MaterialPropertyStorage.C
Go to the documentation of this file.
1 /****************************************************************/
2 /* DO NOT MODIFY THIS HEADER */
3 /* MOOSE - Multiphysics Object Oriented Simulation Environment */
4 /* */
5 /* (c) 2010 Battelle Energy Alliance, LLC */
6 /* ALL RIGHTS RESERVED */
7 /* */
8 /* Prepared by Battelle Energy Alliance, LLC */
9 /* Under Contract No. DE-AC07-05ID14517 */
10 /* With the U. S. Department of Energy */
11 /* */
12 /* See COPYRIGHT for full restrictions */
13 /****************************************************************/
14 
16 #include "Material.h"
17 #include "MaterialData.h"
18 #include "MooseMesh.h"
19 
20 #include "libmesh/fe_interface.h"
21 #include "libmesh/quadrature.h"
22 
23 std::map<std::string, unsigned int> MaterialPropertyStorage::_prop_ids;
24 
31 void
32 shallowCopyData(const std::vector<unsigned int> & stateful_prop_ids,
33  MaterialProperties & data,
34  MaterialProperties & data_from)
35 {
36  for (unsigned int i = 0; i < stateful_prop_ids.size(); ++i)
37  {
38  if (i >= data_from.size() || stateful_prop_ids[i] >= data.size())
39  continue;
40  PropertyValue * prop = data[stateful_prop_ids[i]]; // do the look-up just once (OPT)
41  PropertyValue * prop_from = data_from[i]; // do the look-up just once (OPT)
42  if (prop != nullptr && prop_from != nullptr)
43  prop->swap(prop_from);
44  }
45 }
46 
47 void
48 shallowCopyDataBack(const std::vector<unsigned int> & stateful_prop_ids,
49  MaterialProperties & data,
50  MaterialProperties & data_from)
51 {
52  for (unsigned int i = 0; i < stateful_prop_ids.size(); ++i)
53  {
54  if (i >= data.size() || stateful_prop_ids[i] >= data_from.size())
55  continue;
56  PropertyValue * prop = data[i]; // do the look-up just once (OPT)
57  PropertyValue * prop_from = data_from[stateful_prop_ids[i]]; // do the look-up just once (OPT)
58  if (prop != nullptr && prop_from != nullptr)
59  prop->swap(prop_from);
60  }
61 }
62 
64  : _has_stateful_props(false), _has_older_prop(false)
65 {
69 }
70 
72 {
74 
75  delete _props_elem;
76  delete _props_elem_old;
77  delete _props_elem_older;
78 }
79 
80 void
82 {
83  for (auto & i : *_props_elem)
84  for (auto & j : i.second)
85  j.second.destroy();
86 
87  for (auto & i : *_props_elem_old)
88  for (auto & j : i.second)
89  j.second.destroy();
90 
91  for (auto & i : *_props_elem_older)
92  for (auto & j : i.second)
93  j.second.destroy();
94 }
95 
96 void
98  const std::vector<std::vector<QpMap>> & refinement_map,
99  QBase & qrule,
100  QBase & qrule_face,
101  MaterialPropertyStorage & parent_material_props,
102  MaterialData & child_material_data,
103  const Elem & elem,
104  const int input_parent_side,
105  const int input_child,
106  const int input_child_side)
107 {
108  mooseAssert(input_child != -1 || input_parent_side == input_child_side, "Invalid inputs!");
109 
110  unsigned int n_qpoints = 0;
111 
112  // If we passed in -1 for these then we really need to store properties at 0
113  unsigned int parent_side = input_parent_side == -1 ? 0 : input_parent_side;
114  unsigned int child_side = input_child_side == -1 ? 0 : input_child_side;
115 
116  if (input_child_side == -1) // Not doing side projection (ie, doing volume projection)
117  n_qpoints = qrule.n_points();
118  else
119  n_qpoints = qrule_face.n_points();
120 
121  child_material_data.resize(n_qpoints);
122 
123  unsigned int n_children = elem.n_children();
124 
125  std::vector<unsigned int> children;
126 
127  if (input_child != -1) // Passed in a child explicitly
128  children.push_back(input_child);
129  else
130  {
131  children.resize(n_children);
132  for (unsigned int child = 0; child < n_children; child++)
133  children[child] = child;
134  }
135 
136  for (const auto & child : children)
137  {
138  // If we're not projecting an internal child side, but we are projecting sides, see if this
139  // child is on that side
140  if (input_child == -1 && input_child_side != -1 && !elem.is_child_on_side(child, parent_side))
141  continue;
142 
143  const Elem * child_elem = elem.child(child);
144 
145  mooseAssert(child < refinement_map.size(), "Refinement_map vector not initialized");
146  const std::vector<QpMap> & child_map = refinement_map[child];
147 
148  initProps(child_material_data, *child_elem, child_side, n_qpoints);
149 
150  for (unsigned int i = 0; i < _stateful_prop_id_to_prop_id.size(); ++i)
151  {
152  // Copy from the parent stateful properties
153  for (unsigned int qp = 0; qp < refinement_map[child].size(); qp++)
154  {
155  PropertyValue * child_property = props(child_elem, child_side)[i];
156  mooseAssert(props().contains(&elem),
157  "Parent pointer is not in the MaterialProps data structure");
158  PropertyValue * parent_property = parent_material_props.props(&elem, parent_side)[i];
159 
160  child_property->qpCopy(qp, parent_property, child_map[qp]._to);
161  propsOld(child_elem, child_side)[i]->qpCopy(
162  qp, parent_material_props.propsOld(&elem, parent_side)[i], child_map[qp]._to);
163  if (hasOlderProperties())
164  propsOlder(child_elem, child_side)[i]->qpCopy(
165  qp, parent_material_props.propsOlder(&elem, parent_side)[i], child_map[qp]._to);
166  }
167  }
168  }
169 }
170 
171 void
173  const std::vector<std::pair<unsigned int, QpMap>> & coarsening_map,
174  const std::vector<const Elem *> & coarsened_element_children,
175  QBase & qrule,
176  QBase & qrule_face,
177  MaterialData & material_data,
178  const Elem & elem,
179  int input_side)
180 {
181  unsigned int side;
182 
183  bool doing_a_side = input_side != -1;
184 
185  unsigned int n_qpoints = 0;
186 
187  if (!doing_a_side)
188  {
189  side = 0; // Use 0 for the elem
190  n_qpoints = qrule.n_points();
191  }
192  else
193  {
194  side = input_side;
195  n_qpoints = qrule_face.n_points();
196  }
197 
198  initProps(material_data, elem, side, n_qpoints);
199 
200  // Copy from the child stateful properties
201  for (unsigned int qp = 0; qp < coarsening_map.size(); qp++)
202  {
203  const std::pair<unsigned int, QpMap> & qp_pair = coarsening_map[qp];
204  unsigned int child = qp_pair.first;
205 
206  mooseAssert(child < coarsened_element_children.size(),
207  "Coarsened element children vector not initialized");
208  const Elem * child_elem = coarsened_element_children[child];
209  const QpMap & qp_map = qp_pair.second;
210 
211  for (unsigned int i = 0; i < _stateful_prop_id_to_prop_id.size(); ++i)
212  {
213  mooseAssert(props().contains(child_elem),
214  "Child element pointer is not in the MaterialProps data structure");
215 
216  PropertyValue * child_property = props(child_elem, side)[i];
217  PropertyValue * parent_property = props(&elem, side)[i];
218 
219  parent_property->qpCopy(qp, child_property, qp_map._to);
220 
221  propsOld(&elem, side)[i]->qpCopy(qp, propsOld(child_elem, side)[i], qp_map._to);
222  if (hasOlderProperties())
223  propsOlder(&elem, side)[i]->qpCopy(qp, propsOlder(child_elem, side)[i], qp_map._to);
224  }
225  }
226 }
227 
228 void
230  const std::vector<std::shared_ptr<Material>> & mats,
231  unsigned int n_qpoints,
232  const Elem & elem,
233  unsigned int side /* = 0*/)
234 {
235  // NOTE: since materials are storing their computed properties in MaterialData class, we need to
236  // juggle the memory between MaterialData and MaterialProperyStorage classes
237 
238  initProps(material_data, elem, side, n_qpoints);
239 
240  // copy from storage to material data
241  swap(material_data, elem, side);
242  // run custom init on properties
243  for (const auto & mat : mats)
244  mat->initStatefulProperties(n_qpoints);
245 
246  swapBack(material_data, elem, side);
247 
248  if (!hasStatefulProperties())
249  return;
250 
251  // This second call to initProps covers cases where code in
252  // "init[Qp]StatefulProperties" may have called a get/declare for a stateful
253  // property affecting the _stateful_prop_id_to_prop_id vector among other
254  // things. This is necessary because a call to
255  // getMaterialProperty[Old/Older] can potentially trigger a material to
256  // become stateful that previously wasn't. This needs to go after the
257  // swapBack.
258  initProps(material_data, elem, side, n_qpoints);
259 
260  // Copy the properties to Old and Older as needed
261  for (unsigned int i = 0; i < _stateful_prop_id_to_prop_id.size(); ++i)
262  {
263  auto curr = props(&elem, side)[i];
264  auto old = propsOld(&elem, side)[i];
265  auto older = propsOlder(&elem, side)[i];
266  for (unsigned int qp = 0; qp < n_qpoints; ++qp)
267  {
268  old->qpCopy(qp, curr, qp);
269  if (hasOlderProperties())
270  older->qpCopy(qp, curr, qp);
271  }
272  }
273 }
274 
275 void
277 {
278  if (_has_older_prop)
279  {
280  // shift the properties back in time and reuse older for current (save reallocations etc.)
284  _props_elem = tmp;
285  }
286  else
287  {
289  }
290 }
291 
292 void
294  const Elem & elem_to,
295  const Elem & elem_from,
296  unsigned int side,
297  unsigned int n_qpoints)
298 {
299  initProps(material_data, elem_to, side, n_qpoints);
300  for (unsigned int i = 0; i < _stateful_prop_id_to_prop_id.size(); ++i)
301  {
302  for (unsigned int qp = 0; qp < n_qpoints; ++qp)
303  {
304  props(&elem_to, side)[i]->qpCopy(qp, props(&elem_from, side)[i], qp);
305  propsOld(&elem_to, side)[i]->qpCopy(qp, propsOld(&elem_from, side)[i], qp);
306  if (hasOlderProperties())
307  propsOlder(&elem_to, side)[i]->qpCopy(qp, propsOlder(&elem_from, side)[i], qp);
308  }
309  }
310 }
311 
312 void
313 MaterialPropertyStorage::swap(MaterialData & material_data, const Elem & elem, unsigned int side)
314 {
315  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
316 
317  shallowCopyData(_stateful_prop_id_to_prop_id, material_data.props(), props(&elem, side));
318  shallowCopyData(_stateful_prop_id_to_prop_id, material_data.propsOld(), propsOld(&elem, side));
319  if (hasOlderProperties())
321  _stateful_prop_id_to_prop_id, material_data.propsOlder(), propsOlder(&elem, side));
322 }
323 
324 void
326  const Elem & elem,
327  unsigned int side)
328 {
329  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
330 
331  shallowCopyDataBack(_stateful_prop_id_to_prop_id, props(&elem, side), material_data.props());
333  _stateful_prop_id_to_prop_id, propsOld(&elem, side), material_data.propsOld());
334  if (hasOlderProperties())
336  _stateful_prop_id_to_prop_id, propsOlder(&elem, side), material_data.propsOlder());
337 }
338 
339 bool
340 MaterialPropertyStorage::hasProperty(const std::string & prop_name) const
341 {
342  return _prop_ids.count(prop_name) > 0;
343 }
344 
345 unsigned int
346 MaterialPropertyStorage::addProperty(const std::string & prop_name)
347 {
348  return getPropertyId(prop_name);
349 }
350 
351 unsigned int
352 MaterialPropertyStorage::addPropertyOld(const std::string & prop_name)
353 {
354  unsigned int prop_id = addProperty(prop_name);
355  _has_stateful_props = true;
356 
357  if (std::find(_stateful_prop_id_to_prop_id.begin(),
359  prop_id) == _stateful_prop_id_to_prop_id.end())
360  _stateful_prop_id_to_prop_id.push_back(prop_id);
361  _prop_names[prop_id] = prop_name;
362 
363  return prop_id;
364 }
365 
366 unsigned int
367 MaterialPropertyStorage::addPropertyOlder(const std::string & prop_name)
368 {
369  _has_older_prop = true;
370  return addPropertyOld(prop_name);
371 }
372 
373 unsigned int
374 MaterialPropertyStorage::getPropertyId(const std::string & prop_name)
375 {
376  auto it = _prop_ids.find(prop_name);
377  if (it != _prop_ids.end())
378  return it->second;
379 
380  auto id = _prop_ids.size();
381  _prop_ids[prop_name] = id;
382  return id;
383 }
384 
385 unsigned int
386 MaterialPropertyStorage::retrievePropertyId(const std::string & prop_name) const
387 {
388  auto it = _prop_ids.find(prop_name);
389  if (it == _prop_ids.end())
390  mooseError("MaterialPropertyStorage: property " + prop_name + " is not yet declared");
391  return it->second;
392 }
393 
394 void
396  const Elem & elem,
397  unsigned int side,
398  unsigned int n_qpoints)
399 {
400  material_data.resize(n_qpoints);
401  auto n = _stateful_prop_id_to_prop_id.size();
402 
403  if (props(&elem, side).size() < n)
404  props(&elem, side).resize(n, nullptr);
405  if (propsOld(&elem, side).size() < n)
406  propsOld(&elem, side).resize(n, nullptr);
407  if (propsOlder(&elem, side).size() < n)
408  propsOlder(&elem, side).resize(n, nullptr);
409 
410  // init properties (allocate memory. etc)
411  for (unsigned int i = 0; i < n; i++)
412  {
413  auto prop_id = _stateful_prop_id_to_prop_id[i];
414  // duplicate the stateful property in property storage (all three states - we will reuse the
415  // allocated memory there)
416  // also allocating the right amount of memory, so we do not have to resize, etc.
417  if (props(&elem, side)[i] == nullptr)
418  props(&elem, side)[i] = material_data.props()[prop_id]->init(n_qpoints);
419  if (propsOld(&elem, side)[i] == nullptr)
420  propsOld(&elem, side)[i] = material_data.propsOld()[prop_id]->init(n_qpoints);
421  if (hasOlderProperties() && propsOlder(&elem, side)[i] == nullptr)
422  propsOlder(&elem, side)[i] = material_data.propsOlder()[prop_id]->init(n_qpoints);
423  }
424 }
void shift()
Shift the material properties in time.
bool _has_stateful_props
Whether or not we have stateful properties.
HashMap is an abstraction for dictionary data type, we make it thread-safe by locking inserts...
Definition: HashMap.h:24
virtual void swap(PropertyValue *rhs)=0
unsigned int addProperty(const std::string &prop_name)
The addProperty functions are idempotent - calling multiple times with the same name will provide the...
void initStatefulProps(MaterialData &material_data, const std::vector< std::shared_ptr< Material >> &mats, unsigned int n_qpoints, const Elem &elem, unsigned int side=0)
Initialize stateful material properties.
unsigned int retrievePropertyId(const std::string &prop_name) const
Container for storing material properties.
unsigned int addPropertyOld(const std::string &prop_name)
void shallowCopyDataBack(const std::vector< unsigned int > &stateful_prop_ids, MaterialProperties &data, MaterialProperties &data_from)
void mooseError(Args &&...args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:182
HashMap< const Elem *, HashMap< unsigned int, MaterialProperties > > & propsOld()
Stores the stateful material properties computed by materials.
std::vector< unsigned int > _stateful_prop_id_to_prop_id
the vector of stateful property ids (the vector index is the map to stateful prop_id) ...
Helper object for holding qp mapping info.
Definition: MooseMesh.h:55
unsigned int addPropertyOlder(const std::string &prop_name)
unsigned int _to
The qp to map to.
Definition: MooseMesh.h:64
virtual void qpCopy(const unsigned int to_qp, PropertyValue *rhs, const unsigned int from_qp)=0
Copy the value of a Property from one specific to a specific qp in this Property. ...
void copy(MaterialData &material_data, const Elem &elem_to, const Elem &elem_from, unsigned int side, unsigned int n_qpoints)
Copy material properties from elem_from to elem_to.
void restrictStatefulProps(const std::vector< std::pair< unsigned int, QpMap >> &coarsening_map, const std::vector< const Elem * > &coarsened_element_children, QBase &qrule, QBase &qrule_face, MaterialData &material_data, const Elem &elem, int input_side=-1)
Creates storage for newly created elements from mesh Adaptivity.
MaterialProperties & propsOld()
Definition: MaterialData.h:98
MaterialProperties & propsOlder()
Definition: MaterialData.h:99
void initProps(MaterialData &material_data, const Elem &elem, unsigned int side, unsigned int n_qpoints)
Initializes hashmap entries for element and side to proper qpoint and property count sizes...
unsigned int getPropertyId(const std::string &prop_name)
Returns the property ID for the given prop_name, adding the property and creating a new ID if it hasn...
HashMap< const Elem *, HashMap< unsigned int, MaterialProperties > > & propsOlder()
Abstract definition of a property value.
X_global swap(X_sys)
void swap(MaterialData &material_data, const Elem &elem, unsigned int side)
Swap (shallow copy) material properties in MaterialData and MaterialPropertyStorage Thread safe...
static std::map< std::string, unsigned int > _prop_ids
mapping from property name to property ID NOTE: this is static so the property numbering is global wi...
std::map< unsigned int, std::string > _prop_names
mapping from property ID to property name
bool hasProperty(const std::string &prop_name) const
HashMap< const Elem *, HashMap< unsigned int, MaterialProperties > > * _props_elem
void swapBack(MaterialData &material_data, const Elem &elem, unsigned int side)
Swap (shallow copy) material properties in MaterialPropertyStorage and MaterialDat Thread safe...
PetscInt n
HashMap< const Elem *, HashMap< unsigned int, MaterialProperties > > & props()
Access methods to the stored material property data.
bool _has_older_prop
True if any material requires older properties to be computed.
void prolongStatefulProps(const std::vector< std::vector< QpMap >> &refinement_map, QBase &qrule, QBase &qrule_face, MaterialPropertyStorage &parent_material_props, MaterialData &child_material_data, const Elem &elem, const int input_parent_side, const int input_child, const int input_child_side)
Creates storage for newly created elements from mesh Adaptivity.
Proxy for accessing MaterialPropertyStorage.
Definition: MaterialData.h:33
void shallowCopyData(const std::vector< unsigned int > &stateful_prop_ids, MaterialProperties &data, MaterialProperties &data_from)
Shallow copy the material properties.
MaterialProperties & props()
Methods for retrieving MaterialProperties object.
Definition: MaterialData.h:97
HashMap< const Elem *, HashMap< unsigned int, MaterialProperties > > * _props_elem_older
void resize(unsigned int n_qpoints)
Resize the data to hold properties for n_qpoints quadrature points.
Definition: MaterialData.C:34
HashMap< const Elem *, HashMap< unsigned int, MaterialProperties > > * _props_elem_old