MFEM  v4.2.0
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
tbilininteg.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2020, 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_TEMPLATE_BILININTEG
13 #define MFEM_TEMPLATE_BILININTEG
14 
15 #include "../config/tconfig.hpp"
16 #include "tcoefficient.hpp"
17 #include "tbilinearform.hpp"
18 
19 namespace mfem
20 {
21 
22 // Templated local bilinear form integrator kernels, cf. bilininteg.?pp
23 
24 /// The Integrator class combines a kernel and a coefficient
25 template <typename coeff_t, template<int,int,typename> class kernel_t>
27 {
28 public:
30 
31  template <int SDim, int Dim, typename complex_t>
32  struct kernel { typedef kernel_t<SDim,Dim,complex_t> type; };
33 
35 
36  TIntegrator(const coefficient_type &c) : coeff(c) { }
37 };
38 
39 
40 /// Mass kernel
41 template <int SDim, int Dim, typename complex_t>
43 {
44  typedef complex_t complex_type;
45 
46  /// Needed for the TElementTransformation::Result class
47  static const bool uses_Jacobians = true;
48 
49  /// @name Needed for the FieldEvaluator::Data class
50  ///@{
51  static const bool in_values = true;
52  static const bool in_gradients = false;
53  static const bool out_values = true;
54  static const bool out_gradients = false;
55  ///@}
56 
57  /** @brief Partially assembled data type for one element with the given number of
58  quadrature points. This type is used in partial assembly, and partially
59  assembled action. */
60  template <int qpts>
62 
63  /** @brief Partially assembled data type for one element with the given
64  number of quadrature points. This type is used in full element matrix
65  assembly. */
66  template <int qpts>
68 
69  template <typename IR, typename coeff_t, typename impl_traits_t>
71  {
73  };
74 
75  /** @brief Method used for un-assembled (matrix free) action.
76  @param k the element number
77  @param F Jt [M x Dim x SDim x NE] - Jacobian transposed, data member in F
78  @param Q CoefficientEval<>::Type
79  @param q CoefficientEval<>::Type::result_t
80  @param R val_qpts [M x NC x NE] - in/out data member in R
81  val_qpts *= w det(J) */
82  template <typename T_result_t, typename Q_t, typename q_t,
83  typename S_data_t>
84  static inline MFEM_ALWAYS_INLINE
85  void Action(const int k, const T_result_t &F,
86  const Q_t &Q, const q_t &q, S_data_t &R)
87  {
88  typedef typename T_result_t::Jt_type::data_type real_t;
89  const int M = S_data_t::eval_type::qpts;
90  const int NC = S_data_t::eval_type::vdim;
91  MFEM_STATIC_ASSERT(T_result_t::Jt_type::layout_type::dim_1 == M,
92  "incompatible dimensions");
93  MFEM_FLOPS_ADD(M*(1+NC)); // TDet counts its flops
94  for (int i = 0; i < M; i++)
95  {
96  const complex_t wi =
97  Q.get(q,i,k) * TDet<real_t>(F.Jt.layout.ind14(i,k), F.Jt);
98  for (int j = 0; j < NC; j++)
99  {
100  R.val_qpts(i,j,k) *= wi;
101  }
102  }
103  }
104 
105  /** @brief Method defining partial assembly.
106  Result in A is the quadrature-point dependent part of element matrix
107  assembly (as opposed to part that is same for all elements),
108  A = w det(J)
109  @param k the element number
110  @param F Jt [M x Dim x SDim x NE] - Jacobian transposed, data member in F
111  @param Q CoefficientEval<>::Type
112  @param q CoefficientEval<>::Type::result_t
113  @param A [M] - partially assembled scalars
114  */
115  template <typename T_result_t, typename Q_t, typename q_t, int qpts>
116  static inline MFEM_ALWAYS_INLINE
117  void Assemble(const int k, const T_result_t &F,
118  const Q_t &Q, const q_t &q, TVector<qpts,complex_t> &A)
119  {
120  typedef typename T_result_t::Jt_type::data_type real_t;
121 
122  const int M = T_result_t::Jt_type::layout_type::dim_1;
123  MFEM_STATIC_ASSERT(qpts == M, "incompatible dimensions");
124  MFEM_FLOPS_ADD(M); // TDet counts its flops
125  for (int i = 0; i < M; i++)
126  {
127  A[i] = Q.get(q,i,k) * TDet<real_t>(F.Jt.layout.ind14(i,k), F.Jt);
128  }
129  }
130 
131  /** @brief Method for partially assembled action.
132  @param k the element number
133  @param A [M] - partially assembled scalars
134  @param R val_qpts [M x NC x NE] - in/out data member in R
135  val_qpts *= A
136  */
137  template <int qpts, typename S_data_t>
138  static inline MFEM_ALWAYS_INLINE
139  void MultAssembled(const int k, const TVector<qpts,complex_t> &A, S_data_t &R)
140  {
141  const int M = S_data_t::eval_type::qpts;
142  const int NC = S_data_t::eval_type::vdim;
143  MFEM_STATIC_ASSERT(qpts == M, "incompatible dimensions");
144  MFEM_FLOPS_ADD(M*NC);
145  for (int i = 0; i < M; i++)
146  {
147  for (int j = 0; j < NC; j++)
148  {
149  R.val_qpts(i,j,k) *= A[i];
150  }
151  }
152  }
153 };
154 
155 
156 /** @brief Diffusion kernel
157  @tparam complex_t - type for the assembled data
158 */
159 template <int SDim, int Dim, typename complex_t>
161 
162 /// Diffusion kernel in 1D
163 template <typename complex_t>
164 struct TDiffusionKernel<1,1,complex_t>
165 {
166  typedef complex_t complex_type;
167 
168  /// Needed for the TElementTransformation::Result class
169  static const bool uses_Jacobians = true;
170 
171  /// Needed for the FieldEvaluator::Data class
172  ///@{
173  static const bool in_values = false;
174  static const bool in_gradients = true;
175  static const bool out_values = false;
176  static const bool out_gradients = true;
177  ///@}
178 
179  /** @brief Partially assembled data type for one element with the given number of
180  quadrature points. This type is used in partial assembly, and partially
181  assembled action. */
182  template <int qpts>
183  struct p_asm_data { typedef TMatrix<qpts,1,complex_t> type; };
184 
185 
186  /** @brief Partially assembled data type for one element with the given number of
187  quadrature points. This type is used in full element matrix assembly. */
188  template <int qpts>
189  struct f_asm_data { typedef TTensor3<qpts,1,1,complex_t> type; };
190 
191  template <typename IR, typename coeff_t, typename impl_traits_t>
192  struct CoefficientEval
193  {
195  };
196 
197  /** @brief Method used for un-assembled (matrix free) action.
198  @param k the element number
199  @param F Jt [M x Dim x SDim x NE] - Jacobian transposed, data member in F
200  @param Q - CoefficientEval<>::Type
201  @param q - CoefficientEval<>::Type::result_t
202  @param R grad_qpts [M x SDim x NC x NE] - in/out data member in R
203  grad_qpts = (w/det(J)) adj(J) adj(J)^t grad_qpts */
204  template <typename T_result_t, typename Q_t, typename q_t,
205  typename S_data_t>
206  static inline MFEM_ALWAYS_INLINE
207  void Action(const int k, const T_result_t &F,
208  const Q_t &Q, const q_t &q, S_data_t &R)
209  {
210  const int M = S_data_t::eval_type::qpts;
211  const int NC = S_data_t::eval_type::vdim;
212  MFEM_STATIC_ASSERT(T_result_t::Jt_type::layout_type::dim_1 == M,
213  "incompatible dimensions");
214  MFEM_FLOPS_ADD(M*(1+NC));
215  for (int i = 0; i < M; i++)
216  {
217  const complex_t wi = Q.get(q,i,k) / F.Jt(i,0,0,k);
218  for (int j = 0; j < NC; j++)
219  {
220  R.grad_qpts(i,0,j,k) *= wi;
221  }
222  }
223  }
224 
225 
226  /** @brief Method defining partial assembly.
227  The pointwise Dim x Dim matrices are stored as symmetric (when
228  asm_type == p_asm_data, i.e. A.layout.rank == 2) or
229  non-symmetric (when asm_type == f_asm_data, i.e. A.layout.rank
230  == 3) matrices.
231  @param k the element number
232  @param F Jt [M x Dim x SDim x NE] - Jacobian transposed, data member in F
233  @param Q CoefficientEval<>::Type
234  @param q CoefficientEval<>::Type::result_t
235  @param A [M x Dim*(Dim+1)/2] - partially assembled Dim x Dim symm. matrices
236  A [M x Dim x Dim] - partially assembled Dim x Dim matrices
237  A = (w/det(J)) adj(J) adj(J)^t
238  */
239  template <typename T_result_t, typename Q_t, typename q_t, typename asm_type>
240  static inline MFEM_ALWAYS_INLINE
241  void Assemble(const int k, const T_result_t &F,
242  const Q_t &Q, const q_t &q, asm_type &A)
243  {
244  const int M = T_result_t::Jt_type::layout_type::dim_1;
245  MFEM_STATIC_ASSERT(asm_type::layout_type::dim_1 == M,
246  "incompatible dimensions");
247  MFEM_FLOPS_ADD(M);
248  for (int i = 0; i < M; i++)
249  {
250  // A[i] is A(i,0) or A(i,0,0)
251  A[i] = Q.get(q,i,k) / F.Jt(i,0,0,k);
252  }
253  }
254  /** @brief Method for partially assembled action.
255  @param k the element number
256  @param A [M x Dim*(Dim+1)/2] partially assembled Dim x Dim symmetric
257  matrices
258  @param R grad_qpts [M x SDim x NC x NE] - in/out data member in R
259  grad_qpts = A grad_qpts
260  */
261  template <int qpts, typename S_data_t>
262  static inline MFEM_ALWAYS_INLINE
263  void MultAssembled(const int k, const TMatrix<qpts,1,complex_t> &A,
264  S_data_t &R)
265  {
266  const int M = S_data_t::eval_type::qpts;
267  const int NC = S_data_t::eval_type::vdim;
268  MFEM_STATIC_ASSERT(qpts == M, "incompatible dimensions");
269  MFEM_FLOPS_ADD(M*NC);
270  for (int i = 0; i < M; i++)
271  {
272  for (int j = 0; j < NC; j++)
273  {
274  R.grad_qpts(i,0,j,k) *= A(i,0);
275  }
276  }
277  }
278 };
279 
280 /// Diffusion kernel in 2D
281 template <typename complex_t>
282 struct TDiffusionKernel<2,2,complex_t>
283 {
284  typedef complex_t complex_type;
285 
286  /// Needed for the TElementTransformation::Result class
287  static const bool uses_Jacobians = true;
288 
289  /// Needed for the FieldEvaluator::Data class
290  ///@{
291  static const bool in_values = false;
292  static const bool in_gradients = true;
293  static const bool out_values = false;
294  static const bool out_gradients = true;
295  ///@}
296 
297  /** @brief Partially assembled data type for one element with the given number of
298  quadrature points. This type is used in partial assembly, and partially
299  assembled action. Stores one symmetric 2 x 2 matrix per point. */
300  template <int qpts>
301  struct p_asm_data { typedef TMatrix<qpts,3,complex_t> type; };
302 
303  /** @brief Partially assembled data type for one element with the given number of
304  quadrature points. This type is used in full element matrix assembly.
305  Stores one general (non-symmetric) 2 x 2 matrix per point. */
306  template <int qpts>
307  struct f_asm_data { typedef TTensor3<qpts,2,2,complex_t> type; };
308 
309  template <typename IR, typename coeff_t, typename impl_traits_t>
310  struct CoefficientEval
311  {
313  };
314 
315  /** @brief Method used for un-assembled (matrix free) action.
316  @param k the element number
317  @param F Jt [M x Dim x SDim x NE] - Jacobian transposed, data member in F
318  @param Q CoefficientEval<>::Type
319  @param q CoefficientEval<>::Type::result_t
320  @param R grad_qpts [M x SDim x NC x NE] - in/out data member in R
321  grad_qpts = (w/det(J)) adj(J) adj(J)^t grad_qpts
322  */
323  template <typename T_result_t, typename Q_t, typename q_t,
324  typename S_data_t>
325  static inline MFEM_ALWAYS_INLINE
326  void Action(const int k, const T_result_t &F,
327  const Q_t &Q, const q_t &q, S_data_t &R)
328  {
329  const int M = S_data_t::eval_type::qpts;
330  const int NC = S_data_t::eval_type::vdim;
331  MFEM_STATIC_ASSERT(T_result_t::Jt_type::layout_type::dim_1 == M,
332  "incompatible dimensions");
333  MFEM_FLOPS_ADD(M*(4+NC*14));
334  for (int i = 0; i < M; i++)
335  {
336  typedef typename T_result_t::Jt_type::data_type real_t;
337  const real_t J11 = F.Jt(i,0,0,k);
338  const real_t J12 = F.Jt(i,1,0,k);
339  const real_t J21 = F.Jt(i,0,1,k);
340  const real_t J22 = F.Jt(i,1,1,k);
341  const complex_t w_det_J = Q.get(q,i,k) / (J11 * J22 - J21 * J12);
342  for (int j = 0; j < NC; j++)
343  {
344  const complex_t x1 = R.grad_qpts(i,0,j,k);
345  const complex_t x2 = R.grad_qpts(i,1,j,k);
346  // z = adj(J)^t x
347  const complex_t z1 = J22 * x1 - J21 * x2;
348  const complex_t z2 = J11 * x2 - J12 * x1;
349  R.grad_qpts(i,0,j,k) = w_det_J * (J22 * z1 - J12 * z2);
350  R.grad_qpts(i,1,j,k) = w_det_J * (J11 * z2 - J21 * z1);
351  }
352  }
353  }
354 
355  /** @brief Method defining partial assembly.
356  The pointwise Dim x Dim matrices are stored as symmetric (when
357  asm_type == p_asm_data, i.e. A.layout.rank == 2) or non-symmetric
358  (when asm_type == f_asm_data, i.e. A.layout.rank == 3) matrices.
359  A = (w/det(J)) adj(J) adj(J)^t
360  @param k the element number
361  @param F Jt [M x Dim x SDim x NE] - Jacobian transposed, data member in F
362  @param Q CoefficientEval<>::Type
363  @param q CoefficientEval<>::Type::result_t
364  @param A [M x Dim*(Dim+1)/2] partially assembled Dim x Dim symm. matrices
365  @param A [M x Dim x Dim] partially assembled Dim x Dim matrices
366  */
367  template <typename T_result_t, typename Q_t, typename q_t, typename asm_type>
368  static inline MFEM_ALWAYS_INLINE
369  void Assemble(const int k, const T_result_t &F,
370  const Q_t &Q, const q_t &q, asm_type &A)
371  {
372  typedef typename T_result_t::Jt_type::data_type real_t;
373  const int M = T_result_t::Jt_type::layout_type::dim_1;
374  MFEM_STATIC_ASSERT(asm_type::layout_type::dim_1 == M,
375  "incompatible dimensions");
376  MFEM_FLOPS_ADD(16*M);
377  const bool Symm = (asm_type::layout_type::rank == 2);
378  for (int i = 0; i < M; i++)
379  {
380  const real_t J11 = F.Jt(i,0,0,k);
381  const real_t J12 = F.Jt(i,1,0,k);
382  const real_t J21 = F.Jt(i,0,1,k);
383  const real_t J22 = F.Jt(i,1,1,k);
384  const complex_t w_det_J = Q.get(q,i,k) / (J11 * J22 - J21 * J12);
385  internal::MatrixOps<2,2>::Symm<Symm>::Set(
386  A.layout.ind1(i), A,
387  + w_det_J * (J12*J12 + J22*J22), // (1,1)
388  - w_det_J * (J11*J12 + J21*J22), // (2,1)
389  + w_det_J * (J11*J11 + J21*J21) // (2,2)
390  );
391  }
392  }
393 
394  /** @brief Method for partially assembled action.
395  @param k the element number
396  @param A [M x Dim*(Dim+1)/2] - partially assembled Dim x Dim symmetric
397  matrices
398  @param R grad_qpts [M x SDim x NC x NE] - in/out data member in R
399  grad_qpts = A grad_qpts
400  */
401  template <int qpts, typename S_data_t>
402  static inline MFEM_ALWAYS_INLINE
403  void MultAssembled(const int k, const TMatrix<qpts,3,complex_t> &A,
404  S_data_t &R)
405  {
406  const int M = S_data_t::eval_type::qpts;
407  const int NC = S_data_t::eval_type::vdim;
408  MFEM_STATIC_ASSERT(qpts == M, "incompatible dimensions");
409  MFEM_FLOPS_ADD(6*M*NC);
410  for (int i = 0; i < M; i++)
411  {
412  const complex_t A11 = A(i,0);
413  const complex_t A21 = A(i,1);
414  const complex_t A22 = A(i,2);
415  for (int j = 0; j < NC; j++)
416  {
417  const complex_t x1 = R.grad_qpts(i,0,j,k);
418  const complex_t x2 = R.grad_qpts(i,1,j,k);
419  R.grad_qpts(i,0,j,k) = A11 * x1 + A21 * x2;
420  R.grad_qpts(i,1,j,k) = A21 * x1 + A22 * x2;
421  }
422  }
423  }
424 };
425 
426 /// Diffusion kernel in 3D
427 template <typename complex_t>
428 struct TDiffusionKernel<3,3,complex_t>
429 {
430  typedef complex_t complex_type;
431 
432  /// Needed for the TElementTransformation::Result class
433  static const bool uses_Jacobians = true;
434 
435  /// Needed for the FieldEvaluator::Data class
436  ///@{
437  static const bool in_values = false;
438  static const bool in_gradients = true;
439  static const bool out_values = false;
440  static const bool out_gradients = true;
441  ///@}
442 
443  /** @brief Partially assembled data type for one element with the given number of
444  quadrature points. This type is used in partial assembly, and partially
445  assembled action. Stores one symmetric 3 x 3 matrix per point. */
446  template <int qpts>
447  struct p_asm_data { typedef TMatrix<qpts,6,complex_t> type; };
448 
449  /** @brief Partially assembled data type for one element with the given number of
450  quadrature points. This type is used in full element matrix assembly.
451  Stores one general (non-symmetric) 3 x 3 matrix per point. */
452  template <int qpts>
453  struct f_asm_data { typedef TTensor3<qpts,3,3,complex_t> type; };
454 
455  template <typename IR, typename coeff_t, typename impl_traits_t>
456  struct CoefficientEval
457  {
459  };
460 
461  /** @brief Method used for un-assembled (matrix free) action.
462  grad_qpts = (w/det(J)) adj(J) adj(J)^t grad_qpts
463  Jt [M x Dim x SDim x NE] - Jacobian transposed, data member in F
464  Q - CoefficientEval<>::Type
465  q - CoefficientEval<>::Type::result_t
466  grad_qpts [M x SDim x NC x NE] - in/out data member in R
467  */
468  template <typename T_result_t, typename Q_t, typename q_t,
469  typename S_data_t>
470  static inline MFEM_ALWAYS_INLINE
471  void Action(const int k, const T_result_t &F,
472  const Q_t &Q, const q_t &q, S_data_t &R)
473  {
474  const int M = S_data_t::eval_type::qpts;
475  const int NC = S_data_t::eval_type::vdim;
476  MFEM_STATIC_ASSERT(T_result_t::Jt_type::layout_type::dim_1 == M,
477  "incompatible dimensions");
478  MFEM_FLOPS_ADD(M); // just need to count Q/detJ
479  for (int i = 0; i < M; i++)
480  {
481  typedef typename T_result_t::Jt_type::data_type real_t;
482  TMatrix<3,3,real_t> adj_J;
483  const complex_t w_det_J =
484  (Q.get(q,i,k) /
485  TAdjDet<real_t>(F.Jt.layout.ind14(i,k).transpose_12(), F.Jt,
486  adj_J.layout, adj_J));
487  TMatrix<3,NC,complex_t> z; // z = adj(J)^t x
488  sMult_AB<false>(adj_J.layout.transpose_12(), adj_J,
489  R.grad_qpts.layout.ind14(i,k), R.grad_qpts,
490  z.layout, z);
491  z.Scale(w_det_J);
492  sMult_AB<false>(adj_J.layout, adj_J,
493  z.layout, z,
494  R.grad_qpts.layout.ind14(i,k), R.grad_qpts);
495  }
496  }
497 
498  /** @brief Method defining partial assembly.
499  The pointwise Dim x Dim matrices are stored as symmetric (when
500  asm_type == p_asm_data, i.e. A.layout.rank == 2) or
501  non-symmetric (when asm_type == f_asm_data, i.e. A.layout.rank
502  == 3) matrices.
503  A = (w/det(J)) adj(J) adj(J)^t
504  Jt [M x Dim x SDim x NE] - Jacobian transposed, data member in F
505  Q - CoefficientEval<>::Type
506  q - CoefficientEval<>::Type::result_t
507  A [M x Dim*(Dim+1)/2] - partially assembled Dim x Dim symm. matrices
508  A [M x Dim x Dim] - partially assembled Dim x Dim matrices
509  */
510  template <typename T_result_t, typename Q_t, typename q_t, typename asm_type>
511  static inline MFEM_ALWAYS_INLINE
512  void Assemble(const int k, const T_result_t &F,
513  const Q_t &Q, const q_t &q, asm_type &A)
514  {
515  typedef typename T_result_t::Jt_type::data_type real_t;
516  const int M = T_result_t::Jt_type::layout_type::dim_1;
517  MFEM_STATIC_ASSERT(asm_type::layout_type::dim_1 == M,
518  "incompatible dimensions");
519  MFEM_FLOPS_ADD(37*M);
520  const bool Symm = (asm_type::layout_type::rank == 2);
521  for (int i = 0; i < M; i++)
522  {
523  TMatrix<3,3,real_t> B; // = adj(J)
524  const complex_t u =
525  (Q.get(q,i,k) /
526  TAdjDet<real_t>(F.Jt.layout.ind14(i,k).transpose_12(), F.Jt,
527  B.layout, B));
528  internal::MatrixOps<3,3>::Symm<Symm>::Set(
529  A.layout.ind1(i), A,
530  u*(B(0,0)*B(0,0)+B(0,1)*B(0,1)+B(0,2)*B(0,2)), // 1,1
531  u*(B(0,0)*B(1,0)+B(0,1)*B(1,1)+B(0,2)*B(1,2)), // 2,1
532  u*(B(0,0)*B(2,0)+B(0,1)*B(2,1)+B(0,2)*B(2,2)), // 3,1
533  u*(B(1,0)*B(1,0)+B(1,1)*B(1,1)+B(1,2)*B(1,2)), // 2,2
534  u*(B(1,0)*B(2,0)+B(1,1)*B(2,1)+B(1,2)*B(2,2)), // 3,2
535  u*(B(2,0)*B(2,0)+B(2,1)*B(2,1)+B(2,2)*B(2,2)) // 3,3
536  );
537  }
538  }
539 
540  /** @brief Method for partially assembled action.
541  A [M x Dim*(Dim+1)/2] - partially assembled Dim x Dim symmetric
542  matrices
543  grad_qpts [M x SDim x NC x NE] - in/out data member in R
544  grad_qpts = A grad_qpts
545  */
546  template <int qpts, typename S_data_t>
547  static inline MFEM_ALWAYS_INLINE
548  void MultAssembled(const int k, const TMatrix<qpts,6,complex_t> &A,
549  S_data_t &R)
550  {
551  const int M = S_data_t::eval_type::qpts;
552  const int NC = S_data_t::eval_type::vdim;
553  MFEM_STATIC_ASSERT(qpts == M, "incompatible dimensions");
554  MFEM_FLOPS_ADD(15*M*NC);
555  for (int i = 0; i < M; i++)
556  {
557  const complex_t A11 = A(i,0);
558  const complex_t A21 = A(i,1);
559  const complex_t A31 = A(i,2);
560  const complex_t A22 = A(i,3);
561  const complex_t A32 = A(i,4);
562  const complex_t A33 = A(i,5);
563  for (int j = 0; j < NC; j++)
564  {
565  const complex_t x1 = R.grad_qpts(i,0,j,k);
566  const complex_t x2 = R.grad_qpts(i,1,j,k);
567  const complex_t x3 = R.grad_qpts(i,2,j,k);
568  R.grad_qpts(i,0,j,k) = A11*x1 + A21*x2 + A31*x3;
569  R.grad_qpts(i,1,j,k) = A21*x1 + A22*x2 + A32*x3;
570  R.grad_qpts(i,2,j,k) = A31*x1 + A32*x2 + A33*x3;
571  }
572  }
573  }
574 };
575 
576 } // namespace mfem
577 
578 #endif // MFEM_TEMPLATE_BILININTEG
IntRuleCoefficient< IR, coeff_t, impl_traits_t >::Type Type
Definition: tbilininteg.hpp:72
static const bool uses_Jacobians
Needed for the TElementTransformation::Result class.
Definition: tbilininteg.hpp:47
IntRuleCoefficient< IR, coeff_t, impl_traits_t >::Type Type
static const bool in_values
Definition: tbilininteg.hpp:51
static const layout_type layout
Definition: ttensor.hpp:356
static MFEM_ALWAYS_INLINE void Action(const int k, const T_result_t &F, const Q_t &Q, const q_t &q, S_data_t &R)
Method used for un-assembled (matrix free) action.
Mass kernel.
Definition: tbilininteg.hpp:42
static const bool out_gradients
Definition: tbilininteg.hpp:54
The Integrator class combines a kernel and a coefficient.
Definition: tbilininteg.hpp:26
Partially assembled data type for one element with the given number of quadrature points...
Definition: tbilininteg.hpp:67
static MFEM_ALWAYS_INLINE void Assemble(const int k, const T_result_t &F, const Q_t &Q, const q_t &q, asm_type &A)
Method defining partial assembly. The pointwise Dim x Dim matrices are stored as symmetric (when asm_...
Partially assembled data type for one element with the given number of quadrature points...
Definition: tbilininteg.hpp:61
static MFEM_ALWAYS_INLINE void Assemble(const int k, const T_result_t &F, const Q_t &Q, const q_t &q, asm_type &A)
Method defining partial assembly. The pointwise Dim x Dim matrices are stored as symmetric (when asm_...
static MFEM_ALWAYS_INLINE void MultAssembled(const int k, const TMatrix< qpts, 3, complex_t > &A, S_data_t &R)
Method for partially assembled action.
TConstantCoefficient coeff_t
Definition: ex1.cpp:57
kernel_t< SDim, Dim, complex_t > type
Definition: tbilininteg.hpp:32
static const bool in_gradients
Definition: tbilininteg.hpp:52
IntRuleCoefficient< IR, coeff_t, impl_traits_t >::Type Type
TVector< qpts, complex_t > type
Definition: tbilininteg.hpp:61
static MFEM_ALWAYS_INLINE void Action(const int k, const T_result_t &F, const Q_t &Q, const q_t &q, S_data_t &R)
Method used for un-assembled (matrix free) action.
Definition: tbilininteg.hpp:85
complex_t complex_type
Definition: tbilininteg.hpp:44
static MFEM_ALWAYS_INLINE void Assemble(const int k, const T_result_t &F, const Q_t &Q, const q_t &q, asm_type &A)
Method defining partial assembly. The pointwise Dim x Dim matrices are stored as symmetric (when asm_...
static MFEM_ALWAYS_INLINE void MultAssembled(const int k, const TMatrix< qpts, 1, complex_t > &A, S_data_t &R)
Method for partially assembled action.
static MFEM_ALWAYS_INLINE void Assemble(const int k, const T_result_t &F, const Q_t &Q, const q_t &q, TVector< qpts, complex_t > &A)
Method defining partial assembly. Result in A is the quadrature-point dependent part of element matri...
static MFEM_ALWAYS_INLINE void Action(const int k, const T_result_t &F, const Q_t &Q, const q_t &q, S_data_t &R)
Method used for un-assembled (matrix free) action. grad_qpts = (w/det(J)) adj(J) adj(J)^t grad_qpts J...
coeff_t coefficient_type
Definition: tbilininteg.hpp:29
static MFEM_ALWAYS_INLINE void MultAssembled(const int k, const TMatrix< qpts, 6, complex_t > &A, S_data_t &R)
Method for partially assembled action. A [M x Dim*(Dim+1)/2] - partially assembled Dim x Dim symmetri...
TVector< qpts, complex_t > type
Definition: tbilininteg.hpp:67
static const bool out_values
Definition: tbilininteg.hpp:53
Diffusion kernel.
static MFEM_ALWAYS_INLINE void Action(const int k, const T_result_t &F, const Q_t &Q, const q_t &q, S_data_t &R)
Method used for un-assembled (matrix free) action.
static MFEM_ALWAYS_INLINE void MultAssembled(const int k, const TVector< qpts, complex_t > &A, S_data_t &R)
Method for partially assembled action.
IntRuleCoefficient< IR, coeff_t, impl_traits_t >::Type Type
void Scale(const data_t scale)
Definition: ttensor.hpp:337
TIntegrator(const coefficient_type &c)
Definition: tbilininteg.hpp:36