diff --git a/docs/source/usersguide/geometry.rst b/docs/source/usersguide/geometry.rst index c929503df1..18bdf94b5f 100644 --- a/docs/source/usersguide/geometry.rst +++ b/docs/source/usersguide/geometry.rst @@ -162,22 +162,26 @@ surface. To specify a vacuum boundary condition, simply change the Reflective and periodic boundary conditions can be set with the strings 'reflective' and 'periodic'. Vacuum and reflective boundary conditions can be applied to any type of surface. Periodic boundary conditions can be applied to -pairs of planar surfaces. For axis-aligned planes, matching periodic surfaces -can be determined automatically. For non-axis-aligned planes, it is necessary to -specify pairs explicitly using the :attr:`Surface.periodic_surface` attribute as -in the following example:: +pairs of planar surfaces. If there are only two periodic surfaces they will be +matched automatically. Otherwise it is necessary to specify pairs explicitly +using the :attr:`Surface.periodic_surface` attribute as in the following +example:: p1 = openmc.Plane(a=0.3, b=5.0, d=1.0, boundary_type='periodic') p2 = openmc.Plane(a=0.3, b=5.0, d=-1.0, boundary_type='periodic') p1.periodic_surface = p2 -Rotationally-periodic boundary conditions can be specified for a pair of -:class:`XPlane` and :class:`YPlane`; in that case, the -:attr:`Surface.periodic_surface` attribute must be specified manually as well. +Both rotational and translational periodic boundary conditions are specified in +the same fashion. If both planes have the same normal vector, a translational +periodicity is assumed; rotational periodicity is assumed otherwise. Currently, +only rotations about the :math:`z`-axis are supported. -.. caution:: When using rotationally-periodic boundary conditions, your geometry - must be defined in the first quadrant, i.e., above the y-plane and - to the right of the x-plane. +For a rotational periodic BC, the normal vectors of each surface must point +inwards---towards the valid geometry. For example, a :class:`XPlane` and +:class:`YPlane` would be valid for a 90-degree periodic rotation if the geometry +lies in the first quadrant of the Cartesian grid. If the geometry instead lies +in the fourth quadrant, the :class:`YPlane` must be replaced by a +:class:`Plane` with the normal vector pointing in the :math:`-y` direction. .. _usersguide_cells: diff --git a/include/openmc/boundary_condition.h b/include/openmc/boundary_condition.h index c03e19e50f..7eb93a61d4 100644 --- a/include/openmc/boundary_condition.h +++ b/include/openmc/boundary_condition.h @@ -112,9 +112,6 @@ public: protected: //! Angle about the axis by which particle coordinates will be rotated double angle_; - - //! Whether or not the boundary normal vector reverses after a rotation - bool aligned_normals_; }; } // namespace openmc diff --git a/src/boundary_condition.cpp b/src/boundary_condition.cpp index bc01c21994..2b88e4c7ca 100644 --- a/src/boundary_condition.cpp +++ b/src/boundary_condition.cpp @@ -211,14 +211,6 @@ RotationalPeriodicBC::RotationalPeriodicBC(int i_surf, int j_surf) "angle of {} degrees which does not evenly divide 360 degrees.", angle_ * 180 / PI)); } - - // Guess whether or not the normal vectors of the two planes are aligned, i.e. - // if an arc passing from one surface through the geometry to the other - // surface will pass through the same "side" of both surfaces. If the user - // specified an x-plane and a y-plane then the geometry likely lies in the - // first quadrant which means the normals are not aligned. Otherwise, assume - // the opposite. - aligned_normals_ = !(surf1_is_xyplane && surf2_is_xyplane); } void @@ -233,23 +225,16 @@ RotationalPeriodicBC::handle_particle(Particle& p, const Surface& surf) const double theta; int new_surface; if (i_particle_surf == i_surf_) { - theta = angle_; - new_surface = p.surface_ > 0 ? j_surf_ + 1 : -(j_surf_ + 1); - } else if (i_particle_surf == j_surf_) { theta = -angle_; - new_surface = p.surface_ > 0 ? i_surf_ + 1 : -(i_surf_ + 1); + new_surface = p.surface_ > 0 ? -(j_surf_ + 1) : j_surf_ + 1; + } else if (i_particle_surf == j_surf_) { + theta = angle_; + new_surface = p.surface_ > 0 ? -(i_surf_ + 1) : i_surf_ + 1; } else { throw std::runtime_error("Called BoundaryCondition::handle_particle after " "hitting a surface, but that surface is not recognized by the BC."); } - // If the normal vectors of the two surfaces are not aligned, then the logic - // must be reversed for rotation and picking a new surface halfspace. - if (not aligned_normals_) { - theta = -theta; - new_surface = -new_surface; - } - // Rotate the particle's position and direction about the z-axis. Position r = p.r(); Direction u = p.u(); diff --git a/src/particle.cpp b/src/particle.cpp index b2902238d7..4453701be4 100644 --- a/src/particle.cpp +++ b/src/particle.cpp @@ -589,7 +589,8 @@ Particle::cross_periodic_bc(const Surface& surf, Position new_r, if (!find_cell(*this, true)) { this->mark_as_lost("Couldn't find particle after hitting periodic " - "boundary on surface " + std::to_string(surf.id_) + "."); + "boundary on surface " + std::to_string(surf.id_) + ". The normal vector " + "of one periodic surface may need to be reversed."); return; } diff --git a/tests/regression_tests/periodic/inputs_true.dat b/tests/regression_tests/periodic/inputs_true.dat index ab25560f81..c1f6d15631 100644 --- a/tests/regression_tests/periodic/inputs_true.dat +++ b/tests/regression_tests/periodic/inputs_true.dat @@ -35,11 +35,3 @@ - - - - 2.5 2.5 0 - 6 11 - 300 300 - -