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