32 template <
int dim,
int spacedim>
42 namespace fullydistributed
44 template <
int dim,
int spacedim>
50 const unsigned
int n_partitions) {
53 , currently_processing_create_triangulation_for_internal_usage(
false)
54 , currently_processing_prepare_coarsening_and_refinement_for_internal_usage(
60 template <
int dim,
int spacedim>
68 Assert(construction_data.
comm == this->mpi_communicator,
69 ExcMessage(
"MPI communicators do not match!"));
72 settings = construction_data.
settings;
77 this->set_mesh_smoothing(
79 typename ::Triangulation<dim, spacedim>::MeshSmoothing
>(
83 this->set_mesh_smoothing(
85 typename ::Triangulation<dim, spacedim>::MeshSmoothing
>(
88 this->set_mesh_smoothing(construction_data.
smoothing);
91 this->coarse_cell_id_to_coarse_cell_index_vector.clear();
92 this->coarse_cell_index_to_coarse_cell_id_vector.clear();
98 currently_processing_create_triangulation_for_internal_usage =
true;
100 currently_processing_create_triangulation_for_internal_usage =
false;
103 auto cell = this->
begin();
105 cell->set_level_subdomain_id(
110 this->coarse_cell_id_to_coarse_cell_index_vector.emplace_back(
112 this->coarse_cell_index_to_coarse_cell_id_vector.emplace_back(
118 this->coarse_cell_index_to_coarse_cell_id_vector =
122 std::map<types::coarse_cell_id, unsigned int>
123 coarse_cell_id_to_coarse_cell_index_vector;
124 for (
unsigned int i = 0;
127 coarse_cell_id_to_coarse_cell_index_vector
130 for (
auto i : coarse_cell_id_to_coarse_cell_index_vector)
131 this->coarse_cell_id_to_coarse_cell_index_vector.emplace_back(i);
134 currently_processing_prepare_coarsening_and_refinement_for_internal_usage =
136 currently_processing_create_triangulation_for_internal_usage =
true;
139 currently_processing_prepare_coarsening_and_refinement_for_internal_usage =
141 currently_processing_create_triangulation_for_internal_usage =
false;
144 auto cell_infos = construction_data.
cell_infos;
148 for (
auto &cell_info : cell_infos)
149 std::sort(cell_info.begin(),
153 const CellId a_id(a.id);
154 const CellId b_id(b.id);
156 const auto a_coarse_cell_index =
157 this->coarse_cell_id_to_coarse_cell_index(
158 a_id.get_coarse_cell_id());
159 const auto b_coarse_cell_index =
160 this->coarse_cell_id_to_coarse_cell_index(
161 b_id.get_coarse_cell_id());
168 if (a_coarse_cell_index != b_coarse_cell_index)
169 return a_coarse_cell_index < b_coarse_cell_index;
176 for (
auto cell = this->
begin(); cell != this->
end(); ++cell)
178 if (cell->is_active())
179 cell->set_subdomain_id(
182 cell->set_level_subdomain_id(
187 for (
unsigned int level = 0;
188 level < cell_infos.size() && !cell_infos[
level].empty();
192 auto cell_info = cell_infos[
level].begin();
193 for (; cell_info != cell_infos[
level].end(); ++cell_info)
196 while (cell_info->id != cell->id().template to_binary<dim>())
200 if (cell->is_active())
201 cell->set_subdomain_id(cell_info->subdomain_id);
206 cell->set_level_subdomain_id(cell_info->level_subdomain_id);
211 this->update_number_cache();
212 this->update_cell_relations();
217 template <
int dim,
int spacedim>
225 currently_processing_create_triangulation_for_internal_usage,
227 "You have called the method parallel::fullydistributed::Triangulation::create_triangulation() \n"
228 "that takes 3 arguments. If you have not called this function directly, \n"
229 "it might have been called via a function from the GridGenerator or GridIn \n"
230 "namespace. To be able to setup a fully-distributed Triangulation with these \n"
231 "utility functions nevertheless, please follow the following three steps:\n"
232 " 1) call the utility function for a (serial) Triangulation, \n"
233 " a parallel::shared::Triangulation, or a parallel::distributed::Triangulation object,\n"
234 " 2) use the functions TriangulationDescription::Utilities::create_description_from_triangulation() \n"
235 " or ::create_description_from_triangulation_in_groups() to create the \n"
236 " description of the local partition, and\n"
237 " 3) pass the created description to parallel::fullydistributed::Triangulation::create_triangulation()."));
246 template <
int dim,
int spacedim>
249 const ::Triangulation<dim, spacedim> &other_tria)
255 const ::Triangulation<dim, spacedim> *other_tria_ptr = &other_tria;
262 std::unique_ptr<::Triangulation<dim, spacedim>> serial_tria;
266 if (
dynamic_cast<const ::parallel::TriangulationBase<dim, spacedim>
267 *
>(&other_tria) ==
nullptr)
270 std::make_unique<::Triangulation<dim, spacedim>>();
273 serial_tria->copy_triangulation(other_tria);
276 this->partitioner(*serial_tria,
278 this->mpi_communicator));
281 if (this->is_multilevel_hierarchy_constructed())
285 other_tria_ptr = serial_tria.get();
291 this->mpi_communicator,
300 template <
int dim,
int spacedim>
304 const unsigned int)> &partitioner,
307 this->partitioner = partitioner;
308 this->settings = settings;
313 template <
int dim,
int spacedim>
322 template <
int dim,
int spacedim>
327 currently_processing_prepare_coarsening_and_refinement_for_internal_usage,
328 ExcMessage(
"No coarsening and refinement is supported!"));
330 return ::Triangulation<dim, spacedim>::
331 prepare_coarsening_and_refinement();
336 template <
int dim,
int spacedim>
346 template <
int dim,
int spacedim>
350 const std::size_t mem =
354 coarse_cell_id_to_coarse_cell_index_vector) +
356 coarse_cell_index_to_coarse_cell_id_vector);
362 template <
int dim,
int spacedim>
373 template <
int dim,
int spacedim>
379 coarse_cell_id_to_coarse_cell_index_vector.begin(),
380 coarse_cell_id_to_coarse_cell_index_vector.end(),
382 [](
const std::pair<types::coarse_cell_id, unsigned int> &pair,
384 Assert(coarse_cell_index !=
385 coarse_cell_id_to_coarse_cell_index_vector.cend(),
387 return coarse_cell_index->second;
392 template <
int dim,
int spacedim>
395 const unsigned int coarse_cell_index)
const
398 coarse_cell_index_to_coarse_cell_id_vector.size());
401 coarse_cell_index_to_coarse_cell_id_vector[coarse_cell_index];
403 ExcMessage(
"You are trying to access a dummy cell!"));
408 template <
int dim,
int spacedim>
413 this->local_cell_relations.clear();
414 this->local_cell_relations.reserve(this->n_locally_owned_active_cells());
416 for (
const auto &cell : this->active_cell_iterators())
417 if (cell->is_locally_owned())
418 this->local_cell_relations.emplace_back(
424 template <
int dim,
int spacedim>
428#ifdef DEAL_II_WITH_MPI
429 AssertThrow(this->cell_attached_data.pack_callbacks_variable.size() == 0,
433 this->cell_attached_data.n_attached_deserialize == 0,
435 "Not all SolutionTransfer objects have been deserialized after the last call to load()."));
437 ExcMessage(
"Can not save() an empty Triangulation."));
445 unsigned int n_locally_owned_cells = this->n_locally_owned_active_cells();
447 unsigned int global_first_cell = 0;
449 int ierr = MPI_Exscan(&n_locally_owned_cells,
454 this->mpi_communicator);
457 global_first_cell *=
sizeof(
unsigned int);
462 std::string fname = std::string(filename) +
".info";
463 std::ofstream f(fname.c_str());
464 f <<
"version nproc n_attached_fixed_size_objs n_attached_variable_size_objs n_global_active_cells"
468 << this->cell_attached_data.pack_callbacks_fixed.size() <<
" "
469 << this->cell_attached_data.pack_callbacks_variable.size() <<
" "
470 << this->n_global_active_cells() << std::endl;
474 this->save_attached_data(global_first_cell,
475 this->n_global_active_cells(),
481 int ierr = MPI_Info_create(&info);
484 const std::string fname_tria = filename +
"_triangulation.data";
488 ierr = MPI_File_open(this->mpi_communicator,
490 MPI_MODE_CREATE | MPI_MODE_WRONLY,
495 ierr = MPI_File_set_size(fh, 0);
499 ierr = MPI_Barrier(this->mpi_communicator);
501 ierr = MPI_Info_free(&info);
508 this->mpi_communicator,
512 std::vector<char> buffer;
516 unsigned int buffer_size = buffer.size();
518 unsigned int offset = 0;
520 ierr = MPI_Exscan(&buffer_size,
525 this->mpi_communicator);
529 ierr = MPI_File_write_at(fh,
530 myrank *
sizeof(
unsigned int),
538 ierr = MPI_File_write_at(fh,
539 mpisize *
sizeof(
unsigned int) +
547 ierr = MPI_File_close(&fh);
559 template <
int dim,
int spacedim>
562 const bool autopartition)
564#ifdef DEAL_II_WITH_MPI
566 autopartition ==
false,
568 "load() only works if run with the same number of MPI processes used for saving the triangulation, hence autopartition is disabled."));
571 ExcMessage(
"load() only works if the Triangulation is empty!"));
574 unsigned int n_locally_owned_cells = this->n_locally_owned_active_cells();
576 unsigned int global_first_cell = 0;
578 int ierr = MPI_Exscan(&n_locally_owned_cells,
583 this->mpi_communicator);
586 global_first_cell *=
sizeof(
unsigned int);
589 unsigned int version, numcpus, attached_count_fixed,
590 attached_count_variable, n_global_active_cells;
592 std::string fname = std::string(filename) +
".info";
593 std::ifstream f(fname.c_str());
595 std::string firstline;
596 getline(f, firstline);
597 f >> version >> numcpus >> attached_count_fixed >>
598 attached_count_variable >> n_global_active_cells;
602 ExcMessage(
"Incompatible version found in .info file."));
603 Assert(this->n_global_active_cells() == n_global_active_cells,
604 ExcMessage(
"Number of global active cells differ!"));
617 int ierr = MPI_Info_create(&info);
620 const std::string fname_tria = filename +
"_triangulation.data";
623 ierr = MPI_File_open(this->mpi_communicator,
630 ierr = MPI_Info_free(&info);
634 unsigned int buffer_size;
636 ierr = MPI_File_read_at(fh,
637 myrank *
sizeof(
unsigned int),
644 unsigned int offset = 0;
646 ierr = MPI_Exscan(&buffer_size,
651 this->mpi_communicator);
655 std::vector<char> buffer(buffer_size);
656 ierr = MPI_File_read_at(fh,
657 mpisize *
sizeof(
unsigned int) +
665 ierr = MPI_File_close(&fh);
668 auto construction_data = ::Utilities::template
unpack<
673 construction_data.
comm = this->mpi_communicator;
680 this->cell_attached_data.n_attached_data_sets = 0;
681 this->cell_attached_data.n_attached_deserialize =
682 attached_count_fixed + attached_count_variable;
685 this->load_attached_data(global_first_cell,
686 this->n_global_active_cells(),
687 this->n_locally_owned_active_cells(),
689 attached_count_fixed,
690 attached_count_variable);
692 this->update_cell_relations();
693 this->update_periodic_face_map();
694 this->update_number_cache();
710#include "fully_distributed_tria.inst"
virtual void create_triangulation(const std::vector< Point< spacedim > > &vertices, const std::vector< CellData< dim > > &cells, const SubCellData &subcelldata)
virtual std::size_t memory_consumption() const override
virtual void execute_coarsening_and_refinement() override
virtual bool has_hanging_nodes() const override
virtual types::coarse_cell_id coarse_cell_index_to_coarse_cell_id(const unsigned int coarse_cell_index) const override
void copy_triangulation(const ::Triangulation< dim, spacedim > &other_tria) override
void set_partitioner(const std::function< void(::Triangulation< dim, spacedim > &, const unsigned int)> &partitioner, const TriangulationDescription::Settings &settings)
virtual void update_cell_relations() override
Triangulation(const MPI_Comm &mpi_communicator)
virtual bool prepare_coarsening_and_refinement() override
virtual void load(const std::string &filename, const bool autopartition=false) override
virtual unsigned int coarse_cell_id_to_coarse_cell_index(const types::coarse_cell_id coarse_cell_id) const override
virtual void save(const std::string &filename) const override
virtual bool is_multilevel_hierarchy_constructed() const override
void create_triangulation(const TriangulationDescription::Description< dim, spacedim > &construction_data) override
virtual std::size_t memory_consumption() const override
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcIO()
static ::ExceptionBase & ExcNotImplemented()
static ::ExceptionBase & ExcNeedsMPI()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertThrowMPI(error_code)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
#define DEAL_II_MPI_CONST_CAST(expr)
void create_triangulation(Triangulation< dim, dim > &tria, const AdditionalData &additional_data=AdditionalData())
void hyper_cube(Triangulation< dim, spacedim > &tria, const double left=0., const double right=1., const bool colorize=false)
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
Description< dim, spacedim > create_description_from_triangulation(const ::Triangulation< dim, spacedim > &tria, const MPI_Comm &comm, const TriangulationDescription::Settings settings=TriangulationDescription::Settings::default_setting, const unsigned int my_rank_in=numbers::invalid_unsigned_int)
@ construct_multigrid_hierarchy
VectorType::value_type * end(VectorType &V)
VectorType::value_type * begin(VectorType &V)
unsigned int this_mpi_process(const MPI_Comm &mpi_communicator)
unsigned int n_mpi_processes(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)
Iterator lower_bound(Iterator first, Iterator last, const T &val)
unsigned int n_cells(const internal::TriangulationImplementation::NumberCache< 1 > &c)
const types::coarse_cell_id invalid_coarse_cell_id
const types::subdomain_id artificial_subdomain_id
global_cell_index coarse_cell_id
std::vector< std::vector< CellData< dim > > > cell_infos
Triangulation< dim, spacedim >::MeshSmoothing smoothing
std::vector< Point< spacedim > > coarse_cell_vertices
std::vector< types::coarse_cell_id > coarse_cell_index_to_coarse_cell_id