217 const std::vector<std::pair<types::global_dof_index, number2>> &entries)
219 next_constraint.first.resize(entries.size());
220 if (entries.size() > 0)
222 constraint_indices.resize(entries.size());
225 constraint_entries.assign(entries.begin(), entries.end());
226 std::sort(constraint_entries.begin(),
227 constraint_entries.end(),
228 [](
const std::pair<types::global_dof_index, double> &p1,
229 const std::pair<types::global_dof_index, double> &p2) {
230 return p1.second < p2.second;
236 constraint_indices[j] = constraint_entries[j].first;
239 next_constraint.first[j] = constraint_entries[j].second;
251 const auto position = constraints.find(next_constraint.first);
252 if (position != constraints.end())
253 insert_position = position->second;
256 next_constraint.second = constraints.size();
257 constraints.insert(next_constraint);
258 insert_position = next_constraint.second;
263 Assert(insert_position < (1 << (8 *
sizeof(
unsigned short))),
265 return static_cast<unsigned short>(insert_position);
298 const unsigned int n_cells,
299 const bool use_fast_hanging_node_algorithm)
301 this->dof_indices_per_cell.resize(n_cells);
302 this->plain_dof_indices_per_cell.resize(n_cells);
303 this->constraint_indicator_per_cell.resize(n_cells);
306 const bool has_hanging_nodes =
309 if (use_fast_hanging_node_algorithm && has_hanging_nodes)
311 hanging_nodes = std::make_unique<HangingNodes<dim>>(
314 hanging_node_constraint_masks.resize(n_cells);
318 lexicographic_numbering.resize(fes.size());
319 shape_infos.resize(fes.size());
321 for (
unsigned int i = 0; i < fes.size(); ++i)
323 if (fes[i].reference_cell().is_hyper_cube())
327 shape_infos[i].reinit(dummy_quadrature, fes[i], 0);
331 const auto dummy_quadrature =
332 fes[i].reference_cell().get_gauss_type_quadrature(1);
333 shape_infos[i].reinit(dummy_quadrature, fes[i], 0);
336 lexicographic_numbering[i] = shape_infos[i].lexicographic_numbering;
338 active_fe_indices.resize(n_cells);
357 const unsigned int cell_no,
358 const unsigned int mg_level,
360 const ::AffineConstraints<typename Number::value_type> &constraints,
361 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner)
363 local_dof_indices.resize(cell->get_fe().n_dofs_per_cell());
364 local_dof_indices_lex.resize(cell->get_fe().n_dofs_per_cell());
367 cell->get_dof_indices(local_dof_indices);
369 cell->get_mg_dof_indices(local_dof_indices);
374 const auto &lexicographic_numbering =
375 shape_infos[cell->active_fe_index()].lexicographic_numbering;
378 local_dof_indices.size());
380 for (
unsigned int i = 0; i < cell->get_fe().n_dofs_per_cell(); ++i)
381 local_dof_indices_lex[i] =
382 local_dof_indices[lexicographic_numbering[i]];
385 std::pair<unsigned short, unsigned short> constraint_iterator(0, 0);
391 auto &constraint_indicator = this->constraint_indicator_per_cell[cell_no];
392 auto &dof_indices = this->dof_indices_per_cell[cell_no];
393 auto &plain_dof_indices = this->plain_dof_indices_per_cell[cell_no];
399 const auto global_to_local =
402 return partitioner->global_to_local(global_index);
414 plain_dof_indices.resize(local_dof_indices_lex.size());
415 for (
unsigned int i = 0; i < local_dof_indices_lex.size(); ++i)
416 plain_dof_indices[i] = global_to_local(local_dof_indices_lex[i]);
424 cell->get_fe().n_components(),
426 hanging_nodes->setup_constraints(
427 cell, {}, lexicographic_numbering, local_dof_indices_lex,
mask);
429 hanging_node_constraint_masks[cell_no] =
compress(
mask[0], dim);
430 active_fe_indices[cell_no] = cell->active_fe_index();
433 for (
auto current_dof : local_dof_indices_lex)
435 const auto *entries_ptr =
436 constraints.get_constraint_entries(current_dof);
439 if (entries_ptr !=
nullptr)
441 const auto &entries = *entries_ptr;
443 if (n_entries == 1 &&
445 typename Number::value_type(1.)) <
446 100 * std::numeric_limits<double>::epsilon())
448 current_dof = entries[0].first;
452 constraint_indicator.push_back(constraint_iterator);
453 constraint_indicator.back().second =
454 constraint_values.insert_entries(entries);
457 constraint_iterator.first = 0;
461 const std::vector<types::global_dof_index>
462 &constraint_indices = constraint_values.constraint_indices;
463 for (
unsigned int j = 0; j < n_entries; ++j)
465 dof_indices.push_back(
466 global_to_local(constraint_indices[j]));
473 dof_indices.push_back(global_to_local(current_dof));
477 Assert(constraint_iterator.first <
478 (1 << (8 *
sizeof(
unsigned short))) - 1,
480 constraint_iterator.first++;
490 const unsigned int cell_no,
491 const std::vector<types::global_dof_index> &local_dof_indices_lex,
492 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner)
494 const auto global_to_local =
497 return partitioner->global_to_local(global_index);
508 std::pair<unsigned short, unsigned short> constraint_iterator(0, 0);
510 auto &constraint_indicator = this->constraint_indicator_per_cell[cell_no];
511 auto &dof_indices = this->dof_indices_per_cell[cell_no];
513 for (
const auto current_dof : local_dof_indices_lex)
519 std::pair<types::global_dof_index, typename Number::value_type>>
522 constraint_indicator.push_back(constraint_iterator);
523 constraint_indicator.back().second =
524 constraint_values.insert_entries(entries);
526 constraint_iterator.first = 0;
530 dof_indices.push_back(global_to_local(current_dof));
534 Assert(constraint_iterator.first <
535 (1 << (8 *
sizeof(
unsigned short))) - 1,
537 constraint_iterator.first++;
549 std::pair<types::global_dof_index, types::global_dof_index>{0,
553 this->dof_indices = {};
554 this->plain_dof_indices = {};
555 this->constraint_indicator = {};
557 this->row_starts = {};
558 this->row_starts.emplace_back(0, 0);
560 if (this->plain_dof_indices_per_cell.empty() ==
false)
562 this->row_starts_plain_indices = {};
563 this->row_starts_plain_indices.emplace_back(0);
566 for (
unsigned int i = 0; i < this->dof_indices_per_cell.size(); ++i)
568 this->dof_indices.insert(this->dof_indices.end(),
569 this->dof_indices_per_cell[i].begin(),
570 this->dof_indices_per_cell[i].end());
571 this->constraint_indicator.insert(
572 this->constraint_indicator.end(),
573 constraint_indicator_per_cell[i].begin(),
574 constraint_indicator_per_cell[i].end());
576 this->row_starts.emplace_back(this->dof_indices.size(),
577 this->constraint_indicator.size());
579 if (this->plain_dof_indices_per_cell.empty() ==
false)
581 this->plain_dof_indices.insert(
582 this->plain_dof_indices.end(),
583 this->plain_dof_indices_per_cell[i].begin(),
584 this->plain_dof_indices_per_cell[i].end());
586 this->row_starts_plain_indices.emplace_back(
587 this->plain_dof_indices.size());
591 std::vector<const std::vector<double> *> constraints(
592 constraint_values.constraints.size());
593 unsigned int length = 0;
594 for (
const auto &it : constraint_values.constraints)
597 constraints[it.second] = &it.first;
598 length += it.first.size();
601 constraint_pool_data.clear();
602 constraint_pool_data.reserve(length);
603 constraint_pool_row_index.reserve(constraint_values.constraints.size() +
605 constraint_pool_row_index.resize(1, 0);
607 for (
const auto &constraint : constraints)
610 constraint_pool_data.insert(constraint_pool_data.end(),
613 constraint_pool_row_index.push_back(constraint_pool_data.size());
618 this->dof_indices_per_cell.clear();
619 this->plain_dof_indices_per_cell.clear();
620 constraint_indicator_per_cell.clear();
623 std::all_of(hanging_node_constraint_masks.begin(),
624 hanging_node_constraint_masks.end(),
626 return i == unconstrained_compressed_constraint_kind;
628 hanging_node_constraint_masks.clear();
636 this->dof_indices.clear();
637 this->plain_dof_indices.clear();
638 this->constraint_indicator.clear();
640 this->row_starts.clear();
641 this->row_starts.reserve(this->dof_indices_per_cell.size());
642 this->row_starts.emplace_back(0, 0);
644 if (this->plain_dof_indices_per_cell.empty() ==
false)
646 this->row_starts_plain_indices.clear();
647 this->row_starts_plain_indices.reserve(
648 this->dof_indices_per_cell.size());
649 this->row_starts_plain_indices.emplace_back(0);
652 std::vector<types::global_dof_index> ghost_dofs;
653 std::pair<unsigned int, unsigned int> counts = {0, 0};
655 for (
unsigned int i = 0; i < this->dof_indices_per_cell.size(); ++i)
657 counts.first += this->dof_indices_per_cell[i].size();
659 for (
const auto &j : this->dof_indices_per_cell[i])
661 ghost_dofs.push_back(j -
664 if (this->plain_dof_indices_per_cell.empty() ==
false)
666 counts.second += this->plain_dof_indices_per_cell[i].size();
668 for (
const auto &j : this->plain_dof_indices_per_cell[i])
670 ghost_dofs.push_back(
675 std::sort(ghost_dofs.begin(), ghost_dofs.end());
676 ghost_dofs.erase(std::unique(ghost_dofs.begin(), ghost_dofs.end()),
679 IndexSet locally_relevant_dofs(locally_owned_indices.size());
680 locally_relevant_dofs.
add_indices(ghost_dofs.begin(), ghost_dofs.end());
682 const auto partitioner =
683 std::make_shared<Utilities::MPI::Partitioner>(locally_owned_indices,
684 locally_relevant_dofs,
687 this->dof_indices.reserve(counts.first);
688 this->plain_dof_indices.reserve(counts.second);
690 for (
unsigned int i = 0; i < this->dof_indices_per_cell.size(); ++i)
692 for (
const auto &j : this->dof_indices_per_cell[i])
694 this->dof_indices.push_back(j);
696 this->dof_indices.push_back(partitioner->global_to_local(
699 this->constraint_indicator.insert(
700 this->constraint_indicator.end(),
701 constraint_indicator_per_cell[i].begin(),
702 constraint_indicator_per_cell[i].end());
704 this->row_starts.emplace_back(this->dof_indices.size(),
705 this->constraint_indicator.size());
707 if (this->plain_dof_indices_per_cell.empty() ==
false)
709 for (
const auto &j : this->plain_dof_indices_per_cell[i])
711 this->plain_dof_indices.push_back(j);
713 this->plain_dof_indices.push_back(
714 partitioner->global_to_local(
717 this->row_starts_plain_indices.emplace_back(
718 this->plain_dof_indices.size());
722 std::vector<const std::vector<double> *> constraints(
723 constraint_values.constraints.size());
724 unsigned int length = 0;
725 for (
const auto &it : constraint_values.constraints)
728 constraints[it.second] = &it.first;
729 length += it.first.size();
732 constraint_pool_data.clear();
733 constraint_pool_data.reserve(length);
734 constraint_pool_row_index.reserve(constraint_values.constraints.size() +
736 constraint_pool_row_index.resize(1, 0);
738 for (
const auto &constraint : constraints)
741 constraint_pool_data.insert(constraint_pool_data.end(),
744 constraint_pool_row_index.push_back(constraint_pool_data.size());
749 this->dof_indices_per_cell.clear();
750 this->plain_dof_indices_per_cell.clear();
751 constraint_indicator_per_cell.clear();
754 std::all_of(hanging_node_constraint_masks.begin(),
755 hanging_node_constraint_masks.end(),
757 return i == unconstrained_compressed_constraint_kind;
759 hanging_node_constraint_masks.clear();
771 VectorType &global_vector,
772 Number *local_vector,
773 const unsigned int first_cell,
774 const unsigned int n_cells,
775 const unsigned int n_dofs_per_cell,
776 const bool apply_constraints)
const
778 if ((row_starts_plain_indices.empty() ==
false) &&
779 (apply_constraints ==
false))
781 for (
unsigned int v = 0; v < n_cells; ++v)
783 const unsigned int cell_index = first_cell + v;
784 const unsigned int *dof_indices =
785 this->plain_dof_indices.data() +
788 for (
unsigned int i = 0; i < n_dofs_per_cell; ++dof_indices, ++i)
789 operation.process_dof(*dof_indices,
797 for (
unsigned int v = 0; v < n_cells; ++v)
799 const unsigned int cell_index = first_cell + v;
800 const unsigned int *dof_indices =
801 this->dof_indices.data() + this->row_starts[
cell_index].first;
802 unsigned int index_indicators = this->row_starts[
cell_index].second;
803 unsigned int next_index_indicators =
806 unsigned int ind_local = 0;
807 for (; index_indicators != next_index_indicators; ++index_indicators)
809 const std::pair<unsigned short, unsigned short> indicator =
810 this->constraint_indicator[index_indicators];
813 for (
unsigned int j = 0; j < indicator.first; ++j)
814 operation.process_dof(dof_indices[j],
816 local_vector[ind_local + j][v]);
818 ind_local += indicator.first;
819 dof_indices += indicator.first;
823 typename Number::value_type
value;
824 operation.pre_constraints(local_vector[ind_local][v],
value);
826 const typename Number::value_type *data_val =
827 this->constraint_pool_begin(indicator.second);
828 const typename Number::value_type *end_pool =
829 this->constraint_pool_end(indicator.second);
830 for (; data_val != end_pool; ++data_val, ++dof_indices)
831 operation.process_constraint(*dof_indices,
836 operation.post_constraints(
value, local_vector[ind_local][v]);
842 for (; ind_local < n_dofs_per_cell; ++dof_indices, ++ind_local)
843 operation.process_dof(*dof_indices,
845 local_vector[ind_local][v]);