// ---------------------------------------------------------------------
//
// Copyright (C) 1998 - 2021 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.
//
// ---------------------------------------------------------------------

#ifndef DOXYGEN

for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension : SPACE_DIMENSIONS)
  {
#  if deal_II_dimension <= deal_II_space_dimension
    template class FEValuesBase<deal_II_dimension, deal_II_space_dimension>;
    template class FEValues<deal_II_dimension, deal_II_space_dimension>;

    template class FEFaceValuesBase<deal_II_dimension, deal_II_space_dimension>;
    template class FEFaceValues<deal_II_dimension, deal_II_space_dimension>;
    template class FESubfaceValues<deal_II_dimension, deal_II_space_dimension>;


    namespace FEValuesViews
    \{
      template class Scalar<deal_II_dimension, deal_II_space_dimension>;
      template class Vector<deal_II_dimension, deal_II_space_dimension>;
      template class SymmetricTensor<2,
                                     deal_II_dimension,
                                     deal_II_space_dimension>;
      template class Tensor<2, deal_II_dimension, deal_II_space_dimension>;
    \}

    namespace internal
    \{
      namespace FEValuesImplementation
      \{
        template class MappingRelatedData<deal_II_dimension,
                                          deal_II_space_dimension>;
        template class FiniteElementRelatedData<deal_II_dimension,
                                                deal_II_space_dimension>;
      \}
    \}
#  endif
  }


for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension : SPACE_DIMENSIONS;
     lda : BOOL)
  {
#  if deal_II_dimension <= deal_II_space_dimension
    template void FEValues<deal_II_dimension, deal_II_space_dimension>::reinit(
      const TriaIterator<
        DoFCellAccessor<deal_II_dimension, deal_II_space_dimension, lda>> &);
    template void
    FEFaceValues<deal_II_dimension, deal_II_space_dimension>::reinit(
      const TriaIterator<
        DoFCellAccessor<deal_II_dimension, deal_II_space_dimension, lda>> &,
      unsigned int);

    template void
    FEFaceValues<deal_II_dimension, deal_II_space_dimension>::reinit(
      const TriaIterator<
        DoFCellAccessor<deal_II_dimension, deal_II_space_dimension, lda>> &,
      const TriaIterator<TriaAccessor<deal_II_dimension - 1,
                                      deal_II_dimension,
                                      deal_II_space_dimension>> &);

    template void
    FESubfaceValues<deal_II_dimension, deal_II_space_dimension>::reinit(
      const TriaIterator<
        DoFCellAccessor<deal_II_dimension, deal_II_space_dimension, lda>> &,
      const unsigned int,
      const unsigned int);

    template void
    FESubfaceValues<deal_II_dimension, deal_II_space_dimension>::reinit(
      const TriaIterator<
        DoFCellAccessor<deal_II_dimension, deal_II_space_dimension, lda>> &,
      const TriaIterator<TriaAccessor<deal_II_dimension - 1,
                                      deal_II_dimension,
                                      deal_II_space_dimension>> &,
      const TriaIterator<TriaAccessor<deal_II_dimension - 1,
                                      deal_II_dimension,
                                      deal_II_space_dimension>> &);
#  endif
  }



