preCICE
Loading...
Searching...
No Matches
CoarseGrainingMapping.cpp
Go to the documentation of this file.
2
3#include <boost/container/flat_set.hpp>
5#include "mapping/Mapping.hpp"
7#include "math/math.hpp"
9#include "mesh/Vertex.hpp"
10#include "profiling/Event.hpp"
11#include "utils/IntraComm.hpp"
12#include "utils/Parallel.hpp"
13
14namespace precice::mapping {
15
16namespace impl {
18public:
19 LucyKernelFunction(short grainDim, double functionRadius)
20 : _grainDim(grainDim), _c(functionRadius) {}
21
22 double getFunctionRadius() const
23 {
24 return _c;
25 }
26
27 double evaluate(double r) const
28 {
29 if (r > _c) {
30 return 0;
31 }
32
33 constexpr double pi = 3.1415926535897931;
34 const double ratio = r / _c;
35 double res = 0;
36 double factor = 0;
37
38 // TODO: We could directly store inv c in the class itself
39 switch (_grainDim) {
40 case 1:
41 factor = 5. * (1. / (3 * _c));
42 res = factor * ((1 + ratio) * math::pow_int<3>(1 - ratio));
43 break;
44 case 2:
45 factor = 5. * (1. / (pi * math::pow_int<2>(_c)));
46 res = factor * ((1 + 3 * ratio) * math::pow_int<3>(1 - ratio));
47 break;
48 case 3:
49 factor = 105. * (1. / (16 * pi * math::pow_int<3>(_c)));
50 res = factor * ((1 + 3 * ratio) * math::pow_int<3>(1 - ratio));
51 break;
52 default:
53 PRECICE_UNREACHABLE("Unknown dimension");
54 break;
55 }
56 return res;
57 }
58
59private:
60 const short _grainDim{};
61 const double _c{};
62};
63
64} // namespace impl
65
67 Constraint constraint,
68 int meshDim,
69 double functionRadius)
70 : Mapping(constraint, meshDim, /*requiresGradientData*/ false, Mapping::InitialGuessRequirement::None)
71{
72 PRECICE_CHECK(functionRadius > 0, "Function radius must be greater zero.");
73
74 // I always assume that we deal with 3D particles, i.e., the normalization is in 3 space dimensions.
75 // 2D and 1D cases are rather unphysical and there don't seem to be a real use case for them
76 const short grainDim = 3;
77 _lucyFunction = std::make_unique<impl::LucyKernelFunction>(static_cast<short>(grainDim), functionRadius);
78}
79
81
82void CoarseGrainingMapping::mapConsistentAt(const Eigen::Ref<const Eigen::MatrixXd> &coordinates, const impl::MappingDataCache &cache, Eigen::Ref<Eigen::MatrixXd> values)
83{
84 PRECICE_ERROR("consistent constraint is not implemented.");
85}
86
87void CoarseGrainingMapping::mapConservativeAt(const Eigen::Ref<const Eigen::MatrixXd> &coordinates, const Eigen::Ref<const Eigen::MatrixXd> &source, impl::MappingDataCache &cache, Eigen::Ref<Eigen::MatrixXd> target)
88{
89 precice::profiling::Event e("map.cg.mapConservativeAt.From" + input()->getName());
90 auto &index = output()->index();
91 for (Eigen::Index i = 0; i < coordinates.cols(); ++i) {
92 mesh::Vertex src{coordinates.col(i), -1};
93 auto dest = index.getVerticesInsideBox(src, _lucyFunction->getFunctionRadius());
94
95 for (const auto &d : dest) {
96 const auto &dst = output()->vertex(d).rawCoords();
97 auto dist = computeSquaredDifference(dst, src.rawCoords());
98 auto coeff = _lucyFunction->evaluate(std::sqrt(dist));
99 target.col(d) += coeff * source.col(i);
100 }
101 }
102}
103
105{
106 PRECICE_TRACE(input()->nVertices());
107
108 PRECICE_ASSERT(input().get() != nullptr);
109 PRECICE_ASSERT(output().get() != nullptr);
110
111 const std::string baseEvent = "map.cg.computeMapping.From" + input()->getName() + "To" + output()->getName();
113
114 // Setup Direction of Mapping
115 PRECICE_CHECK(hasConstraint(CONSERVATIVE), "Only conservative constraints are implemented.");
116 // Simply ensure that the index tree is built for the output mesh
117 [[maybe_unused]] auto &index = output()->index();
118
119 _hasComputedMapping = true;
120}
121
122void CoarseGrainingMapping::mapConservative(const time::Sample &inData, Eigen::VectorXd &outData)
123{
124 PRECICE_ERROR("only just-in-time-mapping variant is implemented.");
125}
126
127void CoarseGrainingMapping::mapConsistent(const time::Sample &inData, Eigen::VectorXd &outData)
128{
129 PRECICE_ERROR("only just-in-time-mapping conservative variant is implemented.");
130}
131
133{
135 _hasComputedMapping = false;
136
137 if (getConstraint() == CONSISTENT) {
138 input()->index().clear();
139 } else {
140 output()->index().clear();
141 }
142}
143
145{
146 return "coarse-graining";
147}
148
150{
152 precice::profiling::Event e("map.cg.tagMeshFirstRound.From" + input()->getName() + "To" + output()->getName(), profiling::Synchronize);
153
154 // parallel partitioning for just-in-time mapping:
155 if (this->isJustInTimeMapping()) {
156 // in the usual case, we make use of the indexSet, which is pre-computed from the mapping
157 // for the just-in-time mapping, we can't do that since we don't have the output (local) mesh
158 // what we would need to do in theory for a perfect partitioning:
159 // find all nearest-neighbors at the 'boundary' of the access region, which would require an
160 // infinite fine sampling of output mesh nodes to be used in the computeMapping below
161 // for now, we simply tag everything and move on. The remote mesh is here already filtered
162 // through the geometric filter setting.
163 //
164 // Depending on the mapping constraint, one of these tagAll calls will do nothing, as the vertex
165 // set of the mesh is empty. From a practical point of view, we only need to apply the
166 // tagging to one of the meshes (the remote one). But calling it on both sides reliefs us from any
167 // conditional code.
168 output()->tagAll();
169 input()->tagAll();
170 return;
171 } else {
172 PRECICE_ASSERT(false, "Only just-in-time mapping is implemented, but the mapping is not configured as just-in-time.");
173 }
174}
175
177{
179 // for CG mapping no operation needed here
180}
181
182} // namespace precice::mapping
#define PRECICE_ERROR(...)
Definition LogMacros.hpp:16
#define PRECICE_TRACE(...)
Definition LogMacros.hpp:92
#define PRECICE_CHECK(check,...)
Definition LogMacros.hpp:32
#define PRECICE_ASSERT(...)
Definition assertion.hpp:85
#define PRECICE_UNREACHABLE(...)
Definition assertion.hpp:93
const std::string & getName() const
Returns the name of the mesh, as set in the config file.
Definition Mesh.cpp:242
Vertex & vertex(VertexID id)
Mutable access to a vertex by VertexID.
Definition Mesh.cpp:42
const query::Index & index() const
Call preprocess() before index() to ensure correct projection handling.
Definition Mesh.hpp:329
void tagAll()
Definition Mesh.cpp:347
void mapConsistent(const time::Sample &inData, Eigen::VectorXd &outData) override
Maps data using a consistent constraint.
void clear() final override
Removes a computed mapping.
CoarseGrainingMapping(Constraint constraint, int meshDimension, double functionRadius)
Constructor.
void tagMeshFirstRound() final override
Method used by partition. Tags vertices that could be owned by this rank.
void mapConservative(const time::Sample &inData, Eigen::VectorXd &outData) override
Maps data using a conservative constraint.
void mapConsistentAt(const Eigen::Ref< const Eigen::MatrixXd > &coordinates, const impl::MappingDataCache &cache, Eigen::Ref< Eigen::MatrixXd > values) final override
For reading data just-in-time (only consistent at the moment)
std::unique_ptr< impl::LucyKernelFunction > _lucyFunction
std::string getName() const final override
name of the coarse-graining mapping
void computeMapping() final override
Computes the mapping coefficients from the in- and output mesh.
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
For writing data just-in-time (only conservative at the moment)
void tagMeshSecondRound() final override
Method used by partition. Tags vertices that can be filtered out.
mesh::PtrMesh output() const
Returns pointer to output mesh.
Definition Mapping.cpp:92
Constraint
Specifies additional constraints for a mapping.
Definition Mapping.hpp:30
Mapping(Constraint constraint, int dimensions, bool requiresGradientData, InitialGuessRequirement initialGuessRequirement)
Constructor, takes mapping constraint.
Definition Mapping.cpp:12
mesh::PtrMesh input() const
Returns pointer to input mesh.
Definition Mapping.cpp:87
bool _hasComputedMapping
Flag to indicate whether computeMapping() has been called.
Definition Mapping.hpp:307
bool isJustInTimeMapping() const
Definition Mapping.cpp:263
Constraint getConstraint() const
Returns the constraint (consistent/conservative) of the mapping.
Definition Mapping.cpp:46
virtual bool hasConstraint(const Constraint &constraint) const
Checks whether the mapping has the given constraint or not.
Definition Mapping.cpp:248
InitialGuessRequirement
Specifies whether the mapping requires an initial guess.
Definition Mapping.hpp:64
LucyKernelFunction(short grainDim, double functionRadius)
Vertex of a mesh.
Definition Vertex.hpp:16
const RawCoords & rawCoords() const
Direct access to the coordinates.
Definition Vertex.hpp:121
contains data mapping from points to meshes.
double computeSquaredDifference(const std::array< double, 3 > &u, std::array< double, 3 > v, const std::array< bool, 3 > &activeAxis={{true, true, true}})
Deletes all dead directions from fullVector and returns a vector of reduced dimensionality.
constexpr T pow_int(const T base)
Computes the power of a given number by an integral exponent given at compile time,...
Definition math.hpp:22
static constexpr SynchronizeTag Synchronize
Convenience instance of the SynchronizeTag.
Definition Event.hpp:28
constexpr auto get(span< E, S > s) -> decltype(s[N])
Definition span.hpp:602