From 33965e8ca070bccae146a3fb6f98683cdea2b88d Mon Sep 17 00:00:00 2001 From: Peter Munch Date: Wed, 9 Mar 2022 12:40:12 +0100 Subject: [PATCH] Refactor constraint application of GC --- .../multigrid/mg_transfer_global_coarsening.h | 54 +- .../mg_transfer_global_coarsening.templates.h | 606 +++--------------- 2 files changed, 93 insertions(+), 567 deletions(-) diff --git a/include/deal.II/multigrid/mg_transfer_global_coarsening.h b/include/deal.II/multigrid/mg_transfer_global_coarsening.h index 4b323f6a88..1a2379b94d 100644 --- a/include/deal.II/multigrid/mg_transfer_global_coarsening.h +++ b/include/deal.II/multigrid/mg_transfer_global_coarsening.h @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include @@ -407,22 +407,11 @@ private: mutable LinearAlgebra::distributed::Vector vec_coarse; /** - * Constraint-entry indices for performing manual - * constraint_coarse.distribute_local_to_global(). + * Helper class for reading from and writing to global vectors and for + * applying constraints. */ - std::vector distribute_local_to_global_indices; - - /** - * Constraint-entry values for performing manual - * constraint_coarse.distribute_local_to_global(). - */ - std::vector distribute_local_to_global_values; - - /** - * Pointers to the constraint entries for performing manual - * constraint_coarse.distribute_local_to_global(). - */ - std::vector distribute_local_to_global_ptr; + internal::MatrixFreeFunctions::ConstraintInfo> + constraint_info; /** * Weights for continuous elements. @@ -436,18 +425,6 @@ private: std::vector, Utilities::pow(3, dim)>> weights_compressed; - /** - * DoF indices of the coarse cells, expressed in indices local to the MPI - * rank. - */ - std::vector level_dof_indices_coarse; - - /** - * DoF indices of the coarse cells, expressed in indices local to the MPI - * rank. - */ - std::vector level_dof_indices_coarse_plain; - /** * DoF indices of the fine cells, expressed in indices local to the MPI * rank. @@ -459,28 +436,7 @@ private: */ unsigned int n_components; - /** - * Refinement configuration of the coarse cells, needed for fast - * application of hanging-node constraints. If no hanging-node - * constraints have to be applied or the fast algorithm is not - * applicable, the vector is empty. - */ - std::vector - coarse_cell_refinement_configurations; - friend class internal::MGTwoLevelTransferImplementation; - - /** - * Apply hanging-node constrains with fast algorithm. - */ - void - apply_hanging_node_constraints( - const MGTransferScheme &scheme, - const internal::MatrixFreeFunctions::ConstraintKinds - * coarse_cell_refinement_configurations_ptr, - const unsigned int n_lanes_filled, - const bool transpose, - AlignedVector> &evaluation_data_coarse) const; }; diff --git a/include/deal.II/multigrid/mg_transfer_global_coarsening.templates.h b/include/deal.II/multigrid/mg_transfer_global_coarsening.templates.h index 3298de8946..05fcb5caae 100644 --- a/include/deal.II/multigrid/mg_transfer_global_coarsening.templates.h +++ b/include/deal.II/multigrid/mg_transfer_global_coarsening.templates.h @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -1084,58 +1085,6 @@ namespace internal dof_handler_coarse.get_communicator()); } - template - static void - precompute_restriction_constraints( - const std::shared_ptr &partitioner, - const dealii::AffineConstraints &constraints_coarse, - MGTwoLevelTransfer> - &transfer) - { - transfer.distribute_local_to_global_indices.clear(); - transfer.distribute_local_to_global_values.clear(); - transfer.distribute_local_to_global_ptr = {0}; - - const auto fu = [&](const auto &index_set) { - for (const auto i : index_set) - { - Assert(constraints_coarse.is_inhomogeneously_constrained(i) == - false, - ExcNotImplemented()); - - const auto constraints = - constraints_coarse.get_constraint_entries(i); - - if (constraints) - { - for (const auto &p : *constraints) - { - transfer.distribute_local_to_global_indices.emplace_back( - partitioner->global_to_local(p.first)); - transfer.distribute_local_to_global_values.emplace_back( - p.second); - } - - // add a dummy entry for homogeneous constraints - if (transfer.distribute_local_to_global_indices.size() == - transfer.distribute_local_to_global_ptr.back()) - { - transfer.distribute_local_to_global_indices.emplace_back( - numbers::invalid_unsigned_int); - transfer.distribute_local_to_global_values.emplace_back( - 0.0); - } - } - - transfer.distribute_local_to_global_ptr.push_back( - transfer.distribute_local_to_global_indices.size()); - } - }; - - fu(partitioner->locally_owned_range()); - fu(partitioner->ghost_indices()); - } - template @@ -1399,37 +1348,6 @@ namespace internal const auto reference_cell = dof_handler_fine.get_fe(0).reference_cell(); - std::unique_ptr> - hanging_nodes; - std::vector> lexicographic_mappings; - - // create helper class - if (use_fast_hanging_node_algorithm(dof_handler_coarse, mg_level_coarse)) - { - hanging_nodes = - std::make_unique>( - dof_handler_coarse.get_triangulation()); - - const auto &fes = dof_handler_coarse.get_fe_collection(); - lexicographic_mappings.resize(fes.size()); - - for (unsigned int i = 0; i < fes.size(); ++i) - if (fes[i].reference_cell().is_hyper_cube()) - { - const Quadrature<1> dummy_quadrature( - std::vector>(1, Point<1>())); - internal::MatrixFreeFunctions::ShapeInfo< - VectorizedArray> - shape_info; - shape_info.reinit(dummy_quadrature, fes[i], 0); - lexicographic_mappings[i] = shape_info.lexicographic_numbering; - - if (i == fe_index_coarse) - transfer.schemes[0].shape_info_coarse = - transfer.schemes[1].shape_info_coarse = shape_info; - } - } - // create partitioners and vectors for internal purposes { // ... for fine mesh @@ -1449,9 +1367,6 @@ namespace internal constraints_coarse, mg_level_coarse); transfer.vec_coarse.reinit(transfer.partitioner_coarse); - precompute_restriction_constraints(transfer.partitioner_coarse, - constraints_coarse, - transfer); } } @@ -1567,10 +1482,6 @@ namespace internal // indices { transfer.level_dof_indices_fine.resize(n_dof_indices_fine.back()); - if (hanging_nodes) - transfer.level_dof_indices_coarse.resize(n_dof_indices_coarse.back()); - transfer.level_dof_indices_coarse_plain.resize( - n_dof_indices_coarse.back()); std::vector local_dof_indices( transfer.schemes[0].n_dofs_per_cell_coarse); @@ -1600,90 +1511,32 @@ namespace internal } // ------------------------------ indices ------------------------------ - unsigned int *level_dof_indices_coarse_0 = - transfer.level_dof_indices_coarse.data(); - unsigned int *level_dof_indices_coarse_plain_0 = - transfer.level_dof_indices_coarse_plain.data(); unsigned int *level_dof_indices_fine_0 = transfer.level_dof_indices_fine.data(); - unsigned int *level_dof_indices_coarse_1 = - level_dof_indices_coarse_0 + - transfer.schemes[0].n_dofs_per_cell_coarse * - transfer.schemes[0].n_coarse_cells; - unsigned int *level_dof_indices_coarse_plain_1 = - level_dof_indices_coarse_plain_0 + - transfer.schemes[0].n_dofs_per_cell_coarse * - transfer.schemes[0].n_coarse_cells; unsigned int *level_dof_indices_fine_1 = level_dof_indices_fine_0 + transfer.schemes[0].n_dofs_per_cell_fine * transfer.schemes[0].n_coarse_cells; - if (hanging_nodes) - transfer.coarse_cell_refinement_configurations.resize( - transfer.schemes[0].n_coarse_cells + - transfer.schemes[1].n_coarse_cells); - - internal::MatrixFreeFunctions::ConstraintKinds - *coarse_cell_refinement_configurations_0 = - transfer.coarse_cell_refinement_configurations.data(); - internal::MatrixFreeFunctions::ConstraintKinds - *coarse_cell_refinement_configurations_1 = - coarse_cell_refinement_configurations_0 + - transfer.schemes[0].n_coarse_cells; - - std::vector local_dof_indices_lex( - local_dof_indices.size()); - - const auto get_lexicographic_mapping = [&](const unsigned int c) { - if (lexicographic_mappings.size() > 0) - return lexicographic_mappings[fe_index_coarse][c]; - else - return lexicographic_numbering_coarse[c]; - }; + unsigned int cell_no_0 = 0; + unsigned int cell_no_1 = transfer.schemes[0].n_coarse_cells; + + transfer.constraint_info.reinit( + dof_handler_coarse, + transfer.schemes[0].n_coarse_cells + + transfer.schemes[1].n_coarse_cells, + use_fast_hanging_node_algorithm(dof_handler_coarse, mg_level_coarse)); process_cells( [&](const auto &cell_coarse, const auto &cell_fine) { // parent { - if (mg_level_coarse == numbers::invalid_unsigned_int) - cell_coarse->get_dof_indices(local_dof_indices); - else - cell_coarse->get_mg_dof_indices(local_dof_indices); - - for (unsigned int i = 0; i < local_dof_indices.size(); ++i) - local_dof_indices_lex[i] = - local_dof_indices[get_lexicographic_mapping(i)]; - - for (auto &i : local_dof_indices_lex) - i = transfer.partitioner_coarse->global_to_local(i); - - if (hanging_nodes) - { - std::vector - mask(transfer.n_components); - - local_dof_indices = local_dof_indices_lex; - - hanging_nodes->setup_constraints(cell_coarse, - transfer.partitioner_coarse, - lexicographic_mappings, - local_dof_indices, - mask); - - for (unsigned int i = 0; - i < transfer.schemes[0].n_dofs_per_cell_coarse; - i++) - level_dof_indices_coarse_0[i] = local_dof_indices[i]; - - coarse_cell_refinement_configurations_0[0] = mask[0]; - coarse_cell_refinement_configurations_0 += 1; - } - - for (unsigned int i = 0; - i < transfer.schemes[0].n_dofs_per_cell_coarse; - i++) - level_dof_indices_coarse_plain_0[i] = local_dof_indices_lex[i]; + transfer.constraint_info.read_dof_indices( + cell_no_0++, + mg_level_coarse, + cell_coarse, + constraints_coarse, + transfer.partitioner_coarse); } // child @@ -1699,10 +1552,6 @@ namespace internal // move pointers { - level_dof_indices_coarse_0 += - transfer.schemes[0].n_dofs_per_cell_coarse; - level_dof_indices_coarse_plain_0 += - transfer.schemes[0].n_dofs_per_cell_coarse; level_dof_indices_fine_0 += transfer.schemes[0].n_dofs_per_cell_fine; } @@ -1711,46 +1560,12 @@ namespace internal // parent (only once at the beginning) if (c == 0) { - if (mg_level_coarse == numbers::invalid_unsigned_int) - cell_coarse->get_dof_indices(local_dof_indices); - else - cell_coarse->get_mg_dof_indices(local_dof_indices); - - for (unsigned int i = 0; i < local_dof_indices.size(); ++i) - local_dof_indices_lex[i] = - local_dof_indices[get_lexicographic_mapping(i)]; - - for (auto &i : local_dof_indices_lex) - i = transfer.partitioner_coarse->global_to_local(i); - - if (hanging_nodes) - { - std::vector - mask(transfer.n_components); - - local_dof_indices = local_dof_indices_lex; - - hanging_nodes->setup_constraints( - cell_coarse, - transfer.partitioner_coarse, - lexicographic_mappings, - local_dof_indices, - mask); - - for (unsigned int i = 0; - i < transfer.schemes[1].n_dofs_per_cell_coarse; - ++i) - level_dof_indices_coarse_1[i] = local_dof_indices[i]; - - coarse_cell_refinement_configurations_1[0] = mask[0]; - coarse_cell_refinement_configurations_1 += 1; - } - - for (unsigned int i = 0; - i < transfer.schemes[1].n_dofs_per_cell_coarse; - ++i) - level_dof_indices_coarse_plain_1[i] = - local_dof_indices_lex[i]; + transfer.constraint_info.read_dof_indices( + cell_no_1++, + mg_level_coarse, + cell_coarse, + constraints_coarse, + transfer.partitioner_coarse); } // child @@ -1767,23 +1582,12 @@ namespace internal // move pointers (only once at the end) if (c + 1 == GeometryInfo::max_children_per_cell) { - level_dof_indices_coarse_1 += - transfer.schemes[1].n_dofs_per_cell_coarse; - level_dof_indices_coarse_plain_1 += - transfer.schemes[1].n_dofs_per_cell_coarse; level_dof_indices_fine_1 += transfer.schemes[1].n_dofs_per_cell_fine; } }); - if (hanging_nodes && - std::all_of(transfer.coarse_cell_refinement_configurations.begin(), - transfer.coarse_cell_refinement_configurations.end(), - [](const auto i) { - return i == internal::MatrixFreeFunctions:: - ConstraintKinds::unconstrained; - })) - transfer.coarse_cell_refinement_configurations.clear(); + transfer.constraint_info.finalize(); } @@ -2034,33 +1838,6 @@ namespace internal &fe.base_element(0)) != nullptr); }); - std::unique_ptr> - hanging_nodes; - std::vector> lexicographic_mappings; - - // create helper class - if (use_fast_hanging_node_algorithm(dof_handler_coarse, mg_level_coarse)) - { - hanging_nodes = - std::make_unique>( - dof_handler_coarse.get_triangulation()); - - const auto &fes = dof_handler_coarse.get_fe_collection(); - lexicographic_mappings.resize(fes.size()); - - for (unsigned int i = 0; i < fes.size(); ++i) - if (fes[i].reference_cell().is_hyper_cube()) - { - const Quadrature<1> dummy_quadrature( - std::vector>(1, Point<1>())); - internal::MatrixFreeFunctions::ShapeInfo< - VectorizedArray> - shape_info; - shape_info.reinit(dummy_quadrature, fes[i], 0); - lexicographic_mappings[i] = shape_info.lexicographic_numbering; - } - } - const auto process_cells = [&](const auto &fu) { loop_over_active_or_level_cells( dof_handler_coarse, mg_level_coarse, [&](const auto &cell_coarse) { @@ -2127,13 +1904,11 @@ namespace internal constraints_coarse, mg_level_coarse); transfer.vec_coarse.reinit(transfer.partitioner_coarse); - precompute_restriction_constraints(transfer.partitioner_coarse, - constraints_coarse, - transfer); } std::vector n_dof_indices_fine(fe_index_pairs.size() + 1); std::vector n_dof_indices_coarse(fe_index_pairs.size() + 1); + std::vector cell_no(fe_index_pairs.size() + 1, 0); { std::vector> lexicographic_numbering_fine( @@ -2162,6 +1937,8 @@ namespace internal n_dof_indices_coarse[fe_index_pair.second + 1] = transfer.schemes[fe_index_pair.second].n_dofs_per_cell_coarse * transfer.schemes[fe_index_pair.second].n_coarse_cells; + cell_no[fe_index_pair.second + 1] = + transfer.schemes[fe_index_pair.second].n_coarse_cells; const auto reference_cell = dof_handler_fine.get_fe(fe_index_pair.first.second) @@ -2193,10 +1970,6 @@ namespace internal 0); lexicographic_numbering_coarse[fe_index_pair.second] = shape_info.lexicographic_numbering; - - if (hanging_nodes) - transfer.schemes[fe_index_pair.second].shape_info_coarse = - shape_info; } else { @@ -2224,19 +1997,12 @@ namespace internal { n_dof_indices_fine[i + 1] += n_dof_indices_fine[i]; n_dof_indices_coarse[i + 1] += n_dof_indices_coarse[i]; + cell_no[i + 1] += cell_no[i]; } transfer.level_dof_indices_fine.resize(n_dof_indices_fine.back()); - if (hanging_nodes) - transfer.level_dof_indices_coarse.resize(n_dof_indices_coarse.back()); - transfer.level_dof_indices_coarse_plain.resize( - n_dof_indices_coarse.back()); // ------------------------------ indices ----------------------------- - std::vector level_dof_indices_coarse( - fe_index_pairs.size()); - std::vector level_dof_indices_coarse_plain( - fe_index_pairs.size()); std::vector level_dof_indices_fine( fe_index_pairs.size()); @@ -2244,36 +2010,6 @@ namespace internal { level_dof_indices_fine[i] = transfer.level_dof_indices_fine.data() + n_dof_indices_fine[i]; - level_dof_indices_coarse[i] = - transfer.level_dof_indices_coarse.data() + - n_dof_indices_coarse[i]; - level_dof_indices_coarse_plain[i] = - transfer.level_dof_indices_coarse_plain.data() + - n_dof_indices_coarse[i]; - } - - std::vector - coarse_cell_refinement_configurations; - - if (hanging_nodes) - { - unsigned int n_coarse_cells = 0; - for (unsigned int i = 0; i < transfer.schemes.size(); ++i) - n_coarse_cells += transfer.schemes[i].n_coarse_cells; - transfer.coarse_cell_refinement_configurations.resize( - n_coarse_cells); - - coarse_cell_refinement_configurations.resize(fe_index_pairs.size()); - - if (fe_index_pairs.size() > 0) - { - coarse_cell_refinement_configurations[0] = - transfer.coarse_cell_refinement_configurations.data(); - for (unsigned int i = 1; i < transfer.schemes.size(); ++i) - coarse_cell_refinement_configurations[i] = - coarse_cell_refinement_configurations[i - 1] + - transfer.schemes[i - 1].n_coarse_cells; - } } bool fine_indices_touch_remote_dofs = false; @@ -2282,6 +2018,11 @@ namespace internal dof_handler_fine.locally_owned_dofs() : dof_handler_fine.locally_owned_mg_dofs(mg_level_fine); + transfer.constraint_info.reinit( + dof_handler_coarse, + cell_no.back(), + use_fast_hanging_node_algorithm(dof_handler_coarse, mg_level_coarse)); + process_cells([&](const auto &cell_coarse, const auto &cell_fine) { const auto fe_pair_no = fe_index_pairs[std::pair( @@ -2289,53 +2030,12 @@ namespace internal // parent { - if (mg_level_coarse == numbers::invalid_unsigned_int) - cell_coarse->get_dof_indices( - local_dof_indices_coarse[fe_pair_no]); - else - cell_coarse->get_mg_dof_indices( - local_dof_indices_coarse[fe_pair_no]); - - for (unsigned int i = 0; - i < local_dof_indices_coarse[fe_pair_no].size(); - ++i) - local_dof_indices_coarse_lex[fe_pair_no][i] = - local_dof_indices_coarse - [fe_pair_no][lexicographic_numbering_coarse[fe_pair_no][i]]; - - for (auto &i : local_dof_indices_coarse_lex[fe_pair_no]) - i = transfer.partitioner_coarse->global_to_local(i); - - if (hanging_nodes) - { - std::vector - mask(transfer.n_components); - - local_dof_indices_coarse[fe_pair_no] = - local_dof_indices_coarse_lex[fe_pair_no]; - - hanging_nodes->setup_constraints( - cell_coarse, - transfer.partitioner_coarse, - lexicographic_mappings, - local_dof_indices_coarse[fe_pair_no], - mask); - - for (unsigned int i = 0; - i < transfer.schemes[fe_pair_no].n_dofs_per_cell_coarse; - i++) - level_dof_indices_coarse[fe_pair_no][i] = - local_dof_indices_coarse[fe_pair_no][i]; - - coarse_cell_refinement_configurations[fe_pair_no][0] = mask[0]; - coarse_cell_refinement_configurations[fe_pair_no] += 1; - } - - for (unsigned int i = 0; - i < transfer.schemes[fe_pair_no].n_dofs_per_cell_coarse; - i++) - level_dof_indices_coarse_plain[fe_pair_no][i] = - local_dof_indices_coarse_lex[fe_pair_no][i]; + transfer.constraint_info.read_dof_indices( + cell_no[fe_pair_no]++, + mg_level_coarse, + cell_coarse, + constraints_coarse, + transfer.partitioner_coarse); } // child @@ -2360,10 +2060,6 @@ namespace internal // move pointers { - level_dof_indices_coarse[fe_pair_no] += - transfer.schemes[fe_pair_no].n_dofs_per_cell_coarse; - level_dof_indices_coarse_plain[fe_pair_no] += - transfer.schemes[fe_pair_no].n_dofs_per_cell_coarse; level_dof_indices_fine[fe_pair_no] += transfer.schemes[fe_pair_no].n_dofs_per_cell_fine; } @@ -2376,14 +2072,7 @@ namespace internal comm) == 0) transfer.vec_fine.reinit(0); - if (hanging_nodes && - std::all_of(transfer.coarse_cell_refinement_configurations.begin(), - transfer.coarse_cell_refinement_configurations.end(), - [](const auto i) { - return i == internal::MatrixFreeFunctions:: - ConstraintKinds::unconstrained; - })) - transfer.coarse_cell_refinement_configurations.clear(); + transfer.constraint_info.finalize(); } // ------------------------- prolongation matrix ------------------------- @@ -2809,42 +2498,14 @@ MGTwoLevelTransfer>:: vec_coarse_ptr->update_ghost_values(); - // a helper function similar to FEEvaluation::read_dof_values() - const auto read_dof_values = [&](const auto &index, - const auto &global_vector) -> Number { - if (distribute_local_to_global_ptr[index + 1] == - distribute_local_to_global_ptr[index]) - return global_vector.local_element(index); - else if (((distribute_local_to_global_ptr[index + 1] - - distribute_local_to_global_ptr[index]) == 1 && - distribute_local_to_global_indices - [distribute_local_to_global_ptr[index]] == - numbers::invalid_unsigned_int) == false) - { - Number value = 0.0; - for (unsigned int j = distribute_local_to_global_ptr[index]; - j < distribute_local_to_global_ptr[index + 1]; - ++j) - value += - global_vector.local_element(distribute_local_to_global_indices[j]) * - distribute_local_to_global_values[j]; - return value; - } - else - return 0.0; - }; - if (fine_element_is_continuous && (use_dst_inplace == false)) *vec_fine_ptr = Number(0.); AlignedVector evaluation_data_fine; AlignedVector evaluation_data_coarse; - const unsigned int *indices_coarse = level_dof_indices_coarse.size() > 0 ? - level_dof_indices_coarse.data() : - level_dof_indices_coarse_plain.data(); - const unsigned int *indices_fine = level_dof_indices_fine.data(); - const Number * weights = nullptr; + const unsigned int *indices_fine = level_dof_indices_fine.data(); + const Number * weights = nullptr; const std::array, Utilities::pow(3, dim)> *weights_compressed = nullptr; @@ -2854,9 +2515,7 @@ MGTwoLevelTransfer>:: weights_compressed = this->weights_compressed.data(); } - const internal::MatrixFreeFunctions::ConstraintKinds - *coarse_cell_refinement_configurations_ptr = - coarse_cell_refinement_configurations.data(); + unsigned int cell_counter = 0; for (const auto &scheme : schemes) { @@ -2885,25 +2544,19 @@ MGTwoLevelTransfer>:: (scheme.n_coarse_cells - cell) : n_lanes; - // read from source vector, apply general-purpose constraints, and ... - for (unsigned int v = 0; v < n_lanes_filled; ++v) - { - for (unsigned int i = 0; i < scheme.n_dofs_per_cell_coarse; ++i) - evaluation_data_coarse[i][v] = - read_dof_values(indices_coarse[i], *vec_coarse_ptr); - indices_coarse += scheme.n_dofs_per_cell_coarse; - } - - // ... fast hanging-node-constraints algorithm - apply_hanging_node_constraints( - scheme, - coarse_cell_refinement_configurations_ptr, - n_lanes_filled, - false, - evaluation_data_coarse); + // read from src vector (similar to FEEvaluation::read_dof_values()) + internal::VectorReader reader; + constraint_info.read_write_operation(reader, + *vec_coarse_ptr, + evaluation_data_coarse, + cell_counter, + n_lanes_filled, + scheme.n_dofs_per_cell_coarse, + true); + constraint_info.apply_hanging_node_constraints( + cell_counter, n_lanes_filled, false, evaluation_data_coarse); - if (coarse_cell_refinement_configurations.size() > 0) - coarse_cell_refinement_configurations_ptr += n_lanes_filled; + cell_counter += n_lanes_filled; // ---------------------------- coarse ------------------------------- if (needs_interpolation) @@ -2999,29 +2652,8 @@ MGTwoLevelTransfer>:: AlignedVector evaluation_data_fine; AlignedVector evaluation_data_coarse; - // a helper function similar to FEEvaluation::distribute_local_to_global() - const auto distribute_local_to_global = - [&](const auto &index, const auto &value, auto &global_vector) { - if (distribute_local_to_global_ptr[index + 1] == - distribute_local_to_global_ptr[index]) - global_vector.local_element(index) += value; - else if (((distribute_local_to_global_ptr[index + 1] - - distribute_local_to_global_ptr[index]) == 1 && - distribute_local_to_global_indices - [distribute_local_to_global_ptr[index]] == - numbers::invalid_unsigned_int) == false) - for (unsigned int j = distribute_local_to_global_ptr[index]; - j < distribute_local_to_global_ptr[index + 1]; - ++j) - global_vector.local_element(distribute_local_to_global_indices[j]) += - value * distribute_local_to_global_values[j]; - }; - - const unsigned int *indices_coarse = level_dof_indices_coarse.size() > 0 ? - level_dof_indices_coarse.data() : - level_dof_indices_coarse_plain.data(); - const unsigned int *indices_fine = level_dof_indices_fine.data(); - const Number * weights = nullptr; + const unsigned int *indices_fine = level_dof_indices_fine.data(); + const Number * weights = nullptr; const std::array, Utilities::pow(3, dim)> *weights_compressed = nullptr; @@ -3031,9 +2663,7 @@ MGTwoLevelTransfer>:: weights_compressed = this->weights_compressed.data(); } - const internal::MatrixFreeFunctions::ConstraintKinds - *coarse_cell_refinement_configurations_ptr = - coarse_cell_refinement_configurations.data(); + unsigned int cell_counter = 0; for (const auto &scheme : schemes) { @@ -3111,27 +2741,21 @@ MGTwoLevelTransfer>:: evaluation_data_coarse = evaluation_data_fine; // TODO // ----------------------------- coarse ------------------------------ - // apply fast hanging-node-constraints algorithm, ... - apply_hanging_node_constraints( - scheme, - coarse_cell_refinement_configurations_ptr, - n_lanes_filled, - true, - evaluation_data_coarse); - - - if (coarse_cell_refinement_configurations.size() > 0) - coarse_cell_refinement_configurations_ptr += n_lanes_filled; - - // ... apply general-purpose constraints, and write into dst vector - for (unsigned int v = 0; v < n_lanes_filled; ++v) - { - for (unsigned int i = 0; i < scheme.n_dofs_per_cell_coarse; ++i) - distribute_local_to_global(indices_coarse[i], - evaluation_data_coarse[i][v], - *vec_coarse_ptr); - indices_coarse += scheme.n_dofs_per_cell_coarse; - } + // write into dst vector (similar to + // FEEvaluation::distribute_global_to_local()) + internal::VectorDistributorLocalToGlobal + writer; + constraint_info.apply_hanging_node_constraints( + cell_counter, n_lanes_filled, true, evaluation_data_coarse); + constraint_info.read_write_operation(writer, + *vec_coarse_ptr, + evaluation_data_coarse, + cell_counter, + n_lanes_filled, + scheme.n_dofs_per_cell_coarse, + true); + + cell_counter += n_lanes_filled; } } @@ -3178,10 +2802,10 @@ MGTwoLevelTransfer>:: AlignedVector evaluation_data_fine; AlignedVector evaluation_data_coarse; - const unsigned int *indices_coarse_plain = - level_dof_indices_coarse_plain.data(); const unsigned int *indices_fine = level_dof_indices_fine.data(); + unsigned int cell_counter = 0; + for (const auto &scheme : schemes) { if (scheme.n_coarse_cells == 0) @@ -3191,8 +2815,7 @@ MGTwoLevelTransfer>:: scheme.n_dofs_per_cell_coarse == 0) { indices_fine += scheme.n_coarse_cells * scheme.n_dofs_per_cell_fine; - indices_coarse_plain += - scheme.n_coarse_cells * scheme.n_dofs_per_cell_coarse; + cell_counter += scheme.n_coarse_cells; continue; } @@ -3250,14 +2873,18 @@ MGTwoLevelTransfer>:: evaluation_data_coarse = evaluation_data_fine; // TODO // ----------------------------- coarse ------------------------------ - // write into dst vector - for (unsigned int v = 0; v < n_lanes_filled; ++v) - { - for (unsigned int i = 0; i < scheme.n_dofs_per_cell_coarse; ++i) - vec_coarse_ptr->local_element(indices_coarse_plain[i]) = - evaluation_data_coarse[i][v]; - indices_coarse_plain += scheme.n_dofs_per_cell_coarse; - } + // write into dst vector (similar to + // FEEvaluation::set_dof_values_plain()) + internal::VectorSetter writer; + constraint_info.read_write_operation(writer, + *vec_coarse_ptr, + evaluation_data_coarse, + cell_counter, + n_lanes_filled, + scheme.n_dofs_per_cell_coarse, + false); + + cell_counter += n_lanes_filled; } } @@ -3273,58 +2900,6 @@ MGTwoLevelTransfer>:: -template -void -MGTwoLevelTransfer>:: - apply_hanging_node_constraints( - const MGTransferScheme &scheme, - const internal::MatrixFreeFunctions::ConstraintKinds - * coarse_cell_refinement_configurations_ptr, - const unsigned int n_lanes_filled, - const bool transpose, - AlignedVector> &evaluation_data_coarse) const -{ - if (coarse_cell_refinement_configurations.size() == 0) - return; - - using VectorizedArrayType = VectorizedArray; - - std::array - constraint_mask; - - bool hn_available = false; - - for (unsigned int v = 0; v < n_lanes_filled; ++v) - { - const auto mask = coarse_cell_refinement_configurations_ptr[v]; - - constraint_mask[v] = mask; - - hn_available |= - (mask != internal::MatrixFreeFunctions::ConstraintKinds::unconstrained); - } - - if (hn_available == true) - { - for (unsigned int v = n_lanes_filled; v < VectorizedArrayType::size(); - ++v) - constraint_mask[v] = - internal::MatrixFreeFunctions::ConstraintKinds::unconstrained; - - internal::FEEvaluationHangingNodesFactory< - dim, - Number, - VectorizedArrayType>::apply(n_components, - scheme.degree_coarse, - scheme.shape_info_coarse, - transpose, - constraint_mask, - evaluation_data_coarse.begin()); - } -} - - template void MGTwoLevelTransfer>:: @@ -3495,16 +3070,11 @@ MGTwoLevelTransfer>:: size += partitioner_coarse->memory_consumption(); size += vec_fine.memory_consumption(); size += vec_coarse.memory_consumption(); - size += - MemoryConsumption::memory_consumption(distribute_local_to_global_indices); - size += - MemoryConsumption::memory_consumption(distribute_local_to_global_values); - size += MemoryConsumption::memory_consumption(distribute_local_to_global_ptr); size += MemoryConsumption::memory_consumption(weights); - size += MemoryConsumption::memory_consumption(level_dof_indices_coarse); - size += MemoryConsumption::memory_consumption(level_dof_indices_coarse_plain); size += MemoryConsumption::memory_consumption(level_dof_indices_fine); + // size += constraint_info.memory_consumption(); // TODO + return size; } -- 2.39.5