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 "MooseObjectWarehouse.h" 14 : 15 : /** 16 : * A storage container for MooseObjects that inherit from SetupInterface. 17 : * 18 : * Objects that inherit from SetupInterface have various functions (e.g., initialSetup). This 19 : * class provides convenience functions for looping over all active Objects stored in the warehouse 20 : * and calling the setup methods. 21 : */ 22 : template <typename T> 23 : class MooseObjectTagWarehouse : public MooseObjectWarehouse<T> 24 : { 25 : public: 26 : /** 27 : * Constructor. 28 : * @param threaded When true (default) threaded storage is enabled. 29 : */ 30 : MooseObjectTagWarehouse(bool threaded = true); 31 : 32 : /** 33 : * Update the active status of Kernels 34 : */ 35 : virtual void updateActive(THREAD_ID tid = 0) override; 36 : 37 : /** 38 : * Retrieve a moose object warehouse in which every moose object has the given vector tag. 39 : * If the warehouse is not constructed yet, it will be constructed here and returned. If 40 : * the warehouse is already cached (it was queried before), we just directly return the 41 : * cached warehouse. 42 : */ 43 : MooseObjectWarehouse<T> & getVectorTagObjectWarehouse(TagID tag_id, THREAD_ID tid); 44 : 45 : /** 46 : * Retrieve a moose object warehouse in which every moose object at least has one of the given 47 : * vector tags. 48 : * If the warehouse is not constructed yet, it will be constructed here and returned. If 49 : * the warehouse is already cached (it was queried before), we just directly return the 50 : * cached warehouse. 51 : */ 52 : MooseObjectWarehouse<T> & getVectorTagsObjectWarehouse(const std::set<TagID> & tags, 53 : THREAD_ID tid); 54 : /** 55 : * Retrieve a moose object warehouse in which every moose object has the given matrix tag. 56 : * If the warehouse is not constructed yet, it will be constructed here and returned. If 57 : * the warehouse is already cached (it was queried before), we just directly return the 58 : * cached warehouse. 59 : */ 60 : MooseObjectWarehouse<T> & getMatrixTagObjectWarehouse(TagID tag_id, THREAD_ID tid); 61 : 62 : /** 63 : * const version of the above 64 : */ 65 : const MooseObjectWarehouse<T> & getMatrixTagObjectWarehouse(TagID tag_id, THREAD_ID tid) const; 66 : 67 : /** 68 : * Retrieve a moose object warehouse in which every moose object has one of the given matrix tags. 69 : * If the warehouse is not constructed yet, it will be constructed here and returned. If 70 : * the warehouse is already cached (it was queried before), we just directly return the 71 : * cached warehouse. 72 : */ 73 : MooseObjectWarehouse<T> & getMatrixTagsObjectWarehouse(const std::set<TagID> & tags, 74 : THREAD_ID tid); 75 : 76 : protected: 77 : const THREAD_ID _num_threads; 78 : 79 : /// Tag based storage. Map from a tag to a moose object warehouse for vector tags 80 : std::vector<std::map<TagID, MooseObjectWarehouse<T>>> _vector_tag_to_object_warehouse; 81 : 82 : /// std::set<TagID> based storage. Map from a std::set of tags to a moose object warehouse for vector tags. 83 : std::vector<std::map<std::set<TagID>, MooseObjectWarehouse<T>>> _vector_tags_to_object_warehouse; 84 : 85 : /// Tag based storage. Map fro a tag to moose object warehouse for matrix tags. 86 : std::vector<std::map<TagID, MooseObjectWarehouse<T>>> _matrix_tag_to_object_warehouse; 87 : 88 : /// std::set<TagID> based storage. Map from a std::set of tags to moose object warehouse for matrix tags. 89 : std::vector<std::map<std::set<TagID>, MooseObjectWarehouse<T>>> _matrix_tags_to_object_warehouse; 90 : }; 91 : 92 : template <typename T> 93 513855 : MooseObjectTagWarehouse<T>::MooseObjectTagWarehouse(bool threaded /*=true*/) 94 : : MooseObjectWarehouse<T>(threaded), 95 513855 : _num_threads(threaded ? libMesh::n_threads() : 1), 96 513855 : _vector_tag_to_object_warehouse(_num_threads), 97 513855 : _vector_tags_to_object_warehouse(_num_threads), 98 513855 : _matrix_tag_to_object_warehouse(_num_threads), 99 1027710 : _matrix_tags_to_object_warehouse(_num_threads) 100 : { 101 513855 : } 102 : 103 : template <typename T> 104 : void 105 2625400 : MooseObjectTagWarehouse<T>::updateActive(THREAD_ID tid) 106 : { 107 2625400 : MooseObjectWarehouse<T>::updateActive(tid); 108 : 109 2657462 : for (auto & it : _vector_tag_to_object_warehouse[tid]) 110 32062 : it.second.updateActive(tid); 111 : 112 2647642 : for (auto & it : _vector_tags_to_object_warehouse[tid]) 113 22242 : it.second.updateActive(tid); 114 : 115 2651757 : for (auto & it : _matrix_tag_to_object_warehouse[tid]) 116 26357 : it.second.updateActive(tid); 117 : 118 2626704 : for (auto & it : _matrix_tags_to_object_warehouse[tid]) 119 1304 : it.second.updateActive(tid); 120 2625400 : } 121 : 122 : template <typename T> 123 : MooseObjectWarehouse<T> & 124 198313 : MooseObjectTagWarehouse<T>::getVectorTagObjectWarehouse(TagID tag_id, THREAD_ID tid) 125 : { 126 198313 : auto & vector_tag_to_object_warehouse = _vector_tag_to_object_warehouse[tid]; 127 : 128 198313 : const auto & house_end = vector_tag_to_object_warehouse.end(); 129 198313 : const auto & tag_warehouse = vector_tag_to_object_warehouse.find(tag_id); 130 : 131 198313 : if (tag_warehouse != house_end) 132 165990 : return tag_warehouse->second; 133 : else 134 32323 : vector_tag_to_object_warehouse[tag_id]; 135 : 136 : // Now add actual moose objects into warehouse 137 32323 : const auto & objects = MooseObjectWarehouse<T>::getObjects(tid); 138 70364 : for (auto & object : objects) 139 : { 140 38041 : auto & tags = object->getVectorTags({}); 141 79736 : for (auto & tag : tags) 142 : { 143 44257 : if (tag == tag_id) 144 : { 145 : // Tag based storage 146 2562 : vector_tag_to_object_warehouse[tag_id].addObject(object, tid); 147 2562 : break; 148 : } 149 : } 150 : } 151 : 152 32323 : return vector_tag_to_object_warehouse[tag_id]; 153 : } 154 : 155 : template <typename T> 156 : MooseObjectWarehouse<T> & 157 78937 : MooseObjectTagWarehouse<T>::getMatrixTagObjectWarehouse(TagID tag_id, THREAD_ID tid) 158 : { 159 78937 : auto & matrix_tag_to_object_warehouse = _matrix_tag_to_object_warehouse[tid]; 160 : 161 78937 : const auto & house_end = matrix_tag_to_object_warehouse.end(); 162 78937 : const auto & tag_warehouse = matrix_tag_to_object_warehouse.find(tag_id); 163 : 164 78937 : if (tag_warehouse != house_end) 165 74423 : return tag_warehouse->second; 166 : else 167 4514 : matrix_tag_to_object_warehouse[tag_id]; 168 : 169 : // Add moose objects to matrix-tag warehouse 170 4514 : const auto & objects = MooseObjectWarehouse<T>::getObjects(tid); 171 7677 : for (auto & object : objects) 172 : { 173 3163 : auto & tags = object->getMatrixTags({}); 174 8187 : for (auto & tag : tags) 175 : { 176 6877 : if (tag == tag_id) 177 : { 178 : // Tag based storage 179 1853 : matrix_tag_to_object_warehouse[tag_id].addObject(object, tid); 180 : 181 1853 : break; 182 : } 183 : } 184 : } 185 : 186 4514 : return matrix_tag_to_object_warehouse[tag_id]; 187 : } 188 : 189 : template <typename T> 190 : const MooseObjectWarehouse<T> & 191 56 : MooseObjectTagWarehouse<T>::getMatrixTagObjectWarehouse(TagID tag_id, THREAD_ID tid) const 192 : { 193 56 : return const_cast<MooseObjectTagWarehouse<T> *>(this)->getMatrixTagObjectWarehouse(tag_id, tid); 194 : } 195 : 196 : template <typename T> 197 : MooseObjectWarehouse<T> & 198 139772 : MooseObjectTagWarehouse<T>::getVectorTagsObjectWarehouse(const std::set<TagID> & v_tags, 199 : THREAD_ID tid) 200 : { 201 : // std::map is not thread-safe for writes 202 139772 : auto & vector_tags_to_object_warehouse = _vector_tags_to_object_warehouse[tid]; 203 : 204 139772 : const auto & house_end = vector_tags_to_object_warehouse.end(); 205 139772 : const auto & tags_warehouse = vector_tags_to_object_warehouse.find(v_tags); 206 : 207 139772 : if (tags_warehouse != house_end) 208 135744 : return tags_warehouse->second; 209 : else 210 4028 : vector_tags_to_object_warehouse[v_tags]; 211 : 212 : // Add moose objects to vector-tags warehouse 213 4028 : const auto & objects = MooseObjectWarehouse<T>::getObjects(tid); 214 7743 : for (auto & object : objects) 215 : { 216 3715 : auto & tags = object->getVectorTags({}); 217 3715 : const auto & tags_end = tags.end(); 218 5652 : for (auto & v_tag : v_tags) 219 : { 220 5332 : const auto & tag_found = tags.find(v_tag); 221 : // Object contains at least one of required tags 222 5332 : if (tag_found != tags_end) 223 : { 224 : // std::vector<Tag> based storage 225 3395 : vector_tags_to_object_warehouse[v_tags].addObject(object, tid); 226 : // Then we should work for next object 227 3395 : break; 228 : } 229 : } 230 : } 231 : 232 4028 : return vector_tags_to_object_warehouse[v_tags]; 233 : } 234 : 235 : template <typename T> 236 : MooseObjectWarehouse<T> & 237 8708 : MooseObjectTagWarehouse<T>::getMatrixTagsObjectWarehouse(const std::set<TagID> & m_tags, 238 : THREAD_ID tid) 239 : { 240 8708 : auto & matrix_tags_to_object_warehouse = _matrix_tags_to_object_warehouse[tid]; 241 : 242 8708 : const auto & house_end = matrix_tags_to_object_warehouse.end(); 243 8708 : const auto & tags_warehouse = matrix_tags_to_object_warehouse.find(m_tags); 244 : 245 8708 : if (tags_warehouse != house_end) 246 7260 : return tags_warehouse->second; 247 : else 248 1448 : matrix_tags_to_object_warehouse[m_tags]; 249 : 250 1448 : const auto & objects = MooseObjectWarehouse<T>::getObjects(tid); 251 2769 : for (auto & object : objects) 252 : { 253 1321 : auto & tags = object->getMatrixTags({}); 254 1321 : const auto & tags_end = tags.end(); 255 1771 : for (auto & m_tag : m_tags) 256 : { 257 1735 : const auto & tag_found = tags.find(m_tag); 258 : // Object contains at least one of required tags 259 1735 : if (tag_found != tags_end) 260 : { 261 : // std::vector<Tag> based storage 262 1285 : matrix_tags_to_object_warehouse[m_tags].addObject(object, tid); 263 : // Then we should work for next object 264 1285 : break; 265 : } 266 : } 267 : } 268 : 269 1448 : return matrix_tags_to_object_warehouse[m_tags]; 270 : }