Reference documentation for deal.II version GIT d9d8a449a2 2022-08-17 08:45:02+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
mg_transfer_global_coarsening.h
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2020 - 2022 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_mg_transfer_global_coarsening_h
17 #define dealii_mg_transfer_global_coarsening_h
18 
21 
23 
26 
29 
32 
34 
35 // Forward declarations
36 #ifndef DOXYGEN
37 namespace internal
38 {
39  class MGTwoLevelTransferImplementation;
40 }
41 
43 {
44  template <int dim, int spacedim>
45  class Base;
46 }
47 #endif
48 
49 
50 
55 {
64  {
69  bisect,
79  go_to_one
80  };
81 
86  unsigned int
88  const unsigned int degree,
89  const PolynomialCoarseningSequenceType &p_sequence);
90 
96  std::vector<unsigned int>
98  const unsigned int max_degree,
99  const PolynomialCoarseningSequenceType &p_sequence);
100 
111  template <int dim, int spacedim>
112  std::vector<std::shared_ptr<const Triangulation<dim, spacedim>>>
115 
132  template <int dim, int spacedim>
133  std::vector<std::shared_ptr<const Triangulation<dim, spacedim>>>
137  const bool preserve_fine_triangulation,
138  const bool repartition_fine_triangulation);
139 
145  template <int dim, int spacedim>
146  std::vector<std::shared_ptr<const Triangulation<dim, spacedim>>>
150  const bool repartition_fine_triangulation = false);
151 
152 } // namespace MGTransferGlobalCoarseningTools
153 
154 
155 
161 template <int dim, typename VectorType>
163 {
164 public:
168  void
169  prolongate_and_add(VectorType &dst, const VectorType &src) const;
170 
174  void
175  restrict_and_add(VectorType &dst, const VectorType &src) const;
176 
183  void
184  interpolate(VectorType &dst, const VectorType &src) const;
185 
190  void
192  const std::shared_ptr<const Utilities::MPI::Partitioner>
193  &partitioner_coarse,
194  const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner_fine);
195 
199  std::size_t
201 };
202 
203 
204 
211 template <int dim, typename Number>
213 {
214 public:
220  void
222  const DoFHandler<dim> & dof_handler_fine,
223  const DoFHandler<dim> & dof_handler_coarse,
224  const AffineConstraints<Number> &constraint_fine =
226  const AffineConstraints<Number> &constraint_coarse =
228  const unsigned int mg_level_fine = numbers::invalid_unsigned_int,
229  const unsigned int mg_level_coarse = numbers::invalid_unsigned_int);
230 
240  void
242  const DoFHandler<dim> & dof_handler_fine,
243  const DoFHandler<dim> & dof_handler_coarse,
244  const AffineConstraints<Number> &constraint_fine =
246  const AffineConstraints<Number> &constraint_coarse =
248  const unsigned int mg_level_fine = numbers::invalid_unsigned_int,
249  const unsigned int mg_level_coarse = numbers::invalid_unsigned_int);
250 
264  void
265  reinit(const DoFHandler<dim> & dof_handler_fine,
266  const DoFHandler<dim> & dof_handler_coarse,
267  const AffineConstraints<Number> &constraint_fine =
269  const AffineConstraints<Number> &constraint_coarse =
271  const unsigned int mg_level_fine = numbers::invalid_unsigned_int,
272  const unsigned int mg_level_coarse = numbers::invalid_unsigned_int);
273 
282  static bool
283  fast_polynomial_transfer_supported(const unsigned int fe_degree_fine,
284  const unsigned int fe_degree_coarse);
285 
289  void
293 
297  void
300 
307  void
310 
315  void
317  const std::shared_ptr<const Utilities::MPI::Partitioner>
318  &partitioner_coarse,
319  const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner_fine);
320 
324  std::size_t
326 
327 private:
335  struct MGTransferScheme
336  {
340  unsigned int n_coarse_cells;
341 
349 
356  unsigned int n_dofs_per_cell_fine;
357 
361  unsigned int degree_coarse;
362 
368  unsigned int degree_fine;
369 
374 
379 
384 
389 
396  };
397 
401  std::vector<MGTransferScheme> schemes;
402 
409 
413  std::shared_ptr<const Utilities::MPI::Partitioner> partitioner_fine;
414 
418  std::shared_ptr<const Utilities::MPI::Partitioner> partitioner_coarse;
419 
428 
433 
440 
444  std::vector<Number> weights;
445 
451 
456  std::vector<unsigned int> level_dof_indices_fine;
457 
461  unsigned int n_components;
462 
463  friend class internal::MGTwoLevelTransferImplementation;
464 };
465 
466 
467 
480 template <int dim, typename VectorType>
482 {
483 public:
487  using Number = typename VectorType::value_type;
488 
498  const std::function<void(const unsigned int, VectorType &)>
499  &initialize_dof_vector = {});
500 
509  void
510  build(const std::vector<std::shared_ptr<const Utilities::MPI::Partitioner>>
511  &external_partitioners = {});
512 
517  void
518  build(const std::function<void(const unsigned int, VectorType &)>
520 
524  void
525  prolongate(const unsigned int to_level,
526  VectorType & dst,
527  const VectorType & src) const override;
528 
532  void
533  prolongate_and_add(const unsigned int to_level,
534  VectorType & dst,
535  const VectorType & src) const override;
536 
540  virtual void
541  restrict_and_add(const unsigned int from_level,
542  VectorType & dst,
543  const VectorType & src) const override;
544 
551  template <class InVector, int spacedim>
552  void
555  const InVector & src) const;
556 
563  template <class OutVector, int spacedim>
564  void
566  OutVector & dst,
567  const MGLevelObject<VectorType> &src) const;
568 
581  template <class InVector>
582  void
583  interpolate_to_mg(MGLevelObject<VectorType> &dst, const InVector &src) const;
584 
591  template <class InVector, int spacedim>
592  void
595  const InVector & src) const;
596 
603  std::size_t
605 
609  unsigned int
610  min_level() const;
611 
615  unsigned int
616  max_level() const;
617 
618 private:
622  void
623  initialize_dof_vector(const unsigned int level, VectorType &vector) const;
624 
629 
633  std::vector<std::shared_ptr<const Utilities::MPI::Partitioner>>
635 };
636 
637 
638 
644 template <int dim, typename VectorType>
647  dim,
648  typename VectorType::value_type,
649  MGTransferGlobalCoarsening<dim, VectorType>>
650 {
651 public:
657 
658 protected:
660  get_matrix_free_transfer(const unsigned int b) const override;
661 
662 private:
667 };
668 
669 
670 
671 #ifndef DOXYGEN
672 
673 /* ----------------------- Inline functions --------------------------------- */
674 
675 
676 
677 template <int dim, typename VectorType>
680  const std::function<void(const unsigned int, VectorType &)>
681  &initialize_dof_vector)
682  : transfer(transfer)
683 {
684  this->build(initialize_dof_vector);
685 }
686 
687 
688 
689 template <int dim, typename VectorType>
690 void
692  const std::vector<std::shared_ptr<const Utilities::MPI::Partitioner>>
693  &external_partitioners)
694 {
695  this->external_partitioners = external_partitioners;
696 
697  if (this->external_partitioners.size() > 0)
698  {
699  const unsigned int min_level = transfer.min_level();
700  const unsigned int max_level = transfer.max_level();
701 
702  AssertDimension(this->external_partitioners.size(), transfer.n_levels());
703 
704  for (unsigned int l = min_level + 1; l <= max_level; ++l)
705  transfer[l].enable_inplace_operations_if_possible(
706  this->external_partitioners[l - 1 - min_level],
707  this->external_partitioners[l - min_level]);
708  }
709 }
710 
711 
712 
713 template <int dim, typename VectorType>
714 void
716  const std::function<void(const unsigned int, VectorType &)>
717  &initialize_dof_vector)
718 {
719  if (initialize_dof_vector)
720  {
721  const unsigned int min_level = transfer.min_level();
722  const unsigned int max_level = transfer.max_level();
723  const unsigned int n_levels = transfer.n_levels();
724 
725  std::vector<std::shared_ptr<const Utilities::MPI::Partitioner>>
726  external_partitioners(n_levels);
727 
728  for (unsigned int l = min_level; l <= max_level; ++l)
729  {
731  vector;
732  initialize_dof_vector(l, vector);
733  external_partitioners[l - min_level] = vector.get_partitioner();
734  }
735 
736  this->build(external_partitioners);
737  }
738  else
739  {
740  this->build();
741  }
742 }
743 
744 
745 
746 template <int dim, typename VectorType>
747 void
749  const unsigned int level,
750  VectorType & vec) const
751 {
752  AssertDimension(transfer.n_levels(), external_partitioners.size());
753  AssertIndexRange(level, transfer.max_level() + 1);
754 
755  const auto &external_partitioner =
756  external_partitioners[level - transfer.min_level()];
757 
758  if (vec.get_partitioner().get() != external_partitioner.get())
759  vec.reinit(external_partitioner);
760 }
761 
762 
763 
764 template <int dim, typename VectorType>
765 void
767  const unsigned int to_level,
768  VectorType & dst,
769  const VectorType & src) const
770 {
771  dst = 0;
772  prolongate_and_add(to_level, dst, src);
773 }
774 
775 
776 
777 template <int dim, typename VectorType>
778 void
780  const unsigned int to_level,
781  VectorType & dst,
782  const VectorType & src) const
783 {
784  this->transfer[to_level].prolongate_and_add(dst, src);
785 }
786 
787 
788 
789 template <int dim, typename VectorType>
790 void
792  const unsigned int from_level,
793  VectorType & dst,
794  const VectorType & src) const
795 {
796  this->transfer[from_level].restrict_and_add(dst, src);
797 }
798 
799 
800 
801 template <int dim, typename VectorType>
802 template <class InVector, int spacedim>
803 void
805  const DoFHandler<dim, spacedim> &dof_handler,
807  const InVector & src) const
808 {
809  (void)dof_handler;
810 
811  for (unsigned int level = dst.min_level(); level <= dst.max_level(); ++level)
812  {
813  initialize_dof_vector(level, dst[level]);
814 
815  if (level == dst.max_level())
816  dst[level].copy_locally_owned_data_from(src);
817  else
818  dst[level] = 0.0;
819  }
820 }
821 
822 
823 
824 template <int dim, typename VectorType>
825 template <class OutVector, int spacedim>
826 void
828  const DoFHandler<dim, spacedim> &dof_handler,
829  OutVector & dst,
830  const MGLevelObject<VectorType> &src) const
831 {
832  (void)dof_handler;
833 
834  dst.copy_locally_owned_data_from(src[src.max_level()]);
835 }
836 
837 
838 
839 template <int dim, typename VectorType>
840 template <class InVector>
841 void
844  const InVector & src) const
845 {
846  const unsigned int min_level = transfer.min_level();
847  const unsigned int max_level = transfer.max_level();
848 
849  AssertDimension(min_level, dst.min_level());
850  AssertDimension(max_level, dst.max_level());
851 
852  for (unsigned int level = min_level; level <= max_level; ++level)
853  initialize_dof_vector(level, dst[level]);
854 
855  dst[transfer.max_level()].copy_locally_owned_data_from(src);
856 
857  for (unsigned int l = max_level; l > min_level; --l)
858  this->transfer[l].interpolate(dst[l - 1], dst[l]);
859 }
860 
861 
862 
863 template <int dim, typename VectorType>
864 template <class InVector, int spacedim>
865 void
867  const DoFHandler<dim, spacedim> &dof_handler,
869  const InVector & src) const
870 {
871  (void)dof_handler;
872 
873  this->interpolate_to_mg(dst, src);
874 }
875 
876 
877 
878 template <int dim, typename VectorType>
879 std::size_t
881 {
882  std::size_t size = 0;
883 
884  const unsigned int min_level = transfer.min_level();
885  const unsigned int max_level = transfer.max_level();
886 
887  for (unsigned int l = min_level + 1; l <= max_level; ++l)
888  size += this->transfer[l].memory_consumption();
889 
890  return size;
891 }
892 
893 
894 
895 template <int dim, typename VectorType>
896 inline unsigned int
898 {
899  return transfer.min_level();
900 }
901 
902 
903 
904 template <int dim, typename VectorType>
905 inline unsigned int
907 {
908  return transfer.max_level();
909 }
910 
911 #endif
912 
914 
915 #endif
const std::shared_ptr< const Utilities::MPI::Partitioner > & get_partitioner() const
unsigned int max_level() const
unsigned int min_level() const
MGTransferBlockGlobalCoarsening(const MGTransferGlobalCoarsening< dim, VectorType > &transfer_operator)
const MGTransferGlobalCoarsening< dim, VectorType > & transfer_operator
const MGTransferGlobalCoarsening< dim, VectorType > & get_matrix_free_transfer(const unsigned int b) const override
void copy_from_mg(const DoFHandler< dim, spacedim > &dof_handler, OutVector &dst, const MGLevelObject< VectorType > &src) const
void interpolate_to_mg(const DoFHandler< dim, spacedim > &dof_handler, MGLevelObject< VectorType > &dst, const InVector &src) const
void prolongate(const unsigned int to_level, VectorType &dst, const VectorType &src) const override
typename VectorType::value_type Number
unsigned int min_level() const
std::vector< std::shared_ptr< const Utilities::MPI::Partitioner > > external_partitioners
void build(const std::vector< std::shared_ptr< const Utilities::MPI::Partitioner >> &external_partitioners={})
void copy_to_mg(const DoFHandler< dim, spacedim > &dof_handler, MGLevelObject< VectorType > &dst, const InVector &src) const
virtual void restrict_and_add(const unsigned int from_level, VectorType &dst, const VectorType &src) const override
std::size_t memory_consumption() const
void initialize_dof_vector(const unsigned int level, VectorType &vector) const
void build(const std::function< void(const unsigned int, VectorType &)> &initialize_dof_vector)
void interpolate_to_mg(MGLevelObject< VectorType > &dst, const InVector &src) const
MGLevelObject< MGTwoLevelTransfer< dim, VectorType > > transfer
void prolongate_and_add(const unsigned int to_level, VectorType &dst, const VectorType &src) const override
MGTransferGlobalCoarsening(const MGLevelObject< MGTwoLevelTransfer< dim, VectorType >> &transfer, const std::function< void(const unsigned int, VectorType &)> &initialize_dof_vector={})
unsigned int max_level() const
void enable_inplace_operations_if_possible(const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner_coarse, const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner_fine)
void prolongate_and_add(LinearAlgebra::distributed::Vector< Number > &dst, const LinearAlgebra::distributed::Vector< Number > &src) const
void reinit_polynomial_transfer(const DoFHandler< dim > &dof_handler_fine, const DoFHandler< dim > &dof_handler_coarse, const AffineConstraints< Number > &constraint_fine=AffineConstraints< Number >(), const AffineConstraints< Number > &constraint_coarse=AffineConstraints< Number >(), const unsigned int mg_level_fine=numbers::invalid_unsigned_int, const unsigned int mg_level_coarse=numbers::invalid_unsigned_int)
static bool fast_polynomial_transfer_supported(const unsigned int fe_degree_fine, const unsigned int fe_degree_coarse)
void interpolate(LinearAlgebra::distributed::Vector< Number > &dst, const LinearAlgebra::distributed::Vector< Number > &src) const
internal::MatrixFreeFunctions::ConstraintInfo< dim, VectorizedArray< Number > > constraint_info
void restrict_and_add(LinearAlgebra::distributed::Vector< Number > &dst, const LinearAlgebra::distributed::Vector< Number > &src) const
void reinit(const DoFHandler< dim > &dof_handler_fine, const DoFHandler< dim > &dof_handler_coarse, const AffineConstraints< Number > &constraint_fine=AffineConstraints< Number >(), const AffineConstraints< Number > &constraint_coarse=AffineConstraints< Number >(), const unsigned int mg_level_fine=numbers::invalid_unsigned_int, const unsigned int mg_level_coarse=numbers::invalid_unsigned_int)
void reinit_geometric_transfer(const DoFHandler< dim > &dof_handler_fine, const DoFHandler< dim > &dof_handler_coarse, const AffineConstraints< Number > &constraint_fine=AffineConstraints< Number >(), const AffineConstraints< Number > &constraint_coarse=AffineConstraints< Number >(), const unsigned int mg_level_fine=numbers::invalid_unsigned_int, const unsigned int mg_level_coarse=numbers::invalid_unsigned_int)
void restrict_and_add(VectorType &dst, const VectorType &src) const
void enable_inplace_operations_if_possible(const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner_coarse, const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner_fine)
std::size_t memory_consumption() const
void interpolate(VectorType &dst, const VectorType &src) const
void prolongate_and_add(VectorType &dst, const VectorType &src) const
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:442
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:443
unsigned int level
Definition: grid_out.cc:4608
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1667
#define AssertIndexRange(index, range)
Definition: exceptions.h:1732
void interpolate(const DoFHandler< dim, spacedim > &dof1, const InVector &u1, const DoFHandler< dim, spacedim > &dof2, OutVector &u2)
std::vector< std::shared_ptr< const Triangulation< dim, spacedim > > > create_geometric_coarsening_sequence(const Triangulation< dim, spacedim > &tria)
unsigned int create_next_polynomial_coarsening_degree(const unsigned int degree, const PolynomialCoarseningSequenceType &p_sequence)
std::vector< unsigned int > create_polynomial_coarsening_sequence(const unsigned int max_degree, const PolynomialCoarseningSequenceType &p_sequence)
std::enable_if_t< std::is_fundamental< T >::value, std::size_t > memory_consumption(const T &t)
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
static const unsigned int invalid_unsigned_int
Definition: types.h:201
internal::MatrixFreeFunctions::ShapeInfo< VectorizedArray< Number > > shape_info_coarse
const ::Triangulation< dim, spacedim > & tria