• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

openmc-dev / openmc / 19058781736

04 Nov 2025 05:26AM UTC coverage: 82.008% (-3.1%) from 85.155%
19058781736

Pull #3252

github

web-flow
Merge b8a72730f into bd76fc056
Pull Request #3252: Adding vtkhdf option to write vtk data

16714 of 23236 branches covered (71.93%)

Branch coverage included in aggregate %.

61 of 66 new or added lines in 1 file covered. (92.42%)

3175 existing lines in 103 files now uncovered.

54243 of 63288 relevant lines covered (85.71%)

43393337.77 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.47
/include/openmc/cell.h
1
#ifndef OPENMC_CELL_H
2
#define OPENMC_CELL_H
3

4
#include <cstdint>
5
#include <functional> // for hash
6
#include <limits>
7
#include <string>
8
#include <unordered_map>
9
#include <unordered_set>
10

11
#include "hdf5.h"
12
#include "pugixml.hpp"
13

14
#include "openmc/bounding_box.h"
15
#include "openmc/constants.h"
16
#include "openmc/memory.h" // for unique_ptr
17
#include "openmc/neighbor_list.h"
18
#include "openmc/position.h"
19
#include "openmc/surface.h"
20
#include "openmc/universe.h"
21
#include "openmc/vector.h"
22

