MFEM v4.8.0
Finite element discretization library
Loading...
Searching...
No Matches
interpolate_local_2.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 InterpolateLocal2DKernel(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;
65 MFEM_VERIFY(MD1 <= DofQuadLimits::MAX_D1D,
66 "Increase Max allowable polynomial order.");
67 MFEM_VERIFY(D1D != 0, "Polynomial order not specified.");
68 mfem::forall_2D(npt, D1D, D1D, [=] MFEM_HOST_DEVICE (int i)
69 {
70 MFEM_SHARED double wtr[2*MD1];
71 MFEM_SHARED double sums[MD1*MD1];
72
73 // Evaluate basis functions at the reference space coordinates
74 MFEM_FOREACH_THREAD(j,x,D1D)
75 {
76 MFEM_FOREACH_THREAD(k,y,2)
77 {
78 lagrange_eval(wtr + k*D1D, r[2*i+k], j, D1D, gll1D, lagcoeff);
79 }
80 }
81 MFEM_SYNC_THREAD;
82
83 for (int fld = 0; fld < Nfields; ++fld)
84 {
85 // If using GetNodalValues, ordering is NDOFSxNELxVDIM
86 // const int elemOffset = el[i] * p_Np + fld * gf_offset;
87 //if using R->Mult for L -> E-Vec use below: NDOFSxVDIMxNEL
88 const int elemOffset = el[i] * p_Np * Nfields + fld * p_Np;
89 MFEM_FOREACH_THREAD(j,x,D1D)
90 {
91 MFEM_FOREACH_THREAD(k,y,D1D)
92 {
93 sums[j + k*D1D] = gf_in[elemOffset + j + k * D1D] *
94 wtr[D1D+k] *
95 wtr[j];
96 }
97 }
98 MFEM_SYNC_THREAD;
99
100 // MFEM_FOREACH_THREAD(j,x,D1D)
101 MFEM_FOREACH_THREAD(j,x,1)
102 {
103 MFEM_FOREACH_THREAD(k,y,1)
104 {
105 double sumv = 0.0;
106 for (int jj = 0; jj < D1D*D1D; ++jj)
107 {
108 sumv += sums[jj];
109 }
110 int_out[i + fld * npt] = sumv;
111 }
112 }
113 MFEM_SYNC_THREAD;
114 }
115 });
116}
117
119 Array<int> &gsl_elem_dev_l,
120 Vector &gsl_ref_l,
121 Vector &field_out,
122 int npt, int ncomp,
123 int nel, int dof1Dsol)
124{
125 if (npt == 0) { return; }
126 const int gf_offset = field_in.Size()/ncomp;
127 auto pfin = field_in.Read();
128 auto pgsl = gsl_elem_dev_l.ReadWrite();
129 auto pgslr = gsl_ref_l.ReadWrite();
130 auto pfout = field_out.Write();
131 auto pgll = DEV.gll1d_sol.ReadWrite();
132 auto plcf = DEV.lagcoeff_sol.ReadWrite();
133 switch (dof1Dsol)
134 {
135 case 2: return InterpolateLocal2DKernel<2>(pfin, pgsl, pgslr, pfout,
136 npt, ncomp, nel, gf_offset,
137 pgll, plcf);
138 case 3: return InterpolateLocal2DKernel<3>(pfin, pgsl, pgslr, pfout,
139 npt, ncomp, nel, gf_offset,
140 pgll, plcf);
141 case 4: return InterpolateLocal2DKernel<4>(pfin, pgsl, pgslr, pfout,
142 npt, ncomp, nel, gf_offset,
143 pgll, plcf);
144 case 5: return InterpolateLocal2DKernel<5>(pfin, pgsl, pgslr, pfout,
145 npt, ncomp, nel, gf_offset,
146 pgll, plcf);
147 default: return InterpolateLocal2DKernel(pfin, pgsl, pgslr, pfout,
148 npt, ncomp, nel, gf_offset,
149 pgll, plcf, dof1Dsol);
150 }
151}
152
153
154#undef CODE_INTERNAL
155#undef CODE_BORDER
156#undef CODE_NOT_FOUND
157#else
158void FindPointsGSLIB::InterpolateLocal2(const Vector &field_in,
159 Array<int> &gsl_elem_dev_l,
160 Vector &gsl_ref_l,
161 Vector &field_out,
162 int npt, int ncomp,
163 int nel, int dof1Dsol) {};
164#endif
165} // namespace mfem
166
167#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 InterpolateLocal2(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