mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-21 14:35:27 -04:00
264 lines
8.6 KiB
C++
264 lines
8.6 KiB
C++
#ifndef OPENMC_MATERIAL_H
|
|
#define OPENMC_MATERIAL_H
|
|
|
|
#include <string>
|
|
#include <unordered_map>
|
|
|
|
#include "openmc/span.h"
|
|
#include "openmc/tensor.h"
|
|
#include "pugixml.hpp"
|
|
#include <hdf5.h>
|
|
|
|
#include "openmc/bremsstrahlung.h"
|
|
#include "openmc/constants.h"
|
|
#include "openmc/memory.h" // for unique_ptr
|
|
#include "openmc/ncrystal_interface.h"
|
|
#include "openmc/particle.h"
|
|
#include "openmc/settings.h"
|
|
#include "openmc/vector.h"
|
|
|
|
namespace openmc {
|
|
|
|
//==============================================================================
|
|
// Global variables
|
|
//==============================================================================
|
|
|
|
class Material;
|
|
|
|
namespace model {
|
|
|
|
extern std::unordered_map<int32_t, int32_t> material_map;
|
|
extern vector<unique_ptr<Material>> materials;
|
|
|
|
} // namespace model
|
|
|
|
//==============================================================================
|
|
//! A substance with constituent nuclides and thermal scattering data
|
|
//==============================================================================
|
|
|
|
class Material {
|
|
public:
|
|
//----------------------------------------------------------------------------
|
|
// Types
|
|
struct ThermalTable {
|
|
int index_table; //!< Index of table in data::thermal_scatt
|
|
int index_nuclide; //!< Index in nuclide_
|
|
double fraction; //!< How often to use table
|
|
};
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Constructors, destructors, factory functions
|
|
Material() {};
|
|
explicit Material(pugi::xml_node material_node);
|
|
~Material();
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Methods
|
|
|
|
void calculate_xs(Particle& p) const;
|
|
|
|
//! Assign thermal scattering tables to specific nuclides within the material
|
|
//! so the code knows when to apply bound thermal scattering data
|
|
void init_thermal();
|
|
|
|
//! Set up mapping between global nuclides vector and indices in nuclide_
|
|
void init_nuclide_index();
|
|
|
|
//! Finalize the material, assigning tables, normalize density, etc.
|
|
void finalize();
|
|
|
|
//! Write material data to HDF5
|
|
void to_hdf5(hid_t group) const;
|
|
|
|
//! Export physical properties to HDF5
|
|
//! \param[in] group HDF5 group to write to
|
|
void export_properties_hdf5(hid_t group) const;
|
|
|
|
//! Import physical properties from HDF5
|
|
//! \param[in] group HDF5 group to read from
|
|
void import_properties_hdf5(hid_t group);
|
|
|
|
//! Add nuclide to the material
|
|
//
|
|
//! \param[in] nuclide Name of the nuclide
|
|
//! \param[in] density Density of the nuclide in [atom/b-cm]
|
|
void add_nuclide(const std::string& nuclide, double density);
|
|
|
|
//! Set atom densities for the material
|
|
//
|
|
//! \param[in] name Name of each nuclide
|
|
//! \param[in] density Density of each nuclide in [atom/b-cm]
|
|
void set_densities(
|
|
const vector<std::string>& name, const vector<double>& density);
|
|
|
|
//! Clone the material by deep-copying all members, except for the ID,
|
|
// which will get auto-assigned to the next available ID. After creating
|
|
// the new material, it is added to openmc::model::materials.
|
|
//! \return reference to the cloned material
|
|
Material& clone();
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Accessors
|
|
|
|
//! Get the atom density in [atom/b-cm]
|
|
//! \return Density in [atom/b-cm]
|
|
double atom_density(int32_t i, double rho_multiplier = 1.0) const
|
|
{
|
|
return atom_density_(i) * rho_multiplier;
|
|
}
|
|
|
|
//! Get density in [atom/b-cm]
|
|
//! \return Density in [atom/b-cm]
|
|
double density() const { return density_; }
|
|
|
|
//! Get density in [g/cm^3].
|
|
//! \return Density in [g/cm^3]
|
|
double density_gpcc() const
|
|
{
|
|
return settings::run_CE ? density_gpcc_ : density();
|
|
}
|
|
|
|
//! Get charge density in [e/b-cm]
|
|
//! \return Charge density in [e/b-cm]
|
|
double charge_density() const { return charge_density_; };
|
|
|
|
//! Get name
|
|
//! \return Material name
|
|
const std::string& name() const { return name_; }
|
|
|
|
//! Set name
|
|
void set_name(const std::string& name) { name_ = name; }
|
|
|
|
//! Set total density of the material
|
|
//
|
|
//! \param[in] density Density value
|
|
//! \param[in] units Units of density
|
|
void set_density(double density, const std::string& units);
|
|
|
|
//! Set temperature of the material
|
|
void set_temperature(double temperature) { temperature_ = temperature; };
|
|
|
|
//! Get nuclides in material
|
|
//! \return Indices into the global nuclides vector
|
|
span<const int> nuclides() const
|
|
{
|
|
return {nuclide_.data(), nuclide_.size()};
|
|
}
|
|
|
|
//! Get densities of each nuclide in material
|
|
//! \return Densities in [atom/b-cm]
|
|
span<const double> densities() const
|
|
{
|
|
return {atom_density_.data(), atom_density_.size()};
|
|
}
|
|
|
|
//! Get ID of material
|
|
//! \return ID of material
|
|
int32_t id() const { return id_; }
|
|
|
|
//! Assign a unique ID to the material
|
|
//! \param[in] Unique ID to assign. A value of -1 indicates that an ID
|
|
//! should be automatically assigned.
|
|
void set_id(int32_t id);
|
|
|
|
//! Get whether material is fissionable
|
|
//! \return Whether material is fissionable
|
|
bool fissionable() const { return fissionable_; }
|
|
bool& fissionable() { return fissionable_; }
|
|
|
|
//! Get volume of material
|
|
//! \return Volume in [cm^3]
|
|
double volume() const;
|
|
|
|
//! Get temperature of material
|
|
//! \return Temperature in [K]
|
|
double temperature() const;
|
|
|
|
//! Whether or not the material is depletable
|
|
bool depletable() const { return depletable_; }
|
|
bool& depletable() { return depletable_; }
|
|
|
|
//! Get pointer to NCrystal material object
|
|
//! \return Pointer to NCrystal material object
|
|
const NCrystalMat& ncrystal_mat() const { return ncrystal_mat_; };
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Data
|
|
int32_t id_ {C_NONE}; //!< Unique ID
|
|
std::string name_; //!< Name of material
|
|
vector<int> nuclide_; //!< Indices in nuclides vector
|
|
vector<int> element_; //!< Indices in elements vector
|
|
NCrystalMat ncrystal_mat_; //!< NCrystal material object
|
|
tensor::Tensor<double> atom_density_; //!< Nuclide atom density in [atom/b-cm]
|
|
double density_; //!< Total atom density in [atom/b-cm]
|
|
double density_gpcc_; //!< Total atom density in [g/cm^3]
|
|
double charge_density_; //!< Total charge density in [e/b-cm]
|
|
double volume_ {-1.0}; //!< Volume in [cm^3]
|
|
vector<bool> p0_; //!< Indicate which nuclides are to be treated with
|
|
//!< iso-in-lab scattering
|
|
|
|
// To improve performance of tallying, we store an array (direct address
|
|
// table) that indicates for each nuclide in data::nuclides the index of the
|
|
// corresponding nuclide in the nuclide_ vector. If it is not present in the
|
|
// material, the entry is set to -1.
|
|
vector<int> mat_nuclide_index_;
|
|
|
|
// Thermal scattering tables
|
|
vector<ThermalTable> thermal_tables_;
|
|
|
|
unique_ptr<Bremsstrahlung> ttb_;
|
|
|
|
private:
|
|
//----------------------------------------------------------------------------
|
|
// Private methods
|
|
|
|
//! Calculate the collision stopping power
|
|
void collision_stopping_power(double* s_col, bool positron);
|
|
|
|
//! Initialize bremsstrahlung data
|
|
void init_bremsstrahlung();
|
|
|
|
//! Normalize density
|
|
void normalize_density();
|
|
|
|
void calculate_neutron_xs(Particle& p) const;
|
|
void calculate_photon_xs(Particle& p) const;
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Private data members
|
|
int64_t index_;
|
|
|
|
bool depletable_ {false}; //!< Is the material depletable?
|
|
bool fissionable_ {
|
|
false}; //!< Does this material contain fissionable nuclides
|
|
//! \brief Default temperature for cells containing this material.
|
|
//!
|
|
//! A negative value indicates no default temperature was specified.
|
|
double temperature_ {-1};
|
|
};
|
|
|
|
//==============================================================================
|
|
// Non-member functions
|
|
//==============================================================================
|
|
|
|
//! Calculate Sternheimer adjustment factor
|
|
double sternheimer_adjustment(const vector<double>& f,
|
|
const vector<double>& e_b_sq, double e_p_sq, double n_conduction,
|
|
double log_I, double tol, int max_iter);
|
|
|
|
//! Calculate density effect correction
|
|
double density_effect(const vector<double>& f, const vector<double>& e_b_sq,
|
|
double e_p_sq, double n_conduction, double rho, double E, double tol,
|
|
int max_iter);
|
|
|
|
//! Read material data from materials.xml
|
|
void read_materials_xml();
|
|
|
|
//! Read material data XML node
|
|
//! \param[in] root node of materials XML element
|
|
void read_materials_xml(pugi::xml_node root);
|
|
|
|
void free_memory_material();
|
|
|
|
} // namespace openmc
|
|
#endif // OPENMC_MATERIAL_H
|