for (VEC : VECTOR_TYPES; deal_II_dimension : DIMENSIONS;
     deal_II_space_dimension : SPACE_DIMENSIONS)
  {
#  if deal_II_dimension <= deal_II_space_dimension
    template void
    FEValuesViews::Scalar<deal_II_dimension, deal_II_space_dimension>::
      get_function_values<dealii::VEC>(
        const dealii::VEC &,
        std::vector<ProductType<dealii::VEC::value_type, value_type>::type> &)
        const;
    template void
    FEValuesViews::Scalar<deal_II_dimension, deal_II_space_dimension>::
      get_function_gradients<dealii::VEC>(
        const dealii::VEC &,
        std::vector<
          ProductType<dealii::VEC::value_type,
                      dealii::Tensor<1, deal_II_space_dimension>>::type> &)
        const;
    template void
    FEValuesViews::Scalar<deal_II_dimension, deal_II_space_dimension>::
      get_function_hessians<dealii::VEC>(
        const dealii::VEC &,
        std::vector<
          ProductType<dealii::VEC::value_type,
                      dealii::Tensor<2, deal_II_space_dimension>>::type> &)
        const;
    template void
    FEValuesViews::Scalar<deal_II_dimension, deal_II_space_dimension>::
      get_function_laplacians<dealii::VEC>(
        const dealii::VEC &,
        std::vector<ProductType<dealii::VEC::value_type, double>::type> &)
        const;
    template void
    FEValuesViews::Scalar<deal_II_dimension, deal_II_space_dimension>::
      get_function_third_derivatives<dealii::VEC>(
        const dealii::VEC &,
        std::vector<
          ProductType<dealii::VEC::value_type,
                      dealii::Tensor<3, deal_II_space_dimension>>::type> &)
        const;

    template void
    FEValuesViews::Vector<deal_II_dimension, deal_II_space_dimension>::
      get_function_values<dealii::VEC>(
        const dealii::VEC &,
        std::vector<
          ProductType<dealii::VEC::value_type,
                      dealii::Tensor<1, deal_II_space_dimension>>::type> &)
        const;
    template void
    FEValuesViews::Vector<deal_II_dimension, deal_II_space_dimension>::
      get_function_gradients<dealii::VEC>(
        const dealii::VEC &,
        std::vector<
          ProductType<dealii::VEC::value_type,
                      dealii::Tensor<2, deal_II_space_dimension>>::type> &)
        const;
    template void
    FEValuesViews::Vector<deal_II_dimension, deal_II_space_dimension>::
      get_function_symmetric_gradients<dealii::VEC>(
        const dealii::VEC &,
        std::vector<ProductType<
          dealii::VEC::value_type,
          dealii::SymmetricTensor<2, deal_II_space_dimension>>::type> &) const;
    template void
    FEValuesViews::Vector<deal_II_dimension, deal_II_space_dimension>::
      get_function_curls<dealii::VEC>(
        const dealii::VEC &,
        std::vector<ProductType<dealii::VEC::value_type, curl_type>::type> &)
        const;
    template void
    FEValuesViews::Vector<deal_II_dimension, deal_II_space_dimension>::
      get_function_divergences<dealii::VEC>(
        const dealii::VEC &,
        std::vector<ProductType<dealii::VEC::value_type, divergence_type>::type>
          &) const;
    template void
    FEValuesViews::Vector<deal_II_dimension, deal_II_space_dimension>::
      get_function_hessians<dealii::VEC>(
        const dealii::VEC &,
        std::vector<
          ProductType<dealii::VEC::value_type,
                      dealii::Tensor<3, deal_II_space_dimension>>::type> &)
        const;
    template void
    FEValuesViews::Vector<deal_II_dimension, deal_II_space_dimension>::
      get_function_laplacians<dealii::VEC>(
        const dealii::VEC &,
        std::vector<
          ProductType<dealii::VEC::value_type,
                      dealii::Tensor<1, deal_II_space_dimension>>::type> &)
        const;
    template void
    FEValuesViews::Vector<deal_II_dimension, deal_II_space_dimension>::
      get_function_third_derivatives<dealii::VEC>(
        const dealii::VEC &,
        std::vector<
          ProductType<dealii::VEC::value_type,
                      dealii::Tensor<4, deal_II_space_dimension>>::type> &)
        const;

    template void FEValuesViews::SymmetricTensor<2,
                                                 deal_II_dimension,
                                                 deal_II_space_dimension>::
      get_function_values<dealii::VEC>(
        const dealii::VEC &,
        std::vector<ProductType<
          dealii::VEC::value_type,
          dealii::SymmetricTensor<2, deal_II_space_dimension>>::type> &) const;
    template void FEValuesViews::
      SymmetricTensor<2, deal_II_dimension, deal_II_space_dimension>::
        get_function_divergences<dealii::VEC>(
          const dealii::VEC &,
          std::vector<
            ProductType<dealii::VEC::value_type,
                        dealii::Tensor<1, deal_II_space_dimension>>::type> &)
          const;

    template void
    FEValuesViews::Tensor<2, deal_II_dimension, deal_II_space_dimension>::
      get_function_values<dealii::VEC>(
        const dealii::VEC &,
        std::vector<
          ProductType<dealii::VEC::value_type,
                      dealii::Tensor<2, deal_II_space_dimension>>::type> &)
        const;
    template void
    FEValuesViews::Tensor<2, deal_II_dimension, deal_II_space_dimension>::
      get_function_divergences<dealii::VEC>(
        const dealii::VEC &,
        std::vector<
          ProductType<dealii::VEC::value_type,
                      dealii::Tensor<1, deal_II_space_dimension>>::type> &)
        const;
    template void
    FEValuesViews::Tensor<2, deal_II_dimension, deal_II_space_dimension>::
      get_function_gradients<dealii::VEC>(
        const dealii::VEC &,
        std::vector<
          ProductType<dealii::VEC::value_type,
                      dealii::Tensor<3, deal_II_space_dimension>>::type> &)
        const;
#  endif
  }


