OpenMC/include/openmc/mesh.h

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

957 lines
30 KiB
C
Raw Permalink Normal View History

2018-09-03 14:01:59 -05:00
//! \file mesh.h
//! \brief Mesh types used for tallies, Shannon entropy, CMFD, etc.
2018-08-28 06:59:39 -05:00
#ifndef OPENMC_MESH_H
#define OPENMC_MESH_H
#include <unordered_map>
#include "hdf5.h"
#include "pugixml.hpp"
2023-01-13 00:00:16 -06:00
#include "xtensor/xtensor.hpp"
#include <gsl/gsl-lite.hpp>
2018-08-28 06:59:39 -05:00
#include "openmc/error.h"
#include "openmc/memory.h" // for unique_ptr
#include "openmc/particle.h"
2018-08-28 06:59:39 -05:00
#include "openmc/position.h"
#include "openmc/vector.h"
#include "openmc/xml_interface.h"
2018-08-28 06:59:39 -05:00
#ifdef DAGMC
2019-05-02 20:12:51 -05:00
#include "moab/AdaptiveKDTree.hpp"
2019-05-03 10:53:50 -05:00
#include "moab/Core.hpp"
2019-05-14 22:05:55 -05:00
#include "moab/GeomUtil.hpp"
2019-05-02 20:12:51 -05:00
#include "moab/Matrix3.hpp"
#endif
2019-12-05 22:29:47 -06:00
#ifdef LIBMESH
#include "libmesh/bounding_box.h"
2020-04-09 13:29:55 -05:00
#include "libmesh/dof_map.h"
2019-12-17 20:44:56 -06:00
#include "libmesh/elem.h"
#include "libmesh/equation_systems.h"
#include "libmesh/exodusII_io.h"
#include "libmesh/explicit_system.h"
2020-04-09 13:29:55 -05:00
#include "libmesh/libmesh.h"
2019-12-05 22:29:47 -06:00
#include "libmesh/mesh.h"
#include "libmesh/point.h"
2019-12-05 22:29:47 -06:00
#endif
2018-08-28 06:59:39 -05:00
namespace openmc {
Adding more mesh interrogation options for the libmesh Finishing methods for connectivity and coordinates. Writing vertices and connectivity to statepoint file Loading vertices and connectivity from statepoint. Correcting string repr Correcting connectivity length Adding method to write the mesh elements to VTK with data applied. Updating hdf5 output to include element types Adding support for hex elements when writing unstructured meshes to VTK Adding simple check for VTK writing if the module is present Removing centroids from the statepoint file and Python UM class Updating test check for vtk Adding warning for skipped elements. Correcting element type Adding warning for skipped elements. Using an enum to indicate element types for readability Updating to element types on the Python side as well Handling integer data applied to VTK files. Doc updates for Python API UM class Incrementing statepoint version number Refactor of unstructured mesh tests to extract model Updating inputs for floating point surface coefficients Adding test for hexes and refactoring comparison funcs Updating reference mesh files Adding reference file for the hexes test case Passing test for hex mesh Adding inputs for the hexes test case. Adding hex test meshes. Skipping hex mesh test if not built with libmesh Adding small VTK write tests for unstructured mesh. Allowing file path to be a pathlib path. Adding skips if libmesh or dagmc not enabled Adding a few comments to test file Changing where conversion to str happens for mesh filename. Setting output to false. Removing VTK check from unstructured mesh regression test Removnig VTK test files for regression test -- too large Adding __init__.py file for pytest
2022-05-31 08:33:43 -05:00
//==============================================================================
// Constants
//==============================================================================
2023-01-13 00:00:16 -06:00
enum class ElementType { UNSUPPORTED = -1, LINEAR_TET, LINEAR_HEX };
Adding more mesh interrogation options for the libmesh Finishing methods for connectivity and coordinates. Writing vertices and connectivity to statepoint file Loading vertices and connectivity from statepoint. Correcting string repr Correcting connectivity length Adding method to write the mesh elements to VTK with data applied. Updating hdf5 output to include element types Adding support for hex elements when writing unstructured meshes to VTK Adding simple check for VTK writing if the module is present Removing centroids from the statepoint file and Python UM class Updating test check for vtk Adding warning for skipped elements. Correcting element type Adding warning for skipped elements. Using an enum to indicate element types for readability Updating to element types on the Python side as well Handling integer data applied to VTK files. Doc updates for Python API UM class Incrementing statepoint version number Refactor of unstructured mesh tests to extract model Updating inputs for floating point surface coefficients Adding test for hexes and refactoring comparison funcs Updating reference mesh files Adding reference file for the hexes test case Passing test for hex mesh Adding inputs for the hexes test case. Adding hex test meshes. Skipping hex mesh test if not built with libmesh Adding small VTK write tests for unstructured mesh. Allowing file path to be a pathlib path. Adding skips if libmesh or dagmc not enabled Adding a few comments to test file Changing where conversion to str happens for mesh filename. Setting output to false. Removing VTK check from unstructured mesh regression test Removnig VTK test files for regression test -- too large Adding __init__.py file for pytest
2022-05-31 08:33:43 -05:00
//==============================================================================
// Global variables
//==============================================================================
extern "C" const bool LIBMESH_ENABLED;
2019-05-24 10:50:57 -04:00
class Mesh;
namespace model {
extern std::unordered_map<int32_t, int32_t> mesh_map;
extern vector<unique_ptr<Mesh>> meshes;
} // namespace model
2020-10-30 16:14:49 -05:00
#ifdef LIBMESH
namespace settings {
// used when creating new libMesh::MeshBase instances
extern unique_ptr<libMesh::LibMeshInit> libmesh_init;
extern const libMesh::Parallel::Communicator* libmesh_comm;
2020-10-30 16:14:49 -05:00
} // namespace settings
#endif
2019-11-26 04:57:16 -06:00
class Mesh {
2019-05-24 10:50:57 -04:00
public:
// Types, aliases
struct MaterialVolume {
int32_t material; //!< material index
double volume; //!< volume in [cm^3]
};
// Constructors and destructor
2019-05-24 10:50:57 -04:00
Mesh() = default;
Mesh(pugi::xml_node node);
virtual ~Mesh() = default;
2019-05-24 10:50:57 -04:00
2018-08-28 06:59:39 -05:00
// Methods
//! Perform any preparation needed to support use in mesh filters
virtual void prepare_for_tallies() {};
//! Update a position to the local coordinates of the mesh
2023-03-04 23:57:55 -06:00
virtual void local_coords(Position& r) const {};
//! Return a position in the local coordinates of the mesh
virtual Position local_coords(const Position& r) const { return r; };
//! Sample a position within a mesh element
2022-06-10 13:31:39 -05:00
//
//! \param[in] bin Bin value of the mesh element sampled
//! \param[inout] seed Seed to use for random sampling
//! \return sampled position within mesh element
virtual Position sample_element(int32_t bin, uint64_t* seed) const = 0;
//! Determine which bins were crossed by a particle
//
//! \param[in] r0 Previous position of the particle
//! \param[in] r1 Current position of the particle
//! \param[in] u Particle direction
//! \param[out] bins Bins that were crossed
//! \param[out] lengths Fraction of tracklength in each bin
virtual void bins_crossed(Position r0, Position r1, const Direction& u,
vector<int>& bins, vector<double>& lengths) const = 0;
//! Determine which surface bins were crossed by a particle
//
//! \param[in] r0 Previous position of the particle
//! \param[in] r1 Current position of the particle
//! \param[in] u Particle direction
//! \param[out] bins Surface bins that were crossed
virtual void surface_bins_crossed(
Position r0, Position r1, const Direction& u, vector<int>& bins) const = 0;
//! Get bin at a given position in space
//
//! \param[in] r Position to get bin for
//! \return Mesh bin
2019-05-28 13:23:59 -04:00
virtual int get_bin(Position r) const = 0;
//! Get the number of mesh cells.
virtual int n_bins() const = 0;
//! Get the number of mesh cell surfaces.
virtual int n_surface_bins() const = 0;
int32_t id() const { return id_; }
//! Set the mesh ID
void set_id(int32_t id = -1);
//! Write mesh data to an HDF5 group
//
//! \param[in] group HDF5 group
virtual void to_hdf5(hid_t group) const = 0;
//! Find the mesh lines that intersect an axis-aligned slice plot
//
//! \param[in] plot_ll The lower-left coordinates of the slice plot.
//! \param[in] plot_ur The upper-right coordinates of the slice plot.
//! \return A pair of vectors indicating where the mesh lines lie along each
//! of the plot's axes. For example an xy-slice plot will get back a vector
//! of x-coordinates and another of y-coordinates. These vectors may be
//! empty for low-dimensional meshes.
2021-04-29 16:23:54 -04:00
virtual std::pair<vector<double>, vector<double>> plot(
Position plot_ll, Position plot_ur) const = 0;
//! Return a string representation of the mesh bin
//
//! \param[in] bin Mesh bin to generate a label for
virtual std::string bin_label(int bin) const = 0;
//! Get the volume of a mesh bin
//
//! \param[in] bin Bin to return the volume for
//! \return Volume of the bin
virtual double volume(int bin) const = 0;
//! Volumes of all elements in the mesh in bin ordering
vector<double> volumes() const;
2021-12-22 16:19:58 +01:00
virtual std::string get_mesh_type() const = 0;
//! Determine volume of materials within a single mesh elemenet
//
//! \param[in] n_sample Number of samples within each element
//! \param[in] bin Index of mesh element
//! \param[out] Array of (material index, volume) for desired element
//! \param[inout] seed Pseudorandom number seed
//! \return Number of materials within element
int material_volumes(int n_sample, int bin, gsl::span<MaterialVolume> volumes,
uint64_t* seed) const;
//! Determine volume of materials within a single mesh elemenet
//
//! \param[in] n_sample Number of samples within each element
//! \param[in] bin Index of mesh element
//! \param[inout] seed Pseudorandom number seed
//! \return Vector of (material index, volume) for desired element
vector<MaterialVolume> material_volumes(
int n_sample, int bin, uint64_t* seed) const;
// Data members
int id_ {-1}; //!< User-specified ID
int n_dimension_ {-1}; //!< Number of dimensions
};
class StructuredMesh : public Mesh {
public:
StructuredMesh() = default;
StructuredMesh(pugi::xml_node node) : Mesh {node} {};
virtual ~StructuredMesh() = default;
using MeshIndex = std::array<int, 3>;
2021-12-22 16:19:58 +01:00
struct MeshDistance {
2021-12-22 16:19:58 +01:00
MeshDistance() = default;
MeshDistance(int _index, bool _max_surface, double _distance)
: next_index {_index}, max_surface {_max_surface}, distance {_distance}
{}
int next_index {-1};
bool max_surface {true};
double distance {INFTY};
bool operator<(const MeshDistance& o) const
{
return distance < o.distance;
}
};
Position sample_element(int32_t bin, uint64_t* seed) const override
{
return sample_element(get_indices_from_bin(bin), seed);
};
virtual Position sample_element(const MeshIndex& ijk, uint64_t* seed) const;
int get_bin(Position r) const override;
int n_bins() const override;
int n_surface_bins() const override;
void bins_crossed(Position r0, Position r1, const Direction& u,
vector<int>& bins, vector<double>& lengths) const override;
void surface_bins_crossed(Position r0, Position r1, const Direction& u,
vector<int>& bins) const override;
//! Determine which cell or surface bins were crossed by a particle
//
//! \param[in] r0 Previous position of the particle
//! \param[in] r1 Current position of the particle
//! \param[in] u Particle direction
//! \param[in] tally Functor that eventually stores the tally data
template<class T>
void raytrace_mesh(
Position r0, Position r1, const Direction& u, T tally) const;
//! Count number of bank sites in each mesh bin / energy bin
//
//! \param[in] Pointer to bank sites
//! \param[in] Number of bank sites
//! \param[out] Whether any bank sites are outside the mesh
xt::xtensor<double, 1> count_sites(
2021-04-29 16:23:54 -04:00
const SourceSite* bank, int64_t length, bool* outside) const;
//! Get bin given mesh indices
//
//! \param[in] Array of mesh indices
//! \return Mesh bin
virtual int get_bin_from_indices(const MeshIndex& ijk) const;
//! Get mesh indices given a position
//
//! \param[in] r Position to get indices for
//! \param[out] in_mesh Whether position is in mesh
2021-12-22 16:19:58 +01:00
//! \return Array of mesh indices
virtual MeshIndex get_indices(Position r, bool& in_mesh) const;
//! Get mesh indices corresponding to a mesh bin
//
//! \param[in] bin Mesh bin
2021-12-22 16:19:58 +01:00
//! \return ijk Mesh indices
virtual MeshIndex get_indices_from_bin(int bin) const;
2019-05-28 13:23:59 -04:00
//! Get mesh index in a particular direction
//!
//! \param[in] r Coordinate to get index for
//! \param[in] i Direction index
virtual int get_index_in_direction(double r, int i) const = 0;
//! Get the coordinate for the mesh grid boundary in the positive direction
//!
//! \param[in] ijk Array of mesh indices
//! \param[in] i Direction index
virtual double positive_grid_boundary(const MeshIndex& ijk, int i) const
{
auto msg =
fmt::format("Attempting to call positive_grid_boundary on a {} mesh.",
get_mesh_type());
fatal_error(msg);
};
//! Get the coordinate for the mesh grid boundary in the negative direction
//!
//! \param[in] ijk Array of mesh indices
//! \param[in] i Direction index
virtual double negative_grid_boundary(const MeshIndex& ijk, int i) const
{
auto msg =
fmt::format("Attempting to call negative_grid_boundary on a {} mesh.",
get_mesh_type());
fatal_error(msg);
};
//! Get the closest distance from the coordinate r to the grid surface
2021-12-22 16:19:58 +01:00
//! in i direction that bounds mesh cell ijk and that is larger than l
//! The coordinate r does not have to be inside the mesh cell ijk. In
2021-12-22 16:19:58 +01:00
//! curved coordinates, multiple crossings of the same surface can happen,
//! these are selected by the parameter l
//!
//! \param[in] ijk Array of mesh indices
2021-12-22 16:19:58 +01:00
//! \param[in] i direction index of grid surface
//! \param[in] r0 position, from where to calculate the distance
//! \param[in] u direction of flight. actual position is r0 + l * u
//! \param[in] l actual chord length
//! \return MeshDistance struct with closest distance, next cell index in
//! i-direction and min/max surface indicator
virtual MeshDistance distance_to_grid_boundary(const MeshIndex& ijk, int i,
const Position& r0, const Direction& u, double l) const = 0;
//! Get a label for the mesh bin
std::string bin_label(int bin) const override;
2019-05-28 13:23:59 -04:00
2021-12-22 16:19:58 +01:00
//! Get shape as xt::xtensor
xt::xtensor<int, 1> get_x_shape() const;
double volume(int bin) const override
{
return this->volume(get_indices_from_bin(bin));
}
//! Get the volume of a specified element
//! \param[in] ijk Mesh index to return the volume for
//! \return Volume of the bin
virtual double volume(const MeshIndex& ijk) const = 0;
2019-05-28 13:23:59 -04:00
// Data members
2019-06-06 15:19:15 -04:00
xt::xtensor<double, 1> lower_left_; //!< Lower-left coordinates of mesh
xt::xtensor<double, 1> upper_right_; //!< Upper-right coordinates of mesh
2021-12-22 16:19:58 +01:00
std::array<int, 3> shape_; //!< Number of mesh elements in each dimension
protected:
2019-05-28 13:23:59 -04:00
};
class PeriodicStructuredMesh : public StructuredMesh {
public:
PeriodicStructuredMesh() = default;
PeriodicStructuredMesh(pugi::xml_node node) : StructuredMesh {node} {};
2023-03-04 23:57:55 -06:00
void local_coords(Position& r) const override { r -= origin_; };
Position local_coords(const Position& r) const override
{
return r - origin_;
};
// Data members
2023-03-04 23:57:55 -06:00
Position origin_ {0.0, 0.0, 0.0}; //!< Origin of the mesh
};
2019-05-28 13:23:59 -04:00
//==============================================================================
//! Tessellation of n-dimensional Euclidean space by congruent squares or cubes
//==============================================================================
class RegularMesh : public StructuredMesh {
2019-05-28 13:23:59 -04:00
public:
// Constructors
RegularMesh() = default;
RegularMesh(pugi::xml_node node);
// Overridden methods
int get_index_in_direction(double r, int i) const override;
2021-12-22 16:19:58 +01:00
virtual std::string get_mesh_type() const override;
2021-12-22 16:19:58 +01:00
static const std::string mesh_type;
MeshDistance distance_to_grid_boundary(const MeshIndex& ijk, int i,
const Position& r0, const Direction& u, double l) const override;
2021-04-29 16:23:54 -04:00
std::pair<vector<double>, vector<double>> plot(
Position plot_ll, Position plot_ur) const override;
2019-05-28 13:23:59 -04:00
void to_hdf5(hid_t group) const override;
//! Get the coordinate for the mesh grid boundary in the positive direction
//!
//! \param[in] ijk Array of mesh indices
//! \param[in] i Direction index
double positive_grid_boundary(const MeshIndex& ijk, int i) const override;
//! Get the coordinate for the mesh grid boundary in the negative direction
//!
//! \param[in] ijk Array of mesh indices
//! \param[in] i Direction index
double negative_grid_boundary(const MeshIndex& ijk, int i) const override;
//! Count number of bank sites in each mesh bin / energy bin
//
//! \param[in] bank Array of bank sites
//! \param[out] Whether any bank sites are outside the mesh
//! \return Array indicating number of sites in each mesh/energy bin
xt::xtensor<double, 1> count_sites(
2021-04-29 16:23:54 -04:00
const SourceSite* bank, int64_t length, bool* outside) const;
//! Return the volume for a given mesh index
double volume(const MeshIndex& ijk) const override;
// Data members
double volume_frac_; //!< Volume fraction of each mesh element
double element_volume_; //!< Volume of each mesh element
2019-06-06 15:19:15 -04:00
xt::xtensor<double, 1> width_; //!< Width of each mesh element
2018-08-28 06:59:39 -05:00
};
class RectilinearMesh : public StructuredMesh {
2019-05-24 10:50:57 -04:00
public:
// Constructors
RectilinearMesh() = default;
2019-05-24 10:50:57 -04:00
RectilinearMesh(pugi::xml_node node);
// Overridden methods
int get_index_in_direction(double r, int i) const override;
2021-12-22 16:19:58 +01:00
virtual std::string get_mesh_type() const override;
static const std::string mesh_type;
MeshDistance distance_to_grid_boundary(const MeshIndex& ijk, int i,
const Position& r0, const Direction& u, double l) const override;
std::pair<vector<double>, vector<double>> plot(
Position plot_ll, Position plot_ur) const override;
void to_hdf5(hid_t group) const override;
//! Get the coordinate for the mesh grid boundary in the positive direction
//!
//! \param[in] ijk Array of mesh indices
//! \param[in] i Direction index
double positive_grid_boundary(const MeshIndex& ijk, int i) const override;
//! Get the coordinate for the mesh grid boundary in the negative direction
//!
//! \param[in] ijk Array of mesh indices
//! \param[in] i Direction index
double negative_grid_boundary(const MeshIndex& ijk, int i) const override;
//! Return the volume for a given mesh index
double volume(const MeshIndex& ijk) const override;
int set_grid();
// Data members
array<vector<double>, 3> grid_;
};
class CylindricalMesh : public PeriodicStructuredMesh {
public:
// Constructors
CylindricalMesh() = default;
CylindricalMesh(pugi::xml_node node);
// Overridden methods
virtual MeshIndex get_indices(Position r, bool& in_mesh) const override;
2019-05-24 10:50:57 -04:00
int get_index_in_direction(double r, int i) const override;
2021-12-22 16:19:58 +01:00
virtual std::string get_mesh_type() const override;
static const std::string mesh_type;
Position sample_element(const MeshIndex& ijk, uint64_t* seed) const override;
MeshDistance distance_to_grid_boundary(const MeshIndex& ijk, int i,
const Position& r0, const Direction& u, double l) const override;
std::pair<vector<double>, vector<double>> plot(
Position plot_ll, Position plot_ur) const override;
void to_hdf5(hid_t group) const override;
double volume(const MeshIndex& ijk) const override;
// grid accessors
double r(int i) const { return grid_[0][i]; }
double phi(int i) const { return grid_[1][i]; }
double z(int i) const { return grid_[2][i]; }
int set_grid();
// Data members
array<vector<double>, 3> grid_;
private:
double find_r_crossing(
const Position& r, const Direction& u, double l, int shell) const;
double find_phi_crossing(
const Position& r, const Direction& u, double l, int shell) const;
StructuredMesh::MeshDistance find_z_crossing(
const Position& r, const Direction& u, double l, int shell) const;
bool full_phi_ {false};
inline int sanitize_angular_index(int idx, bool full, int N) const
{
if ((idx > 0) and (idx <= N)) {
return idx;
} else if (full) {
return (idx + N - 1) % N + 1;
} else {
return 0;
}
}
inline int sanitize_phi(int idx) const
{
return sanitize_angular_index(idx, full_phi_, shape_[1]);
}
};
class SphericalMesh : public PeriodicStructuredMesh {
public:
// Constructors
SphericalMesh() = default;
SphericalMesh(pugi::xml_node node);
// Overridden methods
virtual MeshIndex get_indices(Position r, bool& in_mesh) const override;
int get_index_in_direction(double r, int i) const override;
2021-12-22 16:19:58 +01:00
virtual std::string get_mesh_type() const override;
static const std::string mesh_type;
Position sample_element(const MeshIndex& ijk, uint64_t* seed) const override;
MeshDistance distance_to_grid_boundary(const MeshIndex& ijk, int i,
const Position& r0, const Direction& u, double l) const override;
2021-04-29 16:23:54 -04:00
std::pair<vector<double>, vector<double>> plot(
Position plot_ll, Position plot_ur) const override;
2019-05-28 13:23:59 -04:00
void to_hdf5(hid_t group) const override;
2019-05-24 10:50:57 -04:00
double r(int i) const { return grid_[0][i]; }
double theta(int i) const { return grid_[1][i]; }
double phi(int i) const { return grid_[2][i]; }
2021-03-08 20:17:44 -05:00
int set_grid();
// Data members
array<vector<double>, 3> grid_;
private:
double find_r_crossing(
const Position& r, const Direction& u, double l, int shell) const;
double find_theta_crossing(
const Position& r, const Direction& u, double l, int shell) const;
double find_phi_crossing(
const Position& r, const Direction& u, double l, int shell) const;
bool full_theta_ {false};
bool full_phi_ {false};
inline int sanitize_angular_index(int idx, bool full, int N) const
{
if ((idx > 0) and (idx <= N)) {
return idx;
} else if (full) {
return (idx + N - 1) % N + 1;
} else {
return 0;
}
}
double volume(const MeshIndex& ijk) const override;
inline int sanitize_theta(int idx) const
{
return sanitize_angular_index(idx, full_theta_, shape_[1]);
}
inline int sanitize_phi(int idx) const
{
return sanitize_angular_index(idx, full_phi_, shape_[2]);
}
2019-05-24 10:50:57 -04:00
};
2020-12-07 19:29:35 -06:00
// Abstract class for unstructured meshes
class UnstructuredMesh : public Mesh {
2019-12-05 22:29:47 -06:00
public:
// Constructors
UnstructuredMesh() {};
UnstructuredMesh(pugi::xml_node node);
UnstructuredMesh(const std::string& filename);
2021-12-22 16:19:58 +01:00
static const std::string mesh_type;
virtual std::string get_mesh_type() const override;
// Overridden Methods
2022-06-10 13:31:39 -05:00
void surface_bins_crossed(Position r0, Position r1, const Direction& u,
vector<int>& bins) const override;
void to_hdf5(hid_t group) const override;
std::string bin_label(int bin) const override;
// Methods
//! Add a variable to the mesh instance
virtual void add_score(const std::string& var_name) = 0;
//! Remove tally data from the instance
virtual void remove_scores() = 0;
2020-10-26 13:14:25 -05:00
2020-12-07 19:29:35 -06:00
//! Set the value of a bin for a variable on the internal
// mesh instance
virtual void set_score_data(const std::string& var_name,
const vector<double>& values, const vector<double>& std_dev) = 0;
//! Write the unstructured mesh to file
//
//! \param[in] filename Base of the file to write
virtual void write(const std::string& base_filename) const = 0;
//! Retrieve a centroid for the mesh cell
//
//! \param[in] bin Bin to return the centroid for
//! \return The centroid of the bin
virtual Position centroid(int bin) const = 0;
Adding more mesh interrogation options for the libmesh Finishing methods for connectivity and coordinates. Writing vertices and connectivity to statepoint file Loading vertices and connectivity from statepoint. Correcting string repr Correcting connectivity length Adding method to write the mesh elements to VTK with data applied. Updating hdf5 output to include element types Adding support for hex elements when writing unstructured meshes to VTK Adding simple check for VTK writing if the module is present Removing centroids from the statepoint file and Python UM class Updating test check for vtk Adding warning for skipped elements. Correcting element type Adding warning for skipped elements. Using an enum to indicate element types for readability Updating to element types on the Python side as well Handling integer data applied to VTK files. Doc updates for Python API UM class Incrementing statepoint version number Refactor of unstructured mesh tests to extract model Updating inputs for floating point surface coefficients Adding test for hexes and refactoring comparison funcs Updating reference mesh files Adding reference file for the hexes test case Passing test for hex mesh Adding inputs for the hexes test case. Adding hex test meshes. Skipping hex mesh test if not built with libmesh Adding small VTK write tests for unstructured mesh. Allowing file path to be a pathlib path. Adding skips if libmesh or dagmc not enabled Adding a few comments to test file Changing where conversion to str happens for mesh filename. Setting output to false. Removing VTK check from unstructured mesh regression test Removnig VTK test files for regression test -- too large Adding __init__.py file for pytest
2022-05-31 08:33:43 -05:00
//! Get the number of vertices in the mesh
//
//! \return Number of vertices
virtual int n_vertices() const = 0;
//! Retrieve a vertex of the mesh
//
//! \param[in] vertex ID
//! \return vertex coordinates
virtual Position vertex(int id) const = 0;
//! Retrieve connectivity of a mesh element
//
//! \param[in] element ID
//! \return element connectivity as IDs of the vertices
virtual std::vector<int> connectivity(int id) const = 0;
//! Get the library used for this unstructured mesh
virtual std::string library() const = 0;
// Data members
bool output_ {
true}; //!< Write tallies onto the unstructured mesh at the end of a run
std::string filename_; //!< Path to unstructured mesh file
ElementType element_type(int bin) const;
protected:
//! Set the length multiplier to apply to each point in the mesh
void set_length_multiplier(const double length_multiplier);
// Data members
double length_multiplier_ {
1.0}; //!< Constant multiplication factor to apply to mesh coordinates
bool specified_length_multiplier_ {false};
//! Sample barycentric coordinates given a seed and the vertex positions and
//! return the sampled position
//
//! \param[in] coords Coordinates of the tetrahedron
//! \param[in] seed Random number generation seed
//! \return Sampled position within the tetrahedron
Position sample_tet(std::array<Position, 4> coords, uint64_t* seed) const;
private:
//! Setup method for the mesh. Builds data structures,
//! sets up element mapping, creates bounding boxes, etc.
virtual void initialize() = 0;
2019-12-05 22:29:47 -06:00
};
2019-04-24 21:02:51 -05:00
#ifdef DAGMC
2020-10-30 16:14:49 -05:00
class MOABMesh : public UnstructuredMesh {
2019-05-03 10:53:50 -05:00
public:
// Constructors
2020-10-30 16:14:49 -05:00
MOABMesh() = default;
MOABMesh(pugi::xml_node);
MOABMesh(const std::string& filename, double length_multiplier = 1.0);
MOABMesh(std::shared_ptr<moab::Interface> external_mbi);
2019-04-24 21:02:51 -05:00
2021-12-22 16:19:58 +01:00
static const std::string mesh_lib_type;
// Overridden Methods
//! Perform any preparation needed to support use in mesh filters
void prepare_for_tallies() override;
Position sample_element(int32_t bin, uint64_t* seed) const override;
2022-06-10 13:31:39 -05:00
void bins_crossed(Position r0, Position r1, const Direction& u,
vector<int>& bins, vector<double>& lengths) const override;
int get_bin(Position r) const override;
int n_bins() const override;
int n_surface_bins() const override;
std::pair<vector<double>, vector<double>> plot(
Position plot_ll, Position plot_ur) const override;
std::string library() const override;
//! Add a score to the mesh instance
2020-12-07 19:29:35 -06:00
void add_score(const std::string& score) override;
//! Remove all scores from the mesh instance
void remove_scores() override;
//! Set data for a score
void set_score_data(const std::string& score, const vector<double>& values,
const vector<double>& std_dev) override;
//! Write the mesh with any current tally data
void write(const std::string& base_filename) const override;
Position centroid(int bin) const override;
Adding more mesh interrogation options for the libmesh Finishing methods for connectivity and coordinates. Writing vertices and connectivity to statepoint file Loading vertices and connectivity from statepoint. Correcting string repr Correcting connectivity length Adding method to write the mesh elements to VTK with data applied. Updating hdf5 output to include element types Adding support for hex elements when writing unstructured meshes to VTK Adding simple check for VTK writing if the module is present Removing centroids from the statepoint file and Python UM class Updating test check for vtk Adding warning for skipped elements. Correcting element type Adding warning for skipped elements. Using an enum to indicate element types for readability Updating to element types on the Python side as well Handling integer data applied to VTK files. Doc updates for Python API UM class Incrementing statepoint version number Refactor of unstructured mesh tests to extract model Updating inputs for floating point surface coefficients Adding test for hexes and refactoring comparison funcs Updating reference mesh files Adding reference file for the hexes test case Passing test for hex mesh Adding inputs for the hexes test case. Adding hex test meshes. Skipping hex mesh test if not built with libmesh Adding small VTK write tests for unstructured mesh. Allowing file path to be a pathlib path. Adding skips if libmesh or dagmc not enabled Adding a few comments to test file Changing where conversion to str happens for mesh filename. Setting output to false. Removing VTK check from unstructured mesh regression test Removnig VTK test files for regression test -- too large Adding __init__.py file for pytest
2022-05-31 08:33:43 -05:00
int n_vertices() const override;
Position vertex(int id) const override;
std::vector<int> connectivity(int id) const override;
//! Get the volume of a mesh bin
//
//! \param[in] bin Bin to return the volume for
//! \return Volume of the bin
double volume(int bin) const override;
private:
2020-04-09 13:29:55 -05:00
void initialize() override;
2020-04-06 09:52:45 -05:00
// Methods
//! Create the MOAB interface pointer
void create_interface();
//! Find all intersections with faces of the mesh.
//
//! \param[in] start Staring location
//! \param[in] dir Normalized particle direction
//! \param[in] track_len length of particle track
//! \param[out] Mesh intersections
void intersect_track(const moab::CartVect& start, const moab::CartVect& dir,
double track_len, vector<double>& hits) const;
2019-05-14 22:05:55 -05:00
//! Calculate the volume for a given tetrahedron handle.
2019-05-14 22:05:55 -05:00
//
// \param[in] tet MOAB EntityHandle of the tetrahedron
double tet_volume(moab::EntityHandle tet) const;
//! Find the tetrahedron for the given location if
//! one exists
//
//! \param[in]
//! \return MOAB EntityHandle of tet
moab::EntityHandle get_tet(const Position& r) const;
//! Return the containing tet given a position
moab::EntityHandle get_tet(const moab::CartVect& r) const
{
2019-05-14 22:05:55 -05:00
return get_tet(Position(r[0], r[1], r[2]));
};
//! Check for point containment within a tet; uses
2019-05-14 22:05:55 -05:00
//! pre-computed barycentric data.
//
//! \param[in] r Position to check
//! \param[in] MOAB terahedron to check
//! \return True if r is inside, False if r is outside
bool point_in_tet(const moab::CartVect& r, moab::EntityHandle tet) const;
2019-05-14 22:05:55 -05:00
//! Compute barycentric coordinate data for all tetrahedra
//! in the mesh.
//
//! \param[in] tets MOAB Range of tetrahedral elements
void compute_barycentric_data(const moab::Range& tets);
2019-05-14 22:05:55 -05:00
//! Translate a MOAB EntityHandle to its corresponding bin.
2019-05-14 22:05:55 -05:00
//
//! \param[in] eh MOAB EntityHandle to translate
//! \return Mesh bin
int get_bin_from_ent_handle(moab::EntityHandle eh) const;
//! Translate a bin to its corresponding MOAB EntityHandle
2019-05-14 22:05:55 -05:00
//! for the tetrahedron representing that bin.
//
//! \param[in] bin Bin value to translate
//! \return MOAB EntityHandle of tet
moab::EntityHandle get_ent_handle_from_bin(int bin) const;
Adding more mesh interrogation options for the libmesh Finishing methods for connectivity and coordinates. Writing vertices and connectivity to statepoint file Loading vertices and connectivity from statepoint. Correcting string repr Correcting connectivity length Adding method to write the mesh elements to VTK with data applied. Updating hdf5 output to include element types Adding support for hex elements when writing unstructured meshes to VTK Adding simple check for VTK writing if the module is present Removing centroids from the statepoint file and Python UM class Updating test check for vtk Adding warning for skipped elements. Correcting element type Adding warning for skipped elements. Using an enum to indicate element types for readability Updating to element types on the Python side as well Handling integer data applied to VTK files. Doc updates for Python API UM class Incrementing statepoint version number Refactor of unstructured mesh tests to extract model Updating inputs for floating point surface coefficients Adding test for hexes and refactoring comparison funcs Updating reference mesh files Adding reference file for the hexes test case Passing test for hex mesh Adding inputs for the hexes test case. Adding hex test meshes. Skipping hex mesh test if not built with libmesh Adding small VTK write tests for unstructured mesh. Allowing file path to be a pathlib path. Adding skips if libmesh or dagmc not enabled Adding a few comments to test file Changing where conversion to str happens for mesh filename. Setting output to false. Removing VTK check from unstructured mesh regression test Removnig VTK test files for regression test -- too large Adding __init__.py file for pytest
2022-05-31 08:33:43 -05:00
//! Get a vertex index into the global range from a handle
int get_vert_idx_from_handle(moab::EntityHandle vert) const;
//! Get the bin for a given mesh cell index
//
//! \param[in] idx Index of the mesh cell.
//! \return Mesh bin
int get_bin_from_index(int idx) const;
2019-11-26 04:57:16 -06:00
//! Get the mesh cell index for a given position
//
//! \param[in] r Position to get index for
//! \param[in,out] in_mesh Whether position is in the mesh
int get_index(const Position& r, bool* in_mesh) const;
2019-11-26 04:57:16 -06:00
//! Get the mesh cell index from a bin
//
//! \param[in] bin Bin to get the index for
//! \return Index of the bin
int get_index_from_bin(int bin) const;
2019-11-26 04:57:16 -06:00
//! Build a KDTree for all tetrahedra in the mesh. All
2019-05-14 22:05:55 -05:00
//! triangles representing 2D faces of the mesh are
//! added to the tree as well.
//
//! \param[in] all_tets MOAB Range of tetrahedra for the tree
void build_kdtree(const moab::Range& all_tets);
2020-02-17 20:36:00 -06:00
//! Get the tags for a score from the mesh instance
//! or create them if they are not there
//
//! \param[in] score Name of the score
//! \return The MOAB value and error tag handles, respectively
std::pair<moab::Tag, moab::Tag> get_score_tags(std::string score) const;
// Data members
2023-01-13 00:00:16 -06:00
moab::Range ehs_; //!< Range of tetrahedra EntityHandle's in the mesh
Adding more mesh interrogation options for the libmesh Finishing methods for connectivity and coordinates. Writing vertices and connectivity to statepoint file Loading vertices and connectivity from statepoint. Correcting string repr Correcting connectivity length Adding method to write the mesh elements to VTK with data applied. Updating hdf5 output to include element types Adding support for hex elements when writing unstructured meshes to VTK Adding simple check for VTK writing if the module is present Removing centroids from the statepoint file and Python UM class Updating test check for vtk Adding warning for skipped elements. Correcting element type Adding warning for skipped elements. Using an enum to indicate element types for readability Updating to element types on the Python side as well Handling integer data applied to VTK files. Doc updates for Python API UM class Incrementing statepoint version number Refactor of unstructured mesh tests to extract model Updating inputs for floating point surface coefficients Adding test for hexes and refactoring comparison funcs Updating reference mesh files Adding reference file for the hexes test case Passing test for hex mesh Adding inputs for the hexes test case. Adding hex test meshes. Skipping hex mesh test if not built with libmesh Adding small VTK write tests for unstructured mesh. Allowing file path to be a pathlib path. Adding skips if libmesh or dagmc not enabled Adding a few comments to test file Changing where conversion to str happens for mesh filename. Setting output to false. Removing VTK check from unstructured mesh regression test Removnig VTK test files for regression test -- too large Adding __init__.py file for pytest
2022-05-31 08:33:43 -05:00
moab::Range verts_; //!< Range of vertex EntityHandle's in the mesh
2020-03-25 03:21:39 -05:00
moab::EntityHandle tetset_; //!< EntitySet containing all tetrahedra
2019-05-14 22:05:55 -05:00
moab::EntityHandle kdtree_root_; //!< Root of the MOAB KDTree
std::shared_ptr<moab::Interface> mbi_; //!< MOAB instance
unique_ptr<moab::AdaptiveKDTree> kdtree_; //!< MOAB KDTree instance
vector<moab::Matrix3> baryc_data_; //!< Barycentric data for tetrahedra
vector<std::string> tag_names_; //!< Names of score tags added to the mesh
2019-04-24 21:02:51 -05:00
};
#endif
2019-12-05 22:29:47 -06:00
#ifdef LIBMESH
2020-12-07 19:29:35 -06:00
class LibMesh : public UnstructuredMesh {
2019-12-05 22:29:47 -06:00
public:
// Constructors
2019-12-05 22:29:47 -06:00
LibMesh(pugi::xml_node node);
2023-01-13 00:00:16 -06:00
LibMesh(const std::string& filename, double length_multiplier = 1.0);
LibMesh(libMesh::MeshBase& input_mesh, double length_multiplier = 1.0);
2019-12-05 22:29:47 -06:00
2021-12-22 16:19:58 +01:00
static const std::string mesh_lib_type;
// Overridden Methods
void bins_crossed(Position r0, Position r1, const Direction& u,
vector<int>& bins, vector<double>& lengths) const override;
2020-01-10 01:04:08 -06:00
Position sample_element(int32_t bin, uint64_t* seed) const override;
2022-06-10 13:31:39 -05:00
int get_bin(Position r) const override;
int n_bins() const override;
2020-01-10 01:04:08 -06:00
int n_surface_bins() const override;
2020-01-10 01:04:08 -06:00
std::pair<vector<double>, vector<double>> plot(
Position plot_ll, Position plot_ur) const override;
std::string library() const override;
2020-01-10 01:04:08 -06:00
void add_score(const std::string& var_name) override;
2020-01-10 01:04:08 -06:00
void remove_scores() override;
2020-10-26 13:14:25 -05:00
void set_score_data(const std::string& var_name, const vector<double>& values,
const vector<double>& std_dev) override;
2020-01-10 01:04:08 -06:00
void write(const std::string& base_filename) const override;
Position centroid(int bin) const override;
Adding more mesh interrogation options for the libmesh Finishing methods for connectivity and coordinates. Writing vertices and connectivity to statepoint file Loading vertices and connectivity from statepoint. Correcting string repr Correcting connectivity length Adding method to write the mesh elements to VTK with data applied. Updating hdf5 output to include element types Adding support for hex elements when writing unstructured meshes to VTK Adding simple check for VTK writing if the module is present Removing centroids from the statepoint file and Python UM class Updating test check for vtk Adding warning for skipped elements. Correcting element type Adding warning for skipped elements. Using an enum to indicate element types for readability Updating to element types on the Python side as well Handling integer data applied to VTK files. Doc updates for Python API UM class Incrementing statepoint version number Refactor of unstructured mesh tests to extract model Updating inputs for floating point surface coefficients Adding test for hexes and refactoring comparison funcs Updating reference mesh files Adding reference file for the hexes test case Passing test for hex mesh Adding inputs for the hexes test case. Adding hex test meshes. Skipping hex mesh test if not built with libmesh Adding small VTK write tests for unstructured mesh. Allowing file path to be a pathlib path. Adding skips if libmesh or dagmc not enabled Adding a few comments to test file Changing where conversion to str happens for mesh filename. Setting output to false. Removing VTK check from unstructured mesh regression test Removnig VTK test files for regression test -- too large Adding __init__.py file for pytest
2022-05-31 08:33:43 -05:00
int n_vertices() const override;
Position vertex(int id) const override;
std::vector<int> connectivity(int id) const override;
//! Get the volume of a mesh bin
//
//! \param[in] bin Bin to return the volume for
//! \return Volume of the bin
double volume(int bin) const override;
2022-07-26 12:59:43 -05:00
libMesh::MeshBase* mesh_ptr() const { return m_; };
2020-01-10 01:04:08 -06:00
private:
2020-04-09 13:29:55 -05:00
void initialize() override;
void set_mesh_pointer_from_filename(const std::string& filename);
// Methods
//! Translate a bin value to an element reference
const libMesh::Elem& get_element_from_bin(int bin) const;
2020-01-10 01:04:08 -06:00
//! Translate an element pointer to a bin index
2020-01-10 01:04:08 -06:00
int get_bin_from_element(const libMesh::Elem* elem) const;
// Data members
2023-01-13 00:00:16 -06:00
unique_ptr<libMesh::MeshBase> unique_m_ =
nullptr; //!< pointer to the libMesh MeshBase instance, only used if mesh is
//!< created inside OpenMC
libMesh::MeshBase* m_; //!< pointer to libMesh MeshBase instance, always set
//!< during intialization
vector<unique_ptr<libMesh::PointLocatorBase>>
pl_; //!< per-thread point locators
unique_ptr<libMesh::EquationSystems>
equation_systems_; //!< pointer to the equation systems of the mesh
2020-01-10 01:04:08 -06:00
std::string
eq_system_name_; //!< name of the equation system holding OpenMC results
std::unordered_map<std::string, unsigned int>
variable_map_; //!< mapping of variable names (tally scores) to libMesh
//!< variable numbers
2020-10-30 16:14:49 -05:00
libMesh::BoundingBox bbox_; //!< bounding box of the mesh
2021-02-10 11:38:22 -06:00
libMesh::dof_id_type
first_element_id_; //!< id of the first element in the mesh
2019-12-05 22:29:47 -06:00
};
2019-12-05 22:29:47 -06:00
#endif
2018-08-30 09:57:26 -05:00
//==============================================================================
// Non-member functions
//==============================================================================
//! Read meshes from either settings/tallies
//
2018-08-30 09:57:26 -05:00
//! \param[in] root XML node
2019-02-20 23:34:36 -06:00
void read_meshes(pugi::xml_node root);
2018-08-30 09:57:26 -05:00
2018-09-03 14:01:59 -05:00
//! Write mesh data to an HDF5 group
//
2018-09-03 14:01:59 -05:00
//! \param[in] group HDF5 group
void meshes_to_hdf5(hid_t group);
2018-09-03 14:01:59 -05:00
2019-02-21 08:32:32 -06:00
void free_memory_mesh();
2018-08-28 06:59:39 -05:00
} // namespace openmc
#endif // OPENMC_MESH_H