20static void PADivergenceSetup2D(
const int Q1D,
22 const Array<real_t> &w,
27 const auto W =
Reshape(w.Read(), Q1D, Q1D);
28 const auto J =
Reshape(j.Read(), Q1D, Q1D, 2, 2, NE);
29 auto y =
Reshape(op.Write(), Q1D, Q1D, 2, 2, NE);
33 MFEM_FOREACH_THREAD_DIRECT(qx, x, Q1D)
35 MFEM_FOREACH_THREAD_DIRECT(qy, y, Q1D)
37 const real_t J11 = J(qx, qy, 0, 0, e);
38 const real_t J21 = J(qx, qy, 1, 0, e);
39 const real_t J12 = J(qx, qy, 0, 1, e);
40 const real_t J22 = J(qx, qy, 1, 1, e);
41 const real_t cw = W(qx, qy) * COEFF;
42 y(qx, qy, 0, 0, e) = cw * J22;
43 y(qx, qy, 0, 1, e) = cw * -J12;
44 y(qx, qy, 1, 0, e) = cw * -J21;
45 y(qx, qy, 1, 1, e) = cw * J11;
52static void PADivergenceSetup3D(
const int Q1D,
54 const Array<real_t> &w,
59 const auto W =
Reshape(w.Read(), Q1D, Q1D, Q1D);
60 const auto J =
Reshape(j.Read(), Q1D, Q1D, Q1D, 3, 3, NE);
61 auto y =
Reshape(op.Write(), Q1D, Q1D, Q1D, 3, 3, NE);
65 MFEM_FOREACH_THREAD_DIRECT(qx, x, Q1D)
67 MFEM_FOREACH_THREAD_DIRECT(qy, y, Q1D)
69 MFEM_FOREACH_THREAD_DIRECT(qz, z, Q1D)
71 const real_t J11 = J(qx, qy, qz, 0, 0, e);
72 const real_t J21 = J(qx, qy, qz, 1, 0, e);
73 const real_t J31 = J(qx, qy, qz, 2, 0, e);
74 const real_t J12 = J(qx, qy, qz, 0, 1, e);
75 const real_t J22 = J(qx, qy, qz, 1, 1, e);
76 const real_t J32 = J(qx, qy, qz, 2, 1, e);
77 const real_t J13 = J(qx, qy, qz, 0, 2, e);
78 const real_t J23 = J(qx, qy, qz, 1, 2, e);
79 const real_t J33 = J(qx, qy, qz, 2, 2, e);
80 const real_t cw = W(qx, qy, qz) * COEFF;
82 const real_t A11 = (J22 * J33) - (J23 * J32);
83 const real_t A12 = (J32 * J13) - (J12 * J33);
84 const real_t A13 = (J12 * J23) - (J22 * J13);
85 const real_t A21 = (J31 * J23) - (J21 * J33);
86 const real_t A22 = (J11 * J33) - (J13 * J31);
87 const real_t A23 = (J21 * J13) - (J11 * J23);
88 const real_t A31 = (J21 * J32) - (J31 * J22);
89 const real_t A32 = (J31 * J12) - (J11 * J32);
90 const real_t A33 = (J11 * J22) - (J12 * J21);
92 y(qx, qy, qz, 0, 0, e) = cw * A11;
93 y(qx, qy, qz, 0, 1, e) = cw * A12;
94 y(qx, qy, qz, 0, 2, e) = cw * A13;
95 y(qx, qy, qz, 1, 0, e) = cw * A21;
96 y(qx, qy, qz, 1, 1, e) = cw * A22;
97 y(qx, qy, qz, 1, 2, e) = cw * A23;
98 y(qx, qy, qz, 2, 0, e) = cw * A31;
99 y(qx, qy, qz, 2, 1, e) = cw * A32;
100 y(qx, qy, qz, 2, 2, e) = cw * A33;
107static void PADivergenceSetup(
const int dim,
110 const Array<real_t> &W,
115 if (
dim == 1) { MFEM_ABORT(
"dim==1 not supported in PADivergenceSetup"); }
118 PADivergenceSetup2D(Q1D, NE, W, J, COEFF, op);
122 PADivergenceSetup3D(Q1D, NE, W, J, COEFF, op);
131 "PA Only supports Ordering::byNODES!");
132 auto *mesh = trial_fes.
GetMesh();
137 *mesh->GetTypicalElementTransformation());
138 const int dims = trial_fe.GetDim();
139 nq = ir->GetNPoints();
140 dim = mesh->Dimension();
141 ne = trial_fes.
GetNE();
144 trial_dofs1D = trial_maps->
ndof;
145 quad1D = trial_maps->
nqpt;
147 test_dofs1D = test_maps->
ndof;
148 MFEM_ASSERT(quad1D == test_maps->
nqpt,
149 "PA requires test and trial space to have same number of "
150 "quadrature points!");
157 MFEM_VERIFY(cQ,
"only ConstantCoefficient is supported!");
158 coeff = cQ->constant;
160 PADivergenceSetup(
dim, quad1D, ne, ir->GetWeights(), geom->
J, coeff, pa_data);
166 using Kernels = VectorDivergenceAddMultPA;
168 static const auto specializations =
170 Kernels::Specialization<2, 2, 2, 2>::Add(),
171 Kernels::Specialization<2, 2, 2, 3>::Add(),
172 Kernels::Specialization<2, 2, 2, 4>::Add(),
173 Kernels::Specialization<2, 3, 2, 3>::Add(),
174 Kernels::Specialization<2, 3, 2, 4>::Add(),
175 Kernels::Specialization<2, 3, 3, 3>::Add(),
176 Kernels::Specialization<2, 3, 3, 4>::Add(),
177 Kernels::Specialization<2, 3, 3, 5>::Add(),
178 Kernels::Specialization<2, 4, 3, 4>::Add(),
179 Kernels::Specialization<2, 4, 3, 5>::Add(),
180 Kernels::Specialization<2, 4, 4, 4>::Add(),
181 Kernels::Specialization<2, 4, 4, 5>::Add(),
182 Kernels::Specialization<2, 4, 4, 6>::Add(),
183 Kernels::Specialization<2, 5, 4, 5>::Add(),
184 Kernels::Specialization<2, 5, 4, 6>::Add(),
185 Kernels::Specialization<2, 5, 5, 5>::Add(),
186 Kernels::Specialization<2, 5, 5, 6>::Add(),
187 Kernels::Specialization<2, 5, 5, 7>::Add(),
189 Kernels::Specialization<3, 2, 2, 3>::Add(),
190 Kernels::Specialization<3, 2, 2, 4>::Add(),
191 Kernels::Specialization<3, 2, 2, 6>::Add(),
192 Kernels::Specialization<3, 3, 2, 5>::Add(),
193 Kernels::Specialization<3, 3, 3, 4>::Add(),
194 Kernels::Specialization<3, 3, 3, 5>::Add(),
195 Kernels::Specialization<3, 3, 3, 7>::Add(),
196 Kernels::Specialization<3, 4, 4, 5>::Add(),
197 Kernels::Specialization<3, 4, 4, 6>::Add(),
198 Kernels::Specialization<3, 4, 4, 8>::Add(),
199 Kernels::Specialization<3, 5, 5, 6>::Add(),
200 Kernels::Specialization<3, 5, 5, 7>::Add(),
201 Kernels::Specialization<3, 5, 5, 9>::Add(),
203 MFEM_CONTRACT_VAR(specializations);
205 Kernels::Run(
dim, trial_dofs1D, test_dofs1D, quad1D, ne,
206 trial_maps->
B, trial_maps->
G, test_maps->
Bt,
208 trial_dofs1D, test_dofs1D, quad1D);
215 using Kernels = VectorDivergenceAddMultTransposePA;
217 static const auto specializations =
219 Kernels::Specialization<2, 2, 2, 2>::Add(),
220 Kernels::Specialization<2, 2, 2, 3>::Add(),
221 Kernels::Specialization<2, 2, 2, 4>::Add(),
222 Kernels::Specialization<2, 3, 2, 3>::Add(),
223 Kernels::Specialization<2, 3, 2, 4>::Add(),
224 Kernels::Specialization<2, 3, 3, 3>::Add(),
225 Kernels::Specialization<2, 3, 3, 4>::Add(),
226 Kernels::Specialization<2, 3, 3, 5>::Add(),
227 Kernels::Specialization<2, 4, 3, 4>::Add(),
228 Kernels::Specialization<2, 4, 3, 5>::Add(),
229 Kernels::Specialization<2, 4, 4, 4>::Add(),
230 Kernels::Specialization<2, 4, 4, 5>::Add(),
231 Kernels::Specialization<2, 4, 4, 6>::Add(),
232 Kernels::Specialization<2, 5, 4, 5>::Add(),
233 Kernels::Specialization<2, 5, 4, 6>::Add(),
234 Kernels::Specialization<2, 5, 5, 5>::Add(),
235 Kernels::Specialization<2, 5, 5, 6>::Add(),
236 Kernels::Specialization<2, 5, 5, 7>::Add(),
238 Kernels::Specialization<3, 2, 2, 3>::Add(),
239 Kernels::Specialization<3, 2, 2, 4>::Add(),
240 Kernels::Specialization<3, 2, 2, 6>::Add(),
241 Kernels::Specialization<3, 3, 2, 5>::Add(),
242 Kernels::Specialization<3, 3, 3, 4>::Add(),
243 Kernels::Specialization<3, 3, 3, 5>::Add(),
244 Kernels::Specialization<3, 3, 3, 7>::Add(),
245 Kernels::Specialization<3, 4, 4, 5>::Add(),
246 Kernels::Specialization<3, 4, 4, 6>::Add(),
247 Kernels::Specialization<3, 4, 4, 8>::Add(),
248 Kernels::Specialization<3, 5, 5, 6>::Add(),
249 Kernels::Specialization<3, 5, 5, 7>::Add(),
250 Kernels::Specialization<3, 5, 5, 9>::Add(),
252 MFEM_CONTRACT_VAR(specializations);
254 Kernels::Run(
dim, trial_dofs1D, test_dofs1D, quad1D, ne,
255 trial_maps->
Bt, trial_maps->
Gt, test_maps->
B,
257 trial_dofs1D, test_dofs1D, quad1D);
A coefficient that is constant across space and time.
static MemoryType GetMemoryType()
(DEPRECATED) Equivalent to GetDeviceMemoryType().
Array< real_t > G
Gradients/divergences/curls of basis functions evaluated at quadrature points.
@ TENSOR
Tensor product representation using 1D matrices/tensors with dimensions using 1D number of quadrature...
Array< real_t > B
Basis functions evaluated at quadrature points.
int ndof
Number of degrees of freedom = number of basis functions. When mode is TENSOR, this is the 1D number.
Array< real_t > Gt
Transpose of G.
int nqpt
Number of quadrature points. When mode is TENSOR, this is the 1D number.
Array< real_t > Bt
Transpose of B.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Ordering::Type GetOrdering() const
Return the ordering method.
int GetNE() const
Returns number of elements in the mesh.
Mesh * GetMesh() const
Returns the mesh.
const FiniteElement * GetTypicalFE() const
Return GetFE(0) if the local mesh is not empty; otherwise return a typical FE based on the Geometry t...
Vector J
Jacobians of the element transformations at all quadrature points.
const IntegrationRule * IntRule
void AssemblePA(const FiniteElementSpace &trial_fes, const FiniteElementSpace &test_fes) override
void AddMultTransposePA(const Vector &x, Vector &y) const override
Method for partially assembled transposed action.
static const IntegrationRule & GetRule(const FiniteElement &trial_fe, const FiniteElement &test_fe, const ElementTransformation &Trans)
void AddMultPA(const Vector &x, Vector &y) const override
Method for partially assembled action.
void SetSize(int s)
Resize the vector to size s.
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims... dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
void forall_2D(int N, int X, int Y, lambda &&body)
void forall_3D(int N, int X, int Y, int Z, lambda &&body)
Base class for Schrodinger solver kernels.