for (VEC : GENERAL_CONTAINER_TYPES; Number : ALL_SCALAR_TYPES;
     deal_II_dimension : DIMENSIONS;
     deal_II_space_dimension : SPACE_DIMENSIONS)
  {
#  if deal_II_dimension <= deal_II_space_dimension
    template void
    FEValuesViews::Scalar<deal_II_dimension, deal_II_space_dimension>::
      get_function_values_from_local_dof_values<VEC<Number>>(
        const VEC<Number> &, std::vector<solution_value_type<Number>> &) const;

    template void
    FEValuesViews::Scalar<deal_II_dimension, deal_II_space_dimension>::
      get_function_gradients_from_local_dof_values<VEC<Number>>(
        const VEC<Number> &, std::vector<solution_gradient_type<Number>> &)
        const;

    template void
    FEValuesViews::Scalar<deal_II_dimension, deal_II_space_dimension>::
      get_function_hessians_from_local_dof_values<VEC<Number>>(
        const VEC<Number> &, std::vector<solution_hessian_type<Number>> &)
        const;

    template void
    FEValuesViews::Scalar<deal_II_dimension, deal_II_space_dimension>::
      get_function_laplacians_from_local_dof_values<VEC<Number>>(
        const VEC<Number> &, std::vector<solution_value_type<Number>> &) const;

    template void
    FEValuesViews::Scalar<deal_II_dimension, deal_II_space_dimension>::
      get_function_third_derivatives_from_local_dof_values<VEC<Number>>(
        const VEC<Number> &,
        std::vector<solution_third_derivative_type<Number>> &) const;



    template void
    FEValuesViews::Vector<deal_II_dimension, deal_II_space_dimension>::
      get_function_values_from_local_dof_values<VEC<Number>>(
        const VEC<Number> &, std::vector<solution_value_type<Number>> &) const;

    template void
    FEValuesViews::Vector<deal_II_dimension, deal_II_space_dimension>::
      get_function_gradients_from_local_dof_values<VEC<Number>>(
        const VEC<Number> &, std::vector<solution_gradient_type<Number>> &)
        const;

    template void
    FEValuesViews::Vector<deal_II_dimension, deal_II_space_dimension>::
      get_function_symmetric_gradients_from_local_dof_values<VEC<Number>>(
        const VEC<Number> &,
        std::vector<solution_symmetric_gradient_type<Number>> &) const;

    template void
    FEValuesViews::Vector<deal_II_dimension, deal_II_space_dimension>::
      get_function_divergences_from_local_dof_values<VEC<Number>>(
        const VEC<Number> &, std::vector<solution_divergence_type<Number>> &)
        const;

    template void
    FEValuesViews::Vector<deal_II_dimension, deal_II_space_dimension>::
      get_function_curls_from_local_dof_values<VEC<Number>>(
        const VEC<Number> &, std::vector<solution_curl_type<Number>> &) const;

    template void
    FEValuesViews::Vector<deal_II_dimension, deal_II_space_dimension>::
      get_function_hessians_from_local_dof_values<VEC<Number>>(
        const VEC<Number> &, std::vector<solution_hessian_type<Number>> &)
        const;

    template void
    FEValuesViews::Vector<deal_II_dimension, deal_II_space_dimension>::
      get_function_laplacians_from_local_dof_values<VEC<Number>>(
        const VEC<Number> &, std::vector<solution_value_type<Number>> &) const;

    template void
    FEValuesViews::Vector<deal_II_dimension, deal_II_space_dimension>::
      get_function_third_derivatives_from_local_dof_values<VEC<Number>>(
        const VEC<Number> &,
        std::vector<solution_third_derivative_type<Number>> &) const;



    template void FEValuesViews::SymmetricTensor<2,
                                                 deal_II_dimension,
                                                 deal_II_space_dimension>::
      get_function_values_from_local_dof_values<VEC<Number>>(
        const VEC<Number> &, std::vector<solution_value_type<Number>> &) const;

    template void FEValuesViews::
      SymmetricTensor<2, deal_II_dimension, deal_II_space_dimension>::
        get_function_divergences_from_local_dof_values<VEC<Number>>(
          const VEC<Number> &, std::vector<solution_divergence_type<Number>> &)
          const;



    template void
    FEValuesViews::Tensor<2, deal_II_dimension, deal_II_space_dimension>::
      get_function_values_from_local_dof_values<VEC<Number>>(
        const VEC<Number> &, std::vector<solution_value_type<Number>> &) const;

    template void
    FEValuesViews::Tensor<2, deal_II_dimension, deal_II_space_dimension>::
      get_function_divergences_from_local_dof_values<VEC<Number>>(
        const VEC<Number> &, std::vector<solution_divergence_type<Number>> &)
        const;

    template void
    FEValuesViews::Tensor<2, deal_II_dimension, deal_II_space_dimension>::
      get_function_gradients_from_local_dof_values<VEC<Number>>(
        const VEC<Number> &, std::vector<solution_gradient_type<Number>> &)
        const;
#  endif
  }


