21 #include "libmesh/libmesh_config.h"
22 #include "libmesh/mesh_base.h"
23 #include "libmesh/sfc_partitioner.h"
24 #include "libmesh/libmesh_logging.h"
25 #include "libmesh/elem.h"
27 #ifdef LIBMESH_HAVE_SFCURVES
30 # include "sfcurves.h"
34 # include "libmesh/linear_partitioner.h"
56 libmesh_assert_greater (n, 0);
59 #ifndef LIBMESH_HAVE_SFCURVES
62 libMesh::out <<
"ERROR: The library has been built without" << std::endl
63 <<
"Space Filling Curve support. Using a linear" << std::endl
64 <<
"partitioner instead!" << std::endl;);
72 LOG_SCOPE(
"partition_range()",
"SFCPartitioner");
75 if (!
mesh.is_serial())
76 libmesh_not_implemented();
87 std::vector<Elem *> reverse_map (n_range_elem,
nullptr);
89 std::vector<double> x (n_range_elem);
90 std::vector<double> y (n_range_elem);
91 std::vector<double> z (n_range_elem);
92 std::vector<int> table (n_range_elem);
99 libmesh_assert_less (elem->id(), forward_map.size());
100 libmesh_assert_less (el_num, reverse_map.size());
102 forward_map[elem->id()] = el_num;
103 reverse_map[el_num] = elem;
106 libmesh_assert_equal_to (el_num, n_range_elem);
111 libmesh_assert_less (elem->id(), forward_map.size());
113 const Point p = elem->centroid();
115 x[forward_map[elem->id()]] = double(p(0));
116 y[forward_map[elem->id()]] = double(p(1));
117 z[forward_map[elem->id()]] = double(p(2));
121 int size = static_cast<int>(n_range_elem);
125 Sfc::hilbert (x.data(),
132 Sfc::morton (x.data(),
141 <<
" Valid types are" << std::endl
142 <<
" \"Hilbert\"" << std::endl
143 <<
" \"Morton\"" << std::endl
145 <<
"Partitioning with a Hilbert curve." << std::endl;
147 Sfc::hilbert (x.data(),
165 const dof_id_type blksize = (n_range_elem + n - 1) / n;
169 libmesh_assert_less (table[i] - 1, reverse_map.size());
171 Elem * elem = reverse_map[table[i] - 1];
173 elem->
processor_id() = cast_int<processor_id_type>(i/blksize);
183 const unsigned int n)
186 mesh.active_elements_begin(),
187 mesh.active_elements_end(),