preCICE v3.1.1
Loading...
Searching...
No Matches
BasisFunctions.hpp
Go to the documentation of this file.
1#pragma once
2
3#if defined(__NVCC__)
4
5#include <cuda_runtime.h>
6#define BOOST_PP_VARIADICS 1
7#define PRECICE_HOST_DEVICE __host__ __device__
8#define PRECICE_MEMORY_SPACE __device__
9#define FMA fma
10
11#elif defined(__HIPCC__)
12
13// #define __HIP_PLATFORM_AMD__
14#include <hip/hip_runtime.h>
15#define PRECICE_HOST_DEVICE __host__ __device__
16#define PRECICE_MEMORY_SPACE __device__
17#define FMA fma
18
19#else
20
21#define PRECICE_HOST_DEVICE
22#define PRECICE_MEMORY_SPACE
23#define FMA std::fma
24
25#endif
26
28
29#include "logging/Logger.hpp"
30#include "math/math.hpp"
31
32namespace precice {
33namespace mapping {
34
49 double parameter1{};
50 double parameter2{};
51 double parameter3{};
52};
53
56 static constexpr bool hasCompactSupport()
57 {
58 return true;
59 }
60};
61
64 static constexpr bool hasCompactSupport()
65 {
66 return false;
67 }
68
69 static constexpr double getSupportRadius()
70 {
72 }
73};
74
80template <bool isDefinite>
82 static constexpr bool isStrictlyPositiveDefinite()
83 {
84 return isDefinite;
85 }
86};
87
96 public DefiniteFunction<false> {
97public:
98 double evaluate(double radius) const
99 {
100 return operator()(radius, _params);
101 }
102
103 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
104 {
105 // We don't need to read any values from params since there is no need here
106 return std::log(std::max(radius, NUMERICAL_ZERO_DIFFERENCE)) * math::pow_int<2>(radius);
107 }
108
113
114private:
116};
117
126 public DefiniteFunction<false> {
127public:
128 explicit Multiquadrics(double c)
129 : _cPow2(math::pow_int<2>(c))
130 {
132 }
133
134 double evaluate(double radius) const
135 {
136 return operator()(radius, _params);
137 }
138
139 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
140 {
141 double cPow2 = params.parameter1;
142 return std::sqrt(cPow2 + math::pow_int<2>(radius));
143 }
144
149
150private:
151 double _cPow2;
153};
154
164 public DefiniteFunction<true> {
165public:
166 explicit InverseMultiquadrics(double c)
167 : _cPow2(math::pow_int<2>(c))
168 {
169#if !defined(__NVCC__) || !defined(__HIPCC__)
170 logging::Logger _log{"mapping::InverseMultiQuadrics"};
172 "Shape parameter for radial-basis-function inverse multiquadric has to be larger than zero. Please update the \"shape-parameter\" attribute.");
173#endif
175 }
176
177 double evaluate(double radius) const
178 {
179 return operator()(radius, _params);
180 }
181
182 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
183 {
184 double cPow2 = params.parameter1;
185 return 1.0 / std::sqrt(cPow2 + math::pow_int<2>(radius));
186 }
187
192
193private:
194 double const _cPow2;
195
197};
198
207 public DefiniteFunction<false> {
208public:
209 double evaluate(double radius) const
210 {
211 return operator()(radius, _params);
212 }
213
214 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
215 {
216 return std::abs(radius);
217 }
218
223
224private:
226};
227
237 public DefiniteFunction<true> {
238public:
239 Gaussian(const double shape, const double supportRadius = std::numeric_limits<double>::infinity())
240 : _shape(shape),
241 _supportRadius(supportRadius)
242 {
243#if !defined(__NVCC__) || !defined(__HIPCC__)
244 logging::Logger _log{"mapping::Gaussian"};
246 "Shape parameter for radial-basis-function gaussian has to be larger than zero. Please update the \"shape-parameter\" attribute.");
248 "Support radius for radial-basis-function gaussian has to be larger than zero. Please update the \"support-radius\" attribute.");
249#endif
250
251 double threshold = std::sqrt(-std::log(cutoffThreshold)) / shape;
252 _supportRadius = std::min(supportRadius, threshold);
256 if (supportRadius < std::numeric_limits<double>::infinity()) {
257 _deltaY = evaluate(supportRadius);
259 }
260 }
261
262 double getSupportRadius() const
263 {
264 return _supportRadius;
265 }
266
267 double evaluate(const double radius) const
268 {
269 return operator()(radius, _params);
270 }
271
272 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
273 {
274 double shape = params.parameter1;
275 double supportRadius = params.parameter2;
276 double deltaY = params.parameter3;
277
278 if (radius > supportRadius)
279 return 0.0;
280 return std::exp(-math::pow_int<2>(shape * radius)) - deltaY;
281 }
282
287
288public:
290 static constexpr double cutoffThreshold = 1e-9;
291
292private:
293 double const _shape;
294
297
298 double _deltaY = 0;
299
301};
302
315 public DefiniteFunction<true> {
316public:
317 explicit CompactThinPlateSplinesC2(double supportRadius)
318 {
319#if !defined(__NVCC__) || !defined(__HIPCC__)
320 logging::Logger _log{"mapping::CompactThinPlateSplinesC2"};
321 PRECICE_CHECK(math::greater(supportRadius, 0.0),
322 "Support radius for radial-basis-function compact thin-plate-splines c2 has to be larger than zero. Please update the \"support-radius\" attribute.");
323#endif
324 _r_inv = 1. / supportRadius;
326 }
327
328 double getSupportRadius() const
329 {
330 return 1. / _r_inv;
331 }
332
333 double evaluate(double radius) const
334 {
335 return operator()(radius, _params);
336 }
337
338 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
339 {
340 double r_inv = params.parameter1;
341 const double p = radius * r_inv;
342 if (p >= 1)
343 return 0.0;
344 return 1.0 - 30.0 * math::pow_int<2>(p) - 10.0 * math::pow_int<3>(p) + 45.0 * math::pow_int<4>(p) - 6.0 * math::pow_int<5>(p) - math::pow_int<3>(p) * 60.0 * std::log(std::max(p, NUMERICAL_ZERO_DIFFERENCE));
345 }
346
351
352private:
353 double _r_inv;
355};
356
368 public DefiniteFunction<true> {
369public:
370 explicit CompactPolynomialC0(double supportRadius)
371 {
372#if !defined(__NVCC__) || !defined(__HIPCC__)
373 logging::Logger _log{"mapping::CompactPolynomialC0"};
374 PRECICE_CHECK(math::greater(supportRadius, 0.0),
375 "Support radius for radial-basis-function compact polynomial c0 has to be larger than zero. Please update the \"support-radius\" attribute.");
376#endif
377 _r_inv = 1. / supportRadius;
379 }
380
381 double getSupportRadius() const
382 {
383 return 1. / _r_inv;
384 }
385
386 double evaluate(double radius) const
387 {
388 return operator()(radius, _params);
389 }
390
391 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
392 {
393 double r_inv = params.parameter1;
394 const double p = radius * r_inv;
395 if (p >= 1)
396 return 0.0;
397 return math::pow_int<2>(1.0 - p);
398 }
399
404
405private:
406 double _r_inv;
408};
409
421 public DefiniteFunction<true> {
422public:
423 explicit CompactPolynomialC2(double supportRadius)
424 {
425#if !defined(__NVCC__) || !defined(__HIPCC__)
426 logging::Logger _log{"mapping::CompactPolynomialC2"};
427 PRECICE_CHECK(math::greater(supportRadius, 0.0),
428 "Support radius for radial-basis-function compact polynomial c2 has to be larger than zero. Please update the \"support-radius\" attribute.");
429#endif
430
431 _r_inv = 1. / supportRadius;
433 }
434
435 double getSupportRadius() const
436 {
437 return 1. / _r_inv;
438 }
439
440 double evaluate(double radius) const
441 {
442 return operator()(radius, _params);
443 }
444
445 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
446 {
447 double r_inv = params.parameter1;
448 const double p = radius * r_inv;
449 if (p >= 1)
450 return 0.0;
451 return math::pow_int<4>(1.0 - p) * FMA(4, p, 1);
452 }
453
458
459private:
460 double _r_inv;
462};
463
475 public DefiniteFunction<true> {
476public:
477 explicit CompactPolynomialC4(double supportRadius)
478 {
479#if !defined(__NVCC__) || !defined(__HIPCC__)
480 logging::Logger _log{"mapping::CompactPolynomialC4"};
481 PRECICE_CHECK(math::greater(supportRadius, 0.0),
482 "Support radius for radial-basis-function compact polynomial c4 has to be larger than zero. Please update the \"support-radius\" attribute.");
483#endif
484
485 _r_inv = 1. / supportRadius;
487 }
488
489 double getSupportRadius() const
490 {
491 return 1. / _r_inv;
492 }
493
494 double evaluate(double radius) const
495 {
496 return operator()(radius, _params);
497 }
498
499 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
500 {
501 double r_inv = params.parameter1;
502 const double p = radius * r_inv;
503 if (p >= 1)
504 return 0.0;
505 return math::pow_int<6>(1.0 - p) * (35 * math::pow_int<2>(p) + FMA(18, p, 3));
506 }
507
512
513private:
514 double _r_inv;
516};
517
529 public DefiniteFunction<true> {
530public:
531 explicit CompactPolynomialC6(double supportRadius)
532 {
533#if !defined(__NVCC__) || !defined(__HIPCC__)
534 logging::Logger _log{"mapping::CompactPolynomialC6"};
535 PRECICE_CHECK(math::greater(supportRadius, 0.0),
536 "Support radius for radial-basis-function compact polynomial c6 has to be larger than zero. Please update the \"support-radius\" attribute.");
537#endif
538 _r_inv = 1. / supportRadius;
540 }
541
542 double getSupportRadius() const
543 {
544 return 1. / _r_inv;
545 }
546
547 double evaluate(double radius) const
548 {
549 return operator()(radius, _params);
550 }
551
552 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
553 {
554 double r_inv = params.parameter1;
555 const double p = radius * r_inv;
556 if (p >= 1)
557 return 0.0;
558 return math::pow_int<8>(1.0 - p) * (32.0 * math::pow_int<3>(p) + 25.0 * math::pow_int<2>(p) + FMA(8.0, p, 1.0));
559 };
560
562 {
563 return _params;
564 }
565
566private:
567 double _r_inv;
569};
570
582 public DefiniteFunction<true> {
583public:
584 explicit CompactPolynomialC8(double supportRadius)
585 {
586#if !defined(__NVCC__) || !defined(__HIPCC__)
587 logging::Logger _log{"mapping::CompactPolynomialC8"};
588 PRECICE_CHECK(math::greater(supportRadius, 0.0),
589 "Support radius for radial-basis-function compact polynomial c6 has to be larger than zero. Please update the \"support-radius\" attribute.");
590#endif
591 _r_inv = 1. / supportRadius;
593 }
594
595 double getSupportRadius() const
596 {
597 return 1. / _r_inv;
598 }
599
600 double evaluate(double radius) const
601 {
602 return operator()(radius, _params);
603 }
604
605 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
606 {
607 double r_inv = params.parameter1;
608 const double p = radius * r_inv;
609 if (p >= 1)
610 return 0.0;
611 return math::pow_int<10>(1.0 - p) * (1287.0 * math::pow_int<4>(p) + 1350.0 * math::pow_int<3>(p) + 630.0 * math::pow_int<2>(p) + 150.0 * p + 15);
612 };
613
615 {
616 return _params;
617 }
618
619private:
620 double _r_inv;
622};
623} // namespace mapping
624} // namespace precice
#define PRECICE_HOST_DEVICE
#define PRECICE_MEMORY_SPACE
PRECICE_MEMORY_SPACE const double NUMERICAL_ZERO_DIFFERENCE
#define FMA
#define PRECICE_CHECK(check,...)
Definition LogMacros.hpp:35
This class provides a lightweight logger.
Definition Logger.hpp:16
Wendland radial basis function with compact support.
PRECICE_HOST_DEVICE double operator()(const double radius, const RadialBasisParameters params) const
RadialBasisParameters getFunctionParameters()
double evaluate(double radius) const
Wendland radial basis function with compact support.
PRECICE_HOST_DEVICE double operator()(const double radius, const RadialBasisParameters params) const
RadialBasisParameters getFunctionParameters()
double evaluate(double radius) const
Wendland radial basis function with compact support.
double evaluate(double radius) const
PRECICE_HOST_DEVICE double operator()(const double radius, const RadialBasisParameters params) const
RadialBasisParameters getFunctionParameters()
Wendland radial basis function with compact support.
PRECICE_HOST_DEVICE double operator()(const double radius, const RadialBasisParameters params) const
double evaluate(double radius) const
const RadialBasisParameters getFunctionParameters()
Wendland radial basis function with compact support.
const RadialBasisParameters getFunctionParameters()
double evaluate(double radius) const
PRECICE_HOST_DEVICE double operator()(const double radius, const RadialBasisParameters params) const
Radial basis function with compact support.
PRECICE_HOST_DEVICE double operator()(const double radius, const RadialBasisParameters params) const
Radial basis function with global and compact support.
RadialBasisParameters _params
PRECICE_HOST_DEVICE double operator()(const double radius, const RadialBasisParameters params) const
Gaussian(const double shape, const double supportRadius=std::numeric_limits< double >::infinity())
double evaluate(const double radius) const
static constexpr double cutoffThreshold
Below that value the function is supposed to be zero. Defines the support radius if not explicitly gi...
RadialBasisParameters getFunctionParameters()
double _supportRadius
Either explicitly set (from cutoffThreshold) or computed supportRadius.
Radial basis function with global support.
double evaluate(double radius) const
PRECICE_HOST_DEVICE double operator()(const double radius, const RadialBasisParameters params) const
RadialBasisParameters getFunctionParameters()
Radial basis function with global support.
PRECICE_HOST_DEVICE double operator()(const double radius, const RadialBasisParameters params) const
double evaluate(double radius) const
RadialBasisParameters getFunctionParameters()
Radial basis function with global support.
double evaluate(double radius) const
PRECICE_HOST_DEVICE double operator()(const double radius, const RadialBasisParameters params) const
RadialBasisParameters getFunctionParameters()
Radial basis function with global support.
PRECICE_HOST_DEVICE double operator()(const double radius, const RadialBasisParameters params) const
double evaluate(double radius) const
RadialBasisParameters getFunctionParameters()
T exp(T... args)
T log(T... args)
T max(T... args)
T min(T... args)
std::enable_if< std::is_arithmetic< Scalar >::value, bool >::type greater(Scalar A, Scalar B, Scalar tolerance=NUMERICAL_ZERO_DIFFERENCE)
Main namespace of the precice library.
static precice::logging::Logger _log("precicec")
T sqrt(T... args)
Base class for RBF with compact support.
static constexpr bool hasCompactSupport()
Base class for RBF functions to distinguish positive definite functions.
static constexpr bool isStrictlyPositiveDefinite()
Base class for RBF without compact support.
static constexpr double getSupportRadius()
static constexpr bool hasCompactSupport()
Wrapper struct that is used to transfer RBF-specific parameters to the GPU.