www.mooseframework.org
MaterialProperty.h
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 #pragma once
11 
12 #include <vector>
13 #include <memory>
14 #include <typeinfo>
15 
16 #include "MooseADWrapper.h"
17 #include "MooseArray.h"
18 #include "MooseTypes.h"
19 #include "DataIO.h"
20 #include "MooseError.h"
21 #include "UniqueStorage.h"
22 #include "MooseUtils.h"
23 
24 #include "libmesh/libmesh_common.h"
25 #include "libmesh/tensor_value.h"
26 #include "libmesh/vector_value.h"
27 #include "libmesh/int_range.h"
28 
29 #include "metaphysicl/raw_type.h"
30 
31 class PropertyValue;
32 class Material;
34 
39 {
40 public:
42  typedef unsigned int id_type;
43 
44  PropertyValue(const id_type id) : _id(id) {}
45 
46  virtual ~PropertyValue(){};
47 
52 
56  id_type id() const { return _id; }
57 
61  virtual const std::string & type() const = 0;
62 
66  virtual std::unique_ptr<PropertyValue> clone(const std::size_t) const = 0;
67 
68  virtual unsigned int size() const = 0;
69 
73  virtual void resize(const std::size_t size) = 0;
74 
75  virtual void swap(PropertyValue & rhs) = 0;
76 
77  virtual bool isAD() const = 0;
78 
88  virtual void
89  qpCopy(const unsigned int to_qp, const PropertyValue & rhs, const unsigned int from_qp) = 0;
90 
91  // save/restore in a file
92  virtual void store(std::ostream & stream) = 0;
93  virtual void load(std::istream & stream) = 0;
94 
98  virtual const std::type_info & typeID() const = 0;
99 
100 protected:
102  const id_type _id;
103 };
104 
109 template <typename T, bool is_ad>
111 {
112 public:
114 
116 
117  bool isAD() const override final { return is_ad; }
118 
122  const MooseArray<MooseADWrapper<T, is_ad>> & get() const { return _value; }
123 
128 
132  virtual const std::string & type() const override final;
133 
137  virtual void resize(const std::size_t size) override final;
138 
139  virtual unsigned int size() const override final { return _value.size(); }
140 
144  MooseADWrapper<T, is_ad> & operator[](const unsigned int i) { return _value[i]; }
145 
149  const MooseADWrapper<T, is_ad> & operator[](const unsigned int i) const { return _value[i]; }
150 
158  virtual void qpCopy(const unsigned int to_qp,
159  const PropertyValue & rhs,
160  const unsigned int from_qp) override final;
161 
165  virtual void store(std::ostream & stream) override final;
166 
170  virtual void load(std::istream & stream) override final;
171 
172  virtual void swap(PropertyValue & rhs) override final;
173 
174  const std::type_info & typeID() const override final;
175 
183  virtual std::unique_ptr<PropertyValue> clone(const std::size_t size) const override final;
184 
185 private:
187  MaterialPropertyBase(const MaterialPropertyBase<T, is_ad> & /*src*/)
188  {
189  mooseError("Material properties must be assigned to references (missing '&')");
190  }
191 
194  {
195  mooseError("Material properties must be assigned to references (missing '&')");
196  }
197 
198 protected:
201 };
202 
203 template <typename T>
204 class MaterialProperty;
205 template <typename T>
207 
208 // ------------------------------------------------------------
209 // Material::Property<> class inline methods
210 
211 namespace moose
212 {
213 namespace internal
214 {
215 template <typename T1, typename T2>
216 void
217 rawValueEqualityHelper(T1 & out, const T2 & in)
218 {
220 }
221 
222 template <typename T1, typename T2>
223 void
224 rawValueEqualityHelper(std::vector<T1> & out, const std::vector<T2> & in)
225 {
226  out.resize(in.size());
227  for (MooseIndex(in) i = 0; i < in.size(); ++i)
228  rawValueEqualityHelper(out[i], in[i]);
229 }
230 
231 template <typename T1, typename T2, std::size_t N>
232 void
233 rawValueEqualityHelper(std::array<T1, N> & out, const std::array<T2, N> & in)
234 {
235  for (MooseIndex(in) i = 0; i < in.size(); ++i)
236  rawValueEqualityHelper(out[i], in[i]);
237 }
238 }
239 }
240 
241 template <typename T, bool is_ad>
242 inline const std::string &
244 {
245  static const std::string type_name = MooseUtils::prettyCppType<T>();
246  return type_name;
247 }
248 
249 template <typename T, bool is_ad>
250 inline void
252 {
253  _value.template resize</*value_initalize=*/true>(size);
254 }
255 
256 template <typename T, bool is_ad>
257 inline void
258 MaterialPropertyBase<T, is_ad>::qpCopy(const unsigned int to_qp,
259  const PropertyValue & rhs,
260  const unsigned int from_qp)
261 {
262  // If we're the same
263  if (rhs.isAD() == is_ad)
264  _value[to_qp] = cast_ptr<const MaterialPropertyBase<T, is_ad> *>(&rhs)->_value[from_qp];
265  else
267  _value[to_qp], (*cast_ptr<const MaterialPropertyBase<T, !is_ad> *>(&rhs))[from_qp]);
268 }
269 
270 template <typename T, bool is_ad>
271 inline void
273 {
274  for (const auto i : index_range(_value))
275  storeHelper(stream, _value[i], nullptr);
276 }
277 
278 template <typename T, bool is_ad>
279 inline void
281 {
282  for (const auto i : index_range(_value))
283  loadHelper(stream, _value[i], nullptr);
284 }
285 
286 template <typename T, bool is_ad>
287 inline void
289 {
290  mooseAssert(this->id() == rhs.id(), "Inconsistent properties");
291  mooseAssert(this->typeID() == rhs.typeID(), "Inconsistent types");
292 
293  // If we're the same
294  if (rhs.isAD() == is_ad)
295  {
296  mooseAssert(dynamic_cast<decltype(this)>(&rhs), "Expected same type is not the same");
297  this->_value.swap(cast_ptr<decltype(this)>(&rhs)->_value);
298  return;
299  }
300 
301  // We may call this function when doing swap between MaterialData material properties (you can
302  // think of these as the current element properties) and MaterialPropertyStorage material
303  // properties (these are the stateful material properties that we store for *every* element). We
304  // never store ADMaterialProperty in stateful storage (e.g. MaterialPropertyStorage) for memory
305  // resource reasons; instead we keep a regular MaterialProperty version of it. Hence we do have a
306  // need to exchange data between the AD and regular copies which we implement below. The below
307  // is obviously not a swap, for which you cannot identify a giver and receiver. Instead the below
308  // has a clear giver and receiver. The giver is the object passed in as the rhs. The receiver is
309  // *this* object. This directionality, although not conceptually appropriate given the method
310  // name, *is* appropriate to how this method is used in practice. See shallowCopyData and
311  // shallowCopyDataBack in MaterialPropertyStorage.C
312 
313  auto * different_type_prop = dynamic_cast<MaterialPropertyBase<T, !is_ad> *>(&rhs);
314  mooseAssert(different_type_prop,
315  "Wrong material property type T in MaterialPropertyBase<T, is_ad>::swap");
316 
317  this->resize(different_type_prop->size());
318  for (const auto qp : make_range(this->size()))
319  moose::internal::rawValueEqualityHelper(this->_value[qp], (*different_type_prop)[qp]);
320 }
321 
322 template <typename T, bool is_ad>
323 inline const std::type_info &
325 {
326  static const auto & info = typeid(T);
327  return info;
328 }
329 
330 template <typename T, bool is_ad>
331 std::unique_ptr<PropertyValue>
332 MaterialPropertyBase<T, is_ad>::clone(const std::size_t size) const
333 {
334  auto prop = std::make_unique<MaterialProperty<T>>(this->id());
335  if (size)
336  prop->resize(size);
337  return prop;
338 }
339 
340 template <typename T>
341 class MaterialProperty : public MaterialPropertyBase<T, false>
342 {
343 public:
345  : MaterialPropertyBase<T, false>(id)
346  {
347  }
348 
349 private:
352  {
353  mooseError("Material properties must be assigned to references (missing '&')");
354  }
355 
358  {
359  mooseError("Material properties must be assigned to references (missing '&')");
360  }
361 };
362 
363 template <typename T>
364 class ADMaterialProperty : public MaterialPropertyBase<T, true>
365 {
366 public:
368  : MaterialPropertyBase<T, true>(id)
369  {
370  }
371 
373 
374 private:
377  {
378  mooseError("Material properties must be assigned to references (missing '&')");
379  }
380 
383  {
384  mooseError("Material properties must be assigned to references (missing '&')");
385  }
386 };
387 
388 class MaterialData;
390 
391 class MaterialProperties : public UniqueStorage<PropertyValue>
392 {
393 public:
394  class WriteKey
395  {
396  friend class MaterialData;
398  friend void dataLoad(std::istream &, MaterialPropertyStorage &, void *);
399 
400  WriteKey() {}
401  WriteKey(const WriteKey &) {}
402  };
403 
409  void resizeItems(const std::size_t n_qpoints, const WriteKey)
410  {
411  for (const auto i : index_range(*this))
412  if (auto value = queryValue(i))
413  value->resize(n_qpoints);
414  }
415 
416  void resize(const std::size_t size, const WriteKey)
417  {
419  }
420 
421  void setPointer(const std::size_t i, std::unique_ptr<PropertyValue> && ptr, const WriteKey)
422  {
423  return UniqueStorage<PropertyValue>::setPointer(i, std::move(ptr));
424  }
425 };
426 
427 template <typename T, bool is_ad>
429 {
431 };
432 
433 template <typename T>
435 {
437 };
438 
439 template <typename T, bool is_ad>
441 
446 {
447 public:
449 };
450 
451 template <class M, typename T, bool is_ad>
453 
459 template <typename T, bool is_ad>
461 {
463 
464 public:
465  GenericOptionalMaterialProperty(const P * pointer) : _pointer(pointer) {}
466 
472 
474  const MooseADWrapper<T, is_ad> & operator[](const unsigned int i) const
475  {
476  // check if the optional property is valid in debug mode
477  mooseAssert(
478  _pointer,
479  "Attempting to access an optional material property that was not provided by any material "
480  "class. Make sure to check optional material properties before using them.");
481  return (*_pointer)[i];
482  }
483 
485  unsigned int size() const { return (*_pointer).size(); }
486 
488  operator bool() const { return _pointer; }
489 
491  const P * get() const { return _pointer; }
492 
493 private:
496 
498  void set(const P * pointer) { _pointer = pointer; }
499  const P * _pointer;
500 
501  friend class OptionalMaterialPropertyProxy<Material, T, is_ad>;
503 };
504 
505 void dataStore(std::ostream & stream, PropertyValue & p, void * context);
506 void dataLoad(std::istream & stream, PropertyValue & p, void * context);
507 
508 void dataStore(std::ostream & stream, MaterialProperties & v, void * context);
509 void dataLoad(std::istream & stream, MaterialProperties & v, void * context);
510 
511 template <typename T>
513 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:299
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: ADReal.h:73
void dataStore(std::ostream &stream, PropertyValue &p, void *context)
GenericMaterialProperty< T, is_ad > P
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)
void setPointer(const std::size_t i, std::unique_ptr< PropertyValue > &&ptr, const WriteKey)
bool isAD() const override final
const MooseADWrapper< T, is_ad > & operator[](const unsigned int i) const
pass through operator[] to provide a similar API as MaterialProperty
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)
MooseADWrapper< T, is_ad > value_type
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:856
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:256
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
virtual const std::type_info & typeID() const =0
Abstract definition of a property value.
MooseArray< MooseADWrapper< T, is_ad > > _value
Stored parameter value.
const MooseADWrapper< T, is_ad > & operator[](const unsigned int i) const
Get element i out of the array as a ready-only reference.
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
Definition: MooseArray.h:17
virtual void load(std::istream &stream) override final
Load the property from a binary stream.
typename MooseADWrapperStruct< T, is_ad >::type MooseADWrapper
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
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
MooseADWrapper< T, is_ad > & operator[](const unsigned int i)
Get element i out of the array as a writeable reference.
const std::type_info & typeID() const override final
void loadHelper(std::istream &stream, P &data, void *context)
Scalar helper routine.
Definition: DataIO.h:948
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.