-
-
Notifications
You must be signed in to change notification settings - Fork 169
/
NearestNeighborBaseMapping.cpp
134 lines (108 loc) · 3.87 KB
/
NearestNeighborBaseMapping.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include "NearestNeighborBaseMapping.hpp"
#include <boost/container/flat_set.hpp>
#include <functional>
#include <iostream>
#include "logging/LogMacros.hpp"
#include "mapping/Mapping.hpp"
#include "mesh/SharedPointer.hpp"
#include "mesh/Vertex.hpp"
#include "utils/Event.hpp"
#include "utils/Parallel.hpp"
#include "utils/Statistics.hpp"
#include "utils/assertion.hpp"
namespace precice {
extern bool syncMode;
namespace mapping {
NearestNeighborBaseMapping::NearestNeighborBaseMapping(
Constraint constraint,
int dimensions,
bool requiresGradientData,
std::string mappingName,
std::string mappingNameShort)
: Mapping(constraint, dimensions, requiresGradientData),
mappingName(mappingName),
mappingNameShort(mappingNameShort)
{
}
void NearestNeighborBaseMapping::computeMapping()
{
PRECICE_TRACE(input()->vertices().size());
PRECICE_ASSERT(input().get() != nullptr);
PRECICE_ASSERT(output().get() != nullptr);
const std::string baseEvent = "map." + mappingNameShort + ".computeMapping.From" + input()->getName() + "To" + output()->getName();
precice::utils::Event e(baseEvent, precice::syncMode);
// Setup Direction of Mapping
mesh::PtrMesh origins, searchSpace;
if (hasConstraint(CONSERVATIVE)) {
PRECICE_DEBUG("Compute conservative mapping");
origins = input();
searchSpace = output();
} else {
PRECICE_DEBUG((hasConstraint(CONSISTENT) ? "Compute consistent mapping" : "Compute scaled-consistent mapping"));
origins = output();
searchSpace = input();
}
// Set up of output arrays
const size_t verticesSize = origins->vertices().size();
const auto & sourceVertices = origins->vertices();
_vertexIndices.resize(verticesSize);
// Needed for error calculations
utils::statistics::DistanceAccumulator distanceStatistics;
auto &index = searchSpace->index();
for (size_t i = 0; i < verticesSize; ++i) {
const auto &matchedVertex = index.getClosestVertex(sourceVertices[i].getCoords());
_vertexIndices[i] = matchedVertex.index;
distanceStatistics(matchedVertex.distance);
}
// For gradient mapping, the calculation of offsets between source and matched vertex necessary
onMappingComputed(origins, searchSpace);
// This is the distance object between the coordinates of the vertices and its match in the mesh.
// This prints min, max, average and count of the distances.
if (distanceStatistics.empty()) {
PRECICE_INFO("Mapping distance not available due to empty partition.");
} else {
PRECICE_INFO("Mapping distance {}", distanceStatistics);
}
_hasComputedMapping = true;
}
void NearestNeighborBaseMapping::clear()
{
PRECICE_TRACE();
_vertexIndices.clear();
_hasComputedMapping = false;
if (requiresGradientData())
_offsetsMatched.clear();
if (getConstraint() == CONSISTENT) {
input()->index().clear();
} else {
output()->index().clear();
}
}
void NearestNeighborBaseMapping::onMappingComputed(mesh::PtrMesh origins, mesh::PtrMesh searchSpace)
{
// Does nothing by default
}
void NearestNeighborBaseMapping::tagMeshFirstRound()
{
PRECICE_TRACE();
precice::utils::Event e("map." + mappingNameShort + ".tagMeshFirstRound.From" + input()->getName() + "To" + output()->getName(), precice::syncMode);
computeMapping();
// Lookup table of all indices used in the mapping
const boost::container::flat_set<int> indexSet(_vertexIndices.begin(), _vertexIndices.end());
// Get the source mesh depending on the constraint
const mesh::PtrMesh &source = hasConstraint(CONSERVATIVE) ? output() : input();
// Tag all vertices used in the mapping
for (mesh::Vertex &v : source->vertices()) {
if (indexSet.count(v.getID()) != 0) {
v.tag();
}
}
clear();
}
void NearestNeighborBaseMapping::tagMeshSecondRound()
{
PRECICE_TRACE();
// for NN mapping no operation needed here
}
} // namespace mapping
} // namespace precice