39 const auto coarsening_strategy =
41 const typename ::Triangulation<dim, spacedim>::cell_iterator
43 const std::vector<Vector<Number>> &children_values) {
58 Assert(fe.n_dofs_per_cell() > 0,
60 "Cannot coarsen onto a FiniteElement with no DoFs."));
62 children_values.size());
64 const auto child_iterators = dof_cell_iterator->child_iterators();
65 const unsigned int n_children_with_fe_nothing =
66 std::count_if(child_iterators.begin(),
67 child_iterators.end(),
68 [](
const auto &child_cell) {
69 return child_cell->get_fe().n_dofs_per_cell() ==
74 n_children_with_fe_nothing == 0 ||
75 n_children_with_fe_nothing == dof_cell_iterator->n_children(),
77 "Coarsening is only supported for parent cells where either all"
78 " or none of the child cells are FE_Nothing."));
83 if (n_children_with_fe_nothing == dof_cell_iterator->n_children())
85 return children_values[0];
88 const unsigned int dofs_per_cell = fe.n_dofs_per_cell();
95 for (
unsigned int child = 0;
96 child < dof_cell_iterator->n_children();
101 fe.get_restriction_matrix(child,
102 dof_cell_iterator->refinement_case())
103 .vmult(tmp, children_values[child]);
106 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
107 if (fe.restriction_is_additive(i))
108 interpolated_values(i) += tmp(i);
109 else if (tmp(i) !=
Number())
110 interpolated_values(i) = tmp(i);
113 return interpolated_values;
123 &::AdaptationStrategies::Refinement::
124 preserve<dim, spacedim, Vector<Number>>,
125 coarsening_strategy);
134 const VectorType &in,
135 const unsigned int fe_nothing_index)
137 const unsigned int dofs_per_cell =
138 dof_handler.get_fe_collection().max_dofs_per_cell();
143 for (
auto &val : dummy_cell_solution)
145 val = std::numeric_limits<Number>::infinity();
148 in.update_ghost_values();
150 std::vector<types::global_dof_index> dof_indices(dofs_per_cell);
151 for (
const auto &cell : dof_handler.active_cell_iterators())
153 if ((cell->is_locally_owned()) &&
154 (cell->active_fe_index() != fe_nothing_index))
156 cell->get_dof_values(in, cell_solution);
157 data_to_transfer.push_back(cell_solution);
161 data_to_transfer.push_back(dummy_cell_solution);
165 cell_data_transfer->prepare_for_coarsening_and_refinement(
178 const unsigned int dofs_per_cell =
179 dof_handler.get_fe_collection().max_dofs_per_cell();
180 std::vector<Vector<Number>> transferred_data(
181 dof_handler.get_triangulation().n_active_cells(),
184 cell_data_transfer->unpack(transferred_data);
187 data_to_transfer.clear();
189 for (
unsigned int i = 0; i < out.locally_owned_size(); ++i)
190 out.local_element(i) = std::numeric_limits<Number>::infinity();
192 unsigned int cell_i = 0;
193 for (
const auto &cell : dof_handler.active_cell_iterators())
195 if ((cell->is_locally_owned()) &&
196 (transferred_data[cell_i][0] !=
197 std::numeric_limits<Number>::infinity()))
199 cell->set_dof_values(transferred_data[cell_i], out);
209 std::vector<types::global_dof_index> dof_indices;
210 std::vector<types::global_dof_index> dofs_map;
211 std::vector<std::vector<std::pair<types::global_dof_index, Number>>>
213 std::vector<Number> constraint_values;
214 IndexSet locally_owned_dofs = dof_handler.locally_owned_dofs();
215 for (
auto constrained_dof : locally_owned_dofs)
220 const unsigned int line_size = constraint->size();
221 bool add_line =
false;
222 for (
unsigned int i = 0; i < line_size; ++i)
225 (*constraint)[i].first;
228 if (out[constraining_dof] ==
229 std::numeric_limits<Number>::infinity())
238 std::vector<std::pair<types::global_dof_index, Number>> line;
239 Number val = out[constrained_dof];
241 for (
unsigned int i = 0; i < line_size; ++i)
244 (*constraint)[i].first;
246 if (out[constraining_dof] ==
247 std::numeric_limits<Number>::infinity())
249 auto constraining_dof_map_it =
250 std::find(dofs_map.begin(),
253 if (constraining_dof_map_it == dofs_map.end())
255 dofs_map.push_back(constraining_dof);
257 line.push_back((*constraint)[i]);
262 out[constraining_dof] * (*constraint)[i].second;
265 constraint_lines.push_back(line);
266 constraint_values.push_back(val);
271 const unsigned int n_rows = constraint_lines.size();
274 const unsigned int n_cols = dofs_map.size();
278 for (
unsigned int i = 0; i < n_rows; ++i)
280 for (
unsigned int j = 0; j < n_cols; ++j)
282 if (j < constraint_lines[i].size())
285 std::find(dofs_map.begin(),
287 constraint_lines[i][j].first);
288 constraints_matrix(i,
289 constraint_it - dofs_map.begin()) =
290 constraint_lines[i][j].second;
294 constraint_values_vec[i] = constraint_values[i];
300 constraints_matrix.
vmult(new_constrained_values,
301 constraint_values_vec);
303 for (
unsigned int i = 0; i < n_cols; ++i)
305 out[dofs_map[i]] = new_constrained_values[i];
310 std::for_each(out.begin(), out.end(), [&](
Number &val) {
311 if (val == std::numeric_limits<Number>::infinity())