13 #include "libmesh/parallel_algebra.h" 24 "illumination_flux_size>0 && illumination_flux_size<=3",
25 "Radiation direction vector. Each component of the vector can be a constant number or a " 26 "postprocessor name (the latter enables time varying radiation directions - spatial " 27 "variation is not supported)");
33 _dim(_mesh.dimension()),
34 _raw_direction(coupledPostprocessors(
"illumination_flux")),
36 declareRestartableData<
std::map<
SideIDType, unsigned
int>>(
"illumination_status"))
42 mooseError(
"SelfShadowSideUserObject works only for 2 and 3 dimensional problems.");
89 _lines.insert(
_lines.end(), uo._lines.begin(), uo._lines.end());
99 mooseError(
"Illumination status was not calculated for current side.");
108 for (
auto & line :
_lines)
131 unsigned int bit = 1;
155 _lines.emplace_back(cse.node_ref(0), cse.node_ref(1), id);
159 _lines.emplace_back(cse.node_ref(0), cse.node_ref(2), id);
160 _lines.emplace_back(cse.node_ref(2), cse.node_ref(1), id);
164 _lines.emplace_back(cse.node_ref(0), cse.node_ref(2), id);
165 _lines.emplace_back(cse.node_ref(2), cse.node_ref(3), id);
166 _lines.emplace_back(cse.node_ref(3), cse.node_ref(1), id);
181 _triangles.emplace_back(cse.node_ref(0), cse.node_ref(1), cse.node_ref(2), id);
186 _triangles.emplace_back(cse.node_ref(0), cse.node_ref(3), cse.node_ref(5), id);
187 _triangles.emplace_back(cse.node_ref(3), cse.node_ref(1), cse.node_ref(4), id);
188 _triangles.emplace_back(cse.node_ref(4), cse.node_ref(2), cse.node_ref(5), id);
189 _triangles.emplace_back(cse.node_ref(3), cse.node_ref(4), cse.node_ref(5), id);
193 _triangles.emplace_back(cse.node_ref(0), cse.node_ref(1), cse.node_ref(2), id);
194 _triangles.emplace_back(cse.node_ref(2), cse.node_ref(3), cse.node_ref(0), id);
198 _triangles.emplace_back(cse.node_ref(0), cse.node_ref(4), cse.node_ref(7), id);
199 _triangles.emplace_back(cse.node_ref(4), cse.node_ref(1), cse.node_ref(5), id);
200 _triangles.emplace_back(cse.node_ref(5), cse.node_ref(2), cse.node_ref(6), id);
201 _triangles.emplace_back(cse.node_ref(6), cse.node_ref(3), cse.node_ref(7), id);
202 _triangles.emplace_back(cse.node_ref(6), cse.node_ref(7), cse.node_ref(4), id);
203 _triangles.emplace_back(cse.node_ref(4), cse.node_ref(5), cse.node_ref(6), id);
207 _triangles.emplace_back(cse.node_ref(0), cse.node_ref(4), cse.node_ref(7), id);
208 _triangles.emplace_back(cse.node_ref(4), cse.node_ref(1), cse.node_ref(5), id);
209 _triangles.emplace_back(cse.node_ref(5), cse.node_ref(2), cse.node_ref(6), id);
210 _triangles.emplace_back(cse.node_ref(6), cse.node_ref(3), cse.node_ref(7), id);
211 _triangles.emplace_back(cse.node_ref(8), cse.node_ref(6), cse.node_ref(7), id);
212 _triangles.emplace_back(cse.node_ref(8), cse.node_ref(5), cse.node_ref(6), id);
213 _triangles.emplace_back(cse.node_ref(8), cse.node_ref(4), cse.node_ref(5), id);
214 _triangles.emplace_back(cse.node_ref(8), cse.node_ref(7), cse.node_ref(4), id);
225 const auto x = qp(0);
226 const auto y = qp(1);
229 for (
const auto & line :
_lines)
231 const auto & [p1, p2, line_id] = line;
237 const bool ordered = p1(1) <= p2(1);
239 const auto y1 = ordered ? p1(1) : p2(1);
240 const auto y2 = ordered ? p2(1) : p1(1);
242 if (
y >= y1 &&
y <= y2)
249 const auto x1 = ordered ? p1(0) : p2(0);
250 const auto x2 = ordered ? p2(0) : p1(0);
253 const auto xs = (x2 - x1) * (
y - y1) / (y2 - y1) + x1;
265 const auto x = qp(0);
266 const auto y = qp(1);
267 const auto z = qp(2);
272 const auto & [p1, p2, p3, triangle_id] = triangle;
275 if (triangle_id ==
id)
278 const auto x1 = p1(0);
279 const auto x2 = p2(0);
280 const auto x3 = p3(0);
282 const auto y1 = p1(1);
283 const auto y2 = p2(1);
284 const auto y3 = p3(1);
287 const auto a = ((y2 - y3) * (
x - x3) + (x3 - x2) * (
y - y3)) /
288 ((y2 - y3) * (x1 - x3) + (x3 - x2) * (y1 - y3));
289 const auto b = ((y3 - y1) * (
x - x3) + (x1 - x3) * (
y - y3)) /
290 ((y2 - y3) * (x1 - x3) + (x3 - x2) * (y1 - y3));
291 const auto c = 1.0 -
a -
b;
294 if (0 <=
a &&
a <= 1 && 0 <=
b &&
b <= 1 && 0 <=
c &&
c <= 1)
298 const auto zs =
a * p1(2) +
b * p2(2) +
c * p3(2);
317 auto & [p1, p2, p3, triangle_id] = triangle;
328 auto & [p1, p2, line_id] = line;
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
static InputParameters validParams()
static InputParameters validParams()
std::vector< const PostprocessorValue * > _raw_direction
raw illumination vector data (direction the radiation is propagating in)
GenericRealTensorValue< is_ad > rotVec2DToX(const GenericRealVectorValue< is_ad > &vec)
const unsigned int & _current_side
static constexpr Real TOLERANCE
unsigned int illumination(const SideIDType &id) const
const Elem *const & _current_side_elem
bool check2DIllumination(const Point &qp, const SideIDType &id)
const MooseArray< Point > & _q_point
std::tuple< Point, Point, Point, SideIDType > Triangle
const std::vector< double > y
const Parallel::Communicator & _communicator
std::map< SideIDType, unsigned int > & _illumination_status
illumination status data (partition local), we use a bit for each QP
const PostprocessorValue & getPostprocessorValue(const std::string ¶m_name, const unsigned int index=0) const
Given a radiation direction vector this user object computes the illumination state of each side QP o...
virtual void threadJoin(const UserObject &y) override
only needed for ElementUserObjects and NodalUseroObjects
virtual void initialize() override
void libmesh_ignore(const Args &...)
std::vector< Triangle > _triangles
global triange data (3D)
void addLines(const SideIDType &id)
const std::vector< double > x
RealTensorValue _rotation
matrix that rotates the direction onto the z-axis
virtual void finalize() override
std::pair< dof_id_type, unsigned int > SideIDType
GenericRealTensorValue< is_ad > rotVecToZ(GenericRealVectorValue< is_ad > vec)
bool check3DIllumination(const Point &qp, const SideIDType &id)
std::vector< LineSegment > _lines
global line segment data (2D)
SelfShadowSideUserObject(const InputParameters ¶meters)
void mooseError(Args &&... args) const
const Elem *const & _current_elem
const unsigned int _dim
problem dimension
std::vector< std::pair< SideIDType, MooseArray< Point > > > _local_qps
local QP data
registerMooseObject("HeatTransferApp", SelfShadowSideUserObject)
void rotate(MooseArray< Point > &points)
rotate all points in the given container
void addTriangles(const SideIDType &id)
virtual void execute() override
void ErrorVector unsigned int
auto index_range(const T &sizable)