19#include <deal.II/base/mpi.templates.h>
47 template <
int dim,
int spacedim>
50 const typename ::Triangulation<dim, spacedim>::MeshSmoothing
52 const bool check_for_distorted_cells)
54 check_for_distorted_cells)
55 , mpi_communicator(mpi_communicator)
56 , my_subdomain(
Utilities::MPI::this_mpi_process(this->mpi_communicator))
57 , n_subdomains(
Utilities::MPI::n_mpi_processes(this->mpi_communicator))
59#ifndef DEAL_II_WITH_MPI
66 template <
int dim,
int spacedim>
69 const ::Triangulation<dim, spacedim> &other_tria)
71#ifndef DEAL_II_WITH_MPI
77 if (const ::parallel::TriangulationBase<dim, spacedim> *other_tria_x =
78 dynamic_cast<const ::parallel::TriangulationBase<dim, spacedim>
91 template <
int dim,
int spacedim>
100 number_cache.n_global_active_cells) +
105 template <
int dim,
int spacedim>
114 template <
int dim,
int spacedim>
116 : n_locally_owned_active_cells(0)
117 , number_of_global_coarse_cells(0)
121 template <
int dim,
int spacedim>
125 return number_cache.n_locally_owned_active_cells;
128 template <
int dim,
int spacedim>
132 return number_cache.n_global_levels;
135 template <
int dim,
int spacedim>
139 return number_cache.n_global_active_cells;
142 template <
int dim,
int spacedim>
146 return mpi_communicator;
149#ifdef DEAL_II_WITH_MPI
150 template <
int dim,
int spacedim>
154 number_cache.ghost_owners.clear();
155 number_cache.level_ghost_owners.clear();
156 number_cache.n_locally_owned_active_cells = 0;
158 if (this->n_levels() == 0)
165 number_cache.n_global_active_cells = 0;
166 number_cache.n_global_levels = 0;
173 for (
const auto &cell : this->active_cell_iterators())
174 if (cell->is_ghost())
175 number_cache.ghost_owners.insert(cell->subdomain_id());
177 Assert(number_cache.ghost_owners.size() <
182 if (this->n_levels() > 0)
183 number_cache.n_locally_owned_active_cells = std::count_if(
184 this->begin_active(),
187 [](
const auto &i) {
return i.is_locally_owned(); });
189 number_cache.n_locally_owned_active_cells = 0;
193 number_cache.n_global_active_cells =
195 number_cache.n_locally_owned_active_cells),
196 this->mpi_communicator);
198 number_cache.n_global_levels =
203 if (this->is_multilevel_hierarchy_constructed() ==
true)
205 number_cache.level_ghost_owners.clear();
208 if (this->n_levels() == 0)
212 for (
const auto &cell : this->cell_iterators())
214 cell->level_subdomain_id() != this->locally_owned_subdomain())
215 this->number_cache.level_ghost_owners.insert(
216 cell->level_subdomain_id());
222 int ierr = MPI_Barrier(this->mpi_communicator);
229 std::vector<MPI_Request> requests(
230 this->number_cache.level_ghost_owners.size());
231 unsigned int dummy = 0;
232 unsigned int req_counter = 0;
234 for (
const auto &it : this->number_cache.level_ghost_owners)
236 ierr = MPI_Isend(&dummy,
241 this->mpi_communicator,
242 &requests[req_counter]);
247 for (
const auto &it : this->number_cache.level_ghost_owners)
250 ierr = MPI_Recv(&dummy,
255 this->mpi_communicator,
260 if (requests.size() > 0)
262 ierr = MPI_Waitall(requests.size(),
264 MPI_STATUSES_IGNORE);
268 ierr = MPI_Barrier(this->mpi_communicator);
273 Assert(this->number_cache.level_ghost_owners.size() <
278 this->number_cache.number_of_global_coarse_cells = this->
n_cells(0);
281 this->reset_global_cell_indices();
286 template <
int dim,
int spacedim>
295 template <
int dim,
int spacedim>
304 std::vector<unsigned int> reference_cells_ui;
306 for (
const auto &i : this->reference_cells)
307 reference_cells_ui.push_back(
static_cast<unsigned int>(i));
312 this->mpi_communicator);
315 this->reference_cells.clear();
316 for (
const auto &i : reference_cells_ui)
317 this->reference_cells.emplace_back(
323 template <
int dim,
int spacedim>
332 template <
int dim,
int spacedim>
333 const std::set<types::subdomain_id> &
336 return number_cache.ghost_owners;
341 template <
int dim,
int spacedim>
342 const std::set<types::subdomain_id> &
345 return number_cache.level_ghost_owners;
350 template <
int dim,
int spacedim>
351 std::vector<types::boundary_id>
356 this->mpi_communicator);
361 template <
int dim,
int spacedim>
362 std::vector<types::manifold_id>
367 this->mpi_communicator);
372 template <
int dim,
int spacedim>
376#ifndef DEAL_II_WITH_MPI
382 if (pst->with_artificial_cells() ==
false)
388 std::vector<unsigned int> cell_counter(n_subdomains + 1);
391 for (
const auto &cell : this->active_cell_iterators())
392 cell_counter[cell->subdomain_id() + 1]++;
395 for (
unsigned int i = 0; i < n_subdomains; ++i)
396 cell_counter[i + 1] += cell_counter[i];
401 IndexSet is_local(this->n_active_cells());
402 is_local.add_range(cell_counter[my_subdomain],
403 cell_counter[my_subdomain + 1]);
404 number_cache.active_cell_index_partitioner =
405 std::make_shared<const Utilities::MPI::Partitioner>(
408 this->mpi_communicator);
411 for (
const auto &cell : this->active_cell_iterators())
412 cell->set_global_active_cell_index(
413 cell_counter[cell->subdomain_id()]++);
415 Assert(this->is_multilevel_hierarchy_constructed() ==
false,
423 this->n_locally_owned_active_cells();
428 const int ierr = MPI_Exscan(
429 &n_locally_owned_cells,
434 this->mpi_communicator);
439 std::pair<types::global_cell_index, types::global_cell_index> my_range;
442 for (
const auto &cell : this->active_cell_iterators())
443 if (cell->is_locally_owned())
444 cell->set_global_active_cell_index(
cell_index++);
451 std::vector<types::global_dof_index> is_ghost_vector;
452 GridTools::exchange_cell_data_to_ghosts<types::global_cell_index>(
454 [](
const auto &cell) {
return cell->global_active_cell_index(); },
455 [&is_ghost_vector](
const auto &cell,
const auto &id) {
456 cell->set_global_active_cell_index(
id);
457 is_ghost_vector.push_back(
id);
461 IndexSet is_local(this->n_global_active_cells());
462 is_local.add_range(my_range.first, my_range.second);
464 std::sort(is_ghost_vector.begin(), is_ghost_vector.end());
465 IndexSet is_ghost(this->n_global_active_cells());
466 is_ghost.add_indices(is_ghost_vector.begin(), is_ghost_vector.end());
468 number_cache.active_cell_index_partitioner =
469 std::make_shared<const Utilities::MPI::Partitioner>(
470 is_local, is_ghost, this->mpi_communicator);
473 if (this->is_multilevel_hierarchy_constructed() ==
true)
476 std::vector<types::global_cell_index> n_cells_level(
477 this->n_global_levels(), 0);
479 for (
auto cell : this->cell_iterators())
480 if (cell->level_subdomain_id() == this->locally_owned_subdomain())
481 n_cells_level[cell->level()]++;
485 this->n_global_levels(), 0);
487 int ierr = MPI_Exscan(
488 n_cells_level.data(),
490 this->n_global_levels(),
493 this->mpi_communicator);
498 this->mpi_communicator,
504 std::pair<types::global_cell_index, types::global_cell_index>>
505 my_ranges(this->n_global_levels());
506 for (
unsigned int l = 0; l < this->n_global_levels(); ++l)
509 for (
auto cell : this->cell_iterators())
510 if (cell->level_subdomain_id() == this->locally_owned_subdomain())
511 cell->set_global_level_cell_index(
cell_index[cell->level()]++);
515 for (
unsigned int l = 0; l < this->n_global_levels(); ++l)
519 std::vector<std::vector<types::global_dof_index>> is_ghost_vectors(
520 this->n_global_levels());
525 [](
const auto &cell) {
return cell->global_level_cell_index(); },
526 [&is_ghost_vectors](
const auto &cell,
const auto &id) {
527 cell->set_global_level_cell_index(
id);
528 is_ghost_vectors[cell->level()].push_back(
id);
531 number_cache.level_cell_index_partitioners.resize(
532 this->n_global_levels());
535 for (
unsigned int l = 0; l < this->n_global_levels(); ++l)
537 IndexSet is_local(n_cells_level[l]);
538 is_local.add_range(my_ranges[l].
first, my_ranges[l].
second);
540 IndexSet is_ghost(n_cells_level[l]);
541 std::sort(is_ghost_vectors[l].begin(), is_ghost_vectors[l].end());
542 is_ghost.add_indices(is_ghost_vectors[l].begin(),
543 is_ghost_vectors[l].end());
545 number_cache.level_cell_index_partitioners[l] =
546 std::make_shared<const Utilities::MPI::Partitioner>(
547 is_local, is_ghost, this->mpi_communicator);
556 template <
int dim,
int spacedim>
559 const std::vector<bool> &vertex_locally_moved)
564 const std::vector<bool> locally_owned_vertices =
566 for (
unsigned int i = 0; i < locally_owned_vertices.size(); ++i)
567 Assert((vertex_locally_moved[i] ==
false) ||
568 (locally_owned_vertices[i] ==
true),
569 ExcMessage(
"The vertex_locally_moved argument must not "
570 "contain vertices that are not locally owned"));
575 for (
unsigned int d = 0; d < spacedim; ++d)
576 invalid_point[d] = std::numeric_limits<double>::quiet_NaN();
578 const auto pack = [&](
const auto &cell) {
579 std::vector<Point<spacedim>>
vertices(cell->n_vertices());
581 for (
const auto v : cell->vertex_indices())
582 if (vertex_locally_moved[cell->vertex_index(v)])
590 const auto unpack = [&](
const auto &cell,
const auto &
vertices) {
591 for (
const auto v : cell->vertex_indices())
592 if (std::isnan(
vertices[v][0]) ==
false)
596 if (this->is_multilevel_hierarchy_constructed())
600 GridTools::exchange_cell_data_to_ghosts<std::vector<Point<spacedim>>>(
601 *
this, pack, unpack);
606 template <
int dim,
int spacedim>
607 const std::weak_ptr<const Utilities::MPI::Partitioner>
610 return number_cache.active_cell_index_partitioner;
615 template <
int dim,
int spacedim>
616 const std::weak_ptr<const Utilities::MPI::Partitioner>
618 const unsigned int level)
const
623 return number_cache.level_cell_index_partitioners[
level];
628 template <
int dim,
int spacedim>
632 return number_cache.number_of_global_coarse_cells;
637 template <
int dim,
int spacedim>
640 const typename ::Triangulation<dim, spacedim>::MeshSmoothing
642 const bool check_for_distorted_cells)
646 check_for_distorted_cells)
647 , cell_attached_data({0, 0, {}, {}})
648 , data_transfer(mpi_communicator)
653 template <
int dim,
int spacedim>
657 cell_attached_data = {0, 0, {}, {}};
658 data_transfer.clear();
665 template <
int dim,
int spacedim>
668 const unsigned int global_first_cell,
669 const unsigned int global_num_cells,
670 const std::string &filename)
const
673 auto tria =
const_cast<
676 if (this->cell_attached_data.n_attached_data_sets > 0)
679 tria->data_transfer.pack_data(
680 tria->local_cell_relations,
681 tria->cell_attached_data.pack_callbacks_fixed,
682 tria->cell_attached_data.pack_callbacks_variable);
685 tria->data_transfer.
save(global_first_cell, global_num_cells, filename);
694 tria->cell_attached_data.n_attached_data_sets = 0;
695 tria->cell_attached_data.pack_callbacks_fixed.
clear();
696 tria->cell_attached_data.pack_callbacks_variable.
clear();
702 template <
int dim,
int spacedim>
706 if (this->n_global_levels() <= 1)
715 const bool have_coarser_cell =
716 std::any_of(this->begin_active(this->n_global_levels() - 2),
717 this->end_active(this->n_global_levels() - 2),
724 this->mpi_communicator) != 0;
729 template <
int dim,
int spacedim>
732 const unsigned int global_first_cell,
733 const unsigned int global_num_cells,
734 const unsigned int local_num_cells,
735 const std::string &filename,
736 const unsigned int n_attached_deserialize_fixed,
737 const unsigned int n_attached_deserialize_variable)
740 if (this->cell_attached_data.n_attached_deserialize > 0)
742 this->data_transfer.load(global_first_cell,
746 n_attached_deserialize_fixed,
747 n_attached_deserialize_variable);
749 this->data_transfer.unpack_cell_status(this->local_cell_relations);
752 for (
const auto &cell_rel : this->local_cell_relations)
758 spacedim>::CELL_PERSIST),
766 template <
int dim,
int spacedim>
771 const bool returns_variable_size_data)
777 if (returns_variable_size_data)
779 handle = 2 * cell_attached_data.pack_callbacks_variable.size();
780 cell_attached_data.pack_callbacks_variable.push_back(pack_callback);
784 handle = 2 * cell_attached_data.pack_callbacks_fixed.size() + 1;
785 cell_attached_data.pack_callbacks_fixed.push_back(pack_callback);
789 ++cell_attached_data.n_attached_data_sets;
796 template <
int dim,
int spacedim>
799 const unsigned int handle,
803 const boost::iterator_range<std::vector<char>::const_iterator> &)>
807 data_transfer.unpack_data(local_cell_relations, handle, unpack_callback);
810 --cell_attached_data.n_attached_data_sets;
811 if (cell_attached_data.n_attached_deserialize > 0)
812 --cell_attached_data.n_attached_deserialize;
821 if (cell_attached_data.n_attached_data_sets == 0 &&
822 cell_attached_data.n_attached_deserialize == 0)
825 cell_attached_data.pack_callbacks_fixed.clear();
826 cell_attached_data.pack_callbacks_variable.clear();
827 data_transfer.clear();
830 for (
auto &cell_rel : local_cell_relations)
841 template <
int dim,
int spacedim>
844 : variable_size_data_stored(false)
845 , mpi_communicator(mpi_communicator)
850 template <
int dim,
int spacedim>
853 const std::vector<cell_relation_t> &cell_relations,
854 const std::vector<typename CellAttachedData::pack_callback_t>
855 &pack_callbacks_fixed,
856 const std::vector<typename CellAttachedData::pack_callback_t>
857 &pack_callbacks_variable)
859 Assert(src_data_fixed.size() == 0,
860 ExcMessage(
"Previously packed data has not been released yet!"));
863 const unsigned int n_callbacks_fixed = pack_callbacks_fixed.size();
864 const unsigned int n_callbacks_variable = pack_callbacks_variable.size();
868 variable_size_data_stored = (n_callbacks_variable > 0);
874 std::vector<unsigned int> cell_sizes_variable_cumulative(
875 n_callbacks_variable);
889 std::vector<std::vector<std::vector<char>>> packed_fixed_size_data(
890 cell_relations.size());
891 std::vector<std::vector<std::vector<char>>> packed_variable_size_data(
892 variable_size_data_stored ? cell_relations.size() : 0);
900 auto cell_rel_it = cell_relations.cbegin();
901 auto data_cell_fixed_it = packed_fixed_size_data.begin();
902 auto data_cell_variable_it = packed_variable_size_data.begin();
903 for (; cell_rel_it != cell_relations.cend(); ++cell_rel_it)
905 const auto &dealii_cell = cell_rel_it->first;
906 const auto &cell_status = cell_rel_it->second;
927 for (
unsigned int c = 0;
928 c < GeometryInfo<dim>::max_children_per_cell;
930 Assert(dealii_cell->child(c)->is_active(),
952 const unsigned int n_fixed_size_data_sets_on_cell =
958 ((variable_size_data_stored ? 1 : 0) + n_callbacks_fixed));
959 data_cell_fixed_it->resize(n_fixed_size_data_sets_on_cell);
962 auto data_fixed_it = data_cell_fixed_it->begin();
978 for (
auto callback_it = pack_callbacks_fixed.cbegin();
979 callback_it != pack_callbacks_fixed.cend();
980 ++callback_it, ++data_fixed_it)
982 *data_fixed_it = (*callback_it)(dealii_cell, cell_status);
989 if (variable_size_data_stored)
991 const unsigned int n_variable_size_data_sets_on_cell =
996 n_callbacks_variable);
997 data_cell_variable_it->resize(
998 n_variable_size_data_sets_on_cell);
1000 auto callback_it = pack_callbacks_variable.cbegin();
1001 auto data_variable_it = data_cell_variable_it->begin();
1002 auto sizes_variable_it =
1003 cell_sizes_variable_cumulative.begin();
1004 for (; callback_it != pack_callbacks_variable.cend();
1005 ++callback_it, ++data_variable_it, ++sizes_variable_it)
1008 (*callback_it)(dealii_cell, cell_status);
1012 *sizes_variable_it = data_variable_it->size();
1016 std::partial_sum(cell_sizes_variable_cumulative.begin(),
1017 cell_sizes_variable_cumulative.end(),
1018 cell_sizes_variable_cumulative.begin());
1025 data_fixed_it->resize(n_callbacks_variable *
1026 sizeof(
unsigned int));
1027 for (
unsigned int i = 0; i < n_callbacks_variable; ++i)
1028 std::memcpy(&(data_fixed_it->at(i *
sizeof(
unsigned int))),
1029 &(cell_sizes_variable_cumulative.at(i)),
1030 sizeof(
unsigned int));
1037 Assert(data_fixed_it == data_cell_fixed_it->end(),
1041 ++data_cell_fixed_it;
1046 if (variable_size_data_stored)
1047 ++data_cell_variable_it;
1064 std::vector<unsigned int> local_sizes_fixed(
1065 1 + n_callbacks_fixed + (variable_size_data_stored ? 1 : 0));
1066 for (
const auto &data_cell : packed_fixed_size_data)
1068 if (data_cell.size() == local_sizes_fixed.size())
1070 auto sizes_fixed_it = local_sizes_fixed.begin();
1071 auto data_fixed_it = data_cell.cbegin();
1072 for (; data_fixed_it != data_cell.cend();
1073 ++data_fixed_it, ++sizes_fixed_it)
1075 *sizes_fixed_it = data_fixed_it->size();
1083 for (
auto data_cell_fixed_it = packed_fixed_size_data.cbegin();
1084 data_cell_fixed_it != packed_fixed_size_data.cend();
1085 ++data_cell_fixed_it)
1087 Assert((data_cell_fixed_it->size() == 1) ||
1088 (data_cell_fixed_it->size() == local_sizes_fixed.size()),
1095 std::vector<unsigned int> global_sizes_fixed(local_sizes_fixed.size());
1098 global_sizes_fixed);
1102 sizes_fixed_cumulative.resize(global_sizes_fixed.size());
1103 std::partial_sum(global_sizes_fixed.begin(),
1104 global_sizes_fixed.end(),
1105 sizes_fixed_cumulative.begin());
1110 if (variable_size_data_stored)
1112 src_sizes_variable.reserve(packed_variable_size_data.size());
1113 for (
const auto &data_cell : packed_variable_size_data)
1115 int variable_data_size_on_cell = 0;
1117 for (
const auto &data : data_cell)
1118 variable_data_size_on_cell += data.size();
1120 src_sizes_variable.push_back(variable_data_size_on_cell);
1127 const unsigned int expected_size_fixed =
1128 cell_relations.size() * sizes_fixed_cumulative.back();
1129 const unsigned int expected_size_variable =
1130 std::accumulate(src_sizes_variable.begin(),
1131 src_sizes_variable.end(),
1132 std::vector<int>::size_type(0));
1136 src_data_fixed.reserve(expected_size_fixed);
1137 for (
const auto &data_cell_fixed : packed_fixed_size_data)
1141 for (
const auto &data_fixed : data_cell_fixed)
1142 std::move(data_fixed.begin(),
1144 std::back_inserter(src_data_fixed));
1150 if ((data_cell_fixed.size() == 1) &&
1151 (sizes_fixed_cumulative.size() > 1))
1153 const std::size_t bytes_skipped =
1154 sizes_fixed_cumulative.back() - sizes_fixed_cumulative.front();
1156 src_data_fixed.insert(src_data_fixed.end(),
1158 static_cast<char>(-1));
1164 if (variable_size_data_stored)
1166 src_data_variable.reserve(expected_size_variable);
1167 for (
const auto &data_cell : packed_variable_size_data)
1171 for (
const auto &data : data_cell)
1172 std::move(data.begin(),
1174 std::back_inserter(src_data_variable));
1180 Assert(src_data_variable.size() == expected_size_variable,
1186 template <
int dim,
int spacedim>
1189 std::vector<cell_relation_t> &cell_relations)
const
1191 Assert(sizes_fixed_cumulative.size() > 0,
1193 if (cell_relations.size() > 0)
1195 Assert(dest_data_fixed.size() > 0,
1200 const unsigned int size = sizes_fixed_cumulative.front();
1206 auto cell_rel_it = cell_relations.begin();
1207 auto dest_fixed_it = dest_data_fixed.cbegin();
1208 for (; cell_rel_it != cell_relations.end();
1209 ++cell_rel_it, dest_fixed_it += sizes_fixed_cumulative.back())
1211 cell_rel_it->second =
1215 dest_fixed_it + size,
1222 template <
int dim,
int spacedim>
1225 const std::vector<cell_relation_t> &cell_relations,
1226 const unsigned int handle,
1227 const std::function<
1228 void(
const typename ::Triangulation<dim, spacedim>::cell_iterator &,
1229 const typename ::Triangulation<dim, spacedim>::CellStatus &,
1230 const boost::iterator_range<std::vector<char>::const_iterator> &)>
1231 &unpack_callback)
const
1237 const bool callback_variable_transfer = (handle % 2 == 0);
1238 const unsigned int callback_index = handle / 2;
1244 Assert(sizes_fixed_cumulative.size() > 0,
1246 if (cell_relations.size() > 0)
1248 Assert(dest_data_fixed.size() > 0,
1252 std::vector<char>::const_iterator dest_data_it;
1253 std::vector<char>::const_iterator dest_sizes_cell_it;
1263 if (callback_variable_transfer)
1276 const unsigned int offset_variable_data_sizes =
1277 sizes_fixed_cumulative[sizes_fixed_cumulative.size() - 2];
1284 dest_sizes_cell_it = dest_data_fixed.cbegin() +
1285 offset_variable_data_sizes +
1286 callback_index *
sizeof(
unsigned int);
1289 dest_data_it = dest_data_variable.cbegin();
1296 offset = sizes_fixed_cumulative[callback_index];
1297 size = sizes_fixed_cumulative[callback_index + 1] - offset;
1298 data_increment = sizes_fixed_cumulative.back();
1304 if (cell_relations.begin() != cell_relations.end())
1305 dest_data_it = dest_data_fixed.cbegin() + offset;
1309 auto cell_rel_it = cell_relations.begin();
1310 auto dest_sizes_it = dest_sizes_variable.cbegin();
1311 for (; cell_rel_it != cell_relations.end(); ++cell_rel_it)
1313 const auto &dealii_cell = cell_rel_it->first;
1314 const auto &cell_status = cell_rel_it->second;
1316 if (callback_variable_transfer)
1320 data_increment = *dest_sizes_it;
1329 if (callback_index == 0)
1332 std::memcpy(&offset,
1333 &(*(dest_sizes_cell_it -
sizeof(
unsigned int))),
1334 sizeof(
unsigned int));
1337 &(*dest_sizes_cell_it),
1338 sizeof(
unsigned int));
1345 dest_data_it += offset;
1346 data_increment -= offset;
1351 if (cell_rel_it != cell_relations.end() - 1)
1352 dest_sizes_cell_it += sizes_fixed_cumulative.back();
1356 switch (cell_status)
1362 unpack_callback(dealii_cell,
1364 boost::make_iterator_range(dest_data_it,
1365 dest_data_it + size));
1370 unpack_callback(dealii_cell->parent(),
1372 boost::make_iterator_range(dest_data_it,
1373 dest_data_it + size));
1386 if (cell_rel_it != cell_relations.end() - 1)
1387 dest_data_it += data_increment;
1393 template <
int dim,
int spacedim>
1396 const unsigned int global_first_cell,
1397 const unsigned int global_num_cells,
1398 const std::string &filename)
const
1400#ifdef DEAL_II_WITH_MPI
1405 Assert(sizes_fixed_cumulative.size() > 0,
1410 const unsigned int bytes_per_cell = sizes_fixed_cumulative.back();
1416 const std::string fname_fixed = std::string(filename) +
"_fixed.data";
1419 int ierr = MPI_Info_create(&info);
1424 fname_fixed.c_str(),
1425 MPI_MODE_CREATE | MPI_MODE_WRONLY,
1430 ierr = MPI_File_set_size(fh, 0);
1436 ierr = MPI_Info_free(&info);
1449 sizes_fixed_cumulative.data(),
1450 sizes_fixed_cumulative.size(),
1457 const MPI_Offset size_header =
1458 sizes_fixed_cumulative.size() *
sizeof(
unsigned int);
1462 const MPI_Offset my_global_file_position =
1464 static_cast<MPI_Offset
>(global_first_cell) * bytes_per_cell;
1468 my_global_file_position,
1469 src_data_fixed.data(),
1470 src_data_fixed.size(),
1475 ierr = MPI_File_close(&fh);
1484 if (variable_size_data_stored)
1486 const std::string fname_variable =
1487 std::string(filename) +
"_variable.data";
1490 int ierr = MPI_Info_create(&info);
1495 fname_variable.c_str(),
1496 MPI_MODE_CREATE | MPI_MODE_WRONLY,
1501 ierr = MPI_File_set_size(fh, 0);
1507 ierr = MPI_Info_free(&info);
1512 const MPI_Offset my_global_file_position =
1513 static_cast<MPI_Offset
>(global_first_cell) *
sizeof(
unsigned int);
1518 static_cast<std::size_t
>(
1519 std::numeric_limits<int>::max()),
1524 my_global_file_position,
1525 src_sizes_variable.data(),
1526 src_sizes_variable.size(),
1535 const std::uint64_t size_on_proc = src_data_variable.size();
1536 std::uint64_t prefix_sum = 0;
1537 ierr = MPI_Exscan(&size_on_proc,
1545 const MPI_Offset my_global_file_position =
1546 static_cast<MPI_Offset
>(global_num_cells) *
sizeof(
unsigned int) +
1552 my_global_file_position,
1553 src_data_variable.data(),
1554 src_data_variable.size(),
1560 ierr = MPI_File_close(&fh);
1564 (void)global_first_cell;
1565 (void)global_num_cells;
1574 template <
int dim,
int spacedim>
1577 const unsigned int global_first_cell,
1578 const unsigned int global_num_cells,
1579 const unsigned int local_num_cells,
1580 const std::string &filename,
1581 const unsigned int n_attached_deserialize_fixed,
1582 const unsigned int n_attached_deserialize_variable)
1584#ifdef DEAL_II_WITH_MPI
1589 Assert(dest_data_fixed.size() == 0,
1590 ExcMessage(
"Previously loaded data has not been released yet!"));
1592 variable_size_data_stored = (n_attached_deserialize_variable > 0);
1598 const std::string fname_fixed = std::string(filename) +
"_fixed.data";
1601 int ierr = MPI_Info_create(&info);
1605 ierr = MPI_File_open(
1609 ierr = MPI_Info_free(&info);
1616 sizes_fixed_cumulative.resize(1 + n_attached_deserialize_fixed +
1617 (variable_size_data_stored ? 1 : 0));
1621 sizes_fixed_cumulative.data(),
1622 sizes_fixed_cumulative.size(),
1628 const unsigned int bytes_per_cell = sizes_fixed_cumulative.back();
1629 dest_data_fixed.resize(
static_cast<size_t>(local_num_cells) *
1633 const MPI_Offset size_header =
1634 sizes_fixed_cumulative.size() *
sizeof(
unsigned int);
1638 const MPI_Offset my_global_file_position =
1640 static_cast<MPI_Offset
>(global_first_cell) * bytes_per_cell;
1643 my_global_file_position,
1644 dest_data_fixed.data(),
1645 dest_data_fixed.size(),
1651 ierr = MPI_File_close(&fh);
1658 if (variable_size_data_stored)
1660 const std::string fname_variable =
1661 std::string(filename) +
"_variable.data";
1664 int ierr = MPI_Info_create(&info);
1668 ierr = MPI_File_open(
1672 ierr = MPI_Info_free(&info);
1676 dest_sizes_variable.resize(local_num_cells);
1678 const MPI_Offset my_global_file_position_sizes =
1679 static_cast<MPI_Offset
>(global_first_cell) *
sizeof(
unsigned int);
1683 my_global_file_position_sizes,
1684 dest_sizes_variable.data(),
1685 dest_sizes_variable.size(),
1693 const std::uint64_t size_on_proc =
1694 std::accumulate(dest_sizes_variable.begin(),
1695 dest_sizes_variable.end(),
1698 std::uint64_t prefix_sum = 0;
1699 ierr = MPI_Exscan(&size_on_proc,
1707 const MPI_Offset my_global_file_position =
1708 static_cast<MPI_Offset
>(global_num_cells) *
sizeof(
unsigned int) +
1711 dest_data_variable.resize(size_on_proc);
1715 my_global_file_position,
1716 dest_data_variable.data(),
1717 dest_data_variable.size(),
1722 ierr = MPI_File_close(&fh);
1726 (void)global_first_cell;
1727 (void)global_num_cells;
1728 (void)local_num_cells;
1730 (void)n_attached_deserialize_fixed;
1731 (void)n_attached_deserialize_variable;
1739 template <
int dim,
int spacedim>
1743 variable_size_data_stored =
false;
1746 sizes_fixed_cumulative.clear();
1747 sizes_fixed_cumulative.shrink_to_fit();
1750 src_data_fixed.clear();
1751 src_data_fixed.shrink_to_fit();
1753 dest_data_fixed.clear();
1754 dest_data_fixed.shrink_to_fit();
1757 src_sizes_variable.clear();
1758 src_sizes_variable.shrink_to_fit();
1760 src_data_variable.clear();
1761 src_data_variable.shrink_to_fit();
1763 dest_sizes_variable.clear();
1764 dest_sizes_variable.shrink_to_fit();
1766 dest_data_variable.clear();
1767 dest_data_variable.shrink_to_fit();
1775#include "tria_base.inst"
bool is_locally_owned() const
virtual void copy_triangulation(const Triangulation< dim, spacedim > &other_tria)
void save(Archive &ar, const unsigned int version) const
virtual std::size_t memory_consumption() const
virtual void update_reference_cells()
void pack_data(const std::vector< cell_relation_t > &cell_relations, const std::vector< typename CellAttachedData::pack_callback_t > &pack_callbacks_fixed, const std::vector< typename CellAttachedData::pack_callback_t > &pack_callbacks_variable)
void save(const unsigned int global_first_cell, const unsigned int global_num_cells, const std::string &filename) const
void unpack_cell_status(std::vector< cell_relation_t > &cell_relations) const
void unpack_data(const std::vector< cell_relation_t > &cell_relations, const unsigned int handle, const std::function< void(const typename ::Triangulation< dim, spacedim >::cell_iterator &, const typename ::Triangulation< dim, spacedim >::CellStatus &, const boost::iterator_range< std::vector< char >::const_iterator > &)> &unpack_callback) const
DataTransfer(const MPI_Comm &mpi_communicator)
void load(const unsigned int global_first_cell, const unsigned int global_num_cells, const unsigned int local_num_cells, const std::string &filename, const unsigned int n_attached_deserialize_fixed, const unsigned int n_attached_deserialize_variable)
virtual void clear() override
void save_attached_data(const unsigned int global_first_cell, const unsigned int global_num_cells, const std::string &filename) const
virtual bool has_hanging_nodes() const override
DistributedTriangulationBase(const MPI_Comm &mpi_communicator, const typename ::Triangulation< dim, spacedim >::MeshSmoothing smooth_grid=(::Triangulation< dim, spacedim >::none), const bool check_for_distorted_cells=false)
void notify_ready_to_unpack(const unsigned int handle, const std::function< void(const cell_iterator &, const CellStatus, const boost::iterator_range< std::vector< char >::const_iterator > &)> &unpack_callback)
typename ::Triangulation< dim, spacedim >::CellStatus CellStatus
unsigned int register_data_attach(const std::function< std::vector< char >(const cell_iterator &, const CellStatus)> &pack_callback, const bool returns_variable_size_data)
typename ::Triangulation< dim, spacedim >::cell_iterator cell_iterator
void load_attached_data(const unsigned int global_first_cell, const unsigned int global_num_cells, const unsigned int local_num_cells, const std::string &filename, const unsigned int n_attached_deserialize_fixed, const unsigned int n_attached_deserialize_variable)
const std::set< types::subdomain_id > & level_ghost_owners() const
virtual std::size_t memory_consumption() const override
virtual types::global_cell_index n_global_active_cells() const override
void update_reference_cells() override
const std::set< types::subdomain_id > & ghost_owners() const
const std::weak_ptr< const Utilities::MPI::Partitioner > global_level_cell_index_partitioner(const unsigned int level) const
types::subdomain_id locally_owned_subdomain() const override
const MPI_Comm mpi_communicator
TriangulationBase(const MPI_Comm &mpi_communicator, const typename ::Triangulation< dim, spacedim >::MeshSmoothing smooth_grid=(::Triangulation< dim, spacedim >::none), const bool check_for_distorted_cells=false)
virtual unsigned int n_global_levels() const override
virtual std::vector< types::boundary_id > get_boundary_ids() const override
unsigned int n_locally_owned_active_cells() const
virtual types::coarse_cell_id n_global_coarse_cells() const override
virtual void update_number_cache()
const std::weak_ptr< const Utilities::MPI::Partitioner > global_active_cell_index_partitioner() const
void communicate_locally_moved_vertices(const std::vector< bool > &vertex_locally_moved)
virtual MPI_Comm get_communicator() const override
void reset_global_cell_indices()
virtual std::vector< types::manifold_id > get_manifold_ids() const override
virtual void copy_triangulation(const ::Triangulation< dim, spacedim > &old_tria) override
virtual ~TriangulationBase() override
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
void release_all_unused_memory()
static ::ExceptionBase & ExcNotImplemented()
static ::ExceptionBase & ExcNeedsMPI()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertThrowMPI(error_code)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
void exchange_cell_data_to_level_ghosts(const MeshType &mesh, const std::function< std_cxx17::optional< DataType >(const typename MeshType::level_cell_iterator &)> &pack, const std::function< void(const typename MeshType::level_cell_iterator &, const DataType &)> &unpack, const std::function< bool(const typename MeshType::level_cell_iterator &)> &cell_filter=always_return< typename MeshType::level_cell_iterator, bool >{ true})
IndexSet complete_index_set(const IndexSet::size_type N)
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
int File_write_at_c(MPI_File fh, MPI_Offset offset, const void *buf, MPI_Count count, MPI_Datatype datatype, MPI_Status *status)
int File_read_at_c(MPI_File fh, MPI_Offset offset, void *buf, MPI_Count count, MPI_Datatype datatype, MPI_Status *status)
unsigned int this_mpi_process(const MPI_Comm &mpi_communicator)
T sum(const T &t, const MPI_Comm &mpi_communicator)
std::vector< T > compute_set_union(const std::vector< T > &vec, const MPI_Comm &comm)
const MPI_Datatype mpi_type_id_for_type
unsigned int n_mpi_processes(const MPI_Comm &mpi_communicator)
T max(const T &t, const MPI_Comm &mpi_communicator)
size_t pack(const T &object, std::vector< char > &dest_buffer, const bool allow_compression=true)
T unpack(const std::vector< char > &buffer, const bool allow_compression=true)
constexpr ::ReferenceCell make_reference_cell_from_int(const std::uint8_t kind)
unsigned int n_cells(const internal::TriangulationImplementation::NumberCache< 1 > &c)
const types::subdomain_id artificial_subdomain_id
static const unsigned int invalid_unsigned_int
const types::global_dof_index invalid_dof_index
unsigned int global_cell_index
const ::Triangulation< dim, spacedim > & tria