// ---------------------------------------------------------------------
//
// Copyright (C) 1998 - 2017 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 at
// the top level of the deal.II distribution.
//
// ---------------------------------------------------------------------


for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS)
{
#if deal_II_dimension <= deal_II_space_dimension
    namespace DoFRenumbering
    \{
    namespace boost
    \{
//TODO[WB]: also implement the following boost for hp DoFHandlers etc.
    \}


// non-boost functions:
    template
    void Cuthill_McKee<DoFHandler<deal_II_dimension,deal_II_space_dimension> >
    (DoFHandler<deal_II_dimension,deal_II_space_dimension>&,
     const bool,
     const bool,
     const std::vector<types::global_dof_index>&);

    template
    void
    compute_Cuthill_McKee<DoFHandler<deal_II_dimension,deal_II_space_dimension> >
    (std::vector<types::global_dof_index>&,
     const DoFHandler<deal_II_dimension,deal_II_space_dimension>&,
     const bool,
     const bool,
     const std::vector<types::global_dof_index>&);

    template
    void component_wise<DoFHandler<deal_II_dimension,deal_II_space_dimension> >
    (DoFHandler<deal_II_dimension,deal_II_space_dimension>&,
     const std::vector<unsigned int>&);

    template
    void component_wise<hp::DoFHandler<deal_II_dimension,deal_II_space_dimension> >
    (hp::DoFHandler<deal_II_dimension,deal_II_space_dimension>&,
     const std::vector<unsigned int>&);

    template
    void block_wise<deal_II_dimension,deal_II_space_dimension>
    (DoFHandler<deal_II_dimension,deal_II_space_dimension>&);

    template
    void subdomain_wise<DoFHandler<deal_II_dimension,deal_II_space_dimension> >
    (DoFHandler<deal_II_dimension,deal_II_space_dimension> &);

    template
    void
    compute_subdomain_wise (std::vector<types::global_dof_index> &new_dof_indices,
                            const DoFHandler<deal_II_dimension,deal_II_space_dimension> &dof_handler);

    \}  // namespace DoFRenumbering
#endif
}

