16#include <deal.II/fe/fe_dgq.h>
18#include <hyper.deal/base/mpi_tags.h>
19#include <hyper.deal/matrix_free/matrix_free.h>
46 dealii::types::global_dof_index
gid;
62 FaceInfo(
unsigned int gid,
unsigned int rank,
unsigned char no)
75 unsigned int max_batch_size;
76 unsigned int n_cell_batches;
79 std::vector<unsigned char> cells_fill;
80 std::vector<CellInfo> cells;
81 std::vector<unsigned int> cells_lid;
84 std::vector<unsigned char> faces_fill;
85 std::vector<unsigned int> interior_face_no;
86 std::vector<unsigned int> exterior_face_no;
87 std::vector<unsigned int> face_orientation;
88 std::vector<CellInfo> cells_interior;
89 std::vector<CellInfo> cells_exterior;
92 std::vector<CellInfo> cells_exterior_ecl;
93 std::vector<unsigned int> exterior_face_no_ecl;
94 std::vector<unsigned int> face_orientation_ecl;
97 compute_n_cell_batches()
const
99 return n_cell_batches;
103 compute_n_cell_and_ghost_batches()
const
105 return this->cells_fill.size();
109 compute_n_cells()
const
111 if (max_batch_size == 1)
112 return n_cell_batches;
114 unsigned int n_cells = 0;
115 for (
unsigned int i = 0; i < this->n_cell_batches; i++)
116 for (
unsigned int v = 0; v < this->cells_fill[i]; v++)
122 compute_n_cells_and_ghost()
const
124 if (max_batch_size == 1)
127 unsigned int n_cells = 0;
128 for (
unsigned int i = 0; i < this->cells_fill.size(); i++)
129 for (
unsigned int v = 0; v < this->cells_fill[i]; v++)
150 std::vector<FaceInfo>
157 std::pair<unsigned int, unsigned int>
158 get_local_range()
const
161 unsigned int i_min = std::numeric_limits<unsigned int>::max();
162 unsigned int i_max = std::numeric_limits<unsigned int>::min();
164 for (
unsigned int i = 0; i < info.n_cell_batches; i++)
165 for (
unsigned int v = 0; v < info.cells_fill[i]; v++)
167 unsigned int gid = info.cells[i * info.max_batch_size + v].gid;
168 i_min = std::min(i_min, gid);
169 i_max = std::max(i_max, gid);
172 return {i_min, i_max};
175 std::vector<FaceInfo>
176 get_ghost_faces(
const std::pair<unsigned int, unsigned int> local_range,
178 const bool ecl =
false)
const
180 const auto i_min = local_range.first;
181 const auto i_max = local_range.second;
182 std::vector<FaceInfo> ghosts_faces;
186 for (
unsigned int i = 0; i < info.n_cell_batches; i++)
187 for (
int d = 0; d < 2 * dim; d++)
188 for (
unsigned int v = 0; v < info.max_batch_size; v++)
190 Assert(i * info.max_batch_size * 2 * dim +
191 d * info.max_batch_size + v <
192 info.cells_exterior_ecl.size(),
193 dealii::ExcMessage(
"Out of range!"));
195 const unsigned int index =
196 i * info.max_batch_size * 2 * dim +
197 d * info.max_batch_size + v;
199 const auto cell_info = info.cells_exterior_ecl[index];
200 const unsigned int gid = cell_info.gid;
201 if (gid == dealii::numbers::invalid_unsigned_int)
203 if (gid < i_min || i_max < gid)
204 ghosts_faces.emplace_back(
205 gid, cell_info.rank, info.exterior_face_no_ecl[index]);
210 for (
unsigned int i = 0; i < info.interior_face_no.size(); i++)
211 for (
unsigned int v = 0; v < info.faces_fill[i]; v++)
213 const auto cell_info =
214 info.cells_interior[i * info.max_batch_size + v];
215 const auto gid = cell_info.gid;
217 Assert(gid != dealii::numbers::invalid_dof_index,
218 dealii::StandardExceptions::ExcInternalError());
220 if (gid < i_min || i_max < gid)
221 ghosts_faces.emplace_back(gid,
223 info.interior_face_no[i]);
226 for (
unsigned int i = 0; i < info.exterior_face_no.size(); i++)
227 for (
unsigned int v = 0; v < info.faces_fill[i]; v++)
229 const auto cell_info =
230 info.cells_exterior[i * info.max_batch_size + v];
231 const auto gid = cell_info.gid;
233 Assert(gid != dealii::numbers::invalid_dof_index,
234 dealii::StandardExceptions::ExcInternalError());
236 if (gid < i_min || i_max < gid)
237 ghosts_faces.emplace_back(gid,
239 info.exterior_face_no[i]);
246 const GlobalCellInfo &info;
250 template <
int dim,
typename Number,
typename VectorizedArrayType>
252 collect_global_cell_info(
253 const dealii::MatrixFree<dim, Number, VectorizedArrayType> &data,
254 GlobalCellInfo & info)
261 dealii::FE_DGQ<dim> fe(0);
263 dealii::DoFHandler<dim> dof_handler(
264 data.get_dof_handler().get_triangulation());
265 dof_handler.distribute_dofs(fe);
267 const auto cell_to_gid = [&](
const auto &cell) {
268 typename dealii::DoFHandler<dim>::level_cell_accessor dof_cell(
269 &data.get_dof_handler().get_triangulation(),
274 std::vector<dealii::types::global_dof_index> indices(1);
275 dof_cell.get_dof_indices(indices);
276 return CellInfo(indices[0], dof_cell.subdomain_id());
280 const unsigned int v_len = VectorizedArrayType::size();
283 info.max_batch_size = v_len;
284 info.n_cell_batches = data.n_cell_batches();
287 info.cells.resize(v_len *
288 (data.n_cell_batches() + data.n_ghost_cell_batches()));
289 info.cells_exterior_ecl.resize(dealii::GeometryInfo<dim>::faces_per_cell *
290 v_len * data.n_cell_batches(),
291 {dealii::numbers::invalid_unsigned_int,
292 dealii::numbers::invalid_unsigned_int});
293 info.cells_lid.resize(
294 v_len * (data.n_cell_batches() + data.n_ghost_cell_batches()));
295 info.cells_interior.resize(
296 v_len * (data.n_inner_face_batches() + data.n_boundary_face_batches()));
297 info.cells_exterior.resize(v_len * data.n_inner_face_batches());
300 info.cells_fill.resize(data.n_cell_batches() +
301 data.n_ghost_cell_batches());
302 info.faces_fill.resize(data.n_inner_face_batches() +
303 data.n_boundary_face_batches());
306 info.interior_face_no.resize(data.n_inner_face_batches() +
307 data.n_boundary_face_batches());
308 info.exterior_face_no.resize(data.n_inner_face_batches());
309 info.exterior_face_no_ecl.resize(
310 dealii::GeometryInfo<dim>::faces_per_cell * v_len *
311 data.n_cell_batches());
314 info.face_orientation.resize(data.n_inner_face_batches() +
315 data.n_boundary_face_batches());
316 info.face_orientation_ecl.resize(
317 dealii::GeometryInfo<dim>::faces_per_cell * v_len *
318 data.n_cell_batches());
321 for (
unsigned int cell = 0;
322 cell < data.n_cell_batches() + data.n_ghost_cell_batches();
325 info.cells_fill[cell] = data.n_active_entries_per_cell_batch(cell);
329 for (; v < data.n_active_entries_per_cell_batch(cell); v++)
331 const auto c_it = data.get_cell_iterator(cell, v);
334 info.cells[cell * v_len + v] = cell_to_gid(c_it);
340 info.cells_lid[cell * v_len + v] =
342 .dof_indices_contiguous[2][cell * v_len + v] /
343 data.get_dofs_per_cell();
346 if (cell < data.n_cell_batches())
348 for (
unsigned int face_no = 0;
349 face_no < dealii::GeometryInfo<dim>::faces_per_cell;
352 const unsigned int n_index =
353 cell * v_len * dealii::GeometryInfo<dim>::faces_per_cell +
358 if (!c_it->has_periodic_neighbor(face_no) &&
359 c_it->at_boundary(face_no))
361 info.cells_exterior_ecl[n_index].gid = -1;
362 info.cells_exterior_ecl[n_index].rank = -1;
363 info.exterior_face_no_ecl[n_index] = -1;
364 info.face_orientation_ecl[n_index] = -1;
370 info.cells_exterior_ecl[n_index] =
371 cell_to_gid(c_it->neighbor_or_periodic_neighbor(face_no));
380 const unsigned int cell_this =
381 cell * VectorizedArrayType::size() + v;
383 const unsigned int face_index =
384 data.get_cell_and_face_to_plain_faces()(cell,
389 dealii::numbers::invalid_unsigned_int,
390 dealii::StandardExceptions::ExcNotInitialized());
392 const auto &faces = data.get_face_info(
393 face_index / VectorizedArrayType::size());
396 faces.cells_interior[face_index %
397 VectorizedArrayType::size()];
399 const bool is_interior_face =
400 (cell_m != cell_this) ||
401 ((cell_m == cell_this) &&
404 .get_face_info(face_index /
405 VectorizedArrayType::size())
408 info.exterior_face_no_ecl[n_index] =
409 is_interior_face ? faces.interior_face_no :
410 faces.exterior_face_no;
414 const bool fo_interior_face =
415 faces.face_orientation >= 8;
417 const unsigned int face_orientation =
418 faces.face_orientation % 8;
420 static const std::array<unsigned int, 8> table{
421 {0, 1, 2, 3, 6, 5, 4, 7}};
423 info.face_orientation_ecl[n_index] =
424 (is_interior_face != fo_interior_face) ?
425 table[face_orientation] :
429 info.face_orientation_ecl[n_index] = -1;
436 for (
unsigned int face = 0; face < data.n_inner_face_batches(); ++face)
439 info.faces_fill[face] = data.n_active_entries_per_face_batch(face);
442 info.interior_face_no[face] =
443 data.get_face_info(face).interior_face_no;
444 info.exterior_face_no[face] =
445 data.get_face_info(face).exterior_face_no;
448 info.face_orientation[face] =
449 data.get_face_info(face).face_orientation;
452 for (
unsigned int v = 0;
453 v < data.n_active_entries_per_face_batch(face);
456 const auto cell_m = data.get_face_info(face).cells_interior[v];
457 info.cells_interior[face * v_len + v] = cell_to_gid(
458 data.get_cell_iterator(cell_m / v_len, cell_m % v_len));
460 const auto cell_p = data.get_face_info(face).cells_exterior[v];
461 info.cells_exterior[face * v_len + v] = cell_to_gid(
462 data.get_cell_iterator(cell_p / v_len, cell_p % v_len));
467 for (
unsigned int face = data.n_inner_face_batches();
468 face < data.n_inner_face_batches() + data.n_boundary_face_batches();
471 info.faces_fill[face] = data.n_active_entries_per_face_batch(face);
473 info.interior_face_no[face] =
474 data.get_face_info(face).interior_face_no;
476 for (
unsigned int v = 0;
477 v < data.n_active_entries_per_face_batch(face);
480 const auto cell_m = data.get_face_info(face).cells_interior[v];
481 info.cells_interior[face * v_len + v] = cell_to_gid(
482 data.get_cell_iterator(cell_m / v_len, cell_m % v_len));
501 const MPI_Comm comm_x,
502 const MPI_Comm comm_v)
507 n1.resize(dealii::Utilities::MPI::n_mpi_processes(comm_x) + 1);
510 const unsigned int n_local = info_x.compute_n_cells();
514 &n_local, 1, MPI_UNSIGNED, n1.data() + 1, 1, MPI_UNSIGNED, comm_x);
517 for (
unsigned int i = 0; i < n1.size() - 1; i++)
523 n2.resize(dealii::Utilities::MPI::n_mpi_processes(comm_v) + 1);
524 unsigned int local = info_v.compute_n_cells();
526 &local, 1, MPI_UNSIGNED, n2.data() + 1, 1, MPI_UNSIGNED, comm_v);
527 for (
unsigned int i = 0; i < n2.size() - 1; i++)
539 const unsigned int gid1 = id1.
gid;
540 const unsigned int rank1 = id1.
rank;
541 const unsigned int gid2 = id2.
gid;
542 const unsigned int rank2 = id2.
rank;
544 Assert(rank1 !=
static_cast<unsigned int>(-1),
545 dealii::StandardExceptions::ExcNotImplemented());
546 Assert(rank2 !=
static_cast<unsigned int>(-1),
547 dealii::StandardExceptions::ExcNotImplemented());
549 AssertIndexRange(rank1 + 1, n1.size());
550 AssertIndexRange(rank2 + 1, n2.size());
553 const unsigned int lid1 = gid1 - n1[rank1];
554 const unsigned int lid2 = gid2 - n2[rank2];
557 const unsigned int lid = lid1 + lid2 * (n1[rank1 + 1] - n1[rank1]);
560 return {lid + n1.back() * n2[rank2] +
561 n1[rank1] * (n2[rank2 + 1] - n2[rank2]),
562 rank1 + ((
unsigned int)n1.size() - 1) * rank2};
566 std::vector<unsigned int> n1;
567 std::vector<unsigned int> n2;
571 combine_global_cell_info(
const MPI_Comm comm_x,
572 const MPI_Comm comm_v,
573 const GlobalCellInfo &info_x,
574 const GlobalCellInfo &info_v,
575 GlobalCellInfo & info,
580 info.max_batch_size = info_x.max_batch_size;
583 info.n_cell_batches =
584 info_x.compute_n_cell_batches() * info_v.compute_n_cells();
587 GlobaleCellIDTranslator translator(info_x, info_v, comm_x, comm_v);
590 const auto process = [&](
const unsigned int i_x,
591 const unsigned int i_v,
592 const unsigned int v_v) {
593 unsigned int v_x = 0;
594 for (; v_x < info_x.cells_fill[i_x]; v_x++)
596 const auto cell_x = info_x.cells[i_x * info_x.max_batch_size + v_x];
597 const auto cell_y = info_v.cells[i_v * info_v.max_batch_size + v_v];
598 info.cells.emplace_back(translator.translate(cell_x, cell_y));
600 for (; v_x < info_x.max_batch_size; v_x++)
601 info.cells.emplace_back(-1, -1);
603 info.cells_fill.push_back(info_x.cells_fill[i_x]);
606 const unsigned int n_cell_batches_x = info_x.compute_n_cell_batches();
607 const unsigned int n_cell_batches_v = info_v.compute_n_cell_batches();
609 const unsigned int n_cell_and_ghost_batches_x =
610 info_x.compute_n_cell_and_ghost_batches();
611 const unsigned int n_cell_and_ghost_batches_v =
612 info_v.compute_n_cell_and_ghost_batches();
615 for (
unsigned int i_v = 0; i_v < n_cell_batches_v; i_v++)
616 for (
unsigned int v_v = 0; v_v < info_v.cells_fill[i_v]; v_v++)
617 for (
unsigned int i_x = 0; i_x < n_cell_batches_x; i_x++)
618 process(i_x, i_v, v_v);
621 for (
unsigned int i_v = 0; i_v < n_cell_batches_v; i_v++)
622 for (
unsigned int v_v = 0; v_v < info_v.cells_fill[i_v]; v_v++)
623 for (
unsigned int i_x = 0; i_x < n_cell_batches_x; i_x++)
625 for (
int d = 0; d < 2 * dim_x; d++)
627 unsigned int v_x = 0;
628 for (; v_x < info_x.cells_fill[i_x]; v_x++)
630 const unsigned int index =
631 i_x * info_x.max_batch_size * 2 * dim_x +
632 d * info_x.max_batch_size + v_x;
633 const auto cell_x = info_x.cells_exterior_ecl[index];
635 info_v.cells[i_v * info_v.max_batch_size + v_v];
639 if (cell_x.gid ==
static_cast<decltype(cell_x.gid)
>(-1) ||
640 cell_y.gid ==
static_cast<decltype(cell_y.gid)
>(-1))
642 info.cells_exterior_ecl.emplace_back(-1, -1);
643 info.exterior_face_no_ecl.emplace_back(-1);
644 info.face_orientation_ecl.emplace_back(-1);
648 info.cells_exterior_ecl.emplace_back(
649 translator.translate(cell_x, cell_y));
650 info.exterior_face_no_ecl.emplace_back(
651 info_x.exterior_face_no_ecl[index]);
652 info.face_orientation_ecl.emplace_back(
653 info_x.face_orientation_ecl[index]);
655 for (; v_x < info_x.max_batch_size; v_x++)
657 info.cells_exterior_ecl.emplace_back(-1, -1);
658 info.exterior_face_no_ecl.emplace_back(-1);
659 info.face_orientation_ecl.emplace_back(-1);
663 for (
int d = 0; d < 2 * dim_v; d++)
665 unsigned int v_x = 0;
666 for (; v_x < info_x.cells_fill[i_x]; v_x++)
668 const unsigned index =
669 i_v * info_v.max_batch_size * 2 * dim_v +
670 d * info_v.max_batch_size + v_v;
672 info_x.cells[i_x * info_x.max_batch_size + v_x];
673 const auto cell_y = info_v.cells_exterior_ecl[index];
677 if (cell_x.gid ==
static_cast<decltype(cell_x.gid)
>(-1) ||
678 cell_y.gid ==
static_cast<decltype(cell_y.gid)
>(-1))
680 info.cells_exterior_ecl.emplace_back(-1, -1);
681 info.exterior_face_no_ecl.emplace_back(-1);
682 info.face_orientation_ecl.emplace_back(-1);
686 info.cells_exterior_ecl.emplace_back(
687 translator.translate(cell_x, cell_y));
688 info.exterior_face_no_ecl.emplace_back(
689 info_v.exterior_face_no_ecl[index] + 2 * dim_x);
690 info.face_orientation_ecl.emplace_back(
691 info_v.face_orientation_ecl[index]);
693 for (; v_x < info_x.max_batch_size; v_x++)
695 info.cells_exterior_ecl.emplace_back(-1, -1);
696 info.exterior_face_no_ecl.emplace_back(-1);
697 info.face_orientation_ecl.emplace_back(-1);
703 for (
unsigned int i_v = 0; i_v < n_cell_batches_v; i_v++)
704 for (
unsigned int v_v = 0; v_v < info_v.cells_fill[i_v]; v_v++)
705 for (
unsigned int i_x = n_cell_batches_x;
706 i_x < n_cell_and_ghost_batches_x;
708 process(i_x, i_v, v_v);
711 for (
unsigned int i_v = n_cell_batches_v;
712 i_v < n_cell_and_ghost_batches_v;
714 for (
unsigned int v_v = 0; v_v < info_v.cells_fill[i_v]; v_v++)
715 for (
unsigned int i_x = 0; i_x < n_cell_batches_x; i_x++)
716 process(i_x, i_v, v_v);
720 const unsigned int n_face_batches_x = info_x.exterior_face_no.size();
721 const unsigned int n_face_batches_v = info_v.exterior_face_no.size();
723 const unsigned int n_face_batches_x_all =
724 info_x.interior_face_no.size();
725 const unsigned int n_face_batches_v_all =
726 info_v.interior_face_no.size();
728 for (
unsigned int i_v = 0; i_v < n_cell_batches_v; i_v++)
729 for (
unsigned int v_v = 0; v_v < info_v.cells_fill[i_v]; v_v++)
730 for (
unsigned int i_x = 0; i_x < n_face_batches_x; i_x++)
732 unsigned int v_x = 0;
733 for (; v_x < info_x.faces_fill[i_x]; v_x++)
736 info_v.cells[i_v * info_v.max_batch_size + v_v];
737 info.cells_interior.emplace_back(translator.translate(
738 info_x.cells_interior[i_x * info_x.max_batch_size + v_x],
740 info.cells_exterior.emplace_back(translator.translate(
741 info_x.cells_exterior[i_x * info_x.max_batch_size + v_x],
744 for (; v_x < info_x.max_batch_size; v_x++)
746 info.cells_interior.emplace_back(-1, -1);
747 info.cells_exterior.emplace_back(-1, -1);
750 info.faces_fill.push_back(info_x.faces_fill[i_x]);
752 info.interior_face_no.push_back(info_x.interior_face_no[i_x]);
753 info.exterior_face_no.push_back(info_x.exterior_face_no[i_x]);
754 info.face_orientation.push_back(info_x.face_orientation[i_x]);
758 for (
unsigned int i_v = 0; i_v < n_face_batches_v; i_v++)
759 for (
unsigned int v_v = 0; v_v < info_v.faces_fill[i_v]; v_v++)
760 for (
unsigned int i_x = 0; i_x < n_cell_batches_x; i_x++)
762 unsigned int v_x = 0;
763 for (; v_x < info_x.cells_fill[i_x]; v_x++)
766 info_x.cells[i_x * info_x.max_batch_size + v_x];
767 info.cells_interior.emplace_back(translator.translate(
770 .cells_interior[i_v * info_v.max_batch_size + v_v]));
771 info.cells_exterior.emplace_back(translator.translate(
774 .cells_exterior[i_v * info_v.max_batch_size + v_v]));
776 for (; v_x < info_x.max_batch_size; v_x++)
778 info.cells_interior.emplace_back(-1, -1);
779 info.cells_exterior.emplace_back(-1, -1);
782 info.faces_fill.push_back(info_x.cells_fill[i_x]);
784 info.interior_face_no.push_back(info_v.interior_face_no[i_v] +
786 info.exterior_face_no.push_back(info_v.exterior_face_no[i_v] +
788 info.face_orientation.push_back(info_v.face_orientation[i_v]);
791 for (
unsigned int i_v = 0; i_v < n_cell_batches_v; i_v++)
792 for (
unsigned int v_v = 0; v_v < info_v.cells_fill[i_v]; v_v++)
793 for (
unsigned int i_x = n_face_batches_x;
794 i_x < n_face_batches_x_all;
797 unsigned int v_x = 0;
798 for (; v_x < info_x.faces_fill[i_x]; v_x++)
801 info_x.cells_interior[i_x * info_x.max_batch_size + v_x];
803 info_v.cells[i_v * info_v.max_batch_size + v_v];
804 info.cells_interior.emplace_back(
805 translator.translate(cell_x, cell_y));
807 for (; v_x < info_x.max_batch_size; v_x++)
808 info.cells_interior.emplace_back(-1, -1);
810 info.faces_fill.push_back(info_x.faces_fill[i_x]);
812 info.interior_face_no.push_back(info_x.interior_face_no[i_x]);
813 info.face_orientation.push_back(info_x.face_orientation[i_x]);
817 for (
unsigned int i_v = n_face_batches_v; i_v < n_face_batches_v_all;
819 for (
unsigned int v_v = 0; v_v < info_v.faces_fill[i_v]; v_v++)
820 for (
unsigned int i_x = 0; i_x < n_cell_batches_x; i_x++)
822 unsigned int v_x = 0;
823 for (; v_x < info_x.cells_fill[i_x]; v_x++)
826 info_x.cells[i_x * info_x.max_batch_size + v_x];
828 info_v.cells_interior[i_v * info_v.max_batch_size + v_v];
829 info.cells_interior.emplace_back(
830 translator.translate(cell_x, cell_y));
832 for (; v_x < info_x.max_batch_size; v_x++)
833 info.cells_interior.emplace_back(-1, -1);
835 info.faces_fill.push_back(info_x.cells_fill[i_x]);
837 info.interior_face_no.push_back(info_v.interior_face_no[i_v] +
839 info.face_orientation.push_back(info_v.face_orientation[i_v]);
846 template <
int dim_x,
int dim_v,
typename Number,
typename VectorizedArrayType>
849 const MPI_Comm comm_sm,
850 const dealii::MatrixFree<dim_x, Number, VectorizedArrayTypeX>
852 const dealii::MatrixFree<dim_v, Number, VectorizedArrayTypeV>
856 , matrix_free_x(matrix_free_x)
857 , matrix_free_v(matrix_free_v)
860 template <
int dim_x,
int dim_v,
typename Number,
typename VectorizedArrayType>
868 this->use_ecl = additional_data.
use_ecl;
870 AssertThrow(this->do_ghost_faces,
872 "At the moment only ghost faces are supported!"));
874 AssertThrow(this->use_ecl || ( this->do_buffering),
875 dealii::ExcMessage(
"FCL needs buffering!"));
877 AssertDimension(matrix_free_x.get_shape_info().n_components, 1);
878 AssertDimension(matrix_free_v.get_shape_info().n_components, 1);
879 AssertDimension(matrix_free_x.get_shape_info().data.front().fe_degree,
880 matrix_free_v.get_shape_info().data.front().fe_degree);
882 const int dim = dim_x + dim_v;
885 this->shape_info.template reinit<dim_x, dim_v>(
886 matrix_free_x.get_shape_info().data.front().fe_degree);
889 const auto info = [&]() {
893 internal::collect_global_cell_info(matrix_free_x, info_x);
896 internal::collect_global_cell_info(matrix_free_v, info_v);
899 internal::combine_global_cell_info(
900 matrix_free_x.get_task_info().communicator,
901 matrix_free_v.get_task_info().communicator,
912 this->partitioner = [&] {
913 AssertThrow(do_ghost_faces,
914 dealii::StandardExceptions::ExcNotImplemented());
916 auto partitioner =
new dealii::internal::MatrixFreeFunctions::
917 VectorDataExchange::Contiguous(shape_info);
920 std::vector<dealii::types::global_dof_index> local_list;
922 std::pair<dealii::types::global_dof_index, std::vector<unsigned int>>>
927 for (
unsigned int i = 0; i < info.n_cell_batches; i++)
928 for (
unsigned int v = 0; v < info.cells_fill[i]; v++)
929 local_list.emplace_back(
930 info.cells[i * info.max_batch_size + v].gid);
931 std::sort(local_list.begin(), local_list.end());
942 std::sort(ghost_faces.begin(),
944 [](
const auto &a,
const auto &b) {
950 if (a.gid == b.gid && a.no < b.no)
957 if (ghost_faces.size() > 0)
959 auto ptr = ghost_faces.begin();
961 ghost_list.emplace_back(ptr->gid,
962 std::vector<unsigned int>{ptr->no});
965 for (; ptr != ghost_faces.end(); ptr++)
967 if (ghost_list.back().first == ptr->gid)
968 ghost_list.back().second.emplace_back(ptr->no);
970 ghost_list.emplace_back(ptr->gid,
971 std::vector<unsigned int>{ptr->no});
977 partitioner->reinit(local_list, ghost_list, comm, comm_sm, do_buffering);
979 return std::shared_ptr<
980 const dealii::internal::MatrixFreeFunctions::VectorDataExchange::Base>(
990 std::array<std::vector<unsigned int>, 4> dof_indices_contiguous;
994 auto &n_vectorization_lanes_filled =
995 dof_info.n_vectorization_lanes_filled;
996 auto &no_faces = face_info.no_faces;
997 auto &face_orientations = face_info.face_orientations;
1001 for (
unsigned int i = 0; i < info.interior_face_no.size(); i++)
1002 for (
unsigned int v = 0; v < info.max_batch_size; v++)
1003 dof_indices_contiguous[0].push_back(
1004 info.cells_interior[i * info.max_batch_size + v].gid);
1005 for (
unsigned int i = 0; i < info.exterior_face_no.size(); i++)
1006 for (
unsigned int v = 0; v < info.max_batch_size; v++)
1007 dof_indices_contiguous[1].push_back(
1008 info.cells_exterior[i * info.max_batch_size + v].gid);
1009 for (
unsigned int i = 0; i < info.n_cell_batches; i++)
1010 for (
unsigned int v = 0; v < info.max_batch_size; v++)
1011 dof_indices_contiguous[2].push_back(
1012 info.cells[i * info.max_batch_size + v].gid);
1013 for (
unsigned int i = 0; i < info.n_cell_batches; i++)
1014 for (
unsigned int d = 0;
1015 d < dealii::GeometryInfo<dim>::faces_per_cell;
1017 for (
unsigned int v = 0; v < info.max_batch_size; v++)
1018 dof_indices_contiguous[3].push_back(
1021 [i * info.max_batch_size *
1022 dealii::GeometryInfo<dim>::faces_per_cell +
1023 d * info.max_batch_size + v]
1029 for (
unsigned int i = 0; i < info.interior_face_no.size(); i++)
1030 n_vectorization_lanes_filled[0].push_back(info.faces_fill[i]);
1032 for (
unsigned int i = 0; i < info.exterior_face_no.size(); i++)
1033 n_vectorization_lanes_filled[1].push_back(info.faces_fill[i]);
1035 for (
unsigned int i = 0; i < info.n_cell_batches; i++)
1036 n_vectorization_lanes_filled[2].push_back(info.cells_fill[i]);
1040 for (
unsigned int i = 0; i < info.n_cell_batches; i++)
1041 for (
unsigned int d = 0;
1042 d < dealii::GeometryInfo<dim>::faces_per_cell;
1044 n_vectorization_lanes_filled[3].push_back(info.cells_fill[i]);
1049 no_faces[0] = info.interior_face_no;
1050 no_faces[1] = info.exterior_face_no;
1051 no_faces[3] = info.exterior_face_no_ecl;
1056 face_orientations[0] = info.face_orientation;
1057 face_orientations[3] = info.face_orientation_ecl;
1065 const auto &vectorization_length = dof_info.n_vectorization_lanes_filled;
1066 const auto &no_faces = face_info.no_faces;
1067 const auto &face_orientations = face_info.face_orientations;
1070 dynamic_cast<const dealii::internal::MatrixFreeFunctions::
1071 VectorDataExchange::Contiguous *
>(partitioner.get())
1073 const auto &maps_ghost =
1074 dynamic_cast<const dealii::internal::MatrixFreeFunctions::
1075 VectorDataExchange::Contiguous *
>(partitioner.get())
1078 static const int v_len = VectorizedArrayType::size();
1081 auto &cell_ptrs = dof_info.dof_indices_contiguous_ptr;
1082 auto &face_type = face_info.face_type;
1083 auto &face_all = face_info.face_all;
1086 for (
unsigned int i = 0; i < 4; i++)
1087 cell_ptrs[i].resize(dof_indices_contiguous[i].size());
1089 for (
unsigned int i = 0; i < 4; i++)
1090 face_type[i].resize(i == 2 ? 0 : dof_indices_contiguous[i].size());
1092 for (
unsigned int i = 0; i < 4; i++)
1093 face_all[i].resize(i == 2 ? 0 : vectorization_length[i].size());
1096 for (
unsigned int i = 0; i < 4; i++)
1101 for (
unsigned int j = 0; j < vectorization_length[i].size(); j++)
1102 for (
unsigned int v = 0; v < vectorization_length[i][j]; v++)
1104 const unsigned int l = j * v_len + v;
1105 Assert(l < dof_indices_contiguous[i].size(),
1106 dealii::StandardExceptions::ExcMessage(
1107 "Size of gid does not match."));
1108 const unsigned int gid_this = dof_indices_contiguous[i][l];
1111 if (gid_this == dealii::numbers::invalid_unsigned_int)
1114 const auto ptr1 = maps_ghost.find(
1116 do_ghost_faces ? no_faces[i][i == 3 ? l : j] :
1117 dealii::numbers::invalid_unsigned_int});
1119 if (ptr1 != maps_ghost.end())
1121 cell_ptrs[i][l] = {ptr1->second.first, ptr1->second.second};
1122 face_type[i][l] =
true;
1126 const auto ptr2 = maps.find(gid_this);
1128 if (ptr2 != maps.end())
1130 cell_ptrs[i][l] = {ptr2->second.first, ptr2->second.second};
1131 face_type[i][l] =
false;
1136 dealii::StandardExceptions::ExcMessage(
1137 "Cell not found!"));
1142 for (
unsigned int i = 0; i < 4; i++)
1147 for (
unsigned int j = 0; j < vectorization_length[i].size(); j++)
1150 for (
unsigned int v = 0; v < vectorization_length[i][j]; v++)
1152 (face_type[i][j * v_len] == face_type[i][j * v_len + v]) &&
1154 ((no_faces[i][j * v_len] == no_faces[i][j * v_len + v]) &&
1155 (face_orientations[i][j * v_len] ==
1156 face_orientations[i][j * v_len + v])) :
1158 face_all[i][j] = temp;
1163 for (
unsigned int j = 0; j < vectorization_length[2].size(); j++)
1164 for (
unsigned int v = 0; v < vectorization_length[2][j]; v++)
1166 const unsigned int l = j * v_len + v;
1167 const unsigned int gid_this = dof_indices_contiguous[2][l];
1168 const auto ptr = maps.find(gid_this);
1170 cell_ptrs[2][l] = {ptr->second.first, ptr->second.second};
1175 dof_info.n_vectorization_lanes_filled[3].clear();
1181 for (
auto &partition : partitions)
1184 const unsigned int v_len = VectorizedArrayTypeV::size();
1185 const auto my_rank = dealii::Utilities::MPI::this_mpi_process(comm);
1186 const auto sm_ranks_vec = mpi::procs_of_sm(comm, comm_sm);
1187 const std::set<unsigned int> sm_ranks(sm_ranks_vec.begin(),
1188 sm_ranks_vec.end());
1190 const unsigned int n_cell_batches_x = matrix_free_x.n_cell_batches();
1191 const unsigned int n_cell_batches_v = matrix_free_v.n_cell_batches();
1194 const unsigned int overlapping_level =
1197 for (
unsigned int j = 0, i0 = 0; j < n_cell_batches_v; j++)
1198 for (
unsigned int v = 0;
1199 v < matrix_free_v.n_active_entries_per_cell_batch(j);
1201 for (
unsigned int i = 0; i < n_cell_batches_x; i++, i0++)
1203 unsigned int flag = 0;
1204 for (
unsigned int d = 0;
1205 d < dealii::GeometryInfo<dim>::faces_per_cell;
1207 for (
unsigned int v = 0;
1208 v < dof_info.n_vectorization_lanes_filled[2][i0];
1214 [i0 * info.max_batch_size *
1215 dealii::GeometryInfo<dim>::faces_per_cell +
1216 d * info.max_batch_size + v]
1219 if (overlapping_level >= 1 && gid == my_rank)
1220 flag = std::max(flag, 0u);
1221 else if (overlapping_level == 2 &&
1222 sm_ranks.find(gid) != sm_ranks.end())
1223 flag = std::max(flag, 1u);
1225 flag = std::max(flag, 2u);
1228 partitions[flag].emplace_back(i, j * v_len + v, i0);
1231 if (dealii::Utilities::MPI::this_mpi_process(comm) == 0)
1232 std::cout << partitions[0].size() <<
" " << partitions[1].size()
1233 <<
" " << partitions[2].size() <<
" " << std::endl;
1239 template <
typename Number>
1244 const dealii::internal::MatrixFreeFunctions::VectorDataExchange::Base>
1246 : partitioner(partitioner)
1249 template <
typename VectorType>
1251 export_to_ghosted_array_start(VectorType &vec)
1253 buffer.resize_fast(this->partitioner->n_import_indices());
1255 this->partitioner->export_to_ghosted_array_start(
1257 dealii::ArrayView<const Number>(
1258 vec.begin(), this->partitioner->locally_owned_size()),
1259 vec.shared_vector_data(),
1260 dealii::ArrayView<Number>(
const_cast<Number *
>(vec.begin()) +
1261 this->partitioner->locally_owned_size(),
1262 this->partitioner->n_ghost_indices()),
1263 dealii::ArrayView<Number>(buffer.begin(), buffer.size()),
1267 template <
typename VectorType>
1269 export_to_ghosted_array_finish(VectorType &vec)
1271 AssertDimension(buffer.size(), this->partitioner->n_import_indices());
1273 this->partitioner->export_to_ghosted_array_finish(
1274 dealii::ArrayView<const Number>(
1275 vec.begin(), this->partitioner->locally_owned_size()),
1276 vec.shared_vector_data(),
1277 dealii::ArrayView<Number>(
const_cast<Number *
>(vec.begin()) +
1278 this->partitioner->locally_owned_size(),
1279 this->partitioner->n_ghost_indices()),
1283 template <
typename VectorType>
1285 export_to_ghosted_array_finish_0(VectorType &vec)
1288 dynamic_cast<const dealii::internal::MatrixFreeFunctions::
1289 VectorDataExchange::Contiguous *
>(partitioner.get());
1291 part->export_to_ghosted_array_finish_0(
1292 dealii::ArrayView<const Number>(
1293 const_cast<Number *
>(vec.begin()),
1294 this->partitioner->locally_owned_size()),
1295 vec.shared_vector_data(),
1296 dealii::ArrayView<Number>(
const_cast<Number *
>(vec.begin()) +
1297 this->partitioner->locally_owned_size(),
1298 this->partitioner->n_ghost_indices()),
1302 template <
typename VectorType>
1304 export_to_ghosted_array_finish_1(VectorType &vec)
1307 dynamic_cast<const dealii::internal::MatrixFreeFunctions::
1308 VectorDataExchange::Contiguous *
>(partitioner.get());
1310 part->export_to_ghosted_array_finish_1(
1311 dealii::ArrayView<const Number>(
1312 vec.begin(), this->partitioner->locally_owned_size()),
1313 vec.shared_vector_data(),
1314 dealii::ArrayView<Number>(
const_cast<Number *
>(vec.begin()) +
1315 this->partitioner->locally_owned_size(),
1316 this->partitioner->n_ghost_indices()),
1320 template <
typename VectorType>
1322 import_from_ghosted_array_start(VectorType &vec)
1324 buffer.resize_fast(this->partitioner->n_import_indices());
1326 this->partitioner->import_from_ghosted_array_start(
1327 dealii::VectorOperation::values::add,
1329 dealii::ArrayView<const Number>(
1330 vec.begin(), this->partitioner->locally_owned_size()),
1331 vec.shared_vector_data(),
1332 dealii::ArrayView<Number>(vec.begin() +
1333 this->partitioner->locally_owned_size(),
1334 this->partitioner->n_ghost_indices()),
1335 dealii::ArrayView<Number>(buffer.begin(), buffer.size()),
1339 template <
typename VectorType>
1341 import_from_ghosted_array_finish(VectorType &vec)
1343 AssertDimension(buffer.size(), this->partitioner->n_import_indices());
1345 this->partitioner->import_from_ghosted_array_finish(
1346 dealii::VectorOperation::values::add,
1347 dealii::ArrayView<Number>(vec.begin(),
1348 this->partitioner->locally_owned_size()),
1349 vec.shared_vector_data(),
1350 dealii::ArrayView<Number>(vec.begin() +
1351 this->partitioner->locally_owned_size(),
1352 this->partitioner->n_ghost_indices()),
1353 dealii::ArrayView<const Number>(buffer.begin(), buffer.size()),
1357 const std::shared_ptr<
1358 const dealii::internal::MatrixFreeFunctions::VectorDataExchange::Base>
1361 dealii::AlignedVector<Number> buffer;
1362 std::vector<MPI_Request> requests;
1367 template <
int dim_x,
int dim_v,
typename Number,
typename VectorizedArrayType>
1370 dealii::LinearAlgebra::distributed::Vector<Number> &vec,
1371 const unsigned int dof_handler_index,
1372 const bool do_ghosts,
1373 const bool zero_out_values)
const
1375 AssertThrow(dof_handler_index == 0,
1377 "Only one dof_handler supported at the moment!"));
1379 AssertThrow((partitioner !=
nullptr),
1380 dealii::ExcMessage(
"Partitioner has not been initialized!"));
1383 vec.reinit(partitioner->locally_owned_size(),
1384 do_ghosts ? partitioner->n_ghost_indices() : 0,
1389 if (zero_out_values)
1393 if (zero_out_values && do_ghosts)
1395 vec.zero_out_ghost_values();
1399 data_exchanger.export_to_ghosted_array_start(vec);
1400 data_exchanger.export_to_ghosted_array_finish(vec);
1402 vec.zero_out_ghost_values();
1406 if (zero_out_values && do_ghosts && !use_ecl)
1410 data_exchanger.import_from_ghosted_array_start(vec);
1411 data_exchanger.import_from_ghosted_array_finish(vec);
1417 template <
int dim_x,
int dim_v,
typename Number,
typename VectorizedArrayType>
1418 template <
typename OutVector,
typename InVector>
1421 const std::function<
1422 void(
const MatrixFree &, OutVector &,
const InVector &,
const ID)>
1425 const InVector &src)
const
1427 unsigned int v_len = VectorizedArrayTypeV::size();
1429 const unsigned int n_cell_batches_x = matrix_free_x.n_cell_batches();
1430 const unsigned int n_cell_batches_v = matrix_free_v.n_cell_batches();
1432 unsigned int i0 = 0;
1434 for (
unsigned int j = 0; j < n_cell_batches_v; j++)
1435 for (
unsigned int v = 0;
1436 v < matrix_free_v.n_active_entries_per_cell_batch(j);
1438 for (
unsigned int i = 0; i < n_cell_batches_x; i++)
1439 cell_operation(*
this, dst, src,
ID(i, j * v_len + v, i0++));
1444 template <
int dim_x,
int dim_v,
typename Number,
typename VectorizedArrayType>
1445 template <
typename CLASS,
typename OutVector,
typename InVector>
1448 void (CLASS::*cell_operation)(
const MatrixFree &,
1452 CLASS * owning_class,
1454 const InVector &src)
const
1456 this->
template cell_loop<OutVector, InVector>(
1457 [&cell_operation, &owning_class](
const MatrixFree &mf,
1459 const InVector & src,
1461 (owning_class->*cell_operation)(mf, dst, src,
id);
1467 template <
int dim_x,
int dim_v,
typename Number,
typename VectorizedArrayType>
1468 template <
typename CLASS,
typename OutVector,
typename InVector>
1471 void (CLASS::*cell_operation)(
const MatrixFree &,
1475 CLASS * owning_class,
1477 const InVector & src,
1481 this->
template loop_cell_centric<OutVector, InVector>(
1482 [&cell_operation, &owning_class](
const MatrixFree &mf,
1484 const InVector & src,
1486 (owning_class->*cell_operation)(mf, dst, src,
id);
1490 src_vector_face_access,
1494 template <
int dim_x,
int dim_v,
typename Number,
typename VectorizedArrayType>
1495 template <
typename OutVector,
typename InVector>
1498 const std::function<
1499 void(
const MatrixFree &, OutVector &,
const InVector &,
const ID)>
1502 const InVector & src,
1506 AssertThrow(src_vector_face_access == DataAccessOnFaces::values ||
1507 src_vector_face_access == DataAccessOnFaces::none,
1508 dealii::StandardExceptions::ExcNotImplemented());
1516 for (
unsigned int i = 0; i < this->partitions.size(); ++i)
1519 if (src_vector_face_access == DataAccessOnFaces::values)
1523 if (timers !=
nullptr)
1524 timers->operator[](
"update_ghost_values_0").start();
1527 data_exchanger.export_to_ghosted_array_start(src);
1530 if (dst.has_ghost_elements())
1531 dst.zero_out_ghost_values();
1537 data_exchanger.export_to_ghosted_array_finish_0(src);
1539 if (timers !=
nullptr)
1541 timers->operator[](
"update_ghost_values_0").stop();
1542 timers->operator[](
"update_ghost_values_1").start();
1548 data_exchanger.export_to_ghosted_array_finish_1(src);
1550 if (timers !=
nullptr)
1552 timers->operator[](
"update_ghost_values_1").stop();
1553 timers->operator[](
"update_ghost_values_2").start();
1559 dealii::StandardExceptions::ExcNotImplemented());
1564 for (
const auto &
id : this->partitions[i])
1565 cell_operation(*
this, dst, src,
id);
1569 if (timers !=
nullptr)
1570 timers->operator[](
"update_ghost_values_2").stop();
1572 if (do_buffering ==
false &&
1573 src_vector_face_access == DataAccessOnFaces::values)
1577 dynamic_cast<const dealii::internal::MatrixFreeFunctions::
1578 VectorDataExchange::Contiguous *
>(partitioner.get())
1583 template <
int dim_x,
int dim_v,
typename Number,
typename VectorizedArrayType>
1584 template <
typename CLASS,
typename OutVector,
typename InVector>
1587 void (CLASS::*cell_operation)(
const MatrixFree &,
1591 void (CLASS::*face_operation)(
const MatrixFree &,
1595 void (CLASS::*boundary_operation)(
const MatrixFree &,
1599 CLASS * owning_class,
1601 const InVector & src,
1606 this->
template loop<OutVector, InVector>(
1607 [&cell_operation, &owning_class](
const MatrixFree &mf,
1609 const InVector & src,
1611 (owning_class->*cell_operation)(mf, dst, src,
id);
1613 [&face_operation, &owning_class](
const MatrixFree &mf,
1615 const InVector & src,
1617 (owning_class->*face_operation)(mf, dst, src,
id);
1619 [&boundary_operation, &owning_class](
const MatrixFree &mf,
1621 const InVector & src,
1623 (owning_class->*boundary_operation)(mf, dst, src,
id);
1627 dst_vector_face_access,
1628 src_vector_face_access,
1634 template <
int dim_x,
int dim_v,
typename Number,
typename VectorizedArrayType>
1635 template <
typename OutVector,
typename InVector>
1638 const std::function<
1639 void(
const MatrixFree &, OutVector &,
const InVector &,
const ID)>
1641 const std::function<
1642 void(
const MatrixFree &, OutVector &,
const InVector &,
const ID)>
1644 const std::function<
1645 void(
const MatrixFree &, OutVector &,
const InVector &,
const ID)>
1646 & boundary_operation,
1648 const InVector & src,
1653 if (src_vector_face_access == DataAccessOnFaces::values)
1659 data_exchanger.export_to_ghosted_array_start(src);
1660 data_exchanger.export_to_ghosted_array_finish(src);
1663 AssertThrow(
false, dealii::StandardExceptions::ExcNotImplemented());
1667 dst.zero_out_ghost_values();
1670 unsigned int v_len = VectorizedArrayTypeV::size();
1672 const unsigned int n_cell_batches_x = matrix_free_x.n_cell_batches();
1673 const unsigned int n_inner_face_batches_x =
1674 matrix_free_x.n_inner_face_batches();
1675 const unsigned int n_inner_boundary_batches_x =
1676 matrix_free_x.n_boundary_face_batches();
1677 const unsigned int n_inner_or_boundary_face_batches_x =
1678 n_inner_face_batches_x + n_inner_boundary_batches_x;
1680 const unsigned int n_cell_batches_v = matrix_free_v.n_cell_batches();
1681 const unsigned int n_inner_face_batches_v =
1682 matrix_free_v.n_inner_face_batches();
1683 const unsigned int n_inner_boundary_batches_v =
1684 matrix_free_v.n_boundary_face_batches();
1685 const unsigned int n_inner_or_boundary_face_batches_v =
1686 n_inner_face_batches_v + n_inner_boundary_batches_v;
1688 unsigned int i0 = 0;
1689 unsigned int i1 = 0;
1696 for(
unsigned int j = 0; j < n_cell_batches_v; j++)
1697 for(
unsigned int v = 0; v < matrix_free_v.n_active_entries_per_cell_batch(j); v++)
1698 for(
unsigned int i = 0; i < n_cell_batches_x; i++)
1699 cell_operation(*
this, dst, src,
ID(i, j * v_len + v, i0++));
1705 for(
unsigned int j = 0; j < n_cell_batches_v; j++)
1706 for(
unsigned int v = 0; v < matrix_free_v.n_active_entries_per_cell_batch(j); v++)
1707 for(
unsigned int i = 0; i < n_inner_face_batches_x; i++)
1708 face_operation(*
this, dst, src,
ID(i, j * v_len + v, i1++, ID::SpaceType::X));
1710 for(
unsigned int j = 0; j < n_inner_face_batches_v; j++)
1713 for(
unsigned int v = 0; v < matrix_free_v.n_active_entries_per_face_batch(j); v++)
1714 for(
unsigned int i = 0; i < n_cell_batches_x; i++)
1715 face_operation(*
this, dst, src,
ID(i, j * v_len + v, i1++, ID::SpaceType::V));
1721 for(
unsigned int j = 0; j < n_cell_batches_v; j++)
1722 for(
unsigned int v = 0; v < matrix_free_v.n_active_entries_per_cell_batch(j); v++)
1723 for(
unsigned int i = n_inner_face_batches_x; i < n_inner_or_boundary_face_batches_x; i++)
1724 boundary_operation(*
this, dst, src,
ID(i, j * v_len + v, i1++, ID::SpaceType::X));
1728 for(
unsigned int j = n_inner_face_batches_v; j < n_inner_or_boundary_face_batches_v; j++)
1729 for(
unsigned int v = 0; v < matrix_free_v.n_active_entries_per_face_batch(j); v++)
1730 for(
unsigned int i = 0; i < n_cell_batches_x; i++)
1731 boundary_operation(*
this, dst, src,
ID(i, j * v_len + v, i1++, ID::SpaceType::V));
1735 if (dst_vector_face_access == DataAccessOnFaces::values)
1741 data_exchanger.import_from_ghosted_array_start(dst);
1742 data_exchanger.import_from_ghosted_array_finish(dst);
1745 AssertThrow(
false, dealii::StandardExceptions::ExcNotImplemented());
1750 template <
int dim_x,
int dim_v,
typename Number,
typename VectorizedArrayType>
1760 template <
int dim_x,
int dim_v,
typename Number,
typename VectorizedArrayType>
1761 dealii::types::boundary_id
1763 const ID macro_face)
const
1765 if (macro_face.
type == TensorID::SpaceType::X)
1766 return matrix_free_x.get_boundary_id(macro_face.
x);
1767 else if (macro_face.
type == TensorID::SpaceType::V)
1768 return matrix_free_v.get_boundary_id(macro_face.
v /
1769 VectorizedArrayTypeV::size());
1771 Assert(
false, dealii::StandardExceptions::ExcInternalError());
1778 template <
int dim_x,
int dim_v,
typename Number,
typename VectorizedArrayType>
1779 dealii::types::boundary_id
1782 const unsigned int face_number)
const
1784 if (face_number < 2 * dim_x)
1787 matrix_free_x.get_faces_by_cells_boundary_id(macro_cell.
x,
1791 for (
unsigned int v = 0;
1792 v < matrix_free_x.n_active_entries_per_cell_batch(macro_cell.
x);
1794 AssertDimension(bids[0], bids[v]);
1799 else if (face_number < 2 * dim_x + 2 * dim_v)
1802 matrix_free_v.get_faces_by_cells_boundary_id(macro_cell.
v,
1803 face_number - dim_x * 2);
1806 for (
unsigned int v = 0;
1807 v < matrix_free_v.n_active_entries_per_cell_batch(macro_cell.
v);
1809 AssertDimension(bids[0], bids[v]);
1815 Assert(
false, dealii::StandardExceptions::ExcInternalError());
1822 template <
int dim_x,
int dim_v,
typename Number,
typename VectorizedArrayType>
1832 template <
int dim_x,
int dim_v,
typename Number,
typename VectorizedArrayType>
1837 return do_ghost_faces;
1842 template <
int dim_x,
int dim_v,
typename Number,
typename VectorizedArrayType>
1843 const dealii::MatrixFree<
1847 VectorizedArrayTypeX> &
1851 return matrix_free_x;
1856 template <
int dim_x,
int dim_v,
typename Number,
typename VectorizedArrayType>
1857 const dealii::MatrixFree<
1861 VectorizedArrayTypeV> &
1865 return matrix_free_v;
1870 template <
int dim_x,
int dim_v,
typename Number,
typename VectorizedArrayType>
1879 template <
int dim_x,
int dim_v,
typename Number,
typename VectorizedArrayType>
1888 template <
int dim_x,
int dim_v,
typename Number,
typename VectorizedArrayType>
1897 template <
int dim_x,
int dim_v,
typename Number,
typename VectorizedArrayType>
1904 mem.insert(
"dof_info", dof_info.memory_consumption());
1905 mem.insert(
"face_info", face_info.memory_consumption());
1906 mem.insert(
"shape_info", shape_info.memory_consumption());
1913 template <
int dim_x,
int dim_v,
typename Number,
typename VectorizedArrayType>
1914 const std::shared_ptr<
1915 const dealii::internal::MatrixFreeFunctions::VectorDataExchange::Base> &
Definition matrix_free.h:40
const MPI_Comm & get_communicator() const
Definition matrix_free.templates.h:1752
const dealii::MatrixFree< dim_v, Number, VectorizedArrayTypeV > & get_matrix_free_v() const
Definition matrix_free.templates.h:1862
void cell_loop(const std::function< void(const MatrixFree &, OutVector &, const InVector &, const ID)> &cell_operation, OutVector &dst, const InVector &src) const
Definition matrix_free.templates.h:1420
MemoryConsumption memory_consumption() const
Definition matrix_free.templates.h:1899
MatrixFree(const MPI_Comm comm, const MPI_Comm comm_sm, const dealii::MatrixFree< dim_x, Number, VectorizedArrayTypeX > &matrix_free_x, const dealii::MatrixFree< dim_v, Number, VectorizedArrayTypeV > &matrix_free_v)
Definition matrix_free.templates.h:847
DataAccessOnFaces
Definition matrix_free.h:53
bool is_ecl_supported() const
Definition matrix_free.templates.h:1824
const internal::MatrixFreeFunctions::DoFInfo & get_dof_info() const
Definition matrix_free.templates.h:1872
dealii::types::boundary_id get_boundary_id(const ID macro_face) const
Definition matrix_free.templates.h:1762
dealii::types::boundary_id get_faces_by_cells_boundary_id(const TensorID ¯o_cell, const unsigned int face_number) const
Definition matrix_free.templates.h:1781
void loop_cell_centric(const std::function< void(const MatrixFree &, OutVector &, const InVector &, const ID)> &cell_operation, OutVector &dst, const InVector &src, const DataAccessOnFaces src_vector_face_access=DataAccessOnFaces::unspecified, Timers *timers=nullptr) const
Definition matrix_free.templates.h:1497
void loop(const std::function< void(const MatrixFree &, OutVector &, const InVector &, const ID)> &cell_operation, const std::function< void(const MatrixFree &, OutVector &, const InVector &, const ID)> &face_operation, const std::function< void(const MatrixFree &, OutVector &, const InVector &, const ID)> &boundary_operation, OutVector &dst, const InVector &src, const DataAccessOnFaces dst_vector_face_access=DataAccessOnFaces::unspecified, const DataAccessOnFaces src_vector_face_access=DataAccessOnFaces::unspecified, Timers *timers=nullptr) const
Definition matrix_free.templates.h:1637
const dealii::MatrixFree< dim_x, Number, VectorizedArrayTypeX > & get_matrix_free_x() const
Definition matrix_free.templates.h:1848
bool are_ghost_faces_supported() const
Definition matrix_free.templates.h:1835
const std::shared_ptr< const dealii::internal::MatrixFreeFunctions::VectorDataExchange::Base > & get_vector_partitioner() const
Definition matrix_free.templates.h:1917
void initialize_dof_vector(dealii::LinearAlgebra::distributed::Vector< Number > &vec, const unsigned int dof_handler_index=0, const bool do_ghosts=true, const bool zero_out_values=true) const
Definition matrix_free.templates.h:1369
const internal::MatrixFreeFunctions::FaceInfo & get_face_info() const
Definition matrix_free.templates.h:1881
const internal::MatrixFreeFunctions::ShapeInfo< Number > & get_shape_info() const
Definition matrix_free.templates.h:1890
void reinit(const AdditionalData &ad=AdditionalData())
Definition matrix_free.templates.h:862
Definition memory_consumption.h:349
Definition matrix_free.templates.h:494
GlobaleCellIDTranslator(const GlobalCellInfo &info_x, const GlobalCellInfo &info_v, const MPI_Comm comm_x, const MPI_Comm comm_v)
Definition matrix_free.templates.h:499
CellInfo translate(const CellInfo &id1, const CellInfo &id2) const
Definition matrix_free.templates.h:536
Definition matrix_free.h:64
bool use_ecl
Definition matrix_free.h:96
bool do_ghost_faces
Definition matrix_free.h:80
bool do_buffering
Definition matrix_free.h:88
unsigned int overlapping_level
Definition matrix_free.h:101
const unsigned int v
Definition id.h:59
const unsigned int x
Definition id.h:54
const SpaceType type
Definition id.h:69
Definition matrix_free.templates.h:26
CellInfo(dealii::types::global_dof_index gid, unsigned int rank)
Definition matrix_free.templates.h:38
dealii::types::global_dof_index gid
Definition matrix_free.templates.h:46
CellInfo()
Definition matrix_free.templates.h:30
unsigned int rank
Definition matrix_free.templates.h:51
Definition matrix_free.templates.h:55
Definition matrix_free.templates.h:139
std::vector< FaceInfo > get_ghost_faces(const int dim, const bool ecl=false) const
Definition matrix_free.templates.h:151
GlobalCellInfoProcessor(const GlobalCellInfo &info)
Definition matrix_free.templates.h:143
Definition matrix_free.templates.h:73
Definition face_info.h:17
Definition shape_info.h:19
Definition matrix_free.templates.h:1241