Reference documentation for deal.II version Git fcdb0c0ec9 2020-08-03 17:46:58 +0200
\(\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\}}\)
tria_base.cc
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2015 - 2020 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 
17 #include <deal.II/base/logstream.h>
19 #include <deal.II/base/utilities.h>
20 
22 
24 #include <deal.II/grid/tria.h>
27 
31 
32 #include <algorithm>
33 #include <fstream>
34 #include <iostream>
35 #include <numeric>
36 
37 
39 
40 namespace parallel
41 {
42  template <int dim, int spacedim>
44  MPI_Comm mpi_communicator,
45  const typename ::Triangulation<dim, spacedim>::MeshSmoothing
46  smooth_grid,
47  const bool check_for_distorted_cells)
48  : ::Triangulation<dim, spacedim>(smooth_grid,
49  check_for_distorted_cells)
50  , mpi_communicator(mpi_communicator)
51  , my_subdomain(Utilities::MPI::this_mpi_process(this->mpi_communicator))
52  , n_subdomains(Utilities::MPI::n_mpi_processes(this->mpi_communicator))
53  {
54 #ifndef DEAL_II_WITH_MPI
55  Assert(false, ExcNeedsMPI());
56 #endif
57  }
58 
59 
60 
61  template <int dim, int spacedim>
62  void
64  const ::Triangulation<dim, spacedim> &other_tria)
65  {
66 #ifndef DEAL_II_WITH_MPI
67  (void)other_tria;
68  Assert(false, ExcNeedsMPI());
69 #else
71 
72  if (const ::parallel::TriangulationBase<dim, spacedim> *other_tria_x =
73  dynamic_cast<const ::parallel::TriangulationBase<dim, spacedim>
74  *>(&other_tria))
75  {
76  // release unused vector memory because we will have very different
77  // vectors now
80  }
81 #endif
82  }
83 
84 
85 
86  template <int dim, int spacedim>
87  std::size_t
89  {
90  std::size_t mem =
97  return mem;
98  }
99 
100  template <int dim, int spacedim>
102  {
103  // release unused vector memory because the vector layout is going to look
104  // very different now
107  }
108 
109  template <int dim, int spacedim>
112  , n_global_levels(0)
113  {}
114 
115  template <int dim, int spacedim>
116  unsigned int
118  {
120  }
121 
122  template <int dim, int spacedim>
123  unsigned int
125  {
127  }
128 
129  template <int dim, int spacedim>
132  {
134  }
135 
136  template <int dim, int spacedim>
137  const MPI_Comm &
139  {
140  return mpi_communicator;
141  }
142 
143 #ifdef DEAL_II_WITH_MPI
144  template <int dim, int spacedim>
145  void
147  {
148  number_cache.ghost_owners.clear();
151 
152  if (this->n_levels() == 0)
153  {
154  // Skip communication done below if we do not have any cells
155  // (meaning the Triangulation is empty on all processors). This will
156  // happen when called from the destructor of Triangulation, which
157  // can get called during exception handling causing a hang in this
158  // function.
161  return;
162  }
163 
164 
165  {
166  // find ghost owners
167  for (const auto &cell : this->active_cell_iterators())
168  if (cell->is_ghost())
169  number_cache.ghost_owners.insert(cell->subdomain_id());
170 
173  ExcInternalError());
174  }
175 
176  if (this->n_levels() > 0)
177  for (const auto &cell : this->active_cell_iterators())
178  if (cell->subdomain_id() == my_subdomain)
180 
181  // Potentially cast to a 64 bit type before accumulating to avoid overflow:
183  Utilities::MPI::sum(static_cast<types::global_cell_index>(
185  this->mpi_communicator);
186 
189 
190  // Store MPI ranks of level ghost owners of this processor on all levels.
191  if (this->is_multilevel_hierarchy_constructed() == true)
192  {
194 
195  // if there is nothing to do, then do nothing
196  if (this->n_levels() == 0)
197  return;
198 
199  // find level ghost owners
201  this->begin();
202  cell != this->end();
203  ++cell)
204  if (cell->level_subdomain_id() != numbers::artificial_subdomain_id &&
205  cell->level_subdomain_id() != this->locally_owned_subdomain())
206  this->number_cache.level_ghost_owners.insert(
207  cell->level_subdomain_id());
208 
209 # ifdef DEBUG
210  // Check that level_ghost_owners is symmetric by sending a message to
211  // everyone
212  {
213  int ierr = MPI_Barrier(this->mpi_communicator);
214  AssertThrowMPI(ierr);
215 
216  const int mpi_tag = Utilities::MPI::internal::Tags::
218 
219  // important: preallocate to avoid (re)allocation:
220  std::vector<MPI_Request> requests(
221  this->number_cache.level_ghost_owners.size());
222  unsigned int dummy = 0;
223  unsigned int req_counter = 0;
224 
225  for (std::set<types::subdomain_id>::iterator it =
226  this->number_cache.level_ghost_owners.begin();
227  it != this->number_cache.level_ghost_owners.end();
228  ++it, ++req_counter)
229  {
230  ierr = MPI_Isend(&dummy,
231  1,
232  MPI_UNSIGNED,
233  *it,
234  mpi_tag,
235  this->mpi_communicator,
236  &requests[req_counter]);
237  AssertThrowMPI(ierr);
238  }
239 
240  for (std::set<types::subdomain_id>::iterator it =
241  this->number_cache.level_ghost_owners.begin();
242  it != this->number_cache.level_ghost_owners.end();
243  ++it)
244  {
245  unsigned int dummy;
246  ierr = MPI_Recv(&dummy,
247  1,
248  MPI_UNSIGNED,
249  *it,
250  mpi_tag,
251  this->mpi_communicator,
252  MPI_STATUS_IGNORE);
253  AssertThrowMPI(ierr);
254  }
255 
256  if (requests.size() > 0)
257  {
258  ierr = MPI_Waitall(requests.size(),
259  requests.data(),
260  MPI_STATUSES_IGNORE);
261  AssertThrowMPI(ierr);
262  }
263 
264  ierr = MPI_Barrier(this->mpi_communicator);
265  AssertThrowMPI(ierr);
266  }
267 # endif
268 
269  Assert(this->number_cache.level_ghost_owners.size() <
271  ExcInternalError());
272  }
273  }
274 
275 #else
276 
277  template <int dim, int spacedim>
278  void
280  {
281  Assert(false, ExcNotImplemented());
282  }
283 
284 #endif
285 
286  template <int dim, int spacedim>
289  {
290  return my_subdomain;
291  }
292 
293 
294 
295  template <int dim, int spacedim>
296  const std::set<types::subdomain_id> &
298  {
299  return number_cache.ghost_owners;
300  }
301 
302 
303 
304  template <int dim, int spacedim>
305  const std::set<types::subdomain_id> &
307  {
309  }
310 
311 
312 
313  template <int dim, int spacedim>
314  std::map<unsigned int, std::set<::types::subdomain_id>>
316  const
317  {
319  }
320 
321 
322 
323  template <int dim, int spacedim>
324  std::vector<types::boundary_id>
326  {
329  this->mpi_communicator);
330  }
331 
332 
333 
334  template <int dim, int spacedim>
335  std::vector<types::manifold_id>
337  {
340  this->mpi_communicator);
341  }
342 
343 
344 
345  template <int dim, int spacedim>
347  MPI_Comm mpi_communicator,
348  const typename ::Triangulation<dim, spacedim>::MeshSmoothing
349  smooth_grid,
350  const bool check_for_distorted_cells)
351  : ::parallel::TriangulationBase<dim, spacedim>(
352  mpi_communicator,
353  smooth_grid,
354  check_for_distorted_cells)
355  {}
356 
357 } // end namespace parallel
358 
359 
360 
361 /*-------------- Explicit Instantiations -------------------------------*/
362 #include "tria_base.inst"
363 
virtual types::global_cell_index n_global_active_cells() const override
Definition: tria_base.cc:131
virtual void copy_triangulation(const Triangulation< dim, spacedim > &other_tria)
Definition: tria.cc:9534
const std::set< types::subdomain_id > & level_ghost_owners() const
Definition: tria_base.cc:306
static ::ExceptionBase & ExcNeedsMPI()
virtual std::vector< types::boundary_id > get_boundary_ids() const override
Definition: tria_base.cc:325
const std::set< types::subdomain_id > & ghost_owners() const
Definition: tria_base.cc:297
virtual void copy_triangulation(const ::Triangulation< dim, spacedim > &old_tria) override
Definition: tria_base.cc:63
IteratorRange< active_cell_iterator > active_cell_iterators() const
Definition: tria.cc:11286
virtual std::vector< types::manifold_id > get_manifold_ids() const override
Definition: tria_base.cc:336
TriangulationBase<dim, spacedim>::fill_level_ghost_owners()
Definition: mpi_tags.h:102
virtual ~TriangulationBase() override
Definition: tria_base.cc:101
cell_iterator begin(const unsigned int level=0) const
Definition: tria.cc:11094
unsigned int n_levels() const
cell_iterator end() const
Definition: tria.cc:11180
std::set< types::subdomain_id > ghost_owners
Definition: tria_base.h:278
virtual std::size_t memory_consumption() const override
Definition: tria_base.cc:88
virtual bool is_multilevel_hierarchy_constructed() const =0
const bool check_for_distorted_cells
Definition: tria.h:3873
T sum(const T &t, const MPI_Comm &mpi_communicator)
#define Assert(cond, exc)
Definition: exceptions.h:1411
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:363
std::vector< T > compute_set_union(const std::vector< T > &vec, const MPI_Comm &comm)
types::global_cell_index n_global_active_cells
Definition: tria_base.h:267
virtual std::size_t memory_consumption() const
Definition: tria.cc:14227
types::subdomain_id locally_owned_subdomain() const override
Definition: tria_base.cc:288
DistributedTriangulationBase(MPI_Comm mpi_communicator, const typename ::Triangulation< dim, spacedim >::MeshSmoothing smooth_grid=(::Triangulation< dim, spacedim >::none), const bool check_for_distorted_cells=false)
Definition: tria_base.cc:346
unsigned int n_mpi_processes(const MPI_Comm &mpi_communicator)
Definition: mpi.cc:117
virtual const MPI_Comm & get_communicator() const
Definition: tria_base.cc:138
TriangulationBase(MPI_Comm mpi_communicator, const typename ::Triangulation< dim, spacedim >::MeshSmoothing smooth_grid=(::Triangulation< dim, spacedim >::none), const bool check_for_distorted_cells=false)
Definition: tria_base.cc:43
std::set< types::subdomain_id > level_ghost_owners
Definition: tria_base.h:283
virtual std::map< unsigned int, std::set<::types::subdomain_id > > compute_vertices_with_ghost_neighbors() const
Definition: tria_base.cc:315
const types::subdomain_id artificial_subdomain_id
Definition: types.h:293
virtual void update_number_cache()
Definition: tria_base.cc:146
Definition: cuda.h:31
unsigned int n_locally_owned_active_cells() const
Definition: tria_base.cc:117
#define AssertThrowMPI(error_code)
Definition: exceptions.h:1692
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:362
virtual unsigned int n_global_levels() const override
Definition: tria_base.cc:124
MeshSmoothing smooth_grid
Definition: tria.h:3420
unsigned int this_mpi_process(const MPI_Comm &mpi_communicator)
Definition: mpi.cc:128
static ::ExceptionBase & ExcNotImplemented()
types::subdomain_id my_subdomain
Definition: tria_base.h:246
T max(const T &t, const MPI_Comm &mpi_communicator)
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
static ::ExceptionBase & ExcInternalError()
std::map< unsigned int, std::set<::types::subdomain_id > > compute_vertices_with_ghost_neighbors(const Triangulation< dim, spacedim > &tria)
Definition: grid_tools.cc:5540