63 libmesh_assert_greater (n, 0);
66#ifndef LIBMESH_HAVE_SFCURVES
69 libMesh::out <<
"ERROR: The library has been built without" << std::endl
70 <<
"Space Filling Curve support. Using a linear" << std::endl
71 <<
"partitioner instead!" << std::endl;);
79 LOG_SCOPE(
"partition_range()",
"SFCPartitioner");
82 if (!
mesh.is_serial())
83 libmesh_not_implemented();
85 const dof_id_type n_range_elem = std::distance(beg, end);
94 std::vector<Elem *> reverse_map (n_range_elem,
nullptr);
96 std::vector<double> x (n_range_elem);
97 std::vector<double> y (n_range_elem);
98 std::vector<double> z (n_range_elem);
99 std::vector<int> table (n_range_elem);
104 for (
auto & elem :
as_range(beg, end))
106 libmesh_assert_less (elem->id(), forward_map.size());
107 libmesh_assert_less (el_num, reverse_map.size());
109 forward_map[elem->id()] = el_num;
110 reverse_map[el_num] = elem;
113 libmesh_assert_equal_to (el_num, n_range_elem);
116 for (
const auto & elem :
as_range(beg, end))
118 libmesh_assert_less (elem->id(), forward_map.size());
120 const Point p = elem->vertex_average();
122 x[forward_map[elem->id()]] = double(p(0));
123 y[forward_map[elem->id()]] = double(p(1));
124 z[forward_map[elem->id()]] = double(p(2));
128 int size =
static_cast<int>(n_range_elem);
132 Sfc::hilbert (x.data(),
139 Sfc::morton (x.data(),
148 <<
" Valid types are" << std::endl
149 <<
" \"Hilbert\"" << std::endl
150 <<
" \"Morton\"" << std::endl
152 <<
"Partitioning with a Hilbert curve." << std::endl;
154 Sfc::hilbert (x.data(),
172 const dof_id_type blksize = (n_range_elem + n - 1) / n;
176 libmesh_assert_less (table[i] - 1, reverse_map.size());
178 Elem * elem = reverse_map[table[i] - 1];
180 elem->
processor_id() = cast_int<processor_id_type>(i/blksize);
virtual void partition_range(MeshBase &mesh, MeshBase::element_iterator it, MeshBase::element_iterator end, const unsigned int n) override
Called by the SubdomainPartitioner to partition elements in the range (it, end).
virtual void partition_range(MeshBase &mesh, MeshBase::element_iterator it, MeshBase::element_iterator end, const unsigned int n) override
Called by the SubdomainPartitioner to partition elements in the range (it, end).