MFEM v4.10.0
Finite element discretization library
Loading...
Searching...
No Matches
bilininteg.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_BILININTEG
13#define MFEM_BILININTEG
14
15#include "../config/config.hpp"
16#include "nonlininteg.hpp"
17#include "fespace.hpp"
19#include "qfunction.hpp"
20#include <memory>
21
22#include "kernel_dispatch.hpp"
23
24namespace mfem
25{
26class QuadratureSpace;
27class FaceQuadratureSpace;
28
29/// Abstract base class BilinearFormIntegrator
31{
32protected:
35
36public:
37 // TODO: add support for other assembly levels (in addition to PA) and their
38 // actions.
39
40 // TODO: for mixed meshes the quadrature rules to be used by methods like
41 // AssemblePA() can be given as a QuadratureSpace, e.g. using a new method:
42 // SetQuadratureSpace().
43
44 // TODO: the methods for the various assembly levels make sense even in the
45 // base class NonlinearFormIntegrator, except that not all assembly levels
46 // make sense for the action of the nonlinear operator (but they all make
47 // sense for its Jacobian).
48
49 /// Method defining partial assembly.
50 /** The result of the partial assembly is stored internally so that it can be
51 used later in the methods AddMultPA() and AddMultTransposePA(). */
52 void AssemblePA(const FiniteElementSpace &fes) override;
53 /** Used with BilinearFormIntegrators that have different spaces. */
54 void AssemblePA(const FiniteElementSpace &trial_fes,
55 const FiniteElementSpace &test_fes) override;
56
57 /// Method defining partial assembly on NURBS patches.
58 /** The result of the partial assembly is stored internally so that it can be
59 used later in the method AddMultNURBSPA(). */
60 virtual void AssembleNURBSPA(const FiniteElementSpace &fes);
61
62 virtual void AssemblePABoundary(const FiniteElementSpace &fes);
63
64 virtual void AssemblePAInteriorFaces(const FiniteElementSpace &fes);
65
66 virtual void AssemblePABoundaryFaces(const FiniteElementSpace &fes);
67
68 /// Assemble diagonal and add it to Vector @a diag.
69 virtual void AssembleDiagonalPA(Vector &diag);
70
71 /// Assemble diagonal of $A D A^T$ ($A$ is this integrator) and add it to @a diag.
72 virtual void AssembleDiagonalPA_ADAt(const Vector &D, Vector &diag);
73
74 /// Method for partially assembled action.
75 /** Perform the action of integrator on the input @a x and add the result to
76 the output @a y. Both @a x and @a y are E-vectors, i.e. they represent
77 the element-wise discontinuous version of the FE space.
78
79 This method can be called only after the method AssemblePA() has been
80 called. */
81 void AddMultPA(const Vector &x, Vector &y) const override;
82
83 virtual void AddAbsMultPA(const Vector &x, Vector &y) const;
84
85 /// Method for partially assembled action on NURBS patches.
86 virtual void AddMultNURBSPA(const Vector&x, Vector&y) const;
87
88 /// Method for partially assembled transposed action.
89 /** Perform the transpose action of integrator on the input @a x and add the
90 result to the output @a y. Both @a x and @a y are E-vectors, i.e. they
91 represent the element-wise discontinuous version of the FE space.
92
93 This method can be called only after the method AssemblePA() has been
94 called. */
95 virtual void AddMultTransposePA(const Vector &x, Vector &y) const;
96
97 virtual void AddAbsMultTransposePA(const Vector &x, Vector &y) const;
98
99 /// Method defining element assembly.
100 /** The result of the element assembly is added to the @a emat Vector if
101 @a add is true. Otherwise, if @a add is false, we set @a emat. */
102 virtual void AssembleEA(const FiniteElementSpace &fes, Vector &emat,
103 const bool add = true);
104 /** Used with BilinearFormIntegrators that have different spaces. */
105 // virtual void AssembleEA(const FiniteElementSpace &trial_fes,
106 // const FiniteElementSpace &test_fes,
107 // Vector &emat);
108
109 /// Method defining matrix-free assembly.
110 /** The result of fully matrix-free assembly is stored internally so that it
111 can be used later in the methods AddMultMF() and AddMultTransposeMF(). */
112 void AssembleMF(const FiniteElementSpace &fes) override;
113
114 /** Perform the action of integrator on the input @a x and add the result to
115 the output @a y. Both @a x and @a y are E-vectors, i.e. they represent
116 the element-wise discontinuous version of the FE space.
117
118 This method can be called only after the method AssembleMF() has been
119 called. */
120 void AddMultMF(const Vector &x, Vector &y) const override;
121
122 /** Perform the transpose action of integrator on the input @a x and add the
123 result to the output @a y. Both @a x and @a y are E-vectors, i.e. they
124 represent the element-wise discontinuous version of the FE space.
125
126 This method can be called only after the method AssemblePA() has been
127 called. */
128 virtual void AddMultTransposeMF(const Vector &x, Vector &y) const;
129
130 /// Assemble diagonal and add it to Vector @a diag.
131 virtual void AssembleDiagonalMF(Vector &diag);
132
133 virtual void AssembleEABoundary(const FiniteElementSpace &fes,
134 Vector &ea_data_bdr,
135 const bool add = true);
136
137 virtual void AssembleEAInteriorFaces(const FiniteElementSpace &fes,
138 Vector &ea_data_int,
139 Vector &ea_data_ext,
140 const bool add = true);
141
142 /// @brief Method defining element assembly for mixed trace integrators.
143 ///
144 /// This is the element assembly analogue of AssembleFaceMatrix(const
145 /// FiniteElement&, const FiniteElement&, const FiniteElement&,
146 /// FaceElementTransformations&, DenseMatrix&).
147 virtual void AssembleEAInteriorFaces(const FiniteElementSpace &trial_fes,
148 const FiniteElementSpace &test_fes,
149 Vector &emat,
150 const bool add = true);
151
152 virtual void AssembleEABoundaryFaces(const FiniteElementSpace &fes,
153 Vector &ea_data_bdr,
154 const bool add = true);
155
156 /// Given a particular Finite Element computes the element matrix elmat.
157 virtual void AssembleElementMatrix(const FiniteElement &el,
159 DenseMatrix &elmat);
160
161 /** Compute the local matrix representation of a bilinear form
162 $a(u,v)$ defined on different trial (given by $u$) and test
163 (given by $v$) spaces. The rows in the local matrix correspond
164 to the test dofs and the columns -- to the trial dofs. */
165 virtual void AssembleElementMatrix2(const FiniteElement &trial_fe,
166 const FiniteElement &test_fe,
168 DenseMatrix &elmat);
169
170 /** Given a particular NURBS patch, computes the patch matrix as a
171 SparseMatrix @a smat.
172 */
173 virtual void AssemblePatchMatrix(const int patch,
174 const FiniteElementSpace &fes,
175 SparseMatrix*& smat);
176
177 virtual void AssembleFaceMatrix(const FiniteElement &el1,
178 const FiniteElement &el2,
180 DenseMatrix &elmat);
181
182 virtual void AssembleFaceMatrix(const FiniteElement &trial_fe1,
183 const FiniteElement &test_fe1,
184 const FiniteElement &trial_fe2,
185 const FiniteElement &test_fe2,
187 DenseMatrix &elmat);
188
189 /** Abstract method used for assembling TraceFaceIntegrators in a
190 MixedBilinearForm. */
191 virtual void AssembleFaceMatrix(const FiniteElement &trial_face_fe,
192 const FiniteElement &test_fe1,
193 const FiniteElement &test_fe2,
195 DenseMatrix &elmat);
196
197 /** Abstract method used for assembling TraceFaceIntegrators for
198 DPG weak formulations. */
199 virtual void AssembleTraceFaceMatrix(int elem,
200 const FiniteElement &trial_face_fe,
201 const FiniteElement &test_fe,
203 DenseMatrix &elmat);
204
205
206 /// @brief Perform the local action of the BilinearFormIntegrator.
207 /// Note that the default implementation in the base class is general but not
208 /// efficient.
211 const Vector &elfun, Vector &elvect) override;
212
213 /// @brief Perform the local action of the BilinearFormIntegrator resulting
214 /// from a face integral term.
215 /// Note that the default implementation in the base class is general but not
216 /// efficient.
217 void AssembleFaceVector(const FiniteElement &el1,
218 const FiniteElement &el2,
220 const Vector &elfun, Vector &elvect) override;
221
224 const Vector &elfun, DenseMatrix &elmat) override
225 { AssembleElementMatrix(el, Tr, elmat); }
226
228 const FiniteElement &el2,
230 const Vector &elfun, DenseMatrix &elmat) override
231 { AssembleFaceMatrix(el1, el2, Tr, elmat); }
232
233 /** @brief Virtual method required for Zienkiewicz-Zhu type error estimators.
234
235 The purpose of the method is to compute a local "flux" finite element
236 function given a local finite element solution. The "flux" function has
237 to be computed in terms of its coefficients (represented by the Vector
238 @a flux) which multiply the basis functions defined by the FiniteElement
239 @a fluxelem. Typically, the "flux" function will have more than one
240 component and consequently @a flux should be store the coefficients of
241 all components: first all coefficient for component 0, then all
242 coefficients for component 1, etc. What the "flux" function represents
243 depends on the specific integrator. For example, in the case of
244 DiffusionIntegrator, the flux is the gradient of the solution multiplied
245 by the diffusion coefficient.
246
247 @param[in] el FiniteElement of the solution.
248 @param[in] Trans The ElementTransformation describing the physical
249 position of the mesh element.
250 @param[in] u Solution coefficients representing the expansion of the
251 solution function in the basis of @a el.
252 @param[in] fluxelem FiniteElement of the "flux".
253 @param[out] flux "Flux" coefficients representing the expansion of the
254 "flux" function in the basis of @a fluxelem. The size
255 of @a flux as a Vector has to be set by this method,
256 e.g. using Vector::SetSize().
257 @param[in] with_coef If zero (the default value is 1) the implementation
258 of the method may choose not to scale the "flux"
259 function by any coefficients describing the
260 integrator.
261 @param[in] ir If passed (the default value is NULL), the implementation
262 of the method will ignore the integration rule provided
263 by the @a fluxelem parameter and, instead, compute the
264 discrete flux at the points specified by the integration
265 rule @a ir.
266 */
267 virtual void ComputeElementFlux(const FiniteElement &el,
269 Vector &u,
270 const FiniteElement &fluxelem,
271 Vector &flux, bool with_coef = true,
272 const IntegrationRule *ir = NULL) { }
273
274 /** @brief Virtual method required for Zienkiewicz-Zhu type error estimators.
275
276 The purpose of this method is to compute a local number that measures the
277 energy of a given "flux" function (see ComputeElementFlux() for a
278 description of the "flux" function). Typically, the energy of a "flux"
279 function should be equal to a_local(u,u), if the "flux" is defined from
280 a solution u; here a_local(.,.) denotes the element-local bilinear
281 form represented by the integrator.
282
283 @param[in] fluxelem FiniteElement of the "flux".
284 @param[in] Trans The ElementTransformation describing the physical
285 position of the mesh element.
286 @param[in] flux "Flux" coefficients representing the expansion of the
287 "flux" function in the basis of @a fluxelem.
288 @param[out] d_energy If not NULL, the given Vector should be set to
289 represent directional energy split that can be used
290 for anisotropic error estimation.
291 @returns The computed energy.
292 */
293 virtual real_t ComputeFluxEnergy(const FiniteElement &fluxelem,
295 Vector &flux, Vector *d_energy = NULL)
296 { return 0.0; }
297
298 /** @brief For bilinear forms on element faces, specifies if the normal
299 derivatives are needed on the faces or just the face restriction.
300
301 @details if RequiresFaceNormalDerivatives() == true, then
302 AddMultPAFaceNormalDerivatives(...) should be invoked in place
303 of AddMultPA(...) and L2NormalDerivativeFaceRestriction should
304 be used to compute the normal derivatives. This is used for some
305 DG integrators, for example DGDiffusionIntegrator.
306
307 @returns whether normal derivatives appear in the bilinear form.
308 */
309 virtual bool RequiresFaceNormalDerivatives() const { return false; }
310
311 /// Method for partially assembled action.
312 /** @brief For bilinear forms on element faces that depend on the normal
313 derivative on the faces, computes the action of integrator to the
314 face values @a x and reference-normal derivatives @a dxdn and adds
315 the result to @a y and @a dydn.
316
317 @details This method can be called only after the method AssemblePA() has
318 been called.
319
320 @param[in] x E-vector of face values (provided by
321 FaceRestriction::Mult)
322 @param[in] dxdn E-vector of face reference-normal derivatives
323 (provided by FaceRestriction::NormalDerivativeMult)
324 @param[in,out] y E-vector of face values to add action to.
325 @param[in,out] dydn E-vector of face reference-normal derivative values to
326 add action to.
327 */
328 virtual void AddMultPAFaceNormalDerivatives(const Vector &x, const Vector &dxdn,
329 Vector &y, Vector &dydn) const;
330
332};
333
334/** Wraps a given @a BilinearFormIntegrator and transposes the resulting element
335 matrices. See for example ex9, ex9p. */
337{
338private:
339 int own_bfi;
341
342 DenseMatrix bfi_elmat;
343
344public:
346 { bfi = bfi_; own_bfi = own_bfi_; }
347
348 void SetIntRule(const IntegrationRule *ir) override;
349
352 DenseMatrix &elmat) override;
353
354 void AssembleElementMatrix2(const FiniteElement &trial_fe,
355 const FiniteElement &test_fe,
357 DenseMatrix &elmat) override;
358
360 void AssembleFaceMatrix(const FiniteElement &el1,
361 const FiniteElement &el2,
363 DenseMatrix &elmat) override;
364
365 void AssembleFaceMatrix(const FiniteElement &trial_fe1,
366 const FiniteElement &test_fe1,
367 const FiniteElement &trial_fe2,
368 const FiniteElement &test_fe2,
370 DenseMatrix &elmat) override;
371
372 void AssemblePA(const FiniteElementSpace& fes) override
373 {
374 bfi->AssemblePA(fes);
375 }
376
377 void AssemblePA(const FiniteElementSpace &trial_fes,
378 const FiniteElementSpace &test_fes) override
379 {
380 bfi->AssemblePA(test_fes, trial_fes); // Reverse test and trial
381 }
382
384 {
385 bfi->AssemblePAInteriorFaces(fes);
386 }
387
389 {
390 bfi->AssemblePABoundaryFaces(fes);
391 }
392
393 void AddMultTransposePA(const Vector &x, Vector &y) const override
394 {
395 bfi->AddMultPA(x, y);
396 }
397
398 void AddMultPA(const Vector& x, Vector& y) const override
399 {
400 bfi->AddMultTransposePA(x, y);
401 }
402
403 void AssembleEA(const FiniteElementSpace &fes, Vector &emat,
404 const bool add) override;
405
408 Vector &ea_data_int,
409 Vector &ea_data_ext,
410 const bool add) override;
411
413 Vector &ea_data_bdr,
414 const bool add) override;
415
416 virtual ~TransposeIntegrator() { if (own_bfi) { delete bfi; } }
417};
418
420{
421private:
422 int own_bfi;
424
425public:
426 LumpedIntegrator (BilinearFormIntegrator *bfi_, int own_bfi_ = 1)
427 { bfi = bfi_; own_bfi = own_bfi_; }
428
429 void SetIntRule(const IntegrationRule *ir) override;
430
433 DenseMatrix &elmat) override;
434
435 virtual ~LumpedIntegrator() { if (own_bfi) { delete bfi; } }
436};
437
438/// Integrator that inverts the matrix assembled by another integrator.
440{
441private:
442 int own_integrator;
443 BilinearFormIntegrator *integrator;
444
445public:
446 InverseIntegrator(BilinearFormIntegrator *integ, int own_integ = 1)
447 { integrator = integ; own_integrator = own_integ; }
448
449 void SetIntRule(const IntegrationRule *ir) override;
450
453 DenseMatrix &elmat) override;
454
455 virtual ~InverseIntegrator() { if (own_integrator) { delete integrator; } }
456};
457
458/// Integrator defining a sum of multiple Integrators.
460{
461private:
462 int own_integrators;
463 mutable DenseMatrix elem_mat;
465
466public:
467 SumIntegrator(int own_integs = 1) { own_integrators = own_integs; }
468
469 void SetIntRule(const IntegrationRule *ir) override;
470
472 { integrators.Append(integ); }
473
476 DenseMatrix &elmat) override;
477 void AssembleElementMatrix2(const FiniteElement &trial_fe,
478 const FiniteElement &test_fe,
480 DenseMatrix &elmat) override;
481
483 void AssembleFaceMatrix(const FiniteElement &el1,
484 const FiniteElement &el2,
486 DenseMatrix &elmat) override;
487
488 void AssembleFaceMatrix(const FiniteElement &trial_face_fe,
489 const FiniteElement &test_fe1,
490 const FiniteElement &test_fe2,
492 DenseMatrix &elmat) override;
493
495 void AssemblePA(const FiniteElementSpace& fes) override;
496
497 void AssembleDiagonalPA(Vector &diag) override;
498
499 void AssemblePAInteriorFaces(const FiniteElementSpace &fes) override;
500
501 void AssemblePABoundaryFaces(const FiniteElementSpace &fes) override;
502
503 void AddMultTransposePA(const Vector &x, Vector &y) const override;
504
505 void AddAbsMultTransposePA(const Vector &x, Vector &y) const override;
506
507 void AddMultPA(const Vector& x, Vector& y) const override;
508
509 void AddAbsMultPA(const Vector& x, Vector& y) const override;
510
511 void AssembleMF(const FiniteElementSpace &fes) override;
512
513 void AddMultMF(const Vector &x, Vector &y) const override;
514
515 void AddMultTransposeMF(const Vector &x, Vector &y) const override;
516
517 void AssembleDiagonalMF(Vector &diag) override;
518
519 void AssembleEA(const FiniteElementSpace &fes, Vector &emat,
520 const bool add) override;
521
524 Vector &ea_data_int,
525 Vector &ea_data_ext,
526 const bool add) override;
527
529 Vector &ea_data_bdr,
530 const bool add) override;
531
532 virtual ~SumIntegrator();
533};
534
535/** An abstract class for integrating the product of two scalar basis functions
536 with an optional scalar coefficient. */
538{
539public:
540 void AssembleElementMatrix2(const FiniteElement &trial_fe,
541 const FiniteElement &test_fe,
543 DenseMatrix &elmat) override;
544
545 /// Support for use in BilinearForm. Can be used only when appropriate.
548 DenseMatrix &elmat) override
549 { AssembleElementMatrix2(fe, fe, Trans, elmat); }
550
551protected:
552 /// This parameter can be set by derived methods to enable single shape
553 /// evaluation in case CalcTestShape() and CalcTrialShape() return the same
554 /// result if given the same FiniteElement. The default is false.
556
559
561 const FiniteElement & trial_fe,
562 const FiniteElement & test_fe) const
563 {
564 return (trial_fe.GetRangeType() == mfem::FiniteElement::SCALAR &&
566 }
567
568 virtual const char * FiniteElementTypeFailureMessage() const
569 {
570 return "MixedScalarIntegrator: "
571 "Trial and test spaces must both be scalar fields.";
572 }
573
574 virtual int GetIntegrationOrder(const FiniteElement & trial_fe,
575 const FiniteElement & test_fe,
577 { return trial_fe.GetOrder() + test_fe.GetOrder() + Trans.OrderW(); }
578
579
580 virtual void CalcTestShape(const FiniteElement & test_fe,
582 Vector & shape)
583 { test_fe.CalcPhysShape(Trans, shape); }
584
585 virtual void CalcTrialShape(const FiniteElement & trial_fe,
587 Vector & shape)
588 { trial_fe.CalcPhysShape(Trans, shape); }
589
591
592private:
593
594#ifndef MFEM_THREAD_SAFE
595 Vector test_shape;
596 Vector trial_shape;
597#endif
598
599};
600
601/** An abstract class for integrating the inner product of two vector basis
602 functions with an optional scalar, vector, or matrix coefficient. */
604{
605public:
606
607 void AssembleElementMatrix2(const FiniteElement &trial_fe,
608 const FiniteElement &test_fe,
610 DenseMatrix &elmat) override;
611
612 /// Support for use in BilinearForm. Can be used only when appropriate.
615 DenseMatrix &elmat) override
616 { AssembleElementMatrix2(fe, fe, Trans, elmat); }
617
618protected:
619 /// This parameter can be set by derived methods to enable single shape
620 /// evaluation in case CalcTestShape() and CalcTrialShape() return the same
621 /// result if given the same FiniteElement. The default is false.
623
625 : same_calc_shape(false), Q(NULL), VQ(NULL), DQ(NULL), MQ(NULL) {}
627 : same_calc_shape(false), Q(&q), VQ(NULL), DQ(NULL), MQ(NULL) {}
629 : same_calc_shape(false), Q(NULL), VQ(diag?NULL:&vq), DQ(diag?&vq:NULL),
630 MQ(NULL) {}
632 : same_calc_shape(false), Q(NULL), VQ(NULL), DQ(NULL), MQ(&mq) {}
633
635 const FiniteElement & trial_fe,
636 const FiniteElement & test_fe) const
637 {
638 return (trial_fe.GetRangeType() == mfem::FiniteElement::VECTOR &&
640 }
641
642 virtual const char * FiniteElementTypeFailureMessage() const
643 {
644 return "MixedVectorIntegrator: "
645 "Trial and test spaces must both be vector fields";
646 }
647
648 virtual int GetIntegrationOrder(const FiniteElement & trial_fe,
649 const FiniteElement & test_fe,
651 { return trial_fe.GetOrder() + test_fe.GetOrder() + Trans.OrderW(); }
652
653
654 virtual int GetTestVDim(const FiniteElement & test_fe)
655 { return std::max(space_dim, test_fe.GetRangeDim()); }
656
657 virtual void CalcTestShape(const FiniteElement & test_fe,
659 DenseMatrix & shape)
660 { test_fe.CalcVShape(Trans, shape); }
661
662 virtual int GetTrialVDim(const FiniteElement & trial_fe)
663 { return std::max(space_dim, trial_fe.GetRangeDim()); }
664
665 virtual void CalcTrialShape(const FiniteElement & trial_fe,
667 DenseMatrix & shape)
668 { trial_fe.CalcVShape(Trans, shape); }
669
675
676private:
677
678#ifndef MFEM_THREAD_SAFE
679 Vector V;
680 Vector D;
681 DenseMatrix M;
682 DenseMatrix test_shape;
683 DenseMatrix trial_shape;
684 DenseMatrix shape_tmp;
685#endif
686
687};
688
689/** An abstract class for integrating the product of a scalar basis function and
690 the inner product of a vector basis function with a vector coefficient. In
691 2D the inner product can be replaced with a cross product. */
693{
694public:
695
696 void AssembleElementMatrix2(const FiniteElement &trial_fe,
697 const FiniteElement &test_fe,
699 DenseMatrix &elmat) override;
700
701 /// Support for use in BilinearForm. Can be used only when appropriate.
702 /** Appropriate use cases are classes derived from
703 MixedScalarVectorIntegrator where the trial and test spaces can be the
704 same. Examples of such classes are: MixedVectorDivergenceIntegrator,
705 MixedScalarWeakDivergenceIntegrator, etc. */
708 DenseMatrix &elmat) override
709 { AssembleElementMatrix2(fe, fe, Trans, elmat); }
710
711protected:
712
713 MixedScalarVectorIntegrator(VectorCoefficient &vq, bool transpose_ = false,
714 bool cross_2d_ = false)
715 : VQ(&vq), transpose(transpose_), cross_2d(cross_2d_) {}
716
718 const FiniteElement & trial_fe,
719 const FiniteElement & test_fe) const
720 {
721 return ((transpose &&
724 (!transpose &&
727 );
728 }
729
730 virtual const char * FiniteElementTypeFailureMessage() const
731 {
732 if ( transpose )
733 {
734 return "MixedScalarVectorIntegrator: "
735 "Trial space must be a vector field "
736 "and the test space must be a scalar field";
737 }
738 else
739 {
740 return "MixedScalarVectorIntegrator: "
741 "Trial space must be a scalar field "
742 "and the test space must be a vector field";
743 }
744 }
745
746 virtual int GetIntegrationOrder(const FiniteElement & trial_fe,
747 const FiniteElement & test_fe,
749 { return trial_fe.GetOrder() + test_fe.GetOrder() + Trans.OrderW(); }
750
751
752 virtual int GetVDim(const FiniteElement & vector_fe)
753 { return std::max(space_dim, vector_fe.GetRangeDim()); }
754
755 virtual void CalcVShape(const FiniteElement & vector_fe,
757 DenseMatrix & shape_)
758 { vector_fe.CalcVShape(Trans, shape_); }
759
760 virtual void CalcShape(const FiniteElement & scalar_fe,
762 Vector & shape_)
763 { scalar_fe.CalcPhysShape(Trans, shape_); }
764
768 bool cross_2d; // In 2D use a cross product rather than a dot product
769
770private:
771
772#ifndef MFEM_THREAD_SAFE
773 Vector V;
774 DenseMatrix vshape;
775 Vector shape;
776 Vector vshape_tmp;
777#endif
778
779};
780
781/** Class for integrating the bilinear form $a(u,v) := (Q u, v)$ in either 1D, 2D,
782 or 3D and where $Q$ is an optional scalar coefficient, $u$ and $v$ are each in $H^1$
783 or $L_2$. */
791
792/** Class for integrating the bilinear form $a(u,v) := (\vec{V} u, v)$ in either 2D, or
793 3D and where $\vec{V}$ is a vector coefficient, $u$ is in $H^1$ or $L_2$ and $v$ is in $H(curl)$
794 or $H(div)$. */
801
802/** Class for integrating the bilinear form $a(u,v) := (Q \nabla u, v)$ in 1D where Q
803 is an optional scalar coefficient, $u$ is in $H^1$, and $v$ is in $L_2$. */
805{
806public:
810
811protected:
813 const FiniteElement & trial_fe,
814 const FiniteElement & test_fe) const override
815 {
816 return (trial_fe.GetDim() == 1 && test_fe.GetDim() == 1 &&
819 }
820
821 const char * FiniteElementTypeFailureMessage() const override
822 {
823 return "MixedScalarDerivativeIntegrator: "
824 "Trial and test spaces must both be scalar fields in 1D "
825 "and the trial space must implement CalcDShape.";
826 }
827
828 void CalcTrialShape(const FiniteElement & trial_fe,
830 Vector & shape) override
831 {
832 DenseMatrix dshape(shape.GetData(), shape.Size(), 1);
833 trial_fe.CalcPhysDShape(Trans, dshape);
834 }
835};
836
837/** Class for integrating the bilinear form $a(u,v) := -(Q u, \nabla v)$ in 1D where $Q$
838 is an optional scalar coefficient, $u$ is in $L_2$, and $v$ is in $H^1$. */
840{
841public:
845
846protected:
848 const FiniteElement & trial_fe,
849 const FiniteElement & test_fe) const override
850 {
851 return (trial_fe.GetDim() == 1 && test_fe.GetDim() == 1 &&
854 }
855
856 const char * FiniteElementTypeFailureMessage() const override
857 {
858 return "MixedScalarWeakDerivativeIntegrator: "
859 "Trial and test spaces must both be scalar fields in 1D "
860 "and the test space must implement CalcDShape with "
861 "map type \"VALUE\".";
862 }
863
864 void CalcTestShape(const FiniteElement & test_fe,
866 Vector & shape) override
867 {
868 DenseMatrix dshape(shape.GetData(), shape.Size(), 1);
869 test_fe.CalcPhysDShape(Trans, dshape);
870 shape *= -1.0;
871 }
872};
873
874/** Class for integrating the bilinear form $a(u,v) := (Q \nabla \cdot u, v)$ in either 2D
875 or 3D where $Q$ is an optional scalar coefficient, $u$ is in $H(div)$, and $v$ is a
876 scalar field. */
878{
879public:
883
884protected:
886 const FiniteElement & trial_fe,
887 const FiniteElement & test_fe) const override
888 {
889 return (trial_fe.GetDerivType() == mfem::FiniteElement::DIV &&
891 }
892
893 const char * FiniteElementTypeFailureMessage() const override
894 {
895 return "MixedScalarDivergenceIntegrator: "
896 "Trial must be $H(div)$ and the test space must be a "
897 "scalar field";
898 }
899
900 int GetIntegrationOrder(const FiniteElement & trial_fe,
901 const FiniteElement & test_fe,
902 ElementTransformation &Trans) override
903 { return trial_fe.GetOrder() + test_fe.GetOrder() + Trans.OrderW() - 1; }
904
905 void CalcTrialShape(const FiniteElement & trial_fe,
907 Vector & shape) override
908 { trial_fe.CalcPhysDivShape(Trans, shape); }
909};
910
911/** Class for integrating the bilinear form $a(u,v) := (\vec{V} \nabla \cdot u, v)$ in either 2D
912 or 3D where $\vec{V}$ is a vector coefficient, $u$ is in $H(div)$, and $v$ is in $H(div)$. */
914{
915public:
918
919protected:
921 const FiniteElement & trial_fe,
922 const FiniteElement & test_fe) const override
923 {
924 return (trial_fe.GetDerivType() == mfem::FiniteElement::DIV &&
926 }
927
928 const char * FiniteElementTypeFailureMessage() const override
929 {
930 return "MixedVectorDivergenceIntegrator: "
931 "Trial must be H(Div) and the test space must be a "
932 "vector field";
933 }
934
935 // Subtract one due to the divergence and add one for the coefficient
936 // which is assumed to be at least linear.
937 int GetIntegrationOrder(const FiniteElement & trial_fe,
938 const FiniteElement & test_fe,
939 ElementTransformation &Trans) override
940 { return trial_fe.GetOrder() + test_fe.GetOrder() + Trans.OrderW() - 1 + 1; }
941
942 void CalcShape(const FiniteElement & scalar_fe,
944 Vector & shape) override
945 { scalar_fe.CalcPhysDivShape(Trans, shape); }
946};
947
948/** Class for integrating the bilinear form $a(u,v) := -(Q u, \nabla \cdot v)$ in either 2D
949 or 3D where $Q$ is an optional scalar coefficient, $u$ is in $L_2$ or $H^1$, and $v$ is
950 in $H(div)$. */
952{
953public:
957
959 void AssemblePA(const FiniteElementSpace &trial_fes,
960 const FiniteElementSpace &test_fes) override;
961
962 void AddMultPA(const Vector &x, Vector &y) const override;
963 void AddMultTransposePA(const Vector &x, Vector &y) const override;
964
965protected:
967 const FiniteElement & trial_fe,
968 const FiniteElement & test_fe) const override
969 {
970 return (trial_fe.GetRangeType() == mfem::FiniteElement::SCALAR &&
972 }
973
974 const char * FiniteElementTypeFailureMessage() const override
975 {
976 return "MixedScalarWeakGradientIntegrator: "
977 "Trial space must be a scalar field "
978 "and the test space must be H(Div)";
979 }
980
982 const FiniteElement &test_fe,
983 ElementTransformation &Trans) override
984 { return trial_fe.GetOrder() + test_fe.GetOrder() + Trans.OrderW() - 1; }
985
986 void CalcTestShape(const FiniteElement &test_fe,
987 ElementTransformation &Trans, Vector &shape) override
988 {
989 test_fe.CalcPhysDivShape(Trans, shape);
990 shape *= -1.0;
991 }
992
994 const DofToQuad *mapsO = nullptr; ///< Not owned. HDiv open map.
995 const DofToQuad *L2mapsO = nullptr; ///< Not owned. Scalar open/closed map.
996 const DofToQuad *mapsC = nullptr; ///< Not owned. HDiv closed map.
997 int dim = 0, ne = 0, dofs1D = 0, L2dofs1D = 0, quad1D = 0;
998};
999
1000/** Class for integrating the bilinear form $a(u,v) := (Q \mathrm{curl}(u), v)$ in 2D where
1001 $Q$ is an optional scalar coefficient, $u$ is in $H(curl)$, and $v$ is in $L_2$ or
1002 $H^1$. */
1004{
1005public:
1009
1010protected:
1012 const FiniteElement & trial_fe,
1013 const FiniteElement & test_fe) const override
1014 {
1015 return (trial_fe.GetDim() == 2 && test_fe.GetDim() == 2 &&
1018 }
1019
1020 const char * FiniteElementTypeFailureMessage() const override
1021 {
1022 return "MixedScalarCurlIntegrator: "
1023 "Trial must be H(Curl) and the test space must be a "
1024 "scalar field";
1025 }
1026
1028 const FiniteElement & test_fe,
1029 ElementTransformation &Trans) override
1030 { return trial_fe.GetOrder() + test_fe.GetOrder() + Trans.OrderW() - 1; }
1031
1032 void CalcTrialShape(const FiniteElement & trial_fe,
1033 ElementTransformation &Trans,
1034 Vector & shape) override
1035 {
1036 DenseMatrix dshape(shape.GetData(), shape.Size(), 1);
1037 trial_fe.CalcPhysCurlShape(Trans, dshape);
1038 }
1039
1041 void AssemblePA(const FiniteElementSpace &trial_fes,
1042 const FiniteElementSpace &test_fes) override;
1043
1044 void AddMultPA(const Vector&, Vector&) const override;
1045 void AddMultTransposePA(const Vector &x, Vector &y) const override;
1046
1047 // PA extension
1049 const DofToQuad *mapsO; ///< Not owned. DOF-to-quad map, open.
1050 const DofToQuad *mapsC; ///< Not owned. DOF-to-quad map, closed.
1052};
1053
1054/** Class for integrating the bilinear form $a(u,v) := (Q u, \mathrm{curl}(v))$ in 2D where
1055 $Q$ is an optional scalar coefficient, $u$ is in $L_2$ or $H^1$, and $v$ is in
1056 $H(curl)$. Partial assembly (PA) is supported but could be further optimized
1057 by using more efficient threading and shared memory.
1058*/
1060{
1061public:
1065
1066protected:
1068 const FiniteElement & trial_fe,
1069 const FiniteElement & test_fe) const override
1070 {
1071 return (trial_fe.GetDim() == 2 && test_fe.GetDim() == 2 &&
1074 }
1075
1076 const char * FiniteElementTypeFailureMessage() const override
1077 {
1078 return "MixedScalarWeakCurlIntegrator: "
1079 "Trial space must be a scalar field "
1080 "and the test space must be H(Curl)";
1081 }
1082
1083 void CalcTestShape(const FiniteElement & test_fe,
1084 ElementTransformation &Trans,
1085 Vector & shape) override
1086 {
1087 DenseMatrix dshape(shape.GetData(), shape.Size(), 1);
1088 test_fe.CalcPhysCurlShape(Trans, dshape);
1089 }
1090};
1091
1092/** Class for integrating the bilinear form $a(u,v) := (Q u, v)$ in either 2D or
1093 3D and where $Q$ is an optional coefficient (of type scalar, matrix, or
1094 diagonal matrix) $u$ and $v$ are each in $H(curl)$ or $H(div)$. */
1106
1107/** Class for integrating the bilinear form $a(u,v) := (\vec{V} \times u, v)$ in 3D and where
1108 $\vec{V}$ is a vector coefficient $u$ and $v$ are each in $H(curl)$ or $H(div)$. */
1115
1116/** Class for integrating the bilinear form $a(u,v) := (\vec{V} \cdot u, v)$ in 2D or 3D and
1117 where $\vec{V}$ is a vector coefficient $u$ is in $H(curl)$ or $H(div)$ and $v$ is in $H^1$ or
1118 $L_2$. */
1120{
1121public:
1124
1126 const FiniteElement & trial_fe,
1127 const FiniteElement & test_fe) const override
1128 {
1129 return (trial_fe.GetRangeType() == mfem::FiniteElement::VECTOR &&
1131 }
1132
1133 const char * FiniteElementTypeFailureMessage() const override
1134 {
1135 return "MixedDotProductIntegrator: "
1136 "Trial space must be a vector field "
1137 "and the test space must be a scalar field";
1138 }
1139
1141 void AssemblePA(const FiniteElementSpace &trial_fes,
1142 const FiniteElementSpace &test_fes) override;
1143
1144 void AddMultPA(const Vector&, Vector&) const override;
1145 void AddMultTransposePA(const Vector&, Vector&) const override;
1146
1147private:
1148 Vector pa_data;
1149 const DofToQuad *mapsO = nullptr; ///< Not owned. Trial open map.
1150 const DofToQuad *mapsC = nullptr; ///< Not owned. Trial closed map.
1151 const DofToQuad *mapsTest = nullptr; ///< Not owned. Scalar test map.
1152 const GeometricFactors *geom = nullptr;///< Not owned.
1153 int dim = 0, ne = 0, dofs1D = 0, dofs1Dtest = 0, quad1D = 0;
1154 bool test_map_integral = false;
1155};
1156
1157/** Class for integrating the bilinear form $a(u,v) := (-\vec{V} \cdot u, \nabla \cdot v)$ in 2D or
1158 3D and where $\vec{V}$ is a vector coefficient $u$ is in $H(curl)$ or $H(div)$ and $v$ is in
1159 $H(div)$. */
1161{
1162public:
1165
1167 const FiniteElement & trial_fe,
1168 const FiniteElement & test_fe) const override
1169 {
1170 return (trial_fe.GetRangeType() == mfem::FiniteElement::VECTOR &&
1173 }
1174
1175 const char * FiniteElementTypeFailureMessage() const override
1176 {
1177 return "MixedWeakGradDotIntegrator: "
1178 "Trial space must be a vector field "
1179 "and the test space must be a vector field with a divergence";
1180 }
1181
1182 // Subtract one due to the gradient and add one for the coefficient
1183 // which is assumed to be at least linear.
1185 const FiniteElement & test_fe,
1186 ElementTransformation &Trans) override
1187 { return trial_fe.GetOrder() + test_fe.GetOrder() + Trans.OrderW() - 1 + 1; }
1188
1189 void CalcShape(const FiniteElement & scalar_fe,
1190 ElementTransformation &Trans,
1191 Vector & shape) override
1192 { scalar_fe.CalcPhysDivShape(Trans, shape); shape *= -1.0; }
1193};
1194
1195/** Class for integrating the bilinear form $a(u,v) := (v \vec{V} \times u, \nabla v)$ in 3D and
1196 where $\vec{V}$ is a vector coefficient $u$ is in $H(curl)$ or $H(div)$ and $v$ is in $H^1$. */
1198{
1199public:
1202
1204 const FiniteElement & trial_fe,
1205 const FiniteElement & test_fe) const override
1206 {
1207 return (trial_fe.GetRangeDim() == 3 &&
1211 }
1212
1213 const char * FiniteElementTypeFailureMessage() const override
1214 {
1215 return "MixedWeakDivCrossIntegrator: "
1216 "Trial space must be a vector field in 3D "
1217 "and the test space must be a scalar field with a gradient";
1218 }
1219
1220 int GetTestVDim(const FiniteElement & test_fe) override
1221 { return space_dim; }
1222
1223 void CalcTestShape(const FiniteElement & test_fe,
1224 ElementTransformation &Trans,
1225 DenseMatrix & shape) override
1226 { test_fe.CalcPhysDShape(Trans, shape); shape *= -1.0; }
1227};
1228
1229/** Class for integrating the bilinear form $a(u,v) := (Q \nabla u, \nabla v)$ in 3D
1230 or in 2D and where $Q$ is a scalar or matrix coefficient $u$ and $v$ are both in
1231 $H^1$. */
1233{
1234public:
1242
1244 const FiniteElement & trial_fe,
1245 const FiniteElement & test_fe) const override
1246 {
1247 return (trial_fe.GetRangeType() == mfem::FiniteElement::SCALAR &&
1251 }
1252
1253 const char * FiniteElementTypeFailureMessage() const override
1254 {
1255 return "MixedGradGradIntegrator: "
1256 "Trial and test spaces must both be scalar fields "
1257 "with a gradient operator.";
1258 }
1259
1261 const FiniteElement & test_fe,
1262 ElementTransformation &Trans) override
1263 {
1264 // Same as DiffusionIntegrator
1265 return test_fe.Space() == FunctionSpace::Pk ?
1266 trial_fe.GetOrder() + test_fe.GetOrder() - 2 :
1267 trial_fe.GetOrder() + test_fe.GetOrder() + test_fe.GetDim() - 1;
1268 }
1269
1270 int GetTrialVDim(const FiniteElement & trial_fe) override
1271 { return space_dim; }
1272
1273 void CalcTrialShape(const FiniteElement & trial_fe,
1274 ElementTransformation &Trans,
1275 DenseMatrix & shape) override
1276 { trial_fe.CalcPhysDShape(Trans, shape); }
1277
1278 int GetTestVDim(const FiniteElement & test_fe) override
1279 { return space_dim; }
1280
1281 void CalcTestShape(const FiniteElement & test_fe,
1282 ElementTransformation &Trans,
1283 DenseMatrix & shape) override
1284 { test_fe.CalcPhysDShape(Trans, shape); }
1285};
1286
1287/** Class for integrating the bilinear form $a(u,v) := (\vec{V} \times \nabla u, \nabla v)$ in 3D
1288 or in 2D and where $\vec{V}$ is a vector coefficient $u$ and $v$ are both in $H^1$. */
1290{
1291public:
1294
1296 const FiniteElement & trial_fe,
1297 const FiniteElement & test_fe) const override
1298 {
1299 return (trial_fe.GetRangeType() == mfem::FiniteElement::SCALAR &&
1303 }
1304
1305 const char * FiniteElementTypeFailureMessage() const override
1306 {
1307 return "MixedCrossGradGradIntegrator: "
1308 "Trial and test spaces must both be scalar fields "
1309 "with a gradient operator.";
1310 }
1311
1312 int GetTrialVDim(const FiniteElement & trial_fe) override
1313 { return space_dim; }
1314
1315 void CalcTrialShape(const FiniteElement & trial_fe,
1316 ElementTransformation &Trans,
1317 DenseMatrix & shape) override
1318 { trial_fe.CalcPhysDShape(Trans, shape); }
1319
1320 int GetTestVDim(const FiniteElement & test_fe) override
1321 { return space_dim; }
1322
1323 void CalcTestShape(const FiniteElement & test_fe,
1324 ElementTransformation &Trans,
1325 DenseMatrix & shape) override
1326 { test_fe.CalcPhysDShape(Trans, shape); }
1327};
1328
1329/** Class for integrating the bilinear form $a(u,v) := (Q \mathrm{curl}(u), \mathrm{curl}(v))$ in 3D
1330 and where $Q$ is a scalar or matrix coefficient $u$ and $v$ are both in
1331 $H(curl)$. */
1333{
1334public:
1342
1344 const FiniteElement & trial_fe,
1345 const FiniteElement & test_fe) const override
1346 {
1347 return (trial_fe.GetCurlDim() == 3 && test_fe.GetCurlDim() == 3 &&
1352 }
1353
1354 const char * FiniteElementTypeFailureMessage() const override
1355 {
1356 return "MixedCurlCurlIntegrator"
1357 "Trial and test spaces must both be vector fields in 3D "
1358 "with a curl.";
1359 }
1360
1361 int GetTrialVDim(const FiniteElement & trial_fe) override
1362 { return trial_fe.GetCurlDim(); }
1363
1364 void CalcTrialShape(const FiniteElement & trial_fe,
1365 ElementTransformation &Trans,
1366 DenseMatrix & shape) override
1367 { trial_fe.CalcPhysCurlShape(Trans, shape); }
1368
1369 int GetTestVDim(const FiniteElement & test_fe) override
1370 { return test_fe.GetCurlDim(); }
1371
1372 void CalcTestShape(const FiniteElement & test_fe,
1373 ElementTransformation &Trans,
1374 DenseMatrix & shape) override
1375 { test_fe.CalcPhysCurlShape(Trans, shape); }
1376};
1377
1378/** Class for integrating the bilinear form $a(u,v) := (\vec{V} \times \mathrm{curl}(u), \mathrm{curl}(v))$ in 3D
1379 and where $\vec{V}$ is a vector coefficient $u$ and $v$ are both in $H(curl)$. */
1381{
1382public:
1385
1387 const FiniteElement & trial_fe,
1388 const FiniteElement & test_fe) const override
1389 {
1390 return (trial_fe.GetCurlDim() == 3 && trial_fe.GetRangeDim() == 3 &&
1391 test_fe.GetCurlDim() == 3 && test_fe.GetRangeDim() == 3 &&
1396 }
1397
1398 const char * FiniteElementTypeFailureMessage() const override
1399 {
1400 return "MixedCrossCurlCurlIntegrator: "
1401 "Trial and test spaces must both be vector fields in 3D "
1402 "with a curl.";
1403 }
1404
1405 int GetTrialVDim(const FiniteElement & trial_fe) override
1406 { return trial_fe.GetCurlDim(); }
1407
1408 void CalcTrialShape(const FiniteElement & trial_fe,
1409 ElementTransformation &Trans,
1410 DenseMatrix & shape) override
1411 { trial_fe.CalcPhysCurlShape(Trans, shape); }
1412
1413 int GetTestVDim(const FiniteElement & test_fe) override
1414 { return test_fe.GetCurlDim(); }
1415
1416 void CalcTestShape(const FiniteElement & test_fe,
1417 ElementTransformation &Trans,
1418 DenseMatrix & shape) override
1419 { test_fe.CalcPhysCurlShape(Trans, shape); }
1420};
1421
1422/** Class for integrating the bilinear form $a(u,v) := (\vec{V} \times \mathrm{curl}(u), \nabla \cdot v)$ in 3D
1423 and where $\vec{V}$ is a vector coefficient $u$ is in $H(curl)$ and $v$ is in $H^1$. */
1425{
1426public:
1429
1431 const FiniteElement & trial_fe,
1432 const FiniteElement & test_fe) const override
1433 {
1434 return (trial_fe.GetCurlDim() == 3 &&
1439 }
1440
1441 const char * FiniteElementTypeFailureMessage() const override
1442 {
1443 return "MixedCrossCurlGradIntegrator"
1444 "Trial space must be a vector field in 3D with a curl"
1445 "and the test space must be a scalar field with a gradient";
1446 }
1447
1448 int GetTrialVDim(const FiniteElement & trial_fe) override
1449 { return trial_fe.GetCurlDim(); }
1450
1451 void CalcTrialShape(const FiniteElement & trial_fe,
1452 ElementTransformation &Trans,
1453 DenseMatrix & shape) override
1454 { trial_fe.CalcPhysCurlShape(Trans, shape); }
1455
1456 int GetTestVDim(const FiniteElement & test_fe) override
1457 { return space_dim; }
1458
1459 void CalcTestShape(const FiniteElement & test_fe,
1460 ElementTransformation &Trans,
1461 DenseMatrix & shape) override
1462 { test_fe.CalcPhysDShape(Trans, shape); }
1463};
1464
1465/** Class for integrating the bilinear form $a(u,v) := (v \times \nabla \cdot u, \mathrm{curl}(v))$ in 3D
1466 and where $v$ is a scalar coefficient $u$ is in $H^1$ and $v$ is in $H(curl)$. */
1468{
1469public:
1472
1474 const FiniteElement & trial_fe,
1475 const FiniteElement & test_fe) const override
1476 {
1477 return (test_fe.GetCurlDim() == 3 &&
1482 }
1483
1484 const char * FiniteElementTypeFailureMessage() const override
1485 {
1486 return "MixedCrossGradCurlIntegrator"
1487 "Trial space must be a scalar field in 3D with a gradient"
1488 "and the test space must be a vector field with a curl";
1489 }
1490
1491 int GetTrialVDim(const FiniteElement & trial_fe) override
1492 { return space_dim; }
1493
1494 void CalcTrialShape(const FiniteElement & trial_fe,
1495 ElementTransformation &Trans,
1496 DenseMatrix & shape) override
1497 { trial_fe.CalcPhysDShape(Trans, shape); }
1498
1499 int GetTestVDim(const FiniteElement & test_fe) override
1500 { return test_fe.GetCurlDim(); }
1501
1502 void CalcTestShape(const FiniteElement & test_fe,
1503 ElementTransformation &Trans,
1504 DenseMatrix & shape) override
1505 { test_fe.CalcPhysCurlShape(Trans, shape); }
1506};
1507
1508/** Class for integrating the bilinear form $a(u,v) := (\vec{V} \times u, \mathrm{curl}(v))$ in 3D and
1509 where $\vec{V}$ is a vector coefficient $u$ is in $H(curl)$ or $H(div)$ and $v$ is in
1510 $H(curl)$. */
1512{
1513public:
1516
1518 const FiniteElement & trial_fe,
1519 const FiniteElement & test_fe) const override
1520 {
1521 return (trial_fe.GetRangeDim() == 3 && test_fe.GetCurlDim() == 3 &&
1525 }
1526
1527 const char * FiniteElementTypeFailureMessage() const override
1528 {
1529 return "MixedWeakCurlCrossIntegrator: "
1530 "Trial space must be a vector field in 3D "
1531 "and the test space must be a vector field with a curl";
1532 }
1533
1534 int GetTestVDim(const FiniteElement & test_fe) override
1535 { return test_fe.GetCurlDim(); }
1536
1537 void CalcTestShape(const FiniteElement & test_fe,
1538 ElementTransformation &Trans,
1539 DenseMatrix & shape) override
1540 { test_fe.CalcPhysCurlShape(Trans, shape); }
1541};
1542
1543/** Class for integrating the bilinear form $a(u,v) := (\vec{V} \times u, \mathrm{curl}(v))$ in 2D and
1544 where $\vec{V}$ is a vector coefficient $u$ is in $H(curl)$ or $H(div)$ and $v$ is in
1545 $H(curl)$. */
1547{
1548public:
1551
1553 const FiniteElement & trial_fe,
1554 const FiniteElement & test_fe) const override
1555 {
1556 return (trial_fe.GetDim() == 2 && test_fe.GetDim() == 2 &&
1560 }
1561
1562 const char * FiniteElementTypeFailureMessage() const override
1563 {
1564 return "MixedScalarWeakCurlCrossIntegrator: "
1565 "Trial space must be a vector field in 2D "
1566 "and the test space must be a vector field with a curl";
1567 }
1568
1569 void CalcShape(const FiniteElement & scalar_fe,
1570 ElementTransformation &Trans,
1571 Vector & shape) override
1572 {
1573 DenseMatrix dshape(shape.GetData(), shape.Size(), 1);
1574 scalar_fe.CalcPhysCurlShape(Trans, dshape);
1575 }
1576};
1577
1578/** Class for integrating the bilinear form $a(u,v) := (\vec{V} \times \nabla \cdot u, v)$ in 3D or
1579 in 2D and where $\vec{V}$ is a vector coefficient $u$ is in $H^1$ and $v$ is in $H(curl)$ or
1580 $H(div)$. */
1582{
1583public:
1586
1588 const FiniteElement & trial_fe,
1589 const FiniteElement & test_fe) const override
1590 {
1591 return (test_fe.GetRangeDim() == 3 &&
1595 }
1596
1597 const char * FiniteElementTypeFailureMessage() const override
1598 {
1599 return "MixedCrossGradIntegrator: "
1600 "Trial space must be a scalar field with a gradient operator"
1601 " and the test space must be a vector field both in 3D.";
1602 }
1603
1604 int GetTrialVDim(const FiniteElement & trial_fe) override
1605 { return space_dim; }
1606
1607 void CalcTrialShape(const FiniteElement & trial_fe,
1608 ElementTransformation &Trans,
1609 DenseMatrix & shape) override
1610 { trial_fe.CalcPhysDShape(Trans, shape); }
1611
1612 void CalcTestShape(const FiniteElement & test_fe,
1613 ElementTransformation &Trans,
1614 DenseMatrix & shape) override
1615 { test_fe.CalcVShape(Trans, shape); }
1616};
1617
1618/** Class for integrating the bilinear form $a(u,v) := (\vec{V} \times \mathrm{curl}(u), v)$ in 3D and
1619 where $\vec{V}$ is a vector coefficient $u$ is in $H(curl)$ and $v$ is in $H(curl)$ or
1620 $H(div)$. */
1622{
1623public:
1626
1628 const FiniteElement & trial_fe,
1629 const FiniteElement & test_fe) const override
1630 {
1631 return (trial_fe.GetCurlDim() == 3 && test_fe.GetRangeDim() == 3 &&
1635 }
1636
1637 const char * FiniteElementTypeFailureMessage() const override
1638 {
1639 return "MixedCrossCurlIntegrator: "
1640 "Trial space must be a vector field in 3D with a curl "
1641 "and the test space must be a vector field";
1642 }
1643
1644 int GetTrialVDim(const FiniteElement & trial_fe) override
1645 { return trial_fe.GetCurlDim(); }
1646
1647 void CalcTrialShape(const FiniteElement & trial_fe,
1648 ElementTransformation &Trans,
1649 DenseMatrix & shape) override
1650 { trial_fe.CalcPhysCurlShape(Trans, shape); }
1651};
1652
1653/** Class for integrating the bilinear form $a(u,v) := (\vec{V} \times \mathrm{curl}(u), v)$ in 2D and
1654 where $\vec{V}$ is a vector coefficient $u$ is in $H(curl)$ and $v$ is in $H(curl)$ or
1655 $H(div)$. */
1657{
1658public:
1661
1663 const FiniteElement & trial_fe,
1664 const FiniteElement & test_fe) const override
1665 {
1666 return (trial_fe.GetDim() == 2 && test_fe.GetDim() == 2 &&
1670 }
1671
1672 const char * FiniteElementTypeFailureMessage() const override
1673 {
1674 return "MixedCrossCurlIntegrator: "
1675 "Trial space must be a vector field in 2D with a curl "
1676 "and the test space must be a vector field";
1677 }
1678
1679 void CalcShape(const FiniteElement & scalar_fe,
1680 ElementTransformation &Trans,
1681 Vector & shape) override
1682 {
1683 DenseMatrix dshape(shape.GetData(), shape.Size(), 1);
1684 scalar_fe.CalcPhysCurlShape(Trans, dshape); shape *= -1.0;
1685 }
1686};
1687
1688/** Class for integrating the bilinear form $a(u,v) := (\vec{V} \times \nabla \cdot u, v)$ in 2D and
1689 where $\vec{V}$ is a vector coefficient $u$ is in $H^1$ and $v$ is in $H^1$ or $L_2$. */
1691{
1692public:
1695
1697 const FiniteElement & trial_fe,
1698 const FiniteElement & test_fe) const override
1699 {
1700 return (trial_fe.GetDim() == 2 && test_fe.GetDim() == 2 &&
1704 }
1705
1706 const char * FiniteElementTypeFailureMessage() const override
1707 {
1708 return "MixedScalarCrossGradIntegrator: "
1709 "Trial space must be a scalar field in 2D with a gradient "
1710 "and the test space must be a scalar field";
1711 }
1712
1713 int GetVDim(const FiniteElement & vector_fe) override
1714 { return space_dim; }
1715
1716 void CalcVShape(const FiniteElement & vector_fe,
1717 ElementTransformation &Trans,
1718 DenseMatrix & shape) override
1719 { vector_fe.CalcPhysDShape(Trans, shape); }
1720};
1721
1722/** Class for integrating the bilinear form $a(u,v) := (\vec{V} \times u, v)$ in 2D and where
1723 $\vec{V}$ is a vector coefficient $u$ is in $H(curl)$ or $H(div)$ and $v$ is in $H^1$ or $L_2$. */
1725{
1726public:
1729
1731 void AssemblePA(const FiniteElementSpace &trial_fes,
1732 const FiniteElementSpace &test_fes) override;
1733
1734 void AddMultPA(const Vector &x, Vector &y) const override;
1735 void AddMultTransposePA(const Vector &x, Vector &y) const override;
1736
1738 const FiniteElement & trial_fe,
1739 const FiniteElement & test_fe) const override
1740 {
1741 return (trial_fe.GetDim() == 2 && test_fe.GetDim() == 2 &&
1744 }
1745
1746 const char * FiniteElementTypeFailureMessage() const override
1747 {
1748 return "MixedScalarCrossProductIntegrator: "
1749 "Trial space must be a vector field in 2D "
1750 "and the test space must be a scalar field";
1751 }
1752
1753private:
1754 Vector pa_data;
1755 const DofToQuad *mapsO = nullptr; ///< Not owned. H(div) open map.
1756 const DofToQuad *mapsC = nullptr; ///< Not owned. H(div) closed map.
1757 const DofToQuad *mapsTest = nullptr; ///< Not owned. Scalar test map.
1758 const GeometricFactors *geom = nullptr;///< Not owned.
1759 int dim = 0, ne = 0, dofs1D = 0, dofs1Dtest = 0, quad1D = 0;
1760 bool test_map_integral = false;
1761};
1762
1763/** @brief Class for integrating the bilinear form
1764 $a(u,v) := (\vec{V} \times u \hat{z}, v)$ in 2D and where $\vec{V}$ is a
1765 vector coefficient $u$ is in $H^1$ or $L_2$, $v$ is in $H(curl)$ or
1766 $H(div)$, and $\hat{z}$ denotes the out-of-plane normal direction.
1767
1768 @note The vector coefficient should be a 2D coefficient with implicit 0
1769 third component. */
1771{
1772public:
1775
1777 void AssemblePA(const FiniteElementSpace &trial_fes,
1778 const FiniteElementSpace &test_fes) override;
1779
1780 void AddMultPA(const Vector &x, Vector &y) const override;
1781 void AddMultTransposePA(const Vector &x, Vector &y) const override;
1782
1784 const FiniteElement & trial_fe,
1785 const FiniteElement & test_fe) const override
1786 {
1787 return (trial_fe.GetDim() == 2 && test_fe.GetDim() == 2 &&
1790 }
1791
1792 const char * FiniteElementTypeFailureMessage() const override
1793 {
1794 return "MixedScalarWeakCrossProductIntegrator: "
1795 "Trial space must be a scalar field in 2D "
1796 "and the test space must be a vector field";
1797 }
1798
1799 void CalcShape(const FiniteElement & scalar_fe,
1800 ElementTransformation &Trans,
1801 Vector & shape) override
1802 { scalar_fe.CalcPhysShape(Trans, shape); shape *= -1.0; }
1803
1804private:
1805 Vector pa_data;
1806 const DofToQuad *mapsO = nullptr; ///< Not owned. H(curl) open map.
1807 const DofToQuad *mapsC = nullptr; ///< Not owned. H(curl) closed map.
1808 const DofToQuad *mapsTrial = nullptr; ///< Not owned. Scalar trial map.
1809 const GeometricFactors *geom = nullptr;///< Not owned.
1810 int dim = 0, ne = 0, dofs1D = 0, dofs1Dtrial = 0, quad1D = 0;
1811 bool trial_map_integral = false;
1812};
1813
1814/** Class for integrating the bilinear form $a(u,v) := (\vec{V} \cdot \nabla u, v)$ in 2D or
1815 3D and where $\vec{V}$ is a vector coefficient, $u$ is in $H^1$ and $v$ is in $H^1$ or $L_2$. */
1817{
1818public:
1821
1823 const FiniteElement & trial_fe,
1824 const FiniteElement & test_fe) const override
1825 {
1826 return (trial_fe.GetRangeType() == mfem::FiniteElement::SCALAR &&
1829 }
1830
1831 const char * FiniteElementTypeFailureMessage() const override
1832 {
1833 return "MixedDirectionalDerivativeIntegrator: "
1834 "Trial space must be a scalar field with a gradient "
1835 "and the test space must be a scalar field";
1836 }
1837
1838 int GetVDim(const FiniteElement & vector_fe) override
1839 { return space_dim; }
1840
1841 void CalcVShape(const FiniteElement & vector_fe,
1842 ElementTransformation &Trans,
1843 DenseMatrix & shape) override
1844 { vector_fe.CalcPhysDShape(Trans, shape); }
1845};
1846
1847/** Class for integrating the bilinear form $a(u,v) := (-\hat{V} \cdot \nabla u, \nabla \cdot v)$ in 2D
1848 or 3D and where $\hat{V}$ is a vector coefficient, $u$ is in $H^1$ and $v$ is in $H(div)$. */
1850{
1851public:
1854
1856 const FiniteElement & trial_fe,
1857 const FiniteElement & test_fe) const override
1858 {
1859 return (trial_fe.GetRangeType() == mfem::FiniteElement::SCALAR &&
1863 }
1864
1865 const char * FiniteElementTypeFailureMessage() const override
1866 {
1867 return "MixedGradDivIntegrator: "
1868 "Trial space must be a scalar field with a gradient"
1869 "and the test space must be a vector field with a divergence";
1870 }
1871
1872 int GetVDim(const FiniteElement & vector_fe) override
1873 { return space_dim; }
1874
1875 void CalcVShape(const FiniteElement & vector_fe,
1876 ElementTransformation &Trans,
1877 DenseMatrix & shape) override
1878 { vector_fe.CalcPhysDShape(Trans, shape); shape *= -1.0; }
1879
1880 void CalcShape(const FiniteElement & scalar_fe,
1881 ElementTransformation &Trans,
1882 Vector & shape) override
1883 { scalar_fe.CalcPhysDivShape(Trans, shape); }
1884};
1885
1886/** Class for integrating the bilinear form $a(u,v) := (-\hat{V} \nabla \cdot u, \nabla v)$ in 2D
1887 or 3D and where $\hat{V}$ is a vector coefficient, $u$ is in $H(div)$ and $v$ is in $H^1$. */
1889{
1890public:
1893
1895 const FiniteElement & trial_fe,
1896 const FiniteElement & test_fe) const override
1897 {
1898 return (trial_fe.GetRangeType() == mfem::FiniteElement::VECTOR &&
1899 trial_fe.GetDerivType() == mfem::FiniteElement::DIV &&
1902 );
1903 }
1904
1905 const char * FiniteElementTypeFailureMessage() const override
1906 {
1907 return "MixedDivGradIntegrator: "
1908 "Trial space must be a vector field with a divergence"
1909 "and the test space must be a scalar field with a gradient";
1910 }
1911
1912 int GetVDim(const FiniteElement & vector_fe) override
1913 { return space_dim; }
1914
1915 void CalcVShape(const FiniteElement & vector_fe,
1916 ElementTransformation &Trans,
1917 DenseMatrix & shape) override
1918 { vector_fe.CalcPhysDShape(Trans, shape); shape *= -1.0; }
1919
1920 void CalcShape(const FiniteElement & scalar_fe,
1921 ElementTransformation &Trans,
1922 Vector & shape) override
1923 { scalar_fe.CalcPhysDivShape(Trans, shape); }
1924};
1925
1926/** Class for integrating the bilinear form $a(u,v) := (-\hat{V} u, \nabla v)$ in 2D or 3D
1927 and where $\hat{V}$ is a vector coefficient, $u$ is in $H^1$ or $L_2$ and $v$ is in $H^1$. */
1929{
1930public:
1933
1935 const FiniteElement & trial_fe,
1936 const FiniteElement & test_fe) const override
1937 {
1938 return (trial_fe.GetRangeType() == mfem::FiniteElement::SCALAR &&
1941 }
1942
1943 const char * FiniteElementTypeFailureMessage() const override
1944 {
1945 return "MixedScalarWeakDivergenceIntegrator: "
1946 "Trial space must be a scalar field "
1947 "and the test space must be a scalar field with a gradient";
1948 }
1949
1950 int GetVDim(const FiniteElement & vector_fe) override
1951 { return space_dim; }
1952
1953 void CalcVShape(const FiniteElement & vector_fe,
1954 ElementTransformation &Trans,
1955 DenseMatrix & shape) override
1956 { vector_fe.CalcPhysDShape(Trans, shape); shape *= -1.0; }
1957};
1958
1959/** Class for integrating the bilinear form $a(u,v) := (Q \nabla u, v)$ in either 2D
1960 or 3D and where $Q$ is an optional coefficient (of type scalar, matrix, or
1961 diagonal matrix) $u$ is in $H^1$ and $v$ is in $H(curl)$ or $H(div)$. Partial assembly
1962 (PA) is supported but could be further optimized by using more efficient
1963 threading and shared memory.
1964*/
1966{
1967public:
1975
1976protected:
1978 const FiniteElement & trial_fe,
1979 const FiniteElement & test_fe) const override
1980 {
1981 return (trial_fe.GetDerivType() == mfem::FiniteElement::GRAD &&
1983 }
1984
1985 const char * FiniteElementTypeFailureMessage() const override
1986 {
1987 return "MixedVectorGradientIntegrator: "
1988 "Trial spaces must be $H^1$ and the test space must be a "
1989 "vector field in 2D or 3D";
1990 }
1991
1992 int GetTrialVDim(const FiniteElement & trial_fe) override
1993 { return space_dim; }
1994
1995 void CalcTrialShape(const FiniteElement & trial_fe,
1996 ElementTransformation &Trans,
1997 DenseMatrix & shape) override
1998 {
1999 trial_fe.CalcPhysDShape(Trans, shape);
2000 }
2001
2003 void AssemblePA(const FiniteElementSpace &trial_fes,
2004 const FiniteElementSpace &test_fes) override;
2005
2006 void AddMultPA(const Vector&, Vector&) const override;
2007 void AddMultTransposePA(const Vector&, Vector&) const override;
2008
2009private:
2010 DenseMatrix Jinv;
2011
2012 // PA extension
2013 Vector pa_data;
2014 const DofToQuad *mapsO; ///< Not owned. DOF-to-quad map, open.
2015 const DofToQuad *mapsC; ///< Not owned. DOF-to-quad map, closed.
2016 const GeometricFactors *geom; ///< Not owned
2017 int dim, ne, dofs1D, quad1D;
2018 int op_entries;
2019 FiniteElement::DerivType test_fetype =
2020 mfem::FiniteElement::NONE; ///< Derivative type of the vector test space.
2021};
2022
2023/** Class for integrating the bilinear form $a(u,v) := (Q \mathrm{curl}(u), v)$ in 3D and
2024 where $Q$ is an optional coefficient (of type scalar, matrix, or diagonal
2025 matrix) $u$ is in $H(curl)$ and $v$ is in $H(div)$ or $H(curl)$. */
2027{
2028public:
2036
2037protected:
2039 const FiniteElement & trial_fe,
2040 const FiniteElement & test_fe) const override
2041 {
2042 return (trial_fe.GetCurlDim() == 3 && test_fe.GetRangeDim() == 3 &&
2045 }
2046
2047 const char * FiniteElementTypeFailureMessage() const override
2048 {
2049 return "MixedVectorCurlIntegrator: "
2050 "Trial space must be H(Curl) and the test space must be a "
2051 "vector field in 3D";
2052 }
2053
2054 int GetTrialVDim(const FiniteElement & trial_fe) override
2055 { return trial_fe.GetCurlDim(); }
2056
2057 void CalcTrialShape(const FiniteElement & trial_fe,
2058 ElementTransformation &Trans,
2059 DenseMatrix & shape) override
2060 {
2061 trial_fe.CalcPhysCurlShape(Trans, shape);
2062 }
2063
2065 void AssemblePA(const FiniteElementSpace &trial_fes,
2066 const FiniteElementSpace &test_fes) override;
2067
2068 void AddMultPA(const Vector&, Vector&) const override;
2069 void AddMultTransposePA(const Vector&, Vector&) const override;
2070
2071private:
2072 // PA extension
2073 Vector pa_data;
2074 const DofToQuad *mapsO; ///< Not owned. DOF-to-quad map, open.
2075 const DofToQuad *mapsC; ///< Not owned. DOF-to-quad map, closed.
2076 const DofToQuad *mapsOtest; ///< Not owned. DOF-to-quad map, open.
2077 const DofToQuad *mapsCtest; ///< Not owned. DOF-to-quad map, closed.
2078 const GeometricFactors *geom; ///< Not owned
2079 int dim, ne, dofs1D, dofs1Dtest,quad1D, testType, trialType, coeffDim;
2080};
2081
2082/** Class for integrating the bilinear form $a(u,v) := (Q u, \mathrm{curl}(v))$ in 3D and
2083 where $Q$ is an optional coefficient (of type scalar, matrix, or diagonal
2084 matrix) $u$ is in $H(div)$ or $H(curl)$ and $v$ is in $H(curl)$. */
2086{
2087public:
2095
2096protected:
2098 const FiniteElement & trial_fe,
2099 const FiniteElement & test_fe) const override
2100 {
2101 return (trial_fe.GetRangeDim() == 3 && test_fe.GetCurlDim() == 3 &&
2104 }
2105
2106 const char * FiniteElementTypeFailureMessage() const override
2107 {
2108 return "MixedVectorWeakCurlIntegrator: "
2109 "Trial space must be vector field in 3D and the "
2110 "test space must be H(Curl)";
2111 }
2112
2113 int GetTestVDim(const FiniteElement & test_fe) override
2114 { return test_fe.GetCurlDim(); }
2115
2116 void CalcTestShape (const FiniteElement & test_fe,
2117 ElementTransformation &Trans,
2118 DenseMatrix & shape) override
2119 {
2120 test_fe.CalcPhysCurlShape(Trans, shape);
2121 }
2122
2124 void AssemblePA(const FiniteElementSpace &trial_fes,
2125 const FiniteElementSpace &test_fes) override;
2126
2127 void AddMultPA(const Vector&, Vector&) const override;
2128 void AddMultTransposePA(const Vector&, Vector&) const override;
2129
2130private:
2131 // PA extension
2132 Vector pa_data;
2133 const DofToQuad *mapsO; ///< Not owned. DOF-to-quad map, open.
2134 const DofToQuad *mapsC; ///< Not owned. DOF-to-quad map, closed.
2135 const GeometricFactors *geom; ///< Not owned
2136 int dim, ne, dofs1D, quad1D, testType, trialType, coeffDim;
2137};
2138
2139/** Class for integrating the bilinear form $a(u,v) := - (Q u, \nabla v)$ in either
2140 2D or 3D and where $Q$ is an optional coefficient (of type scalar, matrix, or
2141 diagonal matrix) $u$ is in $H(div)$ or $H(curl)$ and $v$ is in $H^1$. */
2143{
2144public:
2152
2153protected:
2155 const FiniteElement & trial_fe,
2156 const FiniteElement & test_fe) const override
2157 {
2158 return (trial_fe.GetRangeType() == mfem::FiniteElement::VECTOR &&
2160 }
2161
2162 const char * FiniteElementTypeFailureMessage() const override
2163 {
2164 return "MixedVectorWeakDivergenceIntegrator: "
2165 "Trial space must be vector field and the "
2166 "test space must be H1";
2167 }
2168
2169 int GetTestVDim(const FiniteElement & test_fe) override
2170 { return space_dim; }
2171
2172 void CalcTestShape(const FiniteElement & test_fe,
2173 ElementTransformation &Trans,
2174 DenseMatrix & shape) override
2175 {
2176 test_fe.CalcPhysDShape(Trans, shape);
2177 shape *= -1.0;
2178 }
2179};
2180
2181/** Class for integrating the bilinear form $a(u,v) := (Q \nabla u, v)$ where $Q$ is a
2182 scalar coefficient, $u$ is in ($H^1$), and $v$ is a vector with components
2183 $v_i$ in ($H^1$) or ($L^2$).
2184
2185 See also MixedVectorGradientIntegrator when $v$ is in $H(curl)$. */
2187{
2188protected:
2190
2191private:
2192 Vector shape;
2193 DenseMatrix dshape;
2194 DenseMatrix gshape;
2195 DenseMatrix Jadj;
2196 DenseMatrix elmat_comp;
2197 // PA extension
2198 Vector pa_data;
2199 const DofToQuad *trial_maps, *test_maps; ///< Not owned
2200 const GeometricFactors *geom; ///< Not owned
2201 int dim, ne, nq;
2202 int trial_dofs1D, test_dofs1D, quad1D;
2203
2204public:
2206 Q{NULL}, trial_maps{NULL}, test_maps{NULL}, geom{NULL}
2207 { }
2209 Q{q_}, trial_maps{NULL}, test_maps{NULL}, geom{NULL}
2210 { }
2212 Q{&q}, trial_maps{NULL}, test_maps{NULL}, geom{NULL}
2213 { }
2214
2215 void AssembleElementMatrix2(const FiniteElement &trial_fe,
2216 const FiniteElement &test_fe,
2217 ElementTransformation &Trans,
2218 DenseMatrix &elmat) override;
2219
2221 void AssemblePA(const FiniteElementSpace &trial_fes,
2222 const FiniteElementSpace &test_fes) override;
2223
2224 void AddMultPA(const Vector &x, Vector &y) const override;
2225 void AddMultTransposePA(const Vector &x, Vector &y) const override;
2226
2227 static const IntegrationRule &GetRule(const FiniteElement &trial_fe,
2228 const FiniteElement &test_fe,
2229 const ElementTransformation &Trans);
2230protected:
2232 const FiniteElement& trial_fe,
2233 const FiniteElement& test_fe,
2234 const ElementTransformation& trans) const override
2235 {
2236 return &GetRule(trial_fe, test_fe, trans);
2237 }
2238};
2239
2240/** Class for integrating the bilinear form $a(u,v) := (Q \nabla u, \nabla v)$ where $Q$
2241 can be a scalar or a matrix coefficient. */
2243{
2244public:
2245
2246 using ApplyKernelType = void(*)(const int, const bool, const Array<real_t>&,
2247 const Array<real_t>&, const Array<real_t>&,
2248 const Array<real_t>&,
2249 const Vector&, const Vector&,
2250 Vector&, const int, const int);
2251
2252 using ApplySimplexKernelType = void(*)(const int, const bool, const Array<int>&,
2253 const Array<int>&,
2254 const Array<int>&, const Array<int>&, const Array<int>&,
2255 const Array<real_t>&, const Array<real_t>&,
2256 const Array<real_t>&, const Array<real_t>&,
2257 const Array<real_t>&, const Array<real_t>&,
2258 const Vector&, const Vector&,
2259 Vector&, const int, const int);
2260
2261 using DiagonalKernelType = void(*)(const int, const bool, const Array<real_t>&,
2262 const Array<real_t>&, const Vector&, Vector&,
2263 const int, const int);
2264
2265 MFEM_REGISTER_KERNELS(ApplyPAKernels, ApplyKernelType, (int, int, int));
2266 MFEM_REGISTER_KERNELS(ApplySimplexPAKernels, ApplySimplexKernelType, (int, int,
2267 int));
2268 MFEM_REGISTER_KERNELS(DiagonalPAKernels, DiagonalKernelType, (int, int, int));
2269 struct Kernels { Kernels(); };
2270
2271protected:
2275
2276private:
2277 Vector vec, vecdxt, pointflux, shape;
2278#ifndef MFEM_THREAD_SAFE
2279 DenseMatrix dshape, dshapedxt, invdfdx, M, dshapedxt_m;
2280 DenseMatrix te_dshape, te_dshapedxt;
2281 Vector D;
2282#endif
2283
2284 // PA extension
2285 const FiniteElementSpace *fespace;
2286 const DofToQuad *maps; ///< Not owned
2287 const GeometricFactors *geom; ///< Not owned
2288 int dim, ne, dofs1D, quad1D;
2289 Vector pa_data;
2290 bool symmetric = true; ///< False if using a nonsymmetric matrix coefficient
2291
2292 // Data for NURBS patch PA
2293
2294 // Type for a variable-row-length 2D array, used for data related to 1D
2295 // quadrature rules in each dimension.
2296 typedef std::vector<std::vector<int>> IntArrayVar2D;
2297
2298 int numPatches = 0;
2299 static constexpr int numTypes = 2; // Number of rule types
2300
2301 // In the case integrationMode == Mode::PATCHWISE_REDUCED, an approximate
2302 // integration rule with sparse nonzero weights is computed by NNLSSolver,
2303 // for each 1D basis function on each patch, in each spatial dimension. For a
2304 // fixed 1D basis function b_i with DOF index i, in the tensor product basis
2305 // of patch p, the prescribed exact 1D rule is of the form
2306 // \sum_k a_{i,j,k} w_k for some integration points indexed by k, with
2307 // weights w_k and coefficients a_{i,j,k} depending on Q(x), an element
2308 // transformation, b_i, and b_j, for all 1D basis functions b_j whose support
2309 // overlaps that of b_i. Define the constraint matrix G = [g_{j,k}] with
2310 // g_{j,k} = a_{i,j,k} and the vector of exact weights w = [w_k]. A reduced
2311 // rule should have different weights w_r, many of them zero, and should
2312 // approximately satisfy Gw_r = Gw. A sparse approximate solution to this
2313 // underdetermined system is computed by NNLSSolver, and its data is stored
2314 // in the following members.
2315
2316 // For each patch p, spatial dimension d (total dim), and rule type t (total
2317 // numTypes), an std::vector<Vector> of reduced quadrature weights for all
2318 // basis functions is stored in reducedWeights[t + numTypes * (d + dim * p)],
2319 // reshaped as rw(t,d,p). Note that nd may vary with respect to the patch and
2320 // spatial dimension. Array reducedIDs is treated similarly.
2321 std::vector<std::vector<Vector>> reducedWeights;
2322 std::vector<IntArrayVar2D> reducedIDs;
2323 std::vector<Array<int>> pQ1D, pD1D;
2324 std::vector<std::vector<Array2D<real_t>>> pB, pG;
2325 std::vector<IntArrayVar2D> pminD, pmaxD, pminQ, pmaxQ, pminDD, pmaxDD;
2326
2327 std::vector<Array<const IntegrationRule*>> pir1d;
2328
2329 void SetupPatchPA(const int patch, Mesh *mesh, bool unitWeights=false);
2330
2331 void SetupPatchBasisData(Mesh *mesh, unsigned int patch);
2332
2333 /** Called by AssemblePatchMatrix for sparse matrix assembly on a NURBS patch
2334 with full 1D quadrature rules. */
2335 void AssemblePatchMatrix_fullQuadrature(const int patch,
2336 const FiniteElementSpace &fes,
2337 SparseMatrix*& smat);
2338
2339 /** Called by AssemblePatchMatrix for sparse matrix assembly on a NURBS patch
2340 with reduced 1D quadrature rules. */
2341 void AssemblePatchMatrix_reducedQuadrature(const int patch,
2342 const FiniteElementSpace &fes,
2343 SparseMatrix*& smat);
2344
2345public:
2346 /// Construct a diffusion integrator with coefficient Q = 1
2347 DiffusionIntegrator(const IntegrationRule *ir = nullptr);
2348
2349 /// Construct a diffusion integrator with a scalar coefficient q
2350 DiffusionIntegrator(Coefficient &q, const IntegrationRule *ir = nullptr);
2351
2352 /// Construct a diffusion integrator with a vector coefficient q
2353 DiffusionIntegrator(VectorCoefficient &q, const IntegrationRule *ir = nullptr);
2354
2355 /// Construct a diffusion integrator with a matrix coefficient q
2356 DiffusionIntegrator(MatrixCoefficient &q, const IntegrationRule *ir = nullptr);
2357
2358 /** Given a particular Finite Element computes the element stiffness matrix
2359 elmat. */
2360 void AssembleElementMatrix(const FiniteElement &el,
2361 ElementTransformation &Trans,
2362 DenseMatrix &elmat) override;
2363 /** Given a trial and test Finite Element computes the element stiffness
2364 matrix elmat. */
2365 void AssembleElementMatrix2(const FiniteElement &trial_fe,
2366 const FiniteElement &test_fe,
2367 ElementTransformation &Trans,
2368 DenseMatrix &elmat) override;
2369
2370 void AssemblePatchMatrix(const int patch,
2371 const FiniteElementSpace &fes,
2372 SparseMatrix*& smat) override;
2373
2374 void AssembleNURBSPA(const FiniteElementSpace &fes) override;
2375
2376 void AssemblePatchPA(const int patch, const FiniteElementSpace &fes);
2377
2378 /// Perform the local action of the BilinearFormIntegrator
2379 void AssembleElementVector(const FiniteElement &el,
2381 const Vector &elfun, Vector &elvect) override;
2382
2383 void ComputeElementFlux(const FiniteElement &el,
2384 ElementTransformation &Trans,
2385 Vector &u, const FiniteElement &fluxelem,
2386 Vector &flux, bool with_coef = true,
2387 const IntegrationRule *ir = NULL) override;
2388
2389 real_t ComputeFluxEnergy(const FiniteElement &fluxelem,
2390 ElementTransformation &Trans,
2391 Vector &flux, Vector *d_energy = NULL) override;
2392
2393 void AssembleMF(const FiniteElementSpace &fes) override;
2394
2396 void AssemblePA(const FiniteElementSpace &fes) override;
2397
2398 void AssembleEA(const FiniteElementSpace &fes, Vector &emat,
2399 const bool add) override;
2400
2401 void AssembleDiagonalPA(Vector &diag) override;
2402
2403 void AssembleDiagonalMF(Vector &diag) override;
2404
2405 void AddMultMF(const Vector&, Vector&) const override;
2406
2407 void AddMultPA(const Vector&, Vector&) const override;
2408
2409 void AddAbsMultPA(const Vector&, Vector&) const override;
2410
2411 void AddMultTransposePA(const Vector&, Vector&) const override;
2412
2413 void AddAbsMultTransposePA(const Vector&, Vector&) const override;
2414
2415 void AddMultNURBSPA(const Vector&, Vector&) const override;
2416
2417 void AddMultPatchPA(const int patch, const Vector &x, Vector &y) const;
2418
2419 static const IntegrationRule &GetRule(const FiniteElement &trial_fe,
2420 const FiniteElement &test_fe,
2421 const bool stroud = false);
2422
2423 bool SupportsCeed() const override { return DeviceCanUseCeed(); }
2424
2425 Coefficient *GetCoefficient() const { return Q; }
2426
2427 template <int DIM, int D1D, int Q1D>
2428 static void AddSpecialization()
2429 {
2430 ApplyPAKernels::Specialization<DIM,D1D,Q1D>::Add();
2431 DiagonalPAKernels::Specialization<DIM,D1D,Q1D>::Add();
2433 }
2434
2435 template <int DIM, int D1D, int Q1D>
2437 {
2438 ApplySimplexPAKernels::Specialization<DIM,D1D,Q1D>::Add();
2439 }
2440protected:
2442 const FiniteElement& trial_fe,
2443 const FiniteElement& test_fe,
2444 const ElementTransformation& trans) const override
2445 {
2446 return &GetRule(trial_fe, test_fe);
2447 }
2448};
2449
2450/** Class for local mass matrix assembling $a(u,v) := (Q u, v)$ */
2452{
2453 friend class DGMassInverse;
2454protected:
2455#ifndef MFEM_THREAD_SAFE
2457#endif
2459 // PA extension
2462 const DofToQuad *maps; ///< Not owned
2463 const GeometricFactors *geom; ///< Not owned
2464 const FaceGeometricFactors *face_geom; ///< Not owned
2466
2467 void AssembleEA_(Vector &ea, const bool add);
2468
2469public:
2470
2471 using ApplyKernelType = void(*)(const int, const Array<real_t>&,
2472 const Array<real_t>&, const Vector&,
2473 const Vector&, Vector&, const int, const int);
2474
2475 using ApplySimplexKernelType = void(*)(const int, const Array<int>&,
2476 const Array<int>&,
2477 const Array<int>&, const Array<int>&, const Array<int>&,
2478 const Array<real_t>&, const Array<real_t>&,
2479 const Array<real_t>&, const Array<real_t>&,
2480 const Array<real_t>&, const Array<real_t>&,
2481 const Vector&, const Vector&, Vector&,
2482 const int, const int);
2483
2484 using DiagonalKernelType = void(*)(const int, const Array<real_t>&,
2485 const Vector&, Vector&, const int,
2486 const int);
2487
2488 MFEM_REGISTER_KERNELS(ApplyPAKernels, ApplyKernelType, (int, int, int));
2489 MFEM_REGISTER_KERNELS(ApplySimplexPAKernels, ApplySimplexKernelType, (int, int,
2490 int));
2491 MFEM_REGISTER_KERNELS(DiagonalPAKernels, DiagonalKernelType, (int, int, int));
2492 struct Kernels { Kernels(); };
2493
2494public:
2495 MassIntegrator(const IntegrationRule *ir = nullptr);
2496
2497 /// Construct a mass integrator with coefficient q
2498 MassIntegrator(Coefficient &q, const IntegrationRule *ir = NULL);
2499
2500 /** Given a particular Finite Element computes the element mass matrix
2501 elmat. */
2502 void AssembleElementMatrix(const FiniteElement &el,
2503 ElementTransformation &Trans,
2504 DenseMatrix &elmat) override;
2505 void AssembleElementMatrix2(const FiniteElement &trial_fe,
2506 const FiniteElement &test_fe,
2507 ElementTransformation &Trans,
2508 DenseMatrix &elmat) override;
2509
2510 void AssembleMF(const FiniteElementSpace &fes) override;
2511
2513 void AssemblePA(const FiniteElementSpace &fes) override;
2514
2515 void AssemblePABoundary(const FiniteElementSpace &fes) override;
2516
2517 void AssembleEA(const FiniteElementSpace &fes, Vector &emat,
2518 const bool add) override;
2519
2520 void AssembleEABoundary(const FiniteElementSpace &fes, Vector &emat,
2521 const bool add) override;
2522
2523 void AssembleDiagonalPA(Vector &diag) override;
2524
2525 void AssembleDiagonalMF(Vector &diag) override;
2526
2527 void AddMultMF(const Vector&, Vector&) const override;
2528
2529 void AddMultPA(const Vector&, Vector&) const override;
2530
2531 void AddAbsMultPA(const Vector&, Vector&) const override;
2532
2533 void AddMultTransposePA(const Vector&, Vector&) const override;
2534
2535 void AddAbsMultTransposePA(const Vector&, Vector&) const override;
2536
2537 static const IntegrationRule &GetRule(const FiniteElement &trial_fe,
2538 const FiniteElement &test_fe,
2539 const ElementTransformation &Trans,
2540 const bool stroud = false);
2541
2542 bool SupportsCeed() const override { return DeviceCanUseCeed(); }
2543
2544 const Coefficient *GetCoefficient() const { return Q; }
2545
2546 template <int DIM, int D1D, int Q1D>
2547 static void AddSpecialization()
2548 {
2549 ApplyPAKernels::Specialization<DIM,D1D,Q1D>::Add();
2550 DiagonalPAKernels::Specialization<DIM,D1D,Q1D>::Add();
2552 }
2553
2554 template <int DIM, int D1D, int Q1D>
2556 {
2557 ApplySimplexPAKernels::Specialization<DIM,D1D,Q1D>::Add();
2558 }
2559
2560protected:
2562 const FiniteElement& trial_fe,
2563 const FiniteElement& test_fe,
2564 const ElementTransformation& trans) const override
2565 {
2566 return &GetRule(trial_fe, test_fe, trans);
2567 }
2568};
2569
2570/** Mass integrator $(u, v)$ restricted to the boundary of a domain */
2572{
2573public:
2575
2577 void AssembleFaceMatrix(const FiniteElement &el1,
2578 const FiniteElement &el2,
2580 DenseMatrix &elmat) override;
2581};
2582
2583/// $\alpha (Q \cdot \nabla u, v)$
2585{
2586protected:
2589 // PA extension
2591 const DofToQuad *maps; ///< Not owned
2592 const GeometricFactors *geom; ///< Not owned
2594
2595private:
2596#ifndef MFEM_THREAD_SAFE
2597 DenseMatrix dshape, adjJ, Q_ir;
2598 Vector shape, vec2, BdFidxT;
2599#endif
2600
2601public:
2603
2606 DenseMatrix &) override;
2607
2608 void AssembleMF(const FiniteElementSpace &fes) override;
2609
2611 void AssemblePA(const FiniteElementSpace&) override;
2612
2613 void AssembleEA(const FiniteElementSpace &fes, Vector &emat,
2614 const bool add) override;
2615
2616 void AssembleDiagonalPA(Vector &diag) override;
2617
2618 void AssembleDiagonalMF(Vector &diag) override;
2619
2620 void AddMultMF(const Vector&, Vector&) const override;
2621
2622 void AddMultPA(const Vector&, Vector&) const override;
2623
2624 void AddMultTransposePA(const Vector &x, Vector &y) const override;
2625
2626 static const IntegrationRule &GetRule(const FiniteElement &el,
2627 const ElementTransformation &Trans);
2628
2629 static const IntegrationRule &GetRule(const FiniteElement &trial_fe,
2630 const FiniteElement &test_fe,
2631 const ElementTransformation &Trans);
2632
2633 bool SupportsCeed() const override { return DeviceCanUseCeed(); }
2634
2635 /// arguments: NE, B, G, Bt, Gt, pa_data, x, y, D1D, Q1D
2636 using ApplyKernelType = void (*)(const int, const Array<real_t> &,
2637 const Array<real_t> &,
2638 const Array<real_t> &,
2639 const Array<real_t> &, const Vector &,
2640 const Vector &, Vector &, const int,
2641 const int);
2642
2643 /// arguments: DIMS, D1D, Q1D
2644 MFEM_REGISTER_KERNELS(ApplyPAKernels, ApplyKernelType, (int, int, int));
2645 /// arguments: DIMS, D1D, Q1D
2646 MFEM_REGISTER_KERNELS(ApplyPATKernels, ApplyKernelType, (int, int, int));
2647
2648 template <int DIM, int D1D, int Q1D>
2649 static void AddSpecialization()
2650 {
2651 ApplyPAKernels::Specialization<DIM, D1D, Q1D>::Add();
2652 ApplyPATKernels::Specialization<DIM, D1D, Q1D>::Add();
2653 }
2654
2655 struct Kernels { Kernels(); };
2656
2657protected:
2659 const FiniteElement& trial_fe,
2660 const FiniteElement& test_fe,
2661 const ElementTransformation& trans) const override
2662 {
2663 return &GetRule(trial_fe, test_fe, trans);
2664 }
2665};
2666
2667// Alias for @ConvectionIntegrator.
2669
2670/// $-\alpha (u, q \cdot \nabla v)$, negative transpose of ConvectionIntegrator
2677
2678/// $\alpha (Q \cdot \nabla u, v)$ using the "group" FE discretization
2680{
2681protected:
2684
2685private:
2686 DenseMatrix dshape, adjJ, Q_nodal, grad;
2687 Vector shape;
2688
2689public:
2694 DenseMatrix &) override;
2695};
2696
2697/** Class for integrating the bilinear form $a(u,v) := (Q u, v)$,
2698 where $u=(u_1,\dots,u_n)$ and $v=(v_1,\dots,v_n)$, $u_i$ and $v_i$ are defined
2699 by scalar FE through standard transformation. */
2701{
2702 int vdim = -1, Q_order = 0;
2703 Vector shape, te_shape, vec;
2704 DenseMatrix partelmat;
2705 DenseMatrix mcoeff;
2706
2707protected:
2708 Coefficient *Q = nullptr;
2711 // PA extension
2712 const DofToQuad *maps; ///< Not owned
2713 const GeometricFactors *geom; ///< Not owned
2716
2717public:
2718 /// Construct an integrator with coefficient 1.0
2720
2721 /** Construct an integrator with scalar coefficient q. If possible, save
2722 memory by using a scalar integrator since the resulting matrix is block
2723 diagonal with the same diagonal block repeated. */
2724 VectorMassIntegrator(Coefficient &q, int qo = 0): Q_order(qo), Q(&q) { }
2725
2728
2729 /// Construct an integrator with diagonal coefficient q
2731 vdim(q.GetVDim()), Q_order(qo), VQ(&q) { }
2732
2733 /// Construct an integrator with matrix coefficient q
2735 vdim(q.GetVDim()), Q_order(qo), MQ(&q) { }
2736
2737 int GetVDim() const { return vdim; }
2738 void SetVDim(int vdim_) { vdim = vdim_; }
2739
2740 void AssembleElementMatrix(const FiniteElement &el,
2741 ElementTransformation &Trans,
2742 DenseMatrix &elmat) override;
2743 void AssembleElementMatrix2(const FiniteElement &trial_fe,
2744 const FiniteElement &test_fe,
2745 ElementTransformation &Trans,
2746 DenseMatrix &elmat) override;
2747
2749 void AssemblePA(const FiniteElementSpace &fes) override;
2750 void AssembleMF(const FiniteElementSpace &fes) override;
2751 void AssembleDiagonalPA(Vector &diag) override;
2752 void AssembleDiagonalMF(Vector &diag) override;
2753 void AddMultPA(const Vector &x, Vector &y) const override;
2754 void AddMultMF(const Vector &x, Vector &y) const override;
2755 bool SupportsCeed() const override { return DeviceCanUseCeed(); }
2756
2757 // PA AddMultPA kernels
2759 void(*)(const int, const int,
2760 const Array<real_t>&, const Vector&,
2761 const Vector&, Vector&, const int, const int);
2762 MFEM_REGISTER_KERNELS(VectorMassAddMultPA,
2764 (int, int, int));
2765
2766 // PA DiagonalPA kernels
2768 void(*)(const int, const int, const int,
2769 const real_t*, const real_t*, real_t*);
2770 MFEM_REGISTER_KERNELS(VectorMassAssembleDiagonalPA,
2772 (int /*dim*/, int /*q1d*/));
2773};
2774
2775
2776/** Class for integrating $(\nabla \cdot u, p)$ where $u$ is a vector field given by
2777 VectorFiniteElement through Piola transformation (for Raviart-Thomas elements); $p$ is
2778 scalar function given by FiniteElement through standard transformation.
2779 Here, $u$ is the trial function and $p$ is the test function.
2780
2781 Note: if the test space does not have map type INTEGRAL, then the element
2782 matrix returned by AssembleElementMatrix2 will not depend on the
2783 ElementTransformation Trans. */
2785{
2786protected:
2788
2790 void AssemblePA(const FiniteElementSpace &trial_fes,
2791 const FiniteElementSpace &test_fes) override;
2792
2793 void AddMultPA(const Vector&, Vector&) const override;
2794 void AddMultTransposePA(const Vector&, Vector&) const override;
2795
2796private:
2797#ifndef MFEM_THREAD_SAFE
2798 Vector divshape, shape;
2799#endif
2800
2801 // PA extension
2802 Vector pa_data;
2803 const DofToQuad *mapsO; ///< Not owned. DOF-to-quad map, open.
2804 const DofToQuad *L2mapsO; ///< Not owned. DOF-to-quad map, open.
2805 const DofToQuad *mapsC; ///< Not owned. DOF-to-quad map, closed.
2806 int dim, ne, dofs1D, L2dofs1D, quad1D;
2807
2808public:
2812 ElementTransformation &Trans,
2813 DenseMatrix &elmat) override { }
2814 void AssembleElementMatrix2(const FiniteElement &trial_fe,
2815 const FiniteElement &test_fe,
2816 ElementTransformation &Trans,
2817 DenseMatrix &elmat) override;
2818
2819 void AssembleDiagonalPA_ADAt(const Vector &D, Vector &diag) override;
2820};
2821
2822
2823/** Integrator for $(-Q u, \nabla v)$ for Nedelec ($u$) and $H^1$ ($v$) elements.
2824 This is equivalent to a weak divergence of the $H(curl)$ basis functions. */
2826{
2827protected:
2829
2830private:
2831#ifndef MFEM_THREAD_SAFE
2832 DenseMatrix dshape;
2833 DenseMatrix dshapedxt;
2834 DenseMatrix vshape;
2835 DenseMatrix invdfdx;
2836#endif
2837
2838public:
2842 ElementTransformation &Trans,
2843 DenseMatrix &elmat) override { }
2844 void AssembleElementMatrix2(const FiniteElement &trial_fe,
2845 const FiniteElement &test_fe,
2846 ElementTransformation &Trans,
2847 DenseMatrix &elmat) override;
2848};
2849
2850/** Integrator for $(\mathrm{curl}(u), v)$ for Nedelec and Raviart-Thomas elements. If the trial and
2851 test spaces are switched, assembles the form $(u, \mathrm{curl}(v))$. */
2853{
2854protected:
2856
2857private:
2858#ifndef MFEM_THREAD_SAFE
2859 DenseMatrix curlshapeTrial;
2860 DenseMatrix vshapeTest;
2861 DenseMatrix curlshapeTrial_dFT;
2862#endif
2863
2864public:
2868 ElementTransformation &Trans,
2869 DenseMatrix &elmat) override { }
2870 void AssembleElementMatrix2(const FiniteElement &trial_fe,
2871 const FiniteElement &test_fe,
2872 ElementTransformation &Trans,
2873 DenseMatrix &elmat) override;
2874};
2875
2876/// Integrator for (Q u.n, v.n) for RT elements
2878{
2879 Coefficient *Q;
2880#ifndef MFEM_THREAD_SAFE
2881 Vector shape, te_shape;
2882#endif
2883public:
2886 void AssembleElementMatrix(const FiniteElement &el,
2887 ElementTransformation &Trans,
2888 DenseMatrix &elmat) override;
2889 void AssembleElementMatrix2(const FiniteElement &trial_fe,
2890 const FiniteElement &test_fe,
2891 ElementTransformation &Trans,
2892 DenseMatrix &elmat) override;
2893};
2894
2895/// Class for integrating $ (Q \partial_i(u), v) $ where $u$ and $v$ are scalars
2897{
2898protected:
2900
2901private:
2902 int xi;
2903 DenseMatrix dshape, dshapedxt, invdfdx;
2904 Vector shape, dshapedxi;
2905
2906public:
2907 DerivativeIntegrator(Coefficient &q, int i) : Q(&q), xi(i) { }
2909 ElementTransformation &Trans,
2910 DenseMatrix &elmat) override
2911 { AssembleElementMatrix2(el,el,Trans,elmat); }
2912 void AssembleElementMatrix2(const FiniteElement &trial_fe,
2913 const FiniteElement &test_fe,
2914 ElementTransformation &Trans,
2915 DenseMatrix &elmat) override;
2916};
2917
2918/// Integrator for $(\mathrm{curl}(u), \mathrm{curl}(v))$ for Nedelec elements
2920{
2921private:
2922 Vector vec, pointflux;
2923#ifndef MFEM_THREAD_SAFE
2924 Vector D;
2925 DenseMatrix curlshape, curlshape_dFt, M;
2926 DenseMatrix te_curlshape, te_curlshape_dFt;
2927 DenseMatrix vshape, projcurl;
2928#endif
2929
2930protected:
2934
2935 // PA extension
2937 const DofToQuad *mapsO; ///< Not owned. DOF-to-quad map, open.
2938 const DofToQuad *mapsC; ///< Not owned. DOF-to-quad map, closed.
2939 const GeometricFactors *geom; ///< Not owned
2941 bool symmetric = true; ///< False if using a nonsymmetric matrix coefficient
2942
2943public:
2945 /// Construct a bilinear form integrator for Nedelec elements
2946 CurlCurlIntegrator(Coefficient &q, const IntegrationRule *ir = nullptr);
2948 const IntegrationRule *ir = nullptr);
2950 const IntegrationRule *ir = nullptr);
2951
2952 /* Given a particular Finite Element, compute the
2953 element curl-curl matrix elmat */
2954 void AssembleElementMatrix(const FiniteElement &el,
2955 ElementTransformation &Trans,
2956 DenseMatrix &elmat) override;
2957
2958 void AssembleElementMatrix2(const FiniteElement &trial_fe,
2959 const FiniteElement &test_fe,
2960 ElementTransformation &Trans,
2961 DenseMatrix &elmat) override;
2962
2963 void ComputeElementFlux(const FiniteElement &el,
2964 ElementTransformation &Trans,
2965 Vector &u, const FiniteElement &fluxelem,
2966 Vector &flux, bool with_coef,
2967 const IntegrationRule *ir = NULL) override;
2968
2969 real_t ComputeFluxEnergy(const FiniteElement &fluxelem,
2970 ElementTransformation &Trans,
2971 Vector &flux, Vector *d_energy = NULL) override;
2972
2974 void AssemblePA(const FiniteElementSpace &fes) override;
2975 void AddMultPA(const Vector &x, Vector &y) const override;
2976 void AddAbsMultPA(const Vector &x, Vector &y) const override;
2977 void AssembleDiagonalPA(Vector& diag) override;
2978
2979 const Coefficient *GetCoefficient() const { return Q; }
2980
2981 /// arguments: d1d, q1d, symmetric, NE, bo, bc, bot, bct, gc, gct, pa_data,
2982 /// x, y, useAbs
2983 using ApplyKernelType = void (*)(
2984 const int, const int, const bool, const int, const Array<real_t> &,
2985 const Array<real_t> &, const Array<real_t> &, const Array<real_t> &,
2986 const Array<real_t> &, const Array<real_t> &, const Vector &,
2987 const Vector &, Vector &, const bool);
2988
2989 /// arguments: d1d, q1d, symmetric, ne, Bo, Bc, Go, Gc, pa_data, diag
2990 using DiagonalKernelType = void (*)(const int, const int, const bool,
2991 const int, const Array<real_t> &,
2992 const Array<real_t> &,
2993 const Array<real_t> &,
2994 const Array<real_t> &, const Vector &,
2995 Vector &);
2996
2997 /// parameters: dim, d1d, q1d
2998 MFEM_REGISTER_KERNELS(ApplyPAKernels, ApplyKernelType, (int, int, int));
2999 /// parameters: dim, d1d, q1d
3000 MFEM_REGISTER_KERNELS(DiagonalPAKernels, DiagonalKernelType, (int, int, int));
3001 struct Kernels { Kernels(); };
3002
3003 template <int DIM, int D1D, int Q1D> static void AddSpecialization()
3004 {
3005 ApplyPAKernels::Specialization<DIM, D1D, Q1D>::Add();
3006 DiagonalPAKernels::Specialization<DIM, D1D, Q1D>::Add();
3007 }
3008};
3009
3010/** Integrator for $(\mathrm{curl}(u), \mathrm{curl}(v))$ for FE spaces defined by 'dim' copies of a
3011 scalar FE space. */
3013{
3014private:
3015#ifndef MFEM_THREAD_SAFE
3016 DenseMatrix dshape_hat, dshape, curlshape, Jadj, grad_hat, grad;
3017#endif
3018
3019protected:
3021
3022public:
3024
3026
3027 /// Assemble an element matrix
3028 void AssembleElementMatrix(const FiniteElement &el,
3029 ElementTransformation &Trans,
3030 DenseMatrix &elmat) override;
3031 /// Compute element energy: $ \frac{1}{2} (\mathrm{curl}(u), \mathrm{curl}(u))_E$
3034 const Vector &elfun) override;
3035};
3036
3037/** Class for integrating the bilinear form $a(u,v) := (Q \mathrm{curl}(u), v)$ where $Q$ is
3038 an optional scalar coefficient, and $v$ is a vector with components $v_i$ in
3039 the $L_2$ or $H^1$ space. This integrator handles 3 cases:
3040 1. u ∈ $H(curl)$ in 3D, $v$ is a 3D vector with components $v_i$ in $L^2$ or $H^1$
3041 2. u ∈ $H(curl)$ in 2D, $v$ is a scalar field in $L^2$ or $H^1$
3042 3. u is a scalar field in $H^1$, i.e, $\mathrm{curl}(u) := \begin{pmatrix} 0 & 1 \\ -1 & 0 \end{pmatrix}$, $\nabla u$ and $v$ is a
3043 2D vector field with components $v_i$ in $L^2$ or $H^1$ space.
3044
3045 Note: Case 2 can also be handled by MixedScalarCurlIntegrator */
3047{
3048protected:
3050
3051private:
3052 Vector shape;
3053 DenseMatrix dshape;
3054 DenseMatrix curlshape;
3055 DenseMatrix elmat_comp;
3056public:
3060
3061 void AssembleElementMatrix2(const FiniteElement &trial_fe,
3062 const FiniteElement &test_fe,
3063 ElementTransformation &Trans,
3064 DenseMatrix &elmat) override;
3065};
3066
3067/** Integrator for $(Q u, v)$, where $Q$ is an optional coefficient (of type scalar,
3068 vector (diagonal matrix), or matrix), trial function $u$ is in $H(curl)$ or
3069 $H(div)$, and test function $v$ is in $H(curl)$, $H(div)$, or $v=(v_1,\dots,v_n)$, where
3070 $v_i$ are in $H^1$. */
3072{
3073private:
3075
3076#ifndef MFEM_THREAD_SAFE
3077 Vector shape;
3078 Vector D;
3079 DenseMatrix K;
3080 DenseMatrix partelmat;
3081 DenseMatrix test_vshape;
3082 DenseMatrix trial_vshape;
3083#endif
3084
3085protected:
3089
3090 // PA extension
3092 const DofToQuad *mapsO; ///< Not owned. DOF-to-quad map, open.
3093 const DofToQuad *mapsC; ///< Not owned. DOF-to-quad map, closed.
3094 const DofToQuad *mapsOtest; ///< Not owned. DOF-to-quad map, open.
3095 const DofToQuad *mapsCtest; ///< Not owned. DOF-to-quad map, closed.
3096 const GeometricFactors *geom; ///< Not owned
3099 bool symmetric = true; ///< False if using a nonsymmetric matrix coefficient
3100
3101public:
3102 VectorFEMassIntegrator() { Init(NULL, NULL, NULL); }
3103 VectorFEMassIntegrator(Coefficient *q_) { Init(q_, NULL, NULL); }
3104 VectorFEMassIntegrator(Coefficient &q) { Init(&q, NULL, NULL); }
3109
3110 void AssembleElementMatrix(const FiniteElement &el,
3111 ElementTransformation &Trans,
3112 DenseMatrix &elmat) override;
3113 void AssembleElementMatrix2(const FiniteElement &trial_fe,
3114 const FiniteElement &test_fe,
3115 ElementTransformation &Trans,
3116 DenseMatrix &elmat) override;
3117
3118 void AssemblePA(const FiniteElementSpace &fes) override;
3119 void AssemblePA(const FiniteElementSpace &trial_fes,
3120 const FiniteElementSpace &test_fes) override;
3121 void AddMultPA(const Vector &x, Vector &y) const override;
3122 void AddAbsMultPA(const Vector &x, Vector &y) const override;
3123 void AddMultTransposePA(const Vector &x, Vector &y) const override;
3124 void AssembleDiagonalPA(Vector& diag) override;
3125 void AssembleEA(const FiniteElementSpace &fes, Vector &emat,
3126 const bool add) override;
3127
3128 const Coefficient *GetCoefficient() const { return Q; }
3129
3131 void (*)(const int NE, bool symmetric, const bool scalar_coeff,
3132 const Array<real_t> &trialBO, const Array<real_t> &trialBC,
3133 const Array<real_t> &testBOt, const Array<real_t> &testBCt,
3134 const Vector &pa_data, const Vector &x, Vector &y,
3135 const int triald1d, const int testd1d, const int q1d);
3136
3137 /// parameters: trial_fetype, test_fetype, ndims, trial_d1d, test_d1d, q1d
3140 int, int, int, int));
3141
3142 struct Kernels { Kernels(); };
3143
3144 template <FiniteElement::DerivType TrialType,
3145 FiniteElement::DerivType TestType, int DIM, int TRIAL_D1D,
3146 int TEST_D1D, int Q1D>
3147 static void AddSpecialization()
3148 {
3149 ApplyPAKernels::Specialization<TrialType, TestType, DIM, TRIAL_D1D,
3150 TEST_D1D, Q1D>::Add();
3151 }
3152};
3153
3154/** Integrator for $(Q \nabla \cdot u, v)$ where $u=(u_1,\cdots,u_n)$ and all $u_i$ are in the same
3155 scalar FE space; $v$ is also in a (different) scalar FE space. */
3157{
3158protected:
3160
3161private:
3162 Vector shape;
3163 Vector divshape;
3164 DenseMatrix dshape;
3165 DenseMatrix gshape;
3166 DenseMatrix Jadj;
3167 // PA extension
3168 Vector pa_data;
3169 const DofToQuad *trial_maps, *test_maps; ///< Not owned
3170 const GeometricFactors *geom; ///< Not owned
3171 int dim, sdim, ne, nq;
3172 int trial_dofs1D, test_dofs1D, quad1D;
3173
3174public:
3176 Q(NULL), trial_maps(NULL), test_maps(NULL), geom(NULL)
3177 { }
3179 Q(q_), trial_maps(NULL), test_maps(NULL), geom(NULL)
3180 { }
3182 Q(&q), trial_maps(NULL), test_maps(NULL), geom(NULL)
3183 { }
3184
3185 void AssembleElementMatrix2(const FiniteElement &trial_fe,
3186 const FiniteElement &test_fe,
3187 ElementTransformation &Trans,
3188 DenseMatrix &elmat) override;
3189
3191 void AssemblePA(const FiniteElementSpace &trial_fes,
3192 const FiniteElementSpace &test_fes) override;
3193
3194 void AddMultPA(const Vector &x, Vector &y) const override;
3195 void AddMultTransposePA(const Vector &x, Vector &y) const override;
3196
3198 void (*)(const int ne,
3199 const Array<real_t> &b, const Array<real_t> &g, const Array<real_t> &bt,
3200 const Vector &op, const Vector &x, Vector &y,
3201 const int tr_d1d, const int te_d1d, const int q1d);
3202 MFEM_REGISTER_KERNELS(VectorDivergenceAddMultPA,
3204 (int, int, int, int));
3205
3207 void (*)(const int ne,
3208 const Array<real_t> &bt, const Array<real_t> &gt, const Array<real_t> &b,
3209 const Vector &q, const Vector &x, Vector &y,
3210 const int tr_d1d, const int te_d1d, const int q1d);
3211 MFEM_REGISTER_KERNELS(VectorDivergenceAddMultTransposePA,
3213 (int, int, int, int));
3214
3215 static const IntegrationRule &GetRule(const FiniteElement &trial_fe,
3216 const FiniteElement &test_fe,
3217 const ElementTransformation &Trans);
3218
3219protected:
3221 const FiniteElement& trial_fe,
3222 const FiniteElement& test_fe,
3223 const ElementTransformation& trans) const override
3224 {
3225 return &GetRule(trial_fe, test_fe, trans);
3226 }
3227};
3228
3229/// $(Q \nabla \cdot u, \nabla \cdot v)$ for Raviart-Thomas elements
3231{
3232protected:
3234
3235private:
3236#ifndef MFEM_THREAD_SAFE
3237 Vector divshape, te_divshape;
3238#endif
3239
3240 // PA extension
3241 Vector pa_data;
3242 const DofToQuad *mapsO; ///< Not owned. DOF-to-quad map, open.
3243 const DofToQuad *mapsC; ///< Not owned. DOF-to-quad map, closed.
3244 const GeometricFactors *geom; ///< Not owned
3245 int dim, ne, dofs1D, quad1D;
3246
3247public:
3248 DivDivIntegrator() { Q = NULL; }
3250 BilinearFormIntegrator(ir), Q(&q) { }
3251
3252 void AssembleElementMatrix(const FiniteElement &el,
3253 ElementTransformation &Trans,
3254 DenseMatrix &elmat) override;
3255
3256 void AssembleElementMatrix2(const FiniteElement &trial_fe,
3257 const FiniteElement &test_fe,
3258 ElementTransformation &Trans,
3259 DenseMatrix &elmat) override;
3260
3262 void AssemblePA(const FiniteElementSpace &fes) override;
3263 void AddMultPA(const Vector &x, Vector &y) const override;
3264 void AssembleDiagonalPA(Vector& diag) override;
3265 void AssembleEA(const FiniteElementSpace &fes, Vector &emat,
3266 const bool add) override;
3267
3268 const Coefficient *GetCoefficient() const { return Q; }
3269};
3270
3271/** Class for integrating the bilinear form $a(u,v) := (Q \nabla u, \nabla v)$,
3272 where $u=(u_1,\dots,u_n)$ and $v=(v_1,\dots,v_n)$, $u_i$ and $v_i$ are
3273 defined by scalar FE through standard transformation.
3274 See the constructors' documentation for all Coefficient options.
3275 The computed local element matrix is square, of size <tt> vdim*dof </tt>,
3276 where \c vdim is the vector dimension space and \c dof is the local degrees
3277 of freedom. The integrator is not aware of the true vector dimension and
3278 must use \c VectorCoefficient, \c MatrixCoefficient, or a caller-specified
3279 value to determine the vector space. For a scalar coefficient, the caller
3280 may manually specify the vector dimension or the vector dimension is assumed
3281 to be the spatial dimension (i.e. 2-dimension or 3-dimension). */
3283{
3284 int vdim = -1;
3285 DenseMatrix dshape, dshapedxt, pelmat;
3286 DenseMatrix mcoeff;
3287 Vector vcoeff;
3288
3289protected:
3290 Coefficient *Q = nullptr;
3293 // PA extension
3294 const DofToQuad *maps; ///< Not owned
3295 const GeometricFactors *geom; ///< Not owned
3298
3299public:
3300 VectorDiffusionIntegrator(const IntegrationRule *ir = nullptr);
3301
3302 /** \brief Integrator with unit coefficient for caller-specified vector
3303 dimension.
3304
3305 If the vector dimension does not match the true dimension of the space,
3306 the resulting element matrix will be mathematically invalid. */
3307 VectorDiffusionIntegrator(int vector_dimension);
3308
3310
3312
3313 /** \brief Integrator with scalar coefficient for caller-specified vector
3314 dimension.
3315
3316 The element matrix is block-diagonal with \c vdim copies of the element
3317 matrix integrated with the \c Coefficient.
3318
3319 If the vector dimension does not match the true dimension of the space,
3320 the resulting element matrix will be mathematically invalid. */
3321 VectorDiffusionIntegrator(Coefficient &q, int vector_dimension);
3322
3323 /** \brief Integrator with \c VectorCoefficient. The vector dimension of the
3324 \c FiniteElementSpace is assumed to be the same as the dimension of the
3325 \c Vector.
3326
3327 The element matrix is block-diagonal and each block is integrated with
3328 coefficient $q_{i}$.
3329
3330 If the vector dimension does not match the true dimension of the space,
3331 the resulting element matrix will be mathematically invalid. */
3333
3334 /** \brief Integrator with \c MatrixCoefficient. The vector dimension of the
3335 \c FiniteElementSpace is assumed to be the same as the dimension of the
3336 \c Matrix.
3337
3338 The element matrix is populated in each block. Each block is integrated
3339 with coefficient $q_{ij}$.
3340
3341 If the vector dimension does not match the true dimension of the space,
3342 the resulting element matrix will be mathematically invalid. */
3344
3345 void AssembleElementMatrix(const FiniteElement &el,
3346 ElementTransformation &Trans,
3347 DenseMatrix &elmat) override;
3348 void AssembleElementVector(const FiniteElement &el,
3350 const Vector &elfun, Vector &elvect) override;
3351
3353 void AssemblePA(const FiniteElementSpace &fes) override;
3354 void AssembleMF(const FiniteElementSpace &fes) override;
3355 void AssembleDiagonalPA(Vector &diag) override;
3356 void AssembleDiagonalMF(Vector &diag) override;
3357 void AddMultPA(const Vector &x, Vector &y) const override;
3358 void AddMultMF(const Vector &x, Vector &y) const override;
3359 bool SupportsCeed() const override { return DeviceCanUseCeed(); }
3360
3361 /// arguments: ne, coeff_vdim, B, G, pa_data, x, y, d1d, q1d, vdim
3362 using ApplyKernelType = void (*)(const int, const int,
3363 const Array<real_t> &, const Array<real_t> &,
3364 const Vector &, const Vector &, Vector &,
3365 const int, const int, const int);
3366
3367 /// arguments: dim, vdim, d1d, q1d
3368 MFEM_REGISTER_KERNELS(ApplyPAKernels, ApplyKernelType, (int, int, int, int));
3369
3370 template <int DIM, int VDIM, int D1D, int Q1D>
3371 static void AddSpecialization()
3372 {
3373 ApplyPAKernels::Specialization<DIM, VDIM, D1D, Q1D>::Add();
3374 }
3375
3376 // struct Kernels { Kernels(); };
3377};
3378
3379/** Integrator for the linear elasticity form:
3380 $$
3381 a(u,v) = (\lambda \mathrm{div}(u), \mathrm{div}(v)) + (2 \mu \varepsilon(u), \varepsilon(v)),
3382 $$
3383 where $\varepsilon(v) = \frac{1}{2} (\mathrm{grad}(v) + \mathrm{grad}(v)^{\mathrm{T}})$.
3384 This is a 'Vector' integrator, i.e. defined for FE spaces
3385 using multiple copies of a scalar FE space. */
3387{
3389
3390protected:
3393
3394private:
3395#ifndef MFEM_THREAD_SAFE
3396 Vector shape;
3397 DenseMatrix dshape, gshape, pelmat;
3398 Vector divshape;
3399#endif
3400
3401 // PA extension
3402
3403 const DofToQuad *maps; ///< Not owned
3404 const GeometricFactors *geom; ///< Not owned
3405 int vdim, ndofs;
3406 const FiniteElementSpace *fespace; ///< Not owned.
3407
3408 std::unique_ptr<QuadratureSpace> q_space;
3409 /// Coefficients projected onto q_space
3410 std::unique_ptr<CoefficientVector> lambda_quad, mu_quad;
3411 /// Workspace vector
3412 std::unique_ptr<QuadratureFunction> q_vec;
3413
3414 /// Set up the quadrature space and project lambda and mu coefficients
3415 void SetUpQuadratureSpaceAndCoefficients(const FiniteElementSpace &fes);
3416
3417public:
3420 /** With this constructor $\lambda = q_l m$ and $\mu = q_m m$
3421 if $dim q_l + 2 q_m = 0$ then $tr(\sigma) = 0$. */
3423 { lambda = NULL; mu = &m; q_lambda = q_l; q_mu = q_m; }
3424
3425 void AssembleElementMatrix(const FiniteElement &el,
3427 DenseMatrix &elmat) override;
3428
3430 void AssemblePA(const FiniteElementSpace &fes) override;
3431
3432 void AssembleDiagonalPA(Vector &diag) override;
3433
3434 void AddMultPA(const Vector &x, Vector &y) const override;
3435
3436 void AddMultTransposePA(const Vector &x, Vector &y) const override;
3437
3438 /** Compute the stress corresponding to the local displacement @a $u$ and
3439 interpolate it at the nodes of the given @a fluxelem. Only the symmetric
3440 part of the stress is stored, so that the size of @a flux is equal to
3441 the number of DOFs in @a fluxelem times dim*(dim+1)/2. In 2D, the order
3442 of the stress components is: $s_xx, s_yy, s_xy$. In 3D, it is: $s_xx, s_yy,
3443 s_zz, s_xy, s_xz, s_yz$. In other words, @a flux is the local vector for
3444 a FE space with dim*(dim+1)/2 vector components, based on the finite
3445 element @a fluxelem. The integration rule is taken from @a fluxelem.
3446 @a ir exists to specific an alternative integration rule. */
3447 void ComputeElementFlux(const FiniteElement &el,
3448 ElementTransformation &Trans,
3449 Vector &u,
3450 const FiniteElement &fluxelem,
3451 Vector &flux, bool with_coef = true,
3452 const IntegrationRule *ir = NULL) override;
3453
3454 /** Compute the element energy (integral of the strain energy density)
3455 corresponding to the stress represented by @a flux which is a vector of
3456 coefficients multiplying the basis functions defined by @a fluxelem. In
3457 other words, @a flux is the local vector for a FE space with
3458 dim*(dim+1)/2 vector components, based on the finite element @a fluxelem.
3459 The number of components, dim*(dim+1)/2 is such that it represents the
3460 symmetric part of the (symmetric) stress tensor. The order of the
3461 components is: $s_xx, s_yy, s_xy$ in 2D, and $s_xx, s_yy, s_zz, s_xy, s_xz,
3462 s_yz$ in 3D. */
3463 real_t ComputeFluxEnergy(const FiniteElement &fluxelem,
3464 ElementTransformation &Trans,
3465 Vector &flux, Vector *d_energy = NULL) override;
3466};
3467
3468/// @brief Integrator that computes the PA action of one of the blocks in an
3469/// ElasticityIntegrator, considering the elasticity operator as a dim x dim
3470/// block operator.
3472{
3473 ElasticityIntegrator &parent;
3474 const int i_block;
3475 const int j_block;
3476
3477 const DofToQuad *maps; ///< Not owned
3478 const GeometricFactors *geom; ///< Not owned
3479 const FiniteElementSpace *fespace; ///< Not owned.
3480
3481public:
3482 /// @brief Given an ElasticityIntegrator, create an integrator that
3483 /// represents the $(i,j)$th component block.
3484 ///
3485 /// @note The parent ElasticityIntegrator must remain valid throughout the
3486 /// lifetime of this integrator.
3487 ElasticityComponentIntegrator(ElasticityIntegrator &parent_, int i_, int j_);
3488
3490 void AssemblePA(const FiniteElementSpace &fes) override;
3491
3492 void AssembleEA(const FiniteElementSpace &fes, Vector &emat,
3493 const bool add = true) override;
3494
3495 void AddMultPA(const Vector &x, Vector &y) const override;
3496
3497 void AddMultTransposePA(const Vector &x, Vector &y) const override;
3498};
3499
3500/** Integrator for the DG form:
3501 $$
3502 \alpha \langle \rho_u (u \cdot n) \{v\},[w] \rangle + \beta \langle \rho_u |u \cdot n| [v],[w] \rangle,
3503 $$
3504 where $v$ and $w$ are the trial and test variables, respectively, and $\rho$/$u$ are
3505 given scalar/vector coefficients. $\{v\}$ represents the average value of $v$ on
3506 the face and $[v]$ is the jump such that $\{v\}=(v_1+v_2)/2$ and $[v]=(v_1-v_2)$ for the
3507 face between elements $1$ and $2$. For boundary elements, $v2=0$. The vector
3508 coefficient, $u$, is assumed to be continuous across the faces and when given
3509 the scalar coefficient, $\rho$, is assumed to be discontinuous. The integrator
3510 uses the upwind value of $\rho$, denoted by $\rho_u$, which is value from the side into which
3511 the vector coefficient, $u$, points.
3512
3513 One use case for this integrator is to discretize the operator $-u \cdot \nabla v$
3514 with a DG formulation. The resulting formulation uses the
3515 ConvectionIntegrator (with coefficient $u$, and parameter $\alpha = -1$) and the
3516 transpose of the DGTraceIntegrator (with coefficient $u$, and parameters $\alpha = 1$,
3517 $\beta = -1/2$ to use the upwind face flux, see also
3518 NonconservativeDGTraceIntegrator). This discretization and the handling of
3519 the inflow and outflow boundaries is illustrated in Example 9/9p.
3520
3521 Another use case for this integrator is to discretize the operator $-\mathrm{div}(u v)$
3522 with a DG formulation. The resulting formulation is conservative and
3523 consists of the ConservativeConvectionIntegrator (with coefficient $u$, and
3524 parameter $\alpha = -1$) plus the DGTraceIntegrator (with coefficient $u$, and
3525 parameters $\alpha = -1$, $\beta = -1/2$ to use the upwind face flux).
3526 */
3528{
3529protected:
3530 Coefficient *rho = nullptr;
3533 // PA extension
3535 const DofToQuad *maps; ///< Not owned
3536 const FaceGeometricFactors *geom; ///< Not owned
3538
3539private:
3540 Vector shape1, shape2;
3541 Vector tr_shape1, te_shape1, tr_shape2, te_shape2;
3542
3543public:
3545
3546 /// Construct integrator with $\rho = 1$, $\beta = \alpha/2$.
3548
3549 /// Construct integrator with $\rho = 1$.
3551
3553 real_t a, real_t b);
3554
3556 void AssembleFaceMatrix(const FiniteElement &el1,
3557 const FiniteElement &el2,
3559 DenseMatrix &elmat) override;
3560
3561 void AssembleFaceMatrix(const FiniteElement &trial_fe1,
3562 const FiniteElement &test_fe1,
3563 const FiniteElement &trial_fe2,
3564 const FiniteElement &test_fe2,
3566 DenseMatrix &elmat) override;
3567
3568 void AssemblePAInteriorFaces(const FiniteElementSpace &fes) override;
3569
3570 void AssemblePABoundaryFaces(const FiniteElementSpace &fes) override;
3571
3572 void AddMultTransposePA(const Vector &x, Vector &y) const override;
3573
3574 void AddMultPA(const Vector&, Vector&) const override;
3575
3578 Vector &ea_data_int,
3579 Vector &ea_data_ext,
3580 const bool add) override;
3581
3583 Vector &ea_data_bdr,
3584 const bool add) override;
3585
3586 static const IntegrationRule &GetRule(Geometry::Type geom, int order,
3588
3589 static const IntegrationRule &GetRule(Geometry::Type geom, int order,
3590 const ElementTransformation &T);
3591
3592 /// arguments: nf, B, Bt, pa_data, x, y, dofs1D, quad1D
3593 using ApplyKernelType = void (*)(const int, const Array<real_t> &,
3594 const Array<real_t> &, const Vector &,
3595 const Vector &, Vector &, const int,
3596 const int);
3597
3598 /// arguments: DIM, d1d, q1d
3599 MFEM_REGISTER_KERNELS(ApplyPAKernels, ApplyKernelType, (int, int, int));
3600 /// arguments: DIM, d1d, q1d
3601 MFEM_REGISTER_KERNELS(ApplyPATKernels, ApplyKernelType, (int, int, int));
3602
3603 template <int DIM, int D1D, int Q1D> static void AddSpecialization()
3604 {
3605 ApplyPAKernels::Specialization<DIM, D1D, Q1D>::Add();
3606 ApplyPATKernels::Specialization<DIM, D1D, Q1D>::Add();
3607 }
3608
3609 struct Kernels { Kernels(); };
3610
3611
3612private:
3613 void SetupPA(const FiniteElementSpace &fes, FaceType type);
3614};
3615
3616// Alias for @a DGTraceIntegrator.
3618
3619/** Integrator that represents the face terms used for the non-conservative
3620 DG discretization of the convection equation:
3621 $$
3622 -\alpha \langle \rho_u (u \cdot n) \{v\},[w] \rangle + \beta \langle \rho_u |u \cdot n| [v],[w] \rangle.
3623 $$
3624 This integrator can be used with together with ConvectionIntegrator to
3625 implement an upwind DG discretization in non-conservative form, see ex9 and
3626 ex9p. */
3640
3641/** Integrator for the DG form:
3642 $$
3643 - \langle \{(Q \nabla u) \cdot n\}, [v] \rangle + \sigma \langle [u], \{(Q \nabla v) \cdot n \} \rangle
3644 + \kappa \langle \{h^{-1} Q\} [u], [v] \rangle
3645 $$
3646 where $Q$ is a scalar or matrix diffusion coefficient and $u$, $v$ are the trial
3647 and test spaces, respectively. The parameters $\sigma$ and $\kappa$ determine the
3648 DG method to be used (when this integrator is added to the "broken"
3649 DiffusionIntegrator):
3650 - $\sigma = -1$, $\kappa \geq \kappa_0$: symm. interior penalty (IP or SIPG) method,
3651 - $\sigma = +1$, $\kappa > 0$: non-symmetric interior penalty (NIPG) method,
3652 - $\sigma = +1$, $\kappa = 0$: the method of Baumann and Oden.
3653
3654 \todo Clarify used notation. */
3656{
3657protected:
3658 Coefficient *Q = nullptr;
3661
3662 // these are not thread-safe!
3665
3666
3667 // PA extension
3668 Vector pa_data; // (Q, h, dot(n,J)|el0, dot(n,J)|el1)
3669 const DofToQuad *maps; ///< Not owned
3672
3673public:
3674 DGDiffusionIntegrator(const real_t s, const real_t k);
3675 DGDiffusionIntegrator(Coefficient &q, const real_t s, const real_t k);
3678 void AssembleFaceMatrix(const FiniteElement &el1, const FiniteElement &el2,
3680 DenseMatrix &elmat) override;
3681
3682 bool RequiresFaceNormalDerivatives() const override { return true; }
3683
3685
3686 void AssemblePAInteriorFaces(const FiniteElementSpace &fes) override;
3687
3688 void AssemblePABoundaryFaces(const FiniteElementSpace &fes) override;
3689
3690 void AddMultPAFaceNormalDerivatives(const Vector &x, const Vector &dxdn,
3691 Vector &y, Vector &dydn) const override;
3692
3694
3695 const IntegrationRule &GetRule(int order, Geometry::Type geom);
3696
3698
3699 /// arguments: nf, B, Bt, G, Gt, sigma, pa_data, x, dxdn, y, dydn, dofs1D,
3700 /// quad1D
3701 using ApplyKernelType = void (*)(const int, const Array<real_t> &,
3702 const Array<real_t> &,
3703 const Array<real_t> &,
3704 const Array<real_t> &, const real_t,
3705 const Vector &, const Vector &_,
3706 const Vector &, Vector &, Vector &,
3707 const int, const int);
3708
3709 /// arguments: DIM, d1d, q1d
3710 MFEM_REGISTER_KERNELS(ApplyPAKernels, ApplyKernelType, (int, int, int));
3711
3712 template <int DIM, int D1D, int Q1D> static void AddSpecialization()
3713 {
3714 ApplyPAKernels::Specialization<DIM, D1D, Q1D>::Add();
3715 }
3716
3717 struct Kernels { Kernels(); };
3718
3719private:
3720 void SetupPA(const FiniteElementSpace &fes, FaceType type);
3721};
3722
3723/** Integrator for the "BR2" diffusion stabilization term
3724 $$
3725 \sum_e \eta (r_e([u]), r_e([v]))
3726 $$
3727 where $r_e$ is the lifting operator defined on each edge $e$ (potentially
3728 weighted by a coefficient $Q$). The parameter eta can be chosen to be one to
3729 obtain a stable discretization. The constructor for this integrator requires
3730 the finite element space because the lifting operator depends on the
3731 element-wise inverse mass matrix.
3732
3733 BR2 stands for the second method of Bassi and Rebay:
3734
3735 - F. Bassi and S. Rebay. A high order discontinuous Galerkin method for
3736 compressible turbulent flows. In B. Cockburn, G. E. Karniadakis, and
3737 C.-W. Shu, editors, Discontinuous Galerkin Methods, pages 77-88. Springer
3738 Berlin Heidelberg, 2000.
3739 - D. N. Arnold, F. Brezzi, B. Cockburn, and L. D. Marini. Unified analysis
3740 of discontinuous Galerkin methods for elliptic problems. SIAM Journal on
3741 Numerical Analysis, 39(5):1749-1779, 2002.
3742*/
3744{
3745protected:
3747
3748 // Block factorizations of local mass matrices, with offsets for the case of
3749 // not equally sized blocks (mixed meshes, p-refinement)
3753
3755
3757
3761
3762 /// Precomputes the inverses (LU factorizations) of the local mass matrices.
3763 /** @a fes must be a DG space, so the mass matrix is block diagonal, and its
3764 inverse can be computed locally. This is required for the computation of
3765 the lifting operators @a r_e.
3766 */
3768
3769public:
3772 real_t e = 1.0);
3773 MFEM_DEPRECATED DGDiffusionBR2Integrator(class FiniteElementSpace *fes,
3774 real_t e = 1.0);
3775
3777 void AssembleFaceMatrix(const FiniteElement &el1,
3778 const FiniteElement &el2,
3780 DenseMatrix &elmat) override;
3781};
3782
3783/** Integrator for the DG elasticity form, for the formulations see:
3784 - PhD Thesis of Jonas De Basabe, High-Order Finite %Element Methods for
3785 Seismic Wave Propagation, UT Austin, 2009, p. 23, and references therein
3786 - Peter Hansbo and Mats G. Larson, Discontinuous Galerkin and the
3787 Crouzeix-Raviart %Element: Application to Elasticity, PREPRINT 2000-09,
3788 p.3
3789
3790 $$
3791 - \left< \{ \tau(u) \}, [v] \right> + \alpha \left< \{ \tau(v) \}, [u]
3792 \right> + \kappa \left< h^{-1} \{ \lambda + 2 \mu \} [u], [v] \right>
3793 $$
3794
3795 where $ \left<u, v\right> = \int_{F} u \cdot v $, and $ F $ is a
3796 face which is either a boundary face $ F_b $ of an element $ K $ or
3797 an interior face $ F_i $ separating elements $ K_1 $ and $ K_2 $.
3798
3799 In the bilinear form above $ \tau(u) $ is traction, and it's also
3800 $ \tau(u) = \sigma(u) \cdot \vec{n} $, where $ \sigma(u) $ is
3801 stress, and $ \vec{n} $ is the unit normal vector w.r.t. to $ F $.
3802
3803 In other words, we have
3804 $$
3805 - \left< \{ \sigma(u) \cdot \vec{n} \}, [v] \right> + \alpha \left< \{
3806 \sigma(v) \cdot \vec{n} \}, [u] \right> + \kappa \left< h^{-1} \{
3807 \lambda + 2 \mu \} [u], [v] \right>
3808 $$
3809
3810 For isotropic media
3811 $$
3812 \begin{split}
3813 \sigma(u) &= \lambda \nabla \cdot u I + 2 \mu \varepsilon(u) \\
3814 &= \lambda \nabla \cdot u I + 2 \mu \frac{1}{2} (\nabla u + \nabla
3815 u^{\mathrm{T}}) \\
3816 &= \lambda \nabla \cdot u I + \mu (\nabla u + \nabla u^{\mathrm{T}})
3817 \end{split}
3818 $$
3819
3820 where $ I $ is identity matrix, $ \lambda $ and $ \mu $ are Lame
3821 coefficients (see ElasticityIntegrator), $ u, v $ are the trial and test
3822 functions, respectively.
3823
3824 The parameters $ \alpha $ and $ \kappa $ determine the DG method to
3825 use (when this integrator is added to the "broken" ElasticityIntegrator):
3826
3827 - IIPG, $\alpha = 0$,
3828 C. Dawson, S. Sun, M. Wheeler, Compatible algorithms for coupled flow and
3829 transport, Comp. Meth. Appl. Mech. Eng., 193(23-26), 2565-2580, 2004.
3830
3831 - SIPG, $\alpha = -1$,
3832 M. Grote, A. Schneebeli, D. Schotzau, Discontinuous Galerkin Finite
3833 %Element Method for the Wave Equation, SINUM, 44(6), 2408-2431, 2006.
3834
3835 - NIPG, $\alpha = 1$,
3836 B. Riviere, M. Wheeler, V. Girault, A Priori Error Estimates for Finite
3837 %Element Methods Based on Discontinuous Approximation Spaces for Elliptic
3838 Problems, SINUM, 39(3), 902-931, 2001.
3839
3840 This is a '%Vector' integrator, i.e. defined for FE spaces using multiple
3841 copies of a scalar FE space.
3842 */
3844{
3845public:
3847 : lambda(NULL), mu(NULL), alpha(alpha_), kappa(kappa_) { }
3848
3850 real_t alpha_, real_t kappa_)
3851 : lambda(&lambda_), mu(&mu_), alpha(alpha_), kappa(kappa_) { }
3852
3854 void AssembleFaceMatrix(const FiniteElement &el1,
3855 const FiniteElement &el2,
3857 DenseMatrix &elmat) override;
3858
3859protected:
3862
3863#ifndef MFEM_THREAD_SAFE
3864 // values of all scalar basis functions for one component of u (which is a
3865 // vector) at the integration point in the reference space
3867 // values of derivatives of all scalar basis functions for one component
3868 // of u (which is a vector) at the integration point in the reference space
3870 // Adjugate of the Jacobian of the transformation: adjJ = det(J) J^{-1}
3872 // gradient of shape functions in the real (physical, not reference)
3873 // coordinates, scaled by det(J):
3874 // dshape_ps(jdof,jm) = sum_{t} adjJ(t,jm)*dshape(jdof,t)
3876 Vector nor; // nor = |weight(J_face)| n
3877 Vector nL1, nL2; // nL1 = (lambda1 * ip.weight / detJ1) nor
3878 Vector nM1, nM2; // nM1 = (mu1 * ip.weight / detJ1) nor
3879 Vector dshape1_dnM, dshape2_dnM; // dshape1_dnM = dshape1_ps . nM1
3880 // 'jmat' corresponds to the term: kappa <h^{-1} {lambda + 2 mu} [u], [v]>
3882#endif
3883
3884 static void AssembleBlock(
3885 const int dim, const int row_ndofs, const int col_ndofs,
3886 const int row_offset, const int col_offset,
3887 const real_t jmatcoef, const Vector &col_nL, const Vector &col_nM,
3888 const Vector &row_shape, const Vector &col_shape,
3889 const Vector &col_dshape_dnM, const DenseMatrix &col_dshape,
3890 DenseMatrix &elmat, DenseMatrix &jmat);
3891};
3892
3893/** Integrator for the DPG form:$ \langle v, [w] \rangle $ over all faces (the interface) where
3894 the trial variable $v$ is defined on the interface and the test variable $w$ is
3895 defined inside the elements, generally in a DG space. */
3897{
3898private:
3899 Vector face_shape, shape1, shape2;
3900
3901public:
3904 void AssembleFaceMatrix(const FiniteElement &trial_face_fe,
3905 const FiniteElement &test_fe1,
3906 const FiniteElement &test_fe2,
3908 DenseMatrix &elmat) override;
3909};
3910
3911/** Integrator for the form:$ \langle v, [w \cdot n] \rangle $ over all faces (the interface) where
3912 the trial variable $v$ is defined on the interface and the test variable $w$ is
3913 in an $H(div)$-conforming space. */
3915{
3916private:
3917 Vector face_shape, normal, shape1_n, shape2_n;
3918 DenseMatrix shape1, shape2;
3919
3920public:
3923 void AssembleFaceMatrix(const FiniteElement &trial_face_fe,
3924 const FiniteElement &test_fe1,
3925 const FiniteElement &test_fe2,
3927 DenseMatrix &elmat) override;
3928
3930 void AssembleEAInteriorFaces(const FiniteElementSpace &trial_fes,
3931 const FiniteElementSpace &test_fes,
3932 Vector &emat,
3933 const bool add = true) override;
3934};
3935
3936/** Integrator for the DPG form:$ \langle v, w \rangle $ over a face (the interface) where
3937 the trial variable $v$ is defined on the interface
3938 ($H^{-1/2}$ i.e., $v := u \cdot n$ normal trace of $H(div)$)
3939 and the test variable $w$ is in an $H^1$-conforming space. */
3941{
3942private:
3943 Vector face_shape, shape;
3944public:
3946 void AssembleTraceFaceMatrix(int elem,
3947 const FiniteElement &trial_face_fe,
3948 const FiniteElement &test_fe,
3950 DenseMatrix &elmat);
3951};
3952
3953/** Integrator for the form: $ \langle v, w \cdot n \rangle $ over a face (the interface) where
3954 the trial variable $v$ is defined on the interface ($H^{1/2}$, i.e., trace of $H^1$)
3955 and the test variable $w$ is in an $H(div)$-conforming space. */
3957{
3958private:
3959 Vector face_shape, normal, shape_n;
3960 DenseMatrix shape;
3961
3962public:
3964 void AssembleTraceFaceMatrix(int ielem,
3965 const FiniteElement &trial_face_fe,
3966 const FiniteElement &test_fe,
3968 DenseMatrix &elmat) override;
3969};
3970
3971
3972/** Integrator for the form: $\langle v, w \times n \rangle$ over a face (the interface)
3973 * In 3D the trial variable $v$ is defined on the interface ($H^{-1/2}$(curl), trace of $H(curl)$)
3974 * In 2D it's defined on the interface ($H^{1/2}$, trace of $H^1$)
3975 * The test variable $w$ is in an $H(curl)$-conforming space. */
3977{
3978private:
3979 DenseMatrix face_shape, shape, shape_n;
3980 Vector normal;
3981 Vector temp;
3982
3983 void cross_product(const Vector & x, const DenseMatrix & Y, DenseMatrix & Z)
3984 {
3985 int dim = x.Size();
3986 MFEM_VERIFY(Y.Width() == dim, "Size mismatch");
3987 int dimc = dim == 3 ? dim : 1;
3988 int h = Y.Height();
3989 Z.SetSize(h,dimc);
3990 if (dim == 3)
3991 {
3992 for (int i = 0; i<h; i++)
3993 {
3994 Z(i,0) = x(2) * Y(i,1) - x(1) * Y(i,2);
3995 Z(i,1) = x(0) * Y(i,2) - x(2) * Y(i,0);
3996 Z(i,2) = x(1) * Y(i,0) - x(0) * Y(i,1);
3997 }
3998 }
3999 else
4000 {
4001 for (int i = 0; i<h; i++)
4002 {
4003 Z(i,0) = x(1) * Y(i,0) - x(0) * Y(i,1);
4004 }
4005 }
4006 }
4007
4008public:
4010 void AssembleTraceFaceMatrix(int elem,
4011 const FiniteElement &trial_face_fe,
4012 const FiniteElement &test_fe,
4014 DenseMatrix &elmat);
4015};
4016
4017/** Abstract class to serve as a base for local interpolators to be used in the
4018 DiscreteLinearOperator class. */
4020
4021
4022/** Class for constructing the gradient as a DiscreteLinearOperator from an
4023 $H^1$-conforming space to an $H(curl)$-conforming space. The range space can be
4024 vector $L_2$ space as well. */
4026{
4027public:
4028 GradientInterpolator() : dofquad_fe(NULL) { }
4029 virtual ~GradientInterpolator() { delete dofquad_fe; }
4030
4032 const FiniteElement &nd_fe,
4033 ElementTransformation &Trans,
4034 DenseMatrix &elmat) override
4035 { nd_fe.ProjectGrad(h1_fe, Trans, elmat); }
4036
4038
4039 /** @brief Setup method for PA data.
4040
4041 @param[in] trial_fes $H^1$ Lagrange space
4042 @param[in] test_fes $H(curl)$ Nedelec space
4043 */
4044 void AssemblePA(const FiniteElementSpace &trial_fes,
4045 const FiniteElementSpace &test_fes) override;
4046
4047 void AddMultPA(const Vector &x, Vector &y) const override;
4048 void AddMultTransposePA(const Vector &x, Vector &y) const override;
4049
4050private:
4051 /// 1D finite element that generates and owns the 1D DofToQuad maps below
4052 FiniteElement *dofquad_fe;
4053
4054 bool B_id; // is the B basis operator (maps_C_C) the identity?
4055 const DofToQuad *maps_C_C; // one-d map with Lobatto rows, Lobatto columns
4056 const DofToQuad *maps_O_C; // one-d map with Legendre rows, Lobatto columns
4057 int dim, ne, o_dofs1D, c_dofs1D;
4058};
4059
4060
4061/** Class for constructing the identity map as a DiscreteLinearOperator. This
4062 is the discrete embedding matrix when the domain space is a subspace of
4063 the range space. Otherwise, a dof projection matrix is constructed. */
4065{
4066protected:
4067 const int vdim;
4068
4069public:
4070 /** @brief Construct an identity interpolator.
4071
4072 @param[in] vdim_ Vector dimension (number of components) in the domain
4073 and range FE spaces.
4074 */
4075 IdentityInterpolator(int vdim_ = 1) : vdim(vdim_) { }
4076
4078 const FiniteElement &ran_fe,
4079 ElementTransformation &Trans,
4080 DenseMatrix &elmat) override
4081 {
4082 if (vdim == 1)
4083 {
4084 ran_fe.Project(dom_fe, Trans, elmat);
4085 return;
4086 }
4087 DenseMatrix elmat_block;
4088 ran_fe.Project(dom_fe, Trans, elmat_block);
4089 elmat.SetSize(vdim*elmat_block.Height(), vdim*elmat_block.Width());
4090 elmat = 0_r;
4091 for (int i = 0; i < vdim; i++)
4092 {
4093 elmat.SetSubMatrix(i*elmat_block.Height(), i*elmat_block.Width(),
4094 elmat_block);
4095 }
4096 }
4097
4099 void AssemblePA(const FiniteElementSpace &trial_fes,
4100 const FiniteElementSpace &test_fes) override;
4101
4102 void AddMultPA(const Vector &x, Vector &y) const override;
4103 void AddMultTransposePA(const Vector &x, Vector &y) const override;
4104
4105private:
4106 /// 1D finite element that generates and owns the 1D DofToQuad maps below
4107 std::unique_ptr<FiniteElement> dofquad_fe;
4108
4109 const DofToQuad *maps_C_C; // one-d map with Lobatto rows, Lobatto columns
4110 const DofToQuad *maps_O_C; // one-d map with Legendre rows, Lobatto columns
4111 int dim, ne, o_dofs1D, c_dofs1D;
4112
4113 Vector pa_data;
4114};
4115
4116
4117/** @brief Class identical to IdentityInterpolator with the exception that it
4118 requires the vector dimension (number of components) to be specified during
4119 construction. */
4121{
4122public:
4124};
4125
4126
4127/** Class for constructing the (local) discrete curl matrix which can be used
4128 as an integrator in a DiscreteLinearOperator object to assemble the global
4129 discrete curl matrix. */
4131{
4132 // members only required for partial assembly
4133 /// 1D finite elements that generate and own the 1D DofToQuad maps below
4134 std::unique_ptr<FiniteElement> closed_dofquad_fe;
4135 std::unique_ptr<FiniteElement> open_dofquad_fe;
4136 const DofToQuad *maps_C_C =
4137 nullptr; // one-d map with Lobatto rows, Lobatto columns
4138 const DofToQuad *maps_O_C =
4139 nullptr; // one-d map with Legendre rows, Lobatto columns
4140 const DofToQuad *maps_O_O =
4141 nullptr; // one-d map with Legendre rows, Legendre columns
4142
4143 int dim, ne;
4144 // "dof" are the domain fespace dof counts
4145 int ndof_o;
4146 // "quads" are the range fespace dof counts
4147 int nquad_o;
4148 int c_dofs1D = 0;
4149 int o_dofs1D = 0;
4150 int pa_mode_2d = 0;
4151
4152 Vector pa_data;
4153
4154public:
4156
4158 const FiniteElement &ran_fe,
4159 ElementTransformation &Trans,
4160 DenseMatrix &elmat) override
4161 { ran_fe.ProjectCurl(dom_fe, Trans, elmat); }
4162
4163 void AssemblePA(const FiniteElementSpace &dom_fes,
4164 const FiniteElementSpace &ran_fes) override;
4165 void AssemblePA(const FiniteElementSpace &fes) override
4166 {
4167 AssemblePA(fes, fes);
4168 }
4169 void AddMultPA(const Vector &x, Vector &y) const override;
4170 void AddMultTransposePA(const Vector &x, Vector &y) const override;
4171
4172 using ApplyKernelType = void (*)(const int ne, const int ndof_o,
4173 const int nquad_o, const Vector &pa,
4174 const Vector &x, Vector &y);
4175
4176 /// arguments: DIM, ndof_o, nquad_o
4177 MFEM_REGISTER_KERNELS(ApplyPAKernels, ApplyKernelType, (int, int, int));
4178 /// arguments: DIM, ndof_o, nquad_o
4179 MFEM_REGISTER_KERNELS(ApplyTPAKernels, ApplyKernelType, (int, int, int));
4180
4181 template <int DIM, int NDOF_O, int NQUAD_O> static void AddSpecialization()
4182 {
4183 ApplyPAKernels::Specialization<DIM, NDOF_O, NQUAD_O>::Add();
4184 ApplyTPAKernels::Specialization<DIM, NDOF_O, NQUAD_O>::Add();
4185 }
4186
4187 struct Kernels { Kernels(); };
4188};
4189
4190
4191/** Class for constructing the (local) discrete divergence matrix which can
4192 be used as an integrator in a DiscreteLinearOperator object to assemble
4193 the global discrete divergence matrix.
4194
4195 Note: Since the dofs in the L2_FECollection are nodal values, the local
4196 discrete divergence matrix (with an $H(div)$-type domain space) will depend on
4197 the transformation. On the other hand, the local matrix returned by
4198 VectorFEDivergenceIntegrator is independent of the transformation. */
4200{
4201public:
4203 const FiniteElement &ran_fe,
4204 ElementTransformation &Trans,
4205 DenseMatrix &elmat) override
4206 { ran_fe.ProjectDiv(dom_fe, Trans, elmat); }
4207};
4208
4209
4210/** A trace face interpolator class for interpolating the normal component of
4211 the domain space, e.g. vector $H^1$, into the range space, e.g. the trace of
4212 $H(div)$ which uses FiniteElement::INTEGRAL map type. */
4214{
4215public:
4216 void AssembleElementMatrix2(const FiniteElement &dom_fe,
4217 const FiniteElement &ran_fe,
4218 ElementTransformation &Trans,
4219 DenseMatrix &elmat) override;
4220};
4221
4222/** Interpolator of a scalar coefficient multiplied by a scalar field onto
4223 another scalar field. Note that this can produce inaccurate fields unless
4224 the target is sufficiently high order. */
4226{
4227public:
4229
4230 void AssembleElementMatrix2(const FiniteElement &dom_fe,
4231 const FiniteElement &ran_fe,
4232 ElementTransformation &Trans,
4233 DenseMatrix &elmat) override;
4234
4235protected:
4237};
4238
4239/** Interpolator of a scalar coefficient multiplied by a vector field onto
4240 another vector field. Note that this can produce inaccurate fields unless
4241 the target is sufficiently high order. */
4243{
4244public:
4247
4248 void AssembleElementMatrix2(const FiniteElement &dom_fe,
4249 const FiniteElement &ran_fe,
4250 ElementTransformation &Trans,
4251 DenseMatrix &elmat) override;
4252protected:
4254};
4255
4256/** Interpolator of a vector coefficient multiplied by a scalar field onto
4257 another vector field. Note that this can produce inaccurate fields unless
4258 the target is sufficiently high order. */
4260{
4261public:
4264
4265 void AssembleElementMatrix2(const FiniteElement &dom_fe,
4266 const FiniteElement &ran_fe,
4267 ElementTransformation &Trans,
4268 DenseMatrix &elmat) override;
4269protected:
4271};
4272
4273/** Interpolator of the 2D cross product between a vector coefficient and an
4274 $H(curl)$-conforming field onto an $L_2$-conforming field. */
4276{
4277public:
4280
4281 void AssembleElementMatrix2(const FiniteElement &nd_fe,
4282 const FiniteElement &l2_fe,
4283 ElementTransformation &Trans,
4284 DenseMatrix &elmat) override;
4285protected:
4287};
4288
4289/** Interpolator of the cross product between a vector coefficient and an
4290 $H(curl)$-conforming field onto an $H(div)$-conforming field. The range space
4291 can also be vector $L_2$. */
4293{
4294public:
4297
4298 void AssembleElementMatrix2(const FiniteElement &nd_fe,
4299 const FiniteElement &rt_fe,
4300 ElementTransformation &Trans,
4301 DenseMatrix &elmat) override;
4302protected:
4304};
4305
4306/** Interpolator of the inner product between a vector coefficient and an
4307 $H(div)$-conforming field onto an $L_2$-conforming field. The range space can
4308 also be $H^1$. */
4310{
4311public:
4313
4314 void AssembleElementMatrix2(const FiniteElement &rt_fe,
4315 const FiniteElement &l2_fe,
4316 ElementTransformation &Trans,
4317 DenseMatrix &elmat) override;
4318protected:
4320};
4321
4322}
4323#endif
int Append(const T &el)
Append element 'el' to array, resize if necessary.
Definition array.hpp:941
Abstract base class BilinearFormIntegrator.
virtual void AssembleFaceMatrix(const FiniteElement &el1, const FiniteElement &el2, FaceElementTransformations &Trans, DenseMatrix &elmat)
virtual void AssembleEABoundary(const FiniteElementSpace &fes, Vector &ea_data_bdr, const bool add=true)
virtual void AssemblePABoundaryFaces(const FiniteElementSpace &fes)
virtual void AssembleDiagonalPA(Vector &diag)
Assemble diagonal and add it to Vector diag.
void AssembleElementVector(const FiniteElement &el, ElementTransformation &Tr, const Vector &elfun, Vector &elvect) override
Perform the local action of the BilinearFormIntegrator. Note that the default implementation in the b...
virtual void AssemblePAInteriorFaces(const FiniteElementSpace &fes)
virtual void AssembleTraceFaceMatrix(int elem, const FiniteElement &trial_face_fe, const FiniteElement &test_fe, FaceElementTransformations &Trans, DenseMatrix &elmat)
void AssembleFaceVector(const FiniteElement &el1, const FiniteElement &el2, FaceElementTransformations &Tr, const Vector &elfun, Vector &elvect) override
Perform the local action of the BilinearFormIntegrator resulting from a face integral term....
virtual void AssembleEA(const FiniteElementSpace &fes, Vector &emat, const bool add=true)
Method defining element assembly.
virtual void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat)
Given a particular Finite Element computes the element matrix elmat.
virtual void AddMultTransposeMF(const Vector &x, Vector &y) const
void AssembleMF(const FiniteElementSpace &fes) override
Method defining matrix-free assembly.
void AssemblePA(const FiniteElementSpace &fes) override
Method defining partial assembly.
virtual void AssembleDiagonalPA_ADAt(const Vector &D, Vector &diag)
Assemble diagonal of ( is this integrator) and add it to diag.
virtual void AssembleEAInteriorFaces(const FiniteElementSpace &fes, Vector &ea_data_int, Vector &ea_data_ext, const bool add=true)
virtual void ComputeElementFlux(const FiniteElement &el, ElementTransformation &Trans, Vector &u, const FiniteElement &fluxelem, Vector &flux, bool with_coef=true, const IntegrationRule *ir=NULL)
Virtual method required for Zienkiewicz-Zhu type error estimators.
virtual void AddMultTransposePA(const Vector &x, Vector &y) const
Method for partially assembled transposed action.
void AddMultPA(const Vector &x, Vector &y) const override
Method for partially assembled action.
virtual void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat)
BilinearFormIntegrator(const IntegrationRule *ir=NULL)
virtual void AssembleEABoundaryFaces(const FiniteElementSpace &fes, Vector &ea_data_bdr, const bool add=true)
virtual void AssembleDiagonalMF(Vector &diag)
Assemble diagonal and add it to Vector diag.
virtual void AddAbsMultPA(const Vector &x, Vector &y) const
virtual void AssemblePatchMatrix(const int patch, const FiniteElementSpace &fes, SparseMatrix *&smat)
void AssembleFaceGrad(const FiniteElement &el1, const FiniteElement &el2, FaceElementTransformations &Tr, const Vector &elfun, DenseMatrix &elmat) override
Assemble the local action of the gradient of the NonlinearFormIntegrator resulting from a face integr...
void AssembleElementGrad(const FiniteElement &el, ElementTransformation &Tr, const Vector &elfun, DenseMatrix &elmat) override
Assemble the local gradient matrix.
virtual void AssemblePABoundary(const FiniteElementSpace &fes)
virtual void AddMultPAFaceNormalDerivatives(const Vector &x, const Vector &dxdn, Vector &y, Vector &dydn) const
Method for partially assembled action.
virtual bool RequiresFaceNormalDerivatives() const
For bilinear forms on element faces, specifies if the normal derivatives are needed on the faces or j...
virtual real_t ComputeFluxEnergy(const FiniteElement &fluxelem, ElementTransformation &Trans, Vector &flux, Vector *d_energy=NULL)
Virtual method required for Zienkiewicz-Zhu type error estimators.
virtual void AddAbsMultTransposePA(const Vector &x, Vector &y) const
void AddMultMF(const Vector &x, Vector &y) const override
virtual void AddMultNURBSPA(const Vector &x, Vector &y) const
Method for partially assembled action on NURBS patches.
virtual void AssembleNURBSPA(const FiniteElementSpace &fes)
Method defining partial assembly on NURBS patches.
void AssembleFaceMatrix(const FiniteElement &el1, const FiniteElement &el2, FaceElementTransformations &Trans, DenseMatrix &elmat) override
BoundaryMassIntegrator(Coefficient &q)
Base class Coefficients that optionally depend on space and time. These are used by the BilinearFormI...
, negative transpose of ConvectionIntegrator
ConservativeConvectionIntegrator(VectorCoefficient &q, real_t a=1.0)
void AssembleMF(const FiniteElementSpace &fes) override
Method defining matrix-free assembly.
const DofToQuad * maps
Not owned.
MFEM_REGISTER_KERNELS(ApplyPAKernels, ApplyKernelType,(int, int, int))
arguments: DIMS, D1D, Q1D
bool SupportsCeed() const override
Indicates whether this integrator can use a Ceed backend.
static const IntegrationRule & GetRule(const FiniteElement &el, const ElementTransformation &Trans)
void AssembleDiagonalPA(Vector &diag) override
Assemble diagonal and add it to Vector diag.
void AssemblePA(const FiniteElementSpace &) override
Method defining partial assembly.
void AddMultPA(const Vector &, Vector &) const override
Method for partially assembled action.
VectorCoefficient * Q
ConvectionIntegrator(VectorCoefficient &q, real_t a=1.0)
void AssembleElementMatrix(const FiniteElement &, ElementTransformation &, DenseMatrix &) override
Given a particular Finite Element computes the element matrix elmat.
void AddMultMF(const Vector &, Vector &) const override
MFEM_REGISTER_KERNELS(ApplyPATKernels, ApplyKernelType,(int, int, int))
arguments: DIMS, D1D, Q1D
const GeometricFactors * geom
Not owned.
const IntegrationRule * GetDefaultIntegrationRule(const FiniteElement &trial_fe, const FiniteElement &test_fe, const ElementTransformation &trans) const override
Subclasses should override to choose a default integration rule.
void AssembleEA(const FiniteElementSpace &fes, Vector &emat, const bool add) override
Method defining element assembly.
void(*)(const int, const Array< real_t > &, const Array< real_t > &, const Array< real_t > &, const Array< real_t > &, const Vector &, const Vector &, Vector &, const int, const int) ApplyKernelType
arguments: NE, B, G, Bt, Gt, pa_data, x, y, D1D, Q1D
void AddMultTransposePA(const Vector &x, Vector &y) const override
Method for partially assembled transposed action.
void AssembleDiagonalMF(Vector &diag) override
Assemble diagonal and add it to Vector diag.
Integrator for for Nedelec elements.
MFEM_REGISTER_KERNELS(DiagonalPAKernels, DiagonalKernelType,(int, int, int))
parameters: dim, d1d, q1d
void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
const GeometricFactors * geom
Not owned.
void AddAbsMultPA(const Vector &x, Vector &y) const override
void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat) override
Given a particular Finite Element computes the element matrix elmat.
static void AddSpecialization()
void ComputeElementFlux(const FiniteElement &el, ElementTransformation &Trans, Vector &u, const FiniteElement &fluxelem, Vector &flux, bool with_coef, const IntegrationRule *ir=NULL) override
Virtual method required for Zienkiewicz-Zhu type error estimators.
bool symmetric
False if using a nonsymmetric matrix coefficient.
const Coefficient * GetCoefficient() const
void(*)(const int, const int, const bool, const int, const Array< real_t > &, const Array< real_t > &, const Array< real_t > &, const Array< real_t > &, const Vector &, Vector &) DiagonalKernelType
arguments: d1d, q1d, symmetric, ne, Bo, Bc, Go, Gc, pa_data, diag
MFEM_REGISTER_KERNELS(ApplyPAKernels, ApplyKernelType,(int, int, int))
parameters: dim, d1d, q1d
MatrixCoefficient * MQ
void(*)( const int, const int, const bool, const int, const Array< real_t > &, const Array< real_t > &, const Array< real_t > &, const Array< real_t > &, const Array< real_t > &, const Array< real_t > &, const Vector &, const Vector &, Vector &, const bool) ApplyKernelType
real_t ComputeFluxEnergy(const FiniteElement &fluxelem, ElementTransformation &Trans, Vector &flux, Vector *d_energy=NULL) override
Virtual method required for Zienkiewicz-Zhu type error estimators.
const DofToQuad * mapsC
Not owned. DOF-to-quad map, closed.
void AddMultPA(const Vector &x, Vector &y) const override
Method for partially assembled action.
void AssembleDiagonalPA(Vector &diag) override
Assemble diagonal and add it to Vector diag.
const DofToQuad * mapsO
Not owned. DOF-to-quad map, open.
void AssemblePA(const FiniteElementSpace &fes) override
Method defining partial assembly.
DiagonalMatrixCoefficient * DQ
MFEM_REGISTER_KERNELS(ApplyTPAKernels, ApplyKernelType,(int, int, int))
arguments: DIM, ndof_o, nquad_o
void AddMultTransposePA(const Vector &x, Vector &y) const override
Method for partially assembled transposed action.
void AssemblePA(const FiniteElementSpace &dom_fes, const FiniteElementSpace &ran_fes) override
void AddMultPA(const Vector &x, Vector &y) const override
Method for partially assembled action.
static void AddSpecialization()
MFEM_REGISTER_KERNELS(ApplyPAKernels, ApplyKernelType,(int, int, int))
arguments: DIM, ndof_o, nquad_o
void AssemblePA(const FiniteElementSpace &fes) override
Method defining partial assembly.
void(*)(const int ne, const int ndof_o, const int nquad_o, const Vector &pa, const Vector &x, Vector &y) ApplyKernelType
void AssembleElementMatrix2(const FiniteElement &dom_fe, const FiniteElement &ran_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
void PrecomputeMassInverse(class FiniteElementSpace &fes)
Precomputes the inverses (LU factorizations) of the local mass matrices.
void AssembleFaceMatrix(const FiniteElement &el1, const FiniteElement &el2, FaceElementTransformations &Trans, DenseMatrix &elmat) override
DGDiffusionBR2Integrator(class FiniteElementSpace &fes, real_t e=1.0)
bool RequiresFaceNormalDerivatives() const override
For bilinear forms on element faces, specifies if the normal derivatives are needed on the faces or j...
MFEM_REGISTER_KERNELS(ApplyPAKernels, ApplyKernelType,(int, int, int))
arguments: DIM, d1d, q1d
void AssembleFaceMatrix(const FiniteElement &el1, const FiniteElement &el2, FaceElementTransformations &Trans, DenseMatrix &elmat) override
void AssemblePAInteriorFaces(const FiniteElementSpace &fes) override
const IntegrationRule & GetRule(int order, FaceElementTransformations &T)
DGDiffusionIntegrator(const real_t s, const real_t k)
real_t GetPenaltyParameter() const
void AddMultPAFaceNormalDerivatives(const Vector &x, const Vector &dxdn, Vector &y, Vector &dydn) const override
Method for partially assembled action.
void AssemblePABoundaryFaces(const FiniteElementSpace &fes) override
void(*)(const int, const Array< real_t > &, const Array< real_t > &, const Array< real_t > &, const Array< real_t > &, const real_t, const Vector &, const Vector &_, const Vector &, Vector &, Vector &, const int, const int) ApplyKernelType
const DofToQuad * maps
Not owned.
static void AssembleBlock(const int dim, const int row_ndofs, const int col_ndofs, const int row_offset, const int col_offset, const real_t jmatcoef, const Vector &col_nL, const Vector &col_nM, const Vector &row_shape, const Vector &col_shape, const Vector &col_dshape_dnM, const DenseMatrix &col_dshape, DenseMatrix &elmat, DenseMatrix &jmat)
DGElasticityIntegrator(real_t alpha_, real_t kappa_)
void AssembleFaceMatrix(const FiniteElement &el1, const FiniteElement &el2, FaceElementTransformations &Trans, DenseMatrix &elmat) override
DGElasticityIntegrator(Coefficient &lambda_, Coefficient &mu_, real_t alpha_, real_t kappa_)
Solver for the discontinuous Galerkin mass matrix.
Definition dgmassinv.hpp:30
MFEM_REGISTER_KERNELS(ApplyPATKernels, ApplyKernelType,(int, int, int))
arguments: DIM, d1d, q1d
MFEM_REGISTER_KERNELS(ApplyPAKernels, ApplyKernelType,(int, int, int))
arguments: DIM, d1d, q1d
void AddMultPA(const Vector &, Vector &) const override
Method for partially assembled action.
void AssemblePABoundaryFaces(const FiniteElementSpace &fes) override
void AddMultTransposePA(const Vector &x, Vector &y) const override
Method for partially assembled transposed action.
DGTraceIntegrator(real_t a, real_t b)
VectorCoefficient * u
void AssemblePAInteriorFaces(const FiniteElementSpace &fes) override
void(*)(const int, const Array< real_t > &, const Array< real_t > &, const Vector &, const Vector &, Vector &, const int, const int) ApplyKernelType
arguments: nf, B, Bt, pa_data, x, y, dofs1D, quad1D
static const IntegrationRule & GetRule(Geometry::Type geom, int order, const FaceElementTransformations &T)
const FaceGeometricFactors * geom
Not owned.
void AssembleEABoundaryFaces(const FiniteElementSpace &fes, Vector &ea_data_bdr, const bool add) override
void AssembleFaceMatrix(const FiniteElement &el1, const FiniteElement &el2, FaceElementTransformations &Trans, DenseMatrix &elmat) override
void AssembleEAInteriorFaces(const FiniteElementSpace &fes, Vector &ea_data_int, Vector &ea_data_ext, const bool add) override
const DofToQuad * maps
Not owned.
static void AddSpecialization()
Data type dense matrix using column-major storage.
Definition densemat.hpp:24
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
Definition densemat.hpp:125
void SetSubMatrix(const Array< int > &idx, const DenseMatrix &A)
Set (*this)(idx[i],idx[j]) = A(i,j)
Class for integrating where and are scalars.
void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat) override
Given a particular Finite Element computes the element matrix elmat.
void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
DerivativeIntegrator(Coefficient &q, int i)
void AddMultMF(const Vector &, Vector &) const override
real_t ComputeFluxEnergy(const FiniteElement &fluxelem, ElementTransformation &Trans, Vector &flux, Vector *d_energy=NULL) override
Virtual method required for Zienkiewicz-Zhu type error estimators.
void AssemblePatchMatrix(const int patch, const FiniteElementSpace &fes, SparseMatrix *&smat) override
void AddMultNURBSPA(const Vector &, Vector &) const override
Method for partially assembled action on NURBS patches.
DiffusionIntegrator(const IntegrationRule *ir=nullptr)
Construct a diffusion integrator with coefficient Q = 1.
void(*)(const int, const bool, const Array< int > &, const Array< int > &, const Array< int > &, const Array< int > &, const Array< int > &, const Array< real_t > &, const Array< real_t > &, const Array< real_t > &, const Array< real_t > &, const Array< real_t > &, const Array< real_t > &, const Vector &, const Vector &, Vector &, const int, const int) ApplySimplexKernelType
void AssemblePatchPA(const int patch, const FiniteElementSpace &fes)
void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat) override
void AddAbsMultTransposePA(const Vector &, Vector &) const override
void(*)(const int, const bool, const Array< real_t > &, const Array< real_t > &, const Vector &, Vector &, const int, const int) DiagonalKernelType
void AssembleElementVector(const FiniteElement &el, ElementTransformation &Tr, const Vector &elfun, Vector &elvect) override
Perform the local action of the BilinearFormIntegrator.
static const IntegrationRule & GetRule(const FiniteElement &trial_fe, const FiniteElement &test_fe, const bool stroud=false)
MatrixCoefficient * MQ
bool SupportsCeed() const override
Indicates whether this integrator can use a Ceed backend.
void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
void ComputeElementFlux(const FiniteElement &el, ElementTransformation &Trans, Vector &u, const FiniteElement &fluxelem, Vector &flux, bool with_coef=true, const IntegrationRule *ir=NULL) override
Virtual method required for Zienkiewicz-Zhu type error estimators.
void AddMultPA(const Vector &, Vector &) const override
Method for partially assembled action.
MFEM_REGISTER_KERNELS(ApplyPAKernels, ApplyKernelType,(int, int, int))
const IntegrationRule * GetDefaultIntegrationRule(const FiniteElement &trial_fe, const FiniteElement &test_fe, const ElementTransformation &trans) const override
Subclasses should override to choose a default integration rule.
void AssembleDiagonalPA(Vector &diag) override
Assemble diagonal and add it to Vector diag.
static void AddSimplexSpecialization()
MFEM_REGISTER_KERNELS(ApplySimplexPAKernels, ApplySimplexKernelType,(int, int, int))
void AssembleMF(const FiniteElementSpace &fes) override
Method defining matrix-free assembly.
VectorCoefficient * VQ
void AddAbsMultPA(const Vector &, Vector &) const override
void AddMultPatchPA(const int patch, const Vector &x, Vector &y) const
static void AddSpecialization()
void AssembleNURBSPA(const FiniteElementSpace &fes) override
Method defining partial assembly on NURBS patches.
MFEM_REGISTER_KERNELS(DiagonalPAKernels, DiagonalKernelType,(int, int, int))
void AssemblePA(const FiniteElementSpace &fes) override
Method defining partial assembly.
void AddMultTransposePA(const Vector &, Vector &) const override
Method for partially assembled transposed action.
void AssembleDiagonalMF(Vector &diag) override
Assemble diagonal and add it to Vector diag.
void(*)(const int, const bool, const Array< real_t > &, const Array< real_t > &, const Array< real_t > &, const Array< real_t > &, const Vector &, const Vector &, Vector &, const int, const int) ApplyKernelType
void AssembleEA(const FiniteElementSpace &fes, Vector &emat, const bool add) override
Method defining element assembly.
Coefficient * GetCoefficient() const
for Raviart-Thomas elements
void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat) override
Given a particular Finite Element computes the element matrix elmat.
DivDivIntegrator(Coefficient &q, const IntegrationRule *ir=NULL)
void AddMultPA(const Vector &x, Vector &y) const override
Method for partially assembled action.
void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
void AssembleEA(const FiniteElementSpace &fes, Vector &emat, const bool add) override
Method defining element assembly.
const Coefficient * GetCoefficient() const
void AssembleDiagonalPA(Vector &diag) override
Assemble diagonal and add it to Vector diag.
void AssemblePA(const FiniteElementSpace &fes) override
Method defining partial assembly.
void AssembleElementMatrix2(const FiniteElement &dom_fe, const FiniteElement &ran_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
Structure representing the matrices/tensors needed to evaluate (in reference space) the values,...
Definition fe_base.hpp:141
Integrator that computes the PA action of one of the blocks in an ElasticityIntegrator,...
ElasticityComponentIntegrator(ElasticityIntegrator &parent_, int i_, int j_)
Given an ElasticityIntegrator, create an integrator that represents the th component block.
void AssemblePA(const FiniteElementSpace &fes) override
Method defining partial assembly.
void AddMultTransposePA(const Vector &x, Vector &y) const override
Method for partially assembled transposed action.
void AssembleEA(const FiniteElementSpace &fes, Vector &emat, const bool add=true) override
Method defining element assembly.
void AddMultPA(const Vector &x, Vector &y) const override
Method for partially assembled action.
ElasticityIntegrator(Coefficient &m, real_t q_l, real_t q_m)
void AddMultTransposePA(const Vector &x, Vector &y) const override
Method for partially assembled transposed action.
void ComputeElementFlux(const FiniteElement &el, ElementTransformation &Trans, Vector &u, const FiniteElement &fluxelem, Vector &flux, bool with_coef=true, const IntegrationRule *ir=NULL) override
void AddMultPA(const Vector &x, Vector &y) const override
Method for partially assembled action.
void AssemblePA(const FiniteElementSpace &fes) override
Method defining partial assembly.
real_t ComputeFluxEnergy(const FiniteElement &fluxelem, ElementTransformation &Trans, Vector &flux, Vector *d_energy=NULL) override
void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Tr, DenseMatrix &elmat) override
Given a particular Finite Element computes the element matrix elmat.
ElasticityIntegrator(Coefficient &l, Coefficient &m)
void AssembleDiagonalPA(Vector &diag) override
Assemble diagonal and add it to Vector diag.
virtual int OrderW() const =0
Return the order of the determinant of the Jacobian (weight) of the transformation.
A specialized ElementTransformation class representing a face and its two neighboring elements.
Definition eltrans.hpp:750
Structure for storing face geometric factors: coordinates, Jacobians, determinants of the Jacobians,...
Definition mesh.hpp:3173
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition fespace.hpp:210
Abstract class for all finite elements.
Definition fe_base.hpp:294
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
Definition fe_base.cpp:50
virtual void ProjectDiv(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &div) const
Compute the discrete divergence matrix from the given FiniteElement onto 'this' FiniteElement....
Definition fe_base.cpp:185
int GetRangeDim() const
Returns the vector dimension for vector-valued finite elements, which is also the dimension of the in...
Definition fe_base.hpp:387
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
Definition fe_base.hpp:414
void CalcPhysDShape(ElementTransformation &Trans, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in physical space at the poi...
Definition fe_base.cpp:202
int GetDerivType() const
Returns the FiniteElement::DerivType of the element describing the spatial derivative method implemen...
Definition fe_base.hpp:441
virtual void ProjectGrad(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Compute the discrete gradient matrix from the given FiniteElement onto 'this' FiniteElement....
Definition fe_base.cpp:171
int GetDim() const
Returns the reference space dimension for the finite element.
Definition fe_base.hpp:381
int GetRangeType() const
Returns the FiniteElement::RangeType of the element, one of {SCALAR, VECTOR}.
Definition fe_base.hpp:427
int Space() const
Returns the type of FunctionSpace on the element.
Definition fe_base.hpp:424
DerivType
Enumeration for DerivType: defines which derivative method is implemented.
Definition fe_base.hpp:363
@ DIV
Implements CalcDivShape methods.
Definition fe_base.hpp:366
@ NONE
No derivatives implemented.
Definition fe_base.hpp:364
@ CURL
Implements CalcCurlShape methods.
Definition fe_base.hpp:367
@ GRAD
Implements CalcDShape methods.
Definition fe_base.hpp:365
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Given a coefficient and a transformation, compute its projection (approximation) in the local finite ...
Definition fe_base.cpp:136
void CalcPhysDivShape(ElementTransformation &Trans, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in physical space at the po...
Definition fe_base.cpp:68
int GetCurlDim() const
Definition fe_base.hpp:398
virtual void ProjectCurl(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Compute the discrete curl matrix from the given FiniteElement onto 'this' FiniteElement....
Definition fe_base.cpp:178
virtual void CalcPhysCurlShape(ElementTransformation &Trans, DenseMatrix &curl_shape) const
Evaluate the curl of all shape functions of a vector finite element in physical space at the point de...
Definition fe_base.cpp:81
void CalcPhysShape(ElementTransformation &Trans, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in physical space at the point ...
Definition fe_base.cpp:192
@ Pk
Polynomials of order k.
Definition fe_base.hpp:280
Structure for storing mesh geometric factors: coordinates, Jacobians, and determinants of the Jacobia...
Definition mesh.hpp:3119
GradientIntegrator(Coefficient *q_)
void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
static const IntegrationRule & GetRule(const FiniteElement &trial_fe, const FiniteElement &test_fe, const ElementTransformation &Trans)
const IntegrationRule * GetDefaultIntegrationRule(const FiniteElement &trial_fe, const FiniteElement &test_fe, const ElementTransformation &trans) const override
Subclasses should override to choose a default integration rule.
GradientIntegrator(Coefficient &q)
void AddMultTransposePA(const Vector &x, Vector &y) const override
Method for partially assembled transposed action.
void AddMultPA(const Vector &x, Vector &y) const override
Method for partially assembled action.
void AssemblePA(const FiniteElementSpace &trial_fes, const FiniteElementSpace &test_fes) override
void AddMultPA(const Vector &x, Vector &y) const override
Method for partially assembled action.
void AddMultTransposePA(const Vector &x, Vector &y) const override
Method for partially assembled transposed action.
void AssemblePA(const FiniteElementSpace &trial_fes, const FiniteElementSpace &test_fes) override
Setup method for PA data.
void AssembleElementMatrix2(const FiniteElement &h1_fe, const FiniteElement &nd_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
using the "group" FE discretization
void AssembleElementMatrix(const FiniteElement &, ElementTransformation &, DenseMatrix &) override
Given a particular Finite Element computes the element matrix elmat.
GroupConvectionIntegrator(VectorCoefficient &q, real_t a=1.0)
IdentityInterpolator(int vdim_=1)
Construct an identity interpolator.
void AddMultTransposePA(const Vector &x, Vector &y) const override
Method for partially assembled transposed action.
void AddMultPA(const Vector &x, Vector &y) const override
Method for partially assembled action.
void AssemblePA(const FiniteElementSpace &trial_fes, const FiniteElementSpace &test_fes) override
void AssembleElementMatrix2(const FiniteElement &dom_fe, const FiniteElement &ran_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
A class to initialize the size of a Tensor.
Definition dtensor.hpp:57
Class for an integration rule - an Array of IntegrationPoint.
Definition intrules.hpp:96
Container class for integration rules.
Definition intrules.hpp:430
Integrator that inverts the matrix assembled by another integrator.
InverseIntegrator(BilinearFormIntegrator *integ, int own_integ=1)
void SetIntRule(const IntegrationRule *ir) override
Prescribe a fixed IntegrationRule to use, or set to null to let the integrator choose an appropriate ...
void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat) override
Given a particular Finite Element computes the element matrix elmat.
void SetIntRule(const IntegrationRule *ir) override
Prescribe a fixed IntegrationRule to use, or set to null to let the integrator choose an appropriate ...
LumpedIntegrator(BilinearFormIntegrator *bfi_, int own_bfi_=1)
void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat) override
Given a particular Finite Element computes the element matrix elmat.
const FiniteElementSpace * fespace
const FaceGeometricFactors * face_geom
Not owned.
MFEM_REGISTER_KERNELS(DiagonalPAKernels, DiagonalKernelType,(int, int, int))
void AddAbsMultPA(const Vector &, Vector &) const override
MFEM_REGISTER_KERNELS(ApplyPAKernels, ApplyKernelType,(int, int, int))
void AssembleDiagonalMF(Vector &diag) override
Assemble diagonal and add it to Vector diag.
const DofToQuad * maps
Not owned.
void(*)(const int, const Array< real_t > &, const Array< real_t > &, const Vector &, const Vector &, Vector &, const int, const int) ApplyKernelType
void AddMultPA(const Vector &, Vector &) const override
Method for partially assembled action.
void(*)(const int, const Array< real_t > &, const Vector &, Vector &, const int, const int) DiagonalKernelType
void AssembleEA_(Vector &ea, const bool add)
void AssemblePABoundary(const FiniteElementSpace &fes) override
static void AddSimplexSpecialization()
void AssembleMF(const FiniteElementSpace &fes) override
Method defining matrix-free assembly.
void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat) override
static const IntegrationRule & GetRule(const FiniteElement &trial_fe, const FiniteElement &test_fe, const ElementTransformation &Trans, const bool stroud=false)
const IntegrationRule * GetDefaultIntegrationRule(const FiniteElement &trial_fe, const FiniteElement &test_fe, const ElementTransformation &trans) const override
Subclasses should override to choose a default integration rule.
MassIntegrator(const IntegrationRule *ir=nullptr)
MFEM_REGISTER_KERNELS(ApplySimplexPAKernels, ApplySimplexKernelType,(int, int, int))
bool SupportsCeed() const override
Indicates whether this integrator can use a Ceed backend.
void AssembleDiagonalPA(Vector &diag) override
Assemble diagonal and add it to Vector diag.
void AssembleEA(const FiniteElementSpace &fes, Vector &emat, const bool add) override
Method defining element assembly.
void AssemblePA(const FiniteElementSpace &fes) override
Method defining partial assembly.
void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
const GeometricFactors * geom
Not owned.
void AssembleEABoundary(const FiniteElementSpace &fes, Vector &emat, const bool add) override
void AddMultMF(const Vector &, Vector &) const override
void AddMultTransposePA(const Vector &, Vector &) const override
Method for partially assembled transposed action.
void(*)(const int, const Array< int > &, const Array< int > &, const Array< int > &, const Array< int > &, const Array< int > &, const Array< real_t > &, const Array< real_t > &, const Array< real_t > &, const Array< real_t > &, const Array< real_t > &, const Array< real_t > &, const Vector &, const Vector &, Vector &, const int, const int) ApplySimplexKernelType
void AddAbsMultTransposePA(const Vector &, Vector &) const override
static void AddSpecialization()
const Coefficient * GetCoefficient() const
Mesh data type.
Definition mesh.hpp:67
int GetTrialVDim(const FiniteElement &trial_fe) override
int GetTestVDim(const FiniteElement &test_fe) override
MixedCrossCurlCurlIntegrator(VectorCoefficient &vq)
void CalcTestShape(const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &shape) override
void CalcTrialShape(const FiniteElement &trial_fe, ElementTransformation &Trans, DenseMatrix &shape) override
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
const char * FiniteElementTypeFailureMessage() const override
void CalcTrialShape(const FiniteElement &trial_fe, ElementTransformation &Trans, DenseMatrix &shape) override
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
int GetTestVDim(const FiniteElement &test_fe) override
MixedCrossCurlGradIntegrator(VectorCoefficient &vq)
const char * FiniteElementTypeFailureMessage() const override
int GetTrialVDim(const FiniteElement &trial_fe) override
void CalcTestShape(const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &shape) override
const char * FiniteElementTypeFailureMessage() const override
int GetTrialVDim(const FiniteElement &trial_fe) override
MixedCrossCurlIntegrator(VectorCoefficient &vq)
void CalcTrialShape(const FiniteElement &trial_fe, ElementTransformation &Trans, DenseMatrix &shape) override
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
void CalcTrialShape(const FiniteElement &trial_fe, ElementTransformation &Trans, DenseMatrix &shape) override
void CalcTestShape(const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &shape) override
int GetTrialVDim(const FiniteElement &trial_fe) override
MixedCrossGradCurlIntegrator(VectorCoefficient &vq)
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
const char * FiniteElementTypeFailureMessage() const override
int GetTestVDim(const FiniteElement &test_fe) override
MixedCrossGradGradIntegrator(VectorCoefficient &vq)
void CalcTestShape(const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &shape) override
const char * FiniteElementTypeFailureMessage() const override
int GetTrialVDim(const FiniteElement &trial_fe) override
void CalcTrialShape(const FiniteElement &trial_fe, ElementTransformation &Trans, DenseMatrix &shape) override
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
int GetTestVDim(const FiniteElement &test_fe) override
const char * FiniteElementTypeFailureMessage() const override
MixedCrossGradIntegrator(VectorCoefficient &vq)
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
void CalcTrialShape(const FiniteElement &trial_fe, ElementTransformation &Trans, DenseMatrix &shape) override
int GetTrialVDim(const FiniteElement &trial_fe) override
void CalcTestShape(const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &shape) override
MixedCrossProductIntegrator(VectorCoefficient &vq)
void CalcTrialShape(const FiniteElement &trial_fe, ElementTransformation &Trans, DenseMatrix &shape) override
void CalcTestShape(const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &shape) override
const char * FiniteElementTypeFailureMessage() const override
MixedCurlCurlIntegrator(MatrixCoefficient &mq)
int GetTestVDim(const FiniteElement &test_fe) override
int GetTrialVDim(const FiniteElement &trial_fe) override
MixedCurlCurlIntegrator(DiagonalMatrixCoefficient &dq)
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
MixedCurlCurlIntegrator(Coefficient &q)
MixedCurlIntegrator(Coefficient &q)
MixedCurlIntegrator(Coefficient *q_)
void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
void CalcVShape(const FiniteElement &vector_fe, ElementTransformation &Trans, DenseMatrix &shape) override
int GetVDim(const FiniteElement &vector_fe) override
MixedDirectionalDerivativeIntegrator(VectorCoefficient &vq)
const char * FiniteElementTypeFailureMessage() const override
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
MixedDivGradIntegrator(VectorCoefficient &vq)
void CalcShape(const FiniteElement &scalar_fe, ElementTransformation &Trans, Vector &shape) override
void CalcVShape(const FiniteElement &vector_fe, ElementTransformation &Trans, DenseMatrix &shape) override
const char * FiniteElementTypeFailureMessage() const override
int GetVDim(const FiniteElement &vector_fe) override
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
void AddMultTransposePA(const Vector &, Vector &) const override
Method for partially assembled transposed action.
void AssemblePA(const FiniteElementSpace &trial_fes, const FiniteElementSpace &test_fes) override
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
void AddMultPA(const Vector &, Vector &) const override
Method for partially assembled action.
MixedDotProductIntegrator(VectorCoefficient &vq)
const char * FiniteElementTypeFailureMessage() const override
void CalcShape(const FiniteElement &scalar_fe, ElementTransformation &Trans, Vector &shape) override
MixedGradDivIntegrator(VectorCoefficient &vq)
const char * FiniteElementTypeFailureMessage() const override
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
int GetVDim(const FiniteElement &vector_fe) override
void CalcVShape(const FiniteElement &vector_fe, ElementTransformation &Trans, DenseMatrix &shape) override
MixedGradGradIntegrator(DiagonalMatrixCoefficient &dq)
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
MixedGradGradIntegrator(Coefficient &q)
const char * FiniteElementTypeFailureMessage() const override
void CalcTestShape(const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &shape) override
int GetTrialVDim(const FiniteElement &trial_fe) override
MixedGradGradIntegrator(MatrixCoefficient &mq)
void CalcTrialShape(const FiniteElement &trial_fe, ElementTransformation &Trans, DenseMatrix &shape) override
int GetIntegrationOrder(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans) override
int GetTestVDim(const FiniteElement &test_fe) override
MixedScalarCrossCurlIntegrator(VectorCoefficient &vq)
const char * FiniteElementTypeFailureMessage() const override
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
void CalcShape(const FiniteElement &scalar_fe, ElementTransformation &Trans, Vector &shape) override
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
int GetVDim(const FiniteElement &vector_fe) override
void CalcVShape(const FiniteElement &vector_fe, ElementTransformation &Trans, DenseMatrix &shape) override
MixedScalarCrossGradIntegrator(VectorCoefficient &vq)
const char * FiniteElementTypeFailureMessage() const override
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
const char * FiniteElementTypeFailureMessage() const override
void AssemblePA(const FiniteElementSpace &trial_fes, const FiniteElementSpace &test_fes) override
void AddMultPA(const Vector &x, Vector &y) const override
Method for partially assembled action.
MixedScalarCrossProductIntegrator(VectorCoefficient &vq)
void AddMultTransposePA(const Vector &x, Vector &y) const override
Method for partially assembled transposed action.
const DofToQuad * mapsO
Not owned. DOF-to-quad map, open.
const DofToQuad * mapsC
Not owned. DOF-to-quad map, closed.
const char * FiniteElementTypeFailureMessage() const override
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
MixedScalarCurlIntegrator(Coefficient &q)
int GetIntegrationOrder(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans) override
void AddMultTransposePA(const Vector &x, Vector &y) const override
Method for partially assembled transposed action.
void AssemblePA(const FiniteElementSpace &trial_fes, const FiniteElementSpace &test_fes) override
void AddMultPA(const Vector &, Vector &) const override
Method for partially assembled action.
void CalcTrialShape(const FiniteElement &trial_fe, ElementTransformation &Trans, Vector &shape) override
const char * FiniteElementTypeFailureMessage() const override
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
void CalcTrialShape(const FiniteElement &trial_fe, ElementTransformation &Trans, Vector &shape) override
void CalcTrialShape(const FiniteElement &trial_fe, ElementTransformation &Trans, Vector &shape) override
int GetIntegrationOrder(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans) override
const char * FiniteElementTypeFailureMessage() const override
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
virtual const char * FiniteElementTypeFailureMessage() const
virtual bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const
void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
virtual void CalcTestShape(const FiniteElement &test_fe, ElementTransformation &Trans, Vector &shape)
void AssembleElementMatrix(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &elmat) override
Support for use in BilinearForm. Can be used only when appropriate.
virtual void CalcTrialShape(const FiniteElement &trial_fe, ElementTransformation &Trans, Vector &shape)
MixedScalarIntegrator(Coefficient &q)
virtual int GetIntegrationOrder(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans)
MixedScalarMassIntegrator(Coefficient &q)
virtual int GetIntegrationOrder(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans)
virtual const char * FiniteElementTypeFailureMessage() const
virtual bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const
MixedScalarVectorIntegrator(VectorCoefficient &vq, bool transpose_=false, bool cross_2d_=false)
virtual void CalcVShape(const FiniteElement &vector_fe, ElementTransformation &Trans, DenseMatrix &shape_)
void AssembleElementMatrix(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &elmat) override
Support for use in BilinearForm. Can be used only when appropriate.
virtual int GetVDim(const FiniteElement &vector_fe)
void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
virtual void CalcShape(const FiniteElement &scalar_fe, ElementTransformation &Trans, Vector &shape_)
Class for integrating the bilinear form in 2D and where is a vector coefficient is in or ,...
MixedScalarWeakCrossProductIntegrator(VectorCoefficient &vq)
const char * FiniteElementTypeFailureMessage() const override
void AddMultTransposePA(const Vector &x, Vector &y) const override
Method for partially assembled transposed action.
void CalcShape(const FiniteElement &scalar_fe, ElementTransformation &Trans, Vector &shape) override
void AssemblePA(const FiniteElementSpace &trial_fes, const FiniteElementSpace &test_fes) override
void AddMultPA(const Vector &x, Vector &y) const override
Method for partially assembled action.
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
const char * FiniteElementTypeFailureMessage() const override
void CalcShape(const FiniteElement &scalar_fe, ElementTransformation &Trans, Vector &shape) override
MixedScalarWeakCurlCrossIntegrator(VectorCoefficient &vq)
void CalcTestShape(const FiniteElement &test_fe, ElementTransformation &Trans, Vector &shape) override
const char * FiniteElementTypeFailureMessage() const override
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
const char * FiniteElementTypeFailureMessage() const override
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
void CalcTestShape(const FiniteElement &test_fe, ElementTransformation &Trans, Vector &shape) override
MixedScalarWeakDivergenceIntegrator(VectorCoefficient &vq)
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
void CalcVShape(const FiniteElement &vector_fe, ElementTransformation &Trans, DenseMatrix &shape) override
const char * FiniteElementTypeFailureMessage() const override
int GetVDim(const FiniteElement &vector_fe) override
int GetIntegrationOrder(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans) override
const DofToQuad * L2mapsO
Not owned. Scalar open/closed map.
void CalcTestShape(const FiniteElement &test_fe, ElementTransformation &Trans, Vector &shape) override
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
void AssemblePA(const FiniteElementSpace &trial_fes, const FiniteElementSpace &test_fes) override
const DofToQuad * mapsO
Not owned. HDiv open map.
void AddMultPA(const Vector &x, Vector &y) const override
Method for partially assembled action.
const DofToQuad * mapsC
Not owned. HDiv closed map.
const char * FiniteElementTypeFailureMessage() const override
void AddMultTransposePA(const Vector &x, Vector &y) const override
Method for partially assembled transposed action.
void AddMultTransposePA(const Vector &, Vector &) const override
Method for partially assembled transposed action.
void AddMultPA(const Vector &, Vector &) const override
Method for partially assembled action.
int GetTrialVDim(const FiniteElement &trial_fe) override
MixedVectorCurlIntegrator(Coefficient &q)
void CalcTrialShape(const FiniteElement &trial_fe, ElementTransformation &Trans, DenseMatrix &shape) override
const char * FiniteElementTypeFailureMessage() const override
MixedVectorCurlIntegrator(DiagonalMatrixCoefficient &dq)
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
void AssemblePA(const FiniteElementSpace &trial_fes, const FiniteElementSpace &test_fes) override
MixedVectorCurlIntegrator(MatrixCoefficient &mq)
MixedVectorDivergenceIntegrator(VectorCoefficient &vq)
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
void CalcShape(const FiniteElement &scalar_fe, ElementTransformation &Trans, Vector &shape) override
const char * FiniteElementTypeFailureMessage() const override
int GetIntegrationOrder(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans) override
const char * FiniteElementTypeFailureMessage() const override
void AddMultPA(const Vector &, Vector &) const override
Method for partially assembled action.
void AssemblePA(const FiniteElementSpace &trial_fes, const FiniteElementSpace &test_fes) override
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
MixedVectorGradientIntegrator(MatrixCoefficient &mq)
MixedVectorGradientIntegrator(DiagonalMatrixCoefficient &dq)
void AddMultTransposePA(const Vector &, Vector &) const override
Method for partially assembled transposed action.
int GetTrialVDim(const FiniteElement &trial_fe) override
void CalcTrialShape(const FiniteElement &trial_fe, ElementTransformation &Trans, DenseMatrix &shape) override
void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
virtual const char * FiniteElementTypeFailureMessage() const
VectorCoefficient * VQ
void AssembleElementMatrix(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &elmat) override
Support for use in BilinearForm. Can be used only when appropriate.
MixedVectorIntegrator(VectorCoefficient &vq, bool diag=true)
virtual int GetIntegrationOrder(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans)
virtual int GetTestVDim(const FiniteElement &test_fe)
MatrixCoefficient * MQ
virtual void CalcTestShape(const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &shape)
virtual int GetTrialVDim(const FiniteElement &trial_fe)
MixedVectorIntegrator(Coefficient &q)
virtual bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const
virtual void CalcTrialShape(const FiniteElement &trial_fe, ElementTransformation &Trans, DenseMatrix &shape)
DiagonalMatrixCoefficient * DQ
MixedVectorIntegrator(MatrixCoefficient &mq)
MixedVectorMassIntegrator(Coefficient &q)
MixedVectorMassIntegrator(DiagonalMatrixCoefficient &dq)
MixedVectorMassIntegrator(MatrixCoefficient &mq)
MixedVectorProductIntegrator(VectorCoefficient &vq)
void AddMultPA(const Vector &, Vector &) const override
Method for partially assembled action.
int GetTestVDim(const FiniteElement &test_fe) override
void AddMultTransposePA(const Vector &, Vector &) const override
Method for partially assembled transposed action.
MixedVectorWeakCurlIntegrator(DiagonalMatrixCoefficient &dq)
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
MixedVectorWeakCurlIntegrator(MatrixCoefficient &mq)
const char * FiniteElementTypeFailureMessage() const override
void CalcTestShape(const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &shape) override
void AssemblePA(const FiniteElementSpace &trial_fes, const FiniteElementSpace &test_fes) override
int GetTestVDim(const FiniteElement &test_fe) override
void CalcTestShape(const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &shape) override
MixedVectorWeakDivergenceIntegrator(DiagonalMatrixCoefficient &dq)
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
const char * FiniteElementTypeFailureMessage() const override
MixedVectorWeakDivergenceIntegrator(MatrixCoefficient &mq)
void CalcTestShape(const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &shape) override
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
int GetTestVDim(const FiniteElement &test_fe) override
const char * FiniteElementTypeFailureMessage() const override
MixedWeakCurlCrossIntegrator(VectorCoefficient &vq)
MixedWeakDivCrossIntegrator(VectorCoefficient &vq)
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
int GetTestVDim(const FiniteElement &test_fe) override
void CalcTestShape(const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &shape) override
const char * FiniteElementTypeFailureMessage() const override
const char * FiniteElementTypeFailureMessage() const override
MixedWeakGradDotIntegrator(VectorCoefficient &vq)
int GetIntegrationOrder(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans) override
bool VerifyFiniteElementTypes(const FiniteElement &trial_fe, const FiniteElement &test_fe) const override
void CalcShape(const FiniteElement &scalar_fe, ElementTransformation &Trans, Vector &shape) override
NonconservativeDGTraceIntegrator(VectorCoefficient &u, real_t a, real_t b)
NonconservativeDGTraceIntegrator(Coefficient &rho, VectorCoefficient &u, real_t a, real_t b)
NonconservativeDGTraceIntegrator(VectorCoefficient &u, real_t a)
This class is used to express the local action of a general nonlinear finite element operator....
void AssembleElementMatrix2(const FiniteElement &dom_fe, const FiniteElement &ran_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
void AssembleTraceFaceMatrix(int ielem, const FiniteElement &trial_face_fe, const FiniteElement &test_fe, FaceElementTransformations &Trans, DenseMatrix &elmat) override
void AssembleFaceMatrix(const FiniteElement &trial_face_fe, const FiniteElement &test_fe1, const FiniteElement &test_fe2, FaceElementTransformations &Trans, DenseMatrix &elmat) override
void AssembleEAInteriorFaces(const FiniteElementSpace &trial_fes, const FiniteElementSpace &test_fes, Vector &emat, const bool add=true) override
Method defining element assembly for mixed trace integrators.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition operator.hpp:68
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Definition operator.hpp:74
void AssembleElementMatrix2(const FiniteElement &nd_fe, const FiniteElement &l2_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
ScalarCrossProductInterpolator(VectorCoefficient &vc)
void AssembleElementMatrix2(const FiniteElement &dom_fe, const FiniteElement &ran_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
ScalarProductInterpolator(Coefficient &sc)
void AssembleElementMatrix2(const FiniteElement &dom_fe, const FiniteElement &ran_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
Data type sparse matrix.
Definition sparsemat.hpp:51
Integrator defining a sum of multiple Integrators.
void AssembleEABoundaryFaces(const FiniteElementSpace &fes, Vector &ea_data_bdr, const bool add) override
void AddMultTransposePA(const Vector &x, Vector &y) const override
Method for partially assembled transposed action.
void SetIntRule(const IntegrationRule *ir) override
Prescribe a fixed IntegrationRule to use, or set to null to let the integrator choose an appropriate ...
void AddAbsMultTransposePA(const Vector &x, Vector &y) const override
void AddIntegrator(BilinearFormIntegrator *integ)
void AssembleMF(const FiniteElementSpace &fes) override
Method defining matrix-free assembly.
void AddMultMF(const Vector &x, Vector &y) const override
void AssembleEAInteriorFaces(const FiniteElementSpace &fes, Vector &ea_data_int, Vector &ea_data_ext, const bool add) override
void AssembleEA(const FiniteElementSpace &fes, Vector &emat, const bool add) override
Method defining element assembly.
void AssembleDiagonalPA(Vector &diag) override
Assemble diagonal and add it to Vector diag.
void AddMultPA(const Vector &x, Vector &y) const override
Method for partially assembled action.
void AssemblePA(const FiniteElementSpace &fes) override
Method defining partial assembly.
void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
void AssembleFaceMatrix(const FiniteElement &el1, const FiniteElement &el2, FaceElementTransformations &Trans, DenseMatrix &elmat) override
void AssembleDiagonalMF(Vector &diag) override
Assemble diagonal and add it to Vector diag.
void AddAbsMultPA(const Vector &x, Vector &y) const override
void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat) override
Given a particular Finite Element computes the element matrix elmat.
void AssemblePABoundaryFaces(const FiniteElementSpace &fes) override
void AddMultTransposeMF(const Vector &x, Vector &y) const override
SumIntegrator(int own_integs=1)
void AssemblePAInteriorFaces(const FiniteElementSpace &fes) override
void AssembleTraceFaceMatrix(int elem, const FiniteElement &trial_face_fe, const FiniteElement &test_fe, FaceElementTransformations &Trans, DenseMatrix &elmat)
void AssembleTraceFaceMatrix(int elem, const FiniteElement &trial_face_fe, const FiniteElement &test_fe, FaceElementTransformations &Trans, DenseMatrix &elmat)
void AssembleFaceMatrix(const FiniteElement &trial_face_fe, const FiniteElement &test_fe1, const FiniteElement &test_fe2, FaceElementTransformations &Trans, DenseMatrix &elmat) override
void AssembleFaceMatrix(const FiniteElement &el1, const FiniteElement &el2, FaceElementTransformations &Trans, DenseMatrix &elmat) override
void SetIntRule(const IntegrationRule *ir) override
Prescribe a fixed IntegrationRule to use, or set to null to let the integrator choose an appropriate ...
void AssemblePA(const FiniteElementSpace &fes) override
Method defining partial assembly.
void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat) override
Given a particular Finite Element computes the element matrix elmat.
void AddMultTransposePA(const Vector &x, Vector &y) const override
Method for partially assembled transposed action.
TransposeIntegrator(BilinearFormIntegrator *bfi_, int own_bfi_=1)
void AssemblePA(const FiniteElementSpace &trial_fes, const FiniteElementSpace &test_fes) override
void AssemblePABoundaryFaces(const FiniteElementSpace &fes) override
void AssembleEABoundaryFaces(const FiniteElementSpace &fes, Vector &ea_data_bdr, const bool add) override
void AddMultPA(const Vector &x, Vector &y) const override
Method for partially assembled action.
void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
void AssemblePAInteriorFaces(const FiniteElementSpace &fes) override
void AssembleEA(const FiniteElementSpace &fes, Vector &emat, const bool add) override
Method defining element assembly.
void AssembleEAInteriorFaces(const FiniteElementSpace &fes, Vector &ea_data_int, Vector &ea_data_ext, const bool add) override
Base class for vector Coefficients that optionally depend on time and space.
void AssembleElementMatrix2(const FiniteElement &nd_fe, const FiniteElement &rt_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
VectorCrossProductInterpolator(VectorCoefficient &vc)
VectorCurlCurlIntegrator(Coefficient &q)
void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat) override
Assemble an element matrix.
real_t GetElementEnergy(const FiniteElement &el, ElementTransformation &Tr, const Vector &elfun) override
Compute element energy: .
void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat) override
Given a particular Finite Element computes the element matrix elmat.
void AssemblePA(const FiniteElementSpace &fes) override
Method defining partial assembly.
const DofToQuad * maps
Not owned.
void AssembleMF(const FiniteElementSpace &fes) override
Method defining matrix-free assembly.
void AssembleDiagonalMF(Vector &diag) override
Assemble diagonal and add it to Vector diag.
VectorDiffusionIntegrator(const IntegrationRule *ir=nullptr)
void AssembleElementVector(const FiniteElement &el, ElementTransformation &Tr, const Vector &elfun, Vector &elvect) override
Perform the local action of the BilinearFormIntegrator. Note that the default implementation in the b...
MFEM_REGISTER_KERNELS(ApplyPAKernels, ApplyKernelType,(int, int, int, int))
arguments: dim, vdim, d1d, q1d
void(*)(const int, const int, const Array< real_t > &, const Array< real_t > &, const Vector &, const Vector &, Vector &, const int, const int, const int) ApplyKernelType
arguments: ne, coeff_vdim, B, G, pa_data, x, y, d1d, q1d, vdim
void AddMultPA(const Vector &x, Vector &y) const override
Method for partially assembled action.
void AddMultMF(const Vector &x, Vector &y) const override
const GeometricFactors * geom
Not owned.
bool SupportsCeed() const override
Indicates whether this integrator can use a Ceed backend.
void AssembleDiagonalPA(Vector &diag) override
Assemble diagonal and add it to Vector diag.
void AssemblePA(const FiniteElementSpace &trial_fes, const FiniteElementSpace &test_fes) override
void(*)(const int ne, const Array< real_t > &bt, const Array< real_t > &gt, const Array< real_t > &b, const Vector &q, const Vector &x, Vector &y, const int tr_d1d, const int te_d1d, const int q1d) VectorDivergenceAddMultTransposePAType
const IntegrationRule * GetDefaultIntegrationRule(const FiniteElement &trial_fe, const FiniteElement &test_fe, const ElementTransformation &trans) const override
Subclasses should override to choose a default integration rule.
MFEM_REGISTER_KERNELS(VectorDivergenceAddMultPA, VectorDivergenceAddMultPAType,(int, int, int, int))
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)
VectorDivergenceIntegrator(Coefficient &q)
void AddMultPA(const Vector &x, Vector &y) const override
Method for partially assembled action.
void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
void(*)(const int ne, const Array< real_t > &b, const Array< real_t > &g, const Array< real_t > &bt, const Vector &op, const Vector &x, Vector &y, const int tr_d1d, const int te_d1d, const int q1d) VectorDivergenceAddMultPAType
MFEM_REGISTER_KERNELS(VectorDivergenceAddMultTransposePA, VectorDivergenceAddMultTransposePAType,(int, int, int, int))
VectorDivergenceIntegrator(Coefficient *q_)
Integrator for (Q u.n, v.n) for RT elements.
void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat) override
Given a particular Finite Element computes the element matrix elmat.
VectorFECurlIntegrator(Coefficient &q)
void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat) override
Given a particular Finite Element computes the element matrix elmat.
void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
void AddMultPA(const Vector &, Vector &) const override
Method for partially assembled action.
void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
void AddMultTransposePA(const Vector &, Vector &) const override
Method for partially assembled transposed action.
void AssemblePA(const FiniteElementSpace &trial_fes, const FiniteElementSpace &test_fes) override
void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat) override
Given a particular Finite Element computes the element matrix elmat.
void AssembleDiagonalPA_ADAt(const Vector &D, Vector &diag) override
Assemble diagonal of ( is this integrator) and add it to diag.
void AddMultPA(const Vector &x, Vector &y) const override
Method for partially assembled action.
VectorFEMassIntegrator(DiagonalMatrixCoefficient *dq_)
void AssembleDiagonalPA(Vector &diag) override
Assemble diagonal and add it to Vector diag.
const Coefficient * GetCoefficient() const
VectorFEMassIntegrator(MatrixCoefficient &mq)
void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat) override
Given a particular Finite Element computes the element matrix elmat.
VectorFEMassIntegrator(MatrixCoefficient *mq_)
void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
FiniteElement::DerivType trial_fetype
void AddAbsMultPA(const Vector &x, Vector &y) const override
void(*)(const int NE, bool symmetric, const bool scalar_coeff, const Array< real_t > &trialBO, const Array< real_t > &trialBC, const Array< real_t > &testBOt, const Array< real_t > &testBCt, const Vector &pa_data, const Vector &x, Vector &y, const int triald1d, const int testd1d, const int q1d) ApplyKernelType
VectorFEMassIntegrator(Coefficient *q_)
const DofToQuad * mapsO
Not owned. DOF-to-quad map, open.
void AssembleEA(const FiniteElementSpace &fes, Vector &emat, const bool add) override
Method defining element assembly.
const DofToQuad * mapsOtest
Not owned. DOF-to-quad map, open.
VectorFEMassIntegrator(DiagonalMatrixCoefficient &dq)
VectorFEMassIntegrator(Coefficient &q)
void AssemblePA(const FiniteElementSpace &fes) override
Method defining partial assembly.
FiniteElement::DerivType test_fetype
MFEM_REGISTER_KERNELS(ApplyPAKernels, ApplyKernelType,(FiniteElement::DerivType, FiniteElement::DerivType, int, int, int, int))
parameters: trial_fetype, test_fetype, ndims, trial_d1d, test_d1d, q1d
bool symmetric
False if using a nonsymmetric matrix coefficient.
void AddMultTransposePA(const Vector &x, Vector &y) const override
Method for partially assembled transposed action.
DiagonalMatrixCoefficient * DQ
const DofToQuad * mapsCtest
Not owned. DOF-to-quad map, closed.
const GeometricFactors * geom
Not owned.
const DofToQuad * mapsC
Not owned. DOF-to-quad map, closed.
void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat) override
Given a particular Finite Element computes the element matrix elmat.
void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
Class identical to IdentityInterpolator with the exception that it requires the vector dimension (num...
void AssembleElementMatrix2(const FiniteElement &rt_fe, const FiniteElement &l2_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
VectorInnerProductInterpolator(VectorCoefficient &vc)
VectorCoefficient * VQ
void AssembleMF(const FiniteElementSpace &fes) override
Method defining matrix-free assembly.
void AssembleDiagonalPA(Vector &diag) override
Assemble diagonal and add it to Vector diag.
MFEM_REGISTER_KERNELS(VectorMassAddMultPA, VectorMassAddMultPAType,(int, int, int))
void AddMultMF(const Vector &x, Vector &y) const override
const DofToQuad * maps
Not owned.
void(*)(const int, const int, const int, const real_t *, const real_t *, real_t *) VectorMassAssembleDiagonalPAType
VectorMassIntegrator(VectorCoefficient &q, int qo=0)
Construct an integrator with diagonal coefficient q.
VectorMassIntegrator(Coefficient &q, int qo=0)
void AddMultPA(const Vector &x, Vector &y) const override
Method for partially assembled action.
void AssembleDiagonalMF(Vector &diag) override
Assemble diagonal and add it to Vector diag.
void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
VectorMassIntegrator()=default
Construct an integrator with coefficient 1.0.
VectorMassIntegrator(MatrixCoefficient &q, int qo=0)
Construct an integrator with matrix coefficient q.
MatrixCoefficient * MQ
void AssemblePA(const FiniteElementSpace &fes) override
Method defining partial assembly.
VectorMassIntegrator(Coefficient &q, const IntegrationRule *ir)
const GeometricFactors * geom
Not owned.
MFEM_REGISTER_KERNELS(VectorMassAssembleDiagonalPA, VectorMassAssembleDiagonalPAType,(int, int))
void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat) override
Given a particular Finite Element computes the element matrix elmat.
void(*)(const int, const int, const Array< real_t > &, const Vector &, const Vector &, Vector &, const int, const int) VectorMassAddMultPAType
bool SupportsCeed() const override
Indicates whether this integrator can use a Ceed backend.
VectorScalarProductInterpolator(VectorCoefficient &vc)
void AssembleElementMatrix2(const FiniteElement &dom_fe, const FiniteElement &ran_fe, ElementTransformation &Trans, DenseMatrix &elmat) override
Vector data type.
Definition vector.hpp:82
int Size() const
Returns the size of the vector.
Definition vector.hpp:234
real_t * GetData() const
Return a pointer to the beginning of the Vector data.
Definition vector.hpp:243
int dimc
Definition maxwell.cpp:123
int dim
Definition ex24.cpp:53
void trans(const Vector &u, Vector &x)
Definition ex27.cpp:412
real_t b
Definition lissajous.cpp:42
real_t a
Definition lissajous.cpp:41
constexpr int DIM
real_t u(const Vector &xvec)
Definition lor_mms.hpp:22
void add(const Vector &v1, const Vector &v2, Vector &v)
Definition vector.cpp:414
bool DeviceCanUseCeed()
Function that determines if a CEED kernel should be used, based on the current mfem::Device configura...
Definition util.cpp:33
float real_t
Definition config.hpp:46
FaceType
Definition mesh.hpp:49
void Add(const DenseMatrix &A, const DenseMatrix &B, real_t alpha, DenseMatrix &C)
C = A + alpha*B.