17 #include <deal.II/base/logstream.h> 18 #include <deal.II/base/function.h> 20 #include <deal.II/lac/vector.h> 21 #include <deal.II/lac/block_vector.h> 22 #include <deal.II/lac/parallel_vector.h> 23 #include <deal.II/lac/parallel_block_vector.h> 24 #include <deal.II/lac/petsc_vector.h> 25 #include <deal.II/lac/petsc_block_vector.h> 26 #include <deal.II/lac/trilinos_vector.h> 27 #include <deal.II/lac/trilinos_block_vector.h> 28 #include <deal.II/grid/tria.h> 29 #include <deal.II/grid/tria_iterator.h> 30 #include <deal.II/dofs/dof_tools.h> 31 #include <deal.II/fe/fe.h> 32 #include <deal.II/dofs/dof_accessor.h> 33 #include <deal.II/multigrid/mg_tools.h> 34 #include <deal.II/multigrid/mg_transfer.h> 35 #include <deal.II/multigrid/mg_transfer.templates.h> 39 DEAL_II_NAMESPACE_OPEN
54 DoFPair(
const unsigned int level,
58 level(level), global_dof_index(global_dof_index), level_dof_index(level_dof_index)
70 template <
int dim,
int spacedim>
73 std::vector<std::vector<std::pair<types::global_dof_index, types::global_dof_index> > > ©_indices,
74 std::vector<std::vector<std::pair<types::global_dof_index, types::global_dof_index> > > ©_indices_global_mine,
75 std::vector<std::vector<std::pair<types::global_dof_index, types::global_dof_index> > > ©_indices_level_mine)
88 std::vector<DoFPair> send_data_temp;
91 copy_indices.resize(n_levels);
92 copy_indices_global_mine.resize(n_levels);
93 copy_indices_level_mine.resize(n_levels);
97 const unsigned int dofs_per_cell = mg_dof.
get_fe().dofs_per_cell;
98 std::vector<types::global_dof_index> global_dof_indices (dofs_per_cell);
99 std::vector<types::global_dof_index> level_dof_indices (dofs_per_cell);
101 for (
unsigned int level=0; level<n_levels; ++level)
103 std::vector<bool> dof_touched(globally_relevant.
n_elements(),
false);
104 copy_indices[level].clear();
105 copy_indices_level_mine[level].clear();
106 copy_indices_global_mine[level].clear();
113 for (; level_cell!=level_end; ++level_cell)
123 level_cell->get_dof_indices (global_dof_indices);
124 level_cell->get_mg_dof_indices (level_dof_indices);
126 for (
unsigned int i=0; i<dofs_per_cell; ++i)
129 if (mg_constrained_dofs != 0
134 if (dof_touched[global_idx])
140 if (global_mine && level_mine)
142 copy_indices[level].push_back(
143 std::make_pair (global_dof_indices[i], level_dof_indices[i]));
145 else if (global_mine)
147 copy_indices_global_mine[level].push_back(
148 std::make_pair (global_dof_indices[i], level_dof_indices[i]));
151 send_data_temp.push_back(DoFPair(level, global_dof_indices[i], level_dof_indices[i]));
158 dof_touched[global_idx] =
true;
163 const ::parallel::distributed::Triangulation<dim,spacedim> *tria =
166 AssertThrow(send_data_temp.size()==0 || tria!=NULL,
ExcMessage(
"parallel Multigrid only works with a distributed Triangulation!"));
168 #ifdef DEAL_II_WITH_MPI 175 std::set<unsigned int> neighbors = tria->level_ghost_owners();
176 std::map<int, std::vector<DoFPair> > send_data;
179 for (
typename std::vector<DoFPair>::iterator dofpair=send_data_temp.begin(); dofpair != send_data_temp.end(); ++dofpair)
181 std::set<unsigned int>::iterator it;
182 for (it = neighbors.begin(); it != neighbors.end(); ++it)
184 if (mg_dof.locally_owned_mg_dofs_per_processor(dofpair->level)[*it].is_element(dofpair->level_dof_index))
186 send_data[*it].push_back(*dofpair);
196 std::vector<MPI_Request> requests;
198 for (std::set<unsigned int>::iterator it = neighbors.begin(); it != neighbors.end(); ++it)
200 requests.push_back(MPI_Request());
201 unsigned int dest = *it;
202 std::vector<DoFPair> &data = send_data[dest];
207 MPI_Isend(&data[0], data.size()*
sizeof(data[0]), MPI_BYTE, dest, 71, tria->get_communicator(), &*requests.rbegin());
209 MPI_Isend(NULL, 0, MPI_BYTE, dest, 71, tria->get_communicator(), &*requests.rbegin());
216 std::vector<DoFPair> receive_buffer;
217 for (
unsigned int counter=0; counter<neighbors.size(); ++counter)
221 MPI_Probe(MPI_ANY_SOURCE, 71, tria->get_communicator(), &status);
222 MPI_Get_count(&status, MPI_BYTE, &len);
226 int err = MPI_Recv(NULL, 0, MPI_BYTE, status.MPI_SOURCE, status.MPI_TAG,
227 tria->get_communicator(), &status);
232 int count = len /
sizeof(DoFPair);
233 Assert(static_cast<int>(count *
sizeof(DoFPair)) == len, ExcInternalError());
234 receive_buffer.resize(count);
236 void *ptr = &receive_buffer[0];
237 int err = MPI_Recv(ptr, len, MPI_BYTE, status.MPI_SOURCE, status.MPI_TAG,
238 tria->get_communicator(), &status);
241 for (
unsigned int i=0; i<receive_buffer.size(); ++i)
243 copy_indices_level_mine[receive_buffer[i].level].push_back(
244 std::make_pair (receive_buffer[i].global_dof_index, receive_buffer[i].level_dof_index)
251 if (requests.size() > 0)
253 MPI_Waitall(requests.size(), &requests[0], MPI_STATUSES_IGNORE);
260 MPI_Barrier(tria->get_communicator());
267 std::less<std::pair<types::global_dof_index, types::global_dof_index> > compare;
268 for (
unsigned int level=0; level<copy_indices.size(); ++level)
269 std::sort(copy_indices[level].begin(), copy_indices[level].end(), compare);
270 for (
unsigned int level=0; level<copy_indices_level_mine.size(); ++level)
271 std::sort(copy_indices_level_mine[level].begin(), copy_indices_level_mine[level].end(), compare);
272 for (
unsigned int level=0; level<copy_indices_global_mine.size(); ++level)
273 std::sort(copy_indices_global_mine[level].begin(), copy_indices_global_mine[level].end(), compare);
282 template <
typename VectorType>
283 template <
int dim,
int spacedim>
288 fill_copy_indices(mg_dof, mg_constrained_dofs, copy_indices,
289 copy_indices_global_mine, copy_indices_level_mine);
298 if (perform_plain_copy)
306 for (
unsigned int i=0; i<copy_indices.back().size(); ++i)
307 if (copy_indices.back()[i].first != copy_indices.back()[i].second)
309 perform_plain_copy =
false;
326 template <
typename VectorType>
331 copy_indices.clear();
332 copy_indices_global_mine.clear();
333 copy_indices_level_mine.clear();
334 component_to_block_map.resize(0);
335 mg_constrained_dofs = 0;
340 template <
typename VectorType>
344 for (
unsigned int level = 0; level<copy_indices.size(); ++level)
346 for (
unsigned int i=0; i<copy_indices[level].size(); ++i)
347 os <<
"copy_indices[" << level
348 <<
"]\t" << copy_indices[level][i].first <<
'\t' << copy_indices[level][i].second << std::endl;
351 for (
unsigned int level = 0; level<copy_indices_level_mine.size(); ++level)
353 for (
unsigned int i=0; i<copy_indices_level_mine[level].size(); ++i)
354 os <<
"copy_ifrom [" << level
355 <<
"]\t" << copy_indices_level_mine[level][i].first <<
'\t' << copy_indices_level_mine[level][i].second << std::endl;
357 for (
unsigned int level = 0; level<copy_indices_global_mine.size(); ++level)
359 for (
unsigned int i=0; i<copy_indices_global_mine[level].size(); ++i)
360 os <<
"copy_ito [" << level
361 <<
"]\t" << copy_indices_global_mine[level][i].first <<
'\t' << copy_indices_global_mine[level][i].second << std::endl;
367 template <
typename VectorType>
371 std::size_t result =
sizeof(*this);
385 template <
typename Number>
386 template <
int dim,
int spacedim>
392 std::vector<std::vector<std::pair<types::global_dof_index, types::global_dof_index> > >
394 std::vector<std::vector<std::pair<types::global_dof_index, types::global_dof_index> > >
395 copy_indices_global_mine;
396 std::vector<std::vector<std::pair<types::global_dof_index, types::global_dof_index> > >
397 copy_indices_level_mine;
399 fill_copy_indices(mg_dof, mg_constrained_dofs, copy_indices,
400 copy_indices_global_mine, copy_indices_level_mine);
417 std::vector<types::global_dof_index> accessed_indices;
419 std::vector<IndexSet> level_index_set(mg_dof.
get_triangulation().n_global_levels());
422 for (
unsigned int i=0; i<copy_indices_level_mine[l].size(); ++i)
423 accessed_indices.push_back(copy_indices_level_mine[l][i].first);
424 std::vector<types::global_dof_index> accessed_level_indices;
425 for (
unsigned int i=0; i<copy_indices_global_mine[l].size(); ++i)
426 accessed_level_indices.push_back(copy_indices_global_mine[l][i].second);
427 std::sort(accessed_level_indices.begin(), accessed_level_indices.end());
429 level_index_set[l].add_indices(accessed_level_indices.begin(),
430 accessed_level_indices.end());
431 level_index_set[l].compress();
436 std::sort(accessed_indices.begin(), accessed_indices.end());
437 index_set.add_indices(accessed_indices.begin(), accessed_indices.end());
438 index_set.compress();
447 this->copy_indices_level_mine.resize(mg_dof.
get_triangulation().n_global_levels());
448 this->copy_indices_global_mine.resize(mg_dof.
get_triangulation().n_global_levels());
449 for (
unsigned int level=0; level<mg_dof.
get_triangulation().n_global_levels(); ++level)
452 *ghosted_global_vector.get_partitioner();
454 *ghosted_level_vector[level].get_partitioner();
457 this->copy_indices[level].resize(copy_indices[level].size());
458 for (
unsigned int i=0; i<copy_indices[level].size(); ++i)
459 this->copy_indices[level][i] =
460 std::pair<unsigned int,unsigned int>
466 this->copy_indices_level_mine[level].
467 resize(copy_indices_level_mine[level].size());
468 for (
unsigned int i=0; i<copy_indices_level_mine[level].size(); ++i)
469 this->copy_indices_level_mine[level][i] =
470 std::pair<unsigned int,unsigned int>
471 (global_partitioner.
global_to_local(copy_indices_level_mine[level][i].first),
472 level_partitioner.
global_to_local(copy_indices_level_mine[level][i].second));
476 this->copy_indices_global_mine[level].
477 resize(copy_indices_global_mine[level].size());
478 for (
unsigned int i=0; i<copy_indices_global_mine[level].size(); ++i)
479 this->copy_indices_global_mine[level][i] =
480 std::pair<unsigned int,unsigned int>
481 (global_partitioner.
global_to_local(copy_indices_global_mine[level][i].first),
482 level_partitioner.
global_to_local(copy_indices_global_mine[level][i].second));
485 perform_plain_copy = this->copy_indices.back().size()
487 if (perform_plain_copy)
495 for (
unsigned int i=0; i<this->copy_indices.back().size(); ++i)
496 if (this->copy_indices.back()[i].first !=
497 this->copy_indices.back()[i].second)
499 perform_plain_copy =
false;
508 if (perform_plain_copy)
510 ghosted_global_vector.reinit(0);
511 ghosted_level_vector.resize(0, 0);
517 template <
typename Number>
522 copy_indices.
clear();
523 copy_indices_global_mine.clear();
524 copy_indices_level_mine.clear();
525 component_to_block_map.resize(0);
526 mg_constrained_dofs = 0;
527 ghosted_global_vector.reinit(0);
528 ghosted_level_vector.resize(0, 0);
533 template <
typename Number>
537 for (
unsigned int level = 0; level<copy_indices.size(); ++level)
539 for (
unsigned int i=0; i<copy_indices[level].size(); ++i)
540 os <<
"copy_indices[" << level
541 <<
"]\t" << copy_indices[level][i].first <<
'\t' << copy_indices[level][i].second << std::endl;
544 for (
unsigned int level = 0; level<copy_indices_level_mine.size(); ++level)
546 for (
unsigned int i=0; i<copy_indices_level_mine[level].size(); ++i)
547 os <<
"copy_ifrom [" << level
548 <<
"]\t" << copy_indices_level_mine[level][i].first <<
'\t' << copy_indices_level_mine[level][i].second << std::endl;
550 for (
unsigned int level = 0; level<copy_indices_global_mine.size(); ++level)
552 for (
unsigned int i=0; i<copy_indices_global_mine[level].size(); ++i)
553 os <<
"copy_ito [" << level
554 <<
"]\t" << copy_indices_global_mine[level][i].first <<
'\t' << copy_indices_global_mine[level][i].second << std::endl;
560 template <
typename Number>
564 std::size_t result =
sizeof(*this);
569 result += ghosted_global_vector.memory_consumption();
570 for (
unsigned int i=ghosted_level_vector.min_level();
571 i<=ghosted_level_vector.max_level(); ++i)
572 result += ghosted_level_vector[i].memory_consumption();
580 #include "mg_level_global_transfer.inst" 588 DEAL_II_NAMESPACE_CLOSE
#define AssertDimension(dim1, dim2)
const types::subdomain_id invalid_subdomain_id
std::size_t memory_consumption() const
::ExceptionBase & ExcMessage(std::string arg1)
ActiveSelector::active_cell_iterator active_cell_iterator
#define AssertThrow(cond, exc)
unsigned int global_to_local(const types::global_dof_index global_index) const
const FiniteElement< dim, spacedim > & get_fe() const
void print_indices(std::ostream &os) const
active_cell_iterator begin_active(const unsigned int level=0) const
unsigned int global_dof_index
void fill_and_communicate_copy_indices(const DoFHandler< dim, spacedim > &mg_dof)
#define Assert(cond, exc)
size_type index_within_set(const size_type global_index) const
active_cell_iterator end_active(const unsigned int level) const
virtual MPI_Comm get_communicator() const
const IndexSet & locally_owned_mg_dofs(const unsigned int level) const
const types::subdomain_id artificial_subdomain_id
std_cxx11::enable_if< std_cxx11::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
bool at_refinement_edge(const unsigned int level, const types::global_dof_index index) const
const Triangulation< dim, spacedim > & get_tria() const DEAL_II_DEPRECATED
T min(const T &t, const MPI_Comm &mpi_communicator)
const Triangulation< dim, spacedim > & get_triangulation() const
bool is_element(const size_type index) const
const IndexSet & locally_owned_dofs() const
size_type n_elements() const