36#include <boost/math/special_functions/relative_difference.hpp>
37#include <boost/math/special_functions/sign.hpp>
38#include <boost/math/tools/roots.hpp>
49 namespace QuadratureGeneratorImplementation
58 const unsigned int component_in_dim,
62 ExcMessage(
"Interval start must be less than interval end."));
64 const double length = end - start;
65 for (
unsigned int j = 0; j < quadrature1D.
size(); ++j)
67 const double x = start + length * quadrature1D.
point(j)[0];
69 point, component_in_dim, x),
70 length * weight * quadrature1D.
weight(j));
86 const unsigned int component_in_dim,
89 for (
unsigned int j = 0; j < lower.
size(); ++j)
106 const std::vector<std::reference_wrapper<
const Function<dim>>>
110 Assert(functions.size() > 0,
112 "The incoming vector must contain at least one function."));
114 const int sign_of_first =
115 boost::math::sign(functions[0].get().value(point));
117 if (sign_of_first == 0)
120 for (
unsigned int j = 1; j < functions.size(); ++j)
122 const int sign = boost::math::sign(functions[j].get().value(point));
124 if (sign != sign_of_first)
128 if (sign_of_first < 0)
152 std::pair<double, double> &value_bounds)
154 const ReferenceCell &cube = ReferenceCells::get_hypercube<dim>();
155 for (
unsigned int i = 0; i < cube.
n_vertices(); ++i)
157 const double vertex_value = function.
value(box.
vertex(i));
159 value_bounds.first =
std::min(value_bounds.first, vertex_value);
160 value_bounds.second =
std::max(value_bounds.second, vertex_value);
179 const std::vector<std::reference_wrapper<
const Function<dim>>>
184 all_function_bounds.clear();
185 all_function_bounds.reserve(functions.size());
189 FunctionTools::taylor_estimate_function_bounds<dim>(
193 all_function_bounds.push_back(bounds);
200 std::pair<double, double>
205 std::pair<double, double> extremes = bounds[0].value;
206 for (
unsigned int i = 1; i < bounds.size(); ++i)
208 extremes.first =
std::min(extremes.first, bounds[i].value.first);
209 extremes.second =
std::max(extremes.second, bounds[i].value.second);
224 if (function_bounds.first > 0)
226 if (function_bounds.second < 0)
256 Assert(function_bounds.first <= function_bounds.second,
257 ExcMessage(
"Function bounds reversed, max < min."));
259 return 0.5 * (
std::abs(function_bounds.second + function_bounds.first) -
260 (function_bounds.second - function_bounds.first));
274 std_cxx17::optional<HeightDirectionData>
280 std_cxx17::optional<std::array<double, dim>> min_lower_abs_grad;
288 if (!min_lower_abs_grad)
290 min_lower_abs_grad.emplace();
291 for (
unsigned int d = 0; d < dim; ++d)
293 (*min_lower_abs_grad)[d] =
299 for (
unsigned int d = 0; d < dim; ++d)
301 (*min_lower_abs_grad)[d] =
309 if (min_lower_abs_grad)
311 const auto max_element =
312 std::max_element(min_lower_abs_grad->begin(),
313 min_lower_abs_grad->end());
317 std::distance(min_lower_abs_grad->begin(), max_element);
323 return std_cxx17::optional<HeightDirectionData>();
338 if (all_function_bounds.size() != 2)
345 if (bounds0.
value.first > 0 && bounds1.
value.second < 0)
347 if (bounds1.
value.first > 0 && bounds0.
value.second < 0)
368 for (
unsigned int i = 0; i < unit_quadrature.
size(); ++i)
371 const double weight = unit_quadrature.
weight(i) * box.
volume();
392 const std::vector<std::reference_wrapper<
const Function<dim>>>
395 const unsigned int direction,
400 restrictions.clear();
401 restrictions.reserve(2 * functions.size());
406 for (
const auto &function : functions)
409 function, direction, bottom));
411 function, direction, top));
428 const std::vector<std::reference_wrapper<
const Function<dim>>>
431 const unsigned int open_direction,
436 restrictions.clear();
437 restrictions.reserve(functions.size());
438 for (
const auto &function : functions)
441 function, open_direction, point));
465 const std::vector<double> &roots,
468 const unsigned int height_function_direction,
469 const std::vector<std::reference_wrapper<
const Function<1>>>
475 const int n_roots = roots.size();
478 for (
int i = -1; i < n_roots; ++i)
481 const double start = i < 0 ? interval.
lower_bound(0) : roots[i];
483 i + 1 < n_roots ? roots[i + 1] : interval.
upper_bound(0);
485 const double length = end - start;
506 height_function_direction,
515 const double tolerance,
516 const unsigned int max_recursion_depth,
517 const unsigned int max_iterations)
518 : tolerance(tolerance)
519 , max_recursion_depth(max_recursion_depth)
520 , max_iterations(max_iterations)
533 const std::vector<std::reference_wrapper<
const Function<1>>> &functions,
535 std::vector<double> & roots)
539 const unsigned int recursion_depth = 0;
540 find_roots(function, interval, recursion_depth, roots);
543 std::sort(roots.begin(), roots.end());
545 const auto roots_are_equal = [
this](
const double &a,
const double &b) {
548 roots.erase(unique(roots.begin(), roots.end(), roots_are_equal),
557 const unsigned int recursion_depth,
558 std::vector<double> & roots)
561 const double left_value = function.
value(interval.
vertex(0));
562 const double right_value = function.
value(interval.
vertex(1));
565 if (boost::math::sign(left_value) != boost::math::sign(right_value))
567 const auto lambda = [&function](
const double x) {
571 const auto stopping_criteria = [
this](
const double &a,
578 const std::pair<double, double> root_bracket =
579 boost::math::tools::toms748_solve(lambda,
587 const double root = .5 * (root_bracket.first + root_bracket.second);
588 roots.push_back(root);
595 std::pair<double, double> value_bounds;
596 std::array<std::pair<double, double>, 1> gradient_bounds;
597 FunctionTools::taylor_estimate_function_bounds<1>(function,
604 const double function_min =
608 if (function_min > 0)
611 const double function_max =
615 if (function_max < 0)
650 this->quadrature_points.push_back(point);
651 this->weights.push_back(weight);
661 switch (definiteness)
684 const unsigned int direction,
692 const double bottom_value = level_set.
value(bottom_point);
698 const double top_value = level_set.
value(top_point);
708 template <
int dim,
int spacedim>
712 : q_collection1D(&q_collection1D)
713 , additional_data(additional_data)
715 RootFinder::AdditionalData(additional_data.root_finder_tolerance,
716 additional_data.max_root_finder_splits))
723 template <
int dim,
int spacedim>
726 const std::vector<std::reference_wrapper<
const Function<dim>>>
730 const unsigned int height_function_direction,
733 const Quadrature<1> &quadrature1D = (*q_collection1D)[q_index];
735 for (
unsigned int q = 0; q < low_dim_quadrature.
size(); ++q)
737 const Point<dim - 1> &point = low_dim_quadrature.
point(q);
738 const double weight = low_dim_quadrature.
weight(q);
741 height_function_direction,
745 const std::vector<std::reference_wrapper<const Function<1>>>
746 restrictions(point_restrictions.begin(),
747 point_restrictions.end());
750 box.
bounds(height_function_direction);
753 root_finder.find_roots(restrictions, bounds_in_direction, roots);
760 height_function_direction,
766 create_surface_point(point,
770 height_function_direction,
774 point_restrictions.clear();
779 template <
int dim,
int spacedim>
784 const std::vector<std::reference_wrapper<
const Function<dim>>>
787 const unsigned int height_function_direction,
797 if (roots.size() == 1)
800 point, height_function_direction, roots[0]);
816 point, height_function_direction, box, level_set);
821 normal *= 1. / normal.
norm();
825 const double surface_weight =
826 weight * gradient.norm() /
827 std::abs(gradient[height_function_direction]);
828 surface_quadrature.
push_back(surface_point, surface_weight, normal);
833 template <
int dim,
int spacedim>
836 unsigned int q_index)
839 this->q_index = q_index;
844 template <
int dim,
int spacedim>
848 : additional_data(additional_data)
849 , q_collection1D(&q_collection1D)
856 template <
int dim,
int spacedim>
861 , low_dim_algorithm(q_collection1D, additional_data)
862 , up_through_dimension_creator(q_collection1D, additional_data)
870 template <
int dim,
int spacedim>
879 template <
int dim,
int spacedim>
883 return q_partitioning;
888 template <
int dim,
int spacedim>
891 const std::vector<std::reference_wrapper<
const Function<dim>>>
894 const unsigned int n_box_splits)
896 std::vector<FunctionBounds<dim>> all_function_bounds;
899 const std::pair<double, double> extreme_values =
902 if (extreme_values.first > this->additional_data.limit_to_be_definite)
906 this->q_partitioning.positive);
908 else if (extreme_values.second <
909 -(this->additional_data.limit_to_be_definite))
913 this->q_partitioning.negative);
919 this->q_partitioning.indefinite);
923 const std_cxx17::optional<HeightDirectionData> data =
928 if (data && data->min_abs_dfdx >
929 this->additional_data.lower_bound_implicit_function)
931 create_low_dim_quadratures(data->direction,
935 create_high_dim_quadratures(data->direction, level_sets, box);
937 else if (n_box_splits < this->additional_data.max_box_splits)
939 split_box_and_recurse(level_sets, box, data, n_box_splits);
945 use_midpoint_method(level_sets, box);
958 std_cxx17::optional<unsigned int>
962 std::array<std::pair<double, unsigned int>, dim> side_lengths;
963 for (
unsigned int i = 0; i < dim; ++i)
966 side_lengths[i].second = i;
969 std::sort(side_lengths.begin(), side_lengths.end());
973 if (boost::math::epsilon_difference(side_lengths[dim - 1].
first,
975 return std_cxx17::optional<unsigned int>();
977 return side_lengths.back().second;
997 const std_cxx17::optional<HeightDirectionData> &height_direction_data)
999 const std_cxx17::optional<unsigned int> direction =
1007 if (height_direction_data)
1008 return height_direction_data->direction;
1028 corners.second[direction] -= .5 * box.
side_length(direction);
1047 corners.first[direction] += .5 * box.
side_length(direction);
1054 template <
int dim,
int spacedim>
1057 const std::vector<std::reference_wrapper<
const Function<dim>>>
1060 const std_cxx17::optional<HeightDirectionData> &direction_data,
1061 const unsigned int n_box_splits)
1063 if (this->additional_data.split_in_half)
1065 const unsigned int direction =
1071 generate(level_sets, left_box, n_box_splits + 1);
1072 generate(level_sets, right_box, n_box_splits + 1);
1076 for (
unsigned int i = 0;
1077 i < GeometryInfo<dim>::max_children_per_cell;
1080 generate(level_sets, box.
child(i), n_box_splits + 1);
1087 template <
int dim,
int spacedim>
1090 const unsigned int height_function_direction,
1094 const unsigned int n_box_splits)
1100 height_function_direction,
1104 const std::vector<std::reference_wrapper<
const Function<dim - 1>>>
1105 restrictions(face_restrictions.begin(), face_restrictions.end());
1110 low_dim_algorithm.clear_quadratures();
1111 low_dim_algorithm.generate(restrictions, cross_section, n_box_splits);
1116 template <
int dim,
int spacedim>
1119 const unsigned int height_function_direction,
1120 const std::vector<std::reference_wrapper<
const Function<dim>>>
1125 low_dim_algorithm.get_quadratures();
1128 (*this->q_collection1D)[this->q_index];
1134 height_function_direction,
1135 this->q_partitioning.negative);
1141 height_function_direction,
1142 this->q_partitioning.positive);
1144 up_through_dimension_creator.generate(level_sets,
1146 low_dim_quadratures.indefinite,
1147 height_function_direction,
1148 this->q_partitioning);
1153 template <
int dim,
int spacedim>
1156 const std::vector<std::reference_wrapper<
const Function<dim>>>
1165 this->q_partitioning.quadrature_by_definiteness(definiteness);
1172 template <
int dim,
int spacedim>
1178 this->q_index = q_index;
1179 low_dim_algorithm.set_1D_quadrature(q_index);
1180 up_through_dimension_creator.set_1D_quadrature(q_index);
1185 template <
int spacedim>
1191 RootFinder::AdditionalData(additional_data.root_finder_tolerance,
1192 additional_data.max_root_finder_splits))
1195 ExcMessage(
"Incoming quadrature collection is empty."));
1200 template <
int spacedim>
1203 const std::vector<std::reference_wrapper<
const Function<1>>>
1206 const unsigned int n_box_splits)
1211 root_finder.find_roots(level_sets, box, roots);
1214 (*this->q_collection1D)[this->q_index];
1223 this->additional_data,
1224 this->q_partitioning);
1227 this->create_surface_points(level_sets);
1232 template <
int spacedim>
1235 const std::vector<std::reference_wrapper<
const Function<1>>>
1240 for (
const double root : roots)
1244 const double weight = 1;
1247 Tensor<1, 1> normal = level_sets[0].get().gradient(point);
1248 const double gradient_norm = normal.
norm();
1250 gradient_norm > 1e-11,
1252 "The level set function has a gradient almost equal to 0."));
1253 normal *= 1. / gradient_norm;
1255 this->q_partitioning.surface.push_back(point, weight, normal);
1261 template <
int spacedim>
1266 this->q_index = q_index;
1275 namespace DiscreteQuadratureGeneratorImplementation
1279 "The set_active_cell function has to be called before calling this function.");
1283 "The reference cell of the incoming cell must be a hypercube.");
1311 template <
int dim,
class VectorType = Vector<
double>>
1323 const VectorType & dof_values);
1341 const unsigned int component = 0)
const override;
1352 const unsigned int component = 0)
const override;
1363 const unsigned int component = 0)
const override;
1405 std::vector<Polynomials::Polynomial<double>>
poly;
1420 template <
int dim,
class VectorType>
1423 const VectorType & dof_values)
1424 : dof_handler(&dof_handler)
1425 , global_dof_values(&dof_values)
1433 template <
int dim,
class VectorType>
1439 &cell->get_triangulation() == &dof_handler->get_triangulation(),
1441 "The incoming cell must belong to the triangulation associated with "
1442 "the DoFHandler passed to the constructor."));
1445 &dof_handler->get_triangulation(),
1456 if (element != &dof_handler_cell->
get_fe())
1459 element = &dof_handler_cell->
get_fe();
1461 if (element->n_base_elements() == 1 &&
1472 element->base_element(0));
1474 polynomials_are_hat_functions =
1475 (poly.size() == 2 && poly[0].value(0.) == 1. &&
1476 poly[0].value(1.) == 0. && poly[1].value(0.) == 0. &&
1477 poly[1].value(1.) == 1.);
1481 element = &dof_handler_cell->
get_fe();
1483 local_dof_indices.resize(element->dofs_per_cell);
1484 dof_handler_cell->get_dof_indices(local_dof_indices);
1486 local_dof_values.resize(element->dofs_per_cell);
1488 for (
unsigned int i = 0; i < local_dof_indices.size(); ++i)
1489 local_dof_values[i] =
1491 *global_dof_values, local_dof_indices[i]);
1496 template <
int dim,
class VectorType>
1502 return local_dof_values.size() > 0;
1507 template <
int dim,
class VectorType>
1511 const unsigned int component)
const
1516 if (!poly.empty() && component == 0)
1519 return ::internal::evaluate_tensor_product_value(
1523 polynomials_are_hat_functions,
1529 for (
unsigned int i = 0; i < local_dof_indices.size(); ++i)
1530 value += local_dof_values[i] *
1531 element->shape_value_component(i, point, component);
1539 template <
int dim,
class VectorType>
1543 const unsigned int component)
const
1548 if (!poly.empty() && component == 0)
1551 return ::internal::evaluate_tensor_product_value_and_gradient(
1555 polynomials_are_hat_functions,
1562 for (
unsigned int i = 0; i < local_dof_indices.size(); ++i)
1563 gradient += local_dof_values[i] *
1564 element->shape_grad_component(i, point, component);
1572 template <
int dim,
class VectorType>
1576 const unsigned int component)
const
1581 if (!poly.empty() && component == 0)
1584 return ::internal::evaluate_tensor_product_hessian(
1585 poly, local_dof_values, point, renumber);
1590 for (
unsigned int i = 0; i < local_dof_indices.size(); ++i)
1592 local_dof_values[i] *
1593 element->shape_grad_grad_component(i, point, component);
1604 const unsigned int max_box_splits,
1605 const double lower_bound_implicit_function,
1606 const double min_distance_between_roots,
1607 const double limit_to_be_definite,
1608 const double root_finder_tolerance,
1609 const unsigned int max_root_finder_splits,
1611 : max_box_splits(max_box_splits)
1612 , lower_bound_implicit_function(lower_bound_implicit_function)
1613 , min_distance_between_roots(min_distance_between_roots)
1614 , limit_to_be_definite(limit_to_be_definite)
1615 , root_finder_tolerance(root_finder_tolerance)
1616 , max_root_finder_splits(max_root_finder_splits)
1617 , split_in_half(split_in_half)
1626 : q_generator(q_collection, additional_data)
1629 ExcMessage(
"Incoming hp::QCollection<1> is empty."));
1641 "The incoming function should be a scalar level set function,"
1642 " it should have one component."));
1645 q_generator.clear_quadratures();
1647 std::vector<std::reference_wrapper<const Function<dim>>> level_sets;
1648 level_sets.push_back(level_set);
1650 const unsigned int n_box_splits = 0;
1651 q_generator.generate(level_sets, box, n_box_splits);
1657 q_generator.get_quadratures().indefinite.size() == 0,
1659 "Generation of quadrature rules failed. This can mean that the level "
1660 "set function is degenerate in some way, e.g. oscillating extremely "
1670 return q_generator.get_quadratures().negative;
1679 return q_generator.get_quadratures().positive;
1688 return q_generator.get_quadratures().surface;
1696 q_generator.set_1D_quadrature(q_index);
1705 : quadrature_generator(quadratures1D, additional_data)
1714 const unsigned int face_index)
1721 const unsigned int face_normal_direction =
1726 const double coordinate_value = vertex0(face_normal_direction);
1729 level_set, face_normal_direction, coordinate_value);
1734 quadrature_generator.generate(face_restriction, cross_section);
1739 &surface_quadrature_wrong_normal =
1740 quadrature_generator.get_surface_quadrature();
1742 std::vector<Tensor<1, dim>> normals;
1743 normals.reserve(surface_quadrature_wrong_normal.size());
1744 for (
unsigned int i = 0; i < surface_quadrature_wrong_normal.size(); ++i)
1747 surface_quadrature_wrong_normal.point(i),
1748 face_normal_direction,
1752 normal /= normal.
norm();
1753 normals.push_back(normal);
1756 surface_quadrature_wrong_normal.get_points(),
1757 surface_quadrature_wrong_normal.get_weights(),
1767 quadrature_generator.set_1D_quadrature(q_index);
1776 return quadrature_generator.get_inside_quadrature();
1784 return quadrature_generator.get_outside_quadrature();
1793 return surface_quadrature;
1802 (void)quadratures1D;
1803 (void)additional_data;
1811 const unsigned int face_index)
1819 const unsigned int n_points = 1;
1820 const double weight = 1;
1821 const std::vector<Point<0>> points(n_points);
1822 const std::vector<double> weights(n_points, weight);
1824 const double level_set_value = level_set.
value(vertex);
1825 if (level_set_value < 0)
1830 else if (level_set_value > 0)
1855 return inside_quadrature;
1862 return outside_quadrature;
1870 return surface_quadrature;
1876 template <
class VectorType>
1880 const VectorType & level_set,
1883 , reference_space_level_set(
1884 std::make_unique<
internal::DiscreteQuadratureGeneratorImplementation::
1885 RefSpaceFEFieldFunction<dim, VectorType>>(
1897 Assert(cell->reference_cell().is_hyper_cube(),
1898 internal::DiscreteQuadratureGeneratorImplementation::
1899 ExcReferenceCellNotHypercube());
1901 reference_space_level_set->set_active_cell(cell);
1909 template <
class VectorType>
1913 const VectorType & level_set,
1916 , reference_space_level_set(
1917 std::make_unique<
internal::DiscreteQuadratureGeneratorImplementation::
1918 RefSpaceFEFieldFunction<dim, VectorType>>(
1929 const unsigned int face_index)
1931 Assert(cell->reference_cell().is_hyper_cube(),
1932 internal::DiscreteQuadratureGeneratorImplementation::
1933 ExcReferenceCellNotHypercube());
1935 reference_space_level_set->set_active_cell(cell);
1942#include "quadrature_generator.inst"
BoundingBox< 1, Number > bounds(const unsigned int direction) const
Point< spacedim, Number > center() const
Number lower_bound(const unsigned int direction) const
std::pair< Point< spacedim, Number >, Point< spacedim, Number > > & get_boundary_points()
Number side_length(const unsigned int direction) const
BoundingBox< spacedim, Number > child(const unsigned int index) const
Point< spacedim, Number > vertex(const unsigned int index) const
BoundingBox< spacedim - 1, Number > cross_section(const unsigned int direction) const
Number upper_bound(const unsigned int direction) const
Point< spacedim, Number > unit_to_real(const Point< spacedim, Number > &point) const
const FiniteElement< dim, spacedim > & get_fe(const types::fe_index index=0) const
virtual Tensor< 1, dim, RangeNumberType > gradient(const Point< dim > &p, const unsigned int component=0) const
const unsigned int n_components
virtual RangeNumberType value(const Point< dim > &p, const unsigned int component=0) const
DiscreteFaceQuadratureGenerator(const hp::QCollection< 1 > &quadratures1D, const DoFHandler< dim > &dof_handler, const VectorType &level_set, const AdditionalData &additional_data=AdditionalData())
void generate(const typename Triangulation< dim >::active_cell_iterator &cell, const unsigned int face_index)
void generate(const typename Triangulation< dim >::active_cell_iterator &cell)
DiscreteQuadratureGenerator(const hp::QCollection< 1 > &quadratures1D, const DoFHandler< dim > &dof_handler, const VectorType &level_set, const AdditionalData &additional_data=AdditionalData())
const Quadrature< dim - 1 > & get_inside_quadrature() const
void generate(const Function< dim > &level_set, const BoundingBox< dim > &box, const unsigned int face_index)
void set_1D_quadrature(const unsigned int q_index)
FaceQuadratureGenerator(const hp::QCollection< 1 > &quadratures1D, const AdditionalData &additional_data=AdditionalData())
const ImmersedSurfaceQuadrature< dim - 1, dim > & get_surface_quadrature() const
const Quadrature< dim - 1 > & get_outside_quadrature() const
void push_back(const Point< dim > &point, const double weight, const Tensor< 1, spacedim > &normal)
void set_1D_quadrature(const unsigned int q_index)
QuadratureGenerator(const hp::QCollection< 1 > &quadratures1D, const AdditionalData &additional_data=AdditionalData())
const Quadrature< dim > & get_inside_quadrature() const
const Quadrature< dim > & get_outside_quadrature() const
const ImmersedSurfaceQuadrature< dim > & get_surface_quadrature() const
void generate(const Function< dim > &level_set, const BoundingBox< dim > &box)
void set_active_cell(const typename Triangulation< dim >::active_cell_iterator &cell) override
Tensor< 1, dim > gradient(const Point< dim > &point, const unsigned int component=0) const override
double value(const Point< dim > &point, const unsigned int component=0) const override
std::vector< types::global_dof_index > local_dof_indices
bool polynomials_are_hat_functions
RefSpaceFEFieldFunction(const DoFHandler< dim > &dof_handler, const VectorType &dof_values)
const SmartPointer< const DoFHandler< dim > > dof_handler
std::vector< Polynomials::Polynomial< double > > poly
SymmetricTensor< 2, dim > hessian(const Point< dim > &point, const unsigned int component=0) const override
SmartPointer< const FiniteElement< dim > > element
std::vector< unsigned int > renumber
std::vector< typename VectorType::value_type > local_dof_values
const SmartPointer< const VectorType > global_dof_values
void push_back(const Point< dim > &point, const double weight)
ExtendableQuadrature()=default
const SmartPointer< const hp::QCollection< 1 > > q_collection1D
QGeneratorBase(const hp::QCollection< 1 > &q_collection1D, const AdditionalQGeneratorData &additional_data)
const QPartitioning< dim > & get_quadratures() const
QGenerator(const hp::QCollection< 1 > &q_collection1D, const AdditionalQGeneratorData &additional_data)
void set_1D_quadrature(const unsigned int q_index)
void create_high_dim_quadratures(const unsigned int height_function_direction, const std::vector< std::reference_wrapper< const Function< dim > > > &level_sets, const BoundingBox< dim > &box)
void generate(const std::vector< std::reference_wrapper< const Function< dim > > > &level_sets, const BoundingBox< dim > &box, const unsigned int n_box_splits)
hp::QCollection< dim > tensor_products
void use_midpoint_method(const std::vector< std::reference_wrapper< const Function< dim > > > &level_sets, const BoundingBox< dim > &box)
void split_box_and_recurse(const std::vector< std::reference_wrapper< const Function< dim > > > &level_sets, const BoundingBox< dim > &box, const std_cxx17::optional< HeightDirectionData > &direction_data, const unsigned int n_box_splits)
void create_low_dim_quadratures(const unsigned int height_function_direction, const std::vector< std::reference_wrapper< const Function< dim > > > &level_sets, const BoundingBox< dim > &box, const unsigned int n_box_splits)
ExtendableQuadrature< dim > & quadrature_by_definiteness(const Definiteness definiteness)
ImmersedSurfaceQuadrature< dim > surface
const AdditionalData additional_data
void find_roots(const std::vector< std::reference_wrapper< const Function< 1 > > > &functions, const BoundingBox< 1 > &interval, std::vector< double > &roots)
RootFinder(const AdditionalData &data=AdditionalData())
void generate(const std::vector< std::reference_wrapper< const Function< dim > > > &level_sets, const BoundingBox< dim > &box, const Quadrature< dim - 1 > &low_dim_quadrature, const unsigned int height_function_direction, QPartitioning< dim > &q_partitioning)
void set_1D_quadrature(const unsigned int q_index)
void create_surface_point(const Point< dim - 1 > &point, const double weight, const std::vector< std::reference_wrapper< const Function< dim > > > &level_sets, const BoundingBox< dim > &box, const unsigned int height_function_direction, ImmersedSurfaceQuadrature< dim > &surface_quadrature)
UpThroughDimensionCreator(const hp::QCollection< 1 > &q_collection1D, const AdditionalQGeneratorData &additional_data)
const Point< dim > & point(const unsigned int i) const
double weight(const unsigned int i) const
unsigned int size() const
unsigned int n_vertices() const
numbers::NumberTraits< Number >::real_type norm() const
unsigned int size() const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#define Assert(cond, exc)
static ::ExceptionBase & ExcCellNotSet()
#define AssertIndexRange(index, range)
#define DeclExceptionMsg(Exception, defaulttext)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcReferenceCellNotHypercube()
static ::ExceptionBase & ExcMessage(std::string arg1)
typename ActiveSelector::active_cell_iterator active_cell_iterator
unsigned int compute_split_direction(const BoundingBox< dim > &box, const std_cxx17::optional< HeightDirectionData > &height_direction_data)
void distribute_points_between_roots(const Quadrature< 1 > &quadrature1D, const BoundingBox< 1 > &interval, const std::vector< double > &roots, const Point< dim - 1 > &point, const double weight, const unsigned int height_function_direction, const std::vector< std::reference_wrapper< const Function< 1 > > > &level_sets, const AdditionalQGeneratorData &additional_data, QPartitioning< dim > &q_partitioning)
double lower_bound_on_abs(const std::pair< double, double > &function_bounds)
void estimate_function_bounds(const std::vector< std::reference_wrapper< const Function< dim > > > &functions, const BoundingBox< dim > &box, std::vector< FunctionBounds< dim > > &all_function_bounds)
BoundingBox< dim > left_half(const BoundingBox< dim > &box, const unsigned int direction)
void add_tensor_product(const Quadrature< dim - 1 > &lower, const Quadrature< 1 > &quadrature1D, const double start, const double end, const unsigned int component_in_dim, ExtendableQuadrature< dim > &quadrature)
bool one_positive_one_negative_definite(const std::vector< FunctionBounds< dim > > &all_function_bounds)
std_cxx17::optional< HeightDirectionData > find_best_height_direction(const std::vector< FunctionBounds< dim > > &all_function_bounds)
void map_quadrature_to_box(const Quadrature< dim > &unit_quadrature, const BoundingBox< dim > &box, ExtendableQuadrature< dim > &quadrature)
std::pair< double, double > find_extreme_values(const std::vector< FunctionBounds< dim > > &all_function_bounds)
void tensor_point_with_1D_quadrature(const Point< dim - 1 > &point, const double weight, const Quadrature< 1 > &quadrature1D, const double start, const double end, const unsigned int component_in_dim, ExtendableQuadrature< dim > &quadrature)
void restrict_to_point(const std::vector< std::reference_wrapper< const Function< dim > > > &functions, const Point< dim - 1 > &point, const unsigned int open_direction, std::vector< Functions::PointRestriction< dim - 1 > > &restrictions)
std_cxx17::optional< unsigned int > direction_of_largest_extent(const BoundingBox< dim > &box)
BoundingBox< dim > right_half(const BoundingBox< dim > &box, const unsigned int direction)
bool is_indefinite(const std::pair< double, double > &function_bounds)
void take_min_max_at_vertices(const Function< dim > &function, const BoundingBox< dim > &box, std::pair< double, double > &value_bounds)
void restrict_to_top_and_bottom(const std::vector< std::reference_wrapper< const Function< dim > > > &functions, const BoundingBox< dim > &box, const unsigned int direction, std::vector< Functions::CoordinateRestriction< dim - 1 > > &restrictions)
Point< dim > face_projection_closest_zero_contour(const Point< dim - 1 > &point, const unsigned int direction, const BoundingBox< dim > &box, const Function< dim > &level_set)
Definiteness pointwise_definiteness(const std::vector< std::reference_wrapper< const Function< dim > > > &functions, const Point< dim > &point)
std::vector< Polynomials::Polynomial< double > > get_polynomial_space(const FiniteElement< dim, spacedim > &fe)
bool is_fast_path_supported(const FiniteElement< dim, spacedim > &fe, const unsigned int base_element_number)
Point< dim+1 > create_higher_dim_point(const Point< dim > &point, const unsigned int component_in_dim_plus_1, const double coordinate_value)
static const unsigned int invalid_unsigned_int
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
double min_distance_between_roots
AdditionalQGeneratorData(const unsigned int max_box_splits=4, const double lower_bound_implicit_function=1e-11, const double min_distance_between_roots=1e-12, const double limit_to_be_definite=1e-11, const double root_finder_tolerance=1e-12, const unsigned int max_root_finder_splits=2, bool split_in_half=true)
std::array< std::pair< double, double >, dim > gradient
std::pair< double, double > value
AdditionalData(const double tolerance=1e-12, const unsigned int max_recursion_depth=2, const unsigned int max_iterations=500)
unsigned int max_iterations
unsigned int max_recursion_depth
void reinit(const Quadrature< dim_q > &quad, const FiniteElement< dim, spacedim > &fe_dim, const unsigned int base_element=0)
std::vector< unsigned int > lexicographic_numbering
DEAL_II_HOST constexpr SymmetricTensor< 2, dim, Number > symmetrize(const Tensor< 2, dim, Number > &t)