18 #include <deal.II/base/memory_consumption.h>
19 #include <deal.II/base/multithread_info.h>
20 #include <deal.II/lac/compressed_simple_sparsity_pattern.h>
21 #include <deal.II/lac/sparsity_pattern.h>
22 #include <deal.II/matrix_free/dof_info.h>
23 #include <deal.II/matrix_free/helper_functions.h>
25 DEAL_II_NAMESPACE_OPEN
29 namespace MatrixFreeFunctions
34 bool operator()(
const std::pair<types::global_dof_index,double> &p1,
35 const std::pair<types::global_dof_index,double> &p2)
const
37 return p1.second < p2.second;
45 template <
typename Number>
58 insert_entries (
const std::vector<std::pair<types::global_dof_index,double> > &entries);
60 std::vector<std::pair<types::global_dof_index, double> > constraint_entries;
61 std::vector<types::global_dof_index> constraint_indices;
68 template <
typename Number>
69 ConstraintValues<Number>::ConstraintValues ()
71 constraints(FPArrayComparator<
double>(1.))
74 template <
typename Number>
77 insert_entries (
const std::vector<std::pair<types::global_dof_index,double> > &entries)
79 next_constraint.first.resize(entries.size());
80 if (entries.size() > 0)
82 constraint_indices.resize(entries.size());
83 constraint_entries = entries;
84 std::sort(constraint_entries.begin(), constraint_entries.end(),
89 constraint_indices[j] = constraint_entries[j].first;
92 next_constraint.first[j] = constraint_entries[j].second;
95 next_constraint.second = constraints.size();
106 bool> it = constraints.insert(next_constraint);
108 types::global_dof_index insert_position = deal_II_numbers::invalid_dof_index;
109 if (it.second ==
false)
110 insert_position = it.first->second;
112 insert_position = next_constraint.second;
116 Assert(insert_position < (1<<(8*
sizeof(
unsigned short))),
118 return static_cast<unsigned short>(insert_position);
131 DoFInfo::DoFInfo (
const DoFInfo &dof_info_in)
133 row_starts (dof_info_in.row_starts),
134 dof_indices (dof_info_in.dof_indices),
135 constraint_indicator (dof_info_in.constraint_indicator),
136 vector_partitioner (dof_info_in.vector_partitioner),
137 constrained_dofs (dof_info_in.constrained_dofs),
138 row_starts_plain_indices (dof_info_in.row_starts_plain_indices),
139 plain_dof_indices (dof_info_in.plain_dof_indices),
140 dimension (dof_info_in.dimension),
141 n_components (dof_info_in.n_components),
142 dofs_per_cell (dof_info_in.dofs_per_cell),
143 dofs_per_face (dof_info_in.dofs_per_face),
144 store_plain_indices (dof_info_in.store_plain_indices),
145 cell_active_fe_index (dof_info_in.cell_active_fe_index),
146 max_fe_index (dof_info_in.max_fe_index),
147 fe_index_conversion (dof_info_in.fe_index_conversion),
148 ghost_dofs (dof_info_in.ghost_dofs)
158 constraint_indicator.clear();
159 vector_partitioner.reset();
161 dofs_per_cell.clear();
162 dofs_per_face.clear();
165 row_starts_plain_indices.clear();
166 plain_dof_indices.clear();
167 store_plain_indices =
false;
168 cell_active_fe_index.clear();
170 fe_index_conversion.clear();
176 DoFInfo::read_dof_indices (
const std::vector<types::global_dof_index> &local_indices,
177 const std::vector<unsigned int> &lexicographic_inv,
179 const unsigned int cell_number,
180 ConstraintValues<double> &constraint_values,
181 bool &cell_at_boundary)
184 const unsigned int n_mpi_procs = vector_partitioner->n_mpi_processes();
187 Assert (last_owned-first_owned < std::numeric_limits<unsigned int>::max(),
188 ExcMessage(
"The size local range of owned indices must not "
189 "exceed the size of unsigned int"));
190 const unsigned int n_owned = last_owned - first_owned;
191 std::pair<unsigned short,unsigned short> constraint_iterator (0,0);
193 unsigned int dofs_this_cell = (cell_active_fe_index.empty()) ?
194 dofs_per_cell[0] : dofs_per_cell[cell_active_fe_index[cell_number]];
195 for (
unsigned int i=0; i<dofs_this_cell; i++)
198 local_indices[lexicographic_inv[i]];
199 const std::vector<std::pair<types::global_dof_index,double> >
204 if (entries_ptr != 0)
209 if (current_dof < first_owned || current_dof >= last_owned)
211 ghost_dofs.push_back (current_dof);
212 cell_at_boundary =
true;
218 const std::vector<std::pair<types::global_dof_index,double> >
219 &entries = *entries_ptr;
221 if (n_entries == 1 && std::fabs(entries[0].second-1.)<1e-14)
223 current_dof = entries[0].first;
228 constraint_indicator.push_back (constraint_iterator);
229 constraint_indicator.back().second =
230 constraint_values.insert_entries (entries);
233 constraint_iterator.first = 0;
240 const std::vector<types::global_dof_index> &constraint_indices =
241 constraint_values.constraint_indices;
242 for (
unsigned int j=0; j<n_entries; ++j)
244 if (n_mpi_procs > 1 &&
245 (constraint_indices[j] < first_owned ||
246 constraint_indices[j] >= last_owned))
248 dof_indices.push_back (n_owned + ghost_dofs.size());
253 ghost_dofs.push_back(constraint_indices[j]);
254 cell_at_boundary =
true;
259 dof_indices.push_back
260 (static_cast<unsigned int>(constraint_indices[j] -
271 if (n_mpi_procs > 1 &&
272 (current_dof < first_owned ||
273 current_dof >= last_owned))
275 ghost_dofs.push_back(current_dof);
276 current_dof = n_owned + ghost_dofs.size()-1;
277 cell_at_boundary =
true;
280 current_dof -= first_owned;
282 dof_indices.push_back (static_cast<unsigned int>(current_dof));
286 Assert (constraint_iterator.first <
287 (1<<(8*
sizeof(
unsigned short)))-1,
289 constraint_iterator.first++;
292 row_starts[cell_number+1][0] = dof_indices.size();
293 row_starts[cell_number+1][1] = constraint_indicator.size();
294 row_starts[cell_number+1][2] = 0;
298 if (store_plain_indices ==
true)
300 if (cell_number == 0)
301 row_starts_plain_indices.resize (row_starts.size());
302 row_starts_plain_indices[cell_number] = plain_dof_indices.size();
303 bool cell_has_constraints = (row_starts[cell_number+1][1] >
304 row_starts[cell_number][1]);
305 if (cell_has_constraints ==
true)
307 for (
unsigned int i=0; i<dofs_this_cell; ++i)
310 local_indices[lexicographic_inv[i]];
311 if (n_mpi_procs > 1 &&
312 (current_dof < first_owned ||
313 current_dof >= last_owned))
315 ghost_dofs.push_back(current_dof);
316 current_dof = n_owned + ghost_dofs.size()-1;
317 cell_at_boundary =
true;
320 current_dof -= first_owned;
321 plain_dof_indices.push_back (static_cast<unsigned int>
331 DoFInfo::assign_ghosts (
const std::vector<unsigned int> &boundary_cells)
336 const unsigned int n_owned = (vector_partitioner->local_range().second-
337 vector_partitioner->local_range().first);
338 const std::size_t n_ghosts = ghost_dofs.size();
339 unsigned int n_unique_ghosts= 0;
341 for (std::vector<unsigned int>::iterator dof = dof_indices.begin();
342 dof!=dof_indices.end(); ++dof)
346 std::vector<unsigned int> ghost_numbering (n_ghosts);
347 IndexSet ghost_indices (vector_partitioner->size());
353 std::vector<std::pair<types::global_dof_index,unsigned int> > ghost_origin(n_ghosts);
354 for (std::size_t i=0; i<n_ghosts; ++i)
356 ghost_origin[i].first = ghost_dofs[i];
357 ghost_origin[i].second = i;
359 std::sort (ghost_origin.begin(), ghost_origin.end());
362 ghost_numbering[ghost_origin[0].second] = 0;
363 for (std::size_t i=1; i<n_ghosts; i++)
365 if (ghost_origin[i].first > ghost_origin[i-1].first+1)
367 ghost_indices.add_range (last_contiguous_start,
368 ghost_origin[i-1].first+1);
369 last_contiguous_start = ghost_origin[i].first;
371 if (ghost_origin[i].first>ghost_origin[i-1].first)
373 ghost_numbering[ghost_origin[i].second] = n_unique_ghosts;
376 ghost_indices.add_range (last_contiguous_start,
377 ghost_origin.back().first+1);
378 ghost_indices.compress();
384 for (std::size_t i=0; i<n_ghosts; ++i)
385 Assert (ghost_numbering[i] ==
386 ghost_indices.index_within_set(ghost_dofs[i]),
394 const unsigned int n_boundary_cells = boundary_cells.size();
395 for (
unsigned int i=0; i<n_boundary_cells; ++i)
397 unsigned int *data_ptr =
const_cast<unsigned int *
> (begin_indices(boundary_cells[i]));
399 const unsigned int *row_end = end_indices(boundary_cells[i]);
400 for ( ; data_ptr != row_end; ++data_ptr)
401 *data_ptr = ((*data_ptr < n_owned)
406 ghost_numbering[*data_ptr - n_owned]);
409 if (store_plain_indices ==
true)
411 if (row_length_indicators(boundary_cells[i]) > 0)
413 unsigned int *data_ptr =
const_cast<unsigned int *
> (begin_indices_plain(boundary_cells[i]));
414 const unsigned int *row_end = end_indices_plain(boundary_cells[i]);
415 for ( ; data_ptr != row_end; ++data_ptr)
416 *data_ptr = ((*data_ptr < n_owned)
421 ghost_numbering[*data_ptr - n_owned]);
427 std::vector<types::global_dof_index> empty;
428 ghost_dofs.swap(empty);
441 DoFInfo::compute_renumber_serial (
const std::vector<unsigned int> &boundary_cells,
442 const SizeInfo &size_info,
443 std::vector<unsigned int> &renumbering)
445 std::vector<unsigned int> reverse_numbering (size_info.n_active_cells,
447 const unsigned int n_boundary_cells = boundary_cells.size();
448 for (
unsigned int j=0; j<n_boundary_cells; ++j)
449 reverse_numbering[boundary_cells[j]] =
450 j + size_info.vectorization_length*size_info.boundary_cells_start;
451 unsigned int counter = 0;
453 while (counter < size_info.n_active_cells &&
454 counter < size_info.vectorization_length * size_info.boundary_cells_start)
457 reverse_numbering[j] = counter++;
460 counter = std::min (size_info.vectorization_length*
461 size_info.boundary_cells_start+n_boundary_cells,
462 size_info.n_active_cells);
463 if (counter < size_info.n_active_cells)
465 for ( ; j<size_info.n_active_cells; ++j)
467 reverse_numbering[j] = counter++;
476 DoFInfo::compute_renumber_hp_serial (SizeInfo &size_info,
477 std::vector<unsigned int> &renumbering,
478 std::vector<unsigned int> &irregular_cells)
480 if (max_fe_index < 2)
482 const unsigned int n_active_cells = size_info.n_active_cells;
483 const unsigned int vectorization_length = size_info.vectorization_length;
484 irregular_cells.resize (0);
485 irregular_cells.resize (size_info.n_macro_cells+3*max_fe_index);
486 std::vector<std::vector<unsigned int> > renumbering_fe_index;
487 renumbering_fe_index.resize(max_fe_index);
488 unsigned int counter,n_macro_cells_before = 0;
490 start_bound = std::min (size_info.n_active_cells,
491 size_info.boundary_cells_start*vectorization_length),
492 end_bound = std::min (size_info.n_active_cells,
493 size_info.boundary_cells_end*vectorization_length);
494 for (counter=0; counter<start_bound; counter++)
496 renumbering_fe_index[cell_active_fe_index[renumbering[counter]]].
497 push_back(renumbering[counter]);
500 for (
unsigned int j=0; j<max_fe_index; j++)
502 for (
unsigned int jj=0; jj<renumbering_fe_index[j].size(); jj++)
503 renumbering[counter++] = renumbering_fe_index[j][jj];
504 irregular_cells[renumbering_fe_index[j].size()/vectorization_length+
505 n_macro_cells_before] =
506 renumbering_fe_index[j].size()%vectorization_length;
507 n_macro_cells_before += (renumbering_fe_index[j].size()+vectorization_length-1)/
508 vectorization_length;
509 renumbering_fe_index[j].resize(0);
511 unsigned int new_boundary_start = n_macro_cells_before;
512 for (counter = start_bound; counter < end_bound; counter++)
514 renumbering_fe_index[cell_active_fe_index[renumbering[counter]]].
515 push_back(renumbering[counter]);
517 counter = start_bound;
518 for (
unsigned int j=0; j<max_fe_index; j++)
520 for (
unsigned int jj=0; jj<renumbering_fe_index[j].size(); jj++)
521 renumbering[counter++] = renumbering_fe_index[j][jj];
522 irregular_cells[renumbering_fe_index[j].size()/vectorization_length+
523 n_macro_cells_before] =
524 renumbering_fe_index[j].size()%vectorization_length;
525 n_macro_cells_before += (renumbering_fe_index[j].size()+vectorization_length-1)/
526 vectorization_length;
527 renumbering_fe_index[j].resize(0);
529 unsigned int new_boundary_end = n_macro_cells_before;
530 for (counter=end_bound; counter<n_active_cells; counter++)
532 renumbering_fe_index[cell_active_fe_index[renumbering[counter]]].
533 push_back(renumbering[counter]);
536 for (
unsigned int j=0; j<max_fe_index; j++)
538 for (
unsigned int jj=0; jj<renumbering_fe_index[j].size(); jj++)
539 renumbering[counter++] = renumbering_fe_index[j][jj];
540 irregular_cells[renumbering_fe_index[j].size()/vectorization_length+
541 n_macro_cells_before] =
542 renumbering_fe_index[j].size()%vectorization_length;
543 n_macro_cells_before += (renumbering_fe_index[j].size()+vectorization_length-1)/
544 vectorization_length;
547 size_info.n_macro_cells + 3*max_fe_index+1);
548 irregular_cells.resize (n_macro_cells_before);
549 size_info.n_macro_cells = n_macro_cells_before;
550 size_info.boundary_cells_start = new_boundary_start;
551 size_info.boundary_cells_end = new_boundary_end;
557 DoFInfo::compute_renumber_parallel (
const std::vector<unsigned int> &boundary_cells,
559 std::vector<unsigned int> &renumbering)
561 std::vector<unsigned int> reverse_numbering (size_info.n_active_cells,
563 const unsigned int n_boundary_cells = boundary_cells.size();
564 for (
unsigned int j=0; j<n_boundary_cells; ++j)
565 reverse_numbering[boundary_cells[j]] = j;
566 unsigned int counter = n_boundary_cells;
567 for (
unsigned int j=0; j<size_info.n_active_cells; ++j)
569 reverse_numbering[j] = counter++;
571 size_info.boundary_cells_end = (size_info.boundary_cells_end -
572 size_info.boundary_cells_start);
573 size_info.boundary_cells_start = 0;
582 DoFInfo::reorder_cells (
const SizeInfo &size_info,
583 const std::vector<unsigned int> &renumbering,
584 const std::vector<unsigned int> &constraint_pool_row_index,
585 const std::vector<unsigned int> &irregular_cells,
586 const unsigned int vectorization_length)
589 if (cell_active_fe_index.size() > 0)
591 std::vector<unsigned int> new_active_fe_index;
592 new_active_fe_index.reserve (size_info.n_macro_cells);
593 std::vector<unsigned int> fe_indices(vectorization_length);
594 unsigned int position_cell = 0;
595 for (
unsigned int cell=0; cell<size_info.n_macro_cells; ++cell)
597 const unsigned int n_comp = (irregular_cells[cell] > 0 ?
598 irregular_cells[cell] : vectorization_length);
599 for (
unsigned int j=0; j<n_comp; ++j)
600 fe_indices[j]=cell_active_fe_index[renumbering[position_cell+j]];
603 for (
unsigned int j=1; j<n_comp; ++j)
606 new_active_fe_index.push_back(fe_indices[0]);
607 position_cell += n_comp;
609 std::swap (new_active_fe_index, cell_active_fe_index);
612 std::vector<std_cxx1x::array<unsigned int, 3> > new_row_starts;
613 std::vector<unsigned int> new_dof_indices;
614 std::vector<std::pair<unsigned short,unsigned short> >
615 new_constraint_indicator;
616 std::vector<unsigned int> new_plain_indices, new_rowstart_plain;
617 unsigned int position_cell = 0;
618 new_row_starts.resize (size_info.n_macro_cells + 1);
619 new_dof_indices.reserve (dof_indices.size());
620 new_constraint_indicator.reserve (constraint_indicator.size());
621 if (store_plain_indices ==
true)
623 new_rowstart_plain.resize (size_info.n_macro_cells + 1,
625 new_plain_indices.reserve (plain_dof_indices.size());
633 std::vector<const unsigned int *> glob_indices (vectorization_length);
634 std::vector<const unsigned int *> plain_glob_indices (vectorization_length);
635 std::vector<const std::pair<unsigned short,unsigned short>*>
636 constr_ind(vectorization_length), constr_end(vectorization_length);
637 std::vector<unsigned int> index(vectorization_length);
638 for (
unsigned int i=0; i<size_info.n_macro_cells; ++i)
640 const unsigned int dofs_mcell =
641 dofs_per_cell[cell_active_fe_index.size() == 0 ? 0 :
642 cell_active_fe_index[i]] * vectorization_length;
643 new_row_starts[i][0] = new_dof_indices.size();
644 new_row_starts[i][1] = new_constraint_indicator.size();
645 new_row_starts[i][2] = irregular_cells[i];
647 const unsigned int n_comp = (irregular_cells[i]>0 ?
648 irregular_cells[i] : vectorization_length);
650 for (
unsigned int j=0; j<n_comp; ++j)
652 glob_indices[j] = begin_indices(renumbering[position_cell+j]);
653 constr_ind[j] = begin_indicators(renumbering[position_cell+j]);
654 constr_end[j] = end_indicators(renumbering[position_cell+j]);
658 bool has_constraints =
false;
659 if (store_plain_indices ==
true)
661 for (
unsigned int j=0; j<n_comp; ++j)
662 if (begin_indicators(renumbering[position_cell+j]) <
663 end_indicators(renumbering[position_cell+j]))
665 plain_glob_indices[j] =
666 begin_indices_plain (renumbering[position_cell+j]);
667 has_constraints =
true;
670 plain_glob_indices[j] =
671 begin_indices (renumbering[position_cell+j]);
672 if (has_constraints ==
true)
673 new_rowstart_plain[i] = new_plain_indices.size();
676 unsigned int m_ind_local = 0, m_index = 0;
677 while (m_ind_local < dofs_mcell)
678 for (
unsigned int j=0; j<vectorization_length; ++j)
693 if (constr_ind[j] == constr_end[j] ||
694 index[j] < constr_ind[j]->first)
696 new_dof_indices.push_back (*glob_indices[j]);
703 const unsigned short constraint_loc = constr_ind[j]->second;
704 new_constraint_indicator.push_back
705 (std::pair<unsigned short,unsigned short> (m_index, constraint_loc));
706 for (
unsigned int k=constraint_pool_row_index[constraint_loc];
707 k<constraint_pool_row_index[constraint_loc+1];
708 ++k, ++glob_indices[j])
709 new_dof_indices.push_back (*glob_indices[j]);
714 if (store_plain_indices==
true && has_constraints==
true)
715 new_plain_indices.push_back (*plain_glob_indices[j]++);
719 for (
unsigned int j=0; j<n_comp; ++j)
720 Assert (glob_indices[j]==end_indices(renumbering[position_cell+j]),
722 position_cell += n_comp;
726 new_row_starts[size_info.n_macro_cells][0] = new_dof_indices.size();
727 new_row_starts[size_info.n_macro_cells][1] = new_constraint_indicator.size();
728 new_row_starts[size_info.n_macro_cells][2] = 0;
732 new_constraint_indicator.size());
734 new_row_starts.swap (row_starts);
735 new_dof_indices.swap (dof_indices);
736 new_constraint_indicator.swap (constraint_indicator);
737 new_plain_indices.swap (plain_dof_indices);
738 new_rowstart_plain.swap (row_starts_plain_indices);
743 const unsigned int index_range = (vector_partitioner->local_range().second-
744 vector_partitioner->local_range().first)
745 + vector_partitioner->ghost_indices().n_elements();
746 for (std::size_t i=0; i<dof_indices.size(); ++i)
753 for (
unsigned int row=0; row<size_info.n_macro_cells; ++row)
755 const unsigned int row_length_ind = row_length_indices(row);
756 const std::pair<unsigned short,unsigned short>
757 *con_it = begin_indicators(row), * end_con = end_indicators(row);
758 for ( ; con_it != end_con; ++con_it)
762 constraint_pool_row_index.size()-1);
768 const unsigned int local_size = (vector_partitioner->local_range().second-
769 vector_partitioner->local_range().first);
770 for (
unsigned int row=0; row<size_info.boundary_cells_start; ++row)
772 const unsigned int *ptr = begin_indices(row);
773 const unsigned int *end_ptr = end_indices (row);
774 for ( ; ptr != end_ptr; ++ptr)
777 for (
unsigned int row=size_info.boundary_cells_end;
778 row<size_info.n_macro_cells; ++row)
780 const unsigned int *ptr = begin_indices(row);
781 const unsigned int *end_ptr = end_indices (row);
782 for ( ; ptr != end_ptr; ++ptr)
790 void DoFInfo::guess_block_size (
const SizeInfo &size_info,
794 if (task_info.block_size == 0)
798 task_info.block_size =
803 const unsigned int minimum_parallel_grain_size = 500;
804 if (dofs_per_cell[0] * task_info.block_size <
805 minimum_parallel_grain_size)
806 task_info.block_size = (minimum_parallel_grain_size /
807 dofs_per_cell[0] + 1);
809 if (task_info.block_size > size_info.n_macro_cells)
810 task_info.block_size = size_info.n_macro_cells;
815 void DoFInfo::make_thread_graph_partition_color
816 (SizeInfo &size_info,
818 std::vector<unsigned int> &renumbering,
819 std::vector<unsigned int> &irregular_cells,
822 if (size_info.n_macro_cells == 0)
825 const std::size_t vectorization_length = size_info.vectorization_length;
828 guess_block_size (size_info, task_info);
833 unsigned int partition = 0, start_up = 0, counter = 0;
836 if (task_info.use_coloring_only ==
false)
839 std::min(((size_info.boundary_cells_end+task_info.block_size-1)/
840 task_info.block_size)*task_info.block_size,
841 size_info.n_macro_cells);
842 start_up = start_nonboundary;
843 size_info.boundary_cells_end = start_nonboundary;
847 start_nonboundary = size_info.n_macro_cells;
848 start_up = size_info.n_macro_cells;
849 size_info.boundary_cells_start = 0;
850 size_info.boundary_cells_end = size_info.n_macro_cells;
854 irregular_cells.resize (0);
855 irregular_cells.resize (size_info.n_macro_cells+2*max_fe_index);
856 std::vector<std::vector<unsigned int> > renumbering_fe_index;
857 renumbering_fe_index.resize(max_fe_index);
858 unsigned int counter,n_macro_cells_before = 0;
859 for (counter=0; counter<start_nonboundary*vectorization_length;
862 renumbering_fe_index[cell_active_fe_index[renumbering[counter]]].
863 push_back(renumbering[counter]);
866 for (
unsigned int j=0; j<max_fe_index; j++)
868 for (
unsigned int jj=0; jj<renumbering_fe_index[j].size(); jj++)
869 renumbering[counter++] = renumbering_fe_index[j][jj];
870 irregular_cells[renumbering_fe_index[j].size()/vectorization_length+
871 n_macro_cells_before] =
872 renumbering_fe_index[j].size()%vectorization_length;
873 n_macro_cells_before += (renumbering_fe_index[j].size()+vectorization_length-1)/
874 vectorization_length;
875 renumbering_fe_index[j].resize(0);
878 unsigned int new_boundary_end = n_macro_cells_before;
879 for (counter=start_nonboundary*vectorization_length;
880 counter<size_info.n_active_cells; counter++)
882 renumbering_fe_index[cell_active_fe_index.empty() ? 0 :
883 cell_active_fe_index[renumbering[counter]]].
884 push_back(renumbering[counter]);
886 counter = start_nonboundary * vectorization_length;
887 for (
unsigned int j=0; j<max_fe_index; j++)
889 for (
unsigned int jj=0; jj<renumbering_fe_index[j].size(); jj++)
890 renumbering[counter++] = renumbering_fe_index[j][jj];
891 irregular_cells[renumbering_fe_index[j].size()/vectorization_length+
892 n_macro_cells_before] =
893 renumbering_fe_index[j].size()%vectorization_length;
894 n_macro_cells_before += (renumbering_fe_index[j].size()+vectorization_length-1)/
895 vectorization_length;
898 size_info.n_macro_cells + 2*max_fe_index+1);
899 irregular_cells.resize (n_macro_cells_before);
900 size_info.n_macro_cells = n_macro_cells_before;
901 size_info.boundary_cells_start = 0;
902 size_info.boundary_cells_end = new_boundary_end;
903 task_info.n_blocks = (size_info.n_macro_cells+task_info.block_size-1)
904 /task_info.block_size;
905 task_info.block_size_last = size_info.n_macro_cells%task_info.block_size;
906 if (task_info.block_size_last == 0)
907 task_info.block_size_last = task_info.block_size;
912 task_info.n_blocks = (size_info.n_macro_cells+task_info.block_size-1)/
913 task_info.block_size;
914 task_info.block_size_last = size_info.n_macro_cells-
915 (task_info.block_size*(task_info.n_blocks-1));
919 make_connectivity_graph (size_info, task_info, renumbering,irregular_cells,
927 std::vector<unsigned int> cell_partition(task_info.n_blocks,
928 size_info.n_macro_cells);
929 std::vector<unsigned int> neighbor_list;
930 std::vector<unsigned int> neighbor_neighbor_list;
934 std::vector<unsigned int> partition_list (task_info.n_blocks,0);
935 std::vector<unsigned int> partition_color_list(task_info.n_blocks,0);
938 std::vector<unsigned int> partition_blocks (2,0);
939 std::vector<unsigned int> cell_color(task_info.n_blocks,
940 size_info.n_macro_cells);
941 std::vector<bool> color_finder;
949 if (start_nonboundary>0 && start_up == start_nonboundary)
951 unsigned int n_blocks = ((start_nonboundary+task_info.block_size-1)
952 /task_info.block_size);
953 for (
unsigned int cell=0; cell<n_blocks; ++cell)
955 cell_partition[cell] = partition;
956 neighbor_list.push_back(cell);
957 partition_list[counter++] = cell;
958 partition_blocks.back()++;
966 cell_partition[start_up] = partition;
967 neighbor_list.push_back(start_up);
968 partition_list[counter++] = start_up;
969 partition_blocks.back()++;
972 while (neighbor_list.size()>0)
975 partition_blocks.push_back(partition_blocks.back());
976 for (
unsigned int j=0; j<neighbor_list.size(); ++j)
978 Assert(cell_partition[neighbor_list[j]]==partition-1,
981 connectivity.
row_begin(neighbor_list[j]),
982 end = connectivity.
row_end(neighbor_list[j]);
983 for (; neighbor!=end ; ++neighbor)
985 if (cell_partition[*neighbor]==size_info.n_macro_cells)
987 partition_blocks.back()++;
988 cell_partition[*neighbor] = partition;
989 neighbor_neighbor_list.push_back(*neighbor);
990 partition_list[counter++] = *neighbor;
994 neighbor_list = neighbor_neighbor_list;
995 neighbor_neighbor_list.resize(0);
1001 for (
unsigned int j=start_up; j<task_info.n_blocks; ++j)
1002 if (cell_partition[j] == size_info.n_macro_cells)
1013 task_info.partition_color_blocks_row_index.resize(partition+1);
1014 unsigned int color_counter = 0, index_counter = 0;
1015 for (
unsigned int part=0; part<partition; part++)
1017 task_info.partition_color_blocks_row_index[part] = index_counter;
1018 unsigned int max_color = 0;
1019 for (
unsigned int k=partition_blocks[part]; k<partition_blocks[part+1];
1022 unsigned int cell = partition_list[k];
1023 unsigned int n_neighbors = connectivity.
row_length(cell);
1027 color_finder.resize(n_neighbors+1);
1028 for (
unsigned int j=0; j<=n_neighbors; ++j)
1029 color_finder[j]=
true;
1031 neighbor = connectivity.
row_begin(cell),
1032 end = connectivity.
row_end(cell);
1033 for (; neighbor!=end ; ++neighbor)
1037 if (cell_partition[*neighbor] == part &&
1038 cell_color[*neighbor] <= n_neighbors)
1039 color_finder[cell_color[*neighbor]] =
false;
1043 while (color_finder[cell_color[cell]] ==
false)
1045 if (cell_color[cell] > max_color)
1046 max_color = cell_color[cell];
1051 for (
unsigned int color=0; color<=max_color; color++)
1053 task_info.partition_color_blocks_data.push_back(color_counter);
1055 for (
unsigned int k=partition_blocks[part];
1056 k<partition_blocks[part+1]; k++)
1058 unsigned int cell=partition_list[k];
1059 if (cell_color[cell] == color)
1061 partition_color_list[color_counter++] = cell;
1066 task_info.partition_color_blocks_data.push_back(task_info.n_blocks);
1067 task_info.partition_color_blocks_row_index[partition] = index_counter;
1070 partition_list = renumbering;
1075 std::vector<unsigned int> sorted_pc_list (partition_color_list);
1076 std::sort(sorted_pc_list.begin(), sorted_pc_list.end());
1077 for (
unsigned int i=0; i<sorted_pc_list.size(); ++i)
1084 std::vector<unsigned int> block_start(size_info.n_macro_cells+1);
1085 std::vector<unsigned int> irregular(size_info.n_macro_cells);
1087 unsigned int mcell_start=0;
1089 for (
unsigned int block=0; block<task_info.n_blocks; block++)
1091 block_start[block+1] = block_start[block];
1092 for (
unsigned int mcell=mcell_start; mcell<
1093 std::min(mcell_start+task_info.block_size,
1094 size_info.n_macro_cells);
1097 unsigned int n_comp = (irregular_cells[mcell]>0)
1098 ?irregular_cells[mcell]:size_info.vectorization_length;
1099 block_start[block+1] += n_comp;
1102 mcell_start += task_info.block_size;
1105 unsigned int counter_macro = 0;
1106 for (
unsigned int block=0; block<task_info.n_blocks; block++)
1108 unsigned int present_block = partition_color_list[block];
1109 for (
unsigned int cell = block_start[present_block];
1110 cell<block_start[present_block+1]; ++cell)
1111 renumbering[counter++] = partition_list[cell];
1112 unsigned int this_block_size = (present_block == task_info.n_blocks-1)?
1113 task_info.block_size_last:task_info.block_size;
1114 for (
unsigned int j=0; j<this_block_size; j++)
1115 irregular[counter_macro++] =
1116 irregular_cells[present_block*task_info.block_size+j];
1117 if (present_block == task_info.n_blocks-1)
1118 task_info.position_short_block = block;
1120 irregular_cells.swap(irregular);
1127 std::vector<unsigned int> sorted_renumbering (renumbering);
1128 std::sort(sorted_renumbering.begin(), sorted_renumbering.end());
1129 for (
unsigned int i=0; i<sorted_renumbering.size(); ++i)
1134 task_info.evens = (partition+1)>>1;
1135 task_info.odds = (partition)>>1;
1136 task_info.n_blocked_workers = task_info.odds-
1137 (task_info.odds+task_info.evens+1)%2;
1138 task_info.n_workers = task_info.partition_color_blocks_data.size()-1-
1139 task_info.n_blocked_workers;
1145 DoFInfo::make_thread_graph_partition_partition
1146 (SizeInfo &size_info,
1147 TaskInfo &task_info,
1148 std::vector<unsigned int> &renumbering,
1149 std::vector<unsigned int> &irregular_cells,
1152 if (size_info.n_macro_cells == 0)
1155 const std::size_t vectorization_length = size_info.vectorization_length;
1158 guess_block_size (size_info, task_info);
1162 task_info.n_blocks = (size_info.n_macro_cells+task_info.block_size-1)/
1163 task_info.block_size;
1164 task_info.block_size_last = size_info.n_macro_cells-
1165 (task_info.block_size*(task_info.n_blocks-1));
1166 task_info.position_short_block = task_info.n_blocks-1;
1167 unsigned int cluster_size = task_info.block_size*vectorization_length;
1171 make_connectivity_graph (size_info, task_info, renumbering,irregular_cells,
1172 false, connectivity);
1179 std::vector<unsigned int> cell_partition (size_info.n_active_cells,
1180 size_info.n_active_cells);
1181 std::vector<unsigned int> neighbor_list;
1182 std::vector<unsigned int> neighbor_neighbor_list;
1186 std::vector<unsigned int> partition_list(size_info.n_active_cells,0);
1187 std::vector<unsigned int> partition_partition_list(size_info.n_active_cells,0);
1190 std::vector<unsigned int> partition_size(2,0);
1192 unsigned int partition = 0,start_up=0,counter=0;
1193 unsigned int start_nonboundary = vectorization_length * size_info.boundary_cells_end;
1194 if (start_nonboundary > size_info.n_active_cells)
1195 start_nonboundary = size_info.n_active_cells;
1197 unsigned int remainder = cluster_size;
1205 if (start_nonboundary>0)
1207 for (
unsigned int cell=0; cell<start_nonboundary; ++cell)
1209 const unsigned int cell_nn = renumbering[cell];
1210 cell_partition[cell_nn] = partition;
1211 neighbor_list.push_back(cell_nn);
1212 partition_list[counter++] = cell_nn;
1213 partition_size.back()++;
1215 remainder -= (start_nonboundary%cluster_size);
1216 if (remainder == cluster_size)
1220 size_info.boundary_cells_end += (remainder+vectorization_length-1)/vectorization_length;
1226 cell_partition[start_up] = partition;
1227 neighbor_list.push_back(start_up);
1228 partition_list[counter++] = start_up;
1229 partition_size.back()++;
1232 if (remainder == cluster_size)
1235 int index_before = neighbor_list.size(), index = index_before,
1239 if (index==index_stop)
1241 index = neighbor_list.size();
1242 if (index == index_before)
1244 neighbor_list.resize(0);
1247 index_stop = index_before;
1248 index_before = index;
1251 unsigned int additional = neighbor_list[index];
1254 end = connectivity.
row_end(additional);
1255 for (; neighbor!=end ; ++neighbor)
1257 if (cell_partition[*neighbor]==size_info.n_active_cells)
1259 partition_size.back()++;
1260 cell_partition[*neighbor] = partition;
1261 neighbor_list.push_back(*neighbor);
1262 partition_list[counter++] = *neighbor;
1270 while (neighbor_list.size()>0)
1273 unsigned int partition_counter = 0;
1274 partition_size.push_back(partition_size.back());
1276 for (
unsigned int j=0; j<neighbor_list.size(); ++j)
1278 Assert(cell_partition[neighbor_list[j]]==partition-1,
1281 connectivity.
row_begin(neighbor_list[j]),
1282 end = connectivity.
row_end(neighbor_list[j]);
1283 for (; neighbor!=end ; ++neighbor)
1285 if (cell_partition[*neighbor]==size_info.n_active_cells)
1287 partition_size.back()++;
1288 cell_partition[*neighbor] = partition;
1289 neighbor_neighbor_list.push_back(*neighbor);
1290 partition_list[counter++] = *neighbor;
1291 partition_counter++;
1295 remainder = cluster_size-(partition_counter%cluster_size);
1296 if (remainder == cluster_size)
1299 int index_before = neighbor_neighbor_list.size(), index = index_before;
1302 if (index==index_stop)
1304 index = neighbor_neighbor_list.size();
1305 if (index == index_before)
1307 neighbor_neighbor_list.resize(0);
1310 index_stop = index_before;
1311 index_before = index;
1314 unsigned int additional = neighbor_neighbor_list[index];
1317 end = connectivity.
row_end(additional);
1318 for (; neighbor!=end ; ++neighbor)
1320 if (cell_partition[*neighbor]==size_info.n_active_cells)
1322 partition_size.back()++;
1323 cell_partition[*neighbor] = partition;
1324 neighbor_neighbor_list.push_back(*neighbor);
1325 partition_list[counter++] = *neighbor;
1333 neighbor_list = neighbor_neighbor_list;
1334 neighbor_neighbor_list.resize(0);
1340 for (
unsigned int j=start_up; j<size_info.n_active_cells; ++j)
1341 if (cell_partition[j] == size_info.n_active_cells)
1346 remainder = cluster_size;
1353 for (
unsigned int j=0; j<renumbering.size(); j++)
1355 irregular_cells.back() = 0;
1356 irregular_cells.resize(size_info.n_active_cells);
1357 unsigned int n_macro_cells_before = 0;
1364 std::vector<unsigned int> cell_partition_l2(size_info.n_active_cells,
1365 size_info.n_active_cells);
1366 task_info.partition_color_blocks_row_index.resize(partition+1,0);
1367 task_info.partition_color_blocks_data.resize(1,0);
1371 unsigned int missing_macros;
1372 for (
unsigned int part=0; part<partition; ++part)
1374 neighbor_neighbor_list.resize(0);
1375 neighbor_list.resize(0);
1377 unsigned int partition_l2 = 0;
1378 start_up = partition_size[part];
1379 unsigned int partition_counter = 0;
1382 if (neighbor_list.size()==0)
1385 partition_counter = 0;
1386 for (
unsigned int j=start_up; j<partition_size[part+1]; ++j)
1387 if (cell_partition[partition_list[j]] == part &&
1388 cell_partition_l2[partition_list[j]] == size_info.n_active_cells)
1392 partition_counter = 1;
1396 cell_partition_l2[partition_list[start_up]] =
1398 neighbor_neighbor_list.push_back
1399 (partition_list[start_up]);
1400 partition_partition_list[counter++] =
1401 partition_list[start_up];
1408 partition_counter = 0;
1409 for (
unsigned int j=0; j<neighbor_list.size(); ++j)
1411 Assert(cell_partition[neighbor_list[j]]==part,
1413 Assert(cell_partition_l2[neighbor_list[j]]==partition_l2-1,
1416 connectivity.
row_begin(neighbor_list[j]),
1417 end = connectivity.
row_end(neighbor_list[j]);
1418 for (; neighbor!=end ; ++neighbor)
1420 if (cell_partition[*neighbor] == part &&
1421 cell_partition_l2[*neighbor]==
1422 size_info.n_active_cells)
1424 cell_partition_l2[*neighbor] = partition_l2;
1425 neighbor_neighbor_list.push_back(*neighbor);
1426 partition_partition_list[counter++] = *neighbor;
1427 partition_counter++;
1432 if (partition_counter>0)
1434 int index_before = neighbor_neighbor_list.size(),
1435 index = index_before;
1440 std::vector<unsigned int> remaining_per_macro_cell
1442 std::vector<std::vector<unsigned int> >
1443 renumbering_fe_index;
1446 if (hp_bool ==
true)
1448 renumbering_fe_index.resize(max_fe_index);
1449 for (cell=counter-partition_counter; cell<counter; ++cell)
1451 renumbering_fe_index
1452 [cell_active_fe_index.empty() ? 0 :
1453 cell_active_fe_index[partition_partition_list
1455 push_back(partition_partition_list[cell]);
1458 for (
unsigned int j=0; j<max_fe_index; j++)
1460 remaining_per_macro_cell[j] =
1461 renumbering_fe_index[j].size()%vectorization_length;
1462 if (remaining_per_macro_cell[j] != 0)
1464 missing_macros += ((renumbering_fe_index[j].size()+
1465 vectorization_length-1)/vectorization_length);
1470 remaining_per_macro_cell.resize(1);
1471 remaining_per_macro_cell[0] = partition_counter%
1472 vectorization_length;
1473 missing_macros = partition_counter/vectorization_length;
1474 if (remaining_per_macro_cell[0] != 0)
1480 missing_macros = task_info.block_size -
1481 (missing_macros%task_info.block_size);
1484 while (missing_macros>0 || filled ==
false)
1488 index = neighbor_neighbor_list.size();
1489 if (index == index_before)
1491 if (missing_macros != 0)
1493 neighbor_neighbor_list.resize(0);
1498 index_before = index;
1501 unsigned int additional = neighbor_neighbor_list
1510 end = connectivity.
row_end(additional);
1511 for (; neighbor!=end ; ++neighbor)
1513 if (cell_partition[*neighbor] == part &&
1514 cell_partition_l2[*neighbor] ==
1515 size_info.n_active_cells)
1517 unsigned int this_index = 0;
1518 if (hp_bool ==
true)
1519 this_index = cell_active_fe_index.empty() ? 0 :
1520 cell_active_fe_index[*neighbor];
1526 if (missing_macros > 0 ||
1527 remaining_per_macro_cell[this_index] > 0)
1529 cell_partition_l2[*neighbor] = partition_l2;
1530 neighbor_neighbor_list.push_back(*neighbor);
1531 if (hp_bool ==
true)
1532 renumbering_fe_index[this_index].
1533 push_back(*neighbor);
1534 partition_partition_list[counter] =
1537 partition_counter++;
1538 if (remaining_per_macro_cell[this_index]
1539 == 0 && missing_macros > 0)
1541 remaining_per_macro_cell[this_index]++;
1542 if (remaining_per_macro_cell[this_index]
1543 == vectorization_length)
1545 remaining_per_macro_cell[this_index] = 0;
1547 if (missing_macros == 0)
1550 for (
unsigned int fe_ind=0;
1551 fe_ind<max_fe_index; ++fe_ind)
1552 if (remaining_per_macro_cell[fe_ind]!=0)
1561 if (hp_bool ==
true)
1566 cell = counter - partition_counter;
1567 for (
unsigned int j=0; j<max_fe_index; j++)
1569 for (
unsigned int jj=0; jj<renumbering_fe_index[j].
1571 renumbering[cell++] =
1572 renumbering_fe_index[j][jj];
1573 if (renumbering_fe_index[j].size()%vectorization_length != 0)
1574 irregular_cells[renumbering_fe_index[j].size()/
1575 vectorization_length+
1576 n_macro_cells_before] =
1577 renumbering_fe_index[j].size()%vectorization_length;
1578 n_macro_cells_before += (renumbering_fe_index[j].
1579 size()+vectorization_length-1)/
1580 vectorization_length;
1581 renumbering_fe_index[j].resize(0);
1586 n_macro_cells_before += partition_counter/vectorization_length;
1587 if (partition_counter%vectorization_length != 0)
1589 irregular_cells[n_macro_cells_before] =
1590 partition_counter%vectorization_length;
1591 n_macro_cells_before++;
1595 task_info.partition_color_blocks_data.
1596 push_back(n_macro_cells_before);
1599 neighbor_list = neighbor_neighbor_list;
1600 neighbor_neighbor_list.resize(0);
1602 task_info.partition_color_blocks_row_index[part+1] =
1603 task_info.partition_color_blocks_row_index[part] + partition_l2;
1607 if (size_info.boundary_cells_end>0)
1608 size_info.boundary_cells_end = task_info.partition_color_blocks_data
1609 [task_info.partition_color_blocks_row_index[1]];
1611 if (hp_bool ==
false)
1612 renumbering.swap(partition_partition_list);
1613 irregular_cells.resize(n_macro_cells_before);
1614 size_info.n_macro_cells = n_macro_cells_before;
1616 task_info.evens = (partition+1)/2;
1617 task_info.odds = partition/2;
1618 task_info.n_blocked_workers =
1619 task_info.odds-(task_info.odds+task_info.evens+1)%2;
1620 task_info.n_workers = task_info.evens+task_info.odds-
1621 task_info.n_blocked_workers;
1622 task_info.partition_evens.resize(partition);
1623 task_info.partition_odds.resize(partition);
1624 task_info.partition_n_blocked_workers.resize(partition);
1625 task_info.partition_n_workers.resize(partition);
1626 for (
unsigned int part=0; part<partition; part++)
1628 task_info.partition_evens[part] =
1629 (task_info.partition_color_blocks_row_index[part+1]-
1630 task_info.partition_color_blocks_row_index[part]+1)/2;
1631 task_info.partition_odds[part] =
1632 (task_info.partition_color_blocks_row_index[part+1]-
1633 task_info.partition_color_blocks_row_index[part])/2;
1634 task_info.partition_n_blocked_workers[part] =
1635 task_info.partition_odds[part]-(task_info.partition_odds[part]+
1636 task_info.partition_evens[part]+1)%2;
1637 task_info.partition_n_workers[part] =
1638 task_info.partition_evens[part]+task_info.partition_odds[part]-
1639 task_info.partition_n_blocked_workers[part];
1655 void reserve (
const std::size_t size)
1658 this->std::vector<types::global_dof_index>::reserve (size);
1664 void insert (
const unsigned int entry,
1665 std::vector<types::global_dof_index>::iterator &dat)
1670 while (dat != end() && *dat < entry)
1678 else if (*dat > entry)
1680 dat = this->std::vector<types::global_dof_index>::insert (dat, entry);
1691 DoFInfo::make_connectivity_graph
1694 const std::vector<unsigned int> &renumbering,
1695 const std::vector<unsigned int> &irregular_cells,
1696 const bool do_blocking,
1700 const unsigned int n_rows =
1701 (vector_partitioner->local_range().second-
1702 vector_partitioner->local_range().first)
1703 + vector_partitioner->ghost_indices().n_elements();
1704 const unsigned int n_blocks = (do_blocking ==
true) ?
1705 task_info.n_blocks : size_info.n_active_cells;
1708 std::vector<unsigned int> row_lengths(n_rows);
1709 unsigned int cell_start = 0, mcell_start = 0;
1710 std::vector<unsigned int> scratch;
1711 for (
unsigned int block = 0; block < n_blocks; ++block)
1717 if (do_blocking ==
true)
1720 for (
unsigned int mcell=mcell_start; mcell<
1721 std::min(mcell_start+task_info.block_size,
1722 size_info.n_macro_cells);
1725 unsigned int n_comp = (irregular_cells[mcell]>0)
1726 ?irregular_cells[mcell]:size_info.vectorization_length;
1727 for (
unsigned int cell = cell_start; cell < cell_start+n_comp;
1729 scratch.insert(scratch.end(),
1730 begin_indices(renumbering[cell]),
1731 end_indices(renumbering[cell]));
1732 cell_start += n_comp;
1734 std::sort(scratch.begin(), scratch.end());
1735 const unsigned int n_unique =
1736 std::unique(scratch.begin(), scratch.end())-scratch.begin();
1737 for (
unsigned int i=0; i<n_unique; ++i)
1738 row_lengths[scratch[i]]++;
1739 mcell_start += task_info.block_size;
1744 scratch.insert(scratch.end(),
1745 begin_indices(block), end_indices(block));
1746 std::sort(scratch.begin(), scratch.end());
1747 const unsigned int n_unique =
1748 std::unique(scratch.begin(), scratch.end())-scratch.begin();
1749 for (
unsigned int i=0; i<n_unique; ++i)
1750 row_lengths[scratch[i]]++;
1755 for (
unsigned int row=0; row<n_rows; ++row)
1756 if (row_lengths[row] == 1)
1757 row_lengths[row] = 0;
1760 cell_start = 0, mcell_start = 0;
1761 for (
unsigned int block = 0; block < n_blocks; ++block)
1767 if (do_blocking ==
true)
1769 for (
unsigned int mcell=mcell_start; mcell<
1770 std::min(mcell_start+task_info.block_size,
1771 size_info.n_macro_cells);
1774 unsigned int n_comp = (irregular_cells[mcell]>0)
1775 ?irregular_cells[mcell]:size_info.vectorization_length;
1776 for (
unsigned int cell = cell_start; cell < cell_start+n_comp;
1780 *it = begin_indices (renumbering[cell]),
1781 *end_cell = end_indices (renumbering[cell]);
1782 for ( ; it != end_cell; ++it)
1783 if (row_lengths[*it]>0)
1784 connectivity_dof.add(*it, block);
1786 cell_start += n_comp;
1788 mcell_start += task_info.block_size;
1793 *it = begin_indices (block),
1794 *end_cell = end_indices (block);
1795 for ( ; it != end_cell; ++it)
1796 if (row_lengths[*it]>0)
1797 connectivity_dof.add(*it, block);
1800 connectivity_dof.compress();
1802 connectivity.
reinit (n_blocks, n_blocks);
1803 internal::ordered_vector row_entries;
1806 for (
unsigned int block=0; block < n_blocks; ++block)
1808 row_entries.clear();
1810 if (do_blocking==
true)
1812 for (
unsigned int mcell=mcell_start; mcell<
1813 std::min(mcell_start+task_info.block_size,
1814 size_info.n_macro_cells);
1817 unsigned int n_comp = (irregular_cells[mcell]>0)
1818 ?irregular_cells[mcell]:size_info.vectorization_length;
1819 for (
unsigned int cell = cell_start; cell < cell_start+n_comp;
1824 *it = begin_indices (renumbering[cell]),
1825 *end_cell = end_indices (renumbering[cell]);
1826 for ( ; it != end_cell; ++it)
1827 if (row_lengths[*it] > 0)
1831 if (connectivity_dof.n_rows()==connectivity_dof.n_cols())
1833 row_entries.reserve (row_entries.size() + end_cell - it);
1834 std::vector<types::global_dof_index>::iterator insert_pos = row_entries.begin();
1835 for ( ; sp != connectivity_dof.end(*it); ++sp)
1836 if (sp->
column() >= block)
1839 row_entries.insert (sp->
column(), insert_pos);
1842 cell_start +=n_comp;
1844 mcell_start += task_info.block_size;
1848 const unsigned int *it = begin_indices (block),
1849 * end_cell = end_indices (block);
1850 for ( ; it != end_cell; ++it)
1851 if (row_lengths[*it] > 0)
1855 if (connectivity_dof.n_rows()==connectivity_dof.n_cols())
1857 row_entries.reserve (row_entries.size() + end_cell - it);
1858 std::vector<types::global_dof_index>::iterator insert_pos = row_entries.begin();
1859 for ( ; sp != connectivity_dof.end(*it); ++sp)
1860 if (sp->
column() >= block)
1863 row_entries.insert (sp->
column(), insert_pos);
1866 connectivity.
add_entries (block, row_entries.begin(), row_entries.end());
1873 void DoFInfo::renumber_dofs (std::vector<types::global_dof_index> &renumbering)
1877 vector_partitioner->size());
1878 const unsigned int local_size = vector_partitioner->local_size();
1879 renumbering.resize (0);
1883 std::vector<unsigned int>::iterator dof_ind = dof_indices.begin(),
1884 end_ind = dof_indices.end();
1885 for ( ; dof_ind != end_ind; ++dof_ind)
1887 if (*dof_ind < local_size)
1890 renumbering[*dof_ind] = counter++;
1891 *dof_ind = renumbering[*dof_ind];
1896 for (std::size_t i=0; i<renumbering.size(); ++i)
1898 renumbering[i] = counter++;
1901 std::vector<unsigned int> new_constrained_dofs (constrained_dofs.size());
1902 for (std::size_t i=0; i<constrained_dofs.size(); ++i)
1903 new_constrained_dofs[i] = renumbering[constrained_dofs[i]];
1908 for (std::size_t i=1; i<new_constrained_dofs.size(); ++i)
1911 std::swap (constrained_dofs, new_constrained_dofs);
1914 for (std::size_t i=0; i<renumbering.size(); ++i)
1915 renumbering[i] = vector_partitioner->local_to_global(renumbering[i]);
1923 DoFInfo::memory_consumption ()
const
1925 std::size_t memory =
sizeof(*this);
1926 memory += (row_starts.capacity()*
sizeof(std_cxx1x::array<unsigned int,3>));
1937 template <
typename STREAM>
1939 DoFInfo::print_memory_consumption (STREAM &out,
1940 const SizeInfo &size_info)
const
1942 out <<
" Memory row starts indices: ";
1943 size_info.print_memory_statistics
1944 (out, (row_starts.capacity()*
sizeof(std_cxx1x::array<unsigned int, 3>)));
1945 out <<
" Memory dof indices: ";
1946 size_info.print_memory_statistics
1948 out <<
" Memory constraint indicators: ";
1949 size_info.print_memory_statistics
1951 out <<
" Memory plain indices: ";
1952 size_info.print_memory_statistics
1955 out <<
" Memory vector partitioner: ";
1956 size_info.print_memory_statistics
1962 template <
typename Number>
1964 DoFInfo::print (
const std::vector<Number> &constraint_pool_data,
1965 const std::vector<unsigned int> &constraint_pool_row_index,
1966 std::ostream &out)
const
1968 const unsigned int n_rows = row_starts.size() - 1;
1969 for (
unsigned int row=0 ; row<n_rows ; ++row)
1971 out <<
"Entries row " << row <<
": ";
1972 const unsigned int *glob_indices = begin_indices(row),
1973 *end_row = end_indices(row);
1974 unsigned int index = 0;
1975 const std::pair<unsigned short,unsigned short>
1976 *con_it = begin_indicators(row),
1977 * end_con = end_indicators(row);
1978 for ( ; con_it != end_con; ++con_it)
1980 for ( ; index<con_it->first; index++)
1983 out << glob_indices[index] <<
" ";
1987 for (
unsigned int k=constraint_pool_row_index[con_it->second];
1988 k<constraint_pool_row_index[con_it->second+1];
1992 out << glob_indices[index] <<
"/"
1993 << constraint_pool_data[k];
1994 if (k<constraint_pool_row_index[con_it->second+1]-1)
1999 glob_indices += index;
2000 for (; glob_indices != end_row; ++glob_indices)
2001 out << *glob_indices <<
" ";
2010 DEAL_II_NAMESPACE_CLOSE
static const unsigned int invalid_unsigned_int
#define AssertDimension(dim1, dim2)
const std::vector< std::pair< size_type, double > > * get_constraint_entries(const size_type line) const
::ExceptionBase & ExcMessage(std::string arg1)
#define AssertIndexRange(index, range)
unsigned int global_dof_index
#define Assert(cond, exc)
std::size_t memory_consumption(const T &t)
unsigned short insert_entries(const std::vector< std::pair< types::global_dof_index, double > > &entries)
row_iterator row_begin(const size_type row) const
std::vector< unsigned int > invert_permutation(const std::vector< unsigned int > &permutation)
void add_entries(const size_type row, ForwardIterator begin, ForwardIterator end, const bool indices_are_unique_and_sorted=false)
size_type row_length(const size_type row) const
row_iterator row_end(const size_type row) const
void reinit(const size_type m, const size_type n, const IndexSet &rowset=IndexSet())
MultithreadInfo multithread_info
const types::global_dof_index invalid_dof_index
::ExceptionBase & ExcInternalError()
void set_ghost_indices(const IndexSet &ghost_indices)
std::vector< size_type >::const_iterator row_iterator