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 280 : CSGBase::CSGBase()
18 280 : : _surface_list(CSGSurfaceList()),
19 280 : _cell_list(CSGCellList()),
20 280 : _universe_list(CSGUniverseList()),
21 280 : _lattice_list(CSGLatticeList())
22 : {
23 280 : }
24 :
25 36 : CSGBase::CSGBase(const CSGBase & other_base)
26 36 : : _surface_list(other_base.getSurfaceList()),
27 36 : _cell_list(CSGCellList()),
28 36 : _universe_list(CSGUniverseList()),
29 36 : _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 118 : for (const auto & [name, cell] : other_base.getCellList().getCellListMap())
35 82 : addCellToList(*cell);
36 :
37 : // Link all cells in other_base root universe to current root universe
38 70 : for (auto & root_cell : other_base.getRootUniverse().getAllCells())
39 : {
40 34 : const auto & list_cell = _cell_list.getCell(root_cell.get().getName());
41 34 : 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 146 : for (const auto & [name, univ] : other_base.getUniverseList().getUniverseListMap())
48 110 : 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 54 : for (const auto & [name, lattice] : other_base.getLatticeList().getLatticeListMap())
53 18 : addLatticeToList(*lattice);
54 36 : }
55 :
56 310 : 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 130 : CSGBase::addCellToList(const CSGCell & cell)
86 : {
87 : // If cell has already been created, we just return a reference to it
88 130 : const auto name = cell.getName();
89 130 : if (_cell_list.hasCell(name))
90 48 : return _cell_list.getCell(name);
91 :
92 : // Otherwise if the cell has material or void cell, we can create it directly
93 82 : const auto fill_type = cell.getFillType();
94 82 : const auto region = cell.getRegion();
95 82 : if (fill_type == "VOID")
96 14 : return _cell_list.addVoidCell(name, region);
97 68 : 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 42 : else if (fill_type == "LATTICE")
103 : {
104 : // add lattice recursively to capture all linked universes in the lattice
105 18 : const CSGLattice & lattice = addLatticeToList(cell.getFillLattice());
106 18 : 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 24 : else if (fill_type == "UNIVERSE")
111 : {
112 24 : const auto & univ = addUniverseToList(cell.getFillUniverse());
113 24 : return _cell_list.addUniverseCell(name, univ, region);
114 : }
115 : else
116 0 : mooseError("Cell " + name + " has unrecognized fill type " + fill_type);
117 130 : }
118 :
119 : const CSGUniverse &
120 194 : CSGBase::addUniverseToList(const CSGUniverse & univ)
121 : {
122 : // If universe has already been created, we just return a reference to it
123 194 : const auto name = univ.getName();
124 194 : if (_universe_list.hasUniverse(name))
125 120 : 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 74 : const auto univ_cells = univ.getAllCells();
131 74 : std::vector<std::reference_wrapper<const CSGCell>> current_univ_cells;
132 122 : for (const auto & univ_cell : univ_cells)
133 48 : current_univ_cells.push_back(addCellToList(univ_cell));
134 74 : return createUniverse(name, current_univ_cells);
135 194 : }
136 :
137 : const CSGLattice &
138 36 : CSGBase::addLatticeToList(const CSGLattice & lattice)
139 : {
140 : // If lattice has already been created, we just return a reference to it
141 36 : const auto name = lattice.getName();
142 36 : if (_lattice_list.hasLattice(name))
143 18 : return _lattice_list.getLattice(name);
144 :
145 : // Clone the lattice (associated universes need to be transferred and set)
146 18 : 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 18 : std::vector<std::vector<std::reference_wrapper<const CSGUniverse>>> current_univ_map;
152 44 : for (const auto & univ_list : lattice.getUniverses())
153 : {
154 26 : std::vector<std::reference_wrapper<const CSGUniverse>> current_univ_list;
155 68 : for (const auto & univ_ref : univ_list)
156 42 : current_univ_list.push_back(addUniverseToList(univ_ref.get()));
157 26 : current_univ_map.push_back(current_univ_list);
158 44 : }
159 :
160 : // Set universes only if lattice has universes defined
161 18 : if (current_univ_map.size() > 0)
162 18 : cloned_lattice->setUniverses(current_univ_map);
163 :
164 : // Update reference to outer universe if it exists
165 18 : if (lattice.getOuterType() == "UNIVERSE")
166 : {
167 18 : const auto & outer_univ_ref = addUniverseToList(lattice.getOuterUniverse());
168 18 : cloned_lattice->updateOuter(outer_univ_ref);
169 : }
170 :
171 : // Use addLattice to add the cloned lattice
172 18 : return addLattice(std::move(cloned_lattice));
173 36 : }
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 24 : CSGBase::createCell(const std::string & name,
229 : const CSGUniverse & fill_univ,
230 : const CSGRegion & region,
231 : const CSGUniverse * add_to_univ)
232 : {
233 24 : checkRegionSurfaces(region);
234 24 : 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 22 : auto & cell = _cell_list.addUniverseCell(name, fill_univ, region);
239 22 : if (add_to_univ)
240 12 : addCellToUniverse(*add_to_univ, cell);
241 : else
242 10 : addCellToUniverse(getRootUniverse(), cell);
243 22 : return cell;
244 : }
245 :
246 : const CSGCell &
247 60 : CSGBase::createCell(const std::string & name,
248 : const CSGLattice & fill_lattice,
249 : const CSGRegion & region,
250 : const CSGUniverse * add_to_univ)
251 : {
252 60 : checkRegionSurfaces(region);
253 :
254 : // check that cell is not being added to a universe that exists in the lattice itself
255 60 : if (add_to_univ)
256 10 : for (auto univ_list : fill_lattice.getUniverses())
257 12 : for (const auto & univ_ref : univ_list)
258 : {
259 8 : const CSGUniverse & univ_in_lattice = univ_ref.get();
260 8 : 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 12 : }
265 :
266 58 : auto & cell = _cell_list.addLatticeCell(name, fill_lattice, region);
267 58 : if (add_to_univ)
268 4 : addCellToUniverse(*add_to_univ, cell);
269 : else
270 54 : addCellToUniverse(getRootUniverse(), cell);
271 58 : 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 150 : CSGBase::createUniverse(const std::string & name,
372 : std::vector<std::reference_wrapper<const CSGCell>> & cells)
373 : {
374 150 : auto & univ = _universe_list.addUniverse(name);
375 150 : addCellsToUniverse(univ, cells); // performs a check that cells are a part of this base
376 150 : 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 493 : CSGBase::addCellToUniverse(const CSGUniverse & universe, const CSGCell & cell)
425 : {
426 : // make sure cell is a part of this CSGBase instance
427 493 : 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 491 : 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 489 : auto & univ = _universe_list.getUniverse(universe.getName());
437 489 : univ.addCell(cell);
438 489 : }
439 :
440 : void
441 152 : CSGBase::addCellsToUniverse(const CSGUniverse & universe,
442 : std::vector<std::reference_wrapper<const CSGCell>> & cells)
443 : {
444 286 : for (auto & c : cells)
445 134 : addCellToUniverse(universe, c);
446 152 : }
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 20 : CSGBase::setLatticeOuter(const CSGLattice & lattice, const CSGUniverse & outer_univ)
486 : {
487 20 : auto name = lattice.getName();
488 20 : 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 20 : 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 18 : _lattice_list.getLattice(name).updateOuter(outer_univ);
496 20 : }
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 126 : 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 126 : std::visit(
551 252 : [&](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 42 : const CSGCell & cell = obj.get();
560 42 : 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 40 : CSGCell & mutable_cell = _cell_list.getCell(cell.getName());
567 : mooseAssert(mutable_cell == cell, "Mutable cell does not match const cell passed in.");
568 40 : mutable_cell.addTransformation(type, values);
569 : }
570 : else if constexpr (std::is_same_v<T, CSGSurface>)
571 : {
572 34 : const CSGSurface & surface = obj.get();
573 34 : 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 32 : CSGSurface & mutable_surface = _surface_list.getSurface(surface.getName());
580 : mooseAssert(mutable_surface == surface,
581 : "Mutable surface does not match const surface passed in.");
582 32 : mutable_surface.addTransformation(type, values);
583 : }
584 : else if constexpr (std::is_same_v<T, CSGUniverse>)
585 : {
586 18 : const CSGUniverse & universe = obj.get();
587 18 : 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 16 : CSGUniverse & mutable_universe = _universe_list.getUniverse(universe.getName());
594 : mooseAssert(mutable_universe == universe,
595 : "Mutable universe does not match const universe passed in.");
596 16 : 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 114 : },
629 : csg_object);
630 114 : }
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 76 : CSGBase::joinOtherBase(std::unique_ptr<CSGBase> base, const bool ignore_identical_components)
664 : {
665 : // If we are ignoring identical incoming CSG components, we need to update any references
666 : // stored by these components to point to the references of the pre-existing CSGBase object
667 76 : if (ignore_identical_components)
668 18 : updateIncomingCSGReferences(*base);
669 76 : joinSurfaceList(base->getSurfaceList(), ignore_identical_components);
670 72 : joinCellList(base->getCellList(), ignore_identical_components);
671 66 : joinLatticeList(base->getLatticeList(), ignore_identical_components);
672 62 : joinUniverseList(base->getUniverseList(), ignore_identical_components);
673 58 : }
674 :
675 : void
676 58 : CSGBase::joinOtherBase(std::unique_ptr<CSGBase> base,
677 : const bool ignore_identical_components,
678 : const std::string & new_root_name_join)
679 : {
680 : // If we are ignoring identical incoming CSG components, we need to update any references
681 : // stored by these components to point to the references of the pre-existing CSGBase object
682 58 : if (ignore_identical_components)
683 0 : updateIncomingCSGReferences(*base);
684 58 : joinSurfaceList(base->getSurfaceList(), ignore_identical_components);
685 58 : joinCellList(base->getCellList(), ignore_identical_components);
686 58 : joinLatticeList(base->getLatticeList(), ignore_identical_components);
687 58 : joinUniverseList(base->getUniverseList(), ignore_identical_components, new_root_name_join);
688 58 : }
689 :
690 : void
691 2 : CSGBase::joinOtherBase(std::unique_ptr<CSGBase> base,
692 : const bool ignore_identical_components,
693 : const std::string & new_root_name_base,
694 : const std::string & new_root_name_join)
695 : {
696 : // If we are ignoring identical incoming CSG components, we need to update any references
697 : // stored by these components to point to the references of the pre-existing CSGBase object
698 2 : if (ignore_identical_components)
699 0 : updateIncomingCSGReferences(*base);
700 2 : joinSurfaceList(base->getSurfaceList(), ignore_identical_components);
701 2 : joinCellList(base->getCellList(), ignore_identical_components);
702 2 : joinLatticeList(base->getLatticeList(), ignore_identical_components);
703 2 : joinUniverseList(
704 : base->getUniverseList(), ignore_identical_components, new_root_name_base, new_root_name_join);
705 2 : }
706 :
707 : void
708 18 : CSGBase::updateIncomingCSGReferences(CSGBase & incoming_base)
709 : {
710 : // Iterate through all incoming surfaces and track which ones have names already
711 : // defined within this CSGSurfaceList object
712 18 : std::map<std::string, std::reference_wrapper<const CSGSurface>> identical_surface_refs;
713 18 : auto & surf_list_map = incoming_base.getSurfaceList().getSurfaceListMap();
714 22 : for (const auto & [surf_name, surf_ptr] : surf_list_map)
715 4 : if (hasSurface(surf_name))
716 4 : identical_surface_refs.insert({surf_name, getSurfaceByName(surf_name)});
717 :
718 : // Iterate through all incoming cells and track which ones have names already
719 : // defined within this CSGCellList object
720 18 : std::map<std::string, std::reference_wrapper<const CSGCell>> identical_cell_refs;
721 18 : auto & cell_list_map = incoming_base.getCellList().getCellListMap();
722 36 : for (const auto & [cell_name, cell_ptr] : cell_list_map)
723 18 : if (hasCell(cell_name))
724 12 : identical_cell_refs.insert({cell_name, getCellByName(cell_name)});
725 :
726 : // Iterate through all incoming universes and track which ones have names already
727 : // defined within this CSGUniverseList object
728 18 : std::map<std::string, std::reference_wrapper<const CSGUniverse>> identical_universe_refs;
729 18 : auto & universe_list_map = incoming_base.getUniverseList().getUniverseListMap();
730 66 : for (const auto & [univ_name, univ_ptr] : universe_list_map)
731 48 : if (hasUniverse(univ_name))
732 34 : identical_universe_refs.insert({univ_name, getUniverseByName(univ_name)});
733 :
734 : // Iterate through all incoming lattices and track which ones have names already
735 : // defined within this CSGLatticeList object
736 18 : std::map<std::string, std::reference_wrapper<const CSGLattice>> identical_lattice_refs;
737 18 : auto & lattice_list_map = incoming_base.getLatticeList().getLatticeListMap();
738 24 : for (const auto & [lat_name, lat_ptr] : lattice_list_map)
739 6 : if (hasLattice(lat_name))
740 6 : identical_lattice_refs.insert({lat_name, getLatticeByName(lat_name)});
741 :
742 : // Update all surface, cell, universe, and lattice references of incoming base to those of this
743 : // base
744 18 : if (!identical_surface_refs.empty())
745 4 : replaceSurfaceRefsByName(identical_surface_refs, incoming_base);
746 :
747 18 : if (!identical_cell_refs.empty())
748 12 : replaceCellRefsByName(identical_cell_refs, incoming_base);
749 :
750 18 : if (!identical_universe_refs.empty())
751 18 : replaceUniverseRefsByName(identical_universe_refs, incoming_base);
752 :
753 18 : if (!identical_lattice_refs.empty())
754 6 : replaceLatticeRefsByName(identical_lattice_refs, incoming_base);
755 18 : }
756 :
757 : void
758 4 : CSGBase::replaceSurfaceRefsByName(
759 : std::map<std::string, std::reference_wrapper<const CSGSurface>> & identical_surface_refs,
760 : CSGBase & base)
761 : {
762 : // Update surface references of cell regions to those of this base
763 8 : for (auto & [cell_name, cell_ptr] : base.getCellList().getCellListMap())
764 4 : cell_ptr->updateCellRegionSurfaces(identical_surface_refs);
765 4 : }
766 :
767 : void
768 12 : CSGBase::replaceCellRefsByName(
769 : std::map<std::string, std::reference_wrapper<const CSGCell>> & identical_cell_refs,
770 : CSGBase & base)
771 : {
772 : // Update cell references of universes to those of this base
773 52 : for (auto & [univ_name, univ_ptr] : base.getUniverseList().getUniverseListMap())
774 80 : for (auto & [cell_name, cell_ref] : identical_cell_refs)
775 40 : if (univ_ptr->hasCell(cell_name))
776 : {
777 12 : univ_ptr->removeCell(cell_name);
778 12 : univ_ptr->addCell(cell_ref);
779 : }
780 12 : }
781 :
782 : void
783 18 : CSGBase::replaceUniverseRefsByName(
784 : std::map<std::string, std::reference_wrapper<const CSGUniverse>> & identical_universe_refs,
785 : CSGBase & base)
786 : {
787 : // Update universe references of cells to those of this base
788 36 : for (auto & [cell_name, cell_ptr] : base.getCellList().getCellListMap())
789 : {
790 18 : const auto fill_type = cell_ptr->getFillType();
791 18 : const auto fill_name = cell_ptr->getFillName();
792 26 : if ((fill_type == "UNIVERSE") &&
793 26 : (identical_universe_refs.find(fill_name) != identical_universe_refs.end()))
794 : {
795 8 : const CSGUniverse * univ_ptr = &identical_universe_refs.at(fill_name).get();
796 8 : cell_ptr->updateCellFill(univ_ptr);
797 : }
798 18 : }
799 :
800 : // Update universe references of lattices to those of this base
801 24 : for (auto & [lat_name, lat_ptr] : base.getLatticeList().getLatticeListMap())
802 20 : for (auto & [univ_name, univ_ref] : identical_universe_refs)
803 : {
804 : // Check if universe belongs to lattice
805 14 : if (lat_ptr->hasUniverse(univ_name))
806 : {
807 : // If so, replace all instances of this universe in the lattice
808 4 : const auto univ_indices = lat_ptr->getUniverseIndices(univ_name);
809 8 : for (const auto & index : univ_indices)
810 4 : lat_ptr->setUniverseAtIndex(univ_ref, index);
811 4 : }
812 : // Check if universe belongs to lattice outer
813 28 : if ((lat_ptr->getOuterType() == "UNIVERSE") &&
814 14 : (lat_ptr->getOuterUniverse().getName() == univ_name))
815 4 : lat_ptr->updateOuter(univ_ref);
816 : }
817 18 : }
818 :
819 : void
820 6 : CSGBase::replaceLatticeRefsByName(
821 : std::map<std::string, std::reference_wrapper<const CSGLattice>> & identical_lattice_refs,
822 : CSGBase & base)
823 : {
824 : // Update lattice references of cells to those of this base
825 12 : for (auto & [cell_name, cell_ptr] : base.getCellList().getCellListMap())
826 : {
827 6 : const auto fill_type = cell_ptr->getFillType();
828 6 : const auto fill_name = cell_ptr->getFillName();
829 12 : if ((fill_type == "LATTICE") &&
830 12 : (identical_lattice_refs.find(fill_name) != identical_lattice_refs.end()))
831 : {
832 6 : const CSGLattice * lat_ptr = &identical_lattice_refs.at(fill_name).get();
833 6 : cell_ptr->updateCellFill(lat_ptr);
834 : }
835 6 : }
836 6 : }
837 :
838 : void
839 136 : CSGBase::joinSurfaceList(CSGSurfaceList & surf_list, const bool ignore_identical_surfaces)
840 : {
841 136 : auto & surf_list_map = surf_list.getSurfaceListMap();
842 688 : for (auto & s : surf_list_map)
843 560 : _surface_list.addSurface(std::move(s.second), ignore_identical_surfaces);
844 132 : }
845 :
846 : void
847 132 : CSGBase::joinCellList(CSGCellList & cell_list, const bool ignore_identical_cells)
848 : {
849 132 : auto & cell_list_map = cell_list.getCellListMap();
850 376 : for (auto & c : cell_list_map)
851 256 : _cell_list.addCell(std::move(c.second), ignore_identical_cells);
852 126 : }
853 :
854 : void
855 126 : CSGBase::joinLatticeList(CSGLatticeList & lattice_list, const bool ignore_identical_lattices)
856 : {
857 126 : auto & lat_list_map = lattice_list.getLatticeListMap();
858 192 : for (auto & lat : lat_list_map)
859 74 : _lattice_list.addLattice(std::move(lat.second), ignore_identical_lattices);
860 122 : }
861 :
862 : void
863 62 : CSGBase::joinUniverseList(CSGUniverseList & univ_list, const bool ignore_identical_universes)
864 : {
865 : // case 1: incoming root is joined into existing root; no new universes are created
866 62 : auto & univ_list_map = univ_list.getUniverseListMap();
867 62 : auto & root = getRootUniverse(); // this root universe
868 238 : for (auto & u : univ_list_map)
869 : {
870 180 : if (u.second->isRoot())
871 : {
872 : // add existing cells to current root instead of creating new universe
873 58 : auto all_cells = u.second->getAllCells();
874 96 : for (auto & cell : all_cells)
875 38 : addCellToUniverse(root, cell);
876 58 : }
877 : else // unique non-root universe to add to list
878 126 : _universe_list.addUniverse(std::move(u.second), ignore_identical_universes);
879 : }
880 58 : }
881 :
882 : void
883 58 : CSGBase::joinUniverseList(CSGUniverseList & univ_list,
884 : const bool ignore_identical_universes,
885 : const std::string & new_root_name_incoming)
886 : {
887 : // case 2: incoming root is turned into new universe and existing root remains root
888 :
889 : // add incoming universes to current Base
890 58 : auto & all_univs = univ_list.getUniverseListMap();
891 126 : for (auto & u : all_univs)
892 : {
893 68 : if (u.second->isRoot())
894 : {
895 : // create new universe from incoming root universe
896 58 : auto all_cells = u.second->getAllCells();
897 58 : createUniverse(new_root_name_incoming, all_cells);
898 58 : }
899 : else // unique non-root universe to add to list
900 10 : _universe_list.addUniverse(std::move(u.second), ignore_identical_universes);
901 : }
902 58 : }
903 :
904 : void
905 2 : CSGBase::joinUniverseList(CSGUniverseList & univ_list,
906 : const bool ignore_identical_universes,
907 : const std::string & new_root_name_base,
908 : const std::string & new_root_name_incoming)
909 : {
910 : // case 3: each root universe becomes a new universe and a new root is created
911 :
912 : // make a new universe from the existing root universe
913 2 : auto & root = getRootUniverse();
914 2 : auto root_cells = root.getAllCells();
915 2 : createUniverse(new_root_name_base, root_cells);
916 2 : removeCellsFromUniverse(root, root_cells);
917 :
918 : // add incoming universes to current Base
919 2 : auto & all_univs = univ_list.getUniverseListMap();
920 6 : for (auto & u : all_univs)
921 : {
922 4 : if (u.second->isRoot())
923 : {
924 : // create new universe from incoming root universe
925 2 : auto all_cells = u.second->getAllCells();
926 2 : createUniverse(new_root_name_incoming, all_cells);
927 2 : }
928 : else // unique non-root universe to add to list
929 2 : _universe_list.addUniverse(std::move(u.second), ignore_identical_universes);
930 : }
931 2 : }
932 :
933 : void
934 307 : CSGBase::checkRegionSurfaces(const CSGRegion & region) const
935 : {
936 307 : const auto surfs = region.getSurfaces();
937 1041 : for (const CSGSurface & s : surfs)
938 : {
939 736 : if (!checkSurfaceInBase(s))
940 6 : mooseError("Region is being set with a surface named " + s.getName() +
941 : " that is different from the surface of the same name in the CSGBase instance.");
942 : }
943 307 : }
944 :
945 : bool
946 792 : CSGBase::checkSurfaceInBase(const CSGSurface & surface) const
947 : {
948 792 : auto name = surface.getName();
949 : // if no surface by this name exists, an error will be produced by getSurface
950 792 : auto & list_surf = _surface_list.getSurface(name);
951 : // return whether that the surface in the list is the same as the surface provided (in memory)
952 792 : return &surface == &list_surf;
953 792 : }
954 :
955 : bool
956 601 : CSGBase::checkCellInBase(const CSGCell & cell) const
957 : {
958 601 : auto name = cell.getName();
959 : // if no cell by this name exists, an error will be produced by getCell
960 601 : auto & list_cell = _cell_list.getCell(name);
961 : // return whether that the cell in the list is the same as the cell provided (in memory)
962 601 : return &cell == &list_cell;
963 601 : }
964 :
965 : bool
966 1011 : CSGBase::checkUniverseInBase(const CSGUniverse & universe) const
967 : {
968 1011 : auto name = universe.getName();
969 : // if no universe by this name exists, an error will be produced by getUniverse
970 1011 : auto & list_univ = _universe_list.getUniverse(name);
971 : // return whether that the universe in the list is the same as the universe provided (in memory)
972 1011 : return &universe == &list_univ;
973 1011 : }
974 :
975 : bool
976 66 : CSGBase::checkLatticeInBase(const CSGLattice & lattice) const
977 : {
978 66 : auto name = lattice.getName();
979 : // if no lattice by this name exists, an error will be produced by getLattice
980 66 : auto & list_lattice = _lattice_list.getLattice(name);
981 : // return whether that the lattice in the list is the same as the lattice provided (in memory)
982 66 : return &lattice == &list_lattice;
983 66 : }
984 :
985 : void
986 78 : CSGBase::checkUniverseLinking() const
987 : {
988 78 : std::vector<std::string> linked_universe_names;
989 78 : std::vector<std::string> linked_cell_names;
990 :
991 : // Recursively figure out which universe names are linked to root universe
992 78 : getLinkedUniverses(getRootUniverse(), linked_universe_names, linked_cell_names);
993 :
994 : // Iterate through all universes in universe list and check that they exist in universes linked
995 : // to root universe
996 266 : for (const CSGUniverse & univ : getAllUniverses())
997 194 : if (std::find(linked_universe_names.begin(), linked_universe_names.end(), univ.getName()) ==
998 388 : linked_universe_names.end())
999 78 : mooseWarning("Universe with name ", univ.getName(), " is not linked to root universe.");
1000 :
1001 : // Iterate through all cells in cell list and check that they exist in cells linked
1002 : // to root universe
1003 284 : for (const CSGCell & cell : getAllCells())
1004 214 : if (std::find(linked_cell_names.begin(), linked_cell_names.end(), cell.getName()) ==
1005 428 : linked_cell_names.end())
1006 72 : mooseWarning("Cell with name ", cell.getName(), " is not linked to root universe.");
1007 86 : }
1008 :
1009 : void
1010 790 : CSGBase::getLinkedUniverses(const CSGUniverse & univ,
1011 : std::vector<std::string> & linked_universe_names,
1012 : std::vector<std::string> & linked_cell_names) const
1013 : {
1014 790 : linked_universe_names.push_back(univ.getName());
1015 790 : const auto & univ_cells = univ.getAllCells();
1016 1698 : for (const CSGCell & cell : univ_cells)
1017 : {
1018 908 : linked_cell_names.push_back(cell.getName());
1019 908 : if (cell.getFillType() == "UNIVERSE")
1020 76 : getLinkedUniverses(cell.getFillUniverse(), linked_universe_names, linked_cell_names);
1021 832 : else if (cell.getFillType() == "LATTICE")
1022 : {
1023 118 : const auto & lattice = cell.getFillLattice();
1024 380 : for (const auto & univ_list : lattice.getUniverses())
1025 876 : for (const auto & univ_ref : univ_list)
1026 : {
1027 614 : const CSGUniverse & lattice_univ = univ_ref.get();
1028 614 : getLinkedUniverses(lattice_univ, linked_universe_names, linked_cell_names);
1029 118 : }
1030 :
1031 118 : if (lattice.getOuterType() == "UNIVERSE")
1032 : {
1033 22 : const CSGUniverse & outer_univ = lattice.getOuterUniverse();
1034 22 : getLinkedUniverses(outer_univ, linked_universe_names, linked_cell_names);
1035 : }
1036 : }
1037 : }
1038 790 : }
1039 :
1040 : nlohmann::json
1041 64 : CSGBase::generateOutput() const
1042 : {
1043 : // Check that orphaned universes do not exist in universe list of CSGBase object
1044 64 : checkUniverseLinking();
1045 :
1046 64 : nlohmann::json csg_json;
1047 :
1048 64 : csg_json["surfaces"] = {};
1049 64 : csg_json["cells"] = {};
1050 64 : csg_json["universes"] = {};
1051 :
1052 : // get all surfaces information
1053 64 : auto all_surfs = getAllSurfaces();
1054 560 : for (const CSGSurface & s : all_surfs)
1055 : {
1056 496 : const auto & surf_name = s.getName();
1057 496 : const auto & coeffs = s.getCoeffs();
1058 3472 : csg_json["surfaces"][surf_name] = {{"type", s.getSurfaceType()}, {"coefficients", {}}};
1059 2480 : for (const auto & c : coeffs)
1060 1984 : csg_json["surfaces"][surf_name]["coefficients"][c.first] = c.second;
1061 : // include any information about transformations if present
1062 496 : if (s.getTransformations().size() > 0)
1063 0 : csg_json["surfaces"][surf_name]["transformations"] = s.getTransformationsAsStrings();
1064 496 : }
1065 :
1066 : // Print out cell information
1067 64 : auto all_cells = getAllCells();
1068 264 : for (const CSGCell & c : all_cells)
1069 : {
1070 200 : const auto & cell_name = c.getName();
1071 200 : const auto & cell_region_infix = c.getRegion().toInfixJSON();
1072 200 : const auto & cell_region_postfix = c.getRegion().toPostfixStringList();
1073 200 : const auto & cell_filltype = c.getFillType();
1074 200 : const auto & fill_name = c.getFillName();
1075 200 : csg_json["cells"][cell_name]["filltype"] = cell_filltype;
1076 200 : csg_json["cells"][cell_name]["region_infix"] = cell_region_infix;
1077 200 : csg_json["cells"][cell_name]["region_postfix"] = cell_region_postfix;
1078 200 : csg_json["cells"][cell_name]["fill"] = fill_name;
1079 : // include any information about transformations if present
1080 200 : if (c.getTransformations().size())
1081 16 : csg_json["cells"][cell_name]["transformations"] = c.getTransformationsAsStrings();
1082 200 : }
1083 :
1084 : // Print out universe information
1085 64 : auto all_univs = getAllUniverses();
1086 224 : for (const CSGUniverse & u : all_univs)
1087 : {
1088 160 : const auto & univ_name = u.getName();
1089 160 : const auto & univ_cells = u.getAllCells();
1090 160 : csg_json["universes"][univ_name]["cells"] = {};
1091 360 : for (const CSGCell & c : univ_cells)
1092 200 : csg_json["universes"][univ_name]["cells"].push_back(c.getName());
1093 160 : if (u.isRoot())
1094 64 : csg_json["universes"][univ_name]["root"] = u.isRoot();
1095 : // include any information about transformations if present
1096 160 : if (u.getTransformations().size())
1097 0 : csg_json["universes"][univ_name]["transformations"] = u.getTransformationsAsStrings();
1098 : }
1099 :
1100 : // print out lattice information if lattices exist
1101 64 : auto all_lats = getAllLattices();
1102 64 : if (all_lats.size())
1103 : {
1104 32 : csg_json["lattices"] = {};
1105 80 : for (const CSGLattice & lat : all_lats)
1106 : {
1107 48 : const auto & lat_name = lat.getName();
1108 48 : csg_json["lattices"][lat_name] = {};
1109 48 : csg_json["lattices"][lat_name]["type"] = lat.getType();
1110 48 : const auto & outer_type = lat.getOuterType();
1111 48 : csg_json["lattices"][lat_name]["outertype"] = outer_type;
1112 48 : if (outer_type == "UNIVERSE")
1113 16 : csg_json["lattices"][lat_name]["outer"] = lat.getOuterUniverse().getName();
1114 32 : else if (outer_type == "CSG_MATERIAL")
1115 0 : csg_json["lattices"][lat_name]["outer"] = lat.getOuterMaterial();
1116 : // write out any additional attributes
1117 48 : csg_json["lattices"][lat_name]["attributes"] = {};
1118 48 : const auto & lat_attrs = lat.getAttributes();
1119 192 : for (const auto & attr : lat_attrs)
1120 144 : csg_json["lattices"][lat_name]["attributes"][attr.first] = attr.second;
1121 : // write the map of universe names: list of lists
1122 48 : csg_json["lattices"][lat_name]["universes"] = lat.getUniverseNameMap();
1123 : // include any information about transformations if present
1124 48 : if (lat.getTransformations().size())
1125 0 : csg_json["lattices"][lat_name]["transformations"] = lat.getTransformationsAsStrings();
1126 48 : }
1127 : }
1128 :
1129 128 : return csg_json;
1130 3040 : }
1131 :
1132 : bool
1133 8 : CSGBase::operator==(const CSGBase & other) const
1134 : {
1135 8 : const auto & surf_list = this->getSurfaceList();
1136 8 : const auto & other_surf_list = other.getSurfaceList();
1137 8 : const auto & cell_list = this->getCellList();
1138 8 : const auto & other_cell_list = other.getCellList();
1139 8 : const auto & univ_list = this->getUniverseList();
1140 8 : const auto & other_univ_list = other.getUniverseList();
1141 8 : const auto & lat_list = this->getLatticeList();
1142 8 : const auto & other_lat_list = other.getLatticeList();
1143 14 : return (surf_list == other_surf_list) && (cell_list == other_cell_list) &&
1144 14 : (univ_list == other_univ_list) && (lat_list == other_lat_list);
1145 : }
1146 :
1147 : bool
1148 4 : CSGBase::operator!=(const CSGBase & other) const
1149 : {
1150 4 : return !(*this == other);
1151 : }
1152 : } // namespace CSG
|