Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #include "PeriodicRayBC.h" 11 : 12 : #include "RayTracingStudy.h" 13 : #include "PeriodicBCHelper.h" 14 : 15 : #include "libmesh/periodic_boundaries.h" 16 : #include "libmesh/periodic_boundary.h" 17 : 18 : registerMooseObject("RayTracingApp", PeriodicRayBC); 19 : 20 : const std::string PeriodicRayBC::periodic_boundaries_param = "_periodic_boundaries"; 21 : 22 : InputParameters 23 59 : PeriodicRayBC::validParams() 24 : { 25 59 : auto params = GeneralRayBC::validParams(); 26 59 : params += Moose::PeriodicBCHelper::validParams(); 27 : 28 : // To be filled with the PeriodicBoundaries object from the 29 : // SetupPeriodicRayBCAction, and is also used to identify 30 : // before construction that this object is a PeriodicRayBC 31 59 : params.addPrivateParam<const libMesh::PeriodicBoundaries *>(periodic_boundaries_param, nullptr); 32 : 33 : // This is now set via auto_direction or primary and secondary 34 59 : params.suppressParameter<std::vector<BoundaryName>>("boundary"); 35 : 36 59 : params.addClassDescription("A RayBC that enforces periodic boundaries."); 37 : 38 59 : return params; 39 0 : } 40 : 41 32 : PeriodicRayBC::PeriodicRayBC(const InputParameters & params) 42 : : GeneralRayBC(params), 43 32 : _periodic_boundaries( 44 64 : *getCheckedPointerParam<const libMesh::PeriodicBoundaries *>(periodic_boundaries_param)), 45 32 : _point_locator(_mesh.getPointLocator()), 46 32 : _periodic_applied(0), 47 32 : _periodic_neighbor(nullptr) 48 : { 49 32 : } 50 : 51 : bool 52 4102 : PeriodicRayBC::isPeriodicRayBC(const InputParameters & params) 53 : { 54 4102 : return params.have_parameter<const libMesh::PeriodicBoundaries *>(periodic_boundaries_param); 55 : } 56 : 57 : void 58 38126 : PeriodicRayBC::onBoundary(const unsigned int num_applying) 59 : { 60 : // No need to do anything if the Ray's gonna die anyway 61 38126 : if (!currentRay()->shouldContinue()) 62 0 : return; 63 : 64 : // The current side we're on, which isn't the physical 65 : // side we're currently at if we've applied multiple periodic 66 : // boundaries 67 38126 : unsigned int current_side = _current_intersected_side; 68 : 69 : // Reset shared state between calls; needed in the event that 70 : // we are applying multiple periodic boundary conditions. Begin 71 : // out with the actual intersection information (the neighbor 72 : // is cleared once all boundaries are applied for a single Ray) 73 38126 : if (!_periodic_neighbor) 74 : { 75 31686 : _periodic_point = _current_intersection_point; 76 31686 : _periodic_neighbor = _current_elem; 77 : } 78 : // We do have a periodic neighbor, which means we're applying 79 : // more than one periodic boundary and need to find the side 80 : // from the last topological neighbor 81 : else 82 : { 83 : mooseAssert(num_applying > 1, "Should be applying multiple"); 84 6440 : current_side = _mesh.sideWithBoundaryID(_periodic_neighbor, _current_bnd_id); 85 : } 86 : 87 : // The PeriodicBoundary object associated with the periodic boundary 88 38126 : const auto periodic_boundary = _periodic_boundaries.boundary(_current_bnd_id); 89 38126 : if (!periodic_boundary) 90 0 : mooseError("Failed to find periodic boundary\n\n", currentRay()->getInfo()); 91 : 92 : // Move the point; this translation could happen multiple times if we are 93 : // applying more than one periodic boundary, which is why the state 94 : // is shared outside of onBoundary() 95 38126 : _periodic_point = periodic_boundary->get_corresponding_pos(_periodic_point); 96 : 97 : // Find the topological neighbor 98 : unsigned int periodic_side; 99 38126 : _periodic_neighbor = _periodic_boundaries.neighbor( 100 38126 : _current_bnd_id, *_point_locator, _periodic_neighbor, current_side, &periodic_side); 101 : mooseAssert(_periodic_neighbor, "Should be set"); 102 38126 : if (_periodic_neighbor == libMesh::remote_elem) 103 0 : mooseError( 104 0 : "Topological neighbor at ", _periodic_point, " is remote\n\n", currentRay()->getInfo()); 105 : 106 : // We've done all translations, so actually move the Ray 107 38126 : if (++_periodic_applied == num_applying) 108 : { 109 31686 : currentRay()->changePointElemSide(_periodic_point, *_periodic_neighbor, periodic_side, {}); 110 31686 : _periodic_neighbor = nullptr; 111 31686 : _periodic_applied = 0; 112 : } 113 : }