52 const std::vector<
Point<dim>> &quadrature_points)
const
54 std::vector<Point<dim>> closest_unit_search_points(quadrature_points);
55 for (
unsigned int q = 0; q < quadrature_points.size(); ++q)
56 closest_unit_search_points[q] =
57 mapping->transform_real_to_unit_cell(search_cell, quadrature_points[q]);
59 std::vector<Number> dof_values_level_set(
60 dof_handler->get_fe().dofs_per_cell);
61 std::vector<types::global_dof_index> level_set_dof_indices(
62 dof_handler->get_fe().dofs_per_cell);
65 &search_cell->get_triangulation(),
71 dof_cell->get_mg_dof_indices(level_set_dof_indices);
73 dof_cell->get_dof_indices(level_set_dof_indices);
75 level_set->extract_subvector_to(level_set_dof_indices,
76 dof_values_level_set);
78 for (
size_t i = 0; i < closest_unit_search_points.size(); ++i)
80 newton_monolithic(closest_unit_search_points[i],
81 dof_handler->get_fe(),
83 closest_unit_search_points[i]);
85 std::vector<Point<dim>> closest_real_points(quadrature_points.size());
86 std::vector<Point<dim>> closest_unit_reference_points(
87 quadrature_points.size());
89 for (
unsigned int q = 0; q < quadrature_points.size(); ++q)
90 closest_real_points[q] =
91 mapping->transform_unit_to_real_cell(search_cell,
92 closest_unit_search_points[q]);
94 for (
unsigned int q = 0; q < quadrature_points.size(); ++q)
95 closest_unit_reference_points[q] =
96 mapping->transform_real_to_unit_cell(reference_cell,
97 closest_real_points[q]);
99 return {closest_real_points, closest_unit_reference_points};
109 const std::vector<Number> &dof_values,
117 "The Newton iteration to find closest surface points requires hessians "
118 "that are not available when the finite element degree is 1."));
127 for (
unsigned int i = 0; i < dim; ++i)
128 current_solution[i] = closest_point[i];
131 for (
unsigned int newton_iter = 0; newton_iter <
data.n_iterations;
136 const double lambda = current_solution[dim];
137 for (
unsigned int k = 0; k < dof_values.size(); ++k)
139 const auto value_k = fe.
shape_value(k, closest_point);
140 const auto grad_k = fe.
shape_grad(k, closest_point);
142 for (
unsigned int i = 0; i < dim; ++i)
144 for (
unsigned int j = 0; j < dim; ++j)
145 hessian(i, j) += lambda * dof_values[k] * hess_k[i][j];
147 hessian(i, dim) += dof_values[k] * grad_k[i];
148 hessian(dim, i) += dof_values[k] * grad_k[i];
151 for (
unsigned int i = 0; i < dim; ++i)
152 residual[i] -= lambda * dof_values[k] * grad_k[i];
154 residual[dim] -= dof_values[k] * value_k;
158 for (
unsigned int i = 0; i < dim; ++i)
160 residual[i] -= current_solution[i] - point[i];
161 hessian[i][i] += 1.0;
168 hessian.gauss_jordan();
169 hessian.vmult(solution_update, residual);
170 current_solution += solution_update;
172 for (
unsigned int i = 0; i < dim; ++i)
173 closest_point[i] = current_solution[i];
178 ExcMessage(
"Newton iteration did not converge"));