#ifndef OPENMC_BOUNDARY_CONDITION_H #define OPENMC_BOUNDARY_CONDITION_H #include "openmc/hdf5_interface.h" #include "openmc/particle.h" #include "openmc/position.h" #include namespace openmc { // Forward declare some types used in function arguments. class Particle; class Surface; //============================================================================== //! A class that tells particles what to do after they strike an outer boundary. //============================================================================== class BoundaryCondition { public: virtual ~BoundaryCondition() = default; //! Perform tracking operations for a particle that strikes the boundary. //! \param p The particle that struck the boundary. This class is not meant //! to directly modify anything about the particle, but it will do so //! indirectly by calling the particle's appropriate cross_*_bc function. //! \param surf The specific surface on the boundary the particle struck. virtual void handle_particle(Particle& p, const Surface& surf) const = 0; //! Modify the incident particle's weight according to the boundary's albedo. //! \param p The particle that struck the boundary. This function calculates //! the reduction in the incident particle's weight as it interacts //! with a boundary. The lost weight is tallied before the remaining weight //! is reassigned to the incident particle. Implementations of the //! handle_particle function typically call this method in its body. //! \param surf The specific surface on the boundary the particle struck. void handle_albedo(Particle& p, const Surface& surf) const { if (!has_albedo()) return; double initial_wgt = p.wgt(); // Treat the lost weight fraction as leakage, similar to VacuumBC. // This ensures the lost weight is tallied properly. p.wgt() *= (1.0 - albedo_); p.cross_vacuum_bc(surf); p.wgt() = initial_wgt * albedo_; }; //! Return a string classification of this BC. virtual std::string type() const = 0; //! Write albedo data of this BC to hdf5. void to_hdf5(hid_t surf_group) const { if (has_albedo()) { write_string(surf_group, "albedo", fmt::format("{}", albedo_), false); } }; //! Set albedo of this BC. void set_albedo(double albedo) { albedo_ = albedo; } //! Return if this BC has an albedo. bool has_albedo() const { return (albedo_ > 0.0); } private: double albedo_ = -1.0; }; //============================================================================== //! A BC that kills particles, indicating they left the problem. //============================================================================== class VacuumBC : public BoundaryCondition { public: void handle_particle(Particle& p, const Surface& surf) const override; std::string type() const override { return "vacuum"; } }; //============================================================================== //! A BC that returns particles via specular reflection. //============================================================================== class ReflectiveBC : public BoundaryCondition { public: void handle_particle(Particle& p, const Surface& surf) const override; std::string type() const override { return "reflective"; } }; //============================================================================== //! A BC that returns particles via diffuse reflection. //============================================================================== class WhiteBC : public BoundaryCondition { public: void handle_particle(Particle& p, const Surface& surf) const override; std::string type() const override { return "white"; } }; //============================================================================== //! A BC that moves particles to another part of the problem. //============================================================================== class PeriodicBC : public BoundaryCondition { public: PeriodicBC(int i_surf, int j_surf) : i_surf_(i_surf), j_surf_(j_surf) {}; std::string type() const override { return "periodic"; } protected: int i_surf_; int j_surf_; }; //============================================================================== //! A BC that moves particles to another part of the problem without rotation. //============================================================================== class TranslationalPeriodicBC : public PeriodicBC { public: TranslationalPeriodicBC(int i_surf, int j_surf); void handle_particle(Particle& p, const Surface& surf) const override; protected: //! Vector along which incident particles will be moved Position translation_; }; //============================================================================== //! A BC that rotates particles about a global axis. // //! Currently only rotations about the z-axis are supported. //============================================================================== class RotationalPeriodicBC : public PeriodicBC { public: RotationalPeriodicBC(int i_surf, int j_surf); void handle_particle(Particle& p, const Surface& surf) const override; protected: //! Angle about the axis by which particle coordinates will be rotated double angle_; }; } // namespace openmc #endif // OPENMC_BOUNDARY_CONDITION_H