Line data Source code
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 "KokkosArray.h"
13 :
14 : #include "MoosePassKey.h"
15 :
16 : #include <typeindex>
17 :
18 : class MooseMesh;
19 : class MaterialBase;
20 :
21 : namespace Moose
22 : {
23 : namespace Kokkos
24 : {
25 :
26 : class MaterialPropertyStorage;
27 :
28 : using StorageKey = Moose::PassKey<MaterialPropertyStorage>;
29 :
30 : template <typename T, unsigned int dimension>
31 : class MaterialPropertyValueBase;
32 :
33 : template <typename T, unsigned int dimension>
34 : class MaterialPropertyValue;
35 :
36 : class Datum;
37 : class Assembly;
38 :
39 : /**
40 : * A structure storing the metadata of Kokkos material properties
41 : */
42 : struct PropRecord
43 : {
44 : /**
45 : * List of declaring materials
46 : */
47 : std::set<const ::MaterialBase *> declarers;
48 : /**
49 : * Property name
50 : */
51 : std::string name;
52 : /**
53 : * Demangled data type name
54 : */
55 : std::string type;
56 : /**
57 : * Property ID
58 : */
59 : unsigned int id = libMesh::invalid_uint;
60 : /**
61 : * Size of each dimension
62 : */
63 : std::vector<unsigned int> dims;
64 : /**
65 : * Flag whether this property is a face property
66 : */
67 : bool bnd = false;
68 : };
69 :
70 : using PropertyStore = std::function<void(std::ostream &, void *)>;
71 : using PropertyLoad = std::function<void(std::istream &, void *)>;
72 :
73 : /**
74 : * The base class for Kokkos material properties
75 : */
76 : class MaterialPropertyBase
77 : {
78 : public:
79 : /**
80 : * Default constructor
81 : */
82 146967 : MaterialPropertyBase() = default;
83 : /**
84 : * Desturctor
85 : */
86 103898 : virtual ~MaterialPropertyBase() {}
87 :
88 : /**
89 : * Get the property ID
90 : * @returns The property ID assigned by the MOOSE registry
91 : */
92 : unsigned int id() const { return _id; }
93 : /**
94 : * Get the property name
95 : * @returns The property name
96 : */
97 : std::string name() const { return _record->name; }
98 : /**
99 : * Get the data type
100 : * @returns The demangled data type name
101 : */
102 2 : std::string type() const { return _record->type; }
103 : /**
104 : * Get the dimension
105 : * @returns The dimension
106 : */
107 2 : unsigned int dim() const { return _record->dims.size(); }
108 : /**
109 : * Get the size of a dimension
110 : * @param i The dimension index
111 : * @returns The size of the dimension
112 : */
113 : unsigned int dim(unsigned int i) const
114 : {
115 : if (i >= dim())
116 : mooseError("Cannot query the size of ",
117 : i,
118 : "-th dimension for the ",
119 : dim(),
120 : "D material property '",
121 : name(),
122 : "'.");
123 :
124 : return _record->dims.at(i);
125 : }
126 :
127 : /**
128 : * Get the property type index for load/store functions
129 : * @returns The property type index for the load/store function pointer map lookup
130 : */
131 : virtual std::type_index propertyType() = 0;
132 :
133 : /**
134 : * Initialize this property
135 : * @param record The record of this property
136 : */
137 : virtual void init(const PropRecord & record, const StorageKey &);
138 :
139 : /**
140 : * Allocate the data storage
141 : * @param mesh The MOOSE mesh
142 : * @param assembly The Kokkos assembly
143 : * @param subdomains The MOOSE subdomain IDs
144 : * @param bnd Whether this property is a face property
145 : */
146 : virtual void allocate(const MooseMesh & mesh,
147 : const Assembly & assembly,
148 : const std::set<SubdomainID> & subdomains,
149 : const bool bnd,
150 : StorageKey) = 0;
151 : /**
152 : * Deep copy another property
153 : * @param prop The property to copy
154 : */
155 : virtual void copy(const MaterialPropertyBase & prop, StorageKey) = 0;
156 : /**
157 : * Swap with another property
158 : * @param prop The property to swap
159 : */
160 : virtual void swap(MaterialPropertyBase & prop, StorageKey) = 0;
161 :
162 : #ifdef MOOSE_KOKKOS_SCOPE
163 : /**
164 : * Get whether this property is valid
165 : * @returns Whether this property is valid
166 : */
167 243200 : KOKKOS_FUNCTION operator bool() const { return _id != libMesh::invalid_uint || _default; }
168 : #endif
169 :
170 : protected:
171 : /**
172 : * Pointer to the record of this property
173 : */
174 : const PropRecord * _record = nullptr;
175 : /**
176 : * Property ID
177 : */
178 : unsigned int _id = libMesh::invalid_uint;
179 : /**
180 : * Flag whether this property has a default value
181 : */
182 : bool _default = false;
183 : };
184 :
185 : template <typename T, unsigned int dimension>
186 : void propertyStore(std::ostream & stream, void * prop);
187 : template <typename T, unsigned int dimension>
188 : void propertyLoad(std::istream & stream, void * prop);
189 :
190 : /**
191 : * The Kokkos material property class
192 : */
193 : template <typename T, unsigned int dimension = 0>
194 : class MaterialProperty final : public MaterialPropertyBase
195 : {
196 : public:
197 : /**
198 : * Default constructor
199 : */
200 47037 : MaterialProperty() = default;
201 : /**
202 : * Constructor for default property
203 : * @param value The default value
204 : */
205 : MaterialProperty(const T & value);
206 : /**
207 : * Copy constructor
208 : * The reference material properties are held by the material property storage, and the user deals
209 : * with the clones of them. The reference material properties also hold the arrays for storing the
210 : * property values (_data), and the user accesses the arrays through their shallow copies in the
211 : * clones. As a result, if the reference material properties reallocate their arrays, the shallow
212 : * copies of arrays in the clones will lose synchronization. Thus, the clones also hold the
213 : * pointers to their reference material properties and shallow copy them in the copy constructor,
214 : * so that the arrays are always synchronized with those in the reference material properties
215 : * during parallel dispatch.
216 : */
217 : MaterialProperty(const MaterialProperty<T, dimension> & property);
218 :
219 : /**
220 : * Shallow copy another property
221 : * @param property The property to be shallow copied
222 : */
223 : auto & operator=(const MaterialProperty<T, dimension> & property);
224 :
225 : #ifdef MOOSE_KOKKOS_SCOPE
226 : /**
227 : * Get the property values of a quadrature point
228 : * @param datum The Datum object of the current thread
229 : * @param qp The local quadrature point index
230 : * @returns The MaterialPropertyValue object that provides access to the property values
231 : */
232 : KOKKOS_FUNCTION MaterialPropertyValue<T, dimension> operator()(const Datum & datum,
233 : const unsigned int qp) const;
234 : #endif
235 :
236 2426 : virtual std::type_index propertyType() override
237 : {
238 2426 : static const std::type_index type = typeid(*this);
239 :
240 2426 : return type;
241 : }
242 :
243 : virtual void init(const PropRecord & record, const StorageKey & key) override;
244 :
245 : #ifdef MOOSE_KOKKOS_SCOPE
246 : virtual void allocate(const MooseMesh & mesh,
247 : const Assembly & assembly,
248 : const std::set<SubdomainID> & subdomains,
249 : const bool bnd,
250 : StorageKey) override;
251 : virtual void copy(const MaterialPropertyBase & prop, StorageKey) override;
252 : virtual void swap(MaterialPropertyBase & prop, StorageKey) override;
253 : #endif
254 :
255 : private:
256 : /**
257 : * Shallow copy another property
258 : * @param property The property to be shallow copied
259 : */
260 : void shallowCopy(const MaterialProperty<T, dimension> & property);
261 :
262 : /**
263 : * Pointer to the reference property
264 : */
265 : const MaterialProperty<T, dimension> * _reference = nullptr;
266 : /**
267 : * Data storage
268 : */
269 : Array<Array<T, dimension + 1>> _data;
270 : /**
271 : * Default value
272 : */
273 : T _value;
274 :
275 : friend class MaterialPropertyValueBase<T, dimension>;
276 :
277 : friend void propertyStore<T, dimension>(std::ostream &, void *);
278 : friend void propertyLoad<T, dimension>(std::istream &, void *);
279 : };
280 :
281 : // The Kokkos array containing Kokkos material properties requires a deep copy because the copy
282 : // constructor of each Kokkos material property should be invoked
283 : template <typename T, unsigned int dimension>
284 : struct ArrayDeepCopy<MaterialProperty<T, dimension>>
285 : {
286 : static const bool value = true;
287 : };
288 :
289 : } // namespace Kokkos
290 : } // namespace Moose
|