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 51834 : const GenericMaterialProperty<T, is_ad> & getGenericMaterialProperty(const std::string & name,
104 : const unsigned int state = 0)
105 : {
106 51834 : 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 16277060 : virtual const std::unordered_set<unsigned int> & getMatPropDependencies() const
426 : {
427 16277060 : 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 : #ifdef MOOSE_KOKKOS_ENABLED
575 : /// Whether the MOOSE object is a Kokkos object
576 : const bool _is_kokkos_object;
577 : #endif
578 :
579 : /// The type of data
580 : const Moose::MaterialDataType _material_data_type;
581 :
582 : /// The material data class that stores properties
583 : MaterialData & _material_data;
584 :
585 : /**
586 : * A helper method for checking material properties
587 : * This method was required to avoid a compiler problem with the template
588 : * getMaterialProperty method
589 : */
590 : virtual void checkMaterialProperty(const std::string & name, const unsigned int state);
591 :
592 : #ifdef MOOSE_KOKKOS_ENABLED
593 : /**
594 : * A virtual method that can be overriden by Kokkos objects to insert additional operations in
595 : * getKokkosMaterialProperty
596 : * @param prop_name_in The property name
597 : * @param state The property state
598 : */
599 258 : virtual void getKokkosMaterialPropertyHook(const std::string & /* prop_name_in */,
600 : const unsigned int /* state */)
601 : {
602 258 : }
603 : #endif
604 :
605 : /**
606 : * A proxy method for _mi_feproblem.markMatPropRequested(name)
607 : */
608 : void markMatPropRequested(const std::string &);
609 :
610 : /**
611 : * @return The name of the material property associated with name \p name.
612 : *
613 : * If \p name is the name of a material property parameter and the parameter is
614 : * valid, this will return the value of said parameter. Otherwise, it will just
615 : * return the name.
616 : */
617 : MaterialPropertyName getMaterialPropertyName(const std::string & name) const;
618 :
619 : /**
620 : * @return The default material property with the name \p name, if any.
621 : *
622 : * "Default" properties are properties whose default values are set from within
623 : * the name. That is, if we can cast \p name to a Real, _and_ the prop type is
624 : * a Real or RealVectorValue, we'll return said value.
625 : */
626 : ///@{
627 : template <typename T, bool is_ad>
628 : const GenericMaterialProperty<T, is_ad> *
629 : defaultGenericMaterialProperty(const std::string & name);
630 : template <typename T>
631 53 : const MaterialProperty<T> * defaultMaterialProperty(const std::string & name)
632 : {
633 53 : return defaultGenericMaterialProperty<T, false>(name);
634 : }
635 : template <typename T>
636 53 : const ADMaterialProperty<T> * defaultADMaterialProperty(const std::string & name)
637 : {
638 53 : return defaultGenericMaterialProperty<T, true>(name);
639 : }
640 : ///@}
641 :
642 : /**
643 : * Check and throw an error if the execution has progressed past the construction stage
644 : */
645 : void checkExecutionStage();
646 :
647 : /**
648 : * True by default. If false, this class throws an error if any of
649 : * the stateful material properties interfaces are used.
650 : */
651 : bool _stateful_allowed;
652 :
653 : /**
654 : * Initialized to false. Gets set to true when getMaterialProperty()
655 : * is called. Clients of this class can inquire whether getMaterialProperty()
656 : * has been called by calling getMaterialPropertyCalled().
657 : */
658 : bool _get_material_property_called;
659 :
660 : /// Storage vector for default properties
661 : std::vector<std::unique_ptr<PropertyValue>> _default_properties;
662 :
663 : /// The set of material properties (as given by their IDs) that _this_ object depends on
664 : std::unordered_set<unsigned int> _material_property_dependencies;
665 :
666 : const MaterialPropertyName _get_suffix;
667 :
668 : /// Use the interpolated state set up through the ProjectedStatefulMaterialStorageAction
669 : const bool _use_interpolated_state;
670 :
671 : ///@{ name suffixes for interpolated old and older properties
672 : static const std::string _interpolated_old;
673 : static const std::string _interpolated_older;
674 : ///@}
675 :
676 : private:
677 : /**
678 : * @returns The MaterialDataType given the interface's parameters
679 : */
680 : Moose::MaterialDataType getMaterialDataType(const std::set<BoundaryID> & boundary_ids) const;
681 :
682 : /*
683 : * A proxy method for _mi_feproblem.getMaxQps()
684 : */
685 : unsigned int getMaxQps() const;
686 :
687 : /*
688 : * A proxy method for _mi_feproblem.addConsumedPropertyName()
689 : */
690 : void addConsumedPropertyName(const MooseObjectName & obj_name, const std::string & prop_name);
691 :
692 : /// BoundaryRestricted flag
693 : const bool _mi_boundary_restricted;
694 :
695 : /// Storage for the block ids created by BlockRestrictable
696 : const std::set<SubdomainID> & _mi_block_ids;
697 :
698 : /// Storage for the boundary ids created by BoundaryRestrictable
699 : const std::set<BoundaryID> & _mi_boundary_ids;
700 :
701 : /// optional material properties
702 : std::vector<std::unique_ptr<OptionalMaterialPropertyProxyBase<MaterialPropertyInterface>>>
703 : _optional_property_proxies;
704 : };
705 :
706 : template <class M, typename T, bool is_ad>
707 : class OptionalMaterialPropertyProxy : public OptionalMaterialPropertyProxyBase<M>
708 : {
709 : public:
710 1728 : OptionalMaterialPropertyProxy(const std::string & name, const unsigned int state)
711 1728 : : OptionalMaterialPropertyProxyBase<M>(name, state)
712 : {
713 1728 : }
714 1728 : const GenericOptionalMaterialProperty<T, is_ad> & value() const { return _value; }
715 1728 : void resolve(M & mpi) override
716 : {
717 1728 : if (mpi.template hasGenericMaterialProperty<T, is_ad>(this->_name))
718 : {
719 : if constexpr (is_ad)
720 157 : if (this->_state > 0)
721 0 : mooseError("Non-current (state > 0) material properties are not available as AD");
722 :
723 750 : _value.set(&mpi.template getGenericMaterialProperty<T, is_ad>(this->_name, this->_state));
724 : }
725 1728 : }
726 :
727 : private:
728 : GenericOptionalMaterialProperty<T, is_ad> _value;
729 : };
730 :
731 : template <typename T, bool is_ad>
732 : const GenericMaterialProperty<T, is_ad> *
733 71487 : MaterialPropertyInterface::defaultGenericMaterialProperty(const std::string & name)
734 : {
735 : if constexpr (std::is_same_v<T, Real> || std::is_same_v<T, RealVectorValue>)
736 : {
737 38773 : std::istringstream ss(name);
738 : Real real_value;
739 :
740 : // check if the string parsed cleanly into a Real number
741 38773 : if (ss >> real_value && ss.eof())
742 : {
743 : using prop_type = GenericMaterialProperty<T, is_ad>;
744 :
745 9245 : const auto nqp = Moose::constMaxQpsPerElem;
746 : auto & property =
747 9245 : _default_properties.emplace_back(std::make_unique<prop_type>(default_property_id));
748 9245 : auto & T_property = static_cast<prop_type &>(*property);
749 :
750 9245 : T_property.resize(nqp);
751 9254245 : for (const auto qp : make_range(nqp))
752 9245000 : T_property[qp] = real_value;
753 :
754 9245 : return &T_property;
755 : }
756 38773 : }
757 :
758 62242 : return nullptr;
759 : }
760 :
761 : template <typename T>
762 : std::pair<const MaterialProperty<T> *, std::set<SubdomainID>>
763 : MaterialPropertyInterface::getBlockMaterialProperty(const MaterialPropertyName & name_in)
764 : {
765 : const auto name = _get_suffix.empty()
766 : ? static_cast<const std::string &>(name_in)
767 : : MooseUtils::join(std::vector<std::string>({name_in, _get_suffix}), "_");
768 :
769 : if (_mi_block_ids.empty())
770 : mooseError("getBlockMaterialProperty must be called by a block restrictable object");
771 :
772 : using pair_type = std::pair<const MaterialProperty<T> *, std::set<SubdomainID>>;
773 :
774 : if (!hasMaterialPropertyByName<T>(name))
775 : return pair_type(nullptr, {});
776 :
777 : // Call first so that the ID gets registered
778 : const auto & prop = _material_data.getProperty<T, false>(name, 0, _mi_moose_object);
779 : auto blocks = getMaterialPropertyBlocks(name);
780 : auto prop_blocks_pair = pair_type(&prop, std::move(blocks));
781 :
782 : _material_property_dependencies.insert(_material_data.getPropertyId(name));
783 :
784 : // Update consumed properties in MaterialPropertyDebugOutput
785 : addConsumedPropertyName(_mi_moose_object_name, name);
786 :
787 : return prop_blocks_pair;
788 : }
789 :
790 : template <typename T>
791 : bool
792 11457 : MaterialPropertyInterface::hasMaterialProperty(const std::string & name)
793 : {
794 : // Check if the supplied parameter is a valid input parameter key
795 11457 : const auto prop_name = getMaterialPropertyName(name);
796 22914 : return hasMaterialPropertyByName<T>(prop_name);
797 11457 : }
798 :
799 : template <typename T>
800 : bool
801 13174 : MaterialPropertyInterface::hasMaterialPropertyByName(const std::string & name_in)
802 : {
803 39522 : const auto name = _get_suffix.empty()
804 13174 : ? name_in
805 13174 : : MooseUtils::join(std::vector<std::string>({name_in, _get_suffix}), "_");
806 26348 : return _material_data.haveProperty<T>(name);
807 13174 : }
808 :
809 : template <typename T, bool is_ad>
810 : const GenericMaterialProperty<T, is_ad> &
811 0 : MaterialPropertyInterface::getGenericZeroMaterialProperty(const std::string & name)
812 : {
813 0 : const auto prop_name = getMaterialPropertyName(name);
814 0 : return getGenericZeroMaterialPropertyByName<T, is_ad>(prop_name);
815 0 : }
816 :
817 : template <typename T, bool is_ad>
818 : const GenericMaterialProperty<T, is_ad> &
819 1773 : MaterialPropertyInterface::getGenericZeroMaterialPropertyByName(const std::string & prop_name)
820 : {
821 : // if found return the requested property
822 1773 : if (hasGenericMaterialPropertyByName<T, is_ad>(prop_name))
823 244 : return getGenericMaterialPropertyByName<T, is_ad>(prop_name);
824 :
825 1529 : return getGenericZeroMaterialProperty<T, is_ad>();
826 : }
827 :
828 : template <typename T, bool is_ad>
829 : const GenericMaterialProperty<T, is_ad> &
830 2077 : MaterialPropertyInterface::getGenericZeroMaterialProperty()
831 : {
832 : // static zero property storage
833 2077 : static GenericMaterialProperty<T, is_ad> zero(zero_property_id);
834 :
835 : // resize to accomodate maximum number of qpoints
836 : // (in multiapp scenarios getMaxQps can return different values in each app; we need the max)
837 2077 : unsigned int nqp = getMaxQps();
838 2077 : if (nqp > zero.size())
839 1308 : zero.resize(nqp);
840 :
841 : // set values for all qpoints to zero
842 13410 : for (unsigned int qp = 0; qp < nqp; ++qp)
843 11333 : MathUtils::mooseSetToZero(zero[qp]);
844 :
845 2077 : return zero;
846 : }
847 :
848 : template <typename T>
849 : bool
850 300 : MaterialPropertyInterface::hasADMaterialProperty(const std::string & name)
851 : {
852 : // Check if the supplied parameter is a valid input parameter key
853 300 : const auto prop_name = getMaterialPropertyName(name);
854 600 : return hasADMaterialPropertyByName<T>(prop_name);
855 300 : }
856 :
857 : template <typename T>
858 : bool
859 356 : MaterialPropertyInterface::hasADMaterialPropertyByName(const std::string & name_in)
860 : {
861 1068 : const auto name = _get_suffix.empty()
862 356 : ? name_in
863 356 : : MooseUtils::join(std::vector<std::string>({name_in, _get_suffix}), "_");
864 712 : return _material_data.haveADProperty<T>(name);
865 356 : }
866 :
867 : template <typename T, bool is_ad>
868 : const GenericOptionalMaterialProperty<T, is_ad> &
869 984 : MaterialPropertyInterface::getGenericOptionalMaterialProperty(const std::string & name,
870 : const unsigned int state)
871 : {
872 984 : auto proxy = std::make_unique<OptionalMaterialPropertyProxy<MaterialPropertyInterface, T, is_ad>>(
873 : name, state);
874 984 : auto & optional_property = proxy->value();
875 984 : _optional_property_proxies.push_back(std::move(proxy));
876 984 : return optional_property;
877 984 : }
878 :
879 : template <typename T, bool is_ad>
880 : const GenericMaterialProperty<T, is_ad> &
881 55333 : MaterialPropertyInterface::getPossiblyConstantGenericMaterialPropertyByName(
882 : const MaterialPropertyName & prop_name, MaterialData & material_data, const unsigned int state)
883 : {
884 : // Check if it's just a constant
885 55333 : if (const auto * default_property = defaultGenericMaterialProperty<T, is_ad>(prop_name))
886 : {
887 7739 : _get_material_property_called = true;
888 7739 : return *default_property;
889 : }
890 :
891 47594 : if (state > 0 && !_stateful_allowed)
892 8 : mooseError("Stateful material properties not allowed for this object."
893 : " State ",
894 : state,
895 : " property for \"",
896 : prop_name,
897 : "\" was requested.");
898 :
899 47586 : return this->getGenericMaterialPropertyByName<T, is_ad>(prop_name, material_data, state);
900 : }
901 :
902 : template <typename T, bool is_ad>
903 : const GenericMaterialProperty<T, is_ad> &
904 55333 : MaterialPropertyInterface::getGenericMaterialProperty(const std::string & name,
905 : MaterialData & material_data,
906 : const unsigned int state)
907 : {
908 : // Check if the supplied parameter is a valid input parameter key
909 55333 : const auto prop_name = getMaterialPropertyName(name);
910 :
911 55333 : return getPossiblyConstantGenericMaterialPropertyByName<T, is_ad>(
912 110650 : prop_name, material_data, state);
913 55325 : }
914 :
915 : template <typename T, bool is_ad>
916 : const GenericMaterialProperty<T, is_ad> &
917 57788 : MaterialPropertyInterface::getGenericMaterialPropertyByName(const MaterialPropertyName & name_in,
918 : MaterialData & material_data,
919 : const unsigned int state)
920 : {
921 : #ifdef MOOSE_KOKKOS_ENABLED
922 39772 : if (_is_kokkos_object)
923 0 : _mi_moose_object.mooseError(
924 : "Attempted to retrieve a standard MOOSE material property from a Kokkos object.");
925 : #endif
926 :
927 57788 : if (_use_interpolated_state)
928 : {
929 504 : if (state == 1)
930 0 : return getGenericMaterialPropertyByName<T, is_ad>(
931 0 : name_in + _interpolated_old, material_data, 0);
932 504 : if (state == 2)
933 0 : return getGenericMaterialPropertyByName<T, is_ad>(
934 0 : name_in + _interpolated_older, material_data, 0);
935 : }
936 :
937 173364 : const auto name = _get_suffix.empty()
938 57788 : ? static_cast<const std::string &>(name_in)
939 57788 : : MooseUtils::join(std::vector<std::string>({name_in, _get_suffix}), "_");
940 :
941 57788 : checkExecutionStage();
942 57788 : checkMaterialProperty(name, state);
943 :
944 : // mark property as requested
945 57788 : markMatPropRequested(name);
946 :
947 : // Update the boolean flag.
948 57788 : _get_material_property_called = true;
949 :
950 : // Call first so that the ID gets registered
951 57788 : auto & prop = material_data.getProperty<T, is_ad>(name, state, _mi_moose_object);
952 :
953 : // Does the material data used here matter?
954 57772 : _material_property_dependencies.insert(material_data.getPropertyId(name));
955 :
956 57772 : if (state == 0)
957 53046 : addConsumedPropertyName(_mi_moose_object_name, name);
958 :
959 57772 : return prop;
960 57772 : }
961 :
962 : #ifdef MOOSE_KOKKOS_SCOPE
963 : template <typename T, unsigned int dimension>
964 : bool
965 : MaterialPropertyInterface::hasKokkosMaterialProperty(const std::string & name)
966 : {
967 : // Check if the supplied parameter is a valid input parameter key
968 : const auto prop_name = getMaterialPropertyName(name);
969 : return hasKokkosMaterialPropertyByName<T, dimension>(prop_name);
970 : }
971 :
972 : template <typename T, unsigned int dimension>
973 : bool
974 : MaterialPropertyInterface::hasKokkosMaterialPropertyByName(const std::string & name_in)
975 : {
976 : const auto name = _get_suffix.empty()
977 : ? name_in
978 : : MooseUtils::join(std::vector<std::string>({name_in, _get_suffix}), "_");
979 : return _material_data.haveKokkosProperty<T, dimension>(name);
980 : }
981 :
982 : template <typename T, unsigned int dimension, unsigned int state>
983 : Moose::Kokkos::MaterialProperty<T, dimension>
984 1241 : MaterialPropertyInterface::getKokkosMaterialPropertyByName(const std::string & prop_name_in)
985 : {
986 1241 : if (!_is_kokkos_object)
987 0 : _mi_moose_object.mooseError(
988 : "Attempted to retrieve a Kokkos material property from a standard MOOSE object.");
989 :
990 : if constexpr (std::is_same_v<T, Real>)
991 : {
992 1241 : std::istringstream ss(prop_name_in);
993 : Real value;
994 :
995 : // Check if the string parsed cleanly into a Real number
996 1241 : if (ss >> value && ss.eof())
997 0 : return Moose::Kokkos::MaterialProperty<T, dimension>(value);
998 1241 : }
999 :
1000 2219 : const auto prop_name =
1001 978 : _get_suffix.empty()
1002 978 : ? static_cast<const std::string &>(prop_name_in)
1003 978 : : MooseUtils::join(std::vector<std::string>({prop_name_in, _get_suffix}), "_");
1004 :
1005 1241 : checkExecutionStage();
1006 1241 : checkMaterialProperty(prop_name, state);
1007 :
1008 : // Mark property as requested
1009 1241 : markMatPropRequested(prop_name);
1010 :
1011 : // Update the boolean flag
1012 1241 : _get_material_property_called = true;
1013 :
1014 : // Call first so that the ID gets registered
1015 1241 : auto prop = _material_data.getKokkosProperty<T, dimension, state>(prop_name);
1016 :
1017 : // Does the material data used here matter?
1018 1241 : _material_property_dependencies.insert(_material_data.getPropertyId(prop_name));
1019 :
1020 : if constexpr (state == 0)
1021 469 : addConsumedPropertyName(_mi_moose_object_name, prop_name);
1022 :
1023 1241 : getKokkosMaterialPropertyHook(prop_name_in, state);
1024 :
1025 1241 : return prop;
1026 1241 : }
1027 : #endif
|