OpenMC/include/openmc/lattice.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

322 lines
10 KiB
C
Raw Permalink Normal View History

2018-08-08 13:54:33 -05:00
#ifndef OPENMC_LATTICE_H
#define OPENMC_LATTICE_H
2018-02-04 23:15:32 -05:00
#include <cstdint>
#include <string>
2018-05-27 13:38:16 -04:00
#include <unordered_map>
2018-02-04 23:15:32 -05:00
#include "hdf5.h"
2018-06-20 10:56:28 -05:00
#include "pugixml.hpp"
2018-02-04 23:15:32 -05:00
#include "openmc/array.h"
#include "openmc/constants.h"
#include "openmc/memory.h"
#include "openmc/position.h"
#include "openmc/vector.h"
2018-02-04 23:15:32 -05:00
namespace openmc {
//==============================================================================
2018-04-29 20:23:41 -04:00
// Module constants
2018-02-07 12:24:25 -05:00
//==============================================================================
constexpr int32_t NO_OUTER_UNIVERSE {-1};
2018-08-21 11:02:14 -04:00
enum class LatticeType { rect, hex };
2018-02-04 23:15:32 -05:00
//==============================================================================
// Global variables
//==============================================================================
class Lattice;
2018-11-08 13:41:23 -06:00
namespace model {
extern std::unordered_map<int32_t, int32_t> lattice_map;
extern vector<unique_ptr<Lattice>> lattices;
2018-11-08 13:41:23 -06:00
} // namespace model
2018-02-04 23:15:32 -05:00
//==============================================================================
2018-05-27 13:38:16 -04:00
//! \class Lattice
//! \brief Abstract type for ordered array of universes.
2018-02-04 23:15:32 -05:00
//==============================================================================
2018-05-11 01:28:38 -04:00
class LatticeIter;
2018-05-25 20:32:17 -04:00
class ReverseLatticeIter;
2018-02-04 23:15:32 -05:00
class Lattice {
public:
int32_t id_; //!< Universe ID number
std::string name_; //!< User-defined name
LatticeType type_;
vector<int32_t> universes_; //!< Universes filling each lattice tile
int32_t outer_ {NO_OUTER_UNIVERSE}; //!< Universe tiled outside the lattice
vector<int32_t> offsets_; //!< Distribcell offset table
2018-02-04 23:15:32 -05:00
explicit Lattice(pugi::xml_node lat_node);
virtual ~Lattice() {}
virtual const int32_t& operator[](const array<int, 3>& i_xyz) = 0;
2018-05-11 01:28:38 -04:00
virtual LatticeIter begin();
virtual LatticeIter end();
virtual int32_t& back();
2018-05-11 01:28:38 -04:00
2018-05-25 20:32:17 -04:00
virtual ReverseLatticeIter rbegin();
virtual ReverseLatticeIter rend();
2018-05-25 20:32:17 -04:00
2018-06-11 15:00:18 -04:00
//! Convert internal universe values from IDs to indices using universe_map.
2018-05-11 01:28:38 -04:00
void adjust_indices();
2018-04-29 20:23:41 -04:00
2018-05-21 16:32:44 -04:00
//! Allocate offset table for distribcell.
2018-05-27 13:38:16 -04:00
void allocate_offset_table(int n_maps)
{
offsets_.resize(n_maps * universes_.size());
std::fill(offsets_.begin(), offsets_.end(), C_NONE);
}
2018-05-21 16:32:44 -04:00
2018-05-27 13:38:16 -04:00
//! Populate the distribcell offset tables.
int32_t fill_offset_table(int32_t target_univ_id, int map,
2020-02-29 19:17:20 -05:00
std::unordered_map<int32_t, int32_t>& univ_count_memo);
2018-05-21 16:32:44 -04:00
2018-05-27 13:38:16 -04:00
//! \brief Check lattice indices.
2018-08-08 13:54:33 -05:00
//! \param i_xyz[3] The indices for a lattice tile.
//! \return true if the given indices fit within the lattice bounds. False
//! otherwise.
virtual bool are_valid_indices(const array<int, 3>& i_xyz) const = 0;
2018-05-27 13:38:16 -04:00
//! \brief Find the next lattice surface crossing
2018-08-08 13:54:33 -05:00
//! \param r A 3D Cartesian coordinate.
//! \param u A 3D Cartesian direction.
2018-08-24 19:48:10 -04:00
//! \param i_xyz The indices for a lattice tile.
2018-08-08 13:54:33 -05:00
//! \return The distance to the next crossing and an array indicating how the
//! lattice indices would change after crossing that boundary.
virtual std::pair<double, array<int, 3>> distance(
Position r, Direction u, const array<int, 3>& i_xyz) const = 0;
2018-05-27 13:38:16 -04:00
//! \brief Find the lattice tile indices for a given point.
2018-08-08 13:54:33 -05:00
//! \param r A 3D Cartesian coordinate.
//! \param u Direction of a particle
//! \param result resulting indices to save to
virtual void get_indices(
Position r, Direction u, array<int, 3>& result) const = 0;
2018-02-04 23:15:32 -05:00
//! \brief Compute the the flat index for a set of lattice cell indices
2022-02-09 23:32:41 -06:00
//! \param i_xyz The indices for a lattice cell.
//! \return Flat index into the universes vector.
virtual int get_flat_index(const array<int, 3>& i_xyz) const = 0;
2018-05-27 13:38:16 -04:00
//! \brief Get coordinates local to a lattice tile.
2018-08-08 13:54:33 -05:00
//! \param r A 3D Cartesian coordinate.
2018-08-24 19:48:10 -04:00
//! \param i_xyz The indices for a lattice tile.
2018-08-08 13:54:33 -05:00
//! \return Local 3D Cartesian coordinates.
virtual Position get_local_position(
Position r, const array<int, 3>& i_xyz) const = 0;
//! \brief get the normal of the lattice surface crossing
//! \param[in] i_xyz The indices for the lattice translation.
//! \param[out] is_valid is the lattice translation correspond to a valid
//! surface. \return The surface normal corresponding to the lattice
//! translation.
virtual Direction get_normal(
const array<int, 3>& i_xyz, bool& is_valid) const = 0;
2018-05-27 13:38:16 -04:00
//! \brief Check flattened lattice index.
2018-08-08 13:54:33 -05:00
//! \param indx The index for a lattice tile.
//! \return true if the given index fit within the lattice bounds. False
2018-05-11 01:28:38 -04:00
//! otherwise.
virtual bool is_valid_index(int indx) const
{
return (indx >= 0) && (indx < universes_.size());
}
2018-05-11 01:28:38 -04:00
2018-05-27 13:38:16 -04:00
//! \brief Get the distribcell offset for a lattice tile.
2018-08-08 13:54:33 -05:00
//! \param The map index for the target cell.
//! \param i_xyz[3] The indices for a lattice tile.
//! \return Distribcell offset i.e. the largest instance number for the target
2018-05-21 16:32:44 -04:00
//! cell found in the geometry tree under this lattice tile.
virtual int32_t& offset(int map, const array<int, 3>& i_xyz) = 0;
2018-05-21 16:32:44 -04:00
2020-05-14 13:44:12 -05:00
//! \brief Get the distribcell offset for a lattice tile.
//! \param The map index for the target cell.
//! \param indx The index for a lattice tile.
//! \return Distribcell offset i.e. the largest instance number for the target
//! cell found in the geometry tree for this lattice index.
2020-06-02 09:10:13 -05:00
virtual int32_t offset(int map, int indx) const = 0;
2020-05-14 13:44:12 -05:00
2018-05-27 13:38:16 -04:00
//! \brief Convert an array index to a useful human-readable string.
2018-08-08 13:54:33 -05:00
//! \param indx The index for a lattice tile.
//! \return A string representing the lattice tile.
2018-05-25 20:32:17 -04:00
virtual std::string index_to_string(int indx) const = 0;
2018-05-27 13:38:16 -04:00
//! \brief Write lattice information to an HDF5 group.
2018-08-08 13:54:33 -05:00
//! \param group_id An HDF5 group id.
2018-02-04 23:15:32 -05:00
void to_hdf5(hid_t group_id) const;
2018-02-07 12:24:25 -05:00
protected:
bool is_3d_; //!< Has divisions along the z-axis?
2018-04-29 21:21:39 -04:00
virtual void to_hdf5_inner(hid_t group_id) const = 0;
2018-02-04 23:15:32 -05:00
};
2018-05-25 20:32:17 -04:00
//==============================================================================
//! An iterator over lattice universes.
//==============================================================================
2018-05-11 01:28:38 -04:00
class LatticeIter {
public:
int indx_; //!< An index to a Lattice universes or offsets array.
2018-05-25 20:32:17 -04:00
LatticeIter(Lattice& lat, int indx) : indx_(indx), lat_(lat) {}
2018-05-11 01:28:38 -04:00
bool operator==(const LatticeIter& rhs) { return (indx_ == rhs.indx_); }
2018-05-11 01:28:38 -04:00
2018-05-27 13:38:16 -04:00
bool operator!=(const LatticeIter& rhs) { return !(*this == rhs); }
2018-05-11 01:28:38 -04:00
int32_t& operator*() { return lat_.universes_[indx_]; }
2018-05-11 01:28:38 -04:00
LatticeIter& operator++()
{
while (indx_ < lat_.end().indx_) {
++indx_;
if (lat_.is_valid_index(indx_))
return *this;
2018-05-11 01:28:38 -04:00
}
indx_ = lat_.end().indx_;
2018-05-11 01:28:38 -04:00
return *this;
}
2018-05-25 20:32:17 -04:00
protected:
Lattice& lat_;
2018-05-11 01:28:38 -04:00
};
2018-05-25 20:32:17 -04:00
//==============================================================================
//! A reverse iterator over lattice universes.
//==============================================================================
class ReverseLatticeIter : public LatticeIter {
public:
ReverseLatticeIter(Lattice& lat, int indx) : LatticeIter {lat, indx} {}
2018-05-25 20:32:17 -04:00
ReverseLatticeIter& operator++()
{
while (indx_ > lat_.begin().indx_ - 1) {
--indx_;
if (lat_.is_valid_index(indx_))
return *this;
2018-05-25 20:32:17 -04:00
}
indx_ = -1;
2018-05-25 20:32:17 -04:00
return *this;
}
};
2018-02-04 23:15:32 -05:00
//==============================================================================
class RectLattice : public Lattice {
public:
explicit RectLattice(pugi::xml_node lat_node);
const int32_t& operator[](const array<int, 3>& i_xyz) override;
2018-04-29 20:23:41 -04:00
bool are_valid_indices(const array<int, 3>& i_xyz) const override;
std::pair<double, array<int, 3>> distance(
2023-02-16 14:06:59 -06:00
Position r, Direction u, const array<int, 3>& i_xyz) const override;
2023-02-16 14:06:59 -06:00
void get_indices(
Position r, Direction u, array<int, 3>& result) const override;
2018-02-16 18:25:52 -05:00
2023-02-16 14:06:59 -06:00
int get_flat_index(const array<int, 3>& i_xyz) const override;
2023-02-16 14:06:59 -06:00
Position get_local_position(
Position r, const array<int, 3>& i_xyz) const override;
Direction get_normal(
const array<int, 3>& i_xyz, bool& is_valid) const override;
int32_t& offset(int map, const array<int, 3>& i_xyz) override;
2018-05-21 16:32:44 -04:00
2023-02-16 14:06:59 -06:00
int32_t offset(int map, int indx) const override;
2020-05-14 13:44:12 -05:00
2023-02-16 14:06:59 -06:00
std::string index_to_string(int indx) const override;
2018-05-25 20:32:17 -04:00
2023-02-16 14:06:59 -06:00
void to_hdf5_inner(hid_t group_id) const override;
2018-04-29 21:21:39 -04:00
2018-05-27 13:38:16 -04:00
private:
array<int, 3> n_cells_; //!< Number of cells along each axis
Position lower_left_; //!< Global lower-left corner of the lattice
Position pitch_; //!< Lattice tile width along each axis
2018-02-04 23:15:32 -05:00
};
2018-05-10 23:17:19 -04:00
//==============================================================================
2018-02-04 23:15:32 -05:00
class HexLattice : public Lattice {
public:
explicit HexLattice(pugi::xml_node lat_node);
const int32_t& operator[](const array<int, 3>& i_xyz) override;
2018-04-29 20:23:41 -04:00
2023-02-16 14:06:59 -06:00
LatticeIter begin() override;
2018-04-29 20:23:41 -04:00
2023-02-16 14:06:59 -06:00
ReverseLatticeIter rbegin() override;
2018-05-25 20:32:17 -04:00
LatticeIter end() override;
int32_t& back() override;
ReverseLatticeIter rend() override;
bool are_valid_indices(const array<int, 3>& i_xyz) const override;
std::pair<double, array<int, 3>> distance(
2023-02-16 14:06:59 -06:00
Position r, Direction u, const array<int, 3>& i_xyz) const override;
2023-02-16 14:06:59 -06:00
void get_indices(
Position r, Direction u, array<int, 3>& result) const override;
2023-02-16 14:06:59 -06:00
int get_flat_index(const array<int, 3>& i_xyz) const override;
2023-02-16 14:06:59 -06:00
Position get_local_position(
Position r, const array<int, 3>& i_xyz) const override;
2018-02-15 14:55:06 -05:00
Direction get_normal(
const array<int, 3>& i_xyz, bool& is_valid) const override;
2023-02-16 14:06:59 -06:00
bool is_valid_index(int indx) const override;
2018-05-11 01:28:38 -04:00
int32_t& offset(int map, const array<int, 3>& i_xyz) override;
2018-05-21 16:32:44 -04:00
2023-02-16 14:06:59 -06:00
int32_t offset(int map, int indx) const override;
2020-05-14 13:44:12 -05:00
2023-02-16 14:06:59 -06:00
std::string index_to_string(int indx) const override;
2023-02-16 14:06:59 -06:00
void to_hdf5_inner(hid_t group_id) const override;
2018-04-29 21:21:39 -04:00
2018-05-27 13:38:16 -04:00
private:
2019-05-31 02:38:06 +03:00
enum class Orientation {
y, //!< Flat side of lattice parallel to y-axis
x //!< Flat side of lattice parallel to x-axis
};
//! Fill universes_ vector for 'y' orientation
void fill_lattice_y(const vector<std::string>& univ_words);
//! Fill universes_ vector for 'x' orientation
void fill_lattice_x(const vector<std::string>& univ_words);
int n_rings_; //!< Number of radial tile positions
int n_axial_; //!< Number of axial tile positions
Orientation orientation_; //!< Orientation of lattice
Position center_; //!< Global center of lattice
array<double, 2> pitch_; //!< Lattice tile width and height
2018-02-04 23:15:32 -05:00
};
2019-02-15 06:35:59 -06:00
//==============================================================================
// Non-member functions
//==============================================================================
void read_lattices(pugi::xml_node node);
2018-02-04 23:15:32 -05:00
} // namespace openmc
2018-08-08 13:54:33 -05:00
#endif // OPENMC_LATTICE_H