https://mooseframework.inl.gov
MaterialProperty.h
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 #pragma once
11 
12 #include <vector>
13 #include <memory>
14 #include <typeinfo>
15 
16 #include "MooseArray.h"
17 #include "MooseTypes.h"
18 #include "DataIO.h"
19 #include "MooseError.h"
20 #include "UniqueStorage.h"
21 #include "MooseUtils.h"
22 
23 #include "libmesh/libmesh_common.h"
24 #include "libmesh/tensor_value.h"
25 #include "libmesh/vector_value.h"
26 #include "libmesh/int_range.h"
27 
28 #include "metaphysicl/raw_type.h"
29 
30 class PropertyValue;
31 class Material;
33 
38 {
39 public:
41  typedef unsigned int id_type;
42 
43  PropertyValue(const id_type id) : _id(id) {}
44 
45  virtual ~PropertyValue(){};
46 
51 
55  id_type id() const { return _id; }
56 
60  virtual const std::string & type() const = 0;
61 
65  virtual std::unique_ptr<PropertyValue> clone(const std::size_t) const = 0;
66 
67  virtual unsigned int size() const = 0;
68 
72  virtual void resize(const std::size_t size) = 0;
73 
74  virtual void swap(PropertyValue & rhs) = 0;
75 
76  virtual bool isAD() const = 0;
77 
87  virtual void
88  qpCopy(const unsigned int to_qp, const PropertyValue & rhs, const unsigned int from_qp) = 0;
89 
90  // save/restore in a file
91  virtual void store(std::ostream & stream) = 0;
92  virtual void load(std::istream & stream) = 0;
93 
97  virtual const std::type_info & typeID() const = 0;
98 
99 protected:
101  const id_type _id;
102 };
103 
108 template <typename T, bool is_ad>
110 {
111 public:
113 
115 
116  bool isAD() const override final { return is_ad; }
117 
121  const MooseArray<Moose::GenericType<T, is_ad>> & get() const { return _value; }
122 
127 
131  virtual const std::string & type() const override final;
132 
136  virtual void resize(const std::size_t size) override final;
137 
138  virtual unsigned int size() const override final { return _value.size(); }
139 
143  Moose::GenericType<T, is_ad> & operator[](const unsigned int i) { return _value[i]; }
144 
148  const Moose::GenericType<T, is_ad> & operator[](const unsigned int i) const { return _value[i]; }
149 
157  virtual void qpCopy(const unsigned int to_qp,
158  const PropertyValue & rhs,
159  const unsigned int from_qp) override final;
160 
164  virtual void store(std::ostream & stream) override final;
165 
169  virtual void load(std::istream & stream) override final;
170 
171  virtual void swap(PropertyValue & rhs) override final;
172 
173  const std::type_info & typeID() const override final;
174 
182  virtual std::unique_ptr<PropertyValue> clone(const std::size_t size) const override final;
183 
184 private:
186  MaterialPropertyBase(const MaterialPropertyBase<T, is_ad> & /*src*/)
187  {
188  mooseError("Material properties must be assigned to references (missing '&')");
189  }
190 
193  {
194  mooseError("Material properties must be assigned to references (missing '&')");
195  }
196 
197 protected:
200 };
201 
202 template <typename T>
203 class MaterialProperty;
204 template <typename T>
206 
207 // ------------------------------------------------------------
208 // Material::Property<> class inline methods
209 
210 namespace moose
211 {
212 namespace internal
213 {
214 template <typename T1, typename T2>
215 void
216 rawValueEqualityHelper(T1 & out, const T2 & in)
217 {
219 }
220 
221 template <typename T1, typename T2>
222 void
223 rawValueEqualityHelper(std::vector<T1> & out, const std::vector<T2> & in)
224 {
225  out.resize(in.size());
226  for (MooseIndex(in) i = 0; i < in.size(); ++i)
227  rawValueEqualityHelper(out[i], in[i]);
228 }
229 
230 template <typename T1, typename T2, std::size_t N>
231 void
232 rawValueEqualityHelper(std::array<T1, N> & out, const std::array<T2, N> & in)
233 {
234  for (MooseIndex(in) i = 0; i < in.size(); ++i)
235  rawValueEqualityHelper(out[i], in[i]);
236 }
237 }
238 }
239 
240 template <typename T, bool is_ad>
241 inline const std::string &
243 {
244  static const std::string type_name = MooseUtils::prettyCppType<T>();
245  return type_name;
246 }
247 
248 template <typename T, bool is_ad>
249 inline void
251 {
252  _value.template resize</*value_initalize=*/true>(size);
253 }
254 
255 template <typename T, bool is_ad>
256 inline void
257 MaterialPropertyBase<T, is_ad>::qpCopy(const unsigned int to_qp,
258  const PropertyValue & rhs,
259  const unsigned int from_qp)
260 {
261  // If we're the same
262  if (rhs.isAD() == is_ad)
263  _value[to_qp] =
265  else
267  _value[to_qp],
268  (*libMesh::cast_ptr<const MaterialPropertyBase<T, !is_ad> *>(&rhs))[from_qp]);
269 }
270 
271 template <typename T, bool is_ad>
272 inline void
274 {
275  for (const auto i : index_range(_value))
276  storeHelper(stream, _value[i], nullptr);
277 }
278 
279 template <typename T, bool is_ad>
280 inline void
282 {
283  for (const auto i : index_range(_value))
284  loadHelper(stream, _value[i], nullptr);
285 }
286 
287 template <typename T, bool is_ad>
288 inline void
290 {
291  mooseAssert(this->id() == rhs.id(), "Inconsistent properties");
292  mooseAssert(this->typeID() == rhs.typeID(), "Inconsistent types");
293 
294  // If we're the same
295  if (rhs.isAD() == is_ad)
296  {
297  mooseAssert(dynamic_cast<decltype(this)>(&rhs), "Expected same type is not the same");
298  this->_value.swap(libMesh::cast_ptr<decltype(this)>(&rhs)->_value);
299  return;
300  }
301 
302  // We may call this function when doing swap between MaterialData material properties (you can
303  // think of these as the current element properties) and MaterialPropertyStorage material
304  // properties (these are the stateful material properties that we store for *every* element). We
305  // never store ADMaterialProperty in stateful storage (e.g. MaterialPropertyStorage) for memory
306  // resource reasons; instead we keep a regular MaterialProperty version of it. Hence we do have a
307  // need to exchange data between the AD and regular copies which we implement below. The below
308  // is obviously not a swap, for which you cannot identify a giver and receiver. Instead the below
309  // has a clear giver and receiver. The giver is the object passed in as the rhs. The receiver is
310  // *this* object. This directionality, although not conceptually appropriate given the method
311  // name, *is* appropriate to how this method is used in practice. See shallowCopyData and
312  // shallowCopyDataBack in MaterialPropertyStorage.C
313 
314  auto * different_type_prop = dynamic_cast<MaterialPropertyBase<T, !is_ad> *>(&rhs);
315  mooseAssert(different_type_prop,
316  "Wrong material property type T in MaterialPropertyBase<T, is_ad>::swap");
317 
318  this->resize(different_type_prop->size());
319  for (const auto qp : make_range(this->size()))
320  moose::internal::rawValueEqualityHelper(this->_value[qp], (*different_type_prop)[qp]);
321 }
322 
323 template <typename T, bool is_ad>
324 inline const std::type_info &
326 {
327  static const auto & info = typeid(T);
328  return info;
329 }
330 
331 template <typename T, bool is_ad>
332 std::unique_ptr<PropertyValue>
333 MaterialPropertyBase<T, is_ad>::clone(const std::size_t size) const
334 {
335  auto prop = std::make_unique<MaterialProperty<T>>(this->id());
336  if (size)
337  prop->resize(size);
338  return prop;
339 }
340 
341 template <typename T>
342 class MaterialProperty : public MaterialPropertyBase<T, false>
343 {
344 public:
346  : MaterialPropertyBase<T, false>(id)
347  {
348  }
349 
350 private:
353  {
354  mooseError("Material properties must be assigned to references (missing '&')");
355  }
356 
359  {
360  mooseError("Material properties must be assigned to references (missing '&')");
361  }
362 };
363 
364 template <typename T>
365 class ADMaterialProperty : public MaterialPropertyBase<T, true>
366 {
367 public:
369  : MaterialPropertyBase<T, true>(id)
370  {
371  }
372 
374 
375 private:
378  {
379  mooseError("Material properties must be assigned to references (missing '&')");
380  }
381 
384  {
385  mooseError("Material properties must be assigned to references (missing '&')");
386  }
387 };
388 
389 class MaterialData;
391 
392 class MaterialProperties : public UniqueStorage<PropertyValue>
393 {
394 public:
395  class WriteKey
396  {
397  friend class MaterialData;
399  friend void dataLoad(std::istream &, MaterialPropertyStorage &, void *);
400 
401  WriteKey() {}
402  WriteKey(const WriteKey &) {}
403  };
404 
410  void resizeItems(const std::size_t n_qpoints, const WriteKey)
411  {
412  for (const auto i : index_range(*this))
413  if (auto value = queryValue(i))
414  value->resize(n_qpoints);
415  }
416 
417  void resize(const std::size_t size, const WriteKey)
418  {
420  }
421 
422  void setPointer(const std::size_t i, std::unique_ptr<PropertyValue> && ptr, const WriteKey)
423  {
424  return UniqueStorage<PropertyValue>::setPointer(i, std::move(ptr));
425  }
426 };
427 
428 template <typename T, bool is_ad>
430 {
432 };
433 
434 template <typename T>
436 {
438 };
439 
440 template <typename T, bool is_ad>
442 
447 {
448 public:
450 };
451 
452 template <class M, typename T, bool is_ad>
454 
460 template <typename T, bool is_ad>
462 {
464 
465 public:
466  GenericOptionalMaterialProperty(const P * pointer) : _pointer(pointer) {}
467 
473 
475  const Moose::GenericType<T, is_ad> & operator[](const unsigned int i) const
476  {
477  // check if the optional property is valid in debug mode
478  mooseAssert(
479  _pointer,
480  "Attempting to access an optional material property that was not provided by any material "
481  "class. Make sure to check optional material properties before using them.");
482  return (*_pointer)[i];
483  }
484 
486  unsigned int size() const { return (*_pointer).size(); }
487 
489  operator bool() const { return _pointer; }
490 
492  const P * get() const { return _pointer; }
493 
494 private:
497 
499  void set(const P * pointer) { _pointer = pointer; }
500  const P * _pointer;
501 
502  friend class OptionalMaterialPropertyProxy<Material, T, is_ad>;
504 };
505 
506 void dataStore(std::ostream & stream, PropertyValue & p, void * context);
507 void dataLoad(std::istream & stream, PropertyValue & p, void * context);
508 
509 void dataStore(std::ostream & stream, MaterialProperties & v, void * context);
510 void dataLoad(std::istream & stream, MaterialProperties & v, void * context);
511 
512 template <typename T>
514 template <typename T>
virtual void store(std::ostream &stream) override final
Store the property into a binary stream.
GenericOptionalMaterialProperty & operator=(const GenericOptionalMaterialProperty< T, is_ad > &)=delete
no copy assignment is permitted
virtual const std::string & type() const override final
String identifying the type of parameter stored.
virtual void qpCopy(const unsigned int to_qp, const PropertyValue &rhs, const unsigned int from_qp)=0
Copy the value of a Property from one specific to a specific qp in this Property. ...
MPI_Info info
MaterialProperty(const PropertyValue::id_type id=PropertyValue::invalid_property_id)
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:302
MaterialProperty(const MaterialProperty< T > &)
private copy constructor to avoid shallow copying of material properties
GenericOptionalMaterialProperty()
the default constructor is only called from the friend class
MaterialPropertyBase(const PropertyValue::id_type id)
virtual void resize(const std::size_t size)=0
Resizes the property to the size n.
ADMaterialProperty(const PropertyValue::id_type id=PropertyValue::invalid_property_id)
Tnew cast_ptr(Told *oldvar)
Storage container that stores a vector of unique pointers of T, but represents most of the public fac...
Definition: UniqueStorage.h:18
Stores the stateful material properties computed by materials.
unsigned int id_type
The type for a material property ID.
auto raw_value(const Eigen::Map< T > &in)
Definition: EigenADReal.h:73
void dataStore(std::ostream &stream, PropertyValue &p, void *context)
GenericMaterialProperty< T, is_ad > P
const Moose::GenericType< T, is_ad > & operator[](const unsigned int i) const
Get element i out of the array as a ready-only reference.
virtual std::unique_ptr< PropertyValue > clone(const std::size_t) const =0
Clone this value.
void setPointer(const std::size_t i, std::unique_ptr< T > &&ptr)
Sets the underlying unique_ptr at index i to ptr.
void resize(const std::size_t size, const WriteKey)
const Moose::GenericType< T, is_ad > & operator[](const unsigned int i) const
pass through operator[] to provide a similar API as MaterialProperty
void setPointer(const std::size_t i, std::unique_ptr< PropertyValue > &&ptr, const WriteKey)
bool isAD() const override final
typename std::conditional< is_ad, typename ADType< T >::type, T >::type GenericType
Definition: MooseTypes.h:644
virtual void resize(const std::size_t size) override final
Resizes the property to the size n.
auto max(const L &left, const R &right)
void resize(const std::size_t size)
Resizes the underlying vector.
GenericOptionalMaterialProperty(const P *pointer)
void storeHelper(std::ostream &stream, P &data, void *context)
Scalar helper routine.
Definition: DataIO.h:893
virtual void swap(PropertyValue &rhs)=0
Wrapper around a material property pointer.
MaterialProperty< T > type
unsigned int size() const
The number of elements that can currently be stored in the array.
Definition: MooseArray.h:259
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
void resizeItems(const std::size_t n_qpoints, const WriteKey)
Resize items in this array, i.e.
const PropertyValue * queryValue(const std::size_t i) const
virtual unsigned int size() const =0
typename GenericMaterialPropertyStruct< T, is_ad >::type GenericMaterialProperty
Moose::GenericType< T, is_ad > value_type
virtual const std::type_info & typeID() const =0
Abstract definition of a property value.
virtual ~PropertyValue()
virtual std::unique_ptr< PropertyValue > clone(const std::size_t size) const override final
unsigned int size() const
pass through size calls
virtual unsigned int size() const override final
Materials compute MaterialProperties.
Definition: Material.h:34
ADMaterialProperty(const ADMaterialProperty< T > &)
private copy constructor to avoid shallow copying of material properties
forward declarations
virtual void load(std::istream &stream) override final
Load the property from a binary stream.
MaterialPropertyBase< T, is_ad > & operator=(const MaterialPropertyBase< T, is_ad > &)
private assignment operator to avoid shallow copying of material properties
virtual void store(std::ostream &stream)=0
MooseArray< Moose::GenericType< T, is_ad > > _value
Stored parameter value.
An interface for accessing Materials.
OStreamProxy out
void rawValueEqualityHelper(T1 &out, const T2 &in)
id_type id() const
ADMaterialProperty< T > & operator=(const ADMaterialProperty< T > &)
private assignment operator to avoid shallow copying of material properties
IntRange< T > make_range(T beg, T end)
virtual void load(std::istream &stream)=0
friend void dataLoad(std::istream &, MaterialPropertyStorage &, void *)
static constexpr id_type invalid_property_id
The material property ID for an invalid property We only have this because there are a few cases wher...
Proxy for accessing MaterialPropertyStorage.
Definition: MaterialData.h:33
virtual bool isAD() const =0
virtual const std::string & type() const =0
String identifying the type of parameter stored.
MaterialProperty< T > & operator=(const MaterialProperty< T > &)
private assignment operator to avoid shallow copying of material properties
void dataLoad(std::istream &stream, PropertyValue &p, void *context)
Base class to facilitate storage using unique pointers.
virtual void swap(PropertyValue &rhs) override final
const std::type_info & typeID() const override final
void loadHelper(std::istream &stream, P &data, void *context)
Scalar helper routine.
Definition: DataIO.h:985
Moose::GenericType< T, is_ad > & operator[](const unsigned int i)
Get element i out of the array as a writeable reference.
auto index_range(const T &sizable)
Concrete definition of a parameter value for a specified type.
PropertyValue(const id_type id)
virtual void qpCopy(const unsigned int to_qp, const PropertyValue &rhs, const unsigned int from_qp) override final
Copy the value of a Property from one specific to a specific qp in this Property. ...
const id_type _id
The material property ID.