12#include <boost/container/small_vector.hpp>
14#include <deal.II/base/table.h>
25 template <
int dim,
int spacedim>
27 spacedim>::TransfiniteInterpolationManifold()
30 AssertThrow(dim > 1, ExcNotImplemented());
34 template <
int dim,
int spacedim>
35 std::unique_ptr<Manifold<dim, spacedim>>
39 if (triangulation.n_levels() != 0)
40 ptr->initialize(triangulation, *chart_manifold);
41 return std::unique_ptr<Manifold<dim, spacedim>>(ptr);
45 template <
int dim,
int spacedim>
47 const Triangulation<dim, spacedim> &external_triangulation,
48 const Manifold<dim, spacedim> &chart_manifold)
50 this->triangulation.clear();
51 this->triangulation.copy_triangulation(external_triangulation);
53 this->chart_manifold = chart_manifold.clone();
55 level_coarse = triangulation.last()->level();
56 coarse_cell_is_flat.resize(triangulation.n_cells(level_coarse),
false);
57 typename Triangulation<dim, spacedim>::active_cell_iterator
58 cell = triangulation.begin(level_coarse),
59 endc = triangulation.end(level_coarse);
60 for (; cell != endc; ++cell) {
61 bool cell_is_flat =
true;
62 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++l)
63 if (cell->line(l)->manifold_id() != cell->manifold_id() &&
64 cell->line(l)->manifold_id() != numbers::flat_manifold_id)
67 for (
unsigned int q = 0; q < GeometryInfo<dim>::quads_per_cell; ++q)
68 if (cell->quad(q)->manifold_id() != cell->manifold_id() &&
69 cell->quad(q)->manifold_id() != numbers::flat_manifold_id)
71 AssertIndexRange(
static_cast<unsigned int>(cell->index()),
72 coarse_cell_is_flat.size());
73 coarse_cell_is_flat[cell->index()] = cell_is_flat;
81 template <
typename AccessorType>
82 Point<AccessorType::space_dimension>
83 compute_transfinite_interpolation(
const AccessorType &cell,
84 const Point<1> &chart_point,
87 return cell.vertex(0) * (1. - chart_point[0]) +
88 cell.vertex(1) * chart_point[0];
92 template <
typename AccessorType>
93 Point<AccessorType::space_dimension>
94 compute_transfinite_interpolation(
const AccessorType &cell,
95 const Point<2> &chart_point,
96 const bool cell_is_flat)
98 const unsigned int dim = AccessorType::dimension;
99 const unsigned int spacedim = AccessorType::space_dimension;
100 const types::manifold_id my_manifold_id = cell.manifold_id();
101 const Triangulation<dim, spacedim> &tria = cell.get_triangulation();
107 const std::array<Point<spacedim>, 4> vertices{
108 {cell.vertex(0), cell.vertex(1), cell.vertex(2), cell.vertex(3)}};
113 std::array<double, 4> weights_vertices{
114 {(1. - chart_point[0]) * (1. - chart_point[1]),
115 chart_point[0] * (1. - chart_point[1]),
116 (1. - chart_point[0]) * chart_point[1],
117 chart_point[0] * chart_point[1]}};
119 Point<spacedim> new_point;
121 for (
const unsigned int v : GeometryInfo<2>::vertex_indices())
122 new_point += weights_vertices[v] * vertices[v];
133 std::array<double, GeometryInfo<2>::vertices_per_face> weights;
134 std::array<Point<spacedim>, GeometryInfo<2>::vertices_per_face> points;
136 const auto weights_view =
137 make_array_view(weights.begin(), weights.end());
138 const auto points_view = make_array_view(points.begin(), points.end());
140 for (
unsigned int line = 0; line < GeometryInfo<2>::lines_per_cell;
142 const double my_weight =
143 (line % 2) ? chart_point[line / 2] : 1 - chart_point[line / 2];
144 const double line_point = chart_point[1 - line / 2];
150 const types::manifold_id line_manifold_id =
151 cell.line(line)->manifold_id();
152 if (line_manifold_id == my_manifold_id ||
153 line_manifold_id == numbers::flat_manifold_id) {
154 weights_vertices[GeometryInfo<2>::line_to_cell_vertices(line, 0)] -=
155 my_weight * (1. - line_point);
156 weights_vertices[GeometryInfo<2>::line_to_cell_vertices(line, 1)] -=
157 my_weight * line_point;
160 vertices[GeometryInfo<2>::line_to_cell_vertices(line, 0)];
162 vertices[GeometryInfo<2>::line_to_cell_vertices(line, 1)];
163 weights[0] = 1. - line_point;
164 weights[1] = line_point;
166 my_weight * tria.get_manifold(line_manifold_id)
167 .get_new_point(points_view, weights_view);
172 for (
const unsigned int v : GeometryInfo<2>::vertex_indices())
173 new_point -= weights_vertices[v] * vertices[v];
182 static constexpr unsigned int face_to_cell_vertices_3d[6][4] = {
193 static constexpr unsigned int face_to_cell_lines_3d[6][4] = {{8, 10, 0, 4},
201 template <
typename AccessorType>
202 Point<AccessorType::space_dimension>
203 compute_transfinite_interpolation(
const AccessorType &cell,
204 const Point<3> &chart_point,
205 const bool cell_is_flat)
207 const unsigned int dim = AccessorType::dimension;
208 const unsigned int spacedim = AccessorType::space_dimension;
209 const types::manifold_id my_manifold_id = cell.manifold_id();
210 const Triangulation<dim, spacedim> &tria = cell.get_triangulation();
214 const std::array<Point<spacedim>, 8> vertices{{cell.vertex(0),
226 double linear_shapes[10];
227 for (
unsigned int d = 0; d < 3; ++d) {
228 linear_shapes[2 * d] = 1. - chart_point[d];
229 linear_shapes[2 * d + 1] = chart_point[d];
233 for (
unsigned int d = 6; d < 10; ++d)
234 linear_shapes[d] = linear_shapes[d - 6];
236 std::array<double, 8> weights_vertices;
237 for (
unsigned int i2 = 0, v = 0; i2 < 2; ++i2)
238 for (
unsigned int i1 = 0; i1 < 2; ++i1)
239 for (
unsigned int i0 = 0; i0 < 2; ++i0, ++v)
240 weights_vertices[v] =
241 (linear_shapes[4 + i2] * linear_shapes[2 + i1]) *
244 Point<spacedim> new_point;
246 for (
unsigned int v = 0; v < 8; ++v)
247 new_point += weights_vertices[v] * vertices[v];
252 std::array<double, GeometryInfo<3>::lines_per_cell> weights_lines;
253 std::fill(weights_lines.begin(), weights_lines.end(), 0.0);
256 std::array<double, GeometryInfo<2>::vertices_per_cell> weights;
257 std::array<Point<spacedim>, GeometryInfo<2>::vertices_per_cell> points;
259 const auto weights_view =
260 make_array_view(weights.begin(), weights.end());
261 const auto points_view = make_array_view(points.begin(), points.end());
263 for (
const unsigned int face : GeometryInfo<3>::face_indices()) {
264 const double my_weight = linear_shapes[face];
265 const unsigned int face_even = face - face % 2;
267 if (std::abs(my_weight) < 1e-13)
272 const types::manifold_id face_manifold_id =
273 cell.face(face)->manifold_id();
274 if (face_manifold_id == my_manifold_id ||
275 face_manifold_id == numbers::flat_manifold_id) {
276 for (
unsigned int line = 0; line < GeometryInfo<2>::lines_per_cell;
278 const double line_weight = linear_shapes[face_even + 2 + line];
279 weights_lines[face_to_cell_lines_3d[face][line]] +=
280 my_weight * line_weight;
286 weights_vertices[face_to_cell_vertices_3d[face][0]] -=
287 linear_shapes[face_even + 2] *
288 (linear_shapes[face_even + 4] * my_weight);
289 weights_vertices[face_to_cell_vertices_3d[face][1]] -=
290 linear_shapes[face_even + 3] *
291 (linear_shapes[face_even + 4] * my_weight);
292 weights_vertices[face_to_cell_vertices_3d[face][2]] -=
293 linear_shapes[face_even + 2] *
294 (linear_shapes[face_even + 5] * my_weight);
295 weights_vertices[face_to_cell_vertices_3d[face][3]] -=
296 linear_shapes[face_even + 3] *
297 (linear_shapes[face_even + 5] * my_weight);
299 for (
const unsigned int v : GeometryInfo<2>::vertex_indices())
300 points[v] = vertices[face_to_cell_vertices_3d[face][v]];
302 linear_shapes[face_even + 2] * linear_shapes[face_even + 4];
304 linear_shapes[face_even + 3] * linear_shapes[face_even + 4];
306 linear_shapes[face_even + 2] * linear_shapes[face_even + 5];
308 linear_shapes[face_even + 3] * linear_shapes[face_even + 5];
310 my_weight * tria.get_manifold(face_manifold_id)
311 .get_new_point(points_view, weights_view);
316 const auto weights_view_line =
317 make_array_view(weights.begin(), weights.begin() + 2);
318 const auto points_view_line =
319 make_array_view(points.begin(), points.begin() + 2);
320 for (
unsigned int line = 0; line < GeometryInfo<3>::lines_per_cell;
322 const double line_point =
323 (line < 8 ? chart_point[1 - (line % 4) / 2] : chart_point[2]);
324 double my_weight = 0.;
326 my_weight = linear_shapes[line % 4] * linear_shapes[4 + line / 4];
328 const unsigned int subline = line - 8;
330 linear_shapes[subline % 2] * linear_shapes[2 + subline / 2];
332 my_weight -= weights_lines[line];
334 if (std::abs(my_weight) < 1e-13)
337 const types::manifold_id line_manifold_id =
338 cell.line(line)->manifold_id();
339 if (line_manifold_id == my_manifold_id ||
340 line_manifold_id == numbers::flat_manifold_id) {
341 weights_vertices[GeometryInfo<3>::line_to_cell_vertices(line, 0)] -=
342 my_weight * (1. - line_point);
343 weights_vertices[GeometryInfo<3>::line_to_cell_vertices(line, 1)] -=
344 my_weight * (line_point);
347 vertices[GeometryInfo<3>::line_to_cell_vertices(line, 0)];
349 vertices[GeometryInfo<3>::line_to_cell_vertices(line, 1)];
350 weights[0] = 1. - line_point;
351 weights[1] = line_point;
352 new_point -= my_weight * tria.get_manifold(line_manifold_id)
353 .get_new_point(points_view_line,
359 for (
const unsigned int v : GeometryInfo<dim>::vertex_indices())
360 new_point += weights_vertices[v] * vertices[v];
367 template <
int dim,
int spacedim>
368 Point<spacedim> TransfiniteInterpolationManifold<dim, spacedim>::push_forward(
369 const typename Triangulation<dim, spacedim>::cell_iterator &cell,
370 const Point<dim> &chart_point)
const
372 AssertDimension(cell->level(), level_coarse);
377 Assert(GeometryInfo<dim>::is_inside_unit_cell(chart_point, 5e-4),
378 ExcMessage(
"chart_point is not in unit interval"));
380 return compute_transfinite_interpolation(
381 *cell, chart_point, coarse_cell_is_flat[cell->index()]);
385 template <
int dim,
int spacedim>
386 DerivativeForm<1, dim, spacedim>
387 TransfiniteInterpolationManifold<dim, spacedim>::push_forward_gradient(
388 const typename Triangulation<dim, spacedim>::cell_iterator &cell,
389 const Point<dim> &chart_point,
390 const Point<spacedim> &pushed_forward_chart_point)
const
393 DerivativeForm<1, dim, spacedim> grad;
394 for (
unsigned int d = 0; d < dim; ++d) {
395 Point<dim> modified = chart_point;
396 const double step = chart_point[d] > 0.5 ? -1e-8 : 1e-8;
400 Tensor<1, spacedim> difference =
401 compute_transfinite_interpolation(
402 *cell, modified, coarse_cell_is_flat[cell->index()]) -
403 pushed_forward_chart_point;
404 for (
unsigned int e = 0; e < spacedim; ++e)
405 grad[e][d] = difference[e] /
step;
411 template <
int dim,
int spacedim>
412 Point<dim> TransfiniteInterpolationManifold<dim, spacedim>::pull_back(
413 const typename Triangulation<dim, spacedim>::cell_iterator &cell,
414 const Point<spacedim> &point,
415 const Point<dim> &initial_guess)
const
418 for (
unsigned int d = 0; d < dim; ++d)
422 Point<dim> chart_point =
423 GeometryInfo<dim>::project_to_unit_cell(initial_guess);
430 Tensor<1, spacedim> residual =
431 point - compute_transfinite_interpolation(
432 *cell, chart_point, coarse_cell_is_flat[cell->index()]);
433 const double tolerance =
434 1e-21 * Utilities::fixed_power<2>(cell->diameter());
435 double residual_norm_square = residual.norm_square();
436 DerivativeForm<1, dim, spacedim> inv_grad;
437 bool must_recompute_jacobian =
true;
438 for (
unsigned int i = 0; i < 100; ++i) {
439 if (residual_norm_square < tolerance) {
444 Tensor<1, dim> update;
445 for (
unsigned int d = 0; d < spacedim; ++d)
446 for (
unsigned int e = 0; e < dim; ++e)
447 update[e] += inv_grad[d][e] * residual[d];
448 return chart_point + update;
462 if (must_recompute_jacobian ||
463 (residual_norm_square > 1e4 * tolerance && i % 7 == 0)) {
469 DerivativeForm<1, dim, spacedim> grad = push_forward_gradient(
470 cell, chart_point, Point<spacedim>(point - residual));
471 if (grad.determinant() <= 0.0)
473 inv_grad = grad.covariant_form();
474 must_recompute_jacobian =
false;
476 Tensor<1, dim> update;
477 for (
unsigned int d = 0; d < spacedim; ++d)
478 for (
unsigned int e = 0; e < dim; ++e)
479 update[e] += inv_grad[d][e] * residual[d];
486 while (!GeometryInfo<dim>::is_inside_unit_cell(
487 chart_point + alpha * update, 0.2) &&
491 const Tensor<1, spacedim> old_residual = residual;
492 while (alpha > 1e-4) {
493 Point<dim> guess = chart_point + alpha * update;
494 const Tensor<1, dim> residual_guess =
495 point - compute_transfinite_interpolation(
496 *cell, guess, coarse_cell_is_flat[cell->index()]);
497 const double residual_norm_new = residual_guess.norm_square();
498 if (residual_norm_new < residual_norm_square) {
499 residual_norm_square = residual_norm_new;
500 chart_point += alpha * update;
501 residual = residual_guess;
518 if (must_recompute_jacobian ==
true) {
519 return residual_norm_square < std::sqrt(tolerance) ? chart_point
522 must_recompute_jacobian =
true;
534 const Tensor<1, spacedim> delta_f = old_residual - residual;
536 Tensor<1, dim> Jinv_deltaf;
537 for (
unsigned int d = 0; d < spacedim; ++d)
538 for (
unsigned int e = 0; e < dim; ++e)
539 Jinv_deltaf[e] += inv_grad[d][e] * delta_f[d];
541 const Tensor<1, dim> delta_x = alpha * update;
546 if (std::abs(delta_x * Jinv_deltaf) > 0.1 * tolerance &&
547 !must_recompute_jacobian) {
548 const Tensor<1, dim> factor =
549 (delta_x - Jinv_deltaf) / (delta_x * Jinv_deltaf);
550 Tensor<1, spacedim> jac_update;
551 for (
unsigned int d = 0; d < spacedim; ++d)
552 for (
unsigned int e = 0; e < dim; ++e)
553 jac_update[d] += delta_x[e] * inv_grad[d][e];
554 for (
unsigned int d = 0; d < spacedim; ++d)
555 for (
unsigned int e = 0; e < dim; ++e)
556 inv_grad[d][e] += factor[e] * jac_update[d];
563 template <
int dim,
int spacedim>
564 std::array<unsigned int, 20> TransfiniteInterpolationManifold<dim, spacedim>::
565 get_possible_cells_around_points(
566 const ArrayView<
const Point<spacedim>> &points)
const
574 Assert(triangulation.n_levels() != 0, ExcNotInitialized());
575 Assert(triangulation.begin_active()->level() == level_coarse,
580 auto cell = triangulation.begin(level_coarse);
581 const auto endc = triangulation.end(level_coarse);
582 boost::container::small_vector<std::pair<double, unsigned int>, 200>
584 for (; cell != endc; ++cell) {
586 if (cell->material_id() == 42)
589 std::array<Point<spacedim>, GeometryInfo<dim>::vertices_per_cell>
591 for (
const unsigned int vertex_n : GeometryInfo<dim>::vertex_indices()) {
592 vertices[vertex_n] = cell->vertex(vertex_n);
598 Point<spacedim> center;
599 for (
const unsigned int v : GeometryInfo<dim>::vertex_indices())
600 center += vertices[v];
601 center *= 1. / GeometryInfo<dim>::vertices_per_cell;
602 double radius_square = 0.;
603 for (
const unsigned int v : GeometryInfo<dim>::vertex_indices())
605 std::max(radius_square, (center - vertices[v]).norm_square());
606 bool inside_circle =
true;
607 for (
unsigned int i = 0; i < points.size(); ++i)
608 if ((center - points[i]).norm_square() > radius_square * 1.5) {
609 inside_circle =
false;
612 if (inside_circle ==
false)
616 double current_distance = 0;
617 for (
unsigned int i = 0; i < points.size(); ++i) {
619 cell->real_to_unit_cell_affine_approximation(points[i]);
620 current_distance += GeometryInfo<dim>::distance_to_unit_cell(point);
622 distances_and_cells.push_back(
623 std::make_pair(current_distance, cell->index()));
626 AssertThrow(distances_and_cells.size() > 0,
627 (
typename Mapping<dim, spacedim>::ExcTransformationFailed()));
628 std::sort(distances_and_cells.begin(), distances_and_cells.end());
629 std::array<unsigned int, 20> cells;
630 cells.fill(numbers::invalid_unsigned_int);
631 for (
unsigned int i = 0; i < distances_and_cells.size() && i < cells.size();
633 cells[i] = distances_and_cells[i].second;
639 template <
int dim,
int spacedim>
640 typename Triangulation<dim, spacedim>::cell_iterator
641 TransfiniteInterpolationManifold<dim, spacedim>::compute_chart_points(
642 const ArrayView<
const Point<spacedim>> &surrounding_points,
643 ArrayView<Point<dim>> chart_points)
const
645 Assert(surrounding_points.size() == chart_points.size(),
646 ExcMessage(
"The chart points array view must be as large as the "
647 "surrounding points array view."));
649 std::array<unsigned int, 20> nearby_cells =
650 get_possible_cells_around_points(surrounding_points);
674 auto guess_chart_point_structdim_2 =
675 [&](
const unsigned int i) -> Point<dim> {
677 surrounding_points.size() == 8 && 2 < i && i < 8,
678 ExcMessage(
"This function assumes that there are eight surrounding "
679 "points around a two-dimensional object. It also assumes "
680 "that the first three chart points have already been "
686 Assert(
false, ExcInternalError());
689 return chart_points[1] + (chart_points[2] - chart_points[0]);
691 return 0.5 * (chart_points[0] + chart_points[2]);
693 return 0.5 * (chart_points[1] + chart_points[3]);
695 return 0.5 * (chart_points[0] + chart_points[1]);
697 return 0.5 * (chart_points[2] + chart_points[3]);
699 Assert(
false, ExcInternalError());
726 auto guess_chart_point_structdim_3 =
727 [&](
const unsigned int i) -> Point<dim> {
729 surrounding_points.size() == 8 && 4 < i && i < 8,
730 ExcMessage(
"This function assumes that there are eight surrounding "
731 "points around a three-dimensional object. It also "
732 "assumes that the first five chart points have already "
734 return chart_points[i - 4] + (chart_points[4] - chart_points[0]);
738 bool use_structdim_2_guesses =
false;
739 bool use_structdim_3_guesses =
false;
744 if (surrounding_points.size() == 8) {
745 const Tensor<1, spacedim> v06 =
746 surrounding_points[6] - surrounding_points[0];
747 const Tensor<1, spacedim> v27 =
748 surrounding_points[7] - surrounding_points[2];
751 const double cosine = scalar_product(v06, v27) /
752 std::sqrt(v06.norm_square() * v27.norm_square());
756 use_structdim_2_guesses =
true;
757 else if (spacedim == 3)
760 use_structdim_3_guesses =
true;
763 Assert((!use_structdim_2_guesses && !use_structdim_3_guesses) ||
764 (use_structdim_2_guesses ^ use_structdim_3_guesses),
768 auto compute_chart_point =
769 [&](
const typename Triangulation<dim, spacedim>::cell_iterator &cell,
770 const unsigned int point_index) {
776 bool used_affine_approximation =
false;
779 if (point_index == 3 && surrounding_points.size() >= 8)
780 guess = chart_points[1] + (chart_points[2] - chart_points[0]);
781 else if (use_structdim_2_guesses && 3 < point_index)
782 guess = guess_chart_point_structdim_2(point_index);
783 else if (use_structdim_3_guesses && 4 < point_index)
784 guess = guess_chart_point_structdim_3(point_index);
785 else if (dim == 3 && point_index > 7 &&
786 surrounding_points.size() == 26) {
787 if (point_index < 20)
789 0.5 * (chart_points[GeometryInfo<dim>::line_to_cell_vertices(
790 point_index - 8, 0)] +
791 chart_points[GeometryInfo<dim>::line_to_cell_vertices(
792 point_index - 8, 1)]);
795 0.25 * (chart_points[GeometryInfo<dim>::face_to_cell_vertices(
796 point_index - 20, 0)] +
797 chart_points[GeometryInfo<dim>::face_to_cell_vertices(
798 point_index - 20, 1)] +
799 chart_points[GeometryInfo<dim>::face_to_cell_vertices(
800 point_index - 20, 2)] +
801 chart_points[GeometryInfo<dim>::face_to_cell_vertices(
802 point_index - 20, 3)]);
804 guess = cell->real_to_unit_cell_affine_approximation(
805 surrounding_points[point_index]);
806 used_affine_approximation =
true;
808 chart_points[point_index] =
809 pull_back(cell, surrounding_points[point_index], guess);
814 if (chart_points[point_index][0] ==
816 !used_affine_approximation) {
817 guess = cell->real_to_unit_cell_affine_approximation(
818 surrounding_points[point_index]);
819 chart_points[point_index] =
820 pull_back(cell, surrounding_points[point_index], guess);
823 if (chart_points[point_index][0] ==
825 for (
unsigned int d = 0; d < dim; ++d)
827 chart_points[point_index] =
828 pull_back(cell, surrounding_points[point_index], guess);
833 for (
unsigned int c = 0; c < nearby_cells.size(); ++c) {
834 typename Triangulation<dim, spacedim>::cell_iterator cell(
835 &triangulation, level_coarse, nearby_cells[c]);
836 bool inside_unit_cell =
true;
837 for (
unsigned int i = 0; i < surrounding_points.size(); ++i) {
838 compute_chart_point(cell, i);
842 if (GeometryInfo<dim>::is_inside_unit_cell(chart_points[i], 5e-4) ==
844 inside_unit_cell =
false;
848 if (inside_unit_cell ==
true) {
854 if (c == nearby_cells.size() - 1 ||
855 nearby_cells[c + 1] == numbers::invalid_unsigned_int) {
858 std::ostringstream message;
859 for (
unsigned int b = 0; b <= c; ++b) {
860 typename Triangulation<dim, spacedim>::cell_iterator cell(
861 &triangulation, level_coarse, nearby_cells[b]);
862 message <<
"Looking at cell " << cell->id()
863 <<
" with vertices: " << std::endl;
864 for (
const unsigned int v : GeometryInfo<dim>::vertex_indices())
865 message << std::setprecision(16) <<
" " << cell->vertex(v)
867 message << std::endl;
868 message <<
"Transformation to chart coordinates: " << std::endl;
869 for (
unsigned int i = 0; i < surrounding_points.size(); ++i) {
870 compute_chart_point(cell, i);
871 message << std::setprecision(16) << surrounding_points[i] <<
" -> "
872 << chart_points[i] << std::endl;
877 (
typename Mapping<dim, spacedim>::ExcTransformationFailed(
885 Assert(
false, ExcInternalError());
886 return typename Triangulation<dim, spacedim>::cell_iterator();
890 template <
int dim,
int spacedim>
893 const ArrayView<
const Point<spacedim>> &surrounding_points,
894 const ArrayView<const double> &weights)
const
896 boost::container::small_vector<Point<dim>, 100> chart_points(
897 surrounding_points.size());
898 ArrayView<Point<dim>> chart_points_view =
899 make_array_view(chart_points.begin(), chart_points.end());
901 compute_chart_points(surrounding_points, chart_points_view);
903 const Point<dim> p_chart =
904 chart_manifold->get_new_point(chart_points_view, weights);
906 return push_forward(cell, p_chart);
910 template <
int dim,
int spacedim>
912 const ArrayView<
const Point<spacedim>> &surrounding_points,
913 const Table<2, double> &weights,
914 ArrayView<Point<spacedim>> new_points)
const
916 Assert(weights.size(0) > 0, ExcEmptyObject());
917 AssertDimension(surrounding_points.size(), weights.size(1));
919 boost::container::small_vector<Point<dim>, 100> chart_points(
920 surrounding_points.size());
921 ArrayView<Point<dim>> chart_points_view =
922 make_array_view(chart_points.begin(), chart_points.end());
924 compute_chart_points(surrounding_points, chart_points_view);
926 boost::container::small_vector<Point<dim>, 100> new_points_on_chart(
928 chart_manifold->get_new_points(chart_points_view,
930 make_array_view(new_points_on_chart.begin(),
931 new_points_on_chart.end()));
933 for (
unsigned int row = 0; row < weights.size(0); ++row)
934 new_points[row] = push_forward(cell, new_points_on_chart[row]);
Point< spacedim > get_new_point(const ArrayView< const Point< spacedim > > &surrounding_points, const ArrayView< const double > &weights) const override
std::unique_ptr< Manifold< dim, spacedim > > clone() const override
void get_new_points(const ArrayView< const Point< spacedim > > &surrounding_points, const Table< 2, double > &weights, ArrayView< Point< spacedim > > new_points) const override
void initialize(const Triangulation< dim, spacedim > &triangulation, const Manifold< dim, spacedim > &chart_manifold=FlatManifold< dim >())
void step(Triangulation< dim, dim > &, const double, const double, const double, const double)
static constexpr double invalid_pull_back_coordinate