//TODO[SP]: replace <deal_II_dimension> by <deal_II_dimension, deal_II_space_dimension>
// where applicable and move to codimension cases above also when applicable
for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS)
{
#if deal_II_dimension == deal_II_space_dimension
    namespace DoFRenumbering
    \{
    namespace boost
    \{
//TODO[WB]: also implement the following boost for hp DoFHandlers etc.
    template
    void
    Cuthill_McKee (DoFHandler<deal_II_dimension> &, bool, bool);

    template
    void
    compute_Cuthill_McKee (std::vector<dealii::types::global_dof_index> &,
                           const DoFHandler<deal_II_dimension> &, bool, bool);

    template
    void
    king_ordering (DoFHandler<deal_II_dimension> &, bool, bool);

    template
    void
    compute_king_ordering (std::vector<dealii::types::global_dof_index> &,
                           const DoFHandler<deal_II_dimension> &, bool, bool);

    template
    void
    minimum_degree (DoFHandler<deal_II_dimension> &, bool, bool);

    template
    void
    compute_minimum_degree (std::vector<dealii::types::global_dof_index> &,
                            const DoFHandler<deal_II_dimension> &, bool, bool);


    template
    void
    Cuthill_McKee (hp::DoFHandler<deal_II_dimension> &, bool, bool);

    template
    void
    compute_Cuthill_McKee (std::vector<dealii::types::global_dof_index> &,
                           const hp::DoFHandler<deal_II_dimension> &, bool, bool);

    template
    void
    king_ordering (hp::DoFHandler<deal_II_dimension> &, bool, bool);

    template
    void
    compute_king_ordering (std::vector<dealii::types::global_dof_index> &,
                           const hp::DoFHandler<deal_II_dimension> &, bool, bool);

    template
    void
    minimum_degree (hp::DoFHandler<deal_II_dimension> &, bool, bool);

    template
    void
    compute_minimum_degree (std::vector<dealii::types::global_dof_index> &,
                            const hp::DoFHandler<deal_II_dimension> &, bool, bool);
    \}


// non-boost functions:

    template
    void Cuthill_McKee<hp::DoFHandler<deal_II_dimension> >
    (hp::DoFHandler<deal_II_dimension>&,
     const bool,
     const bool,
     const std::vector<types::global_dof_index>&);

    template
    void
    compute_Cuthill_McKee<hp::DoFHandler<deal_II_dimension> >
    (std::vector<types::global_dof_index>&,
     const hp::DoFHandler<deal_II_dimension>&,
     const bool,
     const bool,
     const std::vector<types::global_dof_index>&);

    template
    void component_wise
    (DoFHandler<deal_II_dimension>&,
     unsigned int,
     const std::vector<unsigned int>&);

    template
    void block_wise<deal_II_dimension>
    (hp::DoFHandler<deal_II_dimension>&);

    template
    void block_wise<deal_II_dimension>
    (DoFHandler<deal_II_dimension>&,
     unsigned int);

    template
    void hierarchical<deal_II_dimension>
    (DoFHandler<deal_II_dimension>&);

    template void
    cell_wise<DoFHandler<deal_II_dimension> >
    (DoFHandler<deal_II_dimension>&,
     const std::vector<DoFHandler<deal_II_dimension>::active_cell_iterator>&);

    template void
    compute_cell_wise<DoFHandler<deal_II_dimension> >
    (std::vector<types::global_dof_index>&, std::vector<types::global_dof_index>&,
     const DoFHandler<deal_II_dimension>&,
     const std::vector<DoFHandler<deal_II_dimension>::active_cell_iterator>&);

    template void
    cell_wise<DoFHandler<deal_II_dimension> >
    (DoFHandler<deal_II_dimension>&, unsigned int,
     const std::vector<DoFHandler<deal_II_dimension>::level_cell_iterator>&);

    template void
    compute_cell_wise<DoFHandler<deal_II_dimension> >
    (std::vector<types::global_dof_index>&, std::vector<types::global_dof_index>&,
     const DoFHandler<deal_II_dimension>&, unsigned int,
     const std::vector<DoFHandler<deal_II_dimension>::level_cell_iterator>&);

    template void
    compute_downstream<DoFHandler<deal_II_dimension> >
    (std::vector<types::global_dof_index>&,std::vector<types::global_dof_index>&,
     const DoFHandler<deal_II_dimension>&, const Tensor<1,DoFHandler<deal_II_dimension>::space_dimension>&,
     const bool);

    template
    void
    clockwise_dg<DoFHandler<deal_II_dimension> >
    (DoFHandler<deal_II_dimension>&, const Point<deal_II_dimension>&, bool);

    template
    void
    compute_clockwise_dg<DoFHandler<deal_II_dimension> >
    (std::vector<types::global_dof_index>&, const DoFHandler<deal_II_dimension>&,
     const Point<deal_II_dimension>&, const bool);

// Renumbering for hp::DoFHandler

    template void
    cell_wise<hp::DoFHandler<deal_II_dimension> >
    (hp::DoFHandler<deal_II_dimension>&,
     const std::vector<hp::DoFHandler<deal_II_dimension>::active_cell_iterator>&);

    template void
    compute_cell_wise<hp::DoFHandler<deal_II_dimension> >
    (std::vector<types::global_dof_index>&, std::vector<types::global_dof_index>&,
     const hp::DoFHandler<deal_II_dimension>&,
     const std::vector<hp::DoFHandler<deal_II_dimension>::active_cell_iterator>&);

    template void
    compute_downstream<hp::DoFHandler<deal_II_dimension> >
    (std::vector<types::global_dof_index>&,std::vector<types::global_dof_index>&,
     const hp::DoFHandler<deal_II_dimension>&,
     const Tensor<1,hp::DoFHandler<deal_II_dimension>::space_dimension>&,
     const bool);

    template
    void
    clockwise_dg<hp::DoFHandler<deal_II_dimension> >
    (hp::DoFHandler<deal_II_dimension>&,
     const Point<deal_II_dimension>&, bool);

    template
    void
    compute_clockwise_dg<hp::DoFHandler<deal_II_dimension> >
    (std::vector<types::global_dof_index>&,
     const hp::DoFHandler<deal_II_dimension>&,
     const Point<deal_II_dimension>&,
     const bool);

    template
    void downstream
    (DoFHandler<deal_II_dimension>&,
     const Tensor<1,DoFHandler<deal_II_dimension>::space_dimension>&,
     const bool);

// MG

    template
    void downstream
    (DoFHandler<deal_II_dimension>&,
     const unsigned int,
     const Tensor<1,DoFHandler<deal_II_dimension>::space_dimension>&,
     const bool);

    template
    void clockwise_dg
    (DoFHandler<deal_II_dimension>&,
     const unsigned int,
     const Point<deal_II_dimension>&, bool);

// Generic numbering schemes

    template
    void random<DoFHandler<deal_II_dimension> >
    (DoFHandler<deal_II_dimension> &);

    template
    void
    compute_random<DoFHandler<deal_II_dimension> >
    (std::vector<types::global_dof_index>&,
     const DoFHandler<deal_II_dimension> &);

    template
    void sort_selected_dofs_back<DoFHandler<deal_II_dimension> >
    (DoFHandler<deal_II_dimension> &,
     const std::vector<bool> &);

    template
    void
    compute_sort_selected_dofs_back<DoFHandler<deal_II_dimension> >
    (std::vector<types::global_dof_index>&,
     const DoFHandler<deal_II_dimension> &,
     const std::vector<bool> &);

    template
    void random<hp::DoFHandler<deal_II_dimension> >
    (hp::DoFHandler<deal_II_dimension> &);

    template
    void
    compute_random<hp::DoFHandler<deal_II_dimension> >
    (std::vector<types::global_dof_index>&,
     const hp::DoFHandler<deal_II_dimension> &);

    template
    void sort_selected_dofs_back<hp::DoFHandler<deal_II_dimension> >
    (hp::DoFHandler<deal_II_dimension> &,
     const std::vector<bool> &);

    template
    void
    compute_sort_selected_dofs_back<hp::DoFHandler<deal_II_dimension> >
    (std::vector<types::global_dof_index>&,
     const hp::DoFHandler<deal_II_dimension> &,
     const std::vector<bool> &);


    template
    void subdomain_wise<hp::DoFHandler<deal_II_dimension> >
    (hp::DoFHandler<deal_II_dimension> &);

    template
    void Cuthill_McKee<DoFHandler<deal_II_dimension> >
    (DoFHandler<deal_II_dimension>&,
     const unsigned int,
     const bool,
     const std::vector<types::global_dof_index>&);
    \}  // namespace DoFRenumbering
#endif
}