for (VEC : VECTOR_TYPES; deal_II_dimension : DIMENSIONS;
     deal_II_space_dimension : SPACE_DIMENSIONS)
  {
#  if deal_II_dimension <= deal_II_space_dimension

    template void FEValuesBase<deal_II_dimension, deal_II_space_dimension>::
      get_function_values<VEC>(const VEC &, std::vector<VEC::value_type> &)
        const;
    template void FEValuesBase<deal_II_dimension, deal_II_space_dimension>::
      get_function_values<VEC>(const VEC &,
                               const ArrayView<const types::global_dof_index> &,
                               std::vector<VEC::value_type> &) const;

    template void FEValuesBase<deal_II_dimension, deal_II_space_dimension>::
      get_function_values<VEC>(const VEC &,
                               std::vector<Vector<VEC::value_type>> &) const;

    template void FEValuesBase<deal_II_dimension, deal_II_space_dimension>::
      get_function_values<VEC>(const VEC &,
                               const ArrayView<const types::global_dof_index> &,
                               std::vector<Vector<VEC::value_type>> &) const;

    template void FEValuesBase<deal_II_dimension, deal_II_space_dimension>::
      get_function_values<VEC>(const VEC &,
                               const ArrayView<const types::global_dof_index> &,
                               ArrayView<std::vector<VEC::value_type>>,
                               bool) const;

    template void FEValuesBase<deal_II_dimension, deal_II_space_dimension>::
      get_function_gradients<VEC>(
        const VEC &,
        std::vector<dealii::Tensor<1, deal_II_space_dimension, VEC::value_type>>
          &) const;
    template void FEValuesBase<deal_II_dimension, deal_II_space_dimension>::
      get_function_gradients<VEC>(
        const VEC &,
        const ArrayView<const types::global_dof_index> &,
        std::vector<dealii::Tensor<1, deal_II_space_dimension, VEC::value_type>>
          &) const;

    template void FEValuesBase<deal_II_dimension, deal_II_space_dimension>::
      get_function_gradients<VEC>(
        const VEC &,
        std::vector<std::vector<
          dealii::Tensor<1, deal_II_space_dimension, VEC::value_type>>> &)
        const;
    template void FEValuesBase<deal_II_dimension, deal_II_space_dimension>::
      get_function_gradients<VEC>(
        const VEC &,
        const ArrayView<const types::global_dof_index> &,
        ArrayView<std::vector<
          dealii::Tensor<1, deal_II_space_dimension, VEC::value_type>>>,
        bool) const;

    template void FEValuesBase<deal_II_dimension, deal_II_space_dimension>::
      get_function_hessians<VEC>(
        const VEC &,
        std::vector<dealii::Tensor<2, deal_II_space_dimension, VEC::value_type>>
          &) const;
    template void FEValuesBase<deal_II_dimension, deal_II_space_dimension>::
      get_function_hessians<VEC>(
        const VEC &,
        const ArrayView<const types::global_dof_index> &,
        std::vector<dealii::Tensor<2, deal_II_space_dimension, VEC::value_type>>
          &) const;

    template void FEValuesBase<deal_II_dimension, deal_II_space_dimension>::
      get_function_hessians<VEC>(
        const VEC &,
        std::vector<std::vector<
          dealii::Tensor<2, deal_II_space_dimension, VEC::value_type>>> &,
        bool) const;
    template void FEValuesBase<deal_II_dimension, deal_II_space_dimension>::
      get_function_hessians<VEC>(
        const VEC &,
        const ArrayView<const types::global_dof_index> &,
        ArrayView<std::vector<
          dealii::Tensor<2, deal_II_space_dimension, VEC::value_type>>>,
        bool) const;

    template void FEValuesBase<deal_II_dimension, deal_II_space_dimension>::
      get_function_laplacians<VEC>(const VEC &, std::vector<VEC::value_type> &)
        const;
    template void FEValuesBase<deal_II_dimension, deal_II_space_dimension>::
      get_function_laplacians<VEC>(
        const VEC &,
        const ArrayView<const types::global_dof_index> &,
        std::vector<VEC::value_type> &) const;

    template void FEValuesBase<deal_II_dimension, deal_II_space_dimension>::
      get_function_laplacians<VEC>(const VEC &,
                                   std::vector<Vector<VEC::value_type>> &)
        const;

    template void FEValuesBase<deal_II_dimension, deal_II_space_dimension>::
      get_function_laplacians<VEC>(
        const VEC &,
        const ArrayView<const types::global_dof_index> &,
        std::vector<Vector<VEC::value_type>> &) const;

    template void FEValuesBase<deal_II_dimension, deal_II_space_dimension>::
      get_function_laplacians<VEC>(
        const VEC &,
        const ArrayView<const types::global_dof_index> &,
        std::vector<std::vector<VEC::value_type>> &,
        bool) const;

    template void FEValuesBase<deal_II_dimension, deal_II_space_dimension>::
      get_function_third_derivatives<VEC>(
        const VEC &,
        std::vector<dealii::Tensor<3, deal_II_space_dimension, VEC::value_type>>
          &) const;
    template void FEValuesBase<deal_II_dimension, deal_II_space_dimension>::
      get_function_third_derivatives<VEC>(
        const VEC &,
        const ArrayView<const types::global_dof_index> &,
        std::vector<dealii::Tensor<3, deal_II_space_dimension, VEC::value_type>>
          &) const;

    template void FEValuesBase<deal_II_dimension, deal_II_space_dimension>::
      get_function_third_derivatives<VEC>(
        const VEC &,
        std::vector<std::vector<
          dealii::Tensor<3, deal_II_space_dimension, VEC::value_type>>> &,
        bool) const;
    template void FEValuesBase<deal_II_dimension, deal_II_space_dimension>::
      get_function_third_derivatives<VEC>(
        const VEC &,
        const ArrayView<const types::global_dof_index> &,
        ArrayView<std::vector<
          dealii::Tensor<3, deal_II_space_dimension, VEC::value_type>>>,
        bool) const;

#  endif
  }
#endif
