preCICE v3.2.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BasisFunctions.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <stdexcept>
4
5#ifdef __CUDACC__
6#include <cuda_runtime.h>
7#endif
8
9#ifdef __HIPCC__
10#include <hip/hip_runtime.h>
11#endif
12
13#if defined(__CUDACC__) || defined(__HIPCC__)
14
15#include <ginkgo/extensions/kokkos.hpp>
16#include <ginkgo/ginkgo.hpp>
17
18#define PRECICE_HOST_DEVICE __host__ __device__
19#define PRECICE_MEMORY_SPACE __device__
20#define PRECICE_FMA Kokkos::fma
21#define PRECICE_LOG Kokkos::log
22
23#else
24
25#define PRECICE_HOST_DEVICE
26#define PRECICE_MEMORY_SPACE
27#define PRECICE_FMA std::fma
28#define PRECICE_LOG std::log
29
30#endif
31
32#define NUMERICAL_ZERO_DIFFERENCE_DEVICE 1.0e-14
33
34#include "math/math.hpp"
35
36namespace precice::mapping {
37
52 double parameter1{};
53 double parameter2{};
54 double parameter3{};
55};
56
59 static constexpr bool hasCompactSupport()
60 {
61 return true;
62 }
63};
64
67 static constexpr bool hasCompactSupport()
68 {
69 return false;
70 }
71
72 static constexpr double getSupportRadius()
73 {
75 }
76};
77
83template <bool isDefinite>
85 static constexpr bool isStrictlyPositiveDefinite()
86 {
87 return isDefinite;
88 }
89};
90
99 public DefiniteFunction<false> {
100public:
101 double evaluate(double radius) const
102 {
103 return operator()(radius, _params);
104 }
105
106 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
107 {
108 // We don't need to read any values from params since there is no need here
109 return PRECICE_LOG(std::max(radius, NUMERICAL_ZERO_DIFFERENCE_DEVICE)) * math::pow_int<2>(radius);
110 }
111
116
117private:
119};
120
129 public DefiniteFunction<false> {
130public:
131 explicit Multiquadrics(double c)
132 : _cPow2(math::pow_int<2>(c))
133 {
135 }
136
137 double evaluate(double radius) const
138 {
139 return operator()(radius, _params);
140 }
141
142 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
143 {
144 double cPow2 = params.parameter1;
145 return std::sqrt(cPow2 + math::pow_int<2>(radius));
146 }
147
152
153private:
154 double _cPow2;
156};
157
167 public DefiniteFunction<true> {
168public:
169 explicit InverseMultiquadrics(double c)
170 : _cPow2(math::pow_int<2>(c))
171 {
172 if (!math::greater(c, 0.0)) {
173 throw std::invalid_argument{"Shape parameter for radial-basis-function inverse multiquadric has to be larger than zero. Please update the \"shape-parameter\" attribute."};
174 }
176 }
177
178 double evaluate(double radius) const
179 {
180 return operator()(radius, _params);
181 }
182
183 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
184 {
185 double cPow2 = params.parameter1;
186 return 1.0 / std::sqrt(cPow2 + math::pow_int<2>(radius));
187 }
188
193
194private:
195 double const _cPow2;
196
198};
199
208 public DefiniteFunction<false> {
209public:
210 double evaluate(double radius) const
211 {
212 return operator()(radius, _params);
213 }
214
215 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
216 {
217 return std::abs(radius);
218 }
219
224
225private:
227};
228
238 public DefiniteFunction<true> {
239public:
240 Gaussian(const double shape, const double supportRadius = std::numeric_limits<double>::infinity())
241 : _shape(shape),
242 _supportRadius(supportRadius)
243 {
244 if (math::greater(_shape, 0.0)) {
246 "Shape parameter for radial-basis-function gaussian has to be larger than zero. Please update the \"shape-parameter\" attribute."};
247 }
248 if (math::greater(_supportRadius, 0.0)) {
250 "Support radius for radial-basis-function gaussian has to be larger than zero. Please update the \"support-radius\" attribute."};
251 }
252
253 double threshold = std::sqrt(-std::log(cutoffThreshold)) / shape;
254 _supportRadius = std::min(supportRadius, threshold);
258 if (supportRadius < std::numeric_limits<double>::infinity()) {
259 _deltaY = evaluate(supportRadius);
261 }
262 }
263
264 double getSupportRadius() const
265 {
266 return _supportRadius;
267 }
268
269 double evaluate(const double radius) const
270 {
271 return operator()(radius, _params);
272 }
273
274 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
275 {
276 double shape = params.parameter1;
277 double supportRadius = params.parameter2;
278 double deltaY = params.parameter3;
279
280 if (radius > supportRadius)
281 return 0.0;
282 return std::exp(-math::pow_int<2>(shape * radius)) - deltaY;
283 }
284
289
290public:
292 static constexpr double cutoffThreshold = 1e-9;
293
294private:
295 double const _shape;
296
299
300 double _deltaY = 0;
301
303};
304
317 public DefiniteFunction<true> {
318public:
319 explicit CompactThinPlateSplinesC2(double supportRadius)
320 {
321 if (math::greater(supportRadius, 0.0)) {
323 "Support radius for radial-basis-function compact thin-plate-splines c2 has to be larger than zero. Please update the \"support-radius\" attribute."};
324 }
325 _r_inv = 1. / supportRadius;
327 }
328
329 double getSupportRadius() const
330 {
331 return 1. / _r_inv;
332 }
333
334 double evaluate(double radius) const
335 {
336 return operator()(radius, _params);
337 }
338
339 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
340 {
341 double r_inv = params.parameter1;
342 const double p = radius * r_inv;
343 if (p >= 1)
344 return 0.0;
345 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));
346 }
347
352
353private:
354 double _r_inv;
356};
357
369 public DefiniteFunction<true> {
370public:
371 explicit CompactPolynomialC0(double supportRadius)
372 {
373 if (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 }
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 (math::greater(supportRadius, 0.0)) {
427 "Support radius for radial-basis-function compact polynomial c2 has to be larger than zero. Please update the \"support-radius\" attribute."};
428 }
429
430 _r_inv = 1. / supportRadius;
432 }
433
434 double getSupportRadius() const
435 {
436 return 1. / _r_inv;
437 }
438
439 double evaluate(double radius) const
440 {
441 return operator()(radius, _params);
442 }
443
444 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
445 {
446 double r_inv = params.parameter1;
447 const double p = radius * r_inv;
448 if (p >= 1)
449 return 0.0;
450 return math::pow_int<4>(1.0 - p) * PRECICE_FMA(4, p, 1);
451 }
452
457
458private:
459 double _r_inv;
461};
462
474 public DefiniteFunction<true> {
475public:
476 explicit CompactPolynomialC4(double supportRadius)
477 {
478 if (math::greater(supportRadius, 0.0)) {
480 "Support radius for radial-basis-function compact polynomial c4 has to be larger than zero. Please update the \"support-radius\" attribute."};
481 }
482
483 _r_inv = 1. / supportRadius;
485 }
486
487 double getSupportRadius() const
488 {
489 return 1. / _r_inv;
490 }
491
492 double evaluate(double radius) const
493 {
494 return operator()(radius, _params);
495 }
496
497 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
498 {
499 double r_inv = params.parameter1;
500 const double p = radius * r_inv;
501 if (p >= 1)
502 return 0.0;
503 return math::pow_int<6>(1.0 - p) * (35 * math::pow_int<2>(p) + PRECICE_FMA(18, p, 3));
504 }
505
510
511private:
512 double _r_inv;
514};
515
527 public DefiniteFunction<true> {
528public:
529 explicit CompactPolynomialC6(double supportRadius)
530 {
531 if (math::greater(supportRadius, 0.0)) {
533 "Support radius for radial-basis-function compact polynomial c6 has to be larger than zero. Please update the \"support-radius\" attribute."};
534 }
535 _r_inv = 1. / supportRadius;
537 }
538
539 double getSupportRadius() const
540 {
541 return 1. / _r_inv;
542 }
543
544 double evaluate(double radius) const
545 {
546 return operator()(radius, _params);
547 }
548
549 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
550 {
551 double r_inv = params.parameter1;
552 const double p = radius * r_inv;
553 if (p >= 1)
554 return 0.0;
555 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));
556 };
557
559 {
560 return _params;
561 }
562
563private:
564 double _r_inv;
566};
567
579 public DefiniteFunction<true> {
580public:
581 explicit CompactPolynomialC8(double supportRadius)
582 {
583 if (math::greater(supportRadius, 0.0)) {
585 "Support radius for radial-basis-function compact polynomial c6 has to be larger than zero. Please update the \"support-radius\" attribute."};
586 }
587 _r_inv = 1. / supportRadius;
589 }
590
591 double getSupportRadius() const
592 {
593 return 1. / _r_inv;
594 }
595
596 double evaluate(double radius) const
597 {
598 return operator()(radius, _params);
599 }
600
601 PRECICE_HOST_DEVICE inline double operator()(const double radius, const RadialBasisParameters params) const
602 {
603 double r_inv = params.parameter1;
604 const double p = radius * r_inv;
605 if (p >= 1)
606 return 0.0;
607 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);
608 };
609
611 {
612 return _params;
613 }
614
615private:
616 double _r_inv;
618};
619
620#undef PRECICE_FMA
621#undef PRECICE_LOG
622#undef PRECICE_MEMORY_SPACE
623#undef PRECICE_HOST_DEVICE
624#undef NUMERICAL_ZERO_DIFFERENCE_DEVICE
625
626} // namespace precice::mapping
#define PRECICE_FMA
#define PRECICE_LOG
#define NUMERICAL_ZERO_DIFFERENCE_DEVICE
#define PRECICE_HOST_DEVICE
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 make_unique(T... args)
T max(T... args)
T min(T... args)
contains data mapping from points to meshes.
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.