Program Listing for File localization_path_selection.h
↰ Return to documentation for file (src/pcms/localization/localization_path_selection.h)
#ifndef PCMS_LOCALIZATION_PATH_SELECTION_H
#define PCMS_LOCALIZATION_PATH_SELECTION_H
#include "pcms/field/field_layout.h"
#include "pcms/utility/entity_types.h"
#include <optional>
namespace pcms::detail
{
enum class LocalizationPath
{
PointCloudSupports,
VertexAdjacencySearch,
CentroidToVertexAdjacencySearch
};
// Returns the unique entity dimension represented by all DOF holders in the
// layout when its offsets contain exactly one populated entity block and the
// full DOF-holder coordinate set matches that discretization entity count.
// Otherwise, returns std::nullopt.
inline std::optional<int> GetUniformDofHolderEntityDim(
const FieldLayout& layout)
{
auto disc = layout.GetDiscretization();
if (disc == nullptr) {
return std::nullopt;
}
const auto offsets = layout.GetEntOffsets();
std::optional<int> entity_dim;
for (int dim = 0; dim < ent_offsets_len - 1; ++dim) {
const auto block_size = offsets[dim + 1] - offsets[dim];
if (block_size > 0) {
if (entity_dim.has_value()) {
return std::nullopt;
}
entity_dim = dim;
}
}
if (!entity_dim.has_value()) {
return std::nullopt;
}
if (static_cast<LO>(layout.GetDOFHolderCoordinates().GetValues().extent(0)) !=
disc->GetNumEntities(*entity_dim)) {
return std::nullopt;
}
return entity_dim;
}
inline LocalizationPath SelectLocalizationPath(
const FieldLayout& source_layout, const FieldLayout* target_layout = nullptr)
{
auto source_disc = source_layout.GetDiscretization();
if (source_disc == nullptr) {
return LocalizationPath::PointCloudSupports;
}
auto source_entity_dim = GetUniformDofHolderEntityDim(source_layout);
if (source_entity_dim.has_value() && *source_entity_dim == Vertex) {
return LocalizationPath::VertexAdjacencySearch;
}
if (target_layout == nullptr) {
return LocalizationPath::PointCloudSupports;
}
auto target_disc = target_layout->GetDiscretization();
auto target_entity_dim = GetUniformDofHolderEntityDim(*target_layout);
if (source_entity_dim.has_value() && *source_entity_dim == Face &&
target_entity_dim.has_value() && *target_entity_dim == Vertex &&
target_disc != nullptr && source_disc->GetDimension() == 2 &&
source_disc->SameEntities(*target_disc)) {
return LocalizationPath::CentroidToVertexAdjacencySearch;
}
return LocalizationPath::PointCloudSupports;
}
} // namespace pcms::detail
#endif // PCMS_LOCALIZATION_PATH_SELECTION_H