Line data Source code
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 "KokkosMaterialPropertyStorage.h"
14 : #endif
15 :
16 : // MOOSE includes
17 : #include "MaterialProperty.h"
18 : #include "MooseTypes.h"
19 : #include "MaterialData.h"
20 : #include "MathUtils.h"
21 : #include "MooseObjectName.h"
22 : #include "InputParameters.h"
23 :
24 : #include <unordered_map>
25 :
26 : #define usingMaterialPropertyInterfaceMembers \
27 : using MaterialPropertyInterface::_material_data_type; \
28 : using MaterialPropertyInterface::_material_data
29 :
30 : // Forward declarations
31 : class MooseObject;
32 : class FEProblemBase;
33 : class SubProblem;
34 :
35 : /**
36 : * Helper class for deferred getting of material properties after the construction
37 : * phase for materials. This enables "optional material properties" in materials.
38 : * It works by returning a reference to a pointer to a material property (rather
39 : * than a reference to the property value). The pointer will be set to point to
40 : * either an existing material property or to nullptr if the requested property
41 : * does not exist.
42 : */
43 : template <class M>
44 : class OptionalMaterialPropertyProxyBase
45 : {
46 : public:
47 1728 : OptionalMaterialPropertyProxyBase(const std::string & name, const unsigned int state)
48 1728 : : _name(name), _state(state)
49 : {
50 1728 : }
51 1428 : virtual ~OptionalMaterialPropertyProxyBase() {}
52 : virtual void resolve(M & material) = 0;
53 :
54 : protected:
55 : const std::string _name;
56 : const unsigned int _state;
57 : };
58 :
59 : /**
60 : * \class MaterialPropertyInterface
61 : * \brief An interface for accessing Materials
62 : *
63 : * Any object that needs material properties should inherit this interface.
64 : * If your object is also restricted to blocks and/or boundaries via the
65 : * BlockRestrictable and/or BoundaryRestrictable class, then MaterialPropertyInterface
66 : * must be inherited following these two classes for the material property checks
67 : * to operate correctly.
68 : */
69 : class MaterialPropertyInterface
70 : {
71 : public:
72 : MaterialPropertyInterface(const MooseObject * moose_object,
73 : const std::set<SubdomainID> & block_ids,
74 : const std::set<BoundaryID> & boundary_ids);
75 :
76 : #ifdef MOOSE_KOKKOS_ENABLED
77 : /**
78 : * Special constructor used for Kokkos functor copy during parallel dispatch
79 : */
80 : MaterialPropertyInterface(const MaterialPropertyInterface & object,
81 : const Moose::Kokkos::FunctorCopy & key);
82 : #endif
83 :
84 : static InputParameters validParams();
85 :
86 : /// The material property ID for a default (parsed from input) property
87 : static constexpr PropertyValue::id_type default_property_id =
88 : PropertyValue::invalid_property_id - 1;
89 : /// The material property ID for a zero property
90 : static constexpr PropertyValue::id_type zero_property_id = PropertyValue::invalid_property_id - 2;
91 :
92 : ///@{
93 : /**
94 : * Retrieve reference to material property or one of it's old or older values.
95 : * The name required by this method is the name that is hard-coded into
96 : * your source code as the input parameter key. If no input parameter is found
97 : * this behaves like the getMaterialPropertyByName family as a fall back.
98 : * @param name The name of the parameter key of the material property to retrieve
99 : * @param state The state (current = 0, old = 1, older = 2)
100 : * @return Reference to the desired material property
101 : */
102 : template <typename T, bool is_ad>
103 50071 : const GenericMaterialProperty<T, is_ad> & getGenericMaterialProperty(const std::string & name,
104 : const unsigned int state = 0)
105 : {
106 50071 : return getGenericMaterialProperty<T, is_ad>(name, _material_data, state);
107 : }
108 : template <typename T>
109 6226 : const MaterialProperty<T> & getMaterialProperty(const std::string & name,
110 : const unsigned int state = 0)
111 : {
112 6226 : return getGenericMaterialProperty<T, false>(name, state);
113 : }
114 : template <typename T>
115 3366 : const ADMaterialProperty<T> & getADMaterialProperty(const std::string & name)
116 : {
117 3366 : return getGenericMaterialProperty<T, true>(name, 0);
118 : }
119 : template <typename T>
120 114 : const MaterialProperty<T> & getMaterialPropertyOld(const std::string & name)
121 : {
122 114 : return getMaterialProperty<T>(name, 1);
123 : }
124 : template <typename T>
125 32 : const MaterialProperty<T> & getMaterialPropertyOlder(const std::string & name)
126 : {
127 32 : return getMaterialProperty<T>(name, 2);
128 : }
129 : ///@}
130 :
131 : ///@{
132 : /**
133 : * Retrieve reference to material property or its old or older value
134 : * The name required by this method is the name defined in the input file.
135 : * @param name The name of the material property to retrieve
136 : * @param state The state (current = 0, old = 1, older = 2)
137 : * @return Reference to the material property with the name 'name'
138 : */
139 : template <typename T, bool is_ad>
140 : const GenericMaterialProperty<T, is_ad> &
141 9826 : getGenericMaterialPropertyByName(const MaterialPropertyName & name, const unsigned int state = 0)
142 : {
143 9826 : return getGenericMaterialPropertyByName<T, is_ad>(name, _material_data, state);
144 : }
145 : template <typename T>
146 217 : const MaterialProperty<T> & getMaterialPropertyByName(const MaterialPropertyName & name,
147 : const unsigned int state = 0)
148 : {
149 217 : return getGenericMaterialPropertyByName<T, false>(name, state);
150 : }
151 : template <typename T>
152 16 : const ADMaterialProperty<T> & getADMaterialPropertyByName(const MaterialPropertyName & name)
153 : {
154 16 : return getGenericMaterialPropertyByName<T, true>(name, 0);
155 : }
156 : template <typename T>
157 : const MaterialProperty<T> & getMaterialPropertyOldByName(const MaterialPropertyName & name)
158 : {
159 : return getMaterialPropertyByName<T>(name, 1);
160 : }
161 : template <typename T>
162 : const MaterialProperty<T> & getMaterialPropertyOlderByName(const MaterialPropertyName & name)
163 : {
164 : return getMaterialPropertyByName<T>(name, 2);
165 : }
166 : ///@}
167 :
168 : #ifdef MOOSE_KOKKOS_SCOPE
169 : /**
170 : * Get a Kokkos material property by property name for any state
171 : * @tparam T The property data type
172 : * @tparam dimension The property dimension
173 : * @tparam state The property state
174 : * @param prop_name_in The property name
175 : * @returns The Kokkos material property
176 : */
177 : template <typename T, unsigned int dimension = 0, unsigned int state = 0>
178 : Moose::Kokkos::MaterialProperty<T, dimension>
179 : getKokkosMaterialPropertyByName(const std::string & prop_name_in);
180 : /**
181 : * Get an old Kokkos material property by property name
182 : * @tparam T The property data type
183 : * @tparam dimension The property dimension
184 : * @param prop_name The property name
185 : * @returns The Kokkos material property
186 : */
187 : template <typename T, unsigned int dimension = 0>
188 : Moose::Kokkos::MaterialProperty<T, dimension>
189 : getKokkosMaterialPropertyOldByName(const std::string & prop_name)
190 : {
191 : return getKokkosMaterialPropertyByName<T, dimension, 1>(prop_name);
192 : }
193 : /**
194 : * Get an older Kokkos material property by property name
195 : * @tparam T The property data type
196 : * @tparam dimension The property dimension
197 : * @param prop_name The property name
198 : * @returns The Kokkos material property
199 : */
200 : template <typename T, unsigned int dimension = 0>
201 : Moose::Kokkos::MaterialProperty<T, dimension>
202 : getKokkosMaterialPropertyOlderByName(const std::string & prop_name)
203 : {
204 : return getKokkosMaterialPropertyByName<T, dimension, 2>(prop_name);
205 : }
206 : /**
207 : * Get a Kokkos material property for any state
208 : * @tparam T The property data type
209 : * @tparam dimension The property dimension
210 : * @tparam state The property state
211 : * @param name The property name or the parameter name containing the property name
212 : * @returns The Kokkos material property
213 : */
214 : template <typename T, unsigned int dimension = 0, unsigned int state = 0>
215 445 : Moose::Kokkos::MaterialProperty<T, dimension> getKokkosMaterialProperty(const std::string & name)
216 : {
217 445 : return getKokkosMaterialPropertyByName<T, dimension, state>(getMaterialPropertyName(name));
218 : }
219 : /**
220 : * Get an old Kokkos material property
221 : * @tparam T The property data type
222 : * @tparam dimension The property dimension
223 : * @param name The property name or the parameter name containing the property name
224 : * @returns The Kokkos material property
225 : */
226 : template <typename T, unsigned int dimension = 0>
227 : Moose::Kokkos::MaterialProperty<T, dimension>
228 556 : getKokkosMaterialPropertyOld(const std::string & name)
229 : {
230 556 : return getKokkosMaterialPropertyByName<T, dimension, 1>(getMaterialPropertyName(name));
231 : }
232 : /**
233 : * Get an older Kokkos material property
234 : * @tparam T The property data type
235 : * @tparam dimension The property dimension
236 : * @param name The property name or the parameter name containing the property name
237 : * @returns The Kokkos material property
238 : */
239 : template <typename T, unsigned int dimension = 0>
240 : Moose::Kokkos::MaterialProperty<T, dimension>
241 216 : getKokkosMaterialPropertyOlder(const std::string & name)
242 : {
243 216 : return getKokkosMaterialPropertyByName<T, dimension, 2>(getMaterialPropertyName(name));
244 : }
245 : #endif
246 :
247 : ///@{ Optional material property getters
248 : /// \p state is the property state; 0 = current, 1 = old, 2 = older, etc.
249 : template <typename T, bool is_ad>
250 : const GenericOptionalMaterialProperty<T, is_ad> &
251 : getGenericOptionalMaterialProperty(const std::string & name, const unsigned int state = 0);
252 :
253 : template <typename T>
254 56 : const OptionalMaterialProperty<T> & getOptionalMaterialProperty(const std::string & name,
255 : const unsigned int state = 0)
256 : {
257 56 : return getGenericOptionalMaterialProperty<T, false>(name, state);
258 : }
259 : template <typename T>
260 28 : const OptionalADMaterialProperty<T> & getOptionalADMaterialProperty(const std::string & name)
261 : {
262 28 : return getGenericOptionalMaterialProperty<T, true>(name);
263 : }
264 :
265 : template <typename T>
266 14 : const OptionalMaterialProperty<T> & getOptionalMaterialPropertyOld(const std::string & name)
267 : {
268 14 : return getOptionalMaterialProperty<T>(name, 1);
269 : }
270 : template <typename T>
271 14 : const OptionalMaterialProperty<T> & getOptionalMaterialPropertyOlder(const std::string & name)
272 : {
273 14 : return getOptionalMaterialProperty<T>(name, 2);
274 : }
275 : ///@}
276 :
277 : /**
278 : * Retrieve pointer to a material property with the mesh blocks where it is defined
279 : * The name required by this method is the name defined in the input file.
280 : * This function can be thought as the combination of getMaterialPropertyByName and
281 : * getMaterialPropertyBlocks.
282 : * It can be called after the action of all actions.
283 : * @param name The name of the material property to retrieve
284 : * @return Pointer to the material property with the name 'name' and the set of blocks where the
285 : * property is valid
286 : */
287 : template <typename T>
288 : std::pair<const MaterialProperty<T> *, std::set<SubdomainID>>
289 : getBlockMaterialProperty(const MaterialPropertyName & name);
290 :
291 : /**
292 : * Return a material property that is initialized to zero by default and does
293 : * not need to (but can) be declared by another material.
294 : */
295 : template <typename T, bool is_ad>
296 : const GenericMaterialProperty<T, is_ad> &
297 : getGenericZeroMaterialProperty(const std::string & name);
298 : template <typename T, bool is_ad>
299 : const GenericMaterialProperty<T, is_ad> &
300 : getGenericZeroMaterialPropertyByName(const std::string & prop_name);
301 :
302 : /**
303 : * Return a constant zero anonymous material property
304 : */
305 : template <typename T, bool is_ad>
306 : const GenericMaterialProperty<T, is_ad> & getGenericZeroMaterialProperty();
307 :
308 : /// for backwards compatibility
309 : template <typename T, typename... Ts>
310 : const MaterialProperty<T> & getZeroMaterialProperty(Ts... args)
311 : {
312 : return getGenericZeroMaterialProperty<T, false>(args...);
313 : }
314 :
315 : /**
316 : * Retrieve the block ids that the material property is defined
317 : * @param name The name of the material property
318 : * @return A vector the the block ids for the property
319 : */
320 : std::set<SubdomainID> getMaterialPropertyBlocks(const std::string & name);
321 :
322 : /**
323 : * Retrieve the block names that the material property is defined
324 : * @param name The name of the material property
325 : * @return A vector the the block names for the property
326 : */
327 : std::vector<SubdomainName> getMaterialPropertyBlockNames(const std::string & name);
328 :
329 : /**
330 : * Retrieve the boundary ids that the material property is defined
331 : * @param name The name of the material property
332 : * @return A vector the the boundary ids for the property
333 : */
334 : std::set<BoundaryID> getMaterialPropertyBoundaryIDs(const std::string & name);
335 :
336 : /**
337 : * Retrieve the boundary namess that the material property is defined
338 : * @param name The name of the material property
339 : * @return A vector the the boundary names for the property
340 : */
341 : std::vector<BoundaryName> getMaterialPropertyBoundaryNames(const std::string & name);
342 :
343 : /**
344 : * Check if block and boundary restrictions of a given material are compatible with the current
345 : * material. Error out otherwise.
346 : */
347 : void checkBlockAndBoundaryCompatibility(std::shared_ptr<MaterialBase> discrete);
348 :
349 : ///@{
350 : /**
351 : * Return a MaterialBase reference - usable for computing directly.
352 : *
353 : * @param name The name of the input parameter or explicit material name.
354 : * @param no_warn If true, suppress warning about retrieving the material
355 : * potentially during its calculation. If you don't know what this is/means,
356 : * then you don't need it.
357 : */
358 : MaterialBase & getMaterial(const std::string & name);
359 : MaterialBase & getMaterialByName(const std::string & name, bool no_warn = false);
360 : ///@}
361 :
362 : /// get a map of MaterialBase pointers for all material objects that this object depends on for each block
363 : std::unordered_map<SubdomainID, std::vector<MaterialBase *>>
364 : buildRequiredMaterials(bool allow_stateful = true);
365 :
366 : ///@{
367 : /**
368 : * Check if the material property exists
369 : * @param name the name of the property to query
370 : * @return true if the property exists, otherwise false
371 : */
372 : template <typename T>
373 : bool hasMaterialProperty(const std::string & name);
374 : template <typename T>
375 : bool hasMaterialPropertyByName(const std::string & name);
376 : template <typename T>
377 : bool hasADMaterialProperty(const std::string & name);
378 : template <typename T>
379 : bool hasADMaterialPropertyByName(const std::string & name);
380 : #ifdef MOOSE_KOKKOS_SCOPE
381 : template <typename T, unsigned int dimension = 0>
382 : bool hasKokkosMaterialProperty(const std::string & name);
383 : template <typename T, unsigned int dimension = 0>
384 : bool hasKokkosMaterialPropertyByName(const std::string & name);
385 : #endif
386 : ///@}
387 :
388 : ///@{ generic hasMaterialProperty helper
389 : template <typename T, bool is_ad>
390 5003 : bool hasGenericMaterialProperty(const std::string & name)
391 : {
392 : if constexpr (is_ad)
393 214 : return hasADMaterialProperty<T>(name);
394 : else
395 4789 : return hasMaterialProperty<T>(name);
396 : }
397 : template <typename T, bool is_ad>
398 1773 : bool hasGenericMaterialPropertyByName(const std::string & name)
399 : {
400 : if constexpr (is_ad)
401 56 : return hasADMaterialPropertyByName<T>(name);
402 : else
403 1717 : return hasMaterialPropertyByName<T>(name);
404 : }
405 : ///@}
406 :
407 : /**
408 : * Derived classes can declare whether or not they work with
409 : * stateful material properties. See, for example, DiracKernel. By
410 : * default, they are allowed.
411 : */
412 : void statefulPropertiesAllowed(bool);
413 :
414 : /**
415 : * Returns true if getMaterialProperty() has been called, false otherwise.
416 : */
417 368275 : virtual bool getMaterialPropertyCalled() const { return _get_material_property_called; }
418 :
419 : /**
420 : * Retrieve the set of material properties that _this_ object depends on.
421 : *
422 : * @return The IDs corresponding to the material properties that
423 : * MUST be reinited before evaluating this object
424 : */
425 16242474 : virtual const std::unordered_set<unsigned int> & getMatPropDependencies() const
426 : {
427 16242474 : return _material_property_dependencies;
428 : }
429 :
430 : /// resolve all optional properties
431 : virtual void resolveOptionalProperties();
432 :
433 : /**
434 : * Retrieve the generic property named "name" for the specified \p material_data at state \p state
435 : */
436 : template <typename T, bool is_ad>
437 : const GenericMaterialProperty<T, is_ad> & getGenericMaterialProperty(
438 : const std::string & name, MaterialData & material_data, const unsigned int state = 0);
439 :
440 : /**
441 : * Retrieve the property named "name" for the specified \p material_data
442 : *
443 : * \p state is the property state; 0 = current, 1 = old, 2 = older, etc.
444 : */
445 : template <typename T>
446 42 : const MaterialProperty<T> & getMaterialProperty(const std::string & name,
447 : MaterialData & material_data,
448 : const unsigned int state = 0)
449 : {
450 42 : return getGenericMaterialProperty<T, false>(name, material_data, state);
451 : }
452 :
453 : /**
454 : * Retrieve the AD property named "name" for the specified \p material_data
455 : *
456 : * \p state is the property state; 0 = current, 1 = old, 2 = older, etc.
457 : */
458 : template <typename T>
459 1474 : const ADMaterialProperty<T> & getADMaterialProperty(const std::string & name,
460 : MaterialData & material_data)
461 : {
462 1474 : return getGenericMaterialProperty<T, true>(name, material_data, 0);
463 : }
464 :
465 : /**
466 : * Retrieve the generic property named "name" without any deduction for the specified \p
467 : * material_data for state \p state
468 : */
469 : template <typename T, bool is_ad>
470 : const GenericMaterialProperty<T, is_ad> & getGenericMaterialPropertyByName(
471 : const MaterialPropertyName & name, MaterialData & material_data, const unsigned int state);
472 :
473 : /**
474 : * Retrieve the generic property named "prop_name" without any deduction for the specified \p
475 : * material_data for state \p state. This API allows the \p prop_name to be a constant, e.g. it
476 : * allows the possibility that \p prop_name is not a name at all
477 : */
478 : template <typename T, bool is_ad>
479 : const GenericMaterialProperty<T, is_ad> &
480 : getPossiblyConstantGenericMaterialPropertyByName(const MaterialPropertyName & prop_name,
481 : MaterialData & material_data,
482 : const unsigned int state);
483 :
484 : /**
485 : * Retrieve the property named "name" without any deduction for the specified \p material_data
486 : *
487 : * \p state is the property state; 0 = current, 1 = old, 2 = older, etc.
488 : */
489 : template <typename T>
490 14 : const MaterialProperty<T> & getMaterialPropertyByName(const MaterialPropertyName & name,
491 : MaterialData & material_data,
492 : const unsigned int state = 0)
493 : {
494 14 : return getGenericMaterialPropertyByName<T, false>(name, material_data, state);
495 : }
496 :
497 : /**
498 : * Retrieve the AD property named "name" without any deduction for the specified \q
499 : * material_data
500 : */
501 : template <typename T>
502 : const ADMaterialProperty<T> & getADMaterialPropertyByName(const MaterialPropertyName & name,
503 : MaterialData & material_data)
504 : {
505 : return getGenericMaterialPropertyByName<T, true>(name, material_data, 0);
506 : }
507 :
508 : /**
509 : * Retrieve the old property deduced from the name \p name for the specified \p material_data
510 : */
511 : template <typename T>
512 14 : const MaterialProperty<T> & getMaterialPropertyOld(const std::string & name,
513 : MaterialData & material_data)
514 : {
515 14 : return getMaterialProperty<T>(name, material_data, 1);
516 : }
517 :
518 : /**
519 : * Retrieve the older property deduced from the name \p name for the specified \p
520 : * material_data
521 : */
522 : template <typename T>
523 14 : const MaterialProperty<T> & getMaterialPropertyOlder(const std::string & name,
524 : MaterialData & material_data)
525 : {
526 14 : return getMaterialProperty<T>(name, material_data, 2);
527 : }
528 :
529 : /**
530 : * Retrieve the old property named \p name without any deduction for the specified \p
531 : * material_data
532 : */
533 : template <typename T>
534 : const MaterialProperty<T> & getMaterialPropertyOldByName(const MaterialPropertyName & name,
535 : MaterialData & material_data)
536 : {
537 : return getMaterialPropertyByName<T>(name, material_data, 1);
538 : }
539 :
540 : /**
541 : * Retrieve the older property named \p name without any deduction for the specified \p
542 : * material_data
543 : */
544 : template <typename T>
545 : const MaterialProperty<T> & getMaterialPropertyOlderByName(const MaterialPropertyName & name,
546 : MaterialData & material_data)
547 : {
548 : return getMaterialPropertyByName<T>(name, material_data, 2);
549 : }
550 :
551 : private:
552 : /// The MooseObject creating the MaterialPropertyInterface
553 : const MooseObject & _mi_moose_object;
554 :
555 : protected:
556 : /// Parameters of the object with this interface
557 : const InputParameters & _mi_params;
558 :
559 : /// The name of the object that this interface belongs to
560 : const std::string _mi_name;
561 :
562 : /// The "complete" name of the object that this interface belongs for material property output
563 : const MooseObjectName _mi_moose_object_name;
564 :
565 : /// Reference to the FEProblemBase class
566 : FEProblemBase & _mi_feproblem;
567 :
568 : /// Reference to the subproblem
569 : SubProblem & _mi_subproblem;
570 :
571 : /// Current threaded it
572 : const THREAD_ID _mi_tid;
573 :
574 : /// Whether the MOOSE object is a Kokkos object
575 : const bool _is_kokkos_object;
576 :
577 : /// The type of data
578 : const Moose::MaterialDataType _material_data_type;
579 :
580 : /// The material data class that stores properties
581 : MaterialData & _material_data;
582 :
583 : /**
584 : * A helper method for checking material properties
585 : * This method was required to avoid a compiler problem with the template
586 : * getMaterialProperty method
587 : */
588 : virtual void checkMaterialProperty(const std::string & name, const unsigned int state);
589 :
590 : #ifdef MOOSE_KOKKOS_ENABLED
591 : /**
592 : * A virtual method that can be overriden by Kokkos objects to insert additional operations in
593 : * getKokkosMaterialProperty
594 : * @param prop_name_in The property name
595 : * @param state The property state
596 : */
597 258 : virtual void getKokkosMaterialPropertyHook(const std::string & /* prop_name_in */,
598 : const unsigned int /* state */)
599 : {
600 258 : }
601 : #endif
602 :
603 : /**
604 : * A proxy method for _mi_feproblem.markMatPropRequested(name)
605 : */
606 : void markMatPropRequested(const std::string &);
607 :
608 : /**
609 : * @return The name of the material property associated with name \p name.
610 : *
611 : * If \p name is the name of a material property parameter and the parameter is
612 : * valid, this will return the value of said parameter. Otherwise, it will just
613 : * return the name.
614 : */
615 : MaterialPropertyName getMaterialPropertyName(const std::string & name) const;
616 :
617 : /**
618 : * @return The default material property with the name \p name, if any.
619 : *
620 : * "Default" properties are properties whose default values are set from within
621 : * the name. That is, if we can cast \p name to a Real, _and_ the prop type is
622 : * a Real or RealVectorValue, we'll return said value.
623 : */
624 : ///@{
625 : template <typename T, bool is_ad>
626 : const GenericMaterialProperty<T, is_ad> *
627 : defaultGenericMaterialProperty(const std::string & name);
628 : template <typename T>
629 53 : const MaterialProperty<T> * defaultMaterialProperty(const std::string & name)
630 : {
631 53 : return defaultGenericMaterialProperty<T, false>(name);
632 : }
633 : template <typename T>
634 53 : const ADMaterialProperty<T> * defaultADMaterialProperty(const std::string & name)
635 : {
636 53 : return defaultGenericMaterialProperty<T, true>(name);
637 : }
638 : ///@}
639 :
640 : /**
641 : * Check and throw an error if the execution has progressed past the construction stage
642 : */
643 : void checkExecutionStage();
644 :
645 : /**
646 : * True by default. If false, this class throws an error if any of
647 : * the stateful material properties interfaces are used.
648 : */
649 : bool _stateful_allowed;
650 :
651 : /**
652 : * Initialized to false. Gets set to true when getMaterialProperty()
653 : * is called. Clients of this class can inquire whether getMaterialProperty()
654 : * has been called by calling getMaterialPropertyCalled().
655 : */
656 : bool _get_material_property_called;
657 :
658 : /// Storage vector for default properties
659 : std::vector<std::unique_ptr<PropertyValue>> _default_properties;
660 :
661 : /// The set of material properties (as given by their IDs) that _this_ object depends on
662 : std::unordered_set<unsigned int> _material_property_dependencies;
663 :
664 : const MaterialPropertyName _get_suffix;
665 :
666 : /// Use the interpolated state set up through the ProjectedStatefulMaterialStorageAction
667 : const bool _use_interpolated_state;
668 :
669 : ///@{ name suffixes for interpolated old and older properties
670 : static const std::string _interpolated_old;
671 : static const std::string _interpolated_older;
672 : ///@}
673 :
674 : private:
675 : /**
676 : * @returns The MaterialDataType given the interface's parameters
677 : */
678 : Moose::MaterialDataType getMaterialDataType(const std::set<BoundaryID> & boundary_ids) const;
679 :
680 : /*
681 : * A proxy method for _mi_feproblem.getMaxQps()
682 : */
683 : unsigned int getMaxQps() const;
684 :
685 : /*
686 : * A proxy method for _mi_feproblem.addConsumedPropertyName()
687 : */
688 : void addConsumedPropertyName(const MooseObjectName & obj_name, const std::string & prop_name);
689 :
690 : /// BoundaryRestricted flag
691 : const bool _mi_boundary_restricted;
692 :
693 : /// Storage for the block ids created by BlockRestrictable
694 : const std::set<SubdomainID> & _mi_block_ids;
695 :
696 : /// Storage for the boundary ids created by BoundaryRestrictable
697 : const std::set<BoundaryID> & _mi_boundary_ids;
698 :
699 : /// optional material properties
700 : std::vector<std::unique_ptr<OptionalMaterialPropertyProxyBase<MaterialPropertyInterface>>>
701 : _optional_property_proxies;
702 : };
703 :
704 : template <class M, typename T, bool is_ad>
705 : class OptionalMaterialPropertyProxy : public OptionalMaterialPropertyProxyBase<M>
706 : {
707 : public:
708 1728 : OptionalMaterialPropertyProxy(const std::string & name, const unsigned int state)
709 1728 : : OptionalMaterialPropertyProxyBase<M>(name, state)
710 : {
711 1728 : }
712 1728 : const GenericOptionalMaterialProperty<T, is_ad> & value() const { return _value; }
713 1728 : void resolve(M & mpi) override
714 : {
715 1728 : if (mpi.template hasGenericMaterialProperty<T, is_ad>(this->_name))
716 : {
717 : if constexpr (is_ad)
718 157 : if (this->_state > 0)
719 0 : mooseError("Non-current (state > 0) material properties are not available as AD");
720 :
721 750 : _value.set(&mpi.template getGenericMaterialProperty<T, is_ad>(this->_name, this->_state));
722 : }
723 1728 : }
724 :
725 : private:
726 : GenericOptionalMaterialProperty<T, is_ad> _value;
727 : };
728 :
729 : template <typename T, bool is_ad>
730 : const GenericMaterialProperty<T, is_ad> *
731 69724 : MaterialPropertyInterface::defaultGenericMaterialProperty(const std::string & name)
732 : {
733 : if constexpr (std::is_same_v<T, Real> || std::is_same_v<T, RealVectorValue>)
734 : {
735 38729 : std::istringstream ss(name);
736 : Real real_value;
737 :
738 : // check if the string parsed cleanly into a Real number
739 38729 : if (ss >> real_value && ss.eof())
740 : {
741 : using prop_type = GenericMaterialProperty<T, is_ad>;
742 :
743 9245 : const auto nqp = Moose::constMaxQpsPerElem;
744 : auto & property =
745 9245 : _default_properties.emplace_back(std::make_unique<prop_type>(default_property_id));
746 9245 : auto & T_property = static_cast<prop_type &>(*property);
747 :
748 9245 : T_property.resize(nqp);
749 9254245 : for (const auto qp : make_range(nqp))
750 9245000 : T_property[qp] = real_value;
751 :
752 9245 : return &T_property;
753 : }
754 38729 : }
755 :
756 60479 : return nullptr;
757 : }
758 :
759 : template <typename T>
760 : std::pair<const MaterialProperty<T> *, std::set<SubdomainID>>
761 : MaterialPropertyInterface::getBlockMaterialProperty(const MaterialPropertyName & name_in)
762 : {
763 : const auto name = _get_suffix.empty()
764 : ? static_cast<const std::string &>(name_in)
765 : : MooseUtils::join(std::vector<std::string>({name_in, _get_suffix}), "_");
766 :
767 : if (_mi_block_ids.empty())
768 : mooseError("getBlockMaterialProperty must be called by a block restrictable object");
769 :
770 : using pair_type = std::pair<const MaterialProperty<T> *, std::set<SubdomainID>>;
771 :
772 : if (!hasMaterialPropertyByName<T>(name))
773 : return pair_type(nullptr, {});
774 :
775 : // Call first so that the ID gets registered
776 : const auto & prop = _material_data.getProperty<T, false>(name, 0, _mi_moose_object);
777 : auto blocks = getMaterialPropertyBlocks(name);
778 : auto prop_blocks_pair = pair_type(&prop, std::move(blocks));
779 :
780 : _material_property_dependencies.insert(_material_data.getPropertyId(name));
781 :
782 : // Update consumed properties in MaterialPropertyDebugOutput
783 : addConsumedPropertyName(_mi_moose_object_name, name);
784 :
785 : return prop_blocks_pair;
786 : }
787 :
788 : template <typename T>
789 : bool
790 11457 : MaterialPropertyInterface::hasMaterialProperty(const std::string & name)
791 : {
792 : // Check if the supplied parameter is a valid input parameter key
793 11457 : const auto prop_name = getMaterialPropertyName(name);
794 22914 : return hasMaterialPropertyByName<T>(prop_name);
795 11457 : }
796 :
797 : template <typename T>
798 : bool
799 13174 : MaterialPropertyInterface::hasMaterialPropertyByName(const std::string & name_in)
800 : {
801 39522 : const auto name = _get_suffix.empty()
802 13174 : ? name_in
803 13174 : : MooseUtils::join(std::vector<std::string>({name_in, _get_suffix}), "_");
804 26348 : return _material_data.haveProperty<T>(name);
805 13174 : }
806 :
807 : template <typename T, bool is_ad>
808 : const GenericMaterialProperty<T, is_ad> &
809 0 : MaterialPropertyInterface::getGenericZeroMaterialProperty(const std::string & name)
810 : {
811 0 : const auto prop_name = getMaterialPropertyName(name);
812 0 : return getGenericZeroMaterialPropertyByName<T, is_ad>(prop_name);
813 0 : }
814 :
815 : template <typename T, bool is_ad>
816 : const GenericMaterialProperty<T, is_ad> &
817 1773 : MaterialPropertyInterface::getGenericZeroMaterialPropertyByName(const std::string & prop_name)
818 : {
819 : // if found return the requested property
820 1773 : if (hasGenericMaterialPropertyByName<T, is_ad>(prop_name))
821 244 : return getGenericMaterialPropertyByName<T, is_ad>(prop_name);
822 :
823 1529 : return getGenericZeroMaterialProperty<T, is_ad>();
824 : }
825 :
826 : template <typename T, bool is_ad>
827 : const GenericMaterialProperty<T, is_ad> &
828 2077 : MaterialPropertyInterface::getGenericZeroMaterialProperty()
829 : {
830 : // static zero property storage
831 2077 : static GenericMaterialProperty<T, is_ad> zero(zero_property_id);
832 :
833 : // resize to accomodate maximum number of qpoints
834 : // (in multiapp scenarios getMaxQps can return different values in each app; we need the max)
835 2077 : unsigned int nqp = getMaxQps();
836 2077 : if (nqp > zero.size())
837 1308 : zero.resize(nqp);
838 :
839 : // set values for all qpoints to zero
840 13410 : for (unsigned int qp = 0; qp < nqp; ++qp)
841 11333 : MathUtils::mooseSetToZero(zero[qp]);
842 :
843 2077 : return zero;
844 : }
845 :
846 : template <typename T>
847 : bool
848 300 : MaterialPropertyInterface::hasADMaterialProperty(const std::string & name)
849 : {
850 : // Check if the supplied parameter is a valid input parameter key
851 300 : const auto prop_name = getMaterialPropertyName(name);
852 600 : return hasADMaterialPropertyByName<T>(prop_name);
853 300 : }
854 :
855 : template <typename T>
856 : bool
857 356 : MaterialPropertyInterface::hasADMaterialPropertyByName(const std::string & name_in)
858 : {
859 1068 : const auto name = _get_suffix.empty()
860 356 : ? name_in
861 356 : : MooseUtils::join(std::vector<std::string>({name_in, _get_suffix}), "_");
862 712 : return _material_data.haveADProperty<T>(name);
863 356 : }
864 :
865 : template <typename T, bool is_ad>
866 : const GenericOptionalMaterialProperty<T, is_ad> &
867 984 : MaterialPropertyInterface::getGenericOptionalMaterialProperty(const std::string & name,
868 : const unsigned int state)
869 : {
870 984 : auto proxy = std::make_unique<OptionalMaterialPropertyProxy<MaterialPropertyInterface, T, is_ad>>(
871 : name, state);
872 984 : auto & optional_property = proxy->value();
873 984 : _optional_property_proxies.push_back(std::move(proxy));
874 984 : return optional_property;
875 984 : }
876 :
877 : template <typename T, bool is_ad>
878 : const GenericMaterialProperty<T, is_ad> &
879 53570 : MaterialPropertyInterface::getPossiblyConstantGenericMaterialPropertyByName(
880 : const MaterialPropertyName & prop_name, MaterialData & material_data, const unsigned int state)
881 : {
882 : // Check if it's just a constant
883 53570 : if (const auto * default_property = defaultGenericMaterialProperty<T, is_ad>(prop_name))
884 : {
885 7739 : _get_material_property_called = true;
886 7739 : return *default_property;
887 : }
888 :
889 45831 : if (state > 0 && !_stateful_allowed)
890 8 : mooseError("Stateful material properties not allowed for this object."
891 : " State ",
892 : state,
893 : " property for \"",
894 : prop_name,
895 : "\" was requested.");
896 :
897 45823 : return this->getGenericMaterialPropertyByName<T, is_ad>(prop_name, material_data, state);
898 : }
899 :
900 : template <typename T, bool is_ad>
901 : const GenericMaterialProperty<T, is_ad> &
902 53570 : MaterialPropertyInterface::getGenericMaterialProperty(const std::string & name,
903 : MaterialData & material_data,
904 : const unsigned int state)
905 : {
906 : // Check if the supplied parameter is a valid input parameter key
907 53570 : const auto prop_name = getMaterialPropertyName(name);
908 :
909 53570 : return getPossiblyConstantGenericMaterialPropertyByName<T, is_ad>(
910 107124 : prop_name, material_data, state);
911 53562 : }
912 :
913 : template <typename T, bool is_ad>
914 : const GenericMaterialProperty<T, is_ad> &
915 56025 : MaterialPropertyInterface::getGenericMaterialPropertyByName(const MaterialPropertyName & name_in,
916 : MaterialData & material_data,
917 : const unsigned int state)
918 : {
919 56025 : if (_is_kokkos_object)
920 0 : mooseError("Attempted to retrieve a standard MOOSE material property from a Kokkos object.");
921 :
922 56025 : if (_use_interpolated_state)
923 : {
924 504 : if (state == 1)
925 0 : return getGenericMaterialPropertyByName<T, is_ad>(
926 0 : name_in + _interpolated_old, material_data, 0);
927 504 : if (state == 2)
928 0 : return getGenericMaterialPropertyByName<T, is_ad>(
929 0 : name_in + _interpolated_older, material_data, 0);
930 : }
931 :
932 168075 : const auto name = _get_suffix.empty()
933 56025 : ? static_cast<const std::string &>(name_in)
934 56025 : : MooseUtils::join(std::vector<std::string>({name_in, _get_suffix}), "_");
935 :
936 56025 : checkExecutionStage();
937 56025 : checkMaterialProperty(name, state);
938 :
939 : // mark property as requested
940 56025 : markMatPropRequested(name);
941 :
942 : // Update the boolean flag.
943 56025 : _get_material_property_called = true;
944 :
945 : // Call first so that the ID gets registered
946 56025 : auto & prop = material_data.getProperty<T, is_ad>(name, state, _mi_moose_object);
947 :
948 : // Does the material data used here matter?
949 56009 : _material_property_dependencies.insert(material_data.getPropertyId(name));
950 :
951 56009 : if (state == 0)
952 51283 : addConsumedPropertyName(_mi_moose_object_name, name);
953 :
954 56009 : return prop;
955 56009 : }
956 :
957 : #ifdef MOOSE_KOKKOS_SCOPE
958 : template <typename T, unsigned int dimension>
959 : bool
960 : MaterialPropertyInterface::hasKokkosMaterialProperty(const std::string & name)
961 : {
962 : // Check if the supplied parameter is a valid input parameter key
963 : const auto prop_name = getMaterialPropertyName(name);
964 : return hasKokkosMaterialPropertyByName<T, dimension>(prop_name);
965 : }
966 :
967 : template <typename T, unsigned int dimension>
968 : bool
969 : MaterialPropertyInterface::hasKokkosMaterialPropertyByName(const std::string & name_in)
970 : {
971 : const auto name = _get_suffix.empty()
972 : ? name_in
973 : : MooseUtils::join(std::vector<std::string>({name_in, _get_suffix}), "_");
974 : return _material_data.haveKokkosProperty<T, dimension>(name);
975 : }
976 :
977 : template <typename T, unsigned int dimension, unsigned int state>
978 : Moose::Kokkos::MaterialProperty<T, dimension>
979 1241 : MaterialPropertyInterface::getKokkosMaterialPropertyByName(const std::string & prop_name_in)
980 : {
981 1241 : if (!_is_kokkos_object)
982 0 : mooseError("Attempted to retrieve a Kokkos material property from a standard MOOSE object.");
983 :
984 : if constexpr (std::is_same_v<T, Real>)
985 : {
986 1241 : std::istringstream ss(prop_name_in);
987 : Real value;
988 :
989 : // Check if the string parsed cleanly into a Real number
990 1241 : if (ss >> value && ss.eof())
991 0 : return Moose::Kokkos::MaterialProperty<T, dimension>(value);
992 1241 : }
993 :
994 2219 : const auto prop_name =
995 978 : _get_suffix.empty()
996 978 : ? static_cast<const std::string &>(prop_name_in)
997 978 : : MooseUtils::join(std::vector<std::string>({prop_name_in, _get_suffix}), "_");
998 :
999 1241 : checkExecutionStage();
1000 1241 : checkMaterialProperty(prop_name, state);
1001 :
1002 : // Mark property as requested
1003 1241 : markMatPropRequested(prop_name);
1004 :
1005 : // Update the boolean flag
1006 1241 : _get_material_property_called = true;
1007 :
1008 : // Call first so that the ID gets registered
1009 1241 : auto prop = _material_data.getKokkosProperty<T, dimension, state>(prop_name);
1010 :
1011 : // Does the material data used here matter?
1012 1241 : _material_property_dependencies.insert(_material_data.getPropertyId(prop_name));
1013 :
1014 : if constexpr (state == 0)
1015 469 : addConsumedPropertyName(_mi_moose_object_name, prop_name);
1016 :
1017 1241 : getKokkosMaterialPropertyHook(prop_name_in, state);
1018 :
1019 1241 : return prop;
1020 1241 : }
1021 : #endif
|