42 double skeleton_length;
44 double cosecant_polar;
45 double cotangent_polar;
46 double cotangent_azimuth_half_right;
47 double cotangent_azimuth_half_left;
59 const AdditionalData &data)
66 +
x * data.cotangent_polar
69 ((
y > 0) ? data.cotangent_azimuth_half_right :
70 data.cotangent_azimuth_half_left);
81 template <
int dim,
int spacedim = dim>
107 const AdditionalData & data,
108 const double tolerance = 1e-10);
113 virtual std::unique_ptr<::Manifold<dim, spacedim>>
114 clone()
const override;
154 const AdditionalData data;
159 const double tolerance;
170 template <
int dim,
int spacedim>
171 Manifold<dim, spacedim>::Manifold(
175 const AdditionalData & data,
176 const double tolerance)
178 , normal_direction(normal_direction)
179 , direction(direction)
180 , point_on_axis(point_on_axis)
182 , tolerance(tolerance)
187 "PipeSegment::Manifold can only be used for spacedim==3!"));
190 ExcMessage(
"Normal direction must be unit vector."));
192 ExcMessage(
"Direction must be unit vector."));
193 Assert(normal_direction * direction < tolerance,
195 "Direction and normal direction must be perpendicular."));
200 template <
int dim,
int spacedim>
201 std::unique_ptr<::Manifold<dim, spacedim>>
204 return std::make_unique<Manifold<dim, spacedim>>(*this);
209 template <
int dim,
int spacedim>
218 const double r =
p_diff.norm();
220 Assert(r > tolerance * data.skeleton_length,
222 "This class won't handle points on the direction axis."));
235 return {r,
phi, lambda};
240 template <
int dim,
int spacedim>
252 const double lambda =
256 return point_on_axis + direction * lambda +
intermediate;
265 template <
int dim,
int spacedim>
287 constexpr unsigned int dim = 3;
288 constexpr unsigned int spacedim = 3;
291 constexpr unsigned int n_pipes = 3;
292 constexpr double tolerance = 1.e-12;
297 ExcMessage(
"Invalid input: negative radius."));
299 ExcMessage(
"Invalid input: only 3 openings allowed."));
307 const auto cyclic = [](
const unsigned int i) ->
unsigned int {
308 constexpr unsigned int n_pipes = 3;
309 return (i < (
n_pipes - 1)) ? i + 1 : 0;
311 const auto anticyclic = [](
const unsigned int i) ->
unsigned int {
312 constexpr unsigned int n_pipes = 3;
313 return (i > 0) ? i - 1 :
n_pipes - 1;
317 const std::array<vector3d, spacedim>
directions = {
324 std::array<vector3d, n_pipes>
skeleton;
325 for (
unsigned int p = 0; p <
n_pipes; ++p)
328 std::array<double, n_pipes> skeleton_length;
329 for (
unsigned int p = 0; p <
n_pipes; ++p)
338 *std::max_element(skeleton_length.begin(), skeleton_length.end());
341 for (
unsigned int p = 0; p <
n_pipes; ++p)
344 ExcMessage(
"Invalid input: bifurcation matches opening."));
360 ExcMessage(
"Invalid input: all three openings "
361 "are located on one line."));
362 normal /= normal.norm();
367 for (
unsigned int p = 0; p <
n_pipes; ++p)
389 ExcMessage(
"The output triangulation object needs to be empty."));
391 std::vector<PipeSegment::Manifold<dim, spacedim>> manifolds;
392 for (
unsigned int p = 0; p <
n_pipes; ++p)
406 1 +
static_cast<unsigned int>(std::ceil(
418 for (
const auto &cell :
pipe.active_cell_iterators())
420 cell->set_material_id(p);
422 for (
const auto &face : cell->face_iterators())
423 if (face->at_boundary())
425 const auto center_z = face->center()[2];
438 cell->set_all_manifold_ids(
n_pipes);
439 face->set_all_manifold_ids(p);
474 const double polar_angle =
488 ExcMessage(
"Invalid input: at least two openings located "
489 "in same direction from bifurcation"));
496 ExcMessage(
"Invalid input: at least two openings located "
497 "in same direction from bifurcation"));
501 PipeSegment::AdditionalData data;
502 data.skeleton_length = skeleton_length[p];
503 data.cosecant_polar = 1. /
std::sin(polar_angle);
504 data.cotangent_polar =
std::cos(polar_angle) * data.cosecant_polar;
507 data.cotangent_azimuth_half_left =
524 PipeSegment::compute_z_expansion(
x_new,
y_new, data);
526 ExcMessage(
"Invalid input: at least one pipe segment "
527 "is not long enough in this configuration"));
548 if (norm < tolerance)
603 manifolds.emplace_back(
615 for (
unsigned int p = 0; p <
n_pipes; ++p)
616 tria.set_manifold(p, manifolds[p]);
622 for (
const auto &cell :
tria.active_cell_iterators())
624 if (face->at_boundary())
627 face->manifold_id() ==
n_pipes)
629 face->set_boundary_id(cell->material_id());
632 face->set_boundary_id(
n_pipes);
642#include "grid_generator_pipe_junction.inst"
virtual std::unique_ptr< Manifold< dim, spacedim > > clone() const =0
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
void hyper_ball_balanced(Triangulation< dim > &tria, const Point< dim > ¢er=Point< dim >(), const double radius=1.)
void pipe_junction(Triangulation< dim, spacedim > &tria, const std::vector< std::pair< Point< spacedim >, double > > &openings, const std::pair< Point< spacedim >, double > &bifurcation, const double aspect_ratio=0.5)
void extrude_triangulation(const Triangulation< 2, 2 > &input, const unsigned int n_slices, const double height, Triangulation< 3, 3 > &result, const bool copy_manifold_ids=false, const std::vector< types::manifold_id > &manifold_priorities={})
void merge_triangulations(const Triangulation< dim, spacedim > &triangulation_1, const Triangulation< dim, spacedim > &triangulation_2, Triangulation< dim, spacedim > &result, const double duplicated_vertex_tolerance=1.0e-12, const bool copy_manifold_ids=false, const bool copy_boundary_ids=false)
double norm(const FEValuesBase< dim > &fe, const ArrayView< const std::vector< Tensor< 1, dim > > > &Du)
Number signed_angle(const Tensor< 1, spacedim, Number > &a, const Tensor< 1, spacedim, Number > &b, const Tensor< 1, spacedim, Number > &axis)
Number angle(const Tensor< 1, spacedim, Number > &a, const Tensor< 1, spacedim, Number > &b)
static constexpr double PI
const types::manifold_id flat_manifold_id
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > cos(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sin(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
const ::Triangulation< dim, spacedim > & tria