16#include "libmesh/replicated_mesh.h"
17#include "libmesh/mesh_generation.h"
18#include "libmesh/elem.h"
19#include "libmesh/node.h"
20#include "libmesh/enum_elem_type.h"
22namespace fs = std::filesystem;
28 _dim =
static_cast<unsigned int>(axis_pairs.size());
29 mooseAssert(
_dim == 2 ||
_dim == 3,
"OrientedBoundingBox requires 2 or 3 axis pairs");
37 for (
const auto i : make_range(
_dim))
40 _dirs[i] = vec.unit();
46 for (
const auto i : make_range(
_dim))
47 for ([[maybe_unused]]
const auto j : make_range(i + 1,
_dim))
48 mooseAssert(MooseUtils::absoluteFuzzyEqual(
_dirs[i] *
_dirs[j], 0.0),
49 "Basis directions are not orthogonal");
56 for (
const auto i : make_range(
_dim))
57 os <<
" axis[" << i <<
"] dir=" <<
_dirs[i] <<
", len=" <<
_len[i] <<
'\n';
64 for (
const auto i : make_range(
_dim))
66 const Real proj = rel *
_dirs[i];
67 if (!MooseUtils::absoluteFuzzyGreaterEqual(proj, 0.0, tolerance) ||
68 !MooseUtils::absoluteFuzzyLessEqual(proj,
_len[i], tolerance))
83 mooseAssert(i <
_dim,
"Invalid axis index");
90 mooseAssert(i <
_dim,
"Invalid axis index");
97 mooseAssert(i <
_dim,
"Invalid axis index");
99 return rel *
_dirs[i];
118 mooseAssert(
_dim == 2 ||
_dim == 3,
"writeMesh supports only 2D or 3D boxes.");
127 mesh, 1, 1, 1, 0., 1., 0., 1., 0., 1.,
libMesh::HEX8);
131 for (
auto * node :
mesh.node_ptr_range())
133 const Point reference = *node;
135 for (
const auto axis : make_range(
_dim))
136 mapped += reference(axis) *
_len[axis] *
_dirs[axis];
140 if (!path.parent_path().empty())
143 fs::create_directories(path.parent_path(), ec);
145 mesh.write(path.string());
152 mooseAssert(
_dim == 2 ||
_dim == 3,
"Ray writing only supports 2D or 3D");
154 unsigned int i_min = 0;
155 for (
const auto i : make_range(1u,
_dim))
160 for (
const auto i : make_range(
_dim))
164 const Point end = start +
_len[i_min] *
_dirs[i_min];
171 edge->set_node(0, n0);
172 edge->set_node(1, n1);
173 mesh.add_elem(std::move(edge));
174 mesh.prepare_for_use();
176 if (!ray_path.parent_path().empty())
179 fs::create_directories(ray_path.parent_path(), ec);
181 mesh.write(ray_path.string());
OrientedBoundingBox()
Default-constructs an empty box (zero dimension, no axes).
std::vector< Real > _len
length along each basis (size = _dim)
Point _minimal_corner
shared minimal corner
Real getAxisLength(unsigned int i) const
unsigned int _dim
spatial dimension (2 or 3)
std::vector< Point > _dirs
orthonormal basis vectors (size = _dim)
Point getMinimalCorner() const
bool contains(const Point &pt, const Real tolerance=libMesh::TOLERANCE) const
Test whether a point lies inside or on the box.
void writeRayAlongShortestAxis(const std::filesystem::path &ray_path, const libMesh::Parallel::Communicator &comm) const
Write a single-EDGE2 mesh representing a "ray" emanating from the box.
Point getAxisDirection(unsigned int i) const
Point getMaximalCorner() const
Point _maximal_corner
shared maximal corner
void writeMesh(const std::filesystem::path &path, const libMesh::Parallel::Communicator &comm) const
Write the oriented box as a single libMesh element to a mesh file.
Real getProjectedLength(const Point &pt, unsigned int i) const
Get the length of the projection of a point onto axis i.
void print(std::ostream &os) const
Print a summary (dimension, origin, axes).