https://mooseframework.inl.gov
MaterialData.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 #ifdef MOOSE_KOKKOS_ENABLED
13 #include "KokkosMaterialProperty.h"
14 #endif
15 
16 #include "MaterialProperty.h"
17 #include "Moose.h"
18 #include "MooseUtils.h"
19 
20 // libMesh
21 #include "libmesh/elem.h"
22 
23 #include <vector>
24 #include <memory>
25 #include <typeinfo>
26 
28 class MooseObject;
29 class Material;
30 class XFEM;
31 class MaterialBase;
32 
38 {
39 public:
40  MaterialData(MaterialPropertyStorage & storage, const THREAD_ID tid);
41 
43  static constexpr unsigned int max_state = 2;
44 
48  void resize(unsigned int n_qpoints);
49 
54  unsigned int nQPoints() const { return _n_qpoints; }
55 
57  void copy(const Elem & elem_to, const Elem & elem_from, unsigned int side);
58 
60  void swap(const Elem & elem, unsigned int side = 0);
61 
69  template <typename MatContainer>
70  void reinit(const MatContainer & mats);
71 
73  void reset(const std::vector<std::shared_ptr<MaterialBase>> & mats);
74 
76  void swapBack(const Elem & elem, unsigned int side = 0);
77 
83  const MaterialProperties & props(const unsigned int state = 0) const;
85  MaterialProperties & props(const unsigned int state = 0);
87 
88  template <typename T, bool is_ad>
89  bool haveGenericProperty(const std::string & prop_name) const;
90 
92  template <typename T>
93  bool haveProperty(const std::string & prop_name) const
94  {
95  return haveGenericProperty<T, false>(prop_name);
96  }
97 
99  template <typename T>
100  bool haveADProperty(const std::string & prop_name) const
101  {
102  return haveGenericProperty<T, true>(prop_name);
103  }
104 
105 #ifdef MOOSE_KOKKOS_SCOPE
106 
113  template <typename T, unsigned int dimension>
114  bool haveKokkosProperty(const std::string & prop_name) const;
115 #endif
116 
126  template <typename T, bool is_ad = false>
127  GenericMaterialProperty<T, is_ad> & getProperty(const std::string & prop_name,
128  const unsigned int state,
129  const MooseObject & requestor)
130  {
131  return getPropertyHelper<T, is_ad, false>(prop_name, state, requestor);
132  }
141  template <typename T, bool is_ad>
142  GenericMaterialProperty<T, is_ad> & declareProperty(const std::string & prop_name,
143  const MooseObject & requestor)
144  {
145  return getPropertyHelper<T, is_ad, true>(prop_name, 0, requestor);
146  }
147 
148 #ifdef MOOSE_KOKKOS_SCOPE
149 
157  template <typename T, unsigned int dimension, unsigned int state>
159 
172  template <typename T, unsigned int dimension>
174  declareKokkosProperty(const std::string & prop_name,
175  const std::vector<unsigned int> & dims,
176  const MaterialBase * declarer,
177  const bool bnd,
178  const bool on_demand,
179  const Moose::Kokkos::PropertyConstantOption constant_option);
180 #endif
181 
185  bool isSwapped() const { return _swapped; }
186 
191 
195  class XFEMKey
196  {
197  friend class XFEM;
198  XFEMKey() {}
199  XFEMKey(const XFEM &) {}
200  };
201 
212 
216  bool hasProperty(const std::string & prop_name) const;
217 
225  unsigned int getPropertyId(const std::string & prop_name) const;
226 
232  void onlyResizeIfSmaller(bool flag) { _resize_only_if_smaller = flag; };
233 
238 
244  void eraseProperty(const Elem * elem);
245 
246 private:
249 
252 
254  unsigned int _n_qpoints;
255 
257  std::array<MaterialProperties, max_state + 1> _props;
258 
259  unsigned int addPropertyHelper(const std::string & prop_name,
260  const std::type_info & type,
261  const unsigned int state,
262  const MaterialBase * const declarer);
263 
264  template <typename T, bool is_ad, bool declare>
265  GenericMaterialProperty<T, is_ad> & getPropertyHelper(const std::string & prop_name,
266  const unsigned int state,
267  const MooseObject & requestor);
268 
269 #ifdef MOOSE_KOKKOS_ENABLED
270 
279  addKokkosPropertyHelper(const std::string & prop_name,
280  const std::type_info & type,
281  const unsigned int state,
282  std::shared_ptr<Moose::Kokkos::MaterialPropertyBase> shell);
283 
297  declareKokkosPropertyHelper(const std::string & prop_name,
298  const std::type_info & type,
299  const MaterialBase * declarer,
300  const std::vector<unsigned int> & dims,
301  const bool bnd,
302  const bool on_demand,
303  const Moose::Kokkos::PropertyConstantOption constant_option,
304  std::shared_ptr<Moose::Kokkos::MaterialPropertyBase> shell);
305 
314  const std::string & prop_name,
315  const unsigned int state = 0,
316  std::shared_ptr<Moose::Kokkos::MaterialPropertyBase> shell = nullptr) const;
317 
323  bool haveKokkosPropertyHelper(const std::string & prop_name) const;
331  void kokkosRegisterLoadStoreHelper(std::type_index type,
334 #endif
335 
336  static void mooseErrorHelper(const MooseObject & object, const std::string_view & error);
337 
341  const MaterialBase & castRequestorToDeclarer(const MooseObject & requestor) const;
342 
344  bool _swapped;
345 
349 
351  unsigned int getMaxStateRequested(const unsigned int prop_id) const;
352 };
353 
354 inline const MaterialProperties &
355 MaterialData::props(const unsigned int state) const
356 {
357  mooseAssert(_props.size() > state, "Invalid state");
358  return _props[state];
359 }
360 
361 inline MaterialProperties &
362 MaterialData::props(const unsigned int state)
363 {
364  mooseAssert(_props.size() > state, "Invalid state");
365  return _props[state];
366 }
367 
368 template <typename T, bool is_ad>
369 inline bool
370 MaterialData::haveGenericProperty(const std::string & prop_name) const
371 {
372  if (!hasProperty(prop_name))
373  return false;
374 
375  const auto prop_id = getPropertyId(prop_name);
376  // the property id exists, but the property was not created in this instance of the material type
377  if (prop_id >= props(0).size())
378  return false;
379 
380  const PropertyValue * const base_prop = props(0).queryValue(prop_id);
381  return dynamic_cast<const GenericMaterialProperty<T, is_ad> *>(base_prop) != nullptr;
382 }
383 
384 template <typename T, bool is_ad, bool declare>
386 MaterialData::getPropertyHelper(const std::string & prop_name,
387  const unsigned int state,
388  const MooseObject & requestor)
389 {
390  if constexpr (is_ad)
391  mooseAssert(state == 0, "Cannot request/declare AD properties for states other than zero");
392  if constexpr (declare)
393  mooseAssert(state == 0, "Cannot declare properties for states other than zero");
394 
395  // Register/get the ID of the property
396  const auto prop_id = addPropertyHelper(
397  prop_name, typeid(T), state, declare ? &castRequestorToDeclarer(requestor) : nullptr);
398  const auto size = prop_id + 1;
399 
400  // Initialize the states that we need
401  for (const auto state_i : make_range(getMaxStateRequested(prop_id) + 1))
402  {
403  auto & entry = props(state_i);
404  if (entry.size() < size)
405  entry.resize(size, {});
406  // if we are not declaring the property we initialize only what we need (the requested state)
407  if (!entry.hasValue(prop_id) && (declare || state_i == state))
408  {
409  if (state_i == 0)
410  entry.setPointer(
411  prop_id, std::move(std::make_unique<GenericMaterialProperty<T, is_ad>>(prop_id)), {});
412  else
413  entry.setPointer(prop_id, std::move(std::make_unique<MaterialProperty<T>>(prop_id)), {});
414  }
415  }
416 
417  // Should be available now
418  auto & base_prop = props(state)[prop_id];
419 
420  // In the event that this property was already declared/requested, make sure
421  // that the types are consistent
422  auto prop = dynamic_cast<GenericMaterialProperty<T, is_ad> *>(&base_prop);
423  if (!prop)
424  {
425  constexpr std::string_view action = declare ? "declared" : "requested";
426  constexpr auto is_ad_to_str = [](const bool is_ad_bool)
427  { return std::string_view(is_ad_bool ? "AD" : "non-AD"); };
428  constexpr std::string_view ad_type = is_ad_to_str(is_ad);
429 
430  std::stringstream error;
431  error << "The " << action << " " << ad_type << " "
432  << "material property '" + prop_name + "' of type '" << MooseUtils::prettyCppType<T>()
433  << "'\nis already retrieved or declared as a " << is_ad_to_str(base_prop.isAD())
434  << " property of type '" << base_prop.type() << "'.";
435  mooseErrorHelper(requestor, error.str());
436  }
437 
438  return *prop;
439 }
440 
441 template <typename MatContainer>
442 void
443 MaterialData::reinit(const MatContainer & mats)
444 {
445  for (const auto & mat : mats)
446  mat->computeProperties();
447 }
448 
449 #ifdef MOOSE_KOKKOS_SCOPE
450 template <typename T, unsigned int dimension>
451 bool
452 MaterialData::haveKokkosProperty(const std::string & prop_name) const
453 {
454  if (!haveKokkosPropertyHelper(prop_name))
455  return false;
456 
457  auto & prop = getKokkosPropertyHelper(prop_name);
458  return dynamic_cast<Moose::Kokkos::MaterialProperty<T, dimension> *>(&prop) != nullptr;
459 }
460 
461 template <typename T, unsigned int dimension, unsigned int state>
463 MaterialData::getKokkosProperty(const std::string & prop_name)
464 {
465  // Reserve the storages for the property up to the requested state
466  // If the storages were already reserved, it will do nothing
467  for (unsigned int s = 0; s <= state; ++s)
468  {
469  auto shell = std::make_shared<Moose::Kokkos::MaterialProperty<T, dimension>>();
470 
471  addKokkosPropertyHelper(prop_name, typeid(T), state, shell);
472 
473  // Only instantiate load and store functions for stateful properties to avoid requiring users
474  // to provide custom dataLoad and dataStore for non-trivially-copyable types that are never
475  // used as stateful properties
476  if constexpr (state > 0)
477  kokkosRegisterLoadStoreHelper(shell->propertyType(),
478  Moose::Kokkos::propertyStore<T, dimension>,
479  Moose::Kokkos::propertyLoad<T, dimension>);
480  }
481 
482  auto & prop_base = getKokkosPropertyHelper(prop_name, state, nullptr);
483  auto prop_cast = dynamic_cast<Moose::Kokkos::MaterialProperty<T, dimension> *>(&prop_base);
484 
485  if (!prop_cast)
486  mooseError("The requested ",
487  dimension,
488  "D Kokkos material property '",
489  prop_name,
490  "' of type '",
491  MooseUtils::prettyCppType<T>(),
492  "' was already declared or requested as a ",
493  prop_base.dim(),
494  "D property of type '",
495  prop_base.type(),
496  "'.");
497 
498  return *prop_cast;
499 }
500 
501 template <typename T, unsigned int dimension>
503 MaterialData::declareKokkosProperty(const std::string & prop_name,
504  const std::vector<unsigned int> & dims,
505  const MaterialBase * declarer,
506  const bool bnd,
507  const bool on_demand,
508  const Moose::Kokkos::PropertyConstantOption constant_option)
509 {
510  auto shell = std::make_shared<Moose::Kokkos::MaterialProperty<T, dimension>>();
511 
512  auto & prop_base = declareKokkosPropertyHelper(
513  prop_name, typeid(T), declarer, dims, bnd, on_demand, constant_option, shell);
514  auto prop_cast = dynamic_cast<Moose::Kokkos::MaterialProperty<T, dimension> *>(&prop_base);
515 
516  if (!prop_cast)
517  mooseError("The declared ",
518  dimension,
519  "D Kokkos material property '",
520  prop_name,
521  "' of type '",
522  MooseUtils::prettyCppType<T>(),
523  "' was already declared or requested as a ",
524  prop_base.dim(),
525  "D property of type '",
526  prop_base.type(),
527  "'.");
528 
529  return *prop_cast;
530 }
531 #endif
const MaterialPropertyStorage & getMaterialPropertyStorage() const
Provide read-only access to the underlying MaterialPropertyStorage object.
Definition: MaterialData.h:190
bool isSwapped() const
Returns true if the stateful material is in a swapped state.
Definition: MaterialData.h:185
Moose::Kokkos::MaterialProperty< T, dimension > getKokkosProperty(const std::string &prop_name)
Get a Kokkos material property.
Definition: MaterialData.h:463
bool hasProperty(const std::string &prop_name) const
Definition: MaterialData.C:74
bool haveGenericProperty(const std::string &prop_name) const
Definition: MaterialData.h:370
The base class for Kokkos material properties.
void onlyResizeIfSmaller(bool flag)
Set _resize_only_if_smaller to perform a non-destructive resize.
Definition: MaterialData.h:232
const MaterialBase & castRequestorToDeclarer(const MooseObject &requestor) const
Helper for casting requestor to a MaterialBase in addPropertyHelper() (templated) ...
Definition: MaterialData.C:101
bool haveProperty(const std::string &prop_name) const
Returns true if the regular material property exists - defined by any material.
Definition: MaterialData.h:93
void swapBack(const Elem &elem, unsigned int side=0)
material properties for given element (and possible side)
Definition: MaterialData.C:58
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:311
MaterialPropertyStorage & _storage
Reference to the MaterialStorage class.
Definition: MaterialData.h:248
void reinit(const MatContainer &mats)
Reinit material properties for given element (and possible side)
Definition: MaterialData.h:443
bool _resize_only_if_smaller
Use non-destructive resize of material data (calling resize() will not reduce size).
Definition: MaterialData.h:348
std::array< MaterialProperties, max_state+1 > _props
The underlying property data.
Definition: MaterialData.h:257
Stores the stateful material properties computed by materials.
unsigned int getPropertyId(const std::string &prop_name) const
Wrapper for MaterialStorage::getPropertyId.
Definition: MaterialData.C:80
std::function< void(std::istream &, void *)> PropertyLoad
bool isOnlyResizeIfSmaller() const
Check value of _resize_only_if_smaller.
Definition: MaterialData.h:237
void eraseProperty(const Elem *elem)
Remove the property storage and element pointer from MaterialPropertyStorage data structures Use this...
Definition: MaterialData.C:86
MaterialData(MaterialPropertyStorage &storage, const THREAD_ID tid)
Definition: MaterialData.C:15
unsigned int _n_qpoints
Number of quadrature points.
Definition: MaterialData.h:254
Moose::Kokkos::MaterialProperty< T, dimension > declareKokkosProperty(const std::string &prop_name, const std::vector< unsigned int > &dims, const MaterialBase *declarer, const bool bnd, const bool on_demand, const Moose::Kokkos::PropertyConstantOption constant_option)
Declare a Kokkos material property.
Definition: MaterialData.h:503
unsigned int addPropertyHelper(const std::string &prop_name, const std::type_info &type, const unsigned int state, const MaterialBase *const declarer)
Definition: MaterialData.C:92
Moose::Kokkos::MaterialPropertyBase & addKokkosPropertyHelper(const std::string &prop_name, const std::type_info &type, const unsigned int state, std::shared_ptr< Moose::Kokkos::MaterialPropertyBase > shell)
Helper function for adding a Kokkos material property.
const T * queryValue(const std::size_t i) const
PropertyConstantOption
Property constant options.
Every object that can be built by the factory should be derived from this class.
Definition: MooseObject.h:28
typename GenericMaterialPropertyStruct< T, is_ad >::type GenericMaterialProperty
void copy(const Elem &elem_to, const Elem &elem_from, unsigned int side)
copy material properties from one element to another
Definition: MaterialData.C:35
std::function< void(std::ostream &, void *)> PropertyStore
Abstract definition of a property value.
const MaterialProperties & props(const unsigned int state=0) const
Definition: MaterialData.h:355
static constexpr unsigned int max_state
The max time state supported (2 = older)
Definition: MaterialData.h:43
Materials compute MaterialProperties.
Definition: Material.h:35
Moose::Kokkos::MaterialPropertyBase & getKokkosPropertyHelper(const std::string &prop_name, const unsigned int state=0, std::shared_ptr< Moose::Kokkos::MaterialPropertyBase > shell=nullptr) const
Helper function for getting a Kokkos material property.
Moose::Kokkos::MaterialPropertyBase & declareKokkosPropertyHelper(const std::string &prop_name, const std::type_info &type, const MaterialBase *declarer, const std::vector< unsigned int > &dims, const bool bnd, const bool on_demand, const Moose::Kokkos::PropertyConstantOption constant_option, std::shared_ptr< Moose::Kokkos::MaterialPropertyBase > shell)
Helper function for declaring a Kokkos material property.
unsigned int getMaxStateRequested(const unsigned int prop_id) const
maximum state id requested for a property
Definition: MaterialData.C:109
MaterialPropertyStorage & getMaterialPropertyStorageForXFEM(const XFEMKey)
Provide write-only access to the underlying MaterialPropertyStorage object JUST FOR XFEM...
Definition: MaterialData.h:211
bool haveADProperty(const std::string &prop_name) const
Returns true if the AD material property exists - defined by any material.
Definition: MaterialData.h:100
void reset(const std::vector< std::shared_ptr< MaterialBase >> &mats)
Calls the reset method of Materials to ensure that they are in a proper state.
Definition: MaterialData.C:51
void swap(const Elem &elem, unsigned int side=0)
material properties for given element (and possible side)
Definition: MaterialData.C:41
GenericMaterialProperty< T, is_ad > & getProperty(const std::string &prop_name, const unsigned int state, const MooseObject &requestor)
Retrieves a material property.
Definition: MaterialData.h:127
bool _swapped
Status of storage swapping (calling swap sets this to true; swapBack sets it to false) ...
Definition: MaterialData.h:344
bool haveKokkosProperty(const std::string &prop_name) const
Get whether a Kokkos material property exists.
Definition: MaterialData.h:452
IntRange< T > make_range(T beg, T end)
static void mooseErrorHelper(const MooseObject &object, const std::string_view &error)
Definition: MaterialData.C:68
unsigned int nQPoints() const
Returns the number of quadrature points the material properties support/hold.
Definition: MaterialData.h:54
Proxy for accessing MaterialPropertyStorage.
Definition: MaterialData.h:37
The Kokkos material property class.
void kokkosRegisterLoadStoreHelper(std::type_index type, Moose::Kokkos::PropertyStore store, Moose::Kokkos::PropertyLoad load)
Helper function to register load/store functions of a Kokkos material property to the Kokkos material...
bool haveKokkosPropertyHelper(const std::string &prop_name) const
Helper function for checking whether a Kokkos material property exists.
Key that provides access to only the XFEM class.
Definition: MaterialData.h:195
MaterialBases compute MaterialProperties.
Definition: MaterialBase.h:62
GenericMaterialProperty< T, is_ad > & declareProperty(const std::string &prop_name, const MooseObject &requestor)
Declares a material property.
Definition: MaterialData.h:142
void resize(unsigned int n_qpoints)
Resize the data to hold properties for n_qpoints quadrature points.
Definition: MaterialData.C:21
unsigned int THREAD_ID
Definition: MooseTypes.h:237
XFEMKey(const XFEM &)
Definition: MaterialData.h:199
GenericMaterialProperty< T, is_ad > & getPropertyHelper(const std::string &prop_name, const unsigned int state, const MooseObject &requestor)
Definition: MaterialData.h:386
const THREAD_ID _tid
The thread id.
Definition: MaterialData.h:251