MFEM v4.10.0
Finite element discretization library
Loading...
Searching...
No Matches
gslib_kernel_helpers.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2026, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11
12#ifndef MFEM_GSLIB_KERNEL_HELPERS_HPP
13#define MFEM_GSLIB_KERNEL_HELPERS_HPP
14
16
17#include <cmath>
18
19namespace mfem
20{
21
22namespace gslib
23{
24
26{
27 double min, max;
28};
29
30template <int SDIM>
31struct obbox_t
32{
33 double c0[SDIM], A[SDIM * SDIM];
35};
36
37template <int SDIM>
39{
40 int hash_n;
42 double fac[SDIM];
43 unsigned int *offset;
44};
45
46// Eval the ith Lagrange interpolant at x.
47MFEM_HOST_DEVICE inline void lagrange_eval(double *p0, double x,
48 int i, int p_Nq,
49 double *z, double *lagrangeCoeff)
50{
51 double p_i = (1 << (p_Nq - 1));
52 for (int j = 0; j < p_Nq; ++j)
53 {
54 const double d_j = x - z[j];
55 p_i *= j == i ? 1 : d_j;
56 }
57 p0[i] = lagrangeCoeff[i] * p_i;
58}
59
60// Eval the ith Lagrange interpolant and its first derivative at x.
61MFEM_HOST_DEVICE inline void lag_eval_first_der(double *p0, double x,
62 int i, const double *z,
63 const double *lCoeff,
64 int pN)
65{
66 double u0 = 1, u1 = 0;
67 for (int j = 0; j < pN; ++j)
68 {
69 if (i != j)
70 {
71 const double d_j = 2 * (x - z[j]);
72 u1 = d_j * u1 + u0;
73 u0 = d_j * u0;
74 }
75 }
76 p0[i] = lCoeff[i] * u0;
77 p0[pN + i] = 2.0 * lCoeff[i] * u1;
78}
79
80// Eval the ith Lagrange interpolant and its first and second derivative at x.
81MFEM_HOST_DEVICE inline void lag_eval_second_der(double *p0, double x,
82 int i, const double *z,
83 const double *lCoeff,
84 int pN)
85{
86 double u0 = 1, u1 = 0, u2 = 0;
87 for (int j = 0; j < pN; ++j)
88 {
89 if (i != j)
90 {
91 const double d_j = 2 * (x - z[j]);
92 u2 = d_j * u2 + u1;
93 u1 = d_j * u1 + u0;
94 u0 = d_j * u0;
95 }
96 }
97 p0[i] = lCoeff[i] * u0;
98 p0[pN + i] = 2.0 * lCoeff[i] * u1;
99 p0[2 * pN + i] = 8.0 * lCoeff[i] * u2;
100}
101
102// Solve Ax=y where A is a symmetric 2x2 matrix packed as {a00, a01, a11}.
103MFEM_HOST_DEVICE inline void lin_solve_sym_2(double x[2],
104 const double A[3],
105 const double y[2])
106{
107 const double idet = 1 / (A[0] * A[2] - A[1] * A[1]);
108 x[0] = idet * (A[2] * y[0] - A[1] * y[1]);
109 x[1] = idet * (A[0] * y[1] - A[1] * y[0]);
110}
111
112// Positive when the point is inside the axis-aligned bounding box.
113template <int SDIM>
114MFEM_HOST_DEVICE inline double AABB_test(const obbox_t<SDIM> *const b,
115 const double (&x)[SDIM])
116{
117 double test = 1.0;
118 for (int d = 0; d < SDIM; ++d)
119 {
120 const double b_d = (x[d] - b->x[d].min) * (b->x[d].max - x[d]);
121 test = test < 0.0 ? test : b_d;
122 }
123 return test;
124}
125
126// Positive when the point is inside the oriented bounding box.
127template <int SDIM>
128MFEM_HOST_DEVICE inline double bbox_test(const obbox_t<SDIM> *const b,
129 const double (&x)[SDIM])
130{
131 const double bxyz = AABB_test(b, x);
132 if (bxyz < 0.0)
133 {
134 return bxyz;
135 }
136
137 double dxyz[SDIM];
138 for (int d = 0; d < SDIM; ++d)
139 {
140 dxyz[d] = x[d] - b->c0[d];
141 }
142
143 double test = 1.0;
144 for (int d = 0; d < SDIM; ++d)
145 {
146 double rst = 0.0;
147 for (int e = 0; e < SDIM; ++e)
148 {
149 rst += b->A[d * SDIM + e] * dxyz[e];
150 }
151 const double brst = (rst + 1.0) * (1.0 - rst);
152 test = test < 0.0 ? test : brst;
153 }
154 return test;
155}
156
157// Hash index in the hash table for the point x.
158template <int SDIM>
159MFEM_HOST_DEVICE inline int hash_index(
160 const findptsLocalHashData_t<SDIM> *const p,
161 const double (&x)[SDIM])
162{
163 const int n = p->hash_n;
164 int sum = 0;
165 for (int d = SDIM - 1; d >= 0; --d)
166 {
167 sum *= n;
168 const int i = (int)floor((x[d] - p->bnd[d].min) * p->fac[d]);
169 sum += i < 0 ? 0 : (n - 1 < i ? n - 1 : i);
170 }
171 return sum;
172}
173
174// Squared Euclidean norm.
175template <int SDIM>
176MFEM_HOST_DEVICE inline double l2norm2(const double (&x)[SDIM])
177{
178 double sum = 0.0;
179 for (int d = 0; d < SDIM; ++d)
180 {
181 sum += x[d] * x[d];
182 }
183 return sum;
184}
185
186template <int SDIM>
187MFEM_HOST_DEVICE inline double l2norm2(const double *x)
188{
189 double sum = 0.0;
190 for (int d = 0; d < SDIM; ++d)
191 {
192 sum += x[d] * x[d];
193 }
194 return sum;
195}
196
197} // namespace gslib
198
199} // namespace mfem
200
201#endif
real_t b
Definition lissajous.cpp:42
constexpr int SDIM
MFEM_HOST_DEVICE double bbox_test(const obbox_t< SDIM > *const b, const double(&x)[SDIM])
MFEM_HOST_DEVICE void lag_eval_first_der(double *p0, double x, int i, const double *z, const double *lCoeff, int pN)
MFEM_HOST_DEVICE void lagrange_eval(double *p0, double x, int i, int p_Nq, double *z, double *lagrangeCoeff)
MFEM_HOST_DEVICE void lin_solve_sym_2(double x[2], const double A[3], const double y[2])
MFEM_HOST_DEVICE double l2norm2(const double(&x)[SDIM])
MFEM_HOST_DEVICE int hash_index(const findptsLocalHashData_t< SDIM > *const p, const double(&x)[SDIM])
MFEM_HOST_DEVICE void lag_eval_second_der(double *p0, double x, int i, const double *z, const double *lCoeff, int pN)
MFEM_HOST_DEVICE double AABB_test(const obbox_t< SDIM > *const b, const double(&x)[SDIM])
real_t p(const Vector &x, real_t t)