21 #include "libmesh/libmesh_config.h" 22 #include "libmesh/elem.h" 23 #include "libmesh/enum_partitioner_type.h" 24 #include "libmesh/libmesh_logging.h" 25 #include "libmesh/mesh_base.h" 26 #include "libmesh/sfc_partitioner.h" 28 #ifdef LIBMESH_HAVE_SFCURVES 31 # include "sfcurves.h" 35 # include "libmesh/linear_partitioner.h" 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();
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);
190 const unsigned int n)
193 mesh.active_elements_begin(),
194 mesh.active_elements_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).
The definition of the element_iterator struct.
virtual void _do_partition(MeshBase &mesh, const unsigned int n) override
Partition the MeshBase into n subdomains.
bool single_partition_range(MeshBase::element_iterator it, MeshBase::element_iterator end)
Slightly generalized version of single_partition which acts on a range of elements defined by the pai...
The LinearPartitioner simply takes the element list and splits it into equal-sized chunks assigned to...
std::string _sfc_type
The type of space-filling curve to use.
This is the base class from which all geometric element types are derived.
The libMesh namespace provides an interface to certain functionality in the library.
Real distance(const Point &p)
This is the MeshBase class.
PartitionerType
Defines an enum for mesh partitioner types.
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
virtual PartitionerType type() const override
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
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).
processor_id_type processor_id() const
A Point defines a location in LIBMESH_DIM dimensional Real space.