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