Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://www.mooseframework.org 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 "CSGSurfaceList.h" 13 : #include "CSGRegion.h" 14 : #include "CSGCellList.h" 15 : #include "CSGUniverseList.h" 16 : #include "nlohmann/json.h" 17 : 18 : #ifdef MOOSE_UNIT_TEST 19 : #include "gtest/gtest.h" 20 : #endif 21 : 22 : namespace CSG 23 : { 24 : 25 : /** 26 : * CSGBase creates an internal representation of a Constructive Solid Geometry (CSG) 27 : * model. 28 : */ 29 : class CSGBase 30 : { 31 : public: 32 : /** 33 : * Default constructor 34 : */ 35 : CSGBase(); 36 : 37 : /** 38 : * Destructor 39 : */ 40 : ~CSGBase(); 41 : 42 : /** 43 : * @brief add a unique surface pointer to this base instance 44 : * 45 : * @param surf pointer to surface to add 46 : * 47 : * @return reference to CSGSurface that was added 48 : */ 49 198 : const CSGSurface & addSurface(std::unique_ptr<CSGSurface> surf) 50 : { 51 198 : return _surface_list.addSurface(std::move(surf)); 52 : } 53 : 54 : /** 55 : * @brief Get all surface objects 56 : * 57 : * @return list of references to all CSGSurface objects in CSGBase 58 : */ 59 35 : std::vector<std::reference_wrapper<const CSGSurface>> getAllSurfaces() const 60 : { 61 35 : return _surface_list.getAllSurfaces(); 62 : } 63 : 64 : /** 65 : * @brief Get a Surface object by name 66 : * 67 : * @param name surface name 68 : * @return reference to CSGSurface object 69 : */ 70 4 : const CSGSurface & getSurfaceByName(const std::string & name) const 71 : { 72 4 : return _surface_list.getSurface(name); 73 : } 74 : 75 : /** 76 : * @brief rename the specified surface 77 : * 78 : * @param surface CSGSurface to rename 79 : * @param name new name 80 : */ 81 24 : void renameSurface(const CSGSurface & surface, const std::string & name) 82 : { 83 24 : _surface_list.renameSurface(surface, name); 84 20 : } 85 : 86 : /** 87 : * @brief Create a Material Cell object 88 : * 89 : * @param name unique cell name 90 : * @param mat_name material name 91 : * @param region cell region 92 : * @param add_to_univ (optional) universe to which this cell will be added (default is root 93 : * universe) 94 : * @return reference to CSGCell that is created 95 : */ 96 : const CSGCell & createCell(const std::string & name, 97 : const std::string & mat_name, 98 : const CSGRegion & region, 99 : const CSGUniverse * add_to_univ = nullptr); 100 : 101 : /** 102 : * @brief Create a Void Cell object 103 : * 104 : * @param name unique cell name 105 : * @param region cell region 106 : * @param add_to_univ (optional) universe to which this cell will be added (default is root 107 : * universe) 108 : * @return reference to CSGCell that is created 109 : */ 110 : const CSGCell & createCell(const std::string & name, 111 : const CSGRegion & region, 112 : const CSGUniverse * add_to_univ = nullptr); 113 : 114 : /** 115 : * @brief Create a Universe Cell object 116 : * 117 : * @param name unique cell name 118 : * @param fill_univ universe that will fill the cell 119 : * @param region cell region 120 : * @param add_to_univ (optional) universe to which this cell will be added (default is root 121 : * universe) 122 : * @return reference to cell that is created 123 : */ 124 : const CSGCell & createCell(const std::string & name, 125 : const CSGUniverse & fill_univ, 126 : const CSGRegion & region, 127 : const CSGUniverse * add_to_univ = nullptr); 128 : 129 : /** 130 : * @brief Get all cell objects 131 : * 132 : * @return list of references to all CSGCell objects in CSGBase 133 : */ 134 35 : std::vector<std::reference_wrapper<const CSGCell>> getAllCells() const 135 : { 136 35 : return _cell_list.getAllCells(); 137 : } 138 : 139 : /** 140 : * @brief Get a Cell object by name 141 : * 142 : * @param name cell name 143 : * @return reference to CSGCell object 144 : */ 145 13 : const CSGCell & getCellByName(const std::string & name) const { return _cell_list.getCell(name); } 146 : 147 : /** 148 : * @brief rename the specified cell 149 : * 150 : * @param cell reference to CSGCell to rename 151 : * @param name new name 152 : */ 153 15 : void renameCell(const CSGCell & cell, const std::string & name) 154 : { 155 15 : _cell_list.renameCell(cell, name); 156 11 : } 157 : 158 : /** 159 : * @brief change the region of the specified cell 160 : * 161 : * @param cell cell to update the region for 162 : * @param region new region to assign to cell 163 : */ 164 : void updateCellRegion(const CSGCell & cell, const CSGRegion & region); 165 : 166 : /** 167 : * @brief Get the Root Universe object 168 : * 169 : * @return reference to root CSGUniverse 170 : */ 171 138 : const CSGUniverse & getRootUniverse() const { return _universe_list.getRoot(); } 172 : 173 : /** 174 : * @brief rename the root universe for this instance (default is ROOT_UNIVERSE) 175 : * 176 : * @param name new name for the root universe 177 : */ 178 2 : void renameRootUniverse(const std::string & name) 179 : { 180 2 : _universe_list.renameUniverse(_universe_list.getRoot(), name); 181 2 : } 182 : 183 : /** 184 : * @brief rename the specified universe 185 : * 186 : * @param universe reference to CSGUniverse to rename 187 : * @param name new name 188 : */ 189 6 : void renameUniverse(const CSGUniverse & universe, const std::string & name) 190 : { 191 6 : _universe_list.renameUniverse(universe, name); 192 2 : } 193 : 194 : /** 195 : * @brief Create an empty Universe object 196 : * 197 : * @param name unique universe name 198 : * @return reference to CSGUniverse that is created 199 : */ 200 28 : const CSGUniverse & createUniverse(const std::string & name) 201 : { 202 28 : return _universe_list.addUniverse(name); 203 : } 204 : 205 : /** 206 : * @brief Create a Universe object from list of cells 207 : * 208 : * @param name unique universe name 209 : * @param cells list of cells to add to universe 210 : * @return reference to CSGUniverse that is created 211 : */ 212 : const CSGUniverse & createUniverse(const std::string & name, 213 : std::vector<std::reference_wrapper<const CSGCell>> & cells); 214 : 215 : /** 216 : * @brief Add a cell to an existing universe 217 : * 218 : * @param universe universe to which to add the cell 219 : * @param cell cell to add 220 : */ 221 : void addCellToUniverse(const CSGUniverse & universe, const CSGCell & cell); 222 : 223 : /** 224 : * @brief Add a list of cells to an existing universe 225 : * 226 : * @param universe universe to which to add the cells 227 : * @param cells list of references to cells to add 228 : */ 229 : void addCellsToUniverse(const CSGUniverse & universe, 230 : std::vector<std::reference_wrapper<const CSGCell>> & cells); 231 : 232 : /** 233 : * @brief Remove a cell from an existing universe 234 : * 235 : * @param universe universe from which to remove the cell 236 : * @param cell cell to remove 237 : */ 238 : void removeCellFromUniverse(const CSGUniverse & universe, const CSGCell & cell); 239 : 240 : /** 241 : * @brief Remove a list of cells from an existing universe 242 : * 243 : * @param universe universe from which to remove the cells 244 : * @param cells list of references to cells to remove 245 : */ 246 : void removeCellsFromUniverse(const CSGUniverse & universe, 247 : std::vector<std::reference_wrapper<const CSGCell>> & cells); 248 : 249 : /** 250 : * @brief Get all universe objects 251 : * 252 : * @return list of references to CSGUniverse objects in this CSGBase instance 253 : */ 254 66 : std::vector<std::reference_wrapper<const CSGUniverse>> getAllUniverses() const 255 : { 256 66 : return _universe_list.getAllUniverses(); 257 : } 258 : 259 : /** 260 : * @brief Get a universe object by name 261 : * 262 : * @param name universe name 263 : * @return reference to CSGUniverse object 264 : */ 265 20 : const CSGUniverse & getUniverseByName(const std::string & name) 266 : { 267 20 : return _universe_list.getUniverse(name); 268 : } 269 : 270 : /** 271 : * @brief Join another CSGBase object to this one. The cells of the root universe 272 : * of the incoming CSGBase will be added to the existing root universe of this 273 : * CSGBase. 274 : * 275 : * @param base pointer to a different CSGBase object 276 : */ 277 : void joinOtherBase(std::unique_ptr<CSGBase> base); 278 : 279 : /** 280 : * @brief Join another CSGBase object to this one. For the incoming CSGBase object, 281 : * the root universe is added to this CSGBase object as a new non-root universe with 282 : * the specified new name. 283 : * Note: this newly created universe will not be connected to the root universe 284 : * of this CSGBase object by default. 285 : * 286 : * @param base pointer to a different CSGBase object 287 : * @param new_root_name_join new name for the universe generated from the incoming root universe 288 : */ 289 : void joinOtherBase(std::unique_ptr<CSGBase> base, std::string & new_root_name_join); 290 : 291 : /** 292 : * @brief Join another CSGBase object to this one. The root universe for the incoming CSGBase 293 : * object is added to this CSGBase object as a non-root universe with a new name. The root 294 : * universe of this CSGBase object will be renamed and designated as non-root. 295 : * Note: upon completion of this join method, the root universe of this CSGBase 296 : * object will be empty. Neither of the new non-root universes will be connected to the 297 : * new root universe by default. 298 : * 299 : * @param base pointer to a different CSGBase object 300 : * @param new_root_name_base new name for universe generated from this root universe 301 : * @param new_root_name_join new name for the universe generated from the incoming root universe 302 : */ 303 : void joinOtherBase(std::unique_ptr<CSGBase> base, 304 : const std::string & new_root_name_base, 305 : const std::string & new_root_name_join); 306 : 307 : /** 308 : * @brief generate the JSON representation output for the CSG object 309 : * 310 : */ 311 : nlohmann::json generateOutput() const; 312 : 313 : private: 314 : /** 315 : * @brief Get a Surface object by name. 316 : * 317 : * Note: This is a private method that returns a non-const reference. For the public method that 318 : * returns a const reference, use `getSurfaceByName` 319 : * 320 : * @param name surface name 321 : * @return reference to CSGSurface object 322 : */ 323 2 : CSGSurface & getSurface(const std::string & name) { return _surface_list.getSurface(name); } 324 : 325 : /// Check universes linked to root universe match universes defined in _universe_list 326 : void checkUniverseLinking() const; 327 : 328 : /** 329 : * @brief Recursive method to retrieve all universes linked to current universe 330 : * 331 : * @param univ Reference to universe under consideration 332 : * @param linked_universe_name List of universe names linked to current universe 333 : */ 334 : void getLinkedUniverses(const CSGUniverse & univ, 335 : std::vector<std::string> & linked_universe_names) const; 336 : 337 : /** 338 : * @brief Get the CSGSurfaceList object 339 : * 340 : * @return CSGSurfaceList 341 : */ 342 6 : CSGSurfaceList & getSurfaceList() { return _surface_list; } 343 : 344 : /** 345 : * @brief Get the CSGCellList object 346 : * 347 : * @return CSGCellList 348 : */ 349 6 : CSGCellList & getCellList() { return _cell_list; } 350 : 351 : /** 352 : * @brief Get the CSGUniverseList object 353 : * 354 : * @return CSGUniverseList 355 : */ 356 6 : CSGUniverseList & getUniverseList() { return _universe_list; } 357 : 358 : /** 359 : * @brief join a separate CSGSurfaceList object to this one 360 : * 361 : * @param surf_list CSGSurfaceList from a separate CSGBase object 362 : */ 363 : void joinSurfaceList(CSGSurfaceList & surf_list); 364 : 365 : /** 366 : * @brief join a separate CSGCellList object to this one 367 : * 368 : * @param cell_list CSGCellList from a separate CSGBase object 369 : */ 370 : void joinCellList(CSGCellList & cell_list); 371 : 372 : /** 373 : * @brief join a separate CSGUniverseList object to this one; 374 : * root universes from univ_list will be combined into this root universe 375 : * 376 : * @param univ_list CSGUniverseList from a separate CSGBase object 377 : */ 378 : void joinUniverseList(CSGUniverseList & univ_list); 379 : 380 : /** 381 : * @brief join a separate CSGUniverseList object to this one; 382 : * the incoming root universe will be moved to a new universe of the new 383 : * name specified. 384 : * 385 : * @param univ_list CSGUniverseList from a separate CSGBase object 386 : * @param new_root_name_incoming new name for the universe generated from the incoming root 387 : * universe 388 : */ 389 : void joinUniverseList(CSGUniverseList & univ_list, const std::string & new_root_name_incoming); 390 : 391 : /** 392 : * @brief join a separate CSGUniverseList object to this one; 393 : * both this root universe and the incoming root universe will be 394 : * maintained as separate universes of the specified names. 395 : * Note: upon completion of this join method, the root universe will be empty. 396 : * 397 : * @param univ_list CSGUniverseList from a separate CSGBase object 398 : * @param new_root_name_base new name for universe generated from this root universe 399 : * @param new_root_name_incoming new name for the universe generated from the incoming root 400 : * universe 401 : */ 402 : void joinUniverseList(CSGUniverseList & univ_list, 403 : const std::string & new_root_name_base, 404 : const std::string & new_root_name_incoming); 405 : 406 : // check that surfaces used in this region are a part of this CSGBase instance 407 : void checkRegionSurfaces(const CSGRegion & region) const; 408 : 409 : // check that cell being accessed is a part of this CSGBase instance 410 : bool checkCellInBase(const CSGCell & cell) const; 411 : 412 : // check that universe being accessed is a part of this CSGBase instance 413 : bool checkUniverseInBase(const CSGUniverse & universe) const; 414 : 415 : /// List of surfaces associated with CSG object 416 : CSGSurfaceList _surface_list; 417 : 418 : /// List of cells associated with CSG object 419 : CSGCellList _cell_list; 420 : 421 : /// List of universes associated with CSG object 422 : CSGUniverseList _universe_list; 423 : 424 : #ifdef MOOSE_UNIT_TEST 425 : /// Friends for unit testing 426 : ///@{ 427 : FRIEND_TEST(CSGBaseTest, testCheckRegionSurfaces); 428 : FRIEND_TEST(CSGBaseTest, testAddGetSurface); 429 : FRIEND_TEST(CSGBaseTest, testUniverseLinking); 430 : ///@} 431 : #endif 432 : }; 433 : } // namespace CSG