MFEM v4.8.0
Finite element discretization library
Loading...
Searching...
No Matches
interpolate_local_3.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, 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#include "../gslib.hpp"
14
15#ifdef MFEM_USE_GSLIB
16
17#ifdef MFEM_HAVE_GCC_PRAGMA_DIAGNOSTIC
18#pragma GCC diagnostic push
19#pragma GCC diagnostic ignored "-Wunused-function"
20#endif
21#include "gslib.h"
22#ifndef GSLIB_RELEASE_VERSION //gslib v1.0.7
23#define GSLIB_RELEASE_VERSION 10007
24#endif
25#ifdef MFEM_HAVE_GCC_PRAGMA_DIAGNOSTIC
26#pragma GCC diagnostic pop
27#endif
28namespace mfem
29{
30#if GSLIB_RELEASE_VERSION >= 10009
31#define CODE_INTERNAL 0
32#define CODE_BORDER 1
33#define CODE_NOT_FOUND 2
34
35static MFEM_HOST_DEVICE void lagrange_eval(double *p0, double x,
36 int i, int p_Nq,
37 double *z, double *lagrangeCoeff)
38{
39 double p_i = (1 << (p_Nq - 1));
40 for (int j = 0; j < p_Nq; ++j)
41 {
42 double d_j = x - z[j];
43 p_i *= j == i ? 1 : d_j;
44 }
45 p0[i] = lagrangeCoeff[i] * p_i;
46}
47
48template<int T_D1D = 0>
49static void InterpolateLocal3DKernel(const double *const gf_in,
50 int *const el,
51 double *const r,
52 double *const int_out,
53 const int npt,
54 const int ncomp,
55 const int nel,
56 const int gf_offset,
57 double *gll1D,
58 double *lagcoeff,
59 const int pN = 0)
60{
61 const int Nfields = ncomp;
62 const int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
63 const int D1D = T_D1D ? T_D1D : pN;
64 const int p_Np = D1D*D1D*D1D;
65 MFEM_VERIFY(MD1 <= DofQuadLimits::MAX_D1D,
66 "Increase Max allowable polynomial order.");
67 MFEM_VERIFY(D1D != 0, "Polynomial order not specified.");
68#define MAXC(a, b) (((a) > (b)) ? (a) : (b))
69 const int nThreadsy = MAXC(D1D, 3);
70 mfem::forall_2D(npt, D1D, nThreadsy, [=] MFEM_HOST_DEVICE (int i)
71 {
72 MFEM_SHARED double wtr[3*MD1];
73 MFEM_SHARED double sums[MD1*MD1];
74
75 // Evaluate basis functions at the reference space coordinates
76 MFEM_FOREACH_THREAD(j,x,D1D)
77 {
78 MFEM_FOREACH_THREAD(k,y,3)
79 {
80 lagrange_eval(wtr + k*D1D, r[3*i+k], j, D1D, gll1D, lagcoeff);
81 }
82 }
83 MFEM_SYNC_THREAD;
84
85 for (int fld = 0; fld < Nfields; ++fld)
86 {
87 // If using GetNodalValues, ordering is NDOFSxNELxVDIM
88 // const int elemOffset = el[i] * p_Np + fld * gf_offset;
89 //if using R->Mult for L -> E-Vec use below.
90 const int elemOffset = el[i] * p_Np * Nfields + fld * p_Np;
91 MFEM_FOREACH_THREAD(j,x,D1D)
92 {
93 MFEM_FOREACH_THREAD(k,y,D1D)
94 {
95 sums[j + k*D1D] = 0.0;
96 for (int l = 0; l < D1D; ++l)
97 {
98 sums[j + k*D1D] += gf_in[elemOffset + j + k*D1D + l*D1D*D1D] *
99 wtr[2*D1D+l];
100 }
101 sums[j+k*D1D] *= wtr[D1D+k]*wtr[j];
102 }
103 }
104 MFEM_SYNC_THREAD;
105
106 MFEM_FOREACH_THREAD(j,x,1)
107 {
108 MFEM_FOREACH_THREAD(k,y,1)
109 {
110 double sumv = 0.0;
111 for (int jj = 0; jj < D1D*D1D; ++jj)
112 {
113 sumv += sums[jj];
114 }
115 int_out[i + fld * npt] = sumv;
116 }
117 }
118 MFEM_SYNC_THREAD;
119 }
120 });
121}
122
124 Array<int> &gsl_elem_dev_l,
125 Vector &gsl_ref_l,
126 Vector &field_out,
127 int npt, int ncomp,
128 int nel, int dof1Dsol)
129{
130 if (npt == 0) { return; }
131 const int gf_offset = field_in.Size()/ncomp;
132 auto pfin = field_in.Read();
133 auto pgsle = gsl_elem_dev_l.ReadWrite();
134 auto pgslr = gsl_ref_l.ReadWrite();
135 auto pfout = field_out.Write();
136 auto pgll = DEV.gll1d_sol.ReadWrite();
137 auto plcf = DEV.lagcoeff_sol.ReadWrite();
138 switch (dof1Dsol)
139 {
140 case 2: return InterpolateLocal3DKernel<2>(pfin, pgsle, pgslr, pfout,
141 npt, ncomp, nel, gf_offset,
142 pgll, plcf);
143 case 3: return InterpolateLocal3DKernel<3>(pfin, pgsle, pgslr, pfout,
144 npt, ncomp, nel, gf_offset,
145 pgll, plcf);
146 case 4: return InterpolateLocal3DKernel<4>(pfin, pgsle, pgslr, pfout,
147 npt, ncomp, nel, gf_offset,
148 pgll, plcf);
149 case 5: return InterpolateLocal3DKernel<5>(pfin, pgsle, pgslr, pfout,
150 npt, ncomp, nel, gf_offset,
151 pgll, plcf);
152 default: return InterpolateLocal3DKernel(pfin, pgsle, pgslr, pfout,
153 npt, ncomp, nel, gf_offset,
154 pgll, plcf, dof1Dsol);
155 }
156}
157
158
159#undef CODE_INTERNAL
160#undef CODE_BORDER
161#undef CODE_NOT_FOUND
162#else
163void FindPointsGSLIB::InterpolateLocal3(const Vector &field_in,
164 Array<int> &gsl_elem_dev_l,
165 Vector &gsl_ref_l,
166 Vector &field_out,
167 int npt, int ncomp,
168 int nel, int dof1Dsol) {};
169#endif
170} // namespace mfem
171
172#endif //ifdef MFEM_USE_GSLIB
T * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(a.GetMemory(), a.Size(), on_dev).
Definition array.hpp:353
struct mfem::FindPointsGSLIB::@24 DEV
void InterpolateLocal3(const Vector &field_in, Array< int > &gsl_elem_dev_l, Vector &gsl_ref_l, Vector &field_out, int npt, int ncomp, int nel, int dof1dsol)
Vector data type.
Definition vector.hpp:82
virtual const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
Definition vector.hpp:494
virtual real_t * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), on_dev).
Definition vector.hpp:510
int Size() const
Returns the size of the vector.
Definition vector.hpp:226
virtual real_t * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
Definition vector.hpp:502
void forall_2D(int N, int X, int Y, lambda &&body)
Definition forall.hpp:762