LCOV - code coverage report
Current view: top level - src/csg - CSGBase.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 533 569 93.7 %
Date: 2026-05-29 20:35:17 Functions: 56 56 100.0 %
Legend: Lines: hit not hit

          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             : #include "CSGBase.h"
      11             : #include "CSGUtils.h"
      12             : #include "JsonIO.h"
      13             : 
      14             : namespace CSG
      15             : {
      16             : 
      17         274 : CSGBase::CSGBase()
      18         274 :   : _surface_list(CSGSurfaceList()),
      19         274 :     _cell_list(CSGCellList()),
      20         274 :     _universe_list(CSGUniverseList()),
      21         274 :     _lattice_list(CSGLatticeList())
      22             : {
      23         274 : }
      24             : 
      25          12 : CSGBase::CSGBase(const CSGBase & other_base)
      26          12 :   : _surface_list(other_base.getSurfaceList()),
      27          12 :     _cell_list(CSGCellList()),
      28          12 :     _universe_list(CSGUniverseList()),
      29          12 :     _lattice_list(CSGLatticeList())
      30             : {
      31             :   // Iterate through all cell references from the other CSGBase instance and
      32             :   // create new CSGCell pointers based on these references. This is done
      33             :   // recursively to properly handle cells with universe fills
      34          70 :   for (const auto & [name, cell] : other_base.getCellList().getCellListMap())
      35          58 :     addCellToList(*cell);
      36             : 
      37             :   // Link all cells in other_base root universe to current root universe
      38          36 :   for (auto & root_cell : other_base.getRootUniverse().getAllCells())
      39             :   {
      40          24 :     const auto & list_cell = _cell_list.getCell(root_cell.get().getName());
      41          24 :     addCellToUniverse(getRootUniverse(), list_cell);
      42             :   }
      43             : 
      44             :   // Iterate through all universe references from the other CSGBase instance and
      45             :   // create new CSGUniverse pointers based on these references. This is done in case
      46             :   // any universe exist in the universe list that are not connected to the cell list.
      47          54 :   for (const auto & [name, univ] : other_base.getUniverseList().getUniverseListMap())
      48          42 :     addUniverseToList(*univ);
      49             : 
      50             :   // Iterate through all lattice references from the other CSGBase instance and
      51             :   // create new CSGLattice pointers based on these references.
      52          22 :   for (const auto & [name, lattice] : other_base.getLatticeList().getLatticeListMap())
      53          10 :     addLatticeToList(*lattice);
      54          12 : }
      55             : 
      56         280 : CSGBase::~CSGBase() {}
      57             : 
      58             : void
      59           6 : CSGBase::deleteSurface(const CSGSurface & surface)
      60             : {
      61           6 :   if (!checkSurfaceInBase(surface))
      62           0 :     mooseError("Surface with name ",
      63           0 :                surface.getName(),
      64             :                " cannot be deleted as it is different from the surface of the same name in the "
      65             :                "CSGBase instance.");
      66             : 
      67             :   // Check if surface is used in region definition of existing cells
      68           6 :   for (const auto & cell_ref : _cell_list.getAllCells())
      69             :   {
      70           2 :     const auto & cell = cell_ref.get();
      71           2 :     const auto & cell_region = cell.getRegion();
      72           2 :     const auto & region_surfaces = cell_region.getSurfaces();
      73           2 :     for (const auto & region_surf : region_surfaces)
      74           2 :       if (region_surf.get() == surface)
      75           2 :         mooseError("Cannot delete surface with name ",
      76           2 :                    surface.getName(),
      77             :                    " as it is used in region definition of cell with name ",
      78           2 :                    cell.getName());
      79           8 :   }
      80             : 
      81           4 :   _surface_list.getSurfaceListMap().erase(surface.getName());
      82           4 : }
      83             : 
      84             : const CSGCell &
      85          92 : CSGBase::addCellToList(const CSGCell & cell)
      86             : {
      87             :   // If cell has already been created, we just return a reference to it
      88          92 :   const auto name = cell.getName();
      89          92 :   if (_cell_list.hasCell(name))
      90          34 :     return _cell_list.getCell(name);
      91             : 
      92             :   // Otherwise if the cell has material or void cell, we can create it directly
      93          58 :   const auto fill_type = cell.getFillType();
      94          58 :   const auto region = cell.getRegion();
      95          58 :   if (fill_type == "VOID")
      96          12 :     return _cell_list.addVoidCell(name, region);
      97          46 :   else if (fill_type == "CSG_MATERIAL")
      98             :   {
      99          26 :     const auto mat_name = cell.getFillMaterial();
     100          26 :     return _cell_list.addMaterialCell(name, mat_name, region);
     101          26 :   }
     102          20 :   else if (fill_type == "LATTICE")
     103             :   {
     104             :     // add lattice recursively to capture all linked universes in the lattice
     105          10 :     const CSGLattice & lattice = addLatticeToList(cell.getFillLattice());
     106          10 :     return _cell_list.addLatticeCell(name, lattice, region);
     107             :   }
     108             :   // Otherwise if the cell has a universe fill, we need to recursively define
     109             :   // all linked universes and cells first before defining this cell
     110          10 :   else if (fill_type == "UNIVERSE")
     111             :   {
     112          10 :     const auto & univ = addUniverseToList(cell.getFillUniverse());
     113          10 :     return _cell_list.addUniverseCell(name, univ, region);
     114             :   }
     115             :   else
     116           0 :     mooseError("Cell " + name + " has unrecognized fill type " + fill_type);
     117          92 : }
     118             : 
     119             : const CSGUniverse &
     120          96 : CSGBase::addUniverseToList(const CSGUniverse & univ)
     121             : {
     122             :   // If universe has already been created, we just return a reference to it
     123          96 :   const auto name = univ.getName();
     124          96 :   if (_universe_list.hasUniverse(name))
     125          66 :     return _universe_list.getUniverse(name);
     126             : 
     127             :   // Otherwise we create a new universe based on its associated cells.
     128             :   // addCellToList is called recursively in case associated cells have not
     129             :   // been added to the cell list yet.
     130          30 :   const auto univ_cells = univ.getAllCells();
     131          30 :   std::vector<std::reference_wrapper<const CSGCell>> current_univ_cells;
     132          64 :   for (const auto & univ_cell : univ_cells)
     133          34 :     current_univ_cells.push_back(addCellToList(univ_cell));
     134          30 :   return createUniverse(name, current_univ_cells);
     135          96 : }
     136             : 
     137             : const CSGLattice &
     138          20 : CSGBase::addLatticeToList(const CSGLattice & lattice)
     139             : {
     140             :   // If lattice has already been created, we just return a reference to it
     141          20 :   const auto name = lattice.getName();
     142          20 :   if (_lattice_list.hasLattice(name))
     143          10 :     return _lattice_list.getLattice(name);
     144             : 
     145             :   // Clone the lattice (associated universes need to be transferred and set)
     146          10 :   auto cloned_lattice = lattice.clone();
     147             : 
     148             :   // If lattice has associated universes, we need to add them to this CSGBase instance as well.
     149             :   // addUniverseToList is called recursively in case associated universes have not been added to
     150             :   // the universe list yet.
     151          10 :   std::vector<std::vector<std::reference_wrapper<const CSGUniverse>>> current_univ_map;
     152          28 :   for (const auto & univ_list : lattice.getUniverses())
     153             :   {
     154          18 :     std::vector<std::reference_wrapper<const CSGUniverse>> current_univ_list;
     155          52 :     for (const auto & univ_ref : univ_list)
     156          34 :       current_univ_list.push_back(addUniverseToList(univ_ref.get()));
     157          18 :     current_univ_map.push_back(current_univ_list);
     158          28 :   }
     159             : 
     160             :   // Set universes only if lattice has universes defined
     161          10 :   if (current_univ_map.size() > 0)
     162          10 :     cloned_lattice->setUniverses(current_univ_map);
     163             : 
     164             :   // Update reference to outer universe if it exists
     165          10 :   if (lattice.getOuterType() == "UNIVERSE")
     166             :   {
     167          10 :     const auto & outer_univ_ref = addUniverseToList(lattice.getOuterUniverse());
     168          10 :     cloned_lattice->updateOuter(outer_univ_ref);
     169             :   }
     170             : 
     171             :   // Use addLattice to add the cloned lattice
     172          10 :   return addLattice(std::move(cloned_lattice));
     173          20 : }
     174             : 
     175             : void
     176          10 : CSGBase::deleteLattice(const CSGLattice & lattice)
     177             : {
     178          10 :   if (!checkLatticeInBase(lattice))
     179           0 :     mooseError("Lattice with name ",
     180           0 :                lattice.getName(),
     181             :                " cannot be deleted as it is different from the lattice of the same name in the "
     182             :                "CSGBase instance.");
     183             : 
     184             :   // Check if lattice is used as fill in existing cells
     185          12 :   for (const auto & cell_ref : _cell_list.getAllCells())
     186             :   {
     187           4 :     const auto & cell = cell_ref.get();
     188           4 :     if ((cell.getFillType() == "LATTICE") && (cell.getFillLattice() == lattice))
     189           2 :       mooseError("Cannot delete lattice with name ",
     190           2 :                  lattice.getName(),
     191             :                  " as it is used as the fill of cell with name ",
     192           2 :                  cell.getName());
     193          10 :   }
     194             : 
     195           8 :   _lattice_list.getLatticeListMap().erase(lattice.getName());
     196           8 : }
     197             : 
     198             : const CSGCell &
     199         115 : CSGBase::createCell(const std::string & name,
     200             :                     const std::string & mat_name,
     201             :                     const CSGRegion & region,
     202             :                     const CSGUniverse * add_to_univ)
     203             : {
     204         115 :   checkRegionSurfaces(region);
     205         115 :   auto & cell = _cell_list.addMaterialCell(name, mat_name, region);
     206         115 :   if (add_to_univ)
     207          28 :     addCellToUniverse(*add_to_univ, cell);
     208             :   else
     209          87 :     addCellToUniverse(getRootUniverse(), cell);
     210         115 :   return cell;
     211             : }
     212             : 
     213             : const CSGCell &
     214          86 : CSGBase::createCell(const std::string & name,
     215             :                     const CSGRegion & region,
     216             :                     const CSGUniverse * add_to_univ)
     217             : {
     218          86 :   checkRegionSurfaces(region);
     219          86 :   auto & cell = _cell_list.addVoidCell(name, region);
     220          84 :   if (add_to_univ)
     221          10 :     addCellToUniverse(*add_to_univ, cell);
     222             :   else
     223          74 :     addCellToUniverse(getRootUniverse(), cell);
     224          84 :   return cell;
     225             : }
     226             : 
     227             : const CSGCell &
     228          20 : CSGBase::createCell(const std::string & name,
     229             :                     const CSGUniverse & fill_univ,
     230             :                     const CSGRegion & region,
     231             :                     const CSGUniverse * add_to_univ)
     232             : {
     233          20 :   checkRegionSurfaces(region);
     234          20 :   if (add_to_univ && (&fill_univ == add_to_univ))
     235           6 :     mooseError("Cell " + name +
     236             :                " cannot be filled with the same universe to which it is being added.");
     237             : 
     238          18 :   auto & cell = _cell_list.addUniverseCell(name, fill_univ, region);
     239          18 :   if (add_to_univ)
     240          10 :     addCellToUniverse(*add_to_univ, cell);
     241             :   else
     242           8 :     addCellToUniverse(getRootUniverse(), cell);
     243          18 :   return cell;
     244             : }
     245             : 
     246             : const CSGCell &
     247          58 : CSGBase::createCell(const std::string & name,
     248             :                     const CSGLattice & fill_lattice,
     249             :                     const CSGRegion & region,
     250             :                     const CSGUniverse * add_to_univ)
     251             : {
     252          58 :   checkRegionSurfaces(region);
     253             : 
     254             :   // check that cell is not being added to a universe that exists in the lattice itself
     255          58 :   if (add_to_univ)
     256           6 :     for (auto univ_list : fill_lattice.getUniverses())
     257           8 :       for (const auto & univ_ref : univ_list)
     258             :       {
     259           6 :         const CSGUniverse & univ_in_lattice = univ_ref.get();
     260           6 :         if (&univ_in_lattice == add_to_univ)
     261           6 :           mooseError("Cell " + name +
     262             :                      " cannot be filled with a lattice containing the same universe to which it is "
     263             :                      "being added.");
     264           8 :       }
     265             : 
     266          56 :   auto & cell = _cell_list.addLatticeCell(name, fill_lattice, region);
     267          56 :   if (add_to_univ)
     268           2 :     addCellToUniverse(*add_to_univ, cell);
     269             :   else
     270          54 :     addCellToUniverse(getRootUniverse(), cell);
     271          56 :   return cell;
     272             : }
     273             : 
     274             : void
     275          20 : CSGBase::deleteCell(const CSGCell & cell)
     276             : {
     277          20 :   if (!checkCellInBase(cell))
     278           0 :     mooseError("Cell with name ",
     279           0 :                cell.getName(),
     280             :                " cannot be deleted as it is different from the cell of the same name in the "
     281             :                "CSGBase instance.");
     282             : 
     283             :   // Check if cell exists in any existing universes. Cell will be removed from these universes
     284          40 :   for (const auto & univ_ref : _universe_list.getAllUniverses())
     285             :   {
     286          22 :     const auto & univ = univ_ref.get();
     287          22 :     const auto & univ_cells = univ.getAllCells();
     288          32 :     for (const auto & univ_cell : univ_cells)
     289          12 :       if (cell == univ_cell.get() && univ != getRootUniverse())
     290             :       {
     291           2 :         mooseWarning("Removing cell ",
     292           2 :                      cell.getName(),
     293             :                      " from universe with name ",
     294           2 :                      univ.getName(),
     295             :                      " before cell deletion.");
     296           0 :         auto & univ_to_modify = _universe_list.getUniverse(univ.getName());
     297           0 :         univ_to_modify.removeCell(cell.getName());
     298             :       }
     299          20 :   }
     300             : 
     301          18 :   _cell_list.getCellListMap().erase(cell.getName());
     302          18 : }
     303             : 
     304             : void
     305          20 : CSGBase::updateCellRegion(const CSGCell & cell, const CSGRegion & region)
     306             : {
     307          20 :   checkRegionSurfaces(region);
     308          20 :   if (!checkCellInBase(cell))
     309          10 :     mooseError("The region of cell with name " + cell.getName() +
     310           4 :                " that is being updated is different " +
     311             :                "from the cell of the same name in the CSGBase instance.");
     312          18 :   auto & list_cell = _cell_list.getCell(cell.getName());
     313          18 :   list_cell.updateRegion(region);
     314          18 : }
     315             : 
     316             : void
     317           6 : CSGBase::resetCellFill(const CSGCell & cell)
     318             : {
     319           6 :   if (!checkCellInBase(cell))
     320           0 :     mooseError("The fill of cell with name " + cell.getName() +
     321           0 :                " that is being updated is different " +
     322             :                "from the cell of the same name in the CSGBase instance.");
     323           6 :   auto & list_cell = _cell_list.getCell(cell.getName());
     324           6 :   list_cell.resetCellFill();
     325           6 : }
     326             : 
     327             : void
     328           2 : CSGBase::updateCellFill(const CSGCell & cell, const std::string & mat_name)
     329             : {
     330           2 :   if (!checkCellInBase(cell))
     331           0 :     mooseError("The region of cell with name " + cell.getName() +
     332           0 :                " that is being updated is different " +
     333             :                "from the cell of the same name in the CSGBase instance.");
     334           2 :   auto & list_cell = _cell_list.getCell(cell.getName());
     335           2 :   list_cell.updateCellFill(mat_name);
     336           2 : }
     337             : 
     338             : void
     339           2 : CSGBase::updateCellFill(const CSGCell & cell, const CSGUniverse * univ)
     340             : {
     341           2 :   if (!checkUniverseInBase(*univ))
     342           0 :     mooseError("Universe with name ",
     343           0 :                univ->getName(),
     344             :                " is being used as a cell fill that is different from the universe of the same name "
     345             :                "in the CSGBase instance.");
     346           2 :   if (!checkCellInBase(cell))
     347           0 :     mooseError("The fill of cell with name " + cell.getName() +
     348           0 :                " that is being updated is different " +
     349             :                "from the cell of the same name in the CSGBase instance.");
     350           2 :   auto & list_cell = _cell_list.getCell(cell.getName());
     351           2 :   list_cell.updateCellFill(univ);
     352           2 : }
     353             : 
     354             : void
     355           2 : CSGBase::updateCellFill(const CSGCell & cell, const CSGLattice * lattice)
     356             : {
     357           2 :   if (!checkLatticeInBase(*lattice))
     358           0 :     mooseError("Lattice with name ",
     359           0 :                lattice->getName(),
     360             :                " is being used as a cell fill that is different from the lattice of the same name "
     361             :                "in the CSGBase instance.");
     362           2 :   if (!checkCellInBase(cell))
     363           0 :     mooseError("The fill of cell with name " + cell.getName() +
     364           0 :                " that is being updated is different " +
     365             :                "from the cell of the same name in the CSGBase instance.");
     366           2 :   auto & list_cell = _cell_list.getCell(cell.getName());
     367           2 :   list_cell.updateCellFill(lattice);
     368           2 : }
     369             : 
     370             : const CSGUniverse &
     371         106 : CSGBase::createUniverse(const std::string & name,
     372             :                         std::vector<std::reference_wrapper<const CSGCell>> & cells)
     373             : {
     374         106 :   auto & univ = _universe_list.addUniverse(name);
     375         106 :   addCellsToUniverse(univ, cells); // performs a check that cells are a part of this base
     376         106 :   return univ;
     377             : }
     378             : 
     379             : void
     380          28 : CSGBase::deleteUniverse(const CSGUniverse & univ)
     381             : {
     382          28 :   if (!checkUniverseInBase(univ))
     383           0 :     mooseError("Universe with name ",
     384           0 :                univ.getName(),
     385             :                " cannot be deleted as it is different from the universe of the same name in the "
     386             :                "CSGBase instance.");
     387             : 
     388             :   // Check if universe is the root universe
     389          28 :   if (univ == getRootUniverse())
     390           2 :     mooseError("Cannot delete root universe from CSGBase instance");
     391             : 
     392             :   // Check if universe is used in any existing lattices
     393          26 :   for (const auto & lat : _lattice_list.getAllLattices())
     394             :   {
     395           4 :     const auto & lattice_univs = lat.get().getUniqueUniverses();
     396           6 :     for (const auto & lat_univ : lattice_univs)
     397           4 :       if (univ == lat_univ.get())
     398           2 :         mooseError("Cannot delete universe with name ",
     399           2 :                    univ.getName(),
     400             :                    " as it is used in lattice with name ",
     401           2 :                    lat.get().getName());
     402           2 :     if ((lat.get().getOuterType() == "UNIVERSE") && (lat.get().getOuterUniverse() == univ))
     403           2 :       mooseError("Cannot delete universe with name ",
     404           2 :                  univ.getName(),
     405             :                  " as it is used as the outer universe of lattice with name ",
     406           2 :                  lat.get().getName());
     407          30 :   }
     408             : 
     409             :   // Check if universe is used as fill in existing cells
     410          34 :   for (const auto & cell_ref : _cell_list.getAllCells())
     411             :   {
     412          14 :     const auto & cell = cell_ref.get();
     413          14 :     if ((cell.getFillType() == "UNIVERSE") && (cell.getFillUniverse() == univ))
     414           2 :       mooseError("Cannot delete universe with name ",
     415           2 :                  univ.getName(),
     416             :                  " as it is used as the fill of cell with name ",
     417           2 :                  cell.getName());
     418          22 :   }
     419             : 
     420          20 :   _universe_list.getUniverseListMap().erase(univ.getName());
     421          20 : }
     422             : 
     423             : void
     424         461 : CSGBase::addCellToUniverse(const CSGUniverse & universe, const CSGCell & cell)
     425             : {
     426             :   // make sure cell is a part of this CSGBase instance
     427         461 :   if (!checkCellInBase(cell))
     428          12 :     mooseError("A cell named " + cell.getName() + " is being added to universe " +
     429           8 :                universe.getName() +
     430             :                " that is different from the cell of the same name in the CSGBase instance.");
     431             :   // make sure universe is a part of this CSGBase instance
     432         459 :   if (!checkUniverseInBase(universe))
     433          10 :     mooseError("Cells are being added to a universe named " + universe.getName() +
     434           4 :                " that is different " +
     435             :                "from the universe of the same name in the CSGBase instance.");
     436         457 :   auto & univ = _universe_list.getUniverse(universe.getName());
     437         457 :   univ.addCell(cell);
     438         457 : }
     439             : 
     440             : void
     441         108 : CSGBase::addCellsToUniverse(const CSGUniverse & universe,
     442             :                             std::vector<std::reference_wrapper<const CSGCell>> & cells)
     443             : {
     444         228 :   for (auto & c : cells)
     445         120 :     addCellToUniverse(universe, c);
     446         108 : }
     447             : 
     448             : void
     449          14 : CSGBase::removeCellFromUniverse(const CSGUniverse & universe, const CSGCell & cell)
     450             : {
     451             :   // make sure cell is a part of this CSGBase instance
     452          14 :   if (!checkCellInBase(cell))
     453          12 :     mooseError("A cell named " + cell.getName() + " is being removed from universe " +
     454           8 :                universe.getName() +
     455             :                " that is different from the cell of the same name in the CSGBase instance.");
     456             :   // make sure universe is a part of this CSGBase instance
     457          12 :   if (!checkUniverseInBase(universe))
     458          10 :     mooseError("Cells are being removed from a universe named " + universe.getName() +
     459           4 :                " that is different " +
     460             :                "from the universe of the same name in the CSGBase instance.");
     461          10 :   auto & univ = _universe_list.getUniverse(universe.getName());
     462          10 :   univ.removeCell(cell.getName());
     463          10 : }
     464             : 
     465             : void
     466           4 : CSGBase::removeCellsFromUniverse(const CSGUniverse & universe,
     467             :                                  std::vector<std::reference_wrapper<const CSGCell>> & cells)
     468             : {
     469          10 :   for (auto & c : cells)
     470           6 :     removeCellFromUniverse(universe, c);
     471           4 : }
     472             : 
     473             : void
     474           2 : CSGBase::setLatticeOuter(const CSGLattice & lattice, const std::string & outer_name)
     475             : {
     476           2 :   auto name = lattice.getName();
     477           2 :   if (!checkLatticeInBase(lattice))
     478           0 :     mooseError("Cannot set outer for lattice " + name +
     479             :                ". Lattice is different from the lattice of the same name in the "
     480             :                "CSGBase instance.");
     481           2 :   _lattice_list.getLattice(name).updateOuter(outer_name);
     482           2 : }
     483             : 
     484             : void
     485          18 : CSGBase::setLatticeOuter(const CSGLattice & lattice, const CSGUniverse & outer_univ)
     486             : {
     487          18 :   auto name = lattice.getName();
     488          18 :   if (!checkLatticeInBase(lattice))
     489           0 :     mooseError("Cannot set outer universe for lattice " + name +
     490             :                ". Lattice is different from the lattice of the same name in the "
     491             :                "CSGBase instance.");
     492          18 :   if (!checkUniverseInBase(outer_univ))
     493          12 :     mooseError("Cannot set outer universe for lattice " + name + ". Outer universe " +
     494           8 :                outer_univ.getName() + " is not in the CSGBase instance.");
     495          16 :   _lattice_list.getLattice(name).updateOuter(outer_univ);
     496          18 : }
     497             : 
     498             : void
     499           4 : CSGBase::resetLatticeOuter(const CSGLattice & lattice)
     500             : {
     501           4 :   auto name = lattice.getName();
     502           4 :   if (!checkLatticeInBase(lattice))
     503           0 :     mooseError("Cannot reset outer for lattice " + name +
     504             :                ". Lattice is different from the lattice of the same name in the "
     505             :                "CSGBase instance.");
     506           4 :   _lattice_list.getLattice(name).resetOuter();
     507           4 : }
     508             : 
     509             : void
     510           4 : CSGBase::setUniverseAtLatticeIndex(const CSGLattice & lattice,
     511             :                                    const CSGUniverse & universe,
     512             :                                    std::pair<int, int> index)
     513             : {
     514           4 :   auto name = lattice.getName();
     515           4 :   if (!checkLatticeInBase(lattice))
     516           0 :     mooseError("Cannot set universe at index for lattice " + name +
     517             :                ". Lattice is different from the lattice of the same name in the "
     518             :                "CSGBase instance.");
     519           4 :   if (!checkUniverseInBase(universe))
     520          10 :     mooseError("Cannot add universe " + universe.getName() + " to lattice " + lattice.getName() +
     521             :                ". Universe is not in the CSGBase instance.");
     522           2 :   _lattice_list.getLattice(name).setUniverseAtIndex(universe, index);
     523           4 : }
     524             : 
     525             : void
     526           8 : CSGBase::setLatticeUniverses(
     527             :     const CSGLattice & lattice,
     528             :     std::vector<std::vector<std::reference_wrapper<const CSGUniverse>>> & universes)
     529             : {
     530           8 :   auto name = lattice.getName();
     531           8 :   if (!checkLatticeInBase(lattice))
     532           0 :     mooseError("Cannot set universes for lattice " + name +
     533             :                ". Lattice is different from the lattice of the same name in the "
     534             :                "CSGBase instance.");
     535             :   // make sure all universes are a part of this base instance
     536          20 :   for (auto univ_list : universes)
     537          26 :     for (const CSGUniverse & univ : univ_list)
     538          14 :       if (!checkUniverseInBase(univ))
     539          10 :         mooseError("Cannot set universes for lattice " + name + ". Universe " + univ.getName() +
     540          14 :                    " is not in the CSGBase instance.");
     541           6 :   _lattice_list.getLattice(name).setUniverses(universes);
     542           8 : }
     543             : 
     544             : void
     545         120 : CSGBase::addTransformation(const CSGObjectVariant & csg_object,
     546             :                            TransformationType type,
     547             :                            const std::tuple<Real, Real, Real> & values)
     548             : {
     549             :   // Use std::visit to handle each type in the variant
     550         120 :   std::visit(
     551         240 :       [&](const auto & obj)
     552             :       {
     553             :         using T = std::decay_t<decltype(obj.get())>;
     554             : 
     555             :         // Handle each CSG object type differently because each needs to check that it exists in
     556             :         // this base instance
     557             :         if constexpr (std::is_same_v<T, CSGCell>)
     558             :         {
     559          40 :           const CSGCell & cell = obj.get();
     560          40 :           if (!checkCellInBase(cell))
     561           2 :             mooseError("Cannot apply transformation to cell ",
     562           2 :                        cell.getName(),
     563             :                        " that is not in this CSGBase instance.");
     564             : 
     565             :           // Get non-const reference and apply transformation
     566          38 :           CSGCell & mutable_cell = _cell_list.getCell(cell.getName());
     567             :           mooseAssert(mutable_cell == cell, "Mutable cell does not match const cell passed in.");
     568          38 :           mutable_cell.addTransformation(type, values);
     569             :         }
     570             :         else if constexpr (std::is_same_v<T, CSGSurface>)
     571             :         {
     572          32 :           const CSGSurface & surface = obj.get();
     573          32 :           if (!checkSurfaceInBase(surface))
     574           2 :             mooseError("Cannot apply transformation to surface ",
     575           2 :                        surface.getName(),
     576             :                        " that is not in this CSGBase instance.");
     577             : 
     578             :           // Get non-const reference and apply transformation
     579          30 :           CSGSurface & mutable_surface = _surface_list.getSurface(surface.getName());
     580             :           mooseAssert(mutable_surface == surface,
     581             :                       "Mutable surface does not match const surface passed in.");
     582          30 :           mutable_surface.addTransformation(type, values);
     583             :         }
     584             :         else if constexpr (std::is_same_v<T, CSGUniverse>)
     585             :         {
     586          16 :           const CSGUniverse & universe = obj.get();
     587          16 :           if (!checkUniverseInBase(universe))
     588           2 :             mooseError("Cannot apply transformation to universe ",
     589           2 :                        universe.getName(),
     590             :                        " that is not in this CSGBase instance.");
     591             : 
     592             :           // Get non-const reference and apply transformation
     593          14 :           CSGUniverse & mutable_universe = _universe_list.getUniverse(universe.getName());
     594             :           mooseAssert(mutable_universe == universe,
     595             :                       "Mutable universe does not match const universe passed in.");
     596          14 :           mutable_universe.addTransformation(type, values);
     597             :         }
     598             :         else if constexpr (std::is_same_v<T, CSGLattice>)
     599             :         {
     600          16 :           const CSGLattice & lattice = obj.get();
     601          16 :           if (!checkLatticeInBase(lattice))
     602           2 :             mooseError("Cannot apply transformation to lattice ",
     603           2 :                        lattice.getName(),
     604             :                        " that is not in this CSGBase instance.");
     605             : 
     606             :           // Get non-const reference and apply transformation
     607          14 :           CSGLattice & mutable_lattice = _lattice_list.getLattice(lattice.getName());
     608             :           mooseAssert(mutable_lattice == lattice,
     609             :                       "Mutable lattice does not match const lattice passed in.");
     610          14 :           mutable_lattice.addTransformation(type, values);
     611             :         }
     612             :         else if constexpr (std::is_same_v<T, CSGRegion>)
     613             :         {
     614             :           // iterate on the surfaces of the region and apply the transformation to those surfaces
     615          16 :           const CSGRegion & region = obj.get();
     616          16 :           const auto surfaces = region.getSurfaces();
     617          30 :           for (const CSGSurface & surface : surfaces)
     618             :           {
     619          16 :             if (!checkSurfaceInBase(surface))
     620           2 :               mooseError("Cannot apply transformation to region with surface ",
     621           2 :                          surface.getName(),
     622             :                          " that is not in this CSGBase instance.");
     623          14 :             addTransformation(surface, type, values);
     624             :           }
     625          16 :         }
     626             :         else
     627             :           mooseError("Transformation not implemented for this object type: ", typeid(T).name());
     628         108 :       },
     629             :       csg_object);
     630         108 : }
     631             : 
     632             : void
     633          56 : CSGBase::applyAxisRotation(const CSGObjectVariant & csg_object,
     634             :                            RotationAxisType axis,
     635             :                            const Real angle)
     636             : {
     637             :   // convert to the Euler angles (phi, theta, psi) based on axis
     638          56 :   Real phi = 0.0;
     639          56 :   Real theta = 0.0;
     640          56 :   Real psi = 0.0;
     641             : 
     642          56 :   switch (axis)
     643             :   {
     644          20 :     case RotationAxisType::X:
     645          20 :       theta = angle;
     646          20 :       break;
     647          10 :     case RotationAxisType::Y:
     648          10 :       phi = 90.0;
     649          10 :       theta = angle;
     650          10 :       psi = -90.0;
     651          10 :       break;
     652          26 :     case RotationAxisType::Z:
     653          26 :       phi = angle;
     654          26 :       break;
     655           0 :     default:
     656           0 :       mooseError("Invalid axis type provided for axis rotation.");
     657             :   }
     658             : 
     659          56 :   addTransformation(csg_object, TransformationType::ROTATION, std::make_tuple(phi, theta, psi));
     660          46 : }
     661             : 
     662             : void
     663          54 : CSGBase::joinOtherBase(std::unique_ptr<CSGBase> base, const bool ignore_identical_surfaces)
     664             : {
     665             :   // If we are ignoring identical incoming surfaces, we need to update the cell regions to
     666             :   // point to the references of the pre-existing surfaces
     667          54 :   if (ignore_identical_surfaces)
     668           2 :     updateIncomingCellRegions(base->getSurfaceList(), base->getCellList());
     669          54 :   joinSurfaceList(base->getSurfaceList(), ignore_identical_surfaces);
     670          52 :   joinCellList(base->getCellList());
     671          52 :   joinLatticeList(base->getLatticeList());
     672          52 :   joinUniverseList(base->getUniverseList());
     673          52 : }
     674             : 
     675             : void
     676          58 : CSGBase::joinOtherBase(std::unique_ptr<CSGBase> base,
     677             :                        const bool ignore_identical_surfaces,
     678             :                        const std::string & new_root_name_join)
     679             : {
     680             :   // If we are ignoring identical incoming surfaces, we need to update the cell regions to
     681             :   // point to the references of the pre-existing surfaces
     682          58 :   if (ignore_identical_surfaces)
     683           0 :     updateIncomingCellRegions(base->getSurfaceList(), base->getCellList());
     684          58 :   joinSurfaceList(base->getSurfaceList(), ignore_identical_surfaces);
     685          58 :   joinCellList(base->getCellList());
     686          58 :   joinLatticeList(base->getLatticeList());
     687          58 :   joinUniverseList(base->getUniverseList(), new_root_name_join);
     688          58 : }
     689             : 
     690             : void
     691           2 : CSGBase::joinOtherBase(std::unique_ptr<CSGBase> base,
     692             :                        const bool ignore_identical_surfaces,
     693             :                        const std::string & new_root_name_base,
     694             :                        const std::string & new_root_name_join)
     695             : {
     696             :   // If we are ignoring identical incoming surfaces, we need to update the cell regions to
     697             :   // point to the references of the pre-existing surfaces
     698           2 :   if (ignore_identical_surfaces)
     699           0 :     updateIncomingCellRegions(base->getSurfaceList(), base->getCellList());
     700           2 :   joinSurfaceList(base->getSurfaceList(), ignore_identical_surfaces);
     701           2 :   joinCellList(base->getCellList());
     702           2 :   joinLatticeList(base->getLatticeList());
     703           2 :   joinUniverseList(base->getUniverseList(), new_root_name_base, new_root_name_join);
     704           2 : }
     705             : 
     706             : void
     707           2 : CSGBase::updateIncomingCellRegions(CSGSurfaceList & surf_list, CSGCellList & cell_list)
     708             : {
     709             :   // Iterate through all incoming surfaces and track which ones have names already
     710             :   // defined within this CSGSurfaceList object
     711           2 :   std::map<std::string, std::reference_wrapper<const CSGSurface>> identical_surface_refs;
     712           2 :   auto & surf_list_map = surf_list.getSurfaceListMap();
     713           4 :   for (const auto & s : surf_list_map)
     714           2 :     if (hasSurface(s.first))
     715           2 :       identical_surface_refs.insert({s.first, getSurfaceByName(s.first)});
     716             : 
     717           2 :   if (!identical_surface_refs.empty())
     718             :   {
     719           2 :     auto & cell_list_map = cell_list.getCellListMap();
     720           4 :     for (auto & c : cell_list_map)
     721           2 :       c.second->updateCellRegionSurfaces(identical_surface_refs);
     722             :   }
     723           2 : }
     724             : 
     725             : void
     726         114 : CSGBase::joinSurfaceList(CSGSurfaceList & surf_list, const bool ignore_identical_surfaces)
     727             : {
     728         114 :   auto & surf_list_map = surf_list.getSurfaceListMap();
     729         666 :   for (auto & s : surf_list_map)
     730         556 :     _surface_list.addSurface(std::move(s.second), ignore_identical_surfaces);
     731         112 : }
     732             : 
     733             : void
     734         112 : CSGBase::joinCellList(CSGCellList & cell_list)
     735             : {
     736         112 :   auto & cell_list_map = cell_list.getCellListMap();
     737         342 :   for (auto & c : cell_list_map)
     738         230 :     _cell_list.addCell(std::move(c.second));
     739         112 : }
     740             : 
     741             : void
     742         112 : CSGBase::joinLatticeList(CSGLatticeList & lattice_list)
     743             : {
     744         112 :   auto & lat_list_map = lattice_list.getLatticeListMap();
     745         176 :   for (auto & lat : lat_list_map)
     746          64 :     _lattice_list.addLattice(std::move(lat.second));
     747         112 : }
     748             : 
     749             : void
     750          52 : CSGBase::joinUniverseList(CSGUniverseList & univ_list)
     751             : {
     752             :   // case 1: incoming root is joined into existing root; no new universes are created
     753          52 :   auto & univ_list_map = univ_list.getUniverseListMap();
     754          52 :   auto & root = getRootUniverse(); // this root universe
     755         210 :   for (auto & u : univ_list_map)
     756             :   {
     757         158 :     if (u.second->isRoot())
     758             :     {
     759             :       // add existing cells to current root instead of creating new universe
     760          52 :       auto all_cells = u.second->getAllCells();
     761          88 :       for (auto & cell : all_cells)
     762          36 :         addCellToUniverse(root, cell);
     763          52 :     }
     764             :     else // unique non-root universe to add to list
     765         106 :       _universe_list.addUniverse(std::move(u.second));
     766             :   }
     767          52 : }
     768             : 
     769             : void
     770          58 : CSGBase::joinUniverseList(CSGUniverseList & univ_list, const std::string & new_root_name_incoming)
     771             : {
     772             :   // case 2: incoming root is turned into new universe and existing root remains root
     773             : 
     774             :   // add incoming universes to current Base
     775          58 :   auto & all_univs = univ_list.getUniverseListMap();
     776         126 :   for (auto & u : all_univs)
     777             :   {
     778          68 :     if (u.second->isRoot())
     779             :     {
     780             :       // create new universe from incoming root universe
     781          58 :       auto all_cells = u.second->getAllCells();
     782          58 :       createUniverse(new_root_name_incoming, all_cells);
     783          58 :     }
     784             :     else // unique non-root universe to add to list
     785          10 :       _universe_list.addUniverse(std::move(u.second));
     786             :   }
     787          58 : }
     788             : 
     789             : void
     790           2 : CSGBase::joinUniverseList(CSGUniverseList & univ_list,
     791             :                           const std::string & new_root_name_base,
     792             :                           const std::string & new_root_name_incoming)
     793             : {
     794             :   // case 3: each root universe becomes a new universe and a new root is created
     795             : 
     796             :   // make a new universe from the existing root universe
     797           2 :   auto & root = getRootUniverse();
     798           2 :   auto root_cells = root.getAllCells();
     799           2 :   createUniverse(new_root_name_base, root_cells);
     800           2 :   removeCellsFromUniverse(root, root_cells);
     801             : 
     802             :   // add incoming universes to current Base
     803           2 :   auto & all_univs = univ_list.getUniverseListMap();
     804           6 :   for (auto & u : all_univs)
     805             :   {
     806           4 :     if (u.second->isRoot())
     807             :     {
     808             :       // create new universe from incoming root universe
     809           2 :       auto all_cells = u.second->getAllCells();
     810           2 :       createUniverse(new_root_name_incoming, all_cells);
     811           2 :     }
     812             :     else // unique non-root universe to add to list
     813           2 :       _universe_list.addUniverse(std::move(u.second));
     814             :   }
     815           2 : }
     816             : 
     817             : void
     818         301 : CSGBase::checkRegionSurfaces(const CSGRegion & region) const
     819             : {
     820         301 :   const auto surfs = region.getSurfaces();
     821        1035 :   for (const CSGSurface & s : surfs)
     822             :   {
     823         736 :     if (!checkSurfaceInBase(s))
     824           6 :       mooseError("Region is being set with a surface named " + s.getName() +
     825             :                  " that is different from the surface of the same name in the CSGBase instance.");
     826             :   }
     827         301 : }
     828             : 
     829             : bool
     830         790 : CSGBase::checkSurfaceInBase(const CSGSurface & surface) const
     831             : {
     832         790 :   auto name = surface.getName();
     833             :   // if no surface by this name exists, an error will be produced by getSurface
     834         790 :   auto & list_surf = _surface_list.getSurface(name);
     835             :   // return whether that the surface in the list is the same as the surface provided (in memory)
     836         790 :   return &surface == &list_surf;
     837         790 : }
     838             : 
     839             : bool
     840         567 : CSGBase::checkCellInBase(const CSGCell & cell) const
     841             : {
     842         567 :   auto name = cell.getName();
     843             :   // if no cell by this name exists, an error will be produced by getCell
     844         567 :   auto & list_cell = _cell_list.getCell(name);
     845             :   // return whether that the cell in the list is the same as the cell provided (in memory)
     846         567 :   return &cell == &list_cell;
     847         567 : }
     848             : 
     849             : bool
     850         957 : CSGBase::checkUniverseInBase(const CSGUniverse & universe) const
     851             : {
     852         957 :   auto name = universe.getName();
     853             :   // if no universe by this name exists, an error will be produced by getUniverse
     854         957 :   auto & list_univ = _universe_list.getUniverse(name);
     855             :   // return whether that the universe in the list is the same as the universe provided (in memory)
     856         957 :   return &universe == &list_univ;
     857         957 : }
     858             : 
     859             : bool
     860          64 : CSGBase::checkLatticeInBase(const CSGLattice & lattice) const
     861             : {
     862          64 :   auto name = lattice.getName();
     863             :   // if no lattice by this name exists, an error will be produced by getLattice
     864          64 :   auto & list_lattice = _lattice_list.getLattice(name);
     865             :   // return whether that the lattice in the list is the same as the lattice provided (in memory)
     866          64 :   return &lattice == &list_lattice;
     867          64 : }
     868             : 
     869             : void
     870          78 : CSGBase::checkUniverseLinking() const
     871             : {
     872          78 :   std::vector<std::string> linked_universe_names;
     873          78 :   std::vector<std::string> linked_cell_names;
     874             : 
     875             :   // Recursively figure out which universe names are linked to root universe
     876          78 :   getLinkedUniverses(getRootUniverse(), linked_universe_names, linked_cell_names);
     877             : 
     878             :   // Iterate through all universes in universe list and check that they exist in universes linked
     879             :   // to root universe
     880         266 :   for (const CSGUniverse & univ : getAllUniverses())
     881         194 :     if (std::find(linked_universe_names.begin(), linked_universe_names.end(), univ.getName()) ==
     882         388 :         linked_universe_names.end())
     883          78 :       mooseWarning("Universe with name ", univ.getName(), " is not linked to root universe.");
     884             : 
     885             :   // Iterate through all cells in cell list and check that they exist in cells linked
     886             :   // to root universe
     887         284 :   for (const CSGCell & cell : getAllCells())
     888         214 :     if (std::find(linked_cell_names.begin(), linked_cell_names.end(), cell.getName()) ==
     889         428 :         linked_cell_names.end())
     890          72 :       mooseWarning("Cell with name ", cell.getName(), " is not linked to root universe.");
     891          86 : }
     892             : 
     893             : void
     894         790 : CSGBase::getLinkedUniverses(const CSGUniverse & univ,
     895             :                             std::vector<std::string> & linked_universe_names,
     896             :                             std::vector<std::string> & linked_cell_names) const
     897             : {
     898         790 :   linked_universe_names.push_back(univ.getName());
     899         790 :   const auto & univ_cells = univ.getAllCells();
     900        1698 :   for (const CSGCell & cell : univ_cells)
     901             :   {
     902         908 :     linked_cell_names.push_back(cell.getName());
     903         908 :     if (cell.getFillType() == "UNIVERSE")
     904          76 :       getLinkedUniverses(cell.getFillUniverse(), linked_universe_names, linked_cell_names);
     905         832 :     else if (cell.getFillType() == "LATTICE")
     906             :     {
     907         118 :       const auto & lattice = cell.getFillLattice();
     908         380 :       for (const auto & univ_list : lattice.getUniverses())
     909         876 :         for (const auto & univ_ref : univ_list)
     910             :         {
     911         614 :           const CSGUniverse & lattice_univ = univ_ref.get();
     912         614 :           getLinkedUniverses(lattice_univ, linked_universe_names, linked_cell_names);
     913         118 :         }
     914             : 
     915         118 :       if (lattice.getOuterType() == "UNIVERSE")
     916             :       {
     917          22 :         const CSGUniverse & outer_univ = lattice.getOuterUniverse();
     918          22 :         getLinkedUniverses(outer_univ, linked_universe_names, linked_cell_names);
     919             :       }
     920             :     }
     921             :   }
     922         790 : }
     923             : 
     924             : nlohmann::json
     925          64 : CSGBase::generateOutput() const
     926             : {
     927             :   // Check that orphaned universes do not exist in universe list of CSGBase object
     928          64 :   checkUniverseLinking();
     929             : 
     930          64 :   nlohmann::json csg_json;
     931             : 
     932          64 :   csg_json["surfaces"] = {};
     933          64 :   csg_json["cells"] = {};
     934          64 :   csg_json["universes"] = {};
     935             : 
     936             :   // get all surfaces information
     937          64 :   auto all_surfs = getAllSurfaces();
     938         560 :   for (const CSGSurface & s : all_surfs)
     939             :   {
     940         496 :     const auto & surf_name = s.getName();
     941         496 :     const auto & coeffs = s.getCoeffs();
     942        3472 :     csg_json["surfaces"][surf_name] = {{"type", s.getSurfaceType()}, {"coefficients", {}}};
     943        2480 :     for (const auto & c : coeffs)
     944        1984 :       csg_json["surfaces"][surf_name]["coefficients"][c.first] = c.second;
     945             :     // include any information about transformations if present
     946         496 :     if (s.getTransformations().size() > 0)
     947           0 :       csg_json["surfaces"][surf_name]["transformations"] = s.getTransformationsAsStrings();
     948         496 :   }
     949             : 
     950             :   // Print out cell information
     951          64 :   auto all_cells = getAllCells();
     952         264 :   for (const CSGCell & c : all_cells)
     953             :   {
     954         200 :     const auto & cell_name = c.getName();
     955         200 :     const auto & cell_region_infix = c.getRegion().toInfixJSON();
     956         200 :     const auto & cell_region_postfix = c.getRegion().toPostfixStringList();
     957         200 :     const auto & cell_filltype = c.getFillType();
     958         200 :     const auto & fill_name = c.getFillName();
     959         200 :     csg_json["cells"][cell_name]["filltype"] = cell_filltype;
     960         200 :     csg_json["cells"][cell_name]["region_infix"] = cell_region_infix;
     961         200 :     csg_json["cells"][cell_name]["region_postfix"] = cell_region_postfix;
     962         200 :     csg_json["cells"][cell_name]["fill"] = fill_name;
     963             :     // include any information about transformations if present
     964         200 :     if (c.getTransformations().size())
     965          16 :       csg_json["cells"][cell_name]["transformations"] = c.getTransformationsAsStrings();
     966         200 :   }
     967             : 
     968             :   // Print out universe information
     969          64 :   auto all_univs = getAllUniverses();
     970         224 :   for (const CSGUniverse & u : all_univs)
     971             :   {
     972         160 :     const auto & univ_name = u.getName();
     973         160 :     const auto & univ_cells = u.getAllCells();
     974         160 :     csg_json["universes"][univ_name]["cells"] = {};
     975         360 :     for (const CSGCell & c : univ_cells)
     976         200 :       csg_json["universes"][univ_name]["cells"].push_back(c.getName());
     977         160 :     if (u.isRoot())
     978          64 :       csg_json["universes"][univ_name]["root"] = u.isRoot();
     979             :     // include any information about transformations if present
     980         160 :     if (u.getTransformations().size())
     981           0 :       csg_json["universes"][univ_name]["transformations"] = u.getTransformationsAsStrings();
     982             :   }
     983             : 
     984             :   // print out lattice information if lattices exist
     985          64 :   auto all_lats = getAllLattices();
     986          64 :   if (all_lats.size())
     987             :   {
     988          32 :     csg_json["lattices"] = {};
     989          80 :     for (const CSGLattice & lat : all_lats)
     990             :     {
     991          48 :       const auto & lat_name = lat.getName();
     992          48 :       csg_json["lattices"][lat_name] = {};
     993          48 :       csg_json["lattices"][lat_name]["type"] = lat.getType();
     994          48 :       const auto & outer_type = lat.getOuterType();
     995          48 :       csg_json["lattices"][lat_name]["outertype"] = outer_type;
     996          48 :       if (outer_type == "UNIVERSE")
     997          16 :         csg_json["lattices"][lat_name]["outer"] = lat.getOuterUniverse().getName();
     998          32 :       else if (outer_type == "CSG_MATERIAL")
     999           0 :         csg_json["lattices"][lat_name]["outer"] = lat.getOuterMaterial();
    1000             :       // write out any additional attributes
    1001          48 :       csg_json["lattices"][lat_name]["attributes"] = {};
    1002          48 :       const auto & lat_attrs = lat.getAttributes();
    1003         192 :       for (const auto & attr : lat_attrs)
    1004         144 :         csg_json["lattices"][lat_name]["attributes"][attr.first] = attr.second;
    1005             :       // write the map of universe names: list of lists
    1006          48 :       csg_json["lattices"][lat_name]["universes"] = lat.getUniverseNameMap();
    1007             :       // include any information about transformations if present
    1008          48 :       if (lat.getTransformations().size())
    1009           0 :         csg_json["lattices"][lat_name]["transformations"] = lat.getTransformationsAsStrings();
    1010          48 :     }
    1011             :   }
    1012             : 
    1013         128 :   return csg_json;
    1014        3040 : }
    1015             : 
    1016             : bool
    1017           8 : CSGBase::operator==(const CSGBase & other) const
    1018             : {
    1019           8 :   const auto & surf_list = this->getSurfaceList();
    1020           8 :   const auto & other_surf_list = other.getSurfaceList();
    1021           8 :   const auto & cell_list = this->getCellList();
    1022           8 :   const auto & other_cell_list = other.getCellList();
    1023           8 :   const auto & univ_list = this->getUniverseList();
    1024           8 :   const auto & other_univ_list = other.getUniverseList();
    1025           8 :   const auto & lat_list = this->getLatticeList();
    1026           8 :   const auto & other_lat_list = other.getLatticeList();
    1027          14 :   return (surf_list == other_surf_list) && (cell_list == other_cell_list) &&
    1028          14 :          (univ_list == other_univ_list) && (lat_list == other_lat_list);
    1029             : }
    1030             : 
    1031             : bool
    1032           4 : CSGBase::operator!=(const CSGBase & other) const
    1033             : {
    1034           4 :   return !(*this == other);
    1035             : }
    1036             : } // namespace CSG

Generated by: LCOV version 1.14