219 const std::vector<std::pair<types::global_dof_index, number2>> &entries)
221 next_constraint.first.resize(entries.size());
222 if (entries.size() > 0)
224 constraint_indices.resize(entries.size());
227 constraint_entries.assign(entries.begin(), entries.end());
228 std::sort(constraint_entries.begin(),
229 constraint_entries.end(),
230 [](
const std::pair<types::global_dof_index, double> &p1,
231 const std::pair<types::global_dof_index, double> &p2) {
232 return p1.second < p2.second;
238 constraint_indices[j] = constraint_entries[j].first;
241 next_constraint.first[j] = constraint_entries[j].second;
253 const auto position = constraints.find(next_constraint.first);
254 if (position != constraints.end())
255 insert_position = position->second;
258 next_constraint.second = constraints.size();
259 constraints.insert(next_constraint);
260 insert_position = next_constraint.second;
265 Assert(insert_position < (1 << (8 *
sizeof(
unsigned short))),
267 return static_cast<unsigned short>(insert_position);
300 const unsigned int n_cells,
301 const bool use_fast_hanging_node_algorithm)
303 this->dof_indices_per_cell.resize(n_cells);
304 this->plain_dof_indices_per_cell.resize(n_cells);
305 this->constraint_indicator_per_cell.resize(n_cells);
308 const bool has_hanging_nodes =
311 if (use_fast_hanging_node_algorithm && has_hanging_nodes)
313 hanging_nodes = std::make_unique<HangingNodes<dim>>(
316 hanging_node_constraint_masks.resize(n_cells);
320 lexicographic_numbering.resize(fes.size());
321 shape_infos.resize(fes.size());
323 for (
unsigned int i = 0; i < fes.size(); ++i)
325 if (fes[i].reference_cell().is_hyper_cube())
329 shape_infos[i].reinit(dummy_quadrature, fes[i], 0);
333 const auto dummy_quadrature =
334 fes[i].reference_cell().template get_gauss_type_quadrature<dim>(
336 shape_infos[i].reinit(dummy_quadrature, fes[i], 0);
339 lexicographic_numbering[i] = shape_infos[i].lexicographic_numbering;
341 active_fe_indices.resize(n_cells);
360 const unsigned int cell_no,
361 const unsigned int mg_level,
363 const ::AffineConstraints<typename Number::value_type> &constraints,
364 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner)
366 local_dof_indices.resize(cell->get_fe().n_dofs_per_cell());
367 local_dof_indices_lex.resize(cell->get_fe().n_dofs_per_cell());
370 cell->get_dof_indices(local_dof_indices);
372 cell->get_mg_dof_indices(local_dof_indices);
377 const auto &lexicographic_numbering =
378 shape_infos[cell->active_fe_index()].lexicographic_numbering;
381 local_dof_indices.size());
383 for (
unsigned int i = 0; i < cell->get_fe().n_dofs_per_cell(); ++i)
384 local_dof_indices_lex[i] =
385 local_dof_indices[lexicographic_numbering[i]];
388 std::pair<unsigned short, unsigned short> constraint_iterator(0, 0);
394 auto &constraint_indicator = this->constraint_indicator_per_cell[cell_no];
395 auto &dof_indices = this->dof_indices_per_cell[cell_no];
396 auto &plain_dof_indices = this->plain_dof_indices_per_cell[cell_no];
402 const auto global_to_local =
405 return partitioner->global_to_local(global_index);
408 if (local_range.first <= global_index &&
409 global_index < local_range.second)
410 return global_index - local_range.first;
412 return global_index + (local_range.second - local_range.first);
417 plain_dof_indices.resize(local_dof_indices_lex.size());
418 for (
unsigned int i = 0; i < local_dof_indices_lex.size(); ++i)
419 plain_dof_indices[i] = global_to_local(local_dof_indices_lex[i]);
427 cell->get_fe().n_components(),
429 hanging_nodes->setup_constraints(
430 cell, {}, lexicographic_numbering, local_dof_indices_lex,
mask);
432 hanging_node_constraint_masks[cell_no] =
compress(
mask[0], dim);
433 active_fe_indices[cell_no] = cell->active_fe_index();
436 for (
auto current_dof : local_dof_indices_lex)
438 const auto *entries_ptr =
439 constraints.get_constraint_entries(current_dof);
442 if (entries_ptr !=
nullptr)
444 const auto &entries = *entries_ptr;
446 if (n_entries == 1 &&
448 typename Number::value_type(1.)) <
449 100 * std::numeric_limits<double>::epsilon())
451 current_dof = entries[0].first;
455 constraint_indicator.push_back(constraint_iterator);
456 constraint_indicator.back().second =
457 constraint_values.insert_entries(entries);
460 constraint_iterator.first = 0;
464 const std::vector<types::global_dof_index>
465 &constraint_indices = constraint_values.constraint_indices;
466 for (
unsigned int j = 0; j < n_entries; ++j)
468 dof_indices.push_back(
469 global_to_local(constraint_indices[j]));
476 dof_indices.push_back(global_to_local(current_dof));
480 Assert(constraint_iterator.first <
481 (1 << (8 *
sizeof(
unsigned short))) - 1,
483 constraint_iterator.first++;
493 const unsigned int cell_no,
494 const std::vector<types::global_dof_index> &local_dof_indices_lex,
495 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner)
497 const auto global_to_local =
500 return partitioner->global_to_local(global_index);
503 if (local_range.first <= global_index &&
504 global_index < local_range.second)
505 return global_index - local_range.first;
507 return global_index + (local_range.second - local_range.first);
511 std::pair<unsigned short, unsigned short> constraint_iterator(0, 0);
513 auto &constraint_indicator = this->constraint_indicator_per_cell[cell_no];
514 auto &dof_indices = this->dof_indices_per_cell[cell_no];
516 for (
const auto current_dof : local_dof_indices_lex)
522 std::pair<types::global_dof_index, typename Number::value_type>>
525 constraint_indicator.push_back(constraint_iterator);
526 constraint_indicator.back().second =
527 constraint_values.insert_entries(entries);
529 constraint_iterator.first = 0;
533 dof_indices.push_back(global_to_local(current_dof));
537 Assert(constraint_iterator.first <
538 (1 << (8 *
sizeof(
unsigned short))) - 1,
540 constraint_iterator.first++;
552 std::pair<types::global_dof_index, types::global_dof_index>{0,
556 this->dof_indices = {};
557 this->plain_dof_indices = {};
558 this->constraint_indicator = {};
560 this->row_starts = {};
561 this->row_starts.emplace_back(0, 0);
563 if (this->plain_dof_indices_per_cell.empty() ==
false)
565 this->row_starts_plain_indices = {};
566 this->row_starts_plain_indices.emplace_back(0);
569 for (
unsigned int i = 0; i < this->dof_indices_per_cell.size(); ++i)
571 this->dof_indices.insert(this->dof_indices.end(),
572 this->dof_indices_per_cell[i].begin(),
573 this->dof_indices_per_cell[i].end());
574 this->constraint_indicator.insert(
575 this->constraint_indicator.end(),
576 constraint_indicator_per_cell[i].begin(),
577 constraint_indicator_per_cell[i].end());
579 this->row_starts.emplace_back(this->dof_indices.size(),
580 this->constraint_indicator.size());
582 if (this->plain_dof_indices_per_cell.empty() ==
false)
584 this->plain_dof_indices.insert(
585 this->plain_dof_indices.end(),
586 this->plain_dof_indices_per_cell[i].begin(),
587 this->plain_dof_indices_per_cell[i].end());
589 this->row_starts_plain_indices.emplace_back(
590 this->plain_dof_indices.size());
594 std::vector<const std::vector<double> *> constraints(
595 constraint_values.constraints.size());
596 unsigned int length = 0;
597 for (
const auto &it : constraint_values.constraints)
600 constraints[it.second] = &it.first;
601 length += it.first.size();
604 constraint_pool_data.clear();
605 constraint_pool_data.reserve(length);
606 constraint_pool_row_index.reserve(constraint_values.constraints.size() +
608 constraint_pool_row_index.resize(1, 0);
610 for (
const auto &constraint : constraints)
613 constraint_pool_data.insert(constraint_pool_data.end(),
616 constraint_pool_row_index.push_back(constraint_pool_data.size());
621 this->dof_indices_per_cell.clear();
622 constraint_indicator_per_cell.clear();
625 std::all_of(hanging_node_constraint_masks.begin(),
626 hanging_node_constraint_masks.end(),
628 return i == unconstrained_compressed_constraint_kind;
630 hanging_node_constraint_masks.clear();
638 this->dof_indices.clear();
639 this->plain_dof_indices.clear();
640 this->constraint_indicator.clear();
642 this->row_starts.clear();
643 this->row_starts.reserve(this->dof_indices_per_cell.size());
644 this->row_starts.emplace_back(0, 0);
646 if (this->plain_dof_indices_per_cell.empty() ==
false)
648 this->row_starts_plain_indices.clear();
649 this->row_starts_plain_indices.reserve(
650 this->dof_indices_per_cell.size());
651 this->row_starts_plain_indices.emplace_back(0);
654 std::vector<types::global_dof_index> ghost_dofs;
655 std::pair<unsigned int, unsigned int> counts = {0, 0};
657 for (
unsigned int i = 0; i < this->dof_indices_per_cell.size(); ++i)
659 counts.first += this->dof_indices_per_cell[i].size();
661 for (
const auto &j : this->dof_indices_per_cell[i])
662 if (j >= (local_range.second - local_range.first))
663 ghost_dofs.push_back(j -
664 (local_range.second - local_range.first));
666 if (this->plain_dof_indices_per_cell.empty() ==
false)
668 counts.second += this->plain_dof_indices_per_cell[i].size();
670 for (
const auto &j : this->plain_dof_indices_per_cell[i])
671 if (j >= (local_range.second - local_range.first))
672 ghost_dofs.push_back(
673 j - (local_range.second - local_range.first));
677 std::sort(ghost_dofs.begin(), ghost_dofs.end());
678 ghost_dofs.erase(std::unique(ghost_dofs.begin(), ghost_dofs.end()),
681 IndexSet locally_relevant_dofs(locally_owned_indices.size());
682 locally_relevant_dofs.
add_indices(ghost_dofs.begin(), ghost_dofs.end());
684 const auto partitioner =
685 std::make_shared<Utilities::MPI::Partitioner>(locally_owned_indices,
686 locally_relevant_dofs,
689 this->dof_indices.reserve(counts.first);
690 this->plain_dof_indices.reserve(counts.second);
692 for (
unsigned int i = 0; i < this->dof_indices_per_cell.size(); ++i)
694 for (
const auto &j : this->dof_indices_per_cell[i])
695 if (j < (local_range.second - local_range.first))
696 this->dof_indices.push_back(j);
698 this->dof_indices.push_back(partitioner->global_to_local(
699 j - (local_range.second - local_range.first)));
701 this->constraint_indicator.insert(
702 this->constraint_indicator.end(),
703 constraint_indicator_per_cell[i].begin(),
704 constraint_indicator_per_cell[i].end());
706 this->row_starts.emplace_back(this->dof_indices.size(),
707 this->constraint_indicator.size());
709 if (this->plain_dof_indices_per_cell.empty() ==
false)
711 for (
const auto &j : this->plain_dof_indices_per_cell[i])
712 if (j < (local_range.second - local_range.first))
713 this->plain_dof_indices.push_back(j);
715 this->plain_dof_indices.push_back(
716 partitioner->global_to_local(
717 j - (local_range.second - local_range.first)));
719 this->row_starts_plain_indices.emplace_back(
720 this->plain_dof_indices.size());
724 std::vector<const std::vector<double> *> constraints(
725 constraint_values.constraints.size());
726 unsigned int length = 0;
727 for (
const auto &it : constraint_values.constraints)
730 constraints[it.second] = &it.first;
731 length += it.first.size();
734 constraint_pool_data.clear();
735 constraint_pool_data.reserve(length);
736 constraint_pool_row_index.reserve(constraint_values.constraints.size() +
738 constraint_pool_row_index.resize(1, 0);
740 for (
const auto &constraint : constraints)
743 constraint_pool_data.insert(constraint_pool_data.end(),
746 constraint_pool_row_index.push_back(constraint_pool_data.size());
751 this->dof_indices_per_cell.clear();
752 constraint_indicator_per_cell.clear();
755 std::all_of(hanging_node_constraint_masks.begin(),
756 hanging_node_constraint_masks.end(),
758 return i == unconstrained_compressed_constraint_kind;
760 hanging_node_constraint_masks.clear();
772 VectorType &global_vector,
773 Number *local_vector,
774 const unsigned int first_cell,
775 const unsigned int n_cells,
776 const unsigned int n_dofs_per_cell,
777 const bool apply_constraints)
const
779 if ((row_starts_plain_indices.empty() ==
false) &&
780 (apply_constraints ==
false))
782 for (
unsigned int v = 0; v < n_cells; ++v)
784 const unsigned int cell_index = first_cell + v;
785 const unsigned int *dof_indices =
786 this->plain_dof_indices.data() +
789 for (
unsigned int i = 0; i < n_dofs_per_cell; ++dof_indices, ++i)
790 operation.process_dof(*dof_indices,
798 for (
unsigned int v = 0; v < n_cells; ++v)
800 const unsigned int cell_index = first_cell + v;
801 const unsigned int *dof_indices =
802 this->dof_indices.data() + this->row_starts[
cell_index].first;
803 unsigned int index_indicators = this->row_starts[
cell_index].second;
804 unsigned int next_index_indicators =
807 unsigned int ind_local = 0;
808 for (; index_indicators != next_index_indicators; ++index_indicators)
810 const std::pair<unsigned short, unsigned short> indicator =
811 this->constraint_indicator[index_indicators];
814 for (
unsigned int j = 0; j < indicator.first; ++j)
815 operation.process_dof(dof_indices[j],
817 local_vector[ind_local + j][v]);
819 ind_local += indicator.first;
820 dof_indices += indicator.first;
824 typename Number::value_type
value;
825 operation.pre_constraints(local_vector[ind_local][v],
value);
827 const typename Number::value_type *data_val =
828 this->constraint_pool_begin(indicator.second);
829 const typename Number::value_type *end_pool =
830 this->constraint_pool_end(indicator.second);
831 for (; data_val != end_pool; ++data_val, ++dof_indices)
832 operation.process_constraint(*dof_indices,
837 operation.post_constraints(
value, local_vector[ind_local][v]);
843 for (; ind_local < n_dofs_per_cell; ++dof_indices, ++ind_local)
844 operation.process_dof(*dof_indices,
846 local_vector[ind_local][v]);