MFEM v4.10.0
Finite element discretization library
Loading...
Searching...
No Matches
transfer.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_TRANSFER_HPP
13#define MFEM_TRANSFER_HPP
14
15#include "../linalg/linalg.hpp"
16#include "fespace.hpp"
17
18#ifdef MFEM_USE_MPI
19#include "pfespace.hpp"
20#endif
21
22#include <cstddef>
23
24namespace mfem
25{
26
27/** @brief Base class for transfer algorithms that construct transfer Operator%s
28 between two finite element (FE) spaces. */
29/** Generally, the two FE spaces (domain and range) can be defined on different
30 meshes. */
32{
33protected:
34 FiniteElementSpace &dom_fes; ///< Domain FE space
35 FiniteElementSpace &ran_fes; ///< Range FE space
36
37 /** @brief Desired Operator::Type for the construction of all operators
38 defined by the underlying transfer algorithm. It can be ignored by
39 derived classes. */
41
42 OperatorHandle fw_t_oper; ///< Forward true-dof operator
43 OperatorHandle bw_t_oper; ///< Backward true-dof operator
44
45 bool use_ea;
46
48
49#ifdef MFEM_USE_MPI
51#endif
52 bool Parallel() const
53 {
54#ifndef MFEM_USE_MPI
55 return false;
56#else
57 return parallel;
58#endif
59 }
60
62 FiniteElementSpace &fes_out,
63 const Operator &oper,
64 OperatorHandle &t_oper);
65
66public:
67 /** Construct a transfer algorithm between the domain, @a dom_fes_, and
68 range, @a ran_fes_, FE spaces, d_mt_ will specify memory space for
69 large data structures */
71 FiniteElementSpace &ran_fes_);
72
73 /// Virtual destructor
74 virtual ~GridTransfer() { }
75
76 /** Uses device friendly element assembly versions for L2Projection
77 transfers, L2, H1 FEM spaces currently supported */
78 void UseEA(bool use_ea_) { use_ea = use_ea_;}
79
80 /** Set memory type for large data structures */
81 void SetMemType(MemoryType d_mt_) {d_mt = d_mt_;}
82
83 /** @brief Set the desired Operator::Type for the construction of all
84 operators defined by the underlying transfer algorithm. */
85 /** The default value is Operator::ANY_TYPE which typically corresponds to a
86 matrix-free operator representation. Note that derived classes are not
87 required to support this setting and can ignore it. */
89
90 /** @brief Return an Operator that transfers GridFunction%s from the domain
91 FE space to GridFunction%s in the range FE space. */
92 virtual const Operator &ForwardOperator() = 0;
93
94 /** @brief Return an Operator that transfers GridFunction%s from the range FE
95 space back to GridFunction%s in the domain FE space. */
96 virtual const Operator &BackwardOperator() = 0;
97
98 /** @brief Return an Operator that transfers true-dof Vector%s from the
99 domain FE space to true-dof Vector%s in the range FE space. */
100 /** This method is implemented in the base class, based on ForwardOperator(),
101 however, derived classes can overload the construction, if necessary. */
106
107 /** @brief Return an Operator that transfers true-dof Vector%s from the range
108 FE space back to true-dof Vector%s in the domain FE space. */
109 /** This method is implemented in the base class, based on
110 BackwardOperator(), however, derived classes can overload the
111 construction, if necessary. */
116
117 virtual bool SupportsBackwardsOperator() const { return true; }
118};
119
120
121/** @brief Transfer data between a coarse mesh and an embedded refined mesh
122 using interpolation. */
123/** The forward, coarse-to-fine, transfer uses nodal interpolation. The
124 backward, fine-to-coarse, transfer is defined locally (on a coarse element)
125 as B = (F^t M_f F)^{-1} F^t M_f, where F is the forward transfer matrix, and
126 M_f is a mass matrix on the union of all fine elements comprising the coarse
127 element. Note that the backward transfer operator, B, is a left inverse of
128 the forward transfer operator, F, i.e. B F = I. Both F and B are defined in
129 reference space and do not depend on the actual physical shape of the mesh
130 elements.
131
132 It is assumed that both the coarse and the fine FiniteElementSpace%s use
133 compatible types of elements, e.g. finite elements with the same map-type
134 (VALUE, INTEGRAL, H_DIV, H_CURL - see class FiniteElement). Generally, the
135 FE spaces can have different orders, however, in order for the backward
136 operator to be well-defined, the (local) number of the fine dofs should not
137 be smaller than the number of coarse dofs. */
139{
140protected:
141 BilinearFormIntegrator *mass_integ; ///< Ownership depends on #own_mass_integ
142 bool own_mass_integ; ///< Ownership flag for #mass_integ
143
144 OperatorHandle F; ///< Forward, coarse-to-fine, operator
145 OperatorHandle B; ///< Backward, fine-to-coarse, operator
146
147public:
149 FiniteElementSpace &fine_fes)
150 : GridTransfer(coarse_fes, fine_fes),
151 mass_integ(NULL), own_mass_integ(false)
152 { }
153
155
156 /** @brief Assign a mass integrator to be used in the construction of the
157 backward, fine-to-coarse, transfer operator. */
159 bool own_mass_integ_ = true);
160
161 const Operator &ForwardOperator() override;
162
163 const Operator &BackwardOperator() override;
164};
165
166
168{
170 int order;
171 CoefficientWithOrder() : coeff(nullptr), order(0) { }
172 CoefficientWithOrder(std::nullptr_t) : coeff(nullptr), order(0) { }
173 CoefficientWithOrder(Coefficient &coeff_) : coeff(&coeff_), order(1) { }
175 : coeff(&coeff_), order(order_) { }
176 operator bool() const { return coeff != nullptr; }
177};
178
179/** @brief Transfer data in L2 and H1 finite element spaces between a coarse
180 mesh and an embedded refined mesh using L2 projection. */
181/** The forward, coarse-to-fine, transfer uses L2 projection. The backward,
182 fine-to-coarse, transfer is defined as B = (F^t M_f F)^{-1} F^t M_f, where F
183 is the forward transfer matrix, and M_f is the mass matrix on the coarse
184 element. For L2 spaces, M_f is the mass matrix on the union of all fine
185 elements comprising the coarse element. For H1 spaces, M_f is a diagonal
186 (lumped) mass matrix computed through row-summation. Note that the backward
187 transfer operator, B, is a left inverse of the forward transfer operator, F,
188 i.e. B F = I. Both F and B are defined in physical space and, generally for
189 L2 spaces, vary between different mesh elements.
190
191 This class supports H1 and L2 finite element spaces. Fine meshes are a
192 uniform refinement of the coarse mesh, usually created through
193 Mesh::MakeRefined. Generally, the coarse and fine FE spaces can have
194 different orders, however, in order for the backward operator to be
195 well-defined, the number of fine dofs (in a coarse element) should not be
196 smaller than the number of coarse dofs. */
198{
199 // Must be public due to host device lambdas
200public:
201 /** Abstract class representing projection operator between a high-order
202 finite element space on a coarse mesh, and a low-order finite element
203 space on a refined mesh (LOR). We assume that the low-order space,
204 fes_lor, lives on a mesh obtained by refining the mesh of the high-order
205 space, fes_ho. */
206 class L2Projection : public Operator
207 {
208 public:
209 virtual void Prolongate(const Vector& x, Vector& y) const = 0;
210 virtual void ProlongateTranspose(const Vector& x, Vector& y) const = 0;
211 /// @brief Sets relative tolerance in preconditioned conjugate gradient
212 /// solver.
213 ///
214 /// Only used for H1 spaces.
215 virtual void SetRelTol(real_t p_rtol_) = 0;
216 /// @brief Sets absolute tolerance in preconditioned conjugate gradient
217 /// solver.
218 ///
219 /// Only used for H1 spaces.
220 virtual void SetAbsTol(real_t p_atol_) = 0;
221 protected:
226
230
231 L2Projection(const FiniteElementSpace& fes_ho_,
232 const FiniteElementSpace& fes_lor_,
233 CoefficientWithOrder coeff_ho_,
234 CoefficientWithOrder coeff_lor_,
236
238 const FiniteElementSpace& fes_lor_,
240 : L2Projection(fes_ho_, fes_lor_, nullptr, nullptr, d_mt_) { }
241
242 void BuildHo2Lor(int nel_ho, int nel_lor,
243 const CoarseFineTransformations& cf_tr);
244
245 void ElemMixedMass(Geometry::Type geom, const FiniteElement& fe_ho,
246 const FiniteElement& fe_lor, ElementTransformation* tr_ho,
247 ElementTransformation* tr_lor,
249 DenseMatrix& M_mixed_el) const;
250
251 void ElemMixedEvaluation(Geometry::Type geom, const FiniteElement& fe_ho,
252 const FiniteElement& fe_lor,
254 const IntegrationRule& ir,
255 DenseMatrix& B_L, DenseMatrix& B_H) const;
256 public:
257 /* Returns the Mixed Mass M_LH via device element assembly by building the
258 basis functions and data at the quadrature points. */
259 void MixedMassEA(const FiniteElementSpace& fes_ho_,
260 const FiniteElementSpace& fes_lor_,
261 Vector &M_LH,
263 };
264
265 // Class below must be public as we now have device code
266public:
268 {
269 protected:
274 public:
276 const FiniteElementSpace* fes_lor_,
277 Table* ho2lor_, Vector* M_LH_ea_);
278 void Mult(const Vector& x, Vector& y) const;
279 void MultTranspose(const Vector& x, Vector& y) const;
280 };
281
283 {
284 protected:
287 Vector* ML_inv; // inverse of lumped M_L
288 public:
290 const FiniteElementSpace* fes_lor_,
291 Vector& ML_inv_);
292 void Mult(const Vector& x, Vector& y) const;
293 void MultTranspose(const Vector& x, Vector& y) const;
294 };
295
296 /** Class for projection operator between a L2 high-order finite element
297 space on a coarse mesh, and a L2 low-order finite element space on a
298 refined mesh (LOR). */
300 {
301 /// The restriction and prolongation operators are represented as dense
302 /// elementwise matrices (of potentially different sizes, because of mixed
303 /// meshes or p-refinement). The matrix entries are stored in the R and P
304 /// arrays. The entries of the i'th high-order element are stored at the
305 /// index given by offsets[i].
306 mutable Array<real_t> R, P;
307
308 const bool use_ea;
309
310 public:
312 const FiniteElementSpace& fes_lor_,
313 CoefficientWithOrder coeff_ho_,
314 CoefficientWithOrder coeff_lor_,
315 const bool use_ea_,
317
319 const FiniteElementSpace& fes_lor_,
320 const bool use_ea_,
322 : L2ProjectionL2Space(fes_ho_, fes_lor_, nullptr, nullptr, use_ea_, d_mt_) { }
323
324 /*Same as above but assembles and stores R_ea, P_ea */
326
327 /// Maps <tt>x</tt>, primal field coefficients defined on a coarse mesh
328 /// with a higher order L2 finite element space, to <tt>y</tt>, primal
329 /// field coefficients defined on a refined mesh with a low order L2
330 /// finite element space. Refined mesh should be a uniform refinement of
331 /// the coarse mesh. Coefficients are computed through minimization of L2
332 /// error between the fields.
333 void Mult(const Vector& x, Vector& y) const override;
334
335 /// Perform mult on the device (same as above)
336 void EAMult(const Vector& x, Vector& y) const;
337
338 /// Maps <tt>x</tt>, dual field coefficients defined on a refined mesh
339 /// with a low order L2 finite element space, to <tt>y</tt>, dual field
340 /// coefficients defined on a coarse mesh with a higher order L2 finite
341 /// element space. Refined mesh should be a uniform refinement of the
342 /// coarse mesh. Coefficients are computed through minimization of L2
343 /// error between the primal fields. Note, if the <tt>x</tt>-coefficients
344 /// come from ProlongateTranspose, then mass is conserved.
345 void MultTranspose(const Vector& x, Vector& y) const override;
346
347 void EAMultTranspose(const Vector& x, Vector& y) const;
348
349 /// Maps <tt>x</tt>, primal field coefficients defined on a refined mesh
350 /// with a low order L2 finite element space, to <tt>y</tt>, primal field
351 /// coefficients defined on a coarse mesh with a higher order L2 finite
352 /// element space. Refined mesh should be a uniform refinement of the
353 /// coarse mesh. Coefficients are computed from the mass conservative
354 /// left-inverse prolongation operation. This functionality is also
355 /// provided as an Operator by L2Prolongation.
356 void Prolongate(const Vector& x, Vector& y) const override;
357
358 void EAProlongate(const Vector& x, Vector& y) const;
359
360 /// Maps <tt>x</tt>, dual field coefficients defined on a coarse mesh with
361 /// a higher order L2 finite element space, to <tt>y</tt>, dual field
362 /// coefficients defined on a refined mesh with a low order L2 finite
363 /// element space. Refined mesh should be a uniform refinement of the
364 /// coarse mesh. Coefficients are computed from the transpose of the mass
365 /// conservative left-inverse prolongation operation. This functionality
366 /// is also provided as an Operator by L2Prolongation.
367 void ProlongateTranspose(const Vector& x, Vector& y) const override;
368
369 void EAProlongateTranspose(const Vector& x, Vector& y) const;
370
371 void SetRelTol(real_t p_rtol_) override { } ///< No-op.
372 void SetAbsTol(real_t p_atol_) override { } ///< No-op.
373 };
374
375protected:
376
377 /// Class below must be public as we now have device code
378public:
379
380 /** Projection operator between a H1 high-order finite element space on a
381 coarse mesh, and a H1 low-order finite element space on a refined mesh
382 (LOR). */
384 {
385 const bool use_ea;
386
387 public:
389 const FiniteElementSpace &fes_lor_,
390 CoefficientWithOrder coeff_ho_,
391 CoefficientWithOrder coeff_lor_,
392 const bool use_ea_,
394
396 const FiniteElementSpace& fes_lor_,
397 const bool use_ea_,
399 : L2ProjectionH1Space(fes_ho_, fes_lor_, nullptr, nullptr, use_ea_, d_mt_) { }
400
401#ifdef MFEM_USE_MPI
403 const ParFiniteElementSpace &pfes_lor_,
404 CoefficientWithOrder coeff_ho_,
405 CoefficientWithOrder coeff_lor_,
406 const bool use_ea_,
408
410 const ParFiniteElementSpace& fes_lor_,
411 const bool use_ea_,
413 : L2ProjectionH1Space(fes_ho_, fes_lor_, nullptr, nullptr, use_ea_, d_mt_) { }
414#endif
415 /// Same as above but assembles action of R through 4 parts:
416 /// ( ) inv( lumped(M_L) ), which is a diagonal matrix (essentially a vector)
417 /// ( ) ElementRestrictionOperator for LOR space
418 /// ( ) mixed mass matrix M_{LH}
419 /// ( ) ElementRestrictionOperator for HO space
421
422#ifdef MFEM_USE_MPI
423 void EAL2ProjectionH1Space(const ParFiniteElementSpace &pfes_ho_,
424 const ParFiniteElementSpace &pfes_lor_);
425#endif
426 /// Maps <tt>x</tt>, primal field coefficients defined on a coarse mesh
427 /// with a higher order H1 finite element space, to <tt>y</tt>, primal
428 /// field coefficients defined on a refined mesh with a low order H1
429 /// finite element space. Refined mesh should be a uniform refinement of
430 /// the coarse mesh. Coefficients are computed through minimization of L2
431 /// error between the fields.
432 void Mult(const Vector& x, Vector& y) const override;
433
434 /// Maps <tt>x</tt>, dual field coefficients defined on a refined mesh
435 /// with a low order H1 finite element space, to <tt>y</tt>, dual field
436 /// coefficients defined on a coarse mesh with a higher order H1 finite
437 /// element space. Refined mesh should be a uniform refinement of the
438 /// coarse mesh. Coefficients are computed through minimization of L2
439 /// error between the primal fields. Note, if the <tt>x</tt>-coefficients
440 /// come from ProlongateTranspose, then mass is conserved.
441 void MultTranspose(const Vector& x, Vector& y) const override;
442
443 /// Maps <tt>x</tt>, primal field coefficients defined on a refined mesh
444 /// with a low order H1 finite element space, to <tt>y</tt>, primal field
445 /// coefficients defined on a coarse mesh with a higher order H1 finite
446 /// element space. Refined mesh should be a uniform refinement of the
447 /// coarse mesh. Coefficients are computed from the mass conservative
448 /// left-inverse prolongation operation. This functionality is also
449 /// provided as an Operator by L2Prolongation.
450 void Prolongate(const Vector& x, Vector& y) const override;
451
452 /// Maps <tt>x</tt>, dual field coefficients defined on a coarse mesh with
453 /// a higher order H1 finite element space, to <tt>y</tt>, dual field
454 /// coefficients defined on a refined mesh with a low order H1 finite
455 /// element space. Refined mesh should be a uniform refinement of the
456 /// coarse mesh. Coefficients are computed from the transpose of the mass
457 /// conservative left-inverse prolongation operation. This functionality
458 /// is also provided as an Operator by L2Prolongation.
459 void ProlongateTranspose(const Vector& x, Vector& y) const override;
460
461 /// Returns the inverse of an on-rank lumped mass matrix
462 void LumpedMassInverse(Vector& ML_inv) const;
463
464 void SetRelTol(real_t p_rtol_) override;
465 void SetAbsTol(real_t p_atol_) override;
466
467 protected:
468 /// Sets up the PCG solver (sets parameters, operator, and preconditioner)
469 void SetupPCG();
470
471 /// @brief Computes on-rank R and M_LH matrices. If true, computes mixed mass and/or
472 /// inverse lumped mass matrix error when compared to device implementation.
473 std::pair<std::unique_ptr<SparseMatrix>,
474 std::unique_ptr<SparseMatrix>> ComputeSparseRAndM_LH();
475
476 /// @brief Recovers vector of tdofs given a vector of dofs and a finite
477 /// element space
478 void GetTDofs(const FiniteElementSpace& fes, const Vector& x, Vector& X) const;
479 /// Sets dof values given a vector of tdofs and a finite element space
480 void SetFromTDofs(const FiniteElementSpace& fes,
481 const Vector& X,
482 Vector& x) const;
483 /// @brief Recovers a vector of dual field coefficients on the tdofs given
484 /// a vector of dual coefficients and a finite element space
486 const Vector& x,
487 Vector& X) const;
488 /// @brief Sets dual field coefficients given a vector of dual field
489 /// coefficients on the tdofs and a finite element space
491 const Vector& X,
492 Vector& x) const;
493 /// @brief Fills the vdofs_list array with a list of vdofs for a given
494 /// vdim and a given finite element space
495 void TDofsListByVDim(const FiniteElementSpace& fes,
496 int vdim,
497 Array<int>& vdofs_list) const;
498
499 /// @brief Computes sparsity pattern and initializes R matrix.
500 /// Based on BilinearForm::AllocMat(), except maps between coarse HO
501 /// elements and refined LOR elements.
502 std::unique_ptr<SparseMatrix> AllocR();
503
505 std::unique_ptr<Solver> precon;
506 // The restriction operator is represented as an Operator R. The
507 // prolongation operator is a dense matrix computed as the inverse of (R^T
508 // M_L R), and hence, is not stored.
509 // If element assembly is enabled
510 std::unique_ptr<Operator> R;
511 // Used to compute P = (RT*M_LH)^(-1) M_LH^T
512 std::unique_ptr<Operator> M_LH;
513 // Inverted operator in P = (RT*M_LH)^(-1) M_LH^T. Used to compute P via PCG.
514 std::unique_ptr<Operator> RTxM_LH;
515 // Lumped M_L inverse operator built via EA. Wrapped with restriction maps
516 // to multiply with scalar TDof LOR vectors.
517 std::unique_ptr<Operator> ML_inv_vea;
518 // LDof Mixed mass operator built via EA. Wrapped with restriction maps to send
519 // scalar LDof HO vectors to LDof LOR vectors.
521
522 // Scalar finite element spaces for stored Tdof-to-and-from-LDof maps.
523 std::unique_ptr<FiniteElementSpace> fes_ho_scalar;
524 std::unique_ptr<FiniteElementSpace> fes_lor_scalar;
525 // Element Assembled mixed mass
527 // Element Assembled lumped M_L inverse built via EA. Stores diagonal as a Ldof vector.
529
530#ifdef MFEM_USE_MPI
531 std::unique_ptr<ParFiniteElementSpace> pfes_ho_scalar;
532 std::unique_ptr<ParFiniteElementSpace> pfes_lor_scalar;
534#endif
535
537 };
538
539 /** Mass-conservative prolongation operator going in the opposite direction
540 as L2Projection. This operator is a left inverse to the L2Projection. */
542 {
543 const L2Projection &l2proj;
544
545 public:
547 : Operator(l2proj_.Width(), l2proj_.Height()), l2proj(l2proj_) { }
548 void Mult(const Vector &x, Vector &y) const
549 {
550 l2proj.Prolongate(x, y);
551 }
552 void MultTranspose(const Vector &x, Vector &y) const
553 {
554 l2proj.ProlongateTranspose(x, y);
555 }
556 virtual ~L2Prolongation() { }
557 };
558
559 /// Coefficient for the mixed L2 inner product.
561 /// Coefficient for the low-order L2 inner product.
563 L2Projection *F; ///< Forward, coarse-to-fine, operator
564 L2Prolongation *B; ///< Backward, fine-to-coarse, operator
566
567public:
568 /// Construct the unweighted L2 projection grid transfer.
570 FiniteElementSpace &fine_fes_,
571 bool force_l2_space_ = false,
572 MemoryType d_mt_ = Device::GetHostMemoryType()) // move to method
573 : GridTransfer(coarse_fes_, fine_fes_),
574 coeff_ho(nullptr), coeff_lor(nullptr), F(nullptr), B(nullptr),
575 force_l2_space(force_l2_space_) { }
576
577 /// @brief Construct the weighted L2 projection grid transfer.
578 ///
579 /// The low-order inner product is weighted by @a coeff_lor, and the mixed
580 /// inner product is weighted by @a coeff_ho.
582 FiniteElementSpace &fine_fes_,
583 CoefficientWithOrder coeff_ho_,
584 CoefficientWithOrder coeff_lor_,
585 bool force_l2_space_ = false,
586 MemoryType d_mt_ = Device::GetHostMemoryType()) // move to method
587 : GridTransfer(coarse_fes_, fine_fes_),
588 coeff_ho(coeff_ho_), coeff_lor(coeff_lor_), F(nullptr), B(nullptr),
589 force_l2_space(force_l2_space_) { }
590
592
593 const Operator &ForwardOperator() override;
594
595 const Operator &BackwardOperator() override;
596
597 bool SupportsBackwardsOperator() const override;
598
599private:
600 void BuildF();
601};
602
603/// Matrix-free transfer operator between finite element spaces
605{
606private:
607 Operator* opr;
608
609public:
610 /// Constructs a transfer operator from \p lFESpace to \p hFESpace.
611 /** No matrices are assembled, only the action to a vector is being computed.
612 If both spaces' FE collection pointers are pointing to the same
613 collection, we assume that the grid was refined while keeping the order
614 constant. If the FE collections are different, it is assumed that both
615 spaces are using the same mesh. If the first element of the high-order
616 space is a `TensorBasisElement`, the optimized tensor-product transfers
617 are used. If not, the general transfers used. */
618 TransferOperator(const FiniteElementSpace& lFESpace,
619 const FiniteElementSpace& hFESpace);
620
621 /// Destructor
622 virtual ~TransferOperator();
623
624 /// @brief Interpolation or prolongation of a vector \p x corresponding to
625 /// the coarse space to the vector \p y corresponding to the fine space.
626 void Mult(const Vector& x, Vector& y) const override;
627
628 /// Restriction by applying the transpose of the Mult method.
629 /** The vector \p x corresponding to the fine space is restricted to the
630 vector \p y corresponding to the coarse space. */
631 void MultTranspose(const Vector& x, Vector& y) const override;
632};
633
634/// Matrix-free transfer operator between finite element spaces on the same mesh
636{
637private:
638 const FiniteElementSpace& lFESpace;
639 const FiniteElementSpace& hFESpace;
640 bool isvar_order;
641 bool is_trace_space;
642 bool assembled = false;
643 std::unique_ptr<SparseMatrix> P;
644 std::unique_ptr<Operator> tP;
645
646 std::unique_ptr<SparseMatrix> BuildConformingTransferMatrix() const;
647 std::unique_ptr<Operator> BuildConformingTransferOperator() const;
648
649 void AssembleMatrix();
650
651public:
652 /// @brief Constructs a transfer operator from \p lFESpace to \p hFESpace
653 /// which have different FE collections.
654 /** By default no matrices are assembled, only the action to a vector is
655 being computed. The underlying finite elements need to implement
656 the GetTransferMatrix methods. */
658 const FiniteElementSpace& hFESpace_,
659 bool assemble_matrix = false);
660
661 /** @brief Return the true-dof transfer operator.
662
663 The returned pointer is non-owning; the operator is either this object
664 or a cached operator owned by this PRefinementTransferOperator. The
665 pointer remains valid until this PRefinementTransferOperator is
666 destroyed and must not be deleted by the caller. */
669 {
670 return const_cast<PRefinementTransferOperator*>(this)
672 }
673
674 /// Destructor
676
677 /// @brief Interpolation or prolongation of a vector \p x corresponding to
678 /// the coarse space to the vector \p y corresponding to the fine space.
679 void Mult(const Vector& x, Vector& y) const override;
680
681 /// Restriction by applying the transpose of the Mult method.
682 /** The vector \p x corresponding to the fine space is restricted to the
683 vector \p y corresponding to the coarse space. */
684 void MultTranspose(const Vector& x, Vector& y) const override;
685};
686
687/// @brief Matrix-free transfer operator between finite element spaces on the
688/// same mesh exploiting the tensor product structure of the finite elements
690{
691private:
692 const FiniteElementSpace& lFESpace;
693 const FiniteElementSpace& hFESpace;
694 int dim;
695 int NE;
696 int D1D;
697 int Q1D;
699 Array<real_t> Bt;
700 const Operator* elem_restrict_lex_l;
701 const Operator* elem_restrict_lex_h;
702 Vector mask;
703 mutable Vector localL;
704 mutable Vector localH;
705
706public:
707 /// @brief Constructs a transfer operator from \p lFESpace to \p hFESpace
708 /// which have different FE collections.
709 /** No matrices are assembled, only the action to a vector is being computed.
710 The underlying finite elements need to be of type `TensorBasisElement`. It is
711 also assumed that all the elements in the spaces are of the same type. */
713 const FiniteElementSpace& lFESpace_,
714 const FiniteElementSpace& hFESpace_);
715
716 /// Destructor
718
719 /// @brief Interpolation or prolongation of a vector \p x corresponding to
720 /// the coarse space to the vector \p y corresponding to the fine space.
721 void Mult(const Vector& x, Vector& y) const override;
722
723 /// Restriction by applying the transpose of the Mult method.
724 /** The vector \p x corresponding to the fine space is restricted to the
725 vector \p y corresponding to the coarse space. */
726 void MultTranspose(const Vector& x, Vector& y) const override;
727};
728
729/// @brief Matrix-free transfer operator between finite element spaces working
730/// on true degrees of freedom
732{
733private:
734 const FiniteElementSpace& lFESpace;
735 const FiniteElementSpace& hFESpace;
736 const Operator * P = nullptr;
737 const SparseMatrix * R = nullptr;
738 TransferOperator* localTransferOperator;
739 mutable Vector tmpL;
740 mutable Vector tmpH;
741
742public:
743 /// @brief Constructs a transfer operator working on true degrees of freedom
744 /// from \p lFESpace to \p hFESpace
746 const FiniteElementSpace& hFESpace_);
747
748 /// Destructor
750
751 /// @brief Interpolation or prolongation of a true dof vector \p x to a true
752 /// dof vector \p y.
753 /** The true dof vector \p x corresponding to the coarse space is restricted
754 to the true dof vector \p y corresponding to the fine space. */
755 void Mult(const Vector& x, Vector& y) const override;
756
757 /// Restriction by applying the transpose of the Mult method.
758 /** The true dof vector \p x corresponding to the fine space is restricted to
759 the true dof vector \p y corresponding to the coarse space. */
760 void MultTranspose(const Vector& x, Vector& y) const override;
761};
762
763} // namespace mfem
764
765#endif
Abstract base class BilinearFormIntegrator.
Conjugate gradient method.
Definition solvers.hpp:627
Base class Coefficients that optionally depend on space and time. These are used by the BilinearFormI...
Data type dense matrix using column-major storage.
Definition densemat.hpp:24
static MemoryType GetHostMemoryType()
Get the current Host MemoryType. This is the MemoryType used by most MFEM classes when allocating mem...
Definition device.hpp:289
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
Base class for transfer algorithms that construct transfer Operators between two finite element (FE) ...
Definition transfer.hpp:32
void UseEA(bool use_ea_)
Definition transfer.hpp:78
bool Parallel() const
Definition transfer.hpp:52
virtual ~GridTransfer()
Virtual destructor.
Definition transfer.hpp:74
FiniteElementSpace & dom_fes
Domain FE space.
Definition transfer.hpp:34
OperatorHandle fw_t_oper
Forward true-dof operator.
Definition transfer.hpp:42
FiniteElementSpace & ran_fes
Range FE space.
Definition transfer.hpp:35
virtual const Operator & TrueBackwardOperator()
Return an Operator that transfers true-dof Vectors from the range FE space back to true-dof Vectors i...
Definition transfer.hpp:112
OperatorHandle bw_t_oper
Backward true-dof operator.
Definition transfer.hpp:43
virtual bool SupportsBackwardsOperator() const
Definition transfer.hpp:117
void SetMemType(MemoryType d_mt_)
Definition transfer.hpp:81
MemoryType d_mt
Definition transfer.hpp:47
virtual const Operator & ForwardOperator()=0
Return an Operator that transfers GridFunctions from the domain FE space to GridFunctions in the rang...
void SetOperatorType(Operator::Type type)
Set the desired Operator::Type for the construction of all operators defined by the underlying transf...
Definition transfer.hpp:88
virtual const Operator & BackwardOperator()=0
Return an Operator that transfers GridFunctions from the range FE space back to GridFunctions in the ...
Operator::Type oper_type
Desired Operator::Type for the construction of all operators defined by the underlying transfer algor...
Definition transfer.hpp:40
virtual const Operator & TrueForwardOperator()
Return an Operator that transfers true-dof Vectors from the domain FE space to true-dof Vectors in th...
Definition transfer.hpp:102
const Operator & MakeTrueOperator(FiniteElementSpace &fes_in, FiniteElementSpace &fes_out, const Operator &oper, OperatorHandle &t_oper)
Definition transfer.cpp:35
GridTransfer(FiniteElementSpace &dom_fes_, FiniteElementSpace &ran_fes_)
Definition transfer.cpp:20
Class for an integration rule - an Array of IntegrationPoint.
Definition intrules.hpp:96
Transfer data between a coarse mesh and an embedded refined mesh using interpolation.
Definition transfer.hpp:139
InterpolationGridTransfer(FiniteElementSpace &coarse_fes, FiniteElementSpace &fine_fes)
Definition transfer.hpp:148
BilinearFormIntegrator * mass_integ
Ownership depends on own_mass_integ.
Definition transfer.hpp:141
OperatorHandle F
Forward, coarse-to-fine, operator.
Definition transfer.hpp:144
bool own_mass_integ
Ownership flag for mass_integ.
Definition transfer.hpp:142
const Operator & BackwardOperator() override
Return an Operator that transfers GridFunctions from the range FE space back to GridFunctions in the ...
Definition transfer.cpp:190
OperatorHandle B
Backward, fine-to-coarse, operator.
Definition transfer.hpp:145
void SetMassIntegrator(BilinearFormIntegrator *mass_integ_, bool own_mass_integ_=true)
Assign a mass integrator to be used in the construction of the backward, fine-to-coarse,...
Definition transfer.cpp:147
const Operator & ForwardOperator() override
Return an Operator that transfers GridFunctions from the domain FE space to GridFunctions in the rang...
Definition transfer.cpp:156
void MultTranspose(const Vector &x, Vector &y) const
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
H1SpaceLumpedMassOperator(const FiniteElementSpace *fes_ho_, const FiniteElementSpace *fes_lor_, Vector &ML_inv_)
void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
void MultTranspose(const Vector &x, Vector &y) const
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
H1SpaceMixedMassOperator(const FiniteElementSpace *fes_ho_, const FiniteElementSpace *fes_lor_, Table *ho2lor_, Vector *M_LH_ea_)
Class below must be public as we now have device code.
Definition transfer.hpp:384
void Mult(const Vector &x, Vector &y) const override
void SetFromTDofsTranspose(const FiniteElementSpace &fes, const Vector &X, Vector &x) const
Sets dual field coefficients given a vector of dual field coefficients on the tdofs and a finite elem...
L2ProjectionH1Space(const ParFiniteElementSpace &fes_ho_, const ParFiniteElementSpace &fes_lor_, const bool use_ea_, MemoryType d_mt_=Device::GetHostMemoryType())
Definition transfer.hpp:409
std::unique_ptr< FiniteElementSpace > fes_ho_scalar
Definition transfer.hpp:523
std::unique_ptr< ParFiniteElementSpace > pfes_ho_scalar
Definition transfer.hpp:531
void TDofsListByVDim(const FiniteElementSpace &fes, int vdim, Array< int > &vdofs_list) const
Fills the vdofs_list array with a list of vdofs for a given vdim and a given finite element space.
void SetupPCG()
Sets up the PCG solver (sets parameters, operator, and preconditioner)
void Prolongate(const Vector &x, Vector &y) const override
void GetTDofs(const FiniteElementSpace &fes, const Vector &x, Vector &X) const
Recovers vector of tdofs given a vector of dofs and a finite element space.
void SetFromTDofs(const FiniteElementSpace &fes, const Vector &X, Vector &x) const
Sets dof values given a vector of tdofs and a finite element space.
void GetTDofsTranspose(const FiniteElementSpace &fes, const Vector &x, Vector &X) const
Recovers a vector of dual field coefficients on the tdofs given a vector of dual coefficients and a f...
L2ProjectionH1Space(const FiniteElementSpace &fes_ho_, const FiniteElementSpace &fes_lor_, const bool use_ea_, MemoryType d_mt_=Device::GetHostMemoryType())
Definition transfer.hpp:395
L2ProjectionH1Space(const FiniteElementSpace &fes_ho_, const FiniteElementSpace &fes_lor_, CoefficientWithOrder coeff_ho_, CoefficientWithOrder coeff_lor_, const bool use_ea_, MemoryType d_mt_=Device::GetHostMemoryType())
std::unique_ptr< SparseMatrix > AllocR()
Computes sparsity pattern and initializes R matrix. Based on BilinearForm::AllocMat(),...
void MultTranspose(const Vector &x, Vector &y) const override
void LumpedMassInverse(Vector &ML_inv) const
Returns the inverse of an on-rank lumped mass matrix.
std::unique_ptr< FiniteElementSpace > fes_lor_scalar
Definition transfer.hpp:524
void SetAbsTol(real_t p_atol_) override
Sets absolute tolerance in preconditioned conjugate gradient solver.
void ProlongateTranspose(const Vector &x, Vector &y) const override
std::pair< std::unique_ptr< SparseMatrix >, std::unique_ptr< SparseMatrix > > ComputeSparseRAndM_LH()
Computes on-rank R and M_LH matrices. If true, computes mixed mass and/or inverse lumped mass matrix ...
void SetRelTol(real_t p_rtol_) override
Sets relative tolerance in preconditioned conjugate gradient solver.
std::unique_ptr< ParFiniteElementSpace > pfes_lor_scalar
Definition transfer.hpp:532
void ProlongateTranspose(const Vector &x, Vector &y) const override
L2ProjectionL2Space(const FiniteElementSpace &fes_ho_, const FiniteElementSpace &fes_lor_, const bool use_ea_, MemoryType d_mt_=Device::GetHostMemoryType())
Definition transfer.hpp:318
void EAMultTranspose(const Vector &x, Vector &y) const
void EAProlongate(const Vector &x, Vector &y) const
L2ProjectionL2Space(const FiniteElementSpace &fes_ho_, const FiniteElementSpace &fes_lor_, CoefficientWithOrder coeff_ho_, CoefficientWithOrder coeff_lor_, const bool use_ea_, MemoryType d_mt_=Device::GetHostMemoryType())
Definition transfer.cpp:582
void MultTranspose(const Vector &x, Vector &y) const override
Definition transfer.cpp:961
void EAMult(const Vector &x, Vector &y) const
Perform mult on the device (same as above)
Definition transfer.cpp:941
void SetRelTol(real_t p_rtol_) override
No-op.
Definition transfer.hpp:371
void EAProlongateTranspose(const Vector &x, Vector &y) const
void SetAbsTol(real_t p_atol_) override
No-op.
Definition transfer.hpp:372
void Prolongate(const Vector &x, Vector &y) const override
void Mult(const Vector &x, Vector &y) const override
Definition transfer.cpp:902
L2Projection(const FiniteElementSpace &fes_ho_, const FiniteElementSpace &fes_lor_, CoefficientWithOrder coeff_ho_, CoefficientWithOrder coeff_lor_, MemoryType d_mt_=Device::GetHostMemoryType())
Definition transfer.cpp:232
void BuildHo2Lor(int nel_ho, int nel_lor, const CoarseFineTransformations &cf_tr)
Definition transfer.cpp:241
void MixedMassEA(const FiniteElementSpace &fes_ho_, const FiniteElementSpace &fes_lor_, Vector &M_LH, MemoryType d_mt_=Device::GetHostMemoryType())
Definition transfer.cpp:328
virtual void ProlongateTranspose(const Vector &x, Vector &y) const =0
virtual void SetRelTol(real_t p_rtol_)=0
Sets relative tolerance in preconditioned conjugate gradient solver.
L2Projection(const FiniteElementSpace &fes_ho_, const FiniteElementSpace &fes_lor_, MemoryType d_mt_=Device::GetHostMemoryType())
Definition transfer.hpp:237
void ElemMixedEvaluation(Geometry::Type geom, const FiniteElement &fe_ho, const FiniteElement &fe_lor, IntegrationPointTransformation &ip_tr, const IntegrationRule &ir, DenseMatrix &B_L, DenseMatrix &B_H) const
Definition transfer.cpp:299
void ElemMixedMass(Geometry::Type geom, const FiniteElement &fe_ho, const FiniteElement &fe_lor, ElementTransformation *tr_ho, ElementTransformation *tr_lor, IntegrationPointTransformation &ip_tr, DenseMatrix &M_mixed_el) const
Definition transfer.cpp:261
virtual void SetAbsTol(real_t p_atol_)=0
Sets absolute tolerance in preconditioned conjugate gradient solver.
virtual void Prolongate(const Vector &x, Vector &y) const =0
L2Prolongation(const L2Projection &l2proj_)
Definition transfer.hpp:546
void MultTranspose(const Vector &x, Vector &y) const
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
Definition transfer.hpp:552
void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
Definition transfer.hpp:548
Transfer data in L2 and H1 finite element spaces between a coarse mesh and an embedded refined mesh u...
Definition transfer.hpp:198
L2Projection * F
Forward, coarse-to-fine, operator.
Definition transfer.hpp:563
CoefficientWithOrder coeff_ho
Coefficient for the mixed L2 inner product.
Definition transfer.hpp:560
CoefficientWithOrder coeff_lor
Coefficient for the low-order L2 inner product.
Definition transfer.hpp:562
L2ProjectionGridTransfer(FiniteElementSpace &coarse_fes_, FiniteElementSpace &fine_fes_, CoefficientWithOrder coeff_ho_, CoefficientWithOrder coeff_lor_, bool force_l2_space_=false, MemoryType d_mt_=Device::GetHostMemoryType())
Construct the weighted L2 projection grid transfer.
Definition transfer.hpp:581
const Operator & BackwardOperator() override
Return an Operator that transfers GridFunctions from the range FE space back to GridFunctions in the ...
bool SupportsBackwardsOperator() const override
L2Prolongation * B
Backward, fine-to-coarse, operator.
Definition transfer.hpp:564
const Operator & ForwardOperator() override
Return an Operator that transfers GridFunctions from the domain FE space to GridFunctions in the rang...
L2ProjectionGridTransfer(FiniteElementSpace &coarse_fes_, FiniteElementSpace &fine_fes_, bool force_l2_space_=false, MemoryType d_mt_=Device::GetHostMemoryType())
Construct the unweighted L2 projection grid transfer.
Definition transfer.hpp:569
Pointer to an Operator of a specified type.
Definition handle.hpp:34
Abstract operator.
Definition operator.hpp:27
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
Type
Enumeration defining IDs for some classes derived from Operator.
Definition operator.hpp:319
Matrix-free transfer operator between finite element spaces on the same mesh.
Definition transfer.hpp:636
virtual ~PRefinementTransferOperator()
Destructor.
Definition transfer.hpp:675
void MultTranspose(const Vector &x, Vector &y) const override
Restriction by applying the transpose of the Mult method.
const Operator * GetTrueTransferOperator() const
Definition transfer.hpp:668
PRefinementTransferOperator(const FiniteElementSpace &lFESpace_, const FiniteElementSpace &hFESpace_, bool assemble_matrix=false)
Constructs a transfer operator from lFESpace to hFESpace which have different FE collections.
void Mult(const Vector &x, Vector &y) const override
Interpolation or prolongation of a vector x corresponding to the coarse space to the vector y corresp...
Operator * GetTrueTransferOperator()
Return the true-dof transfer operator.
Abstract parallel finite element space.
Definition pfespace.hpp:31
Data type sparse matrix.
Definition sparsemat.hpp:51
Table stores the connectivity of elements of TYPE I to elements of TYPE II. For example,...
Definition table.hpp:43
Matrix-free transfer operator between finite element spaces on the same mesh exploiting the tensor pr...
Definition transfer.hpp:690
virtual ~TensorProductPRefinementTransferOperator()
Destructor.
Definition transfer.hpp:717
void Mult(const Vector &x, Vector &y) const override
Interpolation or prolongation of a vector x corresponding to the coarse space to the vector y corresp...
TensorProductPRefinementTransferOperator(const FiniteElementSpace &lFESpace_, const FiniteElementSpace &hFESpace_)
Constructs a transfer operator from lFESpace to hFESpace which have different FE collections.
void MultTranspose(const Vector &x, Vector &y) const override
Restriction by applying the transpose of the Mult method.
Matrix-free transfer operator between finite element spaces.
Definition transfer.hpp:605
virtual ~TransferOperator()
Destructor.
void Mult(const Vector &x, Vector &y) const override
Interpolation or prolongation of a vector x corresponding to the coarse space to the vector y corresp...
void MultTranspose(const Vector &x, Vector &y) const override
Restriction by applying the transpose of the Mult method.
TransferOperator(const FiniteElementSpace &lFESpace, const FiniteElementSpace &hFESpace)
Constructs a transfer operator from lFESpace to hFESpace.
Matrix-free transfer operator between finite element spaces working on true degrees of freedom.
Definition transfer.hpp:732
~TrueTransferOperator()
Destructor.
void MultTranspose(const Vector &x, Vector &y) const override
Restriction by applying the transpose of the Mult method.
TrueTransferOperator(const FiniteElementSpace &lFESpace_, const FiniteElementSpace &hFESpace_)
Constructs a transfer operator working on true degrees of freedom from lFESpace to hFESpace.
void Mult(const Vector &x, Vector &y) const override
Interpolation or prolongation of a true dof vector x to a true dof vector y.
Vector data type.
Definition vector.hpp:82
float real_t
Definition config.hpp:46
MemoryType
Memory types supported by MFEM.
Defines the coarse-fine transformations of all fine elements.
Definition ncmesh.hpp:90
CoefficientWithOrder(Coefficient &coeff_)
Definition transfer.hpp:173
CoefficientWithOrder(std::nullptr_t)
Definition transfer.hpp:172
CoefficientWithOrder(Coefficient &coeff_, int order_)
Definition transfer.hpp:174