// ---------------------------------------------------------------------
//
// Copyright (C) 1998 - 2022 by the deal.II authors
//
// This file is part of the deal.II library.
//
// The deal.II library is free software; you can use it, redistribute
// it, and/or modify it under the terms of the GNU Lesser General
// Public License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// The full text of the license can be found in the file LICENSE.md at
// the top level directory of deal.II.
//
// ---------------------------------------------------------------------



for (PATTERN : SPARSITY_PATTERNS; deal_II_dimension : DIMENSIONS;
     deal_II_space_dimension : SPACE_DIMENSIONS)
  {
    namespace MGTools
    \{

#if deal_II_dimension <= deal_II_space_dimension
      template void
      make_sparsity_pattern<deal_II_dimension,
                            deal_II_space_dimension,
                            PATTERN,
                            double>(
        const DoFHandler<deal_II_dimension, deal_II_space_dimension> &,
        PATTERN &,
        const unsigned int,
        const AffineConstraints<double> &,
        const bool);

      template void
      make_sparsity_pattern<deal_II_dimension,
                            deal_II_space_dimension,
                            PATTERN,
                            float>(
        const DoFHandler<deal_II_dimension, deal_II_space_dimension> &,
        PATTERN &,
        const unsigned int,
        const AffineConstraints<float> &,
        const bool);

#endif
    \}
  }


for (PATTERN : SPARSITY_PATTERNS; deal_II_dimension : DIMENSIONS;
     deal_II_space_dimension : SPACE_DIMENSIONS)
  {
    namespace MGTools
    \{

#if deal_II_dimension <= deal_II_space_dimension
      template void
      make_interface_sparsity_pattern<deal_II_dimension,
                                      deal_II_space_dimension,
                                      PATTERN>(
        const DoFHandler<deal_II_dimension, deal_II_space_dimension> &,
        const MGConstrainedDoFs &,
        PATTERN &,
        const unsigned int);
#endif

#if deal_II_dimension == deal_II_space_dimension
      template void
      make_flux_sparsity_pattern<deal_II_dimension,
                                 deal_II_space_dimension,
                                 PATTERN,
                                 double>(const DoFHandler<deal_II_dimension> &,
                                         PATTERN &,
                                         const unsigned int,
                                         const AffineConstraints<double> &,
                                         const bool);

      template void
      make_flux_sparsity_pattern<deal_II_dimension,
                                 deal_II_space_dimension,
                                 PATTERN,
                                 float>(const DoFHandler<deal_II_dimension> &,
                                        PATTERN &,
                                        const unsigned int,
                                        const AffineConstraints<float> &,
                                        const bool);

      template void
      make_flux_sparsity_pattern_edge<deal_II_dimension>(
        const DoFHandler<deal_II_dimension> &,
        PATTERN &,
        const unsigned int);

#  if deal_II_dimension > 1

      template void
      make_flux_sparsity_pattern<deal_II_dimension>(
        const DoFHandler<deal_II_dimension> &,
        PATTERN &,
        const unsigned int,
        const Table<2, DoFTools::Coupling> &,
        const Table<2, DoFTools::Coupling> &);

      template void
      make_flux_sparsity_pattern_edge<deal_II_dimension>(
        const DoFHandler<deal_II_dimension> &,
        PATTERN &,
        const unsigned int,
        const Table<2, DoFTools::Coupling> &);
#  endif
#endif
    \}
  }


for (deal_II_dimension : DIMENSIONS)
  {
    namespace MGTools
    \{

#if deal_II_dimension > 1
      template void
      compute_row_length_vector(const DoFHandler<deal_II_dimension> &,
                                unsigned int,
                                std::vector<unsigned int> &,
                                const DoFTools::Coupling);
      template void
      compute_row_length_vector(const DoFHandler<deal_II_dimension> &,
                                unsigned int,
                                std::vector<unsigned int> &,
                                const Table<2, DoFTools::Coupling> &,
                                const Table<2, DoFTools::Coupling> &);
#endif

      template void
      count_dofs_per_component(
        const DoFHandler<deal_II_dimension> &,
        std::vector<std::vector<types::global_dof_index>> &,
        bool,
        std::vector<unsigned int>);
      template void
      count_dofs_per_block(const DoFHandler<deal_II_dimension> &,
                           std::vector<std::vector<types::global_dof_index>> &,
                           std::vector<unsigned int>);

#if deal_II_dimension > 1
      template void
      make_boundary_list(const DoFHandler<deal_II_dimension> &,
                         const std::map<types::boundary_id,
                                        const Function<deal_II_dimension> *> &,
                         std::vector<std::set<types::global_dof_index>> &,
                         const ComponentMask &);
#endif

      template void
      make_boundary_list(const DoFHandler<deal_II_dimension> &,
                         const std::map<types::boundary_id,
                                        const Function<deal_II_dimension> *> &,
                         std::vector<IndexSet> &,
                         const ComponentMask &);

      template void
      make_boundary_list(const DoFHandler<deal_II_dimension> &,
                         const std::set<types::boundary_id> &,
                         std::vector<IndexSet> &,
                         const ComponentMask &);


      template void
      extract_inner_interface_dofs(
        const DoFHandler<deal_II_dimension> &mg_dof_handler,
        std::vector<IndexSet> &              interface_dofs);

#if deal_II_dimension < 3
      template void
      count_dofs_per_block(
        const DoFHandler<deal_II_dimension, deal_II_dimension + 1> &,
        std::vector<std::vector<types::global_dof_index>> &,
        std::vector<unsigned int>);
#endif

#if deal_II_dimension == 3
      template void
      count_dofs_per_block(const DoFHandler<1, 3> &,
                           std::vector<std::vector<types::global_dof_index>> &,
                           std::vector<unsigned int>);
#endif
    \}
  }

for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension : SPACE_DIMENSIONS)
  {
    namespace MGTools
    \{
#if deal_II_dimension <= deal_II_space_dimension
      template unsigned int
      max_level_for_coarse_mesh(
        const Triangulation<deal_II_dimension, deal_II_space_dimension> &tria);

      template std::vector<types::global_dof_index>
      local_workload(
        const Triangulation<deal_II_dimension, deal_II_space_dimension> &tria);

      template std::vector<types::global_dof_index>
      local_workload(
        const std::vector<std::shared_ptr<
          const Triangulation<deal_II_dimension, deal_II_space_dimension>>>
          &tria);

      template double
      workload_imbalance(
        const Triangulation<deal_II_dimension, deal_II_space_dimension> &tria);

      template double
      workload_imbalance(
        const std::vector<std::shared_ptr<
          const Triangulation<deal_II_dimension, deal_II_space_dimension>>>
          &tria);

      template std::vector<
        std::pair<types::global_dof_index, types::global_dof_index>>
      local_vertical_communication_cost(
        const Triangulation<deal_II_dimension, deal_II_space_dimension> &tria);

      template std::vector<
        std::pair<types::global_dof_index, types::global_dof_index>>
      local_vertical_communication_cost(
        const std::vector<std::shared_ptr<
          const Triangulation<deal_II_dimension, deal_II_space_dimension>>>
          &tria);

      template double
      vertical_communication_efficiency(
        const Triangulation<deal_II_dimension, deal_II_space_dimension> &tria);

      template double
      vertical_communication_efficiency(
        const std::vector<std::shared_ptr<
          const Triangulation<deal_II_dimension, deal_II_space_dimension>>>
          &tria);
#endif
    \}
  }
