https://mooseframework.inl.gov
CSGBase.C
Go to the documentation of this file.
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 
12 namespace CSG
13 {
14 
16  : _surface_list(CSGSurfaceList()), _cell_list(CSGCellList()), _universe_list(CSGUniverseList())
17 {
18 }
19 
21 
22 const CSGCell &
23 CSGBase::createCell(const std::string & name,
24  const std::string & mat_name,
25  const CSGRegion & region,
26  const CSGUniverse * add_to_univ)
27 {
28  checkRegionSurfaces(region);
29  auto & cell = _cell_list.addMaterialCell(name, mat_name, region);
30  if (add_to_univ)
31  addCellToUniverse(*add_to_univ, cell);
32  else
34  return cell;
35 }
36 
37 const CSGCell &
38 CSGBase::createCell(const std::string & name,
39  const CSGRegion & region,
40  const CSGUniverse * add_to_univ)
41 {
42  checkRegionSurfaces(region);
43  auto & cell = _cell_list.addVoidCell(name, region);
44  if (add_to_univ)
45  addCellToUniverse(*add_to_univ, cell);
46  else
48  return cell;
49 }
50 
51 const CSGCell &
52 CSGBase::createCell(const std::string & name,
53  const CSGUniverse & fill_univ,
54  const CSGRegion & region,
55  const CSGUniverse * add_to_univ)
56 {
57  checkRegionSurfaces(region);
58  if (add_to_univ && (&fill_univ == add_to_univ))
59  mooseError("Cell " + name +
60  " cannot be filled with the same universe to which it is being added.");
61 
62  auto & cell = _cell_list.addUniverseCell(name, fill_univ, region);
63  if (add_to_univ)
64  addCellToUniverse(*add_to_univ, cell);
65  else
67  return cell;
68 }
69 
70 void
71 CSGBase::updateCellRegion(const CSGCell & cell, const CSGRegion & region)
72 {
73  checkRegionSurfaces(region);
74  if (!checkCellInBase(cell))
75  mooseError("The region of cell with name " + cell.getName() +
76  " is being updated that is different " +
77  "from the cell of the same name in the CSGBase instance.");
78  auto & list_cell = _cell_list.getCell(cell.getName());
79  list_cell.updateRegion(region);
80 }
81 
82 const CSGUniverse &
83 CSGBase::createUniverse(const std::string & name,
84  std::vector<std::reference_wrapper<const CSGCell>> & cells)
85 {
86  auto & univ = _universe_list.addUniverse(name);
87  addCellsToUniverse(univ, cells); // performs a check that cells are a part of this base
88  return univ;
89 }
90 
91 void
92 CSGBase::addCellToUniverse(const CSGUniverse & universe, const CSGCell & cell)
93 {
94  // make sure cell is a part of this CSGBase instance
95  if (!checkCellInBase(cell))
96  mooseError("A cell named " + cell.getName() + " is being added to universe " +
97  universe.getName() +
98  " that is different from the cell of the same name in the CSGBase instance.");
99  // make sure universe is a part of this CSGBase instance
100  if (!checkUniverseInBase(universe))
101  mooseError("Cells are being added to a universe named " + universe.getName() +
102  " that is different " +
103  "from the universe of the same name in the CSGBase instance.");
104  auto & univ = _universe_list.getUniverse(universe.getName());
105  univ.addCell(cell);
106 }
107 
108 void
110  std::vector<std::reference_wrapper<const CSGCell>> & cells)
111 {
112  for (auto & c : cells)
113  addCellToUniverse(universe, c);
114 }
115 
116 void
117 CSGBase::removeCellFromUniverse(const CSGUniverse & universe, const CSGCell & cell)
118 {
119  // make sure cell is a part of this CSGBase instance
120  if (!checkCellInBase(cell))
121  mooseError("A cell named " + cell.getName() + " is being removed from universe " +
122  universe.getName() +
123  " that is different from the cell of the same name in the CSGBase instance.");
124  // make sure universe is a part of this CSGBase instance
125  if (!checkUniverseInBase(universe))
126  mooseError("Cells are being removed from a universe named " + universe.getName() +
127  " that is different " +
128  "from the universe of the same name in the CSGBase instance.");
129  auto & univ = _universe_list.getUniverse(universe.getName());
130  univ.removeCell(cell.getName());
131 }
132 
133 void
135  std::vector<std::reference_wrapper<const CSGCell>> & cells)
136 {
137  for (auto & c : cells)
138  removeCellFromUniverse(universe, c);
139 }
140 
141 void
142 CSGBase::joinOtherBase(std::unique_ptr<CSGBase> base)
143 {
144  joinSurfaceList(base->getSurfaceList());
145  joinCellList(base->getCellList());
146  joinUniverseList(base->getUniverseList());
147 }
148 
149 void
150 CSGBase::joinOtherBase(std::unique_ptr<CSGBase> base, std::string & new_root_name_join)
151 {
152  joinSurfaceList(base->getSurfaceList());
153  joinCellList(base->getCellList());
154  joinUniverseList(base->getUniverseList(), new_root_name_join);
155 }
156 
157 void
158 CSGBase::joinOtherBase(std::unique_ptr<CSGBase> base,
159  const std::string & new_root_name_base,
160  const std::string & new_root_name_join)
161 {
162  joinSurfaceList(base->getSurfaceList());
163  joinCellList(base->getCellList());
164  joinUniverseList(base->getUniverseList(), new_root_name_base, new_root_name_join);
165 }
166 
167 void
169 {
170  // TODO: check if surface is a duplicate (by definition) and skip
171  // adding if duplicate; must update references to the surface in cell
172  // region definitions.
173  auto & surf_list_map = surf_list.getSurfaceListMap();
174  for (auto & s : surf_list_map)
175  _surface_list.addSurface(std::move(s.second));
176 }
177 
178 void
180 {
181  auto & cell_list_map = cell_list.getCellListMap();
182  for (auto & c : cell_list_map)
183  _cell_list.addCell(std::move(c.second));
184 }
185 
186 void
188 {
189  // case 1: incoming root is joined into existing root; no new universes are created
190  auto & univ_list_map = univ_list.getUniverseListMap();
191  auto & root = getRootUniverse(); // this root universe
192  for (auto & u : univ_list_map)
193  {
194  if (u.second->isRoot())
195  {
196  // add existing cells to current root instead of creating new universe
197  auto all_cells = u.second->getAllCells();
198  for (auto & cell : all_cells)
199  addCellToUniverse(root, cell);
200  }
201  else // unique non-root universe to add to list
202  _universe_list.addUniverse(std::move(u.second));
203  }
204 }
205 
206 void
207 CSGBase::joinUniverseList(CSGUniverseList & univ_list, const std::string & new_root_name_incoming)
208 {
209  // case 2: incoming root is turned into new universe and existing root remains root
210 
211  // add incoming universes to current Base
212  auto & all_univs = univ_list.getUniverseListMap();
213  for (auto & u : all_univs)
214  {
215  if (u.second->isRoot())
216  {
217  // create new universe from incoming root universe
218  auto all_cells = u.second->getAllCells();
219  createUniverse(new_root_name_incoming, all_cells);
220  }
221  else // unique non-root universe to add to list
222  _universe_list.addUniverse(std::move(u.second));
223  }
224 }
225 
226 void
228  const std::string & new_root_name_base,
229  const std::string & new_root_name_incoming)
230 {
231  // case 3: each root universe becomes a new universe and a new root is created
232 
233  // make a new universe from the existing root universe
234  auto & root = getRootUniverse();
235  auto root_cells = root.getAllCells();
236  createUniverse(new_root_name_base, root_cells);
237  removeCellsFromUniverse(root, root_cells);
238 
239  // add incoming universes to current Base
240  auto & all_univs = univ_list.getUniverseListMap();
241  for (auto & u : all_univs)
242  {
243  if (u.second->isRoot())
244  {
245  // create new universe from incoming root universe
246  auto all_cells = u.second->getAllCells();
247  createUniverse(new_root_name_incoming, all_cells);
248  }
249  else // unique non-root universe to add to list
250  _universe_list.addUniverse(std::move(u.second));
251  }
252 }
253 
254 void
256 {
257  auto & surfs = region.getSurfaces();
258  for (const CSGSurface & s : surfs)
259  {
260  auto sname = s.getName();
261  // if there is no surface by this name at all, there will be an error from getSurface
262  const auto & list_surf = _surface_list.getSurface(s.getName());
263  // if there is a surface by the same name, check that it is actually the surface being used
264  // (ie same surface points to same location in memory)
265  if (&s != &list_surf)
266  mooseError("Region is being set with a surface named " + sname +
267  " that is different from the surface of the same name in the CSGBase instance.");
268  }
269 }
270 
271 bool
273 {
274  auto name = cell.getName();
275  // if no cell by this name exists, an error will be produced by getCell
276  auto & list_cell = _cell_list.getCell(name);
277  // return whether that the cell in the list is the same as the cell provided (in memory)
278  return &cell == &list_cell;
279 }
280 
281 bool
283 {
284  auto name = universe.getName();
285  // if no universe by this name exists, an error will be produced by getUniverse
286  auto & list_univ = _universe_list.getUniverse(name);
287  // return whether that the cell in the list is the same as the cell provided (in memory)
288  return &universe == &list_univ;
289 }
290 
291 void
293 {
294  std::vector<std::string> linked_universe_names;
295 
296  // Recursively figure out which universe names are linked to root universe
297  getLinkedUniverses(getRootUniverse(), linked_universe_names);
298 
299  // Iterate through all universes in universe list and check that they exist in universes linked
300  // to root universe list
301  for (const CSGUniverse & univ : getAllUniverses())
302  if (std::find(linked_universe_names.begin(), linked_universe_names.end(), univ.getName()) ==
303  linked_universe_names.end())
304  mooseWarning("Universe with name ", univ.getName(), " is not linked to root universe.");
305 }
306 
307 void
309  std::vector<std::string> & linked_universe_names) const
310 {
311  linked_universe_names.push_back(univ.getName());
312  const auto & univ_cells = univ.getAllCells();
313  for (const CSGCell & cell : univ_cells)
314  if (cell.getFillType() == "UNIVERSE")
315  getLinkedUniverses(cell.getFillUniverse(), linked_universe_names);
316 }
317 
318 nlohmann::json
320 {
321  // Check that orphaned universes do not exist in universe list of CSGBase object
323 
324  nlohmann::json csg_json;
325 
326  csg_json["surfaces"] = {};
327  csg_json["cells"] = {};
328  csg_json["universes"] = {};
329 
330  // get all surfaces information
331  auto all_surfs = getAllSurfaces();
332  for (const CSGSurface & s : all_surfs)
333  {
334  const auto & surf_name = s.getName();
335  const auto & coeffs = s.getCoeffs();
336  csg_json["surfaces"][surf_name] = {{"type", s.getSurfaceType()}, {"coefficients", {}}};
337  for (const auto & c : coeffs)
338  csg_json["surfaces"][surf_name]["coefficients"][c.first] = c.second;
339  }
340 
341  // Print out cell information
342  auto all_cells = getAllCells();
343  for (const CSGCell & c : all_cells)
344  {
345  const auto & cell_name = c.getName();
346  const auto & cell_region = c.getRegionAsString();
347  const auto & cell_filltype = c.getFillType();
348  const auto & fill_name = c.getFillName();
349  csg_json["cells"][cell_name]["filltype"] = cell_filltype;
350  csg_json["cells"][cell_name]["region"] = cell_region;
351  csg_json["cells"][cell_name]["fill"] = fill_name;
352  }
353 
354  // Print out universe information
355  auto all_univs = getAllUniverses();
356  for (const CSGUniverse & u : all_univs)
357  {
358  const auto & univ_name = u.getName();
359  const auto & univ_cells = u.getAllCells();
360  csg_json["universes"][univ_name]["cells"] = {};
361  for (const CSGCell & c : univ_cells)
362  csg_json["universes"][univ_name]["cells"].push_back(c.getName());
363  if (u.isRoot())
364  csg_json["universes"][univ_name]["root"] = u.isRoot();
365  }
366 
367  return csg_json;
368 }
369 
370 } // namespace CSG
std::string name(const ElemQuality q)
CSGCell & addCell(std::unique_ptr< CSGCell > cell)
add a cell to the CellList.
Definition: CSGCellList.C:18
void joinCellList(CSGCellList &cell_list)
join a separate CSGCellList object to this one
Definition: CSGBase.C:179
KOKKOS_INLINE_FUNCTION const T * find(const T &target, const T *const begin, const T *const end)
Find a value in an array.
Definition: KokkosUtils.h:30
CSGCell & getCell(const std::string &name) const
Get the CSGCell by name.
Definition: CSGCellList.C:28
const std::string & getName() const
Get the cell name.
Definition: CSGCell.h:94
std::vector< std::reference_wrapper< const CSGUniverse > > getAllUniverses() const
Get all universe objects.
Definition: CSGBase.h:254
CSGUniverseList _universe_list
List of universes associated with CSG object.
Definition: CSGBase.h:422
void updateRegion(const CSGRegion &region)
Definition: CSGCell.h:123
CSGRegions creates an internal representation of a CSG region, which can refer to an intersection...
Definition: CSGRegion.h:21
CSGCellList creates a container for CSGCell objects to pass to CSGBase object.
Definition: CSGCellList.h:20
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:323
std::unordered_map< std::string, std::unique_ptr< CSGCell > > & getCellListMap()
Get map of all names to cells in cell list.
Definition: CSGCellList.h:72
void mooseWarning(Args &&... args)
Emit a warning message with the given stringified, concatenated args.
Definition: MooseError.h:357
const CSGCell & createCell(const std::string &name, const std::string &mat_name, const CSGRegion &region, const CSGUniverse *add_to_univ=nullptr)
Create a Material Cell object.
Definition: CSGBase.C:23
void joinUniverseList(CSGUniverseList &univ_list)
join a separate CSGUniverseList object to this one; root universes from univ_list will be combined in...
Definition: CSGBase.C:187
void joinOtherBase(std::unique_ptr< CSGBase > base)
Join another CSGBase object to this one.
Definition: CSGBase.C:142
CSGCell & addVoidCell(const std::string &name, const CSGRegion &region)
Add a Void Cell object cell list.
Definition: CSGCellList.C:37
CSGUniverse creates an internal representation of a Constructive Solid Geometry (CSG) universe...
Definition: CSGUniverse.h:26
const std::vector< std::reference_wrapper< const CSGCell > > & getAllCells() const
Get list of the all cells in the universe.
Definition: CSGUniverse.h:72
CSGSurface & getSurface(const std::string &name) const
Get a surface by name.
CSGSurfaceList _surface_list
List of surfaces associated with CSG object.
Definition: CSGBase.h:416
void getLinkedUniverses(const CSGUniverse &univ, std::vector< std::string > &linked_universe_names) const
Recursive method to retrieve all universes linked to current universe.
Definition: CSGBase.C:308
nlohmann::json generateOutput() const
generate the JSON representation output for the CSG object
Definition: CSGBase.C:319
CSGCell & addMaterialCell(const std::string &name, const std::string &mat_name, const CSGRegion &region)
Add a Material Cell object to cell list.
Definition: CSGCellList.C:43
void removeCell(const std::string &name)
remove a cell of the specified name from the universe
Definition: CSGUniverse.C:56
CSGCell & addUniverseCell(const std::string &name, const CSGUniverse &univ, const CSGRegion &region)
Add a Universe Cell object to cell list.
Definition: CSGCellList.C:51
CSGUniverse & getUniverse(const std::string &name) const
Get a Universe from the list by its name.
const std::string & getName() const
Get the name of the universe.
Definition: CSGUniverse.h:79
void addCellsToUniverse(const CSGUniverse &universe, std::vector< std::reference_wrapper< const CSGCell >> &cells)
Add a list of cells to an existing universe.
Definition: CSGBase.C:109
const CSGUniverse & getRootUniverse() const
Get the Root Universe object.
Definition: CSGBase.h:171
void updateCellRegion(const CSGCell &cell, const CSGRegion &region)
change the region of the specified cell
Definition: CSGBase.C:71
CSGUniverseList creates a container for CSGUniverse objects to pass to CSGBase.
const std::vector< std::reference_wrapper< const CSGSurface > > & getSurfaces() const
Get the list of surfaces associated with the region.
Definition: CSGRegion.h:97
void joinSurfaceList(CSGSurfaceList &surf_list)
join a separate CSGSurfaceList object to this one
Definition: CSGBase.C:168
void removeCellsFromUniverse(const CSGUniverse &universe, std::vector< std::reference_wrapper< const CSGCell >> &cells)
Remove a list of cells from an existing universe.
Definition: CSGBase.C:134
CSGUniverse & addUniverse(const std::string &name)
create an empty universe
bool checkUniverseInBase(const CSGUniverse &universe) const
Definition: CSGBase.C:282
CSGCell creates an internal representation of a Constructive Solid Geometry (CSG) cell...
Definition: CSGCell.h:27
void checkRegionSurfaces(const CSGRegion &region) const
Definition: CSGBase.C:255
CSGCellList _cell_list
List of cells associated with CSG object.
Definition: CSGBase.h:419
std::unordered_map< std::string, std::unique_ptr< CSGSurface > > & getSurfaceListMap()
Get map of all names to surfaces in surface list.
bool checkCellInBase(const CSGCell &cell) const
Definition: CSGBase.C:272
CSGSurfaceList is a container for storing CSGSurface objects in the CSGBase object.
CSGSurface creates an internal representation of a Constructive Solid Geometry (CSG) surface...
Definition: CSGSurface.h:26
CSGBase()
Default constructor.
Definition: CSGBase.C:15
CSGSurface & addSurface(std::unique_ptr< CSGSurface > surf)
add a surface object to existing SurfaceList.
const CSGUniverse & createUniverse(const std::string &name)
Create an empty Universe object.
Definition: CSGBase.h:200
void addCellToUniverse(const CSGUniverse &universe, const CSGCell &cell)
Add a cell to an existing universe.
Definition: CSGBase.C:92
void checkUniverseLinking() const
Check universes linked to root universe match universes defined in _universe_list.
Definition: CSGBase.C:292
std::vector< std::reference_wrapper< const CSGCell > > getAllCells() const
Get all cell objects.
Definition: CSGBase.h:134
~CSGBase()
Destructor.
Definition: CSGBase.C:20
void removeCellFromUniverse(const CSGUniverse &universe, const CSGCell &cell)
Remove a cell from an existing universe.
Definition: CSGBase.C:117
void addCell(const CSGCell &cell)
add cell to universe
Definition: CSGUniverse.C:25
std::vector< std::reference_wrapper< const CSGSurface > > getAllSurfaces() const
Get all surface objects.
Definition: CSGBase.h:59
std::unordered_map< std::string, std::unique_ptr< CSGUniverse > > & getUniverseListMap()
Get map of all names to universes in universe list.