26 : _surface_list(other_base.getSurfaceList()),
77std::unique_ptr<CSGBase>
80 std::unique_ptr<CSGBase>
clone = std::make_unique<CSGBase>(*
this);
83 std::map<std::string, std::reference_wrapper<const CSGSurface>> identical_surface_refs;
84 auto & surf_list_map =
clone->getSurfaceList().getSurfaceListMap();
85 for (
const auto & [surf_name, surf_ptr] : surf_list_map)
86 identical_surface_refs.insert({surf_name,
clone->getSurfaceByName(surf_name)});
89 for (
auto & [cell_name, cell_ptr] : clone->getCellList().getCellListMap())
90 cell_ptr->updateCellRegionSurfaces(identical_surface_refs);
96CSGBase::addSurface(std::unique_ptr<CSGSurface> surf)
98 if (surfaceToEngUnit(*surf))
101 "' is a CSGSurfaceEngUnit and must be added via addEngUnit(), not addSurface().");
102 return _surface_list.addSurface(std::move(surf));
106CSGBase::prepareSurfaceDeletion(
const CSGSurface & surface)
const
108 for (
const auto & cell_ref : _cell_list.getAllCells())
110 const auto & cell = cell_ref.get();
111 for (
const auto & region_surf : cell.getRegion().getSurfaces())
112 if (region_surf.get() == surface)
113 mooseError(
"Cannot delete surface with name ",
115 " as it is used in region definition of cell with name ",
123 if (!checkSurfaceInBase(surface))
126 " cannot be deleted as it is different from the surface of the same name in the "
127 "CSGBase instance.");
129 prepareSurfaceDeletion(surface);
130 if (
const auto * eng_unit = surfaceToEngUnit(surface))
131 _eng_unit_list.removeEngUnit(*eng_unit);
132 _surface_list.getSurfaceListMap().erase(surface.
getName());
139 const auto name = cell.
getName();
140 if (_cell_list.hasCell(name))
141 return _cell_list.getCell(name);
144 if (cellToEngUnit(cell))
147 "' is a CSGCellEngUnit and must be added via addEngUnit(), not addCellToList().");
152 if (fill_type ==
"VOID")
153 return _cell_list.addVoidCell(name, region);
154 else if (fill_type ==
"CSG_MATERIAL")
157 return _cell_list.addMaterialCell(name, mat_name, region);
159 else if (fill_type ==
"LATTICE")
163 return _cell_list.addLatticeCell(name, lattice, region);
167 else if (fill_type ==
"UNIVERSE")
170 return _cell_list.addUniverseCell(name, univ, region);
173 mooseError(
"Cell " + name +
" has unrecognized fill type " + fill_type);
180 const auto name = univ.
getName();
181 if (_universe_list.hasUniverse(name))
182 return _universe_list.getUniverse(name);
185 if (universeToEngUnit(univ))
188 "' is a CSGUniverseEngUnit and must be added via addEngUnit(), not "
189 "addUniverseToList().");
195 std::vector<std::reference_wrapper<const CSGCell>> current_univ_cells;
196 for (
const auto & univ_cell : univ_cells)
197 current_univ_cells.push_back(addCellToList(univ_cell));
198 return createUniverse(name, current_univ_cells);
205 const auto name = lattice.
getName();
206 if (_lattice_list.hasLattice(name))
207 return _lattice_list.getLattice(name);
210 auto cloned_lattice = lattice.
clone();
215 std::vector<std::vector<std::reference_wrapper<const CSGUniverse>>> current_univ_map;
218 std::vector<std::reference_wrapper<const CSGUniverse>> current_univ_list;
219 for (
const auto & univ_ref : univ_list)
220 current_univ_list.push_back(addUniverseToList(univ_ref.get()));
221 current_univ_map.push_back(current_univ_list);
225 if (current_univ_map.size() > 0)
226 cloned_lattice->setUniverses(current_univ_map);
231 const auto & outer_univ_ref = addUniverseToList(lattice.
getOuterUniverse());
232 cloned_lattice->updateOuter(outer_univ_ref);
236 return addLattice(std::move(cloned_lattice));
242 if (!checkLatticeInBase(lattice))
245 " cannot be deleted as it is different from the lattice of the same name in the "
246 "CSGBase instance.");
249 for (
const auto & cell_ref : _cell_list.getAllCells())
251 const auto & cell = cell_ref.get();
252 if ((cell.getFillType() ==
"LATTICE") && (cell.getFillLattice() == lattice))
253 mooseError(
"Cannot delete lattice with name ",
255 " as it is used as the fill of cell with name ",
259 _lattice_list.getLatticeListMap().erase(lattice.
getName());
263CSGBase::createCell(
const std::string & name,
264 const std::string & mat_name,
268 checkRegionSurfaces(region);
269 auto & cell = _cell_list.addMaterialCell(name, mat_name, region);
271 addCellToUniverse(*add_to_univ, cell);
273 addCellToUniverse(getRootUniverse(), cell);
278CSGBase::createCell(
const std::string & name,
282 checkRegionSurfaces(region);
283 auto & cell = _cell_list.addVoidCell(name, region);
285 addCellToUniverse(*add_to_univ, cell);
287 addCellToUniverse(getRootUniverse(), cell);
292CSGBase::createCell(
const std::string & name,
297 checkRegionSurfaces(region);
298 if (add_to_univ && (&fill_univ == add_to_univ))
300 " cannot be filled with the same universe to which it is being added.");
302 auto & cell = _cell_list.addUniverseCell(name, fill_univ, region);
304 addCellToUniverse(*add_to_univ, cell);
306 addCellToUniverse(getRootUniverse(), cell);
311CSGBase::createCell(
const std::string & name,
316 checkRegionSurfaces(region);
321 for (
const auto & univ_ref : univ_list)
323 const CSGUniverse & univ_in_lattice = univ_ref.get();
324 if (&univ_in_lattice == add_to_univ)
326 " cannot be filled with a lattice containing the same universe to which it is "
330 auto & cell = _cell_list.addLatticeCell(name, fill_lattice, region);
332 addCellToUniverse(*add_to_univ, cell);
334 addCellToUniverse(getRootUniverse(), cell);
339CSGBase::prepareCellDeletion(
const CSGCell & cell)
341 for (
const auto & univ_ref : _universe_list.getAllUniverses())
343 const auto & univ = univ_ref.get();
344 for (
const auto & univ_cell : univ.getAllCells())
345 if (cell == univ_cell.get())
349 if (univ != getRootUniverse())
352 " from universe with name ",
354 " before cell deletion.");
355 _universe_list.getUniverse(univ.getName()).removeCell(cell.
getName());
363 if (!checkCellInBase(cell))
366 " cannot be deleted as it is different from the cell of the same name in the "
367 "CSGBase instance.");
369 prepareCellDeletion(cell);
370 if (
const auto * eng_unit = cellToEngUnit(cell))
371 _eng_unit_list.removeEngUnit(*eng_unit);
372 _cell_list.getCellListMap().erase(cell.
getName());
379 if (cellToEngUnit(cell))
381 "' because it is a CSGCellEngUnit.");
383 checkRegionSurfaces(region);
384 if (!checkCellInBase(cell))
386 " that is being updated is different " +
387 "from the cell of the same name in the CSGBase instance.");
388 auto & list_cell = _cell_list.getCell(cell.
getName());
389 list_cell.updateRegion(region);
396 if (cellToEngUnit(cell))
398 "' because it is a CSGCellEngUnit.");
400 if (!checkCellInBase(cell))
402 " that is being updated is different " +
403 "from the cell of the same name in the CSGBase instance.");
404 auto & list_cell = _cell_list.getCell(cell.
getName());
405 list_cell.resetCellFill();
409CSGBase::updateCellFill(
const CSGCell & cell,
const std::string & mat_name)
412 if (cellToEngUnit(cell))
414 "' because it is a CSGCellEngUnit.");
416 if (!checkCellInBase(cell))
418 " that is being updated is different " +
419 "from the cell of the same name in the CSGBase instance.");
420 auto & list_cell = _cell_list.getCell(cell.
getName());
421 list_cell.updateCellFill(mat_name);
428 if (cellToEngUnit(cell))
430 "' because it is a CSGCellEngUnit.");
432 if (!checkUniverseInBase(*univ))
435 " is being used as a cell fill that is different from the universe of the same name "
436 "in the CSGBase instance.");
437 if (!checkCellInBase(cell))
439 " that is being updated is different " +
440 "from the cell of the same name in the CSGBase instance.");
441 auto & list_cell = _cell_list.getCell(cell.
getName());
442 list_cell.updateCellFill(univ);
449 if (cellToEngUnit(cell))
451 "' because it is a CSGCellEngUnit.");
453 if (!checkLatticeInBase(*lattice))
456 " is being used as a cell fill that is different from the lattice of the same name "
457 "in the CSGBase instance.");
458 if (!checkCellInBase(cell))
460 " that is being updated is different " +
461 "from the cell of the same name in the CSGBase instance.");
462 auto & list_cell = _cell_list.getCell(cell.
getName());
463 list_cell.updateCellFill(lattice);
467CSGBase::createUniverse(
const std::string & name,
468 std::vector<std::reference_wrapper<const CSGCell>> & cells)
470 auto & univ = _universe_list.addUniverse(name);
471 addCellsToUniverse(univ, cells);
478 if (univ == getRootUniverse())
479 mooseError(
"Cannot delete root universe from CSGBase instance");
482 for (
const auto & lat : _lattice_list.getAllLattices())
484 for (
const auto & lat_univ : lat.get().getUniqueUniverses())
485 if (univ == lat_univ.get())
486 mooseError(
"Cannot delete universe with name ",
488 " as it is used in lattice with name ",
489 lat.get().getName());
490 if ((lat.get().getOuterType() ==
"UNIVERSE") && (lat.get().getOuterUniverse() == univ))
491 mooseError(
"Cannot delete universe with name ",
493 " as it is used as the outer universe of lattice with name ",
494 lat.get().getName());
498 for (
const auto & cell_ref : _cell_list.getAllCells())
500 const auto & cell = cell_ref.get();
501 if ((cell.getFillType() ==
"UNIVERSE") && (cell.getFillUniverse() == univ))
502 mooseError(
"Cannot delete universe with name ",
504 " as it is used as the fill of cell with name ",
512 if (!checkUniverseInBase(univ))
515 " cannot be deleted as it is different from the universe of the same name in the "
516 "CSGBase instance.");
518 prepareUniverseDeletion(univ);
519 if (
const auto * eng_unit = universeToEngUnit(univ))
520 _eng_unit_list.removeEngUnit(*eng_unit);
521 _universe_list.getUniverseListMap().erase(univ.
getName());
528 if (universeToEngUnit(universe))
530 "' cannot add cells because it is a CSGUniverseEngUnit.");
533 if (!checkCellInBase(cell))
536 " that is different from the cell of the same name in the CSGBase instance.");
538 if (!checkUniverseInBase(universe))
540 " that is different " +
541 "from the universe of the same name in the CSGBase instance.");
542 auto & univ = _universe_list.getUniverse(universe.
getName());
548 std::vector<std::reference_wrapper<const CSGCell>> & cells)
550 for (
auto & c : cells)
551 addCellToUniverse(universe, c);
558 if (!checkCellInBase(cell))
559 mooseError(
"A cell named " + cell.
getName() +
" is being removed from universe " +
561 " that is different from the cell of the same name in the CSGBase instance.");
563 if (!checkUniverseInBase(universe))
564 mooseError(
"Cells are being removed from a universe named " + universe.
getName() +
565 " that is different " +
566 "from the universe of the same name in the CSGBase instance.");
567 auto & univ = _universe_list.getUniverse(universe.
getName());
570 univ.removeCell(cell.
getName());
575 std::vector<std::reference_wrapper<const CSGCell>> & cells)
577 for (
auto & c : cells)
578 removeCellFromUniverse(universe, c);
582CSGBase::setLatticeOuter(
const CSGLattice & lattice,
const std::string & outer_name)
585 if (!checkLatticeInBase(lattice))
586 mooseError(
"Cannot set outer for lattice " + name +
587 ". Lattice is different from the lattice of the same name in the "
588 "CSGBase instance.");
589 _lattice_list.getLattice(name).updateOuter(outer_name);
596 if (!checkLatticeInBase(lattice))
597 mooseError(
"Cannot set outer universe for lattice " + name +
598 ". Lattice is different from the lattice of the same name in the "
599 "CSGBase instance.");
600 if (!checkUniverseInBase(outer_univ))
601 mooseError(
"Cannot set outer universe for lattice " + name +
". Outer universe " +
602 outer_univ.
getName() +
" is not in the CSGBase instance.");
603 _lattice_list.getLattice(name).updateOuter(outer_univ);
610 if (!checkLatticeInBase(lattice))
611 mooseError(
"Cannot reset outer for lattice " + name +
612 ". Lattice is different from the lattice of the same name in the "
613 "CSGBase instance.");
614 _lattice_list.getLattice(name).resetOuter();
618CSGBase::setUniverseAtLatticeIndex(
const CSGLattice & lattice,
620 std::pair<int, int> index)
623 if (!checkLatticeInBase(lattice))
624 mooseError(
"Cannot set universe at index for lattice " + name +
625 ". Lattice is different from the lattice of the same name in the "
626 "CSGBase instance.");
627 if (!checkUniverseInBase(universe))
629 ". Universe is not in the CSGBase instance.");
630 _lattice_list.getLattice(name).setUniverseAtIndex(universe, index);
634CSGBase::setLatticeUniverses(
636 std::vector<std::vector<std::reference_wrapper<const CSGUniverse>>> & universes)
639 if (!checkLatticeInBase(lattice))
640 mooseError(
"Cannot set universes for lattice " + name +
641 ". Lattice is different from the lattice of the same name in the "
642 "CSGBase instance.");
644 for (
auto univ_list : universes)
646 if (!checkUniverseInBase(univ))
647 mooseError(
"Cannot set universes for lattice " + name +
". Universe " + univ.getName() +
648 " is not in the CSGBase instance.");
649 _lattice_list.getLattice(name).setUniverses(universes);
655 const std::tuple<Real, Real, Real> &
values)
659 [&](
const auto & obj)
661 using T = std::decay_t<
decltype(obj.get())>;
665 if constexpr (std::is_same_v<T, CSGCell>)
667 const CSGCell & cell = obj.get();
668 if (!checkCellInBase(cell))
669 mooseError(
"Cannot apply transformation to cell ",
671 " that is not in this CSGBase instance.");
675 mooseAssert(mutable_cell == cell,
"Mutable cell does not match const cell passed in.");
678 else if constexpr (std::is_same_v<T, CSGSurface>)
681 if (!checkSurfaceInBase(surface))
682 mooseError(
"Cannot apply transformation to surface ",
684 " that is not in this CSGBase instance.");
688 mooseAssert(mutable_surface == surface,
689 "Mutable surface does not match const surface passed in.");
692 else if constexpr (std::is_same_v<T, CSGUniverse>)
695 if (!checkUniverseInBase(universe))
696 mooseError(
"Cannot apply transformation to universe ",
698 " that is not in this CSGBase instance.");
702 mooseAssert(mutable_universe == universe,
703 "Mutable universe does not match const universe passed in.");
706 else if constexpr (std::is_same_v<T, CSGLattice>)
709 if (!checkLatticeInBase(lattice))
710 mooseError(
"Cannot apply transformation to lattice ",
712 " that is not in this CSGBase instance.");
716 mooseAssert(mutable_lattice == lattice,
717 "Mutable lattice does not match const lattice passed in.");
720 else if constexpr (std::is_same_v<T, CSGRegion>)
727 if (!checkSurfaceInBase(surface))
728 mooseError(
"Cannot apply transformation to region with surface ",
730 " that is not in this CSGBase instance.");
731 addTransformation(surface, type,
values);
734 else if constexpr (std::is_same_v<T, CSGEngUnit>)
737 if (!checkEngUnitInBase(eng_unit))
738 mooseError(
"Cannot apply transformation to engineering unit ",
740 " that is not in this CSGBase instance.");
744 s->addTransformation(type,
values);
746 c->addTransformation(type,
values);
748 u->addTransformation(type,
values);
752 "' has an unrecognized type for transformation.");
755 mooseError(
"Transformation not implemented for this object type: ",
typeid(T).name());
772 case RotationAxisType::X:
775 case RotationAxisType::Y:
780 case RotationAxisType::Z:
784 mooseError(
"Invalid axis type provided for axis rotation.");
787 addTransformation(csg_object, TransformationType::ROTATION, std::make_tuple(phi, theta, psi));
791CSGBase::joinOtherBase(std::unique_ptr<CSGBase> base,
const bool ignore_identical_components)
795 if (ignore_identical_components)
796 updateIncomingCSGReferences(*base);
797 joinSurfaceList(base->getSurfaceList(), ignore_identical_components);
798 joinCellList(base->getCellList(), ignore_identical_components);
799 joinLatticeList(base->getLatticeList(), ignore_identical_components);
800 joinUniverseList(base->getUniverseList(), ignore_identical_components);
801 rebuildEngUnitList();
806CSGBase::joinOtherBase(std::unique_ptr<CSGBase> base,
807 const bool ignore_identical_components,
808 const std::string & new_root_name_join)
812 if (ignore_identical_components)
813 updateIncomingCSGReferences(*base);
814 joinSurfaceList(base->getSurfaceList(), ignore_identical_components);
815 joinCellList(base->getCellList(), ignore_identical_components);
816 joinLatticeList(base->getLatticeList(), ignore_identical_components);
817 joinUniverseList(base->getUniverseList(), ignore_identical_components, new_root_name_join);
818 rebuildEngUnitList();
823CSGBase::joinOtherBase(std::unique_ptr<CSGBase> base,
824 const bool ignore_identical_components,
825 const std::string & new_root_name_base,
826 const std::string & new_root_name_join)
830 if (ignore_identical_components)
831 updateIncomingCSGReferences(*base);
832 joinSurfaceList(base->getSurfaceList(), ignore_identical_components);
833 joinCellList(base->getCellList(), ignore_identical_components);
834 joinLatticeList(base->getLatticeList(), ignore_identical_components);
836 base->getUniverseList(), ignore_identical_components, new_root_name_base, new_root_name_join);
837 rebuildEngUnitList();
842CSGBase::updateIncomingCSGReferences(
CSGBase & incoming_base)
846 std::map<std::string, std::reference_wrapper<const CSGSurface>> identical_surface_refs;
848 for (
const auto & [surf_name, surf_ptr] : surf_list_map)
849 if (hasSurface(surf_name))
850 identical_surface_refs.insert({surf_name, getSurfaceByName(surf_name)});
854 std::map<std::string, std::reference_wrapper<const CSGCell>> identical_cell_refs;
855 auto & cell_list_map = incoming_base.getCellList().getCellListMap();
856 for (
const auto & [cell_name, cell_ptr] : cell_list_map)
857 if (hasCell(cell_name))
858 identical_cell_refs.insert({cell_name, getCellByName(cell_name)});
862 std::map<std::string, std::reference_wrapper<const CSGUniverse>> identical_universe_refs;
863 auto & universe_list_map = incoming_base.getUniverseList().getUniverseListMap();
864 for (
const auto & [univ_name, univ_ptr] : universe_list_map)
865 if (hasUniverse(univ_name))
866 identical_universe_refs.insert({univ_name, getUniverseByName(univ_name)});
870 std::map<std::string, std::reference_wrapper<const CSGLattice>> identical_lattice_refs;
871 auto & lattice_list_map = incoming_base.getLatticeList().getLatticeListMap();
872 for (
const auto & [lat_name, lat_ptr] : lattice_list_map)
873 if (hasLattice(lat_name))
874 identical_lattice_refs.insert({lat_name, getLatticeByName(lat_name)});
878 if (!identical_surface_refs.empty())
879 replaceSurfaceRefsByName(identical_surface_refs, incoming_base);
881 if (!identical_cell_refs.empty())
882 replaceCellRefsByName(identical_cell_refs, incoming_base);
884 if (!identical_universe_refs.empty())
885 replaceUniverseRefsByName(identical_universe_refs, incoming_base);
887 if (!identical_lattice_refs.empty())
888 replaceLatticeRefsByName(identical_lattice_refs, incoming_base);
892CSGBase::replaceSurfaceRefsByName(
893 std::map<std::string, std::reference_wrapper<const CSGSurface>> & identical_surface_refs,
898 cell_ptr->updateCellRegionSurfaces(identical_surface_refs);
902CSGBase::replaceCellRefsByName(
903 std::map<std::string, std::reference_wrapper<const CSGCell>> & identical_cell_refs,
908 for (
auto & [cell_name, cell_ref] : identical_cell_refs)
909 if (univ_ptr->hasCell(cell_name))
911 univ_ptr->removeCell(cell_name);
912 univ_ptr->addCell(cell_ref);
917CSGBase::replaceUniverseRefsByName(
918 std::map<std::string, std::reference_wrapper<const CSGUniverse>> & identical_universe_refs,
924 const auto fill_type = cell_ptr->getFillType();
925 const auto fill_name = cell_ptr->getFillName();
926 if ((fill_type ==
"UNIVERSE") &&
927 (identical_universe_refs.find(fill_name) != identical_universe_refs.end()))
929 const CSGUniverse * univ_ptr = &identical_universe_refs.at(fill_name).get();
930 cell_ptr->updateCellFill(univ_ptr);
936 for (
auto & [univ_name, univ_ref] : identical_universe_refs)
939 if (lat_ptr->hasUniverse(univ_name))
942 const auto univ_indices = lat_ptr->getUniverseIndices(univ_name);
943 for (
const auto & index : univ_indices)
944 lat_ptr->setUniverseAtIndex(univ_ref, index);
947 if ((lat_ptr->getOuterType() ==
"UNIVERSE") &&
948 (lat_ptr->getOuterUniverse().getName() == univ_name))
949 lat_ptr->updateOuter(univ_ref);
954CSGBase::replaceLatticeRefsByName(
955 std::map<std::string, std::reference_wrapper<const CSGLattice>> & identical_lattice_refs,
961 const auto fill_type = cell_ptr->getFillType();
962 const auto fill_name = cell_ptr->getFillName();
963 if ((fill_type ==
"LATTICE") &&
964 (identical_lattice_refs.find(fill_name) != identical_lattice_refs.end()))
966 const CSGLattice * lat_ptr = &identical_lattice_refs.at(fill_name).get();
967 cell_ptr->updateCellFill(lat_ptr);
973CSGBase::joinSurfaceList(
CSGSurfaceList & surf_list,
const bool ignore_identical_surfaces)
976 for (
auto & s : surf_list_map)
977 _surface_list.addSurface(std::move(s.second), ignore_identical_surfaces);
981CSGBase::joinCellList(
CSGCellList & cell_list,
const bool ignore_identical_cells)
984 for (
auto & c : cell_list_map)
985 _cell_list.addCell(std::move(c.second), ignore_identical_cells);
989CSGBase::joinLatticeList(
CSGLatticeList & lattice_list,
const bool ignore_identical_lattices)
992 for (
auto & lat : lat_list_map)
993 _lattice_list.addLattice(std::move(lat.second), ignore_identical_lattices);
997CSGBase::rebuildEngUnitList()
1003 for (
auto & [name, surf] : _surface_list.getSurfaceListMap())
1005 _eng_unit_list.addEngUnit(*eu);
1006 for (
auto & [name, cell] : _cell_list.getCellListMap())
1008 _eng_unit_list.addEngUnit(*eu);
1009 for (
auto & [name, univ] : _universe_list.getUniverseListMap())
1011 _eng_unit_list.addEngUnit(*eu);
1015CSGBase::joinUniverseList(
CSGUniverseList & univ_list,
const bool ignore_identical_universes)
1019 auto & root = getRootUniverse();
1020 for (
auto & u : univ_list_map)
1022 if (u.second->isRoot())
1025 auto all_cells = u.second->getAllCells();
1026 for (
auto & cell : all_cells)
1027 addCellToUniverse(root, cell);
1030 _universe_list.addUniverse(std::move(u.second), ignore_identical_universes);
1036 const bool ignore_identical_universes,
1037 const std::string & new_root_name_incoming)
1043 for (
auto & u : all_univs)
1045 if (u.second->isRoot())
1048 auto all_cells = u.second->getAllCells();
1049 createUniverse(new_root_name_incoming, all_cells);
1052 _universe_list.addUniverse(std::move(u.second), ignore_identical_universes);
1058 const bool ignore_identical_universes,
1059 const std::string & new_root_name_base,
1060 const std::string & new_root_name_incoming)
1065 auto & root = getRootUniverse();
1066 auto root_cells = root.getAllCells();
1067 createUniverse(new_root_name_base, root_cells);
1068 removeCellsFromUniverse(root, root_cells);
1072 for (
auto & u : all_univs)
1074 if (u.second->isRoot())
1077 auto all_cells = u.second->getAllCells();
1078 createUniverse(new_root_name_incoming, all_cells);
1081 _universe_list.addUniverse(std::move(u.second), ignore_identical_universes);
1091 if (!checkSurfaceInBase(s))
1092 mooseError(
"Region is being set with a surface named " + s.getName() +
1093 " that is different from the surface of the same name in the CSGBase instance.");
1100 auto name = surface.
getName();
1102 auto & list_surf = _surface_list.getSurface(name);
1104 return &surface == &list_surf;
1108CSGBase::checkCellInBase(
const CSGCell & cell)
const
1112 auto & list_cell = _cell_list.getCell(name);
1114 return &cell == &list_cell;
1120 auto name = universe.
getName();
1122 auto & list_univ = _universe_list.getUniverse(name);
1124 return &universe == &list_univ;
1130 auto name = lattice.
getName();
1132 auto & list_lattice = _lattice_list.getLattice(name);
1134 return &lattice == &list_lattice;
1140 const auto & name = unit.
getName();
1142 const auto & list_unit = _eng_unit_list.getEngUnit(name);
1144 return &unit == &list_unit;
1148CSGBase::renameEngUnit(
const CSGEngUnit & unit,
const std::string & name)
1154 renameSurface(*surf, name);
1155 else if (
const auto * cell =
dynamic_cast<const CSGCellEngUnit *
>(&unit))
1156 renameCell(*cell, name);
1158 renameUniverse(*univ, name);
1161 "Engineering unit '", unit.
getName(),
"' has an unrecognized type and cannot be renamed.");
1165CSGBase::renameSurface(
const CSGSurface & surface,
const std::string & name)
1169 if (surfaceToEngUnit(surface))
1170 if (_eng_unit_list.hasEngUnit(name))
1171 mooseError(
"Cannot rename surface " + surface.
getName() +
" to " + name +
". " +
1172 surface.
getName() +
" is an engineering unit and a unit with name " + name +
1173 " already exists.");
1175 _surface_list.renameSurface(surface, name);
1179CSGBase::renameCell(
const CSGCell & cell,
const std::string & name)
1183 if (cellToEngUnit(cell))
1184 if (_eng_unit_list.hasEngUnit(name))
1186 " is an engineering unit and a unit with name " + name +
" already exists.");
1188 _cell_list.renameCell(cell, name);
1192CSGBase::renameUniverse(
const CSGUniverse & universe,
const std::string & name)
1196 if (universeToEngUnit(universe))
1197 if (_eng_unit_list.hasEngUnit(name))
1198 mooseError(
"Cannot rename universe " + universe.
getName() +
" to " + name +
". " +
1199 universe.
getName() +
" is an engineering unit and a unit with name " + name +
1200 " already exists.");
1202 _universe_list.renameUniverse(universe, name);
1206CSGBase::checkUniverseLinking()
const
1208 std::set<std::string> linked_universe_names;
1209 std::set<std::string> linked_cell_names;
1210 std::set<std::string> linked_surf_names;
1213 getLinkedCSGObjects(
1214 getRootUniverse(), linked_universe_names, linked_cell_names, linked_surf_names);
1218 for (
const CSGUniverse & univ : getAllUniverses())
1219 if (linked_universe_names.find(univ.getName()) == linked_universe_names.end())
1220 mooseWarning(
"Universe with name ", univ.getName(),
" is not linked to root universe.");
1224 for (
const CSGCell & cell : getAllCells())
1225 if (linked_cell_names.find(cell.getName()) == linked_cell_names.end())
1226 mooseWarning(
"Cell with name ", cell.getName(),
" is not linked to root universe.");
1230 for (
const CSGSurface & surf : getAllSurfaces())
1231 if (linked_surf_names.find(surf.getName()) == linked_surf_names.end())
1232 mooseWarning(
"Surface with name ", surf.getName(),
" is not linked to root universe.");
1236CSGBase::areCSGObjectsLinked()
const
1238 std::set<std::string> linked_univs, linked_cells, linked_surfs;
1239 getLinkedCSGObjects(getRootUniverse(), linked_univs, linked_cells, linked_surfs);
1241 for (
const CSGUniverse & univ : getAllUniverses())
1242 if (linked_univs.find(univ.getName()) == linked_univs.end())
1245 for (
const CSGCell & cell : getAllCells())
1246 if (linked_cells.find(cell.getName()) == linked_cells.end())
1249 for (
const CSGSurface & surf : getAllSurfaces())
1250 if (linked_surfs.find(surf.getName()) == linked_surfs.end())
1258 std::set<std::string> & linked_universe_names,
1259 std::set<std::string> & linked_cell_names,
1260 std::set<std::string> & linked_surface_names)
const
1262 linked_universe_names.insert(univ.
getName());
1264 for (
const CSGCell & cell : univ_cells)
1266 linked_cell_names.insert(cell.getName());
1267 for (
const CSGSurface & cell_surf : cell.getRegion().getSurfaces())
1268 linked_surface_names.insert(cell_surf.getName());
1270 if (cell.getFillType() ==
"UNIVERSE")
1271 getLinkedCSGObjects(
1272 cell.getFillUniverse(), linked_universe_names, linked_cell_names, linked_surface_names);
1273 else if (cell.getFillType() ==
"LATTICE")
1275 const auto & lattice = cell.getFillLattice();
1276 for (
const auto & univ_list : lattice.getUniverses())
1277 for (
const auto & univ_ref : univ_list)
1279 const CSGUniverse & lattice_univ = univ_ref.get();
1280 getLinkedCSGObjects(
1281 lattice_univ, linked_universe_names, linked_cell_names, linked_surface_names);
1284 if (lattice.getOuterType() ==
"UNIVERSE")
1286 const CSGUniverse & outer_univ = lattice.getOuterUniverse();
1287 getLinkedCSGObjects(
1288 outer_univ, linked_universe_names, linked_cell_names, linked_surface_names);
1297 if (!checkEngUnitInBase(unit))
1300 " cannot be deleted as it is different from the engineering unit of the same name "
1301 "in the CSGBase instance.");
1305 deleteSurface(cast_ref<const CSGSurface &>(*surf_unit));
1306 else if (
const auto * cell_unit =
dynamic_cast<const CSGCellEngUnit *
>(&unit))
1307 deleteCell(cast_ref<const CSGCell &>(*cell_unit));
1309 deleteUniverse(cast_ref<const CSGUniverse &>(*univ_unit));
1312 "Engineering unit '", unit.
getName(),
"' has an unrecognized type and cannot be deleted.");
1316CSGBase::expandAllEngUnits()
1318 std::set<std::set<std::string>> all_type_sets;
1319 expandAllEngUnitsCycle(all_type_sets);
1323CSGBase::expandAllEngUnitsCycle(std::set<std::set<std::string>> & all_type_sets)
1333 std::set<std::string> current_types;
1334 for (
const auto & u : getAllEngUnits())
1335 current_types.insert(u.get().getUnitType());
1337 if (all_type_sets.count(
1339 mooseError(
"Circular dependency detected in engineering unit expansion");
1341 all_type_sets.insert(current_types);
1345 std::vector<const CSGSurfaceEngUnit *> surfs;
1346 std::vector<const CSGCellEngUnit *> cells;
1347 std::vector<const CSGUniverseEngUnit *> univs;
1348 for (
const auto & u : getAllSurfaceEngUnits())
1349 surfs.push_back(&u.get());
1350 for (
const auto & u : getAllCellEngUnits())
1351 cells.push_back(&u.get());
1352 for (
const auto & u : getAllUniverseEngUnits())
1353 univs.push_back(&u.get());
1356 for (
const auto * s : surfs)
1358 for (
const auto * c : cells)
1360 for (
const auto * u : univs)
1365 if (!getAllEngUnits().empty())
1366 expandAllEngUnitsCycle(all_type_sets);
1375 auto & mutable_unit = cast_ref<CSGSurfaceEngUnit &>(_surface_list.getSurface(unit.
getName()));
1379 mutable_unit.expandUnit();
1383 auto unit_base = mutable_unit.getBase();
1384 if ((unit_base.getAllCells().size() > 0) || (unit_base.getAllUniverses().size() > 1))
1386 mutable_unit.getName(),
1388 mutable_unit.getUnitType(),
1389 " contains either cells or universes (beyond the root universe) after expansion, "
1390 "but should only contain surfaces.");
1393 joinOtherBase(mutable_unit.releaseBase(),
false);
1396 CSGRegion expanded_region = mutable_unit.getExpandedRegion();
1399 const auto & trans = cast_ref<const CSGSurface &>(mutable_unit).getTransformations();
1401 for (
const auto & surf_ref : expanded_region.
getSurfaces())
1403 CSGSurface & mutable_surf = _surface_list.getSurface(surf_ref.get().getName());
1404 for (
const auto & [trans_type,
values] : trans)
1409 replaceSurfaceRefsWithRegion(cast_ref<const CSGSurface &>(mutable_unit), expanded_region);
1413 deleteEngUnit(unit);
1414 return expanded_region;
1423 auto & mutable_unit = cast_ref<CSGCellEngUnit &>(_cell_list.getCell(unit.
getName()));
1427 mutable_unit.expandUnit();
1432 const CSGCell & expanded_cell = mutable_unit.getExpandedCell();
1435 joinOtherBase(mutable_unit.releaseBase(),
false);
1438 const auto & trans = cast_ref<const CSGCell &>(mutable_unit).getTransformations();
1441 CSGCell & mutable_cell = _cell_list.getCell(expanded_cell.
getName());
1442 for (
const auto & [trans_type,
values] : trans)
1448 if (getRootUniverse().hasCell(expanded_cell.
getName()))
1449 removeCellFromUniverse(getRootUniverse(), expanded_cell);
1452 replaceCellRefs(cast_ref<const CSGCell &>(mutable_unit), expanded_cell);
1455 deleteEngUnit(unit);
1456 return expanded_cell;
1462 auto unit_name = unit.
getName();
1467 auto & mutable_unit = cast_ref<CSGUniverseEngUnit &>(_universe_list.getUniverse(unit_name));
1471 mutable_unit.expandUnit();
1476 auto & pre_join_univ = mutable_unit.getExpandedUniverse();
1477 auto expanded_name = pre_join_univ.getName();
1486 auto unit_base = mutable_unit.releaseBase();
1487 if (expanded_name == getRootUniverse().getName())
1490 auto new_expanded_name = unit_name +
"_expanded_root";
1493 " has an expanded root universe named " + expanded_name +
1494 ", which is identical to the name of the current root universe. The expanded "
1495 "universe will be renamed " +
1496 new_expanded_name +
".");
1499 unit_base->renameRootUniverse(new_expanded_name);
1500 expanded_name = new_expanded_name;
1506 joinOtherBase(std::move(unit_base),
false, expanded_name);
1510 const CSGUniverse & expanded_univ = getUniverseByName(expanded_name);
1513 const auto & trans = cast_ref<const CSGUniverse &>(mutable_unit).getTransformations();
1517 for (
const auto & [trans_type,
values] : trans)
1522 replaceUniverseRefs(cast_ref<const CSGUniverse &>(mutable_unit), expanded_univ);
1525 deleteEngUnit(unit);
1526 return expanded_univ;
1533 for (
const auto & cell_ref : getAllCells())
1535 const CSGCell & cell = cell_ref.get();
1537 updateCellFill(cell, &new_univ);
1541 for (
const auto & lat_ref : getAllLattices())
1545 setLatticeOuter(lat, new_univ);
1548 for (std::size_t row = 0; row < lat_map.size(); ++row)
1549 for (std::size_t col = 0; col < lat_map[row].size(); ++col)
1550 if (lat_map[row][col].get() == old_univ)
1551 setUniverseAtLatticeIndex(lat, new_univ, {
static_cast<int>(row),
static_cast<int>(col)});
1555 if (getRootUniverse() == old_univ)
1556 _universe_list._root_universe = &new_univ;
1562 for (
const auto & univ_ref : getAllUniverses())
1566 if (&cell_ref.get() == &old_cell)
1568 removeCellFromUniverse(univ, old_cell);
1569 addCellToUniverse(univ, new_cell);
1577 for (
const auto & cell_ref : getAllCells())
1579 const CSGCell & cell = cell_ref.get();
1581 if (new_region.
getRegionType() == CSGRegion::RegionType::EMPTY)
1585 updateCellRegion(cell, new_region);
1590CSGBase::generateOutput()
const
1593 checkUniverseLinking();
1595 nlohmann::json csg_json;
1597 csg_json[
"surfaces"] = {};
1598 csg_json[
"cells"] = {};
1599 csg_json[
"universes"] = {};
1602 auto all_surfs = getAllSurfaces();
1605 if (surfaceToEngUnit(s))
1607 const auto & surf_name = s.getName();
1608 const auto & coeffs = s.getCoeffs();
1609 csg_json[
"surfaces"][surf_name] = {{
"type", s.getSurfaceType()}, {
"coefficients", {}}};
1610 for (
const auto & c : coeffs)
1611 csg_json[
"surfaces"][surf_name][
"coefficients"][c.first] = c.second;
1613 if (s.getTransformations().size() > 0)
1614 csg_json[
"surfaces"][surf_name][
"transformations"] = s.getTransformationsAsStrings();
1619 if (csg_json[
"surfaces"].empty())
1620 csg_json.erase(
"surfaces");
1623 auto all_cells = getAllCells();
1624 for (
const CSGCell & c : all_cells)
1626 if (cellToEngUnit(c))
1628 const auto & cell_name = c.getName();
1629 const auto & cell_region_infix = c.getRegion().toInfixJSON();
1630 const auto & cell_region_postfix = c.getRegion().toPostfixStringList();
1631 const auto & cell_filltype = c.getFillType();
1632 const auto & fill_name = c.getFillName();
1633 csg_json[
"cells"][cell_name][
"filltype"] = cell_filltype;
1634 csg_json[
"cells"][cell_name][
"region_infix"] = cell_region_infix;
1635 csg_json[
"cells"][cell_name][
"region_postfix"] = cell_region_postfix;
1636 csg_json[
"cells"][cell_name][
"fill"] = fill_name;
1638 if (c.getTransformations().size())
1639 csg_json[
"cells"][cell_name][
"transformations"] = c.getTransformationsAsStrings();
1644 if (csg_json[
"cells"].empty())
1645 csg_json.erase(
"cells");
1648 auto all_univs = getAllUniverses();
1651 if (universeToEngUnit(u))
1653 const auto & univ_name = u.getName();
1654 const auto & univ_cells = u.getAllCells();
1655 csg_json[
"universes"][univ_name][
"cells"] = {};
1656 for (
const CSGCell & c : univ_cells)
1657 csg_json[
"universes"][univ_name][
"cells"].push_back(c.getName());
1659 csg_json[
"universes"][univ_name][
"root"] = u.isRoot();
1661 if (u.getTransformations().size())
1662 csg_json[
"universes"][univ_name][
"transformations"] = u.getTransformationsAsStrings();
1666 auto all_lats = getAllLattices();
1667 if (all_lats.size())
1669 csg_json[
"lattices"] = {};
1672 const auto & lat_name = lat.getName();
1673 csg_json[
"lattices"][lat_name] = {};
1674 csg_json[
"lattices"][lat_name][
"type"] = lat.getType();
1675 const auto & outer_type = lat.getOuterType();
1676 csg_json[
"lattices"][lat_name][
"outertype"] = outer_type;
1677 if (outer_type ==
"UNIVERSE")
1678 csg_json[
"lattices"][lat_name][
"outer"] = lat.getOuterUniverse().getName();
1679 else if (outer_type ==
"CSG_MATERIAL")
1680 csg_json[
"lattices"][lat_name][
"outer"] = lat.getOuterMaterial();
1682 csg_json[
"lattices"][lat_name][
"attributes"] = {};
1683 const auto & lat_attrs = lat.getAttributes();
1684 for (
const auto & attr : lat_attrs)
1685 csg_json[
"lattices"][lat_name][
"attributes"][attr.first] = attr.second;
1687 csg_json[
"lattices"][lat_name][
"universes"] = lat.getUniverseNameMap();
1689 if (lat.getTransformations().size())
1690 csg_json[
"lattices"][lat_name][
"transformations"] = lat.getTransformationsAsStrings();
1695 auto all_units = getAllEngUnits();
1696 if (all_units.size())
1698 csg_json[
"units"] = {};
1701 const auto & unit_name = unit.getName();
1702 csg_json[
"units"][unit_name] = {};
1704 csg_json[
"units"][unit_name][
"unit_type"] = unit.getUnitType();
1705 csg_json[
"units"][unit_name][
"behavior"] = unit.getBehavior();
1707 csg_json[
"units"][unit_name][
"attributes"] = {};
1708 const auto & unit_attrs = unit.getAttributes();
1709 for (
const auto & attr : unit_attrs)
1710 csg_json[
"units"][unit_name][
"attributes"][attr.first] = attr.second;
1711 if (unit.getTransformations().size())
1712 csg_json[
"units"][unit_name][
"transformations"] = unit.getTransformationsAsStrings();
1722 const auto & surf_list = this->getSurfaceList();
1724 const auto & cell_list = this->getCellList();
1725 const auto & other_cell_list = other.
getCellList();
1726 const auto & univ_list = this->getUniverseList();
1728 const auto & lat_list = this->getLatticeList();
1730 const auto & eng_unit_list = this->getEngUnitList();
1732 return (surf_list == other_surf_list) && (cell_list == other_cell_list) &&
1733 (univ_list == other_univ_list) && (lat_list == other_lat_list) &&
1734 (eng_unit_list == other_eng_unit_list);
1740 return !(*
this == other);
void mooseInfoRepeated(Args &&... args)
Emit an informational message with the given stringified, concatenated args.
void mooseWarning(Args &&... args)
Emit a warning message with the given stringified, concatenated args.
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
std::array< Real, 2 > values
if(!dmm->_nl) SETERRQ(PETSC_COMM_WORLD
CSGBase creates an internal representation of a Constructive Solid Geometry (CSG) model.
const CSGSurfaceList & getSurfaceList() const
Get a const reference to the CSGSurfaceList object.
const CSGCell & addCellToList(const CSGCell &cell)
Add a new cell to the cell list based on a cell reference.
const CSGCellList & getCellList() const
Get a const reference to the CSGCellList object.
CSGCellList _cell_list
List of cells associated with CSG object.
std::unique_ptr< CSGBase > clone() const
Create a deep copy of this CSGBase instance.
const CSGLattice & addLatticeToList(const CSGLattice &lattice)
Add a new lattice to the lattice list based on a lattice reference.
const CSGUniverse & addUniverseToList(const CSGUniverse &univ)
Add a new universe to the universe list based on a universe reference.
std::vector< std::reference_wrapper< const CSGUniverseEngUnit > > getAllUniverseEngUnits() const
Get all universe-like engineering units.
const CSGUniverseList & getUniverseList() const
Get a const reference to the CSGUniverseList object.
void rebuildEngUnitList()
rebuilds the list of raw pointers to engineering units by iterating through the surface,...
const CSGLatticeList & getLatticeList() const
Get a const reference to the CSGLatticeList object.
const CSGEngUnitList & getEngUnitList() const
Get a const reference to the CSGEngUnitList object.
const CSGUniverse & getRootUniverse() const
Get the Root Universe object.
const CSGUniverseEngUnit * universeToEngUnit(const CSGUniverse &univ) const
Returns the CSGUniverseEngUnit pointer if univ is an eng unit, nullptr otherwise.
std::vector< std::reference_wrapper< const CSGCellEngUnit > > getAllCellEngUnits() const
Get all cell-like engineering units in CSGBase.
void addCellToUniverse(const CSGUniverse &universe, const CSGCell &cell)
Add a cell to an existing universe.
const T & addEngUnit(std::unique_ptr< T > unit, const CSGUniverse *add_to_univ=nullptr)
Add an engineering unit (surface-, cell-, or universe-like object) to this CSGBase.
CSGBase()
Default constructor.
const CSGCellEngUnit * cellToEngUnit(const CSGCell &cell) const
Returns the CSGCellEngUnit pointer if cell is an eng unit, nullptr otherwise.
CSGCellEngUnit is an abstract base class for "engineering units" that are cell-like.
const std::string & getName() const override
Satisfy CSGEngUnit::getName() (resolved via CSGCell::getName())
CSGCellList creates a container for CSGCell objects to pass to CSGBase object.
std::unordered_map< std::string, std::unique_ptr< CSGCell > > & getCellListMap()
Get non-const map of all names to cells in cell list.
CSGCell & getCell(const std::string &name) const
Get the CSGCell by name.
CSGCell & addCell(std::unique_ptr< CSGCell > cell, const bool ignore_identical_cell=false)
add a cell to the CellList.
CSGCell creates an internal representation of a Constructive Solid Geometry (CSG) cell,...
const CSGRegion & getRegion() const
Get the cell region.
const std::string & getName() const
Get the cell name.
const CSGLattice & getFillLattice() const
Get the cell fill if fill type is LATTICE.
const std::string getFillType() const
Get the type of fill for the cell.
const CSGUniverse & getFillUniverse() const
Get the cell fill if fill type is UNIVERSE.
const std::string & getFillMaterial() const
Get the cell fill material name if fill fype is CSG_MATERIAL.
CSGEngUnitList is a non-owning index of CSGEngUnit objects stored in the type lists (CSGSurfaceList,...
CSGEngUnit is the abstract base class for all "engineering unit" types in the CSG system.
virtual const std::string & getName() const =0
Get the unique instance name of this engineering unit.
CSGLatticeList creates a container for CSGLattice objects to pass to CSGBase.
std::unordered_map< std::string, std::unique_ptr< CSGLattice > > & getLatticeListMap()
Get map of all names to lattices in lattice list.
CSGLattice is the abstract class for defining lattices.
std::vector< std::vector< std::reference_wrapper< const CSGUniverse > > > getUniverses() const
Get the arrangement of CSGUniverses in the lattice.
virtual std::unique_ptr< CSGLattice > clone() const =0
const std::string & getName() const
Get the name of lattice.
const std::string getOuterType() const
Get the type of outer that fills the space around the lattice elements.
const CSGUniverse & getOuterUniverse() const
Get the outer universe if outer type is UNIVERSE.
CSGRegions creates an internal representation of a CSG region, which can refer to an intersection,...
RegionType getRegionType() const
Get the region type.
void replaceWithSubRegion(const CSGSurface &old_surf, const CSGRegion &sub_region)
Replace all occurrences of old_surf in this region's postfix token stream with the tokens of sub_regi...
std::vector< std::reference_wrapper< const CSGSurface > > getSurfaces() const
Get the list of surfaces associated with the region.
CSGSurfaceEngUnit is an abstract base class for "engineering units" that can be used as surfaces in c...
const std::string & getName() const override
Satisfy CSGEngUnit::getName() – resolved via CSGSurface::getName()
CSGSurfaceList is a container for storing CSGSurface objects in the CSGBase object.
std::unordered_map< std::string, std::unique_ptr< CSGSurface > > & getSurfaceListMap()
Get non-const map of all names to surfaces in surface list.
CSGSurface creates an internal representation of a Constructive Solid Geometry (CSG) surface,...
const std::string & getName() const
Get the name of surface.
CSGUniverseEngUnit is an abstract base class for "engineering units" that are universe-like.
const std::string & getName() const override
Satisfy CSGEngUnit::getName() (resolved via CSGUniverse::getName())
CSGUniverseList creates a container for CSGUniverse objects to pass to CSGBase.
std::unordered_map< std::string, std::unique_ptr< CSGUniverse > > & getUniverseListMap()
Get non-const map of all names to universes in universe list.
CSGUniverse creates an internal representation of a Constructive Solid Geometry (CSG) universe,...
const std::string & getName() const
Get the name of the universe.
const std::vector< std::reference_wrapper< const CSGCell > > & getAllCells() const
Get list of the all cells in the universe.
std::variant< std::reference_wrapper< const CSGSurface >, std::reference_wrapper< const CSGCell >, std::reference_wrapper< const CSGUniverse >, std::reference_wrapper< const CSGRegion >, std::reference_wrapper< const CSGLattice >, std::reference_wrapper< const CSGEngUnit > > CSGObjectVariant
Define a variant type that can hold references to different CSG object types.
TransformationType
Enumeration of transformation types that can be applied to CSG objects.
RotationAxisType
Enumeration of axis types for rotations.