preCICE v3.4.1
Loading...
Searching...
No Matches
BasisFunctions.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <stdexcept>
4
5#if !defined(PRECICE_NO_GINKGO) || !defined(PRECICE_NO_KOKKOS_KERNELS)
6
7#include <Kokkos_Core.hpp>
8
9#define PRECICE_HOST_DEVICE KOKKOS_FUNCTION
10#define PRECICE_FMA Kokkos::fma
11#define PRECICE_LOG Kokkos::log
12
13#else
14
15#define PRECICE_HOST_DEVICE
16#define PRECICE_FMA std::fma
17#define PRECICE_LOG std::log
18
19#endif
20
21#define NUMERICAL_ZERO_DIFFERENCE_DEVICE 1.0e-14
22
23#include "math/math.hpp"
24
25namespace precice::mapping {
26
41 double parameter1{};
42 double parameter2{};
43 double parameter3{};
44};
45
48 static constexpr bool hasCompactSupport()
49 {
50 return true;
51 }
52};
53
56 static constexpr bool hasCompactSupport()
57 {
58 return false;
59 }
60
61 static constexpr double getSupportRadius()
62 {
64 }
65};
66
72template <bool isDefinite>
74 static constexpr bool isStrictlyPositiveDefinite()
75 {
76 return isDefinite;
77 }
78};
79
88 public DefiniteFunction<false> {
89public:
90 double evaluate(double radius) const
91 {
92 return operator()(radius, _params);
93 }
94
95 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
96 {
97 // We don't need to read any values from params since there is no need here
99 }
100
105
106private:
108};
109
118 public DefiniteFunction<false> {
119public:
120 explicit Multiquadrics(double c)
121 : _cPow2(math::pow_int<2>(c))
122 {
123 _params.parameter1 = _cPow2;
124 }
125
126 double evaluate(double radius) const
127 {
128 return operator()(radius, _params);
129 }
130
131 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
132 {
133 double cPow2 = params.parameter1;
134 return std::sqrt(cPow2 + math::pow_int<2>(radius));
135 }
136
141
142private:
143 double _cPow2;
145};
146
156 public DefiniteFunction<true> {
157public:
158 explicit InverseMultiquadrics(double c)
159 : _cPow2(math::pow_int<2>(c))
160 {
161 if (!math::greater(c, 0.0)) {
162 throw std::invalid_argument{"Shape parameter for radial-basis-function inverse multiquadric has to be larger than zero. Please update the \"shape-parameter\" attribute."};
163 }
164 _params.parameter1 = _cPow2;
165 }
166
167 double evaluate(double radius) const
168 {
169 return operator()(radius, _params);
170 }
171
172 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
173 {
174 double cPow2 = params.parameter1;
175 return 1.0 / std::sqrt(cPow2 + math::pow_int<2>(radius));
176 }
177
182
183private:
184 double const _cPow2;
185
187};
188
197 public DefiniteFunction<false> {
198public:
199 double evaluate(double radius) const
200 {
201 return operator()(radius, _params);
202 }
203
204 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
205 {
206 return std::abs(radius);
207 }
208
213
214private:
216};
217
227 public DefiniteFunction<true> {
228public:
229 Gaussian(const double shape, const double supportRadius = std::numeric_limits<double>::infinity())
230 : _shape(shape),
231 _supportRadius(supportRadius)
232 {
233 if (!math::greater(_shape, 0.0)) {
235 "Shape parameter for radial-basis-function gaussian has to be larger than zero. Please update the \"shape-parameter\" attribute."};
236 }
237 if (!math::greater(_supportRadius, 0.0)) {
239 "Support radius for radial-basis-function gaussian has to be larger than zero. Please update the \"support-radius\" attribute."};
240 }
241
242 double threshold = std::sqrt(-std::log(cutoffThreshold)) / shape;
243 _supportRadius = std::min(supportRadius, threshold);
244 _params.parameter1 = _shape;
245 _params.parameter2 = _supportRadius;
246 _params.parameter3 = _deltaY;
247 if (supportRadius < std::numeric_limits<double>::infinity()) {
248 _deltaY = evaluate(supportRadius);
249 _params.parameter3 = _deltaY;
250 }
251 }
252
253 double getSupportRadius() const
254 {
255 return _supportRadius;
256 }
257
258 double evaluate(const double radius) const
259 {
260 return operator()(radius, _params);
261 }
262
263 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
264 {
265 double shape = params.parameter1;
266 double supportRadius = params.parameter2;
267 double deltaY = params.parameter3;
268
269 if (radius > supportRadius)
270 return 0.0;
271 return std::exp(-math::pow_int<2>(shape * radius)) - deltaY;
272 }
273
278
279public:
281 static constexpr double cutoffThreshold = 1e-9;
282
283private:
284 double const _shape;
285
288
289 double _deltaY = 0;
290
292};
293
306 public DefiniteFunction<true> {
307public:
308 explicit CompactThinPlateSplinesC2(double supportRadius)
309 {
310 if (!math::greater(supportRadius, 0.0)) {
312 "Support radius for radial-basis-function compact thin-plate-splines c2 has to be larger than zero. Please update the \"support-radius\" attribute."};
313 }
314 _r_inv = 1. / supportRadius;
315 _params.parameter1 = _r_inv;
316 }
317
318 double getSupportRadius() const
319 {
320 return 1. / _r_inv;
321 }
322
323 double evaluate(double radius) const
324 {
325 return operator()(radius, _params);
326 }
327
328 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
329 {
330 double r_inv = params.parameter1;
331 const double p = radius * r_inv;
332 if (p >= 1)
333 return 0.0;
334 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 * PRECICE_LOG(std::max(p, NUMERICAL_ZERO_DIFFERENCE_DEVICE));
335 }
336
341
342private:
343 double _r_inv;
345};
346
358 public DefiniteFunction<true> {
359public:
360 explicit CompactPolynomialC0(double supportRadius)
361 {
362 if (!math::greater(supportRadius, 0.0)) {
364 "Support radius for radial-basis-function compact polynomial c0 has to be larger than zero. Please update the \"support-radius\" attribute."};
365 }
366 _r_inv = 1. / supportRadius;
367 _params.parameter1 = _r_inv;
368 }
369
370 double getSupportRadius() const
371 {
372 return 1. / _r_inv;
373 }
374
375 double evaluate(double radius) const
376 {
377 return operator()(radius, _params);
378 }
379
380 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
381 {
382 double r_inv = params.parameter1;
383 const double p = radius * r_inv;
384 if (p >= 1)
385 return 0.0;
386 return math::pow_int<2>(1.0 - p);
387 }
388
393
394private:
395 double _r_inv;
397};
398
410 public DefiniteFunction<true> {
411public:
412 explicit CompactPolynomialC2(double supportRadius)
413 {
414 if (!math::greater(supportRadius, 0.0)) {
416 "Support radius for radial-basis-function compact polynomial c2 has to be larger than zero. Please update the \"support-radius\" attribute."};
417 }
418
419 _r_inv = 1. / supportRadius;
420 _params.parameter1 = _r_inv;
421 }
422
423 double getSupportRadius() const
424 {
425 return 1. / _r_inv;
426 }
427
428 double evaluate(double radius) const
429 {
430 return operator()(radius, _params);
431 }
432
433 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
434 {
435 double r_inv = params.parameter1;
436 const double p = radius * r_inv;
437 if (p >= 1)
438 return 0.0;
439 return math::pow_int<4>(1.0 - p) * PRECICE_FMA(4, p, 1);
440 }
441
443 {
444 return _params;
445 }
446
447private:
448 double _r_inv;
450};
451
463 public DefiniteFunction<true> {
464public:
465 explicit CompactPolynomialC4(double supportRadius)
466 {
467 if (!math::greater(supportRadius, 0.0)) {
469 "Support radius for radial-basis-function compact polynomial c4 has to be larger than zero. Please update the \"support-radius\" attribute."};
470 }
471
472 _r_inv = 1. / supportRadius;
473 _params.parameter1 = _r_inv;
474 }
475
476 double getSupportRadius() const
477 {
478 return 1. / _r_inv;
479 }
480
481 double evaluate(double radius) const
482 {
483 return operator()(radius, _params);
484 }
485
486 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
487 {
488 double r_inv = params.parameter1;
489 const double p = radius * r_inv;
490 if (p >= 1)
491 return 0.0;
492 return math::pow_int<6>(1.0 - p) * (35 * math::pow_int<2>(p) + PRECICE_FMA(18, p, 3));
493 }
494
499
500private:
501 double _r_inv;
503};
504
516 public DefiniteFunction<true> {
517public:
518 explicit CompactPolynomialC6(double supportRadius)
519 {
520 if (!math::greater(supportRadius, 0.0)) {
522 "Support radius for radial-basis-function compact polynomial c6 has to be larger than zero. Please update the \"support-radius\" attribute."};
523 }
524 _r_inv = 1. / supportRadius;
525 _params.parameter1 = _r_inv;
526 }
527
528 double getSupportRadius() const
529 {
530 return 1. / _r_inv;
531 }
532
533 double evaluate(double radius) const
534 {
535 return operator()(radius, _params);
536 }
537
538 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
539 {
540 double r_inv = params.parameter1;
541 const double p = radius * r_inv;
542 if (p >= 1)
543 return 0.0;
544 return math::pow_int<8>(1.0 - p) * (32.0 * math::pow_int<3>(p) + 25.0 * math::pow_int<2>(p) + PRECICE_FMA(8.0, p, 1.0));
545 };
546
548 {
549 return _params;
550 }
551
552private:
553 double _r_inv;
555};
556
568 public DefiniteFunction<true> {
569public:
570 explicit CompactPolynomialC8(double supportRadius)
571 {
572 if (!math::greater(supportRadius, 0.0)) {
574 "Support radius for radial-basis-function compact polynomial c6 has to be larger than zero. Please update the \"support-radius\" attribute."};
575 }
576 _r_inv = 1. / supportRadius;
577 _params.parameter1 = _r_inv;
578 }
579
580 double getSupportRadius() const
581 {
582 return 1. / _r_inv;
583 }
584
585 double evaluate(double radius) const
586 {
587 return operator()(radius, _params);
588 }
589
590 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
591 {
592 double r_inv = params.parameter1;
593 const double p = radius * r_inv;
594 if (p >= 1)
595 return 0.0;
596 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);
597 };
598
600 {
601 return _params;
602 }
603
604private:
605 double _r_inv;
607};
608
609#undef PRECICE_FMA
610#undef PRECICE_LOG
611#undef PRECICE_HOST_DEVICE
612#undef NUMERICAL_ZERO_DIFFERENCE_DEVICE
613
614} // namespace precice::mapping
#define PRECICE_FMA
#define PRECICE_LOG
#define NUMERICAL_ZERO_DIFFERENCE_DEVICE
#define PRECICE_HOST_DEVICE
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
PRECICE_HOST_DEVICE double operator()(const double radius, const RadialBasisParameters params) const
RadialBasisParameters getFunctionParameters()
double evaluate(double radius) const
PRECICE_HOST_DEVICE double operator()(const double radius, const RadialBasisParameters params) const
double evaluate(double radius) const
RadialBasisParameters getFunctionParameters() const
double evaluate(double radius) const
PRECICE_HOST_DEVICE double operator()(const double radius, const RadialBasisParameters params) const
RadialBasisParameters getFunctionParameters()
PRECICE_HOST_DEVICE double operator()(const double radius, const RadialBasisParameters params) const
double evaluate(double radius) const
const RadialBasisParameters getFunctionParameters()
const RadialBasisParameters getFunctionParameters()
double evaluate(double radius) const
PRECICE_HOST_DEVICE double operator()(const double radius, const RadialBasisParameters params) const
PRECICE_HOST_DEVICE double operator()(const double radius, const RadialBasisParameters params) const
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.
double evaluate(double radius) const
PRECICE_HOST_DEVICE double operator()(const double radius, const RadialBasisParameters params) const
RadialBasisParameters getFunctionParameters()
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 infinity(T... args)
T log(T... args)
T max(T... args)
T min(T... args)
contains data mapping from points to meshes.
provides general mathematical constants and functions.
Definition barycenter.cpp:9
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
std::enable_if< std::is_arithmetic< Scalar >::value, bool >::type greater(Scalar A, Scalar B, Scalar tolerance=NUMERICAL_ZERO_DIFFERENCE)
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.