38 const int outDataDimensions = 3;
39 int effectiveCoordinate =
static_cast<std::underlying_type_t<MultiscaleType>
>(
_axis);
41 effectiveCoordinate ==
static_cast<std::underlying_type_t<MultiscaleType>
>(
MultiscaleAxis::Y) ||
42 effectiveCoordinate ==
static_cast<std::underlying_type_t<MultiscaleType>
>(
MultiscaleAxis::Z),
43 "Unknown multiscale axis type.");
47 PRECICE_CHECK(
input()->nVertices() == 1,
"You can only define an axial geometric multiscale 1D-{} mapping of type spread from a mesh with exactly one vertex.");
61 constexpr double distance_to_radius_threshold = 1.05;
66 for (
size_t i = 0; i < outSize; i++) {
67 Eigen::VectorXd difference(outDataDimensions);
70 double distance_to_radius = difference.norm() /
_radius;
71 PRECICE_CHECK(distance_to_radius <= distance_to_radius_threshold,
"Output mesh has vertices that do not coincide with the geometric multiscale interface defined by the input mesh. Ratio of vertex distance to radius is {} (which is larger than the assumed threshold of distance_to_radius_threshold).", distance_to_radius);
79 const int t1 = (effectiveCoordinate + 1) % 3;
80 const int t2 = (effectiveCoordinate + 2) % 3;
82 for (
size_t i = 0; i < outSize; i++) {
83 Eigen::VectorXd difference(outDataDimensions);
87 const double s1 = difference[t1] /
_radius;
88 const double s2 = difference[t2] /
_radius;
90 const double squareNorm = std::max(std::abs(s1), std::abs(s2));
92 "Output mesh has vertices that do not coincide with the square multiscale interface defined by the input mesh. "
93 "max(|xn|,|yn|) is {} (threshold {}).",
94 squareNorm, distance_to_radius_threshold);
101 PRECICE_CHECK(
input()->nVertices() > 1,
"You can only define an axial geometric multiscale 2D-3D mapping of type spread from a mesh with more than 1 vertex.");
103 Eigen::Vector3d maxC = minC;
106 minC = minC.cwiseMin(c);
107 maxC = maxC.cwiseMax(c);
109 const Eigen::Vector3d
span = maxC - minC;
121 for (
size_t j = 0; j < outSize; j++) {
123 double bestDistance2 = std::numeric_limits<double>::max();
125 for (
size_t i = 0; i < inSize; i++) {
127 Eigen::VectorXd difference = xOut - xIn;
128 double distance2 = difference.squaredNorm();
129 if (distance2 < bestDistance2) {
130 bestDistance2 = distance2;
131 bestIdx =
static_cast<int>(i);
134 PRECICE_ASSERT(bestIdx >= 0,
"Could not find nearest input vertex for output vertex {}", j);
136 double distance = std::sqrt(bestDistance2);
148 PRECICE_CHECK(
output()->nVertices() == 1,
"You can only define an axial geometric multiscale 1D-{} mapping of type collect to a mesh with exactly one vertex.");
151 "You can only define an axial geometric multiscale 1D-2D mapping of type collect to a mesh with exactly one vertex.");
154 PRECICE_CHECK(outSize > 1,
"You can only define an axial geometric multiscale 2D-3D mapping of type collect to a mesh with more than 1 vertex.");
156 Eigen::Vector3d maxC = minC;
159 minC = minC.cwiseMin(c);
160 maxC = maxC.cwiseMax(c);
162 const Eigen::Vector3d
span = maxC - minC;
170 for (
size_t i = 0; i < inSize; i++) {
172 double bestDistance = std::numeric_limits<double>::max();
174 for (
size_t j = 0; j < outSize; j++) {
176 Eigen::VectorXd difference = xIn - xOut;
177 double distance = difference.squaredNorm();
178 if (distance < bestDistance) {
179 bestDistance = distance;
180 bestIdx =
static_cast<int>(j);
183 PRECICE_ASSERT(bestIdx >= 0,
"Could not find nearest output vertex for input vertex {}", i);
215 const int inDataDimensions = inData.
dataDims;
216 const Eigen::VectorXd &inputValues = inData.
values;
217 Eigen::VectorXd &outputValues = outData;
220 PRECICE_ASSERT((inputValues.size() /
static_cast<std::size_t
>(inDataDimensions) ==
input()->nVertices()),
221 inputValues.size(), inDataDimensions,
input()->nVertices());
222 PRECICE_ASSERT((outputValues.size() /
static_cast<std::size_t
>(outDataDimensions) ==
output()->nVertices()),
223 outputValues.size(), outDataDimensions,
output()->nVertices());
228 int effectiveCoordinate;
229 if (inDataDimensions == 1) {
230 effectiveCoordinate = 0;
232 effectiveCoordinate =
static_cast<std::underlying_type_t<MultiscaleType>
>(
_axis);
234 effectiveCoordinate ==
static_cast<std::underlying_type_t<MultiscaleType>
>(
MultiscaleAxis::Y) ||
235 effectiveCoordinate ==
static_cast<std::underlying_type_t<MultiscaleType>
>(
MultiscaleAxis::Z),
236 "Unknown multiscale axis type.");
246 for (
size_t i = 0; i < outSize; i++) {
247 PRECICE_ASSERT(
static_cast<size_t>((i * outDataDimensions) + effectiveCoordinate) <
static_cast<size_t>(outputValues.size()), ((i * outDataDimensions) + effectiveCoordinate), outputValues.size());
250 constexpr double factor = 1.5;
251 outputValues((i * outDataDimensions) + effectiveCoordinate) = factor * inputValues(effectiveCoordinate) * (1 - (
_vertexDistances[i] *
_vertexDistances[i]));
254 constexpr double factor = 2.0;
255 outputValues((i * outDataDimensions) + effectiveCoordinate) = factor * inputValues(effectiveCoordinate) * (1 - (
_vertexDistances[i] *
_vertexDistances[i]));
260 constexpr double factor = 2.096;
261 constexpr double m = 0.879;
262 const double b1raw = 1.0 - s1 * s1;
263 const double b2raw = 1.0 - s2 * s2;
264 const double b1 = std::max(0.0, b1raw);
266 const double b2 = std::max(0.0, b2raw);
267 outputValues((i * outDataDimensions) + effectiveCoordinate) = factor * inputValues(effectiveCoordinate) * std::pow(b1, m) * std::pow(b2, m);
271 outputValues((i * outDataDimensions) + effectiveCoordinate) = inputValues(effectiveCoordinate);
279 for (
size_t i = 0; i < outSize; i++) {
281 PRECICE_ASSERT(
static_cast<size_t>((i * outDataDimensions) + effectiveCoordinate) <
static_cast<size_t>(outputValues.size()), (i * outDataDimensions) + effectiveCoordinate, outputValues.size());
282 PRECICE_ASSERT(
static_cast<size_t>((
static_cast<size_t>(
_nearestVertex[i]) * inDataDimensions) + effectiveCoordinate) <
static_cast<size_t>(inputValues.size()), (
static_cast<size_t>(
_nearestVertex[i]) * inDataDimensions) + effectiveCoordinate, inputValues.size());
285 outputValues((i * outDataDimensions) + effectiveCoordinate) = inputValues((
static_cast<size_t>(
_nearestVertex[i]) * inDataDimensions) + effectiveCoordinate);
289 outputValues((i * outDataDimensions) + effectiveCoordinate) = (4.0 / 3.0) * inputValues((
static_cast<size_t>(
_nearestVertex[i]) * inDataDimensions) + effectiveCoordinate) * (1.0 - r_hat * r_hat);
291 constexpr double umax_over_umean = 2.096;
292 constexpr double line_factor = 1.5;
293 constexpr double m = 0.879;
294 constexpr double eps = 1e-12;
298 const double b1raw = 1.0 - s1 * s1;
299 const double b2raw = 1.0 - s2 * s2;
300 const double b1 = std::max(eps, b1raw);
302 const double b2 = std::max(0.0, b2raw);
303 outputValues((i * outDataDimensions) + effectiveCoordinate) = inputValues((inIdx * inDataDimensions) + effectiveCoordinate) * (umax_over_umean / line_factor) * std::pow(b1, m - 1.0) * std::pow(b2, m);
314 outputValues(effectiveCoordinate) = 0.0;
315 for (
size_t i = 0; i < inSize; i++) {
316 PRECICE_ASSERT(
static_cast<size_t>((i * inDataDimensions) + effectiveCoordinate) <
static_cast<size_t>(inputValues.size()),
317 ((i * inDataDimensions) + effectiveCoordinate), inputValues.size());
318 outputValues(effectiveCoordinate) +=
319 inputValues((i * inDataDimensions) + effectiveCoordinate);
321 outputValues(effectiveCoordinate) = outputValues(effectiveCoordinate) / inSize;
326 outputValues(effectiveCoordinate) = 0.0;
327 for (
size_t i = 0; i < inSize; ++i) {
328 PRECICE_ASSERT(
static_cast<size_t>((i * inDataDimensions) + effectiveCoordinate) <
static_cast<size_t>(inputValues.size()),
329 ((i * inDataDimensions) + effectiveCoordinate), inputValues.size());
330 outputValues(effectiveCoordinate) +=
331 inputValues((i * inDataDimensions) + effectiveCoordinate);
333 outputValues(effectiveCoordinate) = outputValues(effectiveCoordinate) / inSize;
338 for (
size_t j = 0; j < outSize; j++) {
342 PRECICE_ASSERT(
static_cast<size_t>((j * outDataDimensions) + effectiveCoordinate) <
static_cast<size_t>(outputValues.size()), (j * outDataDimensions) + effectiveCoordinate, outputValues.size());
343 outputValues((j * outDataDimensions) + effectiveCoordinate) = 0.0;
346 PRECICE_ASSERT(i >= 0 &&
static_cast<size_t>(i) < inSize, i, inSize);
347 PRECICE_ASSERT(
static_cast<size_t>((
static_cast<size_t>(i) * inDataDimensions) + effectiveCoordinate) <
static_cast<size_t>(inputValues.size()), (
static_cast<size_t>(i) * inDataDimensions) + effectiveCoordinate, inputValues.size());
348 outputValues((j * outDataDimensions) + effectiveCoordinate) += inputValues((
static_cast<size_t>(i) * inDataDimensions) + effectiveCoordinate);
350 outputValues((j * outDataDimensions) + effectiveCoordinate) = outputValues((j * outDataDimensions) + effectiveCoordinate) /
static_cast<double>(
_collectBands[j].size());
354 outputValues((j * outDataDimensions) + effectiveCoordinate) *= 9.0 / 8.0;
357 const double b1raw = 1.0 - s1 * s1;
358 const double b1 = std::max(0.0, b1raw);
359 outputValues((j * outDataDimensions) + effectiveCoordinate) *= 1.03745 * std::pow(b1, 0.121);