23
namespace openmc {
24

25
//==============================================================================
26
// Constants
27
//==============================================================================
28

29
enum class Fill { MATERIAL, UNIVERSE, LATTICE };
30

31
constexpr int32_t OP_LEFT_PAREN {std::numeric_limits<int32_t>::max()};
32
constexpr int32_t OP_RIGHT_PAREN {std::numeric_limits<int32_t>::max() - 1};
33
constexpr int32_t OP_COMPLEMENT {std::numeric_limits<int32_t>::max() - 2};
34
constexpr int32_t OP_INTERSECTION {std::numeric_limits<int32_t>::max() - 3};
35
constexpr int32_t OP_UNION {std::numeric_limits<int32_t>::max() - 4};
36

37
//==============================================================================
38
// Global variables
39
//==============================================================================
40

41
class Cell;
42
class GeometryState;
43
class ParentCell;
44
class CellInstance;
45
class Universe;
46
class UniversePartitioner;
47

48
namespace model {
49
extern std::unordered_map<int32_t, int32_t> cell_map;
50
extern vector<unique_ptr<Cell>> cells;
51

52
} // namespace model
53

54
//==============================================================================
55

56
class Region {
57
public:
58
  //----------------------------------------------------------------------------
59
  // Constructors
60
  Region() {}
33,925✔
61
  explicit Region(std::string region_spec, int32_t cell_id);
62

63
  //----------------------------------------------------------------------------
64
  // Methods
65

66
  //! \brief Determine if a cell contains the particle at a given location.
67
  //!
68
  //! The bounds of the cell are determined by a logical expression involving
69
  //! surface half-spaces. The expression used is given in infix notation
70
  //!
71
  //! The function is split into two cases, one for simple cells (those
72
  //! involving only the intersection of half-spaces) and one for complex cells.
73
  //! Both cases use short circuiting; however, in the case fo complex cells,
74
  //! the complexity increases with the binary operators involved.
75
  //! \param r The 3D Cartesian coordinate to check.
76
  //! \param u A direction used to "break ties" the coordinates are very
77
  //!   close to a surface.
78
  //! \param on_surface The signed index of a surface that the coordinate is
79
  //!   known to be on.  This index takes precedence over surface sense
80
  //!   calculations.
81
  bool contains(Position r, Direction u, int32_t on_surface) const;
82

83
  //! Find the oncoming boundary of this cell.
84
  std::pair<double, int32_t> distance(
85
    Position r, Direction u, int32_t on_surface) const;
86

87
  //! Get the BoundingBox for this cell.
88
  BoundingBox bounding_box(int32_t cell_id) const;
89

90
  //! Get the CSG expression as a string
91
  std::string str() const;
92

93
  //! Get a vector containing all the surfaces in the region expression
94
  vector<int32_t> surfaces() const;
95

96
  //----------------------------------------------------------------------------
97
  // Accessors
98

99
  //! Get Boolean of if the cell is simple or not
100
  bool is_simple() const { return simple_; }
2,147,483,647✔
101

102
private:
103
  //----------------------------------------------------------------------------
104
  // Private Methods
105

106
  //! Get a vector of the region expression in postfix notation
107
  vector<int32_t> generate_postfix(int32_t cell_id) const;
108

109
  //! Determine if a particle is inside the cell for a simple cell (only
110
  //! intersection operators)
111
  bool contains_simple(Position r, Direction u, int32_t on_surface) const;
112

113
  //! Determine if a particle is inside the cell for a complex cell.
114
  //!
115
  //! Uses the comobination of half-spaces and binary operators to determine
116
  //! if short circuiting can be used. Short cicuiting uses the relative and
117
  //! absolute depth of parentheses in the expression.
118
  bool contains_complex(Position r, Direction u, int32_t on_surface) const;
119

120
  //! BoundingBox if the paritcle is in a simple cell.
121
  BoundingBox bounding_box_simple() const;
122

123
  //! BoundingBox if the particle is in a complex cell.
124
  BoundingBox bounding_box_complex(vector<int32_t> postfix) const;
125

126
  //! Enfource precedence: Parenthases, Complement, Intersection, Union
127
  void add_precedence();
128

129
  //! Add parenthesis to enforce precedence
130
  int64_t add_parentheses(int64_t start);
131

132
  //! Remove complement operators from the expression
133
  void remove_complement_ops();
134

135
  //! Remove complement operators by using DeMorgan's laws
136
  void apply_demorgan(
137
    vector<int32_t>::iterator start, vector<int32_t>::iterator stop);
138

139
  //----------------------------------------------------------------------------
140
  // Private Data
141

142
  //! Definition of spatial region as Boolean expression of half-spaces
143
  // TODO: Should this be a vector of some other type
144
  vector<int32_t> expression_;
145
  bool simple_; //!< Does the region contain only intersections?
146
};
147

148
//==============================================================================
149

150
class Cell {
151
public:
152
  //----------------------------------------------------------------------------
153
  // Constructors, destructors, factory functions
154

155
  explicit Cell(pugi::xml_node cell_node);
156
  Cell() {};
34,332✔
157
  virtual ~Cell() = default;
34,330✔
158

159
  //----------------------------------------------------------------------------
160
  // Methods
161

162
  //! \brief Determine if a cell contains the particle at a given location.
163
  //!
164
  //! The bounds of the cell are detemined by a logical expression involving
165
  //! surface half-spaces. At initialization, the expression was converted
166
  //! to RPN notation.
167
  //!
168
  //! The function is split into two cases, one for simple cells (those
169
  //! involving only the intersection of half-spaces) and one for complex cells.
170
  //! Simple cells can be evaluated with short circuit evaluation, i.e., as soon
171
  //! as we know that one half-space is not satisfied, we can exit. This
172
  //! provides a performance benefit for the common case. In
173
  //! contains_complex, we evaluate the RPN expression using a stack, similar to
174
  //! how a RPN calculator would work.
175
  //! \param r The 3D Cartesian coordinate to check.
176
  //! \param u A direction used to "break ties" the coordinates are very
177
  //!   close to a surface.
178
  //! \param on_surface The signed index of a surface that the coordinate is
179
  //!   known to be on.  This index takes precedence over surface sense
180
  //!   calculations.
181
  virtual bool contains(Position r, Direction u, int32_t on_surface) const = 0;
182

183
  //! Find the oncoming boundary of this cell.
184
  virtual std::pair<double, int32_t> distance(
185
    Position r, Direction u, int32_t on_surface, GeometryState* p) const = 0;
186

187
  //! Write all information needed to reconstruct the cell to an HDF5 group.
188
  //! \param group_id An HDF5 group id.
189
  void to_hdf5(hid_t group_id) const;
190

191
  virtual void to_hdf5_inner(hid_t group_id) const = 0;
192

193
  //! Export physical properties to HDF5
194
  //! \param[in] group  HDF5 group to read from
195
  void export_properties_hdf5(hid_t group) const;
196

197
  //! Import physical properties from HDF5
198
  //! \param[in] group  HDF5 group to write to
199
  void import_properties_hdf5(hid_t group);
200

201
  //! Get the BoundingBox for this cell.
202
  virtual BoundingBox bounding_box() const = 0;
203

204
  //! Get a vector of surfaces in the cell
UNCOV
205
  virtual vector<int32_t> surfaces() const { return vector<int32_t>(); }
×
206

207
  //! Check if the cell region expression is simple
208
  virtual bool is_simple() const { return true; }
102,997✔
209

210
  //----------------------------------------------------------------------------
211
  // Accessors
212

213
  //! Get the temperature of a cell instance
214
  //! \param[in] instance Instance index. If -1 is given, the temperature for
215
  //!   the first instance is returned.
216
  //! \return Temperature in [K]
217
  double temperature(int32_t instance = -1) const;
218

219
  //! Get the density multiplier of a cell instance
220
  //! \param[in] instance Instance index. If -1 is given, the density multiplier
221
  //! for the first instance is returned.
222
  //! \return Density multiplier
223
  double density_mult(int32_t instance = -1) const;
224

225
  //! Get the density of a cell instance in g/cm3
226
  //! \param[in] instance Instance index. If -1 is given, the density
227
  //! for the first instance is returned.
228
  //! \return Density in [g/cm3]
229
  double density(int32_t instance = -1) const;
230

231
  //! Set the temperature of a cell instance
232
  //! \param[in] T Temperature in [K]
233
  //! \param[in] instance Instance index. If -1 is given, the temperature for
234
  //!   all instances is set.
235
  //! \param[in] set_contained If this cell is not filled with a material,
236
  //!   collect all contained cells with material fills and set their
237
  //!   temperatures.
238
  void set_temperature(
239
    double T, int32_t instance = -1, bool set_contained = false);
240

241
  //! Set the density of a cell instance
242
  //! \param[in] density Density [g/cm3]
243
  //! \param[in] instance Instance index. If -1 is given, the density
244
  //!   for all instances is set.
245
  //! \param[in] set_contained If this cell is not filled with a material,
246
  //!   collect all contained cells with material fills and set their
247
  //!   densities.
248
  void set_density(
249
    double density, int32_t instance = -1, bool set_contained = false);
250

251
  int32_t n_instances() const;
252

253
  //! Set the rotation matrix of a cell instance
254
  //! \param[in] rot The rotation matrix of length 3 or 9
255
  void set_rotation(const vector<double>& rot);
256

257
  //! Get the name of a cell
258
  //! \return Cell name
259
  const std::string& name() const { return name_; };
303✔
260

261
  //! Set the temperature of a cell instance
262
  //! \param[in] name Cell name
263
  void set_name(const std::string& name) { name_ = name; };
15✔
264

265
  //! Get all cell instances contained by this cell
266
  //! \param[in] instance Instance of the cell for which to get contained cells
267
  //! (default instance is zero)
268
  //! \param[in] hint positional hint for determining the parent cells
269
  //! \return Map with cell indexes as keys and
270
  //! instances as values
271
  std::unordered_map<int32_t, vector<int32_t>> get_contained_cells(
272
    int32_t instance = 0, Position* hint = nullptr) const;
273

274
  //! Determine the material index corresponding to a specific cell instance,
275
  //! taking into account presence of distribcell material
276
  //! \param[in] instance of the cell
277
  //! \return material index
278
  int32_t material(int32_t instance) const
2,147,483,647✔
279
  {
280
    // If distributed materials are used, then each instance has its own
281
    // material definition. If distributed materials are not used, then
282
    // all instances used the same material stored at material_[0]. The
283
    // presence of distributed materials is inferred from the size of
284
    // the material_ vector being greater than one.
285
    if (material_.size() > 1) {
2,147,483,647✔
286
      return material_[instance];
15,770,893✔
287
    } else {
288
      return material_[0];
2,147,483,647✔
289
    }
290
  }
291

292
  //! Determine the temperature index corresponding to a specific cell instance,
293
  //! taking into account presence of distribcell temperature
294
  //! \param[in] instance of the cell
295
  //! \return temperature index
296
  double sqrtkT(int32_t instance) const
2,147,483,647✔
297
  {
298
    // If distributed materials are used, then each instance has its own
299
    // temperature definition. If distributed materials are not used, then
300
    // all instances used the same temperature stored at sqrtkT_[0]. The
301
    // presence of distributed materials is inferred from the size of
302
    // the sqrtkT_ vector being greater than one.
303
    if (sqrtkT_.size() > 1) {
2,147,483,647✔
304
      return sqrtkT_[instance];
12,163,230✔
305
    } else {
306
      return sqrtkT_[0];
2,147,483,647✔
307
    }
308
  }
309

310
protected:
311
  //! Determine the path to this cell instance in the geometry hierarchy
312
  //! \param[in] instance of the cell to find parent cells for
313
  //! \param[in] r position used to do a fast search for parent cells
314
  //! \return parent cells
315
  vector<ParentCell> find_parent_cells(
316
    int32_t instance, const Position& r) const;
317

318
  //! Determine the path to this cell instance in the geometry hierarchy
319
  //! \param[in] instance of the cell to find parent cells for
320
  //! \param[in] p particle used to do a fast search for parent cells
321
  //! \return parent cells
322
  vector<ParentCell> find_parent_cells(
323
    int32_t instance, GeometryState& p) const;
324

325
  //! Determine the path to this cell instance in the geometry hierarchy
326
  //! \param[in] instance of the cell to find parent cells for
327
  //! \return parent cells
328
  vector<ParentCell> exhaustive_find_parent_cells(int32_t instance) const;
329

330
  //! Inner function for retrieving contained cells
331
  void get_contained_cells_inner(
332
    std::unordered_map<int32_t, vector<int32_t>>& contained_cells,
333
    vector<ParentCell>& parent_cells) const;
334

335
public:
336
  //----------------------------------------------------------------------------
337
  // Data members
338

339
  int32_t id_;       //!< Unique ID
340
  std::string name_; //!< User-defined name
341
  Fill type_;        //!< Material, universe, or lattice
342
  int32_t universe_; //!< Universe # this cell is in
343
  int32_t fill_;     //!< Universe # filling this cell
344

345
  //! \brief Index corresponding to this cell in distribcell arrays
346
  int distribcell_index_ {C_NONE};
347

348
  //! \brief Material(s) within this cell.
349
  //!
350
  //! May be multiple materials for distribcell.
351
  vector<int32_t> material_;
352

353
  //! \brief Temperature(s) within this cell.
354
  //!
355
  //! The stored values are actually sqrt(k_Boltzmann * T) for each temperature
356
  //! T. The units are sqrt(eV).
357
  vector<double> sqrtkT_;
358

359
  //! \brief Unitless density multiplier(s) within this cell.
360
  vector<double> density_mult_;
361

362
  //! \brief Neighboring cells in the same universe.
363
  NeighborList neighbors_;
364

365
  Position translation_ {0, 0, 0}; //!< Translation vector for filled universe
366

367
  //! \brief Rotational tranfsormation of the filled universe.
368
  //
369
  //! The vector is empty if there is no rotation. Otherwise, the first 9 values
370
  //! give the rotation matrix in row-major order. When the user specifies
371
  //! rotation angles about the x-, y- and z- axes in degrees, these values are
372
  //! also present at the end of the vector, making it of length 12.
373
  vector<double> rotation_;
374

375
  vector<int32_t> offset_; //!< Distribcell offset table
376

377
  // Right now, either CSG or DAGMC cells are used.
378
  virtual GeometryType geom_type() const = 0;
379
};
380

381
struct CellInstanceItem {
382
  int32_t index {-1};    //! Index into global cells array
383
  int lattice_indx {-1}; //! Flat index value of the lattice cell
384
};
385

386
//==============================================================================
387

388
class CSGCell : public Cell {
389
public:
390
  //----------------------------------------------------------------------------
391
  // Constructors
392
  CSGCell() = default;
30✔
393
  explicit CSGCell(pugi::xml_node cell_node);
394

395
  //----------------------------------------------------------------------------
396
  // Methods
397
  vector<int32_t> surfaces() const override { return region_.surfaces(); }
5,389✔
398

399
  std::pair<double, int32_t> distance(Position r, Direction u,
2,147,483,647✔
400
    int32_t on_surface, GeometryState* p) const override
401
  {
402
    return region_.distance(r, u, on_surface);
2,147,483,647✔
403
  }
404

405
  bool contains(Position r, Direction u, int32_t on_surface) const override
2,147,483,647✔
406
  {
407
    return region_.contains(r, u, on_surface);
2,147,483,647✔
408
  }
409

410
  BoundingBox bounding_box() const override
240✔
411
  {
412
    return region_.bounding_box(id_);
240✔
413
  }
414

415
  void to_hdf5_inner(hid_t group_id) const override;
416

417
  bool is_simple() const override { return region_.is_simple(); }
2,147,483,647✔
418

UNCOV
419
  virtual GeometryType geom_type() const override { return GeometryType::CSG; }
×
420

421
protected:
422
  //! Returns the beginning position of a parenthesis block (immediately before
423
  //! two surface tokens) in the RPN given a starting position at the end of
424
  //! that block (immediately after two surface tokens)
425
  //! \param start Starting position of the search
426
  //! \param rpn The rpn being searched
427
  static vector<int32_t>::iterator find_left_parenthesis(
428
    vector<int32_t>::iterator start, const vector<int32_t>& rpn);
429

430
private:
431
  Region region_;
432
};
433

434
//==============================================================================
435
//! Define an instance of a particular cell
436
//==============================================================================
437

438
//!  Stores information used to identify a unique cell in the model
439
struct CellInstance {
440
  //! Check for equality
441
  bool operator==(const CellInstance& other) const
3,998,558✔
442
  {
443
    return index_cell == other.index_cell && instance == other.instance;
3,998,558!
444
  }
445

446
  int64_t index_cell;
447
  int64_t instance;
448
};
449

450
//! Structure necessary for inserting CellInstance into hashed STL data
451
//! structures
452
struct CellInstanceHash {
453
  std::size_t operator()(const CellInstance& k) const
3,999,208✔
454
  {
455
    return 4096 * k.index_cell + k.instance;
3,999,208✔
456
  }
457
};
458

459
//==============================================================================
460
// Non-member functions
461
//==============================================================================
462

463
void read_cells(pugi::xml_node node);
464

465
//!  Add cells to universes
466
void populate_universes();
467

468
} // namespace openmc
469
#endif // OPENMC_CELL_H
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc