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 : #include "MooseError.h" 13 : #include "RestartableData.h" 14 : #include "MooseObject.h" 15 : 16 : #include <string> 17 : 18 : class MeshGenerator; 19 : 20 : /** 21 : * The Interface used to retrieve mesh meta data (attributes) set by the MeshGenerator system. 22 : * MOOSE objects should avoid retrieving and casting MeshGenerator objects since they are not 23 : * re-created during a recover operation. This data is read from files early during the simulation 24 : * setup an d can be used to make decisions about how to setup the rest of the problem. 25 : */ 26 : class MeshMetaDataInterface 27 : { 28 : public: 29 : /// The system name used when initializing the Restartable interface 30 : static constexpr auto SYSTEM = "MeshMetaData"; 31 : 32 : /// The data name used when initializing the Restartable interface for non-MeshGenerator objects. 33 : static constexpr auto NAME = "<empty>"; 34 : 35 : protected: 36 : /** 37 : * Interface for all objects reading MeshMetaData. The name of the object gets a bogus prefix, 38 : * which is not intended to be used for storing data. Instead this value is overridden during 39 : * retrieval. 40 : */ 41 : MeshMetaDataInterface(const MooseObject * moose_object); 42 : 43 : /** 44 : * This class constructor is used for non-Moose-based objects like interfaces. A name for the 45 : * storage as well as a system name must be passed in along with the thread ID explicitly. 46 : */ 47 : MeshMetaDataInterface(MooseApp & moose_app); 48 : 49 : #ifdef MOOSE_KOKKOS_ENABLED 50 : /** 51 : * Special constructor used for Kokkos functor copy during parallel dispatch 52 : */ 53 : MeshMetaDataInterface(const MeshMetaDataInterface & object, 54 : const Moose::Kokkos::FunctorCopy & key); 55 : #endif 56 : 57 : /** 58 : * Method for retrieving a property with the given type and name exists in the mesh meta-data 59 : * store. This method will throw an error if the property does not exist. 60 : */ 61 : template <typename T> 62 : const T & getMeshProperty(const std::string & data_name, const std::string & prefix); 63 : template <typename T> 64 : const T & getMeshProperty(const std::string & data_name) 65 : { 66 : return getMeshProperty<T>(data_name, meshPropertyPrefix(data_name)); 67 : } 68 : 69 : /** 70 : * @returns Whether or not a mesh meta-data exists. 71 : */ 72 : bool hasMeshProperty(const std::string & data_name, const std::string & prefix) const; 73 : /** 74 : * @returns Whether or not a mesh meta-data exists with the given type. 75 : */ 76 : template <typename T> 77 : bool hasMeshProperty(const std::string & data_name, const std::string & prefix) const; 78 : 79 : /** 80 : * @returns Whether or not a mesh meta-data exists with the default prefix. 81 : */ 82 190840 : bool hasMeshProperty(const std::string & data_name) const 83 : { 84 190840 : return hasMeshProperty(data_name, meshPropertyPrefix(data_name)); 85 : } 86 : /** 87 : * @returns Whether or not a mesh meta-data exists with the default prefix and the given type. 88 : */ 89 : template <typename T> 90 : bool hasMeshProperty(const std::string & data_name) const 91 : { 92 : return hasMeshProperty<T>(data_name, meshPropertyPrefix(data_name)); 93 : } 94 : 95 : /** 96 : * @returns The full name for mesh property data. 97 : */ 98 : static std::string meshPropertyName(const std::string & data_name, const std::string & prefix); 99 : 100 : /** 101 : * @returns The default mesh property name for mesh property data 102 : */ 103 190840 : std::string meshPropertyName(const std::string & data_name) const 104 : { 105 190840 : return meshPropertyName(data_name, meshPropertyPrefix(data_name)); 106 : } 107 : 108 : private: 109 : /** 110 : * The default prefix to use for getting/seeing if mesh properties exist. 111 : * 112 : * For now, this is not supported except in MeshGenerators. In the future, we will 113 : * automate looking for mesh properties. 114 : */ 115 : virtual std::string meshPropertyPrefix(const std::string & data_name) const; 116 : 117 : /// Helper for getting a mesh property 118 : const RestartableDataValue & getMeshPropertyInternal(const std::string & data_name, 119 : const std::string & prefix) const; 120 : 121 : /// Reference to the application 122 : MooseApp & _meta_data_app; 123 : 124 : /// The MooseObject (if any); used for better error handling 125 : const MooseObject * const _meta_data_object; 126 : 127 : /** 128 : * Helper for forwarding a mooseError to an object's mooseError if it is available (said error 129 : * will provide more context: object name and type) 130 : */ 131 : template <typename... Args> 132 6 : [[noreturn]] void mooseErrorInternal(Args &&... args) const 133 : { 134 6 : if (_meta_data_object) 135 3 : _meta_data_object->mooseError(std::forward<Args>(args)...); 136 3 : mooseError(std::forward<Args>(args)...); 137 : } 138 : }; 139 : 140 : template <typename T> 141 : const T & 142 439 : MeshMetaDataInterface::getMeshProperty(const std::string & data_name, const std::string & prefix) 143 : 144 : { 145 439 : if (!hasMeshProperty(data_name, prefix)) 146 3 : mooseErrorInternal("Failed to get mesh property '", prefix, "/", data_name, "'"); 147 : 148 436 : auto value = &getMeshPropertyInternal(data_name, prefix); 149 : mooseAssert(value->declared(), "Value has not been declared"); 150 436 : const RestartableData<T> * T_value = dynamic_cast<const RestartableData<T> *>(value); 151 436 : if (!T_value) 152 3 : mooseErrorInternal("While retrieving mesh property '", 153 : prefix, 154 : "/", 155 : data_name, 156 : "' with type '", 157 : MooseUtils::prettyCppType<T>(), 158 : "',\nthe property exists with different type '", 159 3 : value->type(), 160 : "'"); 161 433 : return T_value->get(); 162 : } 163 : 164 : template <typename T> 165 : bool 166 2728 : MeshMetaDataInterface::hasMeshProperty(const std::string & data_name, 167 : const std::string & prefix) const 168 : { 169 2728 : if (!hasMeshProperty(data_name, prefix)) 170 2097 : return false; 171 631 : const auto & value = getMeshPropertyInternal(data_name, prefix); 172 631 : return dynamic_cast<const RestartableData<T> *>(&value) != nullptr; 173 : }