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