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 
170  template <typename T, unsigned int dimension>
172  declareKokkosProperty(const std::string & prop_name,
173  const std::vector<unsigned int> & dims,
174  const MaterialBase * declarer,
175  const bool bnd);
176 #endif
177 
181  bool isSwapped() const { return _swapped; }
182 
187 
191  class XFEMKey
192  {
193  friend class XFEM;
194  XFEMKey() {}
195  XFEMKey(const XFEM &) {}
196  };
197 
208 
212  bool hasProperty(const std::string & prop_name) const;
213 
221  unsigned int getPropertyId(const std::string & prop_name) const;
222 
228  void onlyResizeIfSmaller(bool flag) { _resize_only_if_smaller = flag; };
229 
234 
240  void eraseProperty(const Elem * elem);
241 
242 private:
245 
248 
250  unsigned int _n_qpoints;
251 
253  std::array<MaterialProperties, max_state + 1> _props;
254 
255  unsigned int addPropertyHelper(const std::string & prop_name,
256  const std::type_info & type,
257  const unsigned int state,
258  const MaterialBase * const declarer);
259 
260  template <typename T, bool is_ad, bool declare>
261  GenericMaterialProperty<T, is_ad> & getPropertyHelper(const std::string & prop_name,
262  const unsigned int state,
263  const MooseObject & requestor);
264 
265 #ifdef MOOSE_KOKKOS_ENABLED
266 
275  addKokkosPropertyHelper(const std::string & prop_name,
276  const std::type_info & type,
277  const unsigned int state,
278  std::shared_ptr<Moose::Kokkos::MaterialPropertyBase> shell);
279 
291  declareKokkosPropertyHelper(const std::string & prop_name,
292  const std::type_info & type,
293  const MaterialBase * declarer,
294  const std::vector<unsigned int> & dims,
295  const bool bnd,
296  std::shared_ptr<Moose::Kokkos::MaterialPropertyBase> shell);
297 
306  const std::string & prop_name,
307  const unsigned int state = 0,
308  std::shared_ptr<Moose::Kokkos::MaterialPropertyBase> shell = nullptr) const;
309 
315  bool haveKokkosPropertyHelper(const std::string & prop_name) const;
323  void kokkosRegisterLoadStoreHelper(std::type_index type,
326 #endif
327 
328  static void mooseErrorHelper(const MooseObject & object, const std::string_view & error);
329 
333  const MaterialBase & castRequestorToDeclarer(const MooseObject & requestor) const;
334 
336  bool _swapped;
337 
341 
343  unsigned int getMaxStateRequested(const unsigned int prop_id) const;
344 };
345 
346 inline const MaterialProperties &
347 MaterialData::props(const unsigned int state) const
348 {
349  mooseAssert(_props.size() > state, "Invalid state");
350  return _props[state];
351 }
352 
353 inline MaterialProperties &
354 MaterialData::props(const unsigned int state)
355 {
356  mooseAssert(_props.size() > state, "Invalid state");
357  return _props[state];
358 }
359 
360 template <typename T, bool is_ad>
361 inline bool
362 MaterialData::haveGenericProperty(const std::string & prop_name) const
363 {
364  if (!hasProperty(prop_name))
365  return false;
366 
367  const auto prop_id = getPropertyId(prop_name);
368  // the property id exists, but the property was not created in this instance of the material type
369  if (prop_id >= props(0).size())
370  return false;
371 
372  const PropertyValue * const base_prop = props(0).queryValue(prop_id);
373  return dynamic_cast<const GenericMaterialProperty<T, is_ad> *>(base_prop) != nullptr;
374 }
375 
376 template <typename T, bool is_ad, bool declare>
378 MaterialData::getPropertyHelper(const std::string & prop_name,
379  const unsigned int state,
380  const MooseObject & requestor)
381 {
382  if constexpr (is_ad)
383  mooseAssert(state == 0, "Cannot request/declare AD properties for states other than zero");
384  if constexpr (declare)
385  mooseAssert(state == 0, "Cannot declare properties for states other than zero");
386 
387  // Register/get the ID of the property
388  const auto prop_id = addPropertyHelper(
389  prop_name, typeid(T), state, declare ? &castRequestorToDeclarer(requestor) : nullptr);
390  const auto size = prop_id + 1;
391 
392  // Initialize the states that we need
393  for (const auto state_i : make_range(getMaxStateRequested(prop_id) + 1))
394  {
395  auto & entry = props(state_i);
396  if (entry.size() < size)
397  entry.resize(size, {});
398  // if we are not declaring the property we initialize only what we need (the requested state)
399  if (!entry.hasValue(prop_id) && (declare || state_i == state))
400  {
401  if (state_i == 0)
402  entry.setPointer(
403  prop_id, std::move(std::make_unique<GenericMaterialProperty<T, is_ad>>(prop_id)), {});
404  else
405  entry.setPointer(prop_id, std::move(std::make_unique<MaterialProperty<T>>(prop_id)), {});
406  }
407  }
408 
409  // Should be available now
410  auto & base_prop = props(state)[prop_id];
411 
412  // In the event that this property was already declared/requested, make sure
413  // that the types are consistent
414  auto prop = dynamic_cast<GenericMaterialProperty<T, is_ad> *>(&base_prop);
415  if (!prop)
416  {
417  constexpr std::string_view action = declare ? "declared" : "requested";
418  constexpr auto is_ad_to_str = [](const bool is_ad_bool)
419  { return std::string_view(is_ad_bool ? "AD" : "non-AD"); };
420  constexpr std::string_view ad_type = is_ad_to_str(is_ad);
421 
422  std::stringstream error;
423  error << "The " << action << " " << ad_type << " "
424  << "material property '" + prop_name + "' of type '" << MooseUtils::prettyCppType<T>()
425  << "'\nis already retrieved or declared as a " << is_ad_to_str(base_prop.isAD())
426  << " property of type '" << base_prop.type() << "'.";
427  mooseErrorHelper(requestor, error.str());
428  }
429 
430  return *prop;
431 }
432 
433 template <typename MatContainer>
434 void
435 MaterialData::reinit(const MatContainer & mats)
436 {
437  for (const auto & mat : mats)
438  mat->computeProperties();
439 }
440 
441 #ifdef MOOSE_KOKKOS_SCOPE
442 template <typename T, unsigned int dimension>
443 bool
444 MaterialData::haveKokkosProperty(const std::string & prop_name) const
445 {
446  if (!haveKokkosPropertyHelper(prop_name))
447  return false;
448 
449  auto & prop = getKokkosPropertyHelper(prop_name);
450  return dynamic_cast<Moose::Kokkos::MaterialProperty<T, dimension> *>(&prop) != nullptr;
451 }
452 
453 template <typename T, unsigned int dimension, unsigned int state>
455 MaterialData::getKokkosProperty(const std::string & prop_name)
456 {
457  // Reserve the storages for the property up to the requested state
458  // If the storages were already reserved, it will do nothing
459  for (unsigned int s = 0; s <= state; ++s)
460  {
461  auto shell = std::make_shared<Moose::Kokkos::MaterialProperty<T, dimension>>();
462 
463  addKokkosPropertyHelper(prop_name, typeid(T), state, shell);
464 
465  // Only instantiate load and store functions for stateful properties to avoid requiring users
466  // to provide custom dataLoad and dataStore for non-trivially-copyable types that are never
467  // used as stateful properties
468  if constexpr (state > 0)
469  kokkosRegisterLoadStoreHelper(shell->propertyType(),
470  Moose::Kokkos::propertyStore<T, dimension>,
471  Moose::Kokkos::propertyLoad<T, dimension>);
472  }
473 
474  auto & prop_base = getKokkosPropertyHelper(prop_name, state, nullptr);
475  auto prop_cast = dynamic_cast<Moose::Kokkos::MaterialProperty<T, dimension> *>(&prop_base);
476 
477  if (!prop_cast)
478  mooseError("The requested ",
479  dimension,
480  "D Kokkos material property '",
481  prop_name,
482  "' of type '",
483  MooseUtils::prettyCppType<T>(),
484  "' was already declared or requested as a ",
485  prop_base.dim(),
486  "D property of type '",
487  prop_base.type(),
488  "'.");
489 
490  return *prop_cast;
491 }
492 
493 template <typename T, unsigned int dimension>
495 MaterialData::declareKokkosProperty(const std::string & prop_name,
496  const std::vector<unsigned int> & dims,
497  const MaterialBase * declarer,
498  const bool bnd)
499 {
500  auto shell = std::make_shared<Moose::Kokkos::MaterialProperty<T, dimension>>();
501 
502  auto & prop_base = declareKokkosPropertyHelper(prop_name, typeid(T), declarer, dims, bnd, shell);
503  auto prop_cast = dynamic_cast<Moose::Kokkos::MaterialProperty<T, dimension> *>(&prop_base);
504 
505  if (!prop_cast)
506  mooseError("The declared ",
507  dimension,
508  "D Kokkos material property '",
509  prop_name,
510  "' of type '",
511  MooseUtils::prettyCppType<T>(),
512  "' was already declared or requested as a ",
513  prop_base.dim(),
514  "D property of type '",
515  prop_base.type(),
516  "'.");
517 
518  return *prop_cast;
519 }
520 #endif
const MaterialPropertyStorage & getMaterialPropertyStorage() const
Provide read-only access to the underlying MaterialPropertyStorage object.
Definition: MaterialData.h:186
bool isSwapped() const
Returns true if the stateful material is in a swapped state.
Definition: MaterialData.h:181
Moose::Kokkos::MaterialProperty< T, dimension > getKokkosProperty(const std::string &prop_name)
Get a Kokkos material property.
Definition: MaterialData.h:455
bool hasProperty(const std::string &prop_name) const
Definition: MaterialData.C:74
bool haveGenericProperty(const std::string &prop_name) const
Definition: MaterialData.h:362
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:228
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
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, std::shared_ptr< Moose::Kokkos::MaterialPropertyBase > shell)
Helper function for declaring a Kokkos material property.
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:323
MaterialPropertyStorage & _storage
Reference to the MaterialStorage class.
Definition: MaterialData.h:244
void reinit(const MatContainer &mats)
Reinit material properties for given element (and possible side)
Definition: MaterialData.h:435
bool _resize_only_if_smaller
Use non-destructive resize of material data (calling resize() will not reduce size).
Definition: MaterialData.h:340
std::array< MaterialProperties, max_state+1 > _props
The underlying property data.
Definition: MaterialData.h:253
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:233
void eraseProperty(const Elem *elem)
Remove the property storage and element pointer from MaterialPropertyStorage data structures Use this...
Definition: MaterialData.C:86
Moose::Kokkos::MaterialProperty< T, dimension > declareKokkosProperty(const std::string &prop_name, const std::vector< unsigned int > &dims, const MaterialBase *declarer, const bool bnd)
Declare a Kokkos material property.
Definition: MaterialData.h:495
MaterialData(MaterialPropertyStorage &storage, const THREAD_ID tid)
Definition: MaterialData.C:15
unsigned int _n_qpoints
Number of quadrature points.
Definition: MaterialData.h:250
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
Every object that can be built by the factory should be derived from this class.
Definition: MooseObject.h:27
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:347
static constexpr unsigned int max_state
The max time state supported (2 = older)
Definition: MaterialData.h:43
Materials compute MaterialProperties.
Definition: Material.h:34
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.
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:207
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:336
bool haveKokkosProperty(const std::string &prop_name) const
Get whether a Kokkos material property exists.
Definition: MaterialData.h:444
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:191
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:209
XFEMKey(const XFEM &)
Definition: MaterialData.h:195
GenericMaterialProperty< T, is_ad > & getPropertyHelper(const std::string &prop_name, const unsigned int state, const MooseObject &requestor)
Definition: MaterialData.h:378
const THREAD_ID _tid
The thread id.
Definition: MaterialData.h:247