deal.II version GIT relicensing-6842-g793a97d2aa 2026-10-02 14:00:01+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\}}\)
Loading...
Searching...
No Matches
fully_distributed_tria.cc
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2019 - 2026 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13
15#include <deal.II/base/mpi.h>
17
20
22
23#include <fstream>
24#include <memory>
25
27
28// Forward declarations
29namespace GridGenerator
30{
31 template <int dim, int spacedim>
32 void
34 const double left,
35 const double right,
36 const bool colorize);
37} // namespace GridGenerator
38
39namespace parallel
40{
41 namespace fullydistributed
42 {
43 template <int dim, int spacedim>
45 Triangulation<dim, spacedim>::Triangulation(const MPI_Comm mpi_communicator)
46 : parallel::DistributedTriangulationBase<dim, spacedim>(mpi_communicator)
47 , settings(TriangulationDescription::Settings::default_setting)
48 , partitioner([](::Triangulation<dim, spacedim> &tria,
49 const unsigned int n_partitions) {
51 })
52 , currently_processing_create_triangulation_for_internal_usage(false)
53 , currently_processing_prepare_coarsening_and_refinement_for_internal_usage(
54 false)
55 {}
56
57
58
59 template <int dim, int spacedim>
61 void Triangulation<dim, spacedim>::create_triangulation(
62 const TriangulationDescription::Description<dim, spacedim>
63 &construction_data)
64 {
65 // check if the communicator of this parallel triangulation has been used
66 // to construct the TriangulationDescription::Description
67 Assert(construction_data.comm == this->mpi_communicator,
68 ExcMessage("MPI communicators do not match!"));
69
70 // store internally the settings
71 settings = construction_data.settings;
72
73 // set the smoothing properties
74 if (settings &
76 this->set_mesh_smoothing(
77 static_cast<
78 typename ::Triangulation<dim, spacedim>::MeshSmoothing>(
81 else
82 this->set_mesh_smoothing(
83 static_cast<
84 typename ::Triangulation<dim, spacedim>::MeshSmoothing>(
86
87 this->set_mesh_smoothing(construction_data.smoothing);
88
89 // clear internal data structures
90 this->coarse_cell_id_to_coarse_cell_index_vector.clear();
91 this->coarse_cell_index_to_coarse_cell_id_vector.clear();
92
93 // check if no locally relevant coarse-grid cells have been provided
94 if (construction_data.coarse_cell_vertices.empty())
95 {
96 // 1) create a dummy hypercube
97 currently_processing_create_triangulation_for_internal_usage = true;
98 GridGenerator::hyper_cube(*this, 0, 1, false);
99 currently_processing_create_triangulation_for_internal_usage = false;
100
101 // 2) mark cell as artificial
102 auto cell = this->begin();
103 cell->set_subdomain_id(::numbers::artificial_subdomain_id);
104 cell->set_level_subdomain_id(
106
107 // 3) set up dummy mapping between locally relevant coarse-grid cells
108 // and global cells
109 this->coarse_cell_id_to_coarse_cell_index_vector.emplace_back(
111 this->coarse_cell_index_to_coarse_cell_id_vector.emplace_back(
113 }
114 else
115 {
116 // 1) store `coarse-cell index to coarse-cell id`-mapping
117 this->coarse_cell_index_to_coarse_cell_id_vector =
118 construction_data.coarse_cell_index_to_coarse_cell_id;
119
120 // 2) set up `coarse-cell id to coarse-cell index`-mapping
121 this->coarse_cell_id_to_coarse_cell_index_vector.resize(
122 construction_data.coarse_cell_index_to_coarse_cell_id.size());
123 for (unsigned int i = 0;
124 i < construction_data.coarse_cell_index_to_coarse_cell_id.size();
125 ++i)
126 this->coarse_cell_id_to_coarse_cell_index_vector[i] =
127 std::make_pair(
128 construction_data.coarse_cell_index_to_coarse_cell_id[i], i);
129
130 std::sort(this->coarse_cell_id_to_coarse_cell_index_vector.begin(),
131 this->coarse_cell_id_to_coarse_cell_index_vector.end(),
132 [](const auto &a, const auto &b) {
133 return a.first < b.first;
134 });
135
136 // create locally-relevant
137 currently_processing_prepare_coarsening_and_refinement_for_internal_usage =
138 true;
139 currently_processing_create_triangulation_for_internal_usage = true;
141 construction_data);
142 currently_processing_prepare_coarsening_and_refinement_for_internal_usage =
143 false;
144 currently_processing_create_triangulation_for_internal_usage = false;
145
146 // create a copy of cell_infos such that we can sort them
147 auto cell_infos = construction_data.cell_infos;
148
149 // sort cell_infos on each level separately (as done in
150 // ::Triangulation::create_triangulation())
151 for (auto &cell_info : cell_infos)
152 std::sort(cell_info.begin(),
153 cell_info.end(),
156 const CellId a_id(a.id);
157 const CellId b_id(b.id);
158
159 const auto a_coarse_cell_index =
160 this->coarse_cell_id_to_coarse_cell_index(
161 a_id.get_coarse_cell_id());
162 const auto b_coarse_cell_index =
163 this->coarse_cell_id_to_coarse_cell_index(
164 b_id.get_coarse_cell_id());
165
166 // according to their coarse-cell index and if that is
167 // same according to their cell id (the result is that
168 // cells on each level are sorted according to their
169 // index on that level - what we need in the following
170 // operations)
171 if (a_coarse_cell_index != b_coarse_cell_index)
172 return a_coarse_cell_index < b_coarse_cell_index;
173 else
174 return a_id < b_id;
175 });
176
177 // 4a) set all cells artificial (and set the actual
178 // (level_)subdomain_ids in the next step)
179 for (const auto &cell : this->cell_iterators())
180 {
181 if (cell->is_active())
182 cell->set_subdomain_id(
184
185 cell->set_level_subdomain_id(
187 }
188
189 // 4b) set actual (level_)subdomain_ids
190 for (unsigned int level = 0;
191 level < cell_infos.size() && !cell_infos[level].empty();
192 ++level)
193 {
194 auto cell = this->begin(level);
195 auto cell_info = cell_infos[level].begin();
196 for (; cell_info != cell_infos[level].end(); ++cell_info)
197 {
198 // find cell that has the correct cell
199 while (cell_info->id != cell->id().template to_binary<dim>())
200 ++cell;
201
202 // subdomain id
203 if (cell->is_active())
204 cell->set_subdomain_id(cell_info->subdomain_id);
205
206 // level subdomain id
208 construct_multigrid_hierarchy)
209 cell->set_level_subdomain_id(cell_info->level_subdomain_id);
210 }
211 }
212 }
213
214 this->update_number_cache();
215 this->update_cell_relations();
216 }
217
218
219
220 template <int dim, int spacedim>
222 void Triangulation<dim, spacedim>::create_triangulation(
223 const std::vector<Point<spacedim>> &vertices,
224 const std::vector<::CellData<dim>> &cells,
225 const SubCellData &subcelldata)
226 {
227 Assert(
228 currently_processing_create_triangulation_for_internal_usage,
230 "You have called the overload of\n"
231 "\n"
232 " parallel::fullydistributed::Triangulation::"
233 "create_triangulation()\n"
234 "\n"
235 "which takes 3 arguments. This function is not yet implemented for "
236 "this class. If you have not called this function directly, it "
237 "might have been called via a function from the GridGenerator or "
238 "GridIn namespace. To set up a fully-distributed Triangulation with "
239 "these utility functions, please start by using the same process to "
240 "set up a serial Triangulation, parallel::shared::Triangulation, or "
241 "a parallel::distributed::Triangulation. Once that is complete use "
242 "the copy_triangulation() member function to finish setting up the "
243 "original fully distributed Triangulation. Alternatively, you can "
244 "use TriangulationDescription::Utilities::"
245 "create_description_from_triangulation() or "
246 "create_description_from_triangulation_in_groups() to create the "
247 "description of the local partition, and pass that description to "
248 "parallel::fullydistributed::Triangulation::create_triangulation()."));
249
251 cells,
252 subcelldata);
253 }
254
255
256
257 template <int dim, int spacedim>
259 void Triangulation<dim, spacedim>::copy_triangulation(
260 const ::Triangulation<dim, spacedim> &other_tria)
261 {
262 // pointer to the triangulation for which the construction data
263 // should be created (normally it is the input triangulation but
264 // in the case of a serial triangulation we create a copy which should
265 // be used)
266 const ::Triangulation<dim, spacedim> *other_tria_ptr = &other_tria;
267
268 // temporary serial triangulation (since the input triangulation is const
269 // and we might modify its subdomain_ids and level_subdomain_ids during
270 // partitioning)
272
273 // check if other triangulation is not a parallel one, which needs to be
274 // partitioned
275 if (dynamic_cast<const ::parallel::TriangulationBase<dim, spacedim>
276 *>(&other_tria) == nullptr)
277 {
278 // actually copy the serial triangulation
279 serial_tria.copy_triangulation(other_tria);
280
281 // partition triangulation
282 this->partitioner(serial_tria,
284 this->mpi_communicator));
285
286 // partition multigrid levels
287 if (this->is_multilevel_hierarchy_constructed())
289
290 // use the new serial triangulation to create the construction data
291 other_tria_ptr = &serial_tria;
292 }
293
294 // create construction data
295 const auto construction_data = TriangulationDescription::Utilities::
297 this->mpi_communicator,
298 this->settings);
299
300 // finally create triangulation
301 this->create_triangulation(construction_data);
302 }
303
304
305
306 template <int dim, int spacedim>
308 void Triangulation<dim, spacedim>::set_partitioner(
309 const std::function<void(::Triangulation<dim, spacedim> &,
310 const unsigned int)> &partitioner,
311 const TriangulationDescription::Settings &settings)
312 {
313 this->partitioner = partitioner;
314 this->settings = settings;
315 }
316
317
318
319 template <int dim, int spacedim>
321 void Triangulation<dim, spacedim>::set_partitioner(
322 const RepartitioningPolicyTools::Base<dim, spacedim> &partitioner,
323 const TriangulationDescription::Settings &settings)
324 {
325 this->partitioner_distributed = &partitioner;
326 this->settings = settings;
327 }
328
329
330
331 template <int dim, int spacedim>
333 void Triangulation<dim, spacedim>::repartition()
334 {
335 // signal that repartitioning has started
336 this->signals.pre_distributed_repartition();
337
338 // create construction_data with the help of the partitioner
339 const auto construction_data = TriangulationDescription::Utilities::
341 *this,
342 this->partitioner_distributed->partition(*this),
343 this->settings);
344
345 // clear old content
346 this->clear();
347 this->coarse_cell_id_to_coarse_cell_index_vector.clear();
348 this->coarse_cell_index_to_coarse_cell_id_vector.clear();
349
350 // use construction_data to set up new triangulation
351 this->create_triangulation(construction_data);
352
353 // signal that repartitioning has completed
354 this->signals.post_distributed_repartition();
355 }
356
357
358
359 template <int dim, int spacedim>
361 void Triangulation<dim, spacedim>::execute_coarsening_and_refinement()
362 {
364 }
365
366
367
368 template <int dim, int spacedim>
370 bool Triangulation<dim, spacedim>::prepare_coarsening_and_refinement()
371 {
372 Assert(
373 currently_processing_prepare_coarsening_and_refinement_for_internal_usage,
374 ExcMessage("No coarsening and refinement is supported!"));
375
376 return ::Triangulation<dim, spacedim>::
377 prepare_coarsening_and_refinement();
378 }
379
380
381
382 template <int dim, int spacedim>
384 std::size_t Triangulation<dim, spacedim>::memory_consumption() const
385 {
386 const std::size_t mem =
390 coarse_cell_id_to_coarse_cell_index_vector) +
392 coarse_cell_index_to_coarse_cell_id_vector);
393 return mem;
394 }
395
396
397
398 template <int dim, int spacedim>
400 bool Triangulation<dim, spacedim>::is_multilevel_hierarchy_constructed()
401 const
402 {
403 return (
404 settings &
406 }
407
408
409
410 template <int dim, int spacedim>
412 unsigned int Triangulation<dim, spacedim>::
413 coarse_cell_id_to_coarse_cell_index(
414 const types::coarse_cell_id coarse_cell_id) const
415 {
416 const auto coarse_cell_index = std::lower_bound(
417 coarse_cell_id_to_coarse_cell_index_vector.begin(),
418 coarse_cell_id_to_coarse_cell_index_vector.end(),
419 coarse_cell_id,
420 [](const std::pair<types::coarse_cell_id, unsigned int> &pair,
421 const types::coarse_cell_id &val) { return pair.first < val; });
422 if (coarse_cell_index !=
423 coarse_cell_id_to_coarse_cell_index_vector.cend())
424 return coarse_cell_index->second;
425 else
426 return numbers::invalid_unsigned_int; // cell could no be found
427 }
428
429
430
431 template <int dim, int spacedim>
435 const unsigned int coarse_cell_index) const
436 {
437 AssertIndexRange(coarse_cell_index,
438 coarse_cell_index_to_coarse_cell_id_vector.size());
439
440 const auto coarse_cell_id =
441 coarse_cell_index_to_coarse_cell_id_vector[coarse_cell_index];
443 ExcMessage("You are trying to access a dummy cell!"));
444 return coarse_cell_id;
445 }
446
447
448 template <int dim, int spacedim>
450 void Triangulation<dim, spacedim>::update_cell_relations()
451 {
452 // Reorganize memory for local_cell_relations.
453 this->local_cell_relations.clear();
454 this->local_cell_relations.reserve(this->n_locally_owned_active_cells());
455
456 for (const auto &cell : this->active_cell_iterators())
457 if (cell->is_locally_owned())
458 this->local_cell_relations.emplace_back(
460 }
461
462
463
464 template <int dim, int spacedim>
466 void Triangulation<dim, spacedim>::save(const std::string &filename) const
467 {
468#ifdef DEAL_II_WITH_MPI
469
470 Assert(
471 this->cell_attached_data.n_attached_deserialize == 0,
473 "Not all SolutionTransfer objects have been deserialized after the last call to load()."));
474 Assert(this->n_cells() > 0,
475 ExcMessage("Can not save() an empty Triangulation."));
476
477 const int myrank =
478 Utilities::MPI::this_mpi_process(this->mpi_communicator);
479 const int mpisize =
480 Utilities::MPI::n_mpi_processes(this->mpi_communicator);
481
482 // Compute global offset for each rank.
483 unsigned int n_locally_owned_cells = this->n_locally_owned_active_cells();
484
485 unsigned int global_first_cell = 0;
486
487 int ierr = MPI_Exscan(&n_locally_owned_cells,
488 &global_first_cell,
489 1,
490 MPI_UNSIGNED,
491 MPI_SUM,
492 this->mpi_communicator);
493 AssertThrowMPI(ierr);
494
495 global_first_cell *= sizeof(unsigned int);
496
497
498 if (myrank == 0)
499 {
500 std::string fname = std::string(filename) + ".info";
501 std::ofstream f(fname);
502 f << "version nproc n_attached_fixed_size_objs n_attached_variable_size_objs n_global_active_cells"
503 << std::endl
505 version_number
506 << " " << Utilities::MPI::n_mpi_processes(this->mpi_communicator)
507 << " " << this->cell_attached_data.pack_callbacks_fixed.size()
508 << " " << this->cell_attached_data.pack_callbacks_variable.size()
509 << " " << this->n_global_active_cells() << std::endl;
510 }
511
512 // Save cell attached data.
513 this->save_attached_data(global_first_cell,
514 this->n_global_active_cells(),
515 filename);
516
517 // Save triangulation description.
518 {
519 MPI_Info info;
520 int ierr = MPI_Info_create(&info);
521 AssertThrowMPI(ierr);
522
523 const std::string fname_tria = filename + "_triangulation.data";
524
525 // Open file.
526 MPI_File fh;
527 ierr = MPI_File_open(this->mpi_communicator,
528 fname_tria.c_str(),
529 MPI_MODE_CREATE | MPI_MODE_WRONLY,
530 info,
531 &fh);
532 AssertThrowMPI(ierr);
533
534 ierr = MPI_File_set_size(fh, 0); // delete the file contents
535 AssertThrowMPI(ierr);
536 // this barrier is necessary, because otherwise others might already
537 // write while one core is still setting the size to zero.
538 ierr = MPI_Barrier(this->mpi_communicator);
539 AssertThrowMPI(ierr);
540 ierr = MPI_Info_free(&info);
541 AssertThrowMPI(ierr);
542 // ------------------
543
544 // Create construction data.
545 const auto construction_data = TriangulationDescription::Utilities::
547 this->mpi_communicator,
548 this->settings);
549
550 // Pack.
551 std::vector<char> buffer;
552 ::Utilities::pack(construction_data, buffer, false);
553
554 // Write offsets to file.
555 const std::uint64_t buffer_size = buffer.size();
556
557 std::uint64_t offset = 0;
558
559 ierr = MPI_Exscan(
560 &buffer_size,
561 &offset,
562 1,
563 Utilities::MPI::mpi_type_id_for_type<decltype(buffer_size)>,
564 MPI_SUM,
565 this->mpi_communicator);
566 AssertThrowMPI(ierr);
567
568 // Write offsets to file.
569 ierr = MPI_File_write_at(
570 fh,
571 myrank * sizeof(std::uint64_t),
572 &buffer_size,
573 1,
574 Utilities::MPI::mpi_type_id_for_type<decltype(buffer_size)>,
575 MPI_STATUS_IGNORE);
576 AssertThrowMPI(ierr);
577
578 // global position in file
579 const std::uint64_t global_position =
580 mpisize * sizeof(std::uint64_t) + offset;
581
582 // Write buffers to file.
584 fh,
585 global_position,
586 buffer.data(),
587 buffer.size(), // local buffer
588 MPI_CHAR,
589 MPI_STATUS_IGNORE);
590 AssertThrowMPI(ierr);
591
592 ierr = MPI_File_close(&fh);
593 AssertThrowMPI(ierr);
594 }
595#else
596 (void)filename;
597
598 AssertThrow(false, ExcNeedsMPI());
599#endif
600 }
601
602
603
604 template <int dim, int spacedim>
606 void Triangulation<dim, spacedim>::load(const std::string &filename)
607 {
608#ifdef DEAL_II_WITH_MPI
609 Assert(this->n_cells() == 0,
610 ExcMessage("load() only works if the Triangulation is empty!"));
611
612
613 unsigned int version, numcpus, attached_count_fixed,
614 attached_count_variable, n_global_active_cells;
615 {
616 std::string fname = std::string(filename) + ".info";
617 std::ifstream f(fname);
618 AssertThrow(f.fail() == false, ExcIO());
619 std::string firstline;
620 getline(f, firstline);
621 f >> version >> numcpus >> attached_count_fixed >>
622 attached_count_variable >> n_global_active_cells;
623 }
624
625 const auto expected_version = ::internal::
626 CellAttachedDataSerializer<dim, spacedim>::version_number;
627
628 AssertThrow(version == expected_version,
629 ExcMessage("Incompatible version found in .info file."));
630
631 // Load description and construct the triangulation.
632 {
633 const int myrank =
634 Utilities::MPI::this_mpi_process(this->mpi_communicator);
635 const int mpisize =
636 Utilities::MPI::n_mpi_processes(this->mpi_communicator);
637
638 AssertDimension(numcpus, mpisize);
639
640 // Open file.
641 MPI_Info info;
642 int ierr = MPI_Info_create(&info);
643 AssertThrowMPI(ierr);
644
645 const std::string fname_tria = filename + "_triangulation.data";
646
647 MPI_File fh;
648 ierr = MPI_File_open(this->mpi_communicator,
649 fname_tria.c_str(),
650 MPI_MODE_RDONLY,
651 info,
652 &fh);
653 AssertThrowMPI(ierr);
654
655 ierr = MPI_Info_free(&info);
656 AssertThrowMPI(ierr);
657
658 // Read offsets from file.
659 std::uint64_t buffer_size;
660
661 ierr = MPI_File_read_at(
662 fh,
663 myrank * sizeof(std::uint64_t),
664 &buffer_size,
665 1,
666 Utilities::MPI::mpi_type_id_for_type<decltype(buffer_size)>,
667 MPI_STATUS_IGNORE);
668 AssertThrowMPI(ierr);
669
670 std::uint64_t offset = 0;
671
672 ierr = MPI_Exscan(
673 &buffer_size,
674 &offset,
675 1,
676 Utilities::MPI::mpi_type_id_for_type<decltype(buffer_size)>,
677 MPI_SUM,
678 this->mpi_communicator);
679 AssertThrowMPI(ierr);
680
681 // global position in file
682 const std::uint64_t global_position =
683 mpisize * sizeof(std::uint64_t) + offset;
684
685 // Read buffers from file.
686 std::vector<char> buffer(buffer_size);
688 fh,
689 global_position,
690 buffer.data(),
691 buffer.size(), // local buffer
692 MPI_CHAR,
693 MPI_STATUS_IGNORE);
694 AssertThrowMPI(ierr);
695
696 ierr = MPI_File_close(&fh);
697 AssertThrowMPI(ierr);
698
699 auto construction_data = ::Utilities::template unpack<
701
702 // WARNING: serialization cannot handle the MPI communicator
703 // which is the reason why we have to set it here explicitly
704 construction_data.comm = this->mpi_communicator;
705
706 this->create_triangulation(construction_data);
707 }
708
709 // Compute global offset for each rank.
710 unsigned int n_locally_owned_cells = this->n_locally_owned_active_cells();
711
712 unsigned int global_first_cell = 0;
713
714 int ierr = MPI_Exscan(&n_locally_owned_cells,
715 &global_first_cell,
716 1,
717 MPI_UNSIGNED,
718 MPI_SUM,
719 this->mpi_communicator);
720 AssertThrowMPI(ierr);
721
722 global_first_cell *= sizeof(unsigned int);
723
724 Assert(this->n_global_active_cells() == n_global_active_cells,
725 ExcMessage("Number of global active cells differ!"));
726
727 // clear all of the callback data, as explained in the documentation of
728 // register_data_attach()
729 this->cell_attached_data.n_attached_data_sets = 0;
730 this->cell_attached_data.n_attached_deserialize =
731 attached_count_fixed + attached_count_variable;
732
733 // Load attached cell data, if any was stored.
734 this->load_attached_data(global_first_cell,
735 this->n_global_active_cells(),
736 this->n_locally_owned_active_cells(),
737 filename,
738 attached_count_fixed,
739 attached_count_variable);
740
741 this->update_cell_relations();
742 this->update_periodic_face_map();
743 this->update_number_cache();
744#else
745 (void)filename;
746
747 AssertThrow(false, ExcNeedsMPI());
748#endif
749 }
750
751
752
753 template <int dim, int spacedim>
755 void Triangulation<dim, spacedim>::update_number_cache()
756 {
758
759 // additionally update the number of global coarse cells
760 types::coarse_cell_id number_of_global_coarse_cells = 0;
761
762 for (const auto &cell : this->active_cell_iterators())
763 if (!cell->is_artificial())
764 number_of_global_coarse_cells =
765 std::max(number_of_global_coarse_cells,
766 cell->id().get_coarse_cell_id());
767
768 number_of_global_coarse_cells =
769 Utilities::MPI::max(number_of_global_coarse_cells,
770 this->mpi_communicator) +
771 1;
772
773 this->number_cache.number_of_global_coarse_cells =
774 number_of_global_coarse_cells;
775 }
776
777
778 } // namespace fullydistributed
779} // namespace parallel
780
781
782
783/*-------------- Explicit Instantiations -------------------------------*/
784#include "distributed/fully_distributed_tria.inst"
785
786
*  *  iterator begin()
types::coarse_cell_id get_coarse_cell_id() const
Definition cell_id.h:385
Definition point.h:111
virtual void copy_triangulation(const Triangulation< dim, spacedim > &other_tria)
virtual std::size_t memory_consumption() const override
Definition tria_base.cc:90
virtual void update_number_cache()
Definition tria_base.cc:168
virtual void clear() override
Definition tria_base.cc:686
virtual types::coarse_cell_id coarse_cell_index_to_coarse_cell_id(const unsigned int coarse_cell_index) const override
void create_triangulation(const TriangulationDescription::Description< dim, spacedim > &construction_data) override
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_CXX20_REQUIRES(condition)
Definition config.h:249
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define DEAL_II_NOT_IMPLEMENTED()
bool colorize
Definition grid_out.cc:4641
unsigned int level
Definition grid_out.cc:4642
static ::ExceptionBase & ExcIO()
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)
void hyper_cube(Triangulation< dim, spacedim > &tria, const double left=0., const double right=1., const bool colorize=false)
void partition_triangulation_zorder(const unsigned int n_partitions, Triangulation< dim, spacedim > &triangulation, const bool group_siblings=true)
void partition_multigrid_levels(Triangulation< dim, spacedim > &triangulation)
std::enable_if_t< std::is_fundamental_v< T >, std::size_t > memory_consumption(const T &t)
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)
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 n_mpi_processes(const MPI_Comm mpi_communicator)
Definition mpi.cc:103
T max(const T &t, const MPI_Comm mpi_communicator)
unsigned int this_mpi_process(const MPI_Comm mpi_communicator)
Definition mpi.cc:118
const MPI_Datatype mpi_type_id_for_type
Definition mpi.h:1685
std::size_t pack(const T &object, std::vector< char > &dest_buffer, const bool allow_compression=true)
Definition utilities.h:1352
constexpr unsigned int invalid_unsigned_int
Definition types.h:228
constexpr types::subdomain_id artificial_subdomain_id
Definition types.h:406
constexpr types::coarse_cell_id invalid_coarse_cell_id
Definition types.h:272
STL namespace.
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
Definition types.h:30
std::vector< std::vector< CellData< dim > > > cell_infos