30template <
typename RADIAL_BASIS_FUNCTION_T>
51 RADIAL_BASIS_FUNCTION_T function,
53 unsigned int verticesPerCluster,
54 double relativeOverlap,
57 bool computeEvaluationOffline =
false);
82 void mapConsistentAt(const Eigen::Ref<const Eigen::MatrixXd> &coordinates, const
impl::MappingDataCache &cache, Eigen::Ref<Eigen::MatrixXd> values) final override;
85 void mapConservativeAt(const Eigen::Ref<const Eigen::MatrixXd> &coordinates, const Eigen::Ref<const Eigen::MatrixXd> &source,
impl::MappingDataCache &cache, Eigen::Ref<Eigen::MatrixXd> target) final override;
100 std::vector<SphericalVertexCluster<RADIAL_BASIS_FUNCTION_T>>
_clusters;
148template <
typename RADIAL_BASIS_FUNCTION_T>
152 RADIAL_BASIS_FUNCTION_T function,
154 unsigned int verticesPerCluster,
155 double relativeOverlap,
158 bool computeEvaluationOffline)
168#ifdef PRECICE_NO_KOKKOS_KERNELS
180template <
typename RADIAL_BASIS_FUNCTION_T>
194 outMesh = this->
input();
196 inMesh = this->
input();
205 e.
addData(
"n clusters", centerCandidates.size());
225template <
typename RADIAL_BASIS_FUNCTION_T>
233 meshVertices.clear();
235 _clusters.reserve(centerCandidates.size());
236 for (
const auto &c : centerCandidates) {
239 const VertexID vertexID = meshVertices.size();
244 if (!cluster.
empty()) {
246 meshVertices.emplace_back(std::move(center));
247 _clusters.emplace_back(std::move(cluster));
255 PRECICE_DEBUG(
"Average number of vertices per cluster {}", std::transform_reduce(
257 [](
const auto &c) { return c.getNumberOfInputVertices(); }) /
259 PRECICE_DEBUG(
"Maximum number of vertices per cluster {}", std::max_element(
_clusters.begin(),
_clusters.end(), [](
auto &v1,
auto &v2) { return v1.getNumberOfInputVertices() < v2.getNumberOfInputVertices(); })->getNumberOfInputVertices());
260 PRECICE_DEBUG(
"Minimum number of vertices per cluster {}", std::min_element(
_clusters.begin(),
_clusters.end(), [](
auto &v1,
auto &v2) { return v1.getNumberOfInputVertices() < v2.getNumberOfInputVertices(); })->getNumberOfInputVertices());
270 for (
const auto &vertex : outMesh->
vertices()) {
274 for (
unsigned int i = 0; i < clusterIDs.size(); ++i) {
276 _clusters[clusterIDs[i]].setNormalizedWeight(normalizedWeights[i], vertex.getID());
290template <
typename RADIAL_BASIS_FUNCTION_T>
307 const auto localNumberOfClusters = clusterIDs.size();
315 "Output vertex {} of mesh \"{}\" could not be assigned to any cluster in the rbf-pum mapping. This probably means that the meshes do not match well geometry-wise: Visualize the exported preCICE meshes to confirm. "
316 "If the meshes are fine geometry-wise, you can try to increase the number of \"vertices-per-cluster\" (default is 50), the \"relative-overlap\" (default is 0.15), or disable the option \"project-to-input\". "
317 "These options are only valid for the <mapping:rbf-pum-direct/> tag.",
324 std::vector<double> weights(localNumberOfClusters);
325 std::transform(clusterIDs.cbegin(), clusterIDs.cend(), weights.begin(), [&](
const auto &ids) { return _clusters[ids].computeWeight(vertex); });
326 double weightSum = std::accumulate(weights.begin(), weights.end(),
static_cast<double>(0.));
329 if (weightSum <= 0) {
331 std::for_each(weights.begin(), weights.end(), [&weights](
auto &w) { w = 1. / weights.size(); });
337 std::transform(weights.begin(), weights.end(), weights.begin(), [weightSum](
double w) { return w / weightSum; });
340 return {clusterIDs, weights};
343template <
typename RADIAL_BASIS_FUNCTION_T>
358 std::for_each(
_clusters.begin(),
_clusters.end(), [&](
auto &cluster) { cluster.mapConservative(inData, outData); });
362template <
typename RADIAL_BASIS_FUNCTION_T>
378 std::for_each(
_clusters.begin(),
_clusters.end(), [&](
auto &clusters) { clusters.mapConsistent(inData, outData); });
382template <
typename RADIAL_BASIS_FUNCTION_T>
396 for (Eigen::Index v = 0; v < coordinates.cols(); ++v) {
400 for (std::size_t i = 0; i < clusterIDs.size(); ++i) {
402 auto id = clusterIDs[i];
404 Eigen::VectorXd res = normalizedWeights[i] * source.col(v);
410template <
typename RADIAL_BASIS_FUNCTION_T>
418 for (std::size_t c = 0; c <
_clusters.size(); ++c) {
420 if (cache.
p[c].squaredNorm() > 0) {
426template <
typename RADIAL_BASIS_FUNCTION_T>
433 for (std::size_t c = 0; c <
_clusters.size(); ++c) {
438template <
typename RADIAL_BASIS_FUNCTION_T>
446 for (std::size_t c = 0; c <
_clusters.size(); ++c) {
451template <
typename RADIAL_BASIS_FUNCTION_T>
464 for (Eigen::Index v = 0; v < values.cols(); ++v) {
468 for (std::size_t i = 0; i < clusterIDs.size(); ++i) {
470 auto id = clusterIDs[i];
473 values.col(v) += localRes;
478template <
typename RADIAL_BASIS_FUNCTION_T>
484 filterMesh = this->
output();
485 outMesh = this->
input();
487 filterMesh = this->
input();
491 if (outMesh->
empty())
530 auto verticesNew = filterMesh->index().getVerticesInsideBox(localBB);
532 std::for_each(verticesNew.begin(), verticesNew.end(), [&filterMesh](
VertexID v) { filterMesh->vertex(v).tag(); });
535template <
typename RADIAL_BASIS_FUNCTION_T>
541template <
typename RADIAL_BASIS_FUNCTION_T>
546 auto dataRadius = centerMesh.
createData(
"radius", 1, -1);
547 auto dataCardinality = centerMesh.
createData(
"number-of-vertices", 1, -1);
550 for (
unsigned int i = 0; i <
_clusters.size(); ++i) {
551 dataCardinality->values()[i] =
static_cast<double>(
_clusters[i].getNumberOfInputVertices());
558 int numberOfVertices = centerMesh.
nVertices();
570 vertexOffsets[0] = centerMesh.
nVertices();
574 int numberOfSecondaryRankVertices = -1;
577 vertexOffsets[secondaryRank] = numberOfSecondaryRankVertices + vertexOffsets[secondaryRank - 1];
586 dataRadius->setSampleAtTime(0,
time::Sample{1, dataRadius->values()});
587 dataCardinality->setSampleAtTime(0,
time::Sample{1, dataCardinality->values()});
592template <
typename RADIAL_BASIS_FUNCTION_T>
602template <
typename RADIAL_BASIS_FUNCTION_T>
605 return "partition-of-unity RBF";
#define PRECICE_DEBUG(...)
#define PRECICE_TRACE(...)
#define PRECICE_CHECK(check,...)
#define PRECICE_ASSERT(...)
VertexContainer & vertices()
Returns modifieable container holding all vertices.
const std::string & getName() const
Returns the name of the mesh, as set in the config file.
std::size_t nVertices() const
Returns the number of vertices.
bool isJustInTime() const
bool empty() const
Does the mesh contain any vertices?
const BoundingBox & getBoundingBox() const
Returns the bounding box of the mesh.
void doExport(int index, double time) final override
Export the mesh and writes files.
mesh::PtrMesh output() const
Returns pointer to output mesh.
Constraint
Specifies additional constraints for a mapping.
int getDimensions() const
Mapping(Constraint constraint, int dimensions, bool requiresGradientData, InitialGuessRequirement initialGuessRequirement)
Constructor, takes mapping constraint.
mesh::PtrMesh input() const
Returns pointer to input mesh.
bool _hasComputedMapping
Flag to indicate whether computeMapping() has been called.
bool isScaledConsistent() const
Returns true if mapping is a form of scaled consistent mapping.
void setInputRequirement(MeshRequirement requirement)
Sets the mesh requirement for the input mesh.
void setOutputRequirement(MeshRequirement requirement)
Sets the mesh requirement for the output mesh.
virtual bool hasConstraint(const Constraint &constraint) const
Checks whether the mapping has the given constraint or not.
InitialGuessRequirement
Specifies whether the mapping requires an initial guess.
void tagMeshSecondRound() final override
const bool _useBatchedSolver
void tagMeshFirstRound() final override
std::unique_ptr< BatchedRBFSolver< RBF > > _batchedSolver
const bool _computeEvaluationOffline
PartitionOfUnityMapping(Mapping::Constraint constraint, int dimension, RADIAL_BASIS_FUNCTION_T function, Polynomial polynomial, unsigned int verticesPerCluster, double relativeOverlap, bool projectToInput, MappingConfiguration::GinkgoParameter ginkgoParameter=MappingConfiguration::GinkgoParameter(), bool computeEvaluationOffline=false)
std::unique_ptr< mesh::Mesh > _centerMesh
void exportClusterCentersAsVTU(mesh::Mesh ¢ers)
std::pair< std::vector< int >, std::vector< double > > computeNormalizedWeight(const mesh::Vertex &v, std::string_view mesh)
precice::logging::Logger _log
void initializeMappingDataCache(impl::MappingDataCache &cache) final override
const double _relativeOverlap
void mapConservativeAt(const Eigen::Ref< const Eigen::MatrixXd > &coordinates, const Eigen::Ref< const Eigen::MatrixXd > &source, impl::MappingDataCache &cache, Eigen::Ref< Eigen::MatrixXd > target) final override
MappingConfiguration::GinkgoParameter _ginkgoParameter
std::vector< SphericalVertexCluster< RBF > > _clusters
const bool _projectToInput
std::string getName() const final override
void mapConsistent(const time::Sample &inData, Eigen::VectorXd &outData) override
Maps data using a consistent constraint.
void _computeCPU(mesh::PtrMesh inMesh, mesh::PtrMesh outMesh, double clusterRadius, const std::vector< mesh::Vertex > ¢erCandidates)
void mapConsistentAt(const Eigen::Ref< const Eigen::MatrixXd > &coordinates, const impl::MappingDataCache &cache, Eigen::Ref< Eigen::MatrixXd > values) final override
const unsigned int _verticesPerCluster
void mapConservative(const time::Sample &inData, Eigen::VectorXd &outData) override
Maps data using a conservative constraint.
void updateMappingDataCache(impl::MappingDataCache &cache, const Eigen::Ref< const Eigen::VectorXd > &in) final override
void computeMapping() final override
void completeJustInTimeMapping(impl::MappingDataCache &cache, Eigen::Ref< Eigen::MatrixXd > buffer) final override
void clear() final override
Container and creator for meshes.
static constexpr MeshID MESH_ID_UNDEFINED
Use if the id of the mesh is not necessary.
std::size_t nVertices() const
Returns the number of vertices.
PtrData & createData(const std::string &name, int dimension, DataID id, int waveformDegree=time::Time::DEFAULT_WAVEFORM_DEGREE)
Create only data for vertex.
const VertexOffsets & getVertexOffsets() const
std::vector< int > VertexOffsets
void setVertexOffsets(VertexOffsets vertexOffsets)
Only used for tests.
void allocateDataValues()
Allocates memory for the vertex data values and corresponding gradient values.
VertexID getID() const
Returns the unique (among vertices of one mesh on one processor) ID of the vertex.
void setCoords(const VECTOR_T &coordinates)
Sets the coordinates of the vertex.
Eigen::VectorXd getCoords() const
Returns the coordinates of the vertex.
void stop()
Stops a running event.
void addData(std::string_view key, int value)
Adds named integer data, associated to an event.
Class to query the index trees of the mesh.
std::vector< VertexID > getVerticesInsideBox(const mesh::Vertex ¢erVertex, double radius)
Return all the vertices inside the box formed by vertex and radius (boundary exclusive)
static int getSize()
Number of ranks. This includes ranks from both participants, e.g. minimal size is 2.
static Rank getRank()
Current rank.
static bool isPrimary()
True if this process is running the primary rank.
static auto allSecondaryRanks()
Returns an iterable range over salve ranks [1, _size)
static bool isSecondary()
True if this process is running a secondary rank.
static com::PtrCommunication & getCommunication()
Intra-participant communication.
contains the logging framework.
std::tuple< double, Vertices > createClustering(mesh::PtrMesh inMesh, mesh::PtrMesh outMesh, double relativeOverlap, unsigned int verticesPerCluster, bool projectClustersToInput)
Creates a clustering as a collection of Vertices (representing the cluster centers) and a cluster rad...
double estimateClusterRadius(unsigned int verticesPerCluster, mesh::PtrMesh inMesh, const mesh::BoundingBox &bb)
Computes an estimate for the cluster radius, which results in approximately verticesPerCluster vertic...
contains data mapping from points to meshes.
Polynomial
How to handle the polynomial?
provides Mesh, Data and primitives.
std::shared_ptr< Mesh > PtrMesh
static constexpr SynchronizeTag Synchronize
Convenience instance of the SynchronizeTag.
Main namespace of the precice library.
bool syncMode
Enabled further inter- and intra-solver synchronisation.
std::vector< Eigen::MatrixXd > polynomialContributions
std::vector< Eigen::MatrixXd > p
int getDataDimensions() const
Returns the number of data components.