MFEM  v4.4.0
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
fespace.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2022, 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_FESPACE
13 #define MFEM_FESPACE
14 
15 #include "../config/config.hpp"
16 #include "../linalg/sparsemat.hpp"
17 #include "../mesh/mesh.hpp"
18 #include "fe_coll.hpp"
19 #include "doftrans.hpp"
20 #include "restriction.hpp"
21 #include <iostream>
22 #include <unordered_map>
23 
24 namespace mfem
25 {
26 
27 /** @brief The ordering method used when the number of unknowns per mesh node
28  (vector dimension) is bigger than 1. */
29 class Ordering
30 {
31 public:
32  /// %Ordering methods:
33  enum Type
34  {
35  byNODES, /**< loop first over the nodes (inner loop) then over the vector
36  dimension (outer loop); symbolically it can be represented
37  as: XXX...,YYY...,ZZZ... */
38  byVDIM /**< loop first over the vector dimension (inner loop) then over
39  the nodes (outer loop); symbolically it can be represented
40  as: XYZ,XYZ,XYZ,... */
41  };
42 
43  template <Type Ord>
44  static inline int Map(int ndofs, int vdim, int dof, int vd);
45 
46  template <Type Ord>
47  static void DofsToVDofs(int ndofs, int vdim, Array<int> &dofs);
48 };
49 
50 template <> inline int
51 Ordering::Map<Ordering::byNODES>(int ndofs, int vdim, int dof, int vd)
52 {
53  MFEM_ASSERT(dof < ndofs && -1-dof < ndofs && 0 <= vd && vd < vdim, "");
54  return (dof >= 0) ? dof+ndofs*vd : dof-ndofs*vd;
55 }
56 
57 template <> inline int
58 Ordering::Map<Ordering::byVDIM>(int ndofs, int vdim, int dof, int vd)
59 {
60  MFEM_ASSERT(dof < ndofs && -1-dof < ndofs && 0 <= vd && vd < vdim, "");
61  return (dof >= 0) ? vd+vdim*dof : -1-(vd+vdim*(-1-dof));
62 }
63 
64 
65 /// Constants describing the possible orderings of the DOFs in one element.
67 {
68  /// Native ordering as defined by the FiniteElement.
69  /** This ordering can be used by tensor-product elements when the
70  interpolation from the DOFs to quadrature points does not use the
71  tensor-product structure. */
72  NATIVE,
73  /// Lexicographic ordering for tensor-product FiniteElements.
74  /** This ordering can be used only with tensor-product elements. */
76 };
77 
78 // Forward declarations
79 class NURBSExtension;
80 class BilinearFormIntegrator;
81 class QuadratureSpace;
82 class QuadratureInterpolator;
83 class FaceQuadratureInterpolator;
84 
85 
86 /** @brief Class FiniteElementSpace - responsible for providing FEM view of the
87  mesh, mainly managing the set of degrees of freedom. */
89 {
92  friend void Mesh::Swap(Mesh &, bool);
93  friend class LORBase;
94 
95 protected:
96  /// The mesh that FE space lives on (not owned).
98 
99  /// Associated FE collection (not owned).
101 
102  /// %Vector dimension (number of unknowns per degree of freedom).
103  int vdim;
104 
105  /** Type of ordering of the vector dofs when #vdim > 1.
106  - Ordering::byNODES - first nodes, then vector dimension,
107  - Ordering::byVDIM - first vector dimension, then nodes */
109 
110  /// Number of degrees of freedom. Number of unknowns is #ndofs * #vdim.
111  int ndofs;
112 
113  /** Polynomial order for each element. If empty, all elements are assumed
114  to be of the default order (fec->GetOrder()). */
116 
118  int uni_fdof; ///< # of single face DOFs if all faces uniform; -1 otherwise
119  int *bdofs; ///< internal DOFs of elements if mixed/var-order; NULL otherwise
120 
121  /** Variable order spaces only: DOF assignments for edges and faces, see
122  docs in MakeDofTable. For constant order spaces the tables are empty. */
124  Table var_face_dofs; ///< NOTE: also used for spaces with mixed faces
125 
126  /** Additional data for the var_*_dofs tables: individual variant orders
127  (these are basically alternate J arrays for var_edge/face_dofs). */
129 
130  // precalculated DOFs for each element, boundary element, and face
131  mutable Table *elem_dof; // owned (except in NURBS FE space)
132  mutable Table *elem_fos; // face orientations by element index
133  mutable Table *bdr_elem_dof; // owned (except in NURBS FE space)
134  mutable Table *bdr_elem_fos; // bdr face orientations by bdr element index
135  mutable Table *face_dof; // owned; in var-order space contains variant 0 DOFs
136 
138 
140  int own_ext;
141  mutable Array<int> face_to_be; // NURBS FE space only
142 
145 
146  /** Matrix representing the prolongation from the global conforming dofs to
147  a set of intermediate partially conforming dofs, e.g. the dofs associated
148  with a "cut" space on a non-conforming mesh. */
149  mutable SparseMatrix *cP; // owned
150  /// Conforming restriction matrix such that cR.cP=I.
151  mutable SparseMatrix *cR; // owned
152  /// A version of the conforming restriction matrix for variable-order spaces.
153  mutable SparseMatrix *cR_hp; // owned
154  mutable bool cP_is_set;
155 
156  /// Transformation to apply to GridFunctions after space Update().
158 
159  /// The element restriction operators, see GetElementRestriction().
161  /// The face restriction operators, see GetFaceRestriction().
162  using key_face = std::tuple<bool, ElementDofOrdering, FaceType, L2FaceValues>;
163  struct key_hash
164  {
165  std::size_t operator()(const key_face& k) const
166  {
167  return std::get<0>(k)
168  + 2 * (int)std::get<1>(k)
169  + 4 * (int)std::get<2>(k)
170  + 8 * (int)std::get<3>(k);
171  }
172  };
173  using map_L2F = std::unordered_map<const key_face,FaceRestriction*,key_hash>;
174  mutable map_L2F L2F;
175 
179 
180  /** Update counter, incremented every time the space is constructed/updated.
181  Used by GridFunctions to check if they are up to date with the space. */
182  long sequence;
183 
184  /** Mesh sequence number last seen when constructing the space. The space
185  needs updating if Mesh::GetSequence() is larger than this. */
187 
188  /// True if at least one element order changed (variable-order space only).
190 
191  bool relaxed_hp; // see SetRelaxedHpConformity()
192 
193  void UpdateNURBS();
194 
195  void Construct();
196  void Destroy();
197 
198  void ConstructDoFTrans();
199  void DestroyDoFTrans();
200 
201  void BuildElementToDofTable() const;
202  void BuildBdrElementToDofTable() const;
203  void BuildFaceToDofTable() const;
204 
205  /** @brief Generates partial face_dof table for a NURBS space.
206 
207  The table is only defined for exterior faces that coincide with a
208  boundary. */
209  void BuildNURBSFaceToDofTable() const;
210 
211  /// Bit-mask representing a set of orders needed by an edge/face.
212  typedef std::uint64_t VarOrderBits;
213  static constexpr int MaxVarOrder = 8*sizeof(VarOrderBits) - 1;
214 
215  /// Return the minimum order (least significant bit set) in the bit mask.
216  static int MinOrder(VarOrderBits bits);
217 
218  /// Return element order: internal version of GetElementOrder without checks.
219  int GetElementOrderImpl(int i) const;
220 
221  /** In a variable order space, calculate a bitmask of polynomial orders that
222  need to be represented on each edge and face. */
223  void CalcEdgeFaceVarOrders(Array<VarOrderBits> &edge_orders,
224  Array<VarOrderBits> &face_orders) const;
225 
226  /** Build the table var_edge_dofs (or var_face_dofs) in a variable order
227  space; return total edge/face DOFs. */
228  int MakeDofTable(int ent_dim, const Array<int> &entity_orders,
229  Table &entity_dofs, Array<char> *var_ent_order);
230 
231  /// Search row of a DOF table for a DOF set of size 'ndof', return first DOF.
232  int FindDofs(const Table &var_dof_table, int row, int ndof) const;
233 
234  /** In a variable order space, return edge DOFs associated with a polynomial
235  order that has 'ndof' degrees of freedom. */
236  int FindEdgeDof(int edge, int ndof) const
237  { return FindDofs(var_edge_dofs, edge, ndof); }
238 
239  /// Similar to FindEdgeDof, but used for mixed meshes too.
240  int FindFaceDof(int face, int ndof) const
241  { return FindDofs(var_face_dofs, face, ndof); }
242 
243  int FirstFaceDof(int face, int variant = 0) const
244  { return uni_fdof >= 0 ? face*uni_fdof : var_face_dofs.GetRow(face)[variant];}
245 
246  /// Return number of possible DOF variants for edge/face (var. order spaces).
247  int GetNVariants(int entity, int index) const;
248 
249  /// Helper to encode a sign flip into a DOF index (for Hcurl/Hdiv shapes).
250  static inline int EncodeDof(int entity_base, int idx)
251  { return (idx >= 0) ? (entity_base + idx) : (-1-(entity_base + (-1-idx))); }
252 
253  /// Helpers to remove encoded sign from a DOF
254  static inline int DecodeDof(int dof)
255  { return (dof >= 0) ? dof : (-1 - dof); }
256 
257  static inline int DecodeDof(int dof, double& sign)
258  { return (dof >= 0) ? (sign = 1, dof) : (sign = -1, (-1 - dof)); }
259 
260  /// Helper to get vertex, edge or face DOFs (entity=0,1,2 resp.).
261  int GetEntityDofs(int entity, int index, Array<int> &dofs,
262  Geometry::Type master_geom = Geometry::INVALID,
263  int variant = 0) const;
264 
265  // Get degenerate face DOFs: see explanation in method implementation.
266  int GetDegenerateFaceDofs(int index, Array<int> &dofs,
267  Geometry::Type master_geom, int variant) const;
268 
269  int GetNumBorderDofs(Geometry::Type geom, int order) const;
270 
271  /// Calculate the cP and cR matrices for a nonconforming mesh.
272  void BuildConformingInterpolation() const;
273 
274  static void AddDependencies(SparseMatrix& deps, Array<int>& master_dofs,
275  Array<int>& slave_dofs, DenseMatrix& I,
276  int skipfirst = 0);
277 
278  static bool DofFinalizable(int dof, const Array<bool>& finalized,
279  const SparseMatrix& deps);
280 
281  void AddEdgeFaceDependencies(SparseMatrix &deps, Array<int>& master_dofs,
282  const FiniteElement *master_fe,
283  Array<int> &slave_dofs, int slave_face,
284  const DenseMatrix *pm) const;
285 
286  /// Replicate 'mat' in the vector dimension, according to vdim ordering mode.
287  void MakeVDimMatrix(SparseMatrix &mat) const;
288 
289  /// GridFunction interpolation operator applicable after mesh refinement.
291  {
292  const FiniteElementSpace* fespace;
294  Table* old_elem_dof; // Owned.
295  Table* old_elem_fos; // Owned.
296 
297  Array<DofTransformation*> old_DoFTrans;
298  mutable VDofTransformation old_VDoFTrans;
299 
300  void ConstructDoFTrans();
301 
302  public:
303  /** Construct the operator based on the elem_dof table of the original
304  (coarse) space. The class takes ownership of the table. */
305  RefinementOperator(const FiniteElementSpace* fespace,
306  Table *old_elem_dof/*takes ownership*/,
307  Table *old_elem_fos/*takes ownership*/, int old_ndofs);
308  RefinementOperator(const FiniteElementSpace *fespace,
309  const FiniteElementSpace *coarse_fes);
310  virtual void Mult(const Vector &x, Vector &y) const;
311  virtual void MultTranspose(const Vector &x, Vector &y) const;
312  virtual ~RefinementOperator();
313  };
314 
315  /// Derefinement operator, used by the friend class InterpolationGridTransfer.
317  {
318  const FiniteElementSpace *fine_fes; // Not owned.
320  Table *coarse_elem_dof; // Owned.
321  // Table *coarse_elem_fos; // Owned.
322  Table coarse_to_fine;
323  Array<int> coarse_to_ref_type;
324  Array<Geometry::Type> ref_type_to_geom;
325  Array<int> ref_type_to_fine_elem_offset;
326 
327  public:
329  const FiniteElementSpace *c_fes,
330  BilinearFormIntegrator *mass_integ);
331  virtual void Mult(const Vector &x, Vector &y) const;
332  virtual ~DerefinementOperator();
333  };
334 
335  /** This method makes the same assumptions as the method:
336  void GetLocalRefinementMatrices(
337  const FiniteElementSpace &coarse_fes, Geometry::Type geom,
338  DenseTensor &localP) const
339  which is defined below. It also assumes that the coarse fes and this have
340  the same vector dimension, vdim. */
341  SparseMatrix *RefinementMatrix_main(const int coarse_ndofs,
342  const Table &coarse_elem_dof,
343  const Table *coarse_elem_fos,
344  const DenseTensor localP[]) const;
345 
347  DenseTensor &localP) const;
349  DenseTensor &localR) const;
350 
351  /** Calculate explicit GridFunction interpolation matrix (after mesh
352  refinement). NOTE: consider using the RefinementOperator class instead
353  of the fully assembled matrix, which can take a lot of memory. */
354  SparseMatrix* RefinementMatrix(int old_ndofs, const Table* old_elem_dof,
355  const Table* old_elem_fos);
356 
357  /// Calculate GridFunction restriction matrix after mesh derefinement.
358  SparseMatrix* DerefinementMatrix(int old_ndofs, const Table* old_elem_dof,
359  const Table* old_elem_fos);
360 
361  /** @brief Return in @a localP the local refinement matrices that map
362  between fespaces after mesh refinement. */
363  /** This method assumes that this->mesh is a refinement of coarse_fes->mesh
364  and that the CoarseFineTransformations of this->mesh are set accordingly.
365  Another assumption is that the FEs of this use the same MapType as the FEs
366  of coarse_fes. Finally, it assumes that the spaces this and coarse_fes are
367  NOT variable-order spaces. */
368  void GetLocalRefinementMatrices(const FiniteElementSpace &coarse_fes,
369  Geometry::Type geom,
370  DenseTensor &localP) const;
371 
372  /// Help function for constructors + Load().
373  void Constructor(Mesh *mesh, NURBSExtension *ext,
375  int vdim = 1, int ordering = Ordering::byNODES);
376 
377  /// Updates the internal mesh pointer. @warning @a new_mesh must be
378  /// <b>topologically identical</b> to the existing mesh. Used if the address
379  /// of the Mesh object has changed, e.g. in @a Mesh::Swap.
380  virtual void UpdateMeshPointer(Mesh *new_mesh);
381 
382  /// Resize the elem_order array on mesh change.
383  void UpdateElementOrders();
384 
385  /// @brief Copies the prolongation and restriction matrices from @a fes.
386  ///
387  /// Used for low order preconditioning on non-conforming meshes. If the DOFs
388  /// require a permutation, it will be supplied by non-NULL @a perm. NULL @a
389  /// perm indicates that no permutation is required.
390  virtual void CopyProlongationAndRestriction(const FiniteElementSpace &fes,
391  const Array<int> *perm);
392 
393 public:
394  /** @brief Default constructor: the object is invalid until initialized using
395  the method Load(). */
397 
398  /** @brief Copy constructor: deep copy all data from @a orig except the Mesh,
399  the FiniteElementCollection, ans some derived data. */
400  /** If the @a mesh or @a fec pointers are NULL (default), then the new
401  FiniteElementSpace will reuse the respective pointers from @a orig. If
402  any of these pointers is not NULL, the given pointer will be used instead
403  of the one used by @a orig.
404 
405  @note The objects pointed to by the @a mesh and @a fec parameters must be
406  either the same objects as the ones used by @a orig, or copies of them.
407  Otherwise, the behavior is undefined.
408 
409  @note Derived data objects, such as the conforming prolongation and
410  restriction matrices, and the update operator, will not be copied, even
411  if they are created in the @a orig object. */
412  FiniteElementSpace(const FiniteElementSpace &orig, Mesh *mesh = NULL,
413  const FiniteElementCollection *fec = NULL);
414 
417  int vdim = 1, int ordering = Ordering::byNODES)
418  { Constructor(mesh, NULL, fec, vdim, ordering); }
419 
420  /// Construct a NURBS FE space based on the given NURBSExtension, @a ext.
421  /** @note If the pointer @a ext is NULL, this constructor is equivalent to
422  the standard constructor with the same arguments minus the
423  NURBSExtension, @a ext. */
426  int vdim = 1, int ordering = Ordering::byNODES)
427  { Constructor(mesh, ext, fec, vdim, ordering); }
428 
429  /// Copy assignment not supported
431 
432  /// Returns the mesh
433  inline Mesh *GetMesh() const { return mesh; }
434 
435  const NURBSExtension *GetNURBSext() const { return NURBSext; }
438 
439  bool Conforming() const { return mesh->Conforming() && cP == NULL; }
440  bool Nonconforming() const { return mesh->Nonconforming() || cP != NULL; }
441 
442  /// Sets the order of the i'th finite element.
443  /** By default, all elements are assumed to be of fec->GetOrder(). Once
444  SetElementOrder is called, the space becomes a variable order space. */
445  void SetElementOrder(int i, int p);
446 
447  /// Returns the order of the i'th finite element.
448  int GetElementOrder(int i) const;
449 
450  /// Return the maximum polynomial order.
451  int GetMaxElementOrder() const
452  { return IsVariableOrder() ? elem_order.Max() : fec->GetOrder(); }
453 
454  /// Returns true if the space contains elements of varying polynomial orders.
455  bool IsVariableOrder() const { return elem_order.Size(); }
456 
457  /// The returned SparseMatrix is owned by the FiniteElementSpace.
459 
460  /// The returned SparseMatrix is owned by the FiniteElementSpace.
461  const SparseMatrix *GetConformingRestriction() const;
462 
463  /** Return a version of the conforming restriction matrix for variable-order
464  spaces with complex hp interfaces, where some true DOFs are not owned by
465  any elements and need to be interpolated from higher order edge/face
466  variants (see also @a SetRelaxedHpConformity()). */
467  /// The returned SparseMatrix is owned by the FiniteElementSpace.
469 
470  /// The returned Operator is owned by the FiniteElementSpace.
471  virtual const Operator *GetProlongationMatrix() const
472  { return GetConformingProlongation(); }
473 
474  /// Return an operator that performs the transpose of GetRestrictionOperator
475  /** The returned operator is owned by the FiniteElementSpace. In serial this
476  is the same as GetProlongationMatrix() */
478  { return GetConformingProlongation(); }
479 
480  /// An abstract operator that performs the same action as GetRestrictionMatrix
481  /** In some cases this is an optimized matrix-free implementation. The
482  returned operator is owned by the FiniteElementSpace. */
483  virtual const Operator *GetRestrictionOperator() const
484  { return GetConformingRestriction(); }
485 
486  /// The returned SparseMatrix is owned by the FiniteElementSpace.
487  virtual const SparseMatrix *GetRestrictionMatrix() const
488  { return GetConformingRestriction(); }
489 
490  /// The returned SparseMatrix is owned by the FiniteElementSpace.
491  virtual const SparseMatrix *GetHpRestrictionMatrix() const
492  { return GetHpConformingRestriction(); }
493 
494  /// Return an Operator that converts L-vectors to E-vectors.
495  /** An L-vector is a vector of size GetVSize() which is the same size as a
496  GridFunction. An E-vector represents the element-wise discontinuous
497  version of the FE space.
498 
499  The layout of the E-vector is: ND x VDIM x NE, where ND is the number of
500  degrees of freedom, VDIM is the vector dimension of the FE space, and NE
501  is the number of the mesh elements.
502 
503  The parameter @a e_ordering describes how the local DOFs in each element
504  should be ordered, see ElementDofOrdering.
505 
506  For discontinuous spaces, the element restriction corresponds to a
507  permutation of the degrees of freedom, implemented by the
508  L2ElementRestriction class.
509 
510  The returned Operator is owned by the FiniteElementSpace. */
511  const Operator *GetElementRestriction(ElementDofOrdering e_ordering) const;
512 
513  /// Return an Operator that converts L-vectors to E-vectors on each face.
514  virtual const FaceRestriction *GetFaceRestriction(
515  ElementDofOrdering e_ordering, FaceType,
517 
518  /** @brief Return a QuadratureInterpolator that interpolates E-vectors to
519  quadrature point values and/or derivatives (Q-vectors). */
520  /** An E-vector represents the element-wise discontinuous version of the FE
521  space and can be obtained, for example, from a GridFunction using the
522  Operator returned by GetElementRestriction().
523 
524  All elements will use the same IntegrationRule, @a ir as the target
525  quadrature points. */
527  const IntegrationRule &ir) const;
528 
529  /** @brief Return a QuadratureInterpolator that interpolates E-vectors to
530  quadrature point values and/or derivatives (Q-vectors). */
531  /** An E-vector represents the element-wise discontinuous version of the FE
532  space and can be obtained, for example, from a GridFunction using the
533  Operator returned by GetElementRestriction().
534 
535  The target quadrature points in the elements are described by the given
536  QuadratureSpace, @a qs. */
538  const QuadratureSpace &qs) const;
539 
540  /** @brief Return a FaceQuadratureInterpolator that interpolates E-vectors to
541  quadrature point values and/or derivatives (Q-vectors). */
543  const IntegrationRule &ir, FaceType type) const;
544 
545  /// Returns the polynomial degree of the i'th finite element.
546  /** NOTE: it is recommended to use GetElementOrder in new code. */
547  int GetOrder(int i) const { return GetElementOrder(i); }
548 
549  /** Return the order of an edge. In a variable order space, return the order
550  of a specific variant, or -1 if there are no more variants. */
551  int GetEdgeOrder(int edge, int variant = 0) const;
552 
553  /// Returns the polynomial degree of the i'th face finite element
554  int GetFaceOrder(int face, int variant = 0) const;
555 
556  /// Returns vector dimension.
557  inline int GetVDim() const { return vdim; }
558 
559  /// Returns number of degrees of freedom.
560  inline int GetNDofs() const { return ndofs; }
561 
562  /// Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
563  inline int GetVSize() const { return vdim * ndofs; }
564 
565  /// Return the number of vector true (conforming) dofs.
566  virtual int GetTrueVSize() const { return GetConformingVSize(); }
567 
568  /// Returns the number of conforming ("true") degrees of freedom
569  /// (if the space is on a nonconforming mesh with hanging nodes).
570  int GetNConformingDofs() const;
571 
572  int GetConformingVSize() const { return vdim * GetNConformingDofs(); }
573 
574  /// Return the ordering method.
575  inline Ordering::Type GetOrdering() const { return ordering; }
576 
577  const FiniteElementCollection *FEColl() const { return fec; }
578 
579  /// Number of all scalar vertex dofs
580  int GetNVDofs() const { return nvdofs; }
581  /// Number of all scalar edge-interior dofs
582  int GetNEDofs() const { return nedofs; }
583  /// Number of all scalar face-interior dofs
584  int GetNFDofs() const { return nfdofs; }
585 
586  /// Returns number of vertices in the mesh.
587  inline int GetNV() const { return mesh->GetNV(); }
588 
589  /// Returns number of elements in the mesh.
590  inline int GetNE() const { return mesh->GetNE(); }
591 
592  /// Returns number of faces (i.e. co-dimension 1 entities) in the mesh.
593  /** The co-dimension 1 entities are those that have dimension 1 less than the
594  mesh dimension, e.g. for a 2D mesh, the faces are the 1D entities, i.e.
595  the edges. */
596  inline int GetNF() const { return mesh->GetNumFaces(); }
597 
598  /// Returns number of boundary elements in the mesh.
599  inline int GetNBE() const { return mesh->GetNBE(); }
600 
601  /// Returns the number of faces according to the requested type.
602  /** If type==Boundary returns only the "true" number of boundary faces
603  contrary to GetNBE() that returns "fake" boundary faces associated to
604  visualization for GLVis.
605  Similarly, if type==Interior, the "fake" boundary faces associated to
606  visualization are counted as interior faces. */
607  inline int GetNFbyType(FaceType type) const
608  { return mesh->GetNFbyType(type); }
609 
610  /// Returns the type of element i.
611  inline int GetElementType(int i) const
612  { return mesh->GetElementType(i); }
613 
614  /// Returns the vertices of element i.
615  inline void GetElementVertices(int i, Array<int> &vertices) const
616  { mesh->GetElementVertices(i, vertices); }
617 
618  /// Returns the type of boundary element i.
619  inline int GetBdrElementType(int i) const
620  { return mesh->GetBdrElementType(i); }
621 
622  /// Returns ElementTransformation for the @a i-th element.
624  { return mesh->GetElementTransformation(i); }
625 
626  /** @brief Returns the transformation defining the @a i-th element in the
627  user-defined variable @a ElTr. */
629  { mesh->GetElementTransformation(i, ElTr); }
630 
631  /// Returns ElementTransformation for the @a i-th boundary element.
633  { return mesh->GetBdrElementTransformation(i); }
634 
635  int GetAttribute(int i) const { return mesh->GetAttribute(i); }
636 
637  int GetBdrAttribute(int i) const { return mesh->GetBdrAttribute(i); }
638 
639  /// Returns indices of degrees of freedom of element 'elem'.
640  virtual DofTransformation *GetElementDofs(int elem, Array<int> &dofs) const;
641 
642  /// Returns indices of degrees of freedom for boundary element 'bel'.
643  virtual DofTransformation *GetBdrElementDofs(int bel,
644  Array<int> &dofs) const;
645 
646  /** @brief Returns the indices of the degrees of freedom for the specified
647  face, including the DOFs for the edges and the vertices of the face. */
648  /** In variable order spaces, multiple variants of DOFs can be returned.
649  See @a GetEdgeDofs for more details.
650  @return Order of the selected variant, or -1 if there are no more
651  variants.*/
652  virtual int GetFaceDofs(int face, Array<int> &dofs, int variant = 0) const;
653 
654  /** @brief Returns the indices of the degrees of freedom for the specified
655  edge, including the DOFs for the vertices of the edge. */
656  /** In variable order spaces, multiple sets of DOFs may exist on an edge,
657  corresponding to the different polynomial orders of incident elements.
658  The 'variant' parameter is the zero-based index of the desired DOF set.
659  The variants are ordered from lowest polynomial degree to the highest.
660  @return Order of the selected variant, or -1 if there are no more
661  variants. */
662  int GetEdgeDofs(int edge, Array<int> &dofs, int variant = 0) const;
663 
664  void GetVertexDofs(int i, Array<int> &dofs) const;
665 
666  void GetElementInteriorDofs(int i, Array<int> &dofs) const;
667 
668  void GetFaceInteriorDofs(int i, Array<int> &dofs) const;
669 
670  int GetNumElementInteriorDofs(int i) const;
671 
672  void GetEdgeInteriorDofs(int i, Array<int> &dofs) const;
673 
674  /** @brief Returns the indices of all of the VDofs for the specified
675  dimension 'vd'. */
676  /** The 'ndofs' parameter defines the number of Dofs in the
677  FiniteElementSpace. If 'ndofs' is -1 (the default value), then the
678  number of Dofs is determined by the FiniteElementSpace. */
679  void GetVDofs(int vd, Array<int> &dofs, int ndofs = -1) const;
680 
681  void DofsToVDofs(Array<int> &dofs, int ndofs = -1) const;
682 
683  void DofsToVDofs(int vd, Array<int> &dofs, int ndofs = -1) const;
684 
685  int DofToVDof(int dof, int vd, int ndofs = -1) const;
686 
687  int VDofToDof(int vdof) const
688  { return (ordering == Ordering::byNODES) ? (vdof%ndofs) : (vdof/vdim); }
689 
690  static void AdjustVDofs(Array<int> &vdofs);
691 
692  /// Returns indexes of degrees of freedom in array dofs for i'th element.
693  DofTransformation *GetElementVDofs(int i, Array<int> &vdofs) const;
694 
695  /// Returns indexes of degrees of freedom for i'th boundary element.
696  DofTransformation *GetBdrElementVDofs(int i, Array<int> &vdofs) const;
697 
698  /// Returns indexes of degrees of freedom for i'th face element (2D and 3D).
699  void GetFaceVDofs(int i, Array<int> &vdofs) const;
700 
701  /// Returns indexes of degrees of freedom for i'th edge.
702  void GetEdgeVDofs(int i, Array<int> &vdofs) const;
703 
704  void GetVertexVDofs(int i, Array<int> &vdofs) const;
705 
706  void GetElementInteriorVDofs(int i, Array<int> &vdofs) const;
707 
708  void GetEdgeInteriorVDofs(int i, Array<int> &vdofs) const;
709 
710  /// (@deprecated) Use the Update() method if the space or mesh changed.
711  MFEM_DEPRECATED void RebuildElementToDofTable();
712 
713  /** @brief Reorder the scalar DOFs based on the element ordering.
714 
715  The new ordering is constructed as follows: 1) loop over all elements as
716  ordered in the Mesh; 2) for each element, assign new indices to all of
717  its current DOFs that are still unassigned; the new indices we assign are
718  simply the sequence `0,1,2,...`; if there are any signed DOFs their sign
719  is preserved. */
721 
723 
724  /** @brief Return a reference to the internal Table that stores the lists of
725  scalar dofs, for each mesh element, as returned by GetElementDofs(). */
726  const Table &GetElementToDofTable() const { return *elem_dof; }
727 
728  /** @brief Return a reference to the internal Table that stores the lists of
729  scalar dofs, for each boundary mesh element, as returned by
730  GetBdrElementDofs(). */
732  { if (!bdr_elem_dof) { BuildBdrElementToDofTable(); } return *bdr_elem_dof; }
733 
734  /** @brief Return a reference to the internal Table that stores the lists of
735  scalar dofs, for each face in the mesh, as returned by GetFaceDofs(). In
736  this context, "face" refers to a (dim-1)-dimensional mesh entity. */
737  /** @note In the case of a NURBS space, the rows corresponding to interior
738  faces will be empty. */
739  const Table &GetFaceToDofTable() const
740  { if (!face_dof) { BuildFaceToDofTable(); } return *face_dof; }
741 
742  /** @brief Initialize internal data that enables the use of the methods
743  GetElementForDof() and GetLocalDofForDof(). */
744  void BuildDofToArrays();
745 
746  /// Return the index of the first element that contains dof @a i.
747  /** This method can be called only after setup is performed using the method
748  BuildDofToArrays(). */
749  int GetElementForDof(int i) const { return dof_elem_array[i]; }
750  /// Return the local dof index in the first element that contains dof @a i.
751  /** This method can be called only after setup is performed using the method
752  BuildDofToArrays(). */
753  int GetLocalDofForDof(int i) const { return dof_ldof_array[i]; }
754 
755  /** @brief Returns pointer to the FiniteElement in the FiniteElementCollection
756  associated with i'th element in the mesh object. */
757  virtual const FiniteElement *GetFE(int i) const;
758 
759  /** @brief Returns pointer to the FiniteElement in the FiniteElementCollection
760  associated with i'th boundary face in the mesh object. */
761  const FiniteElement *GetBE(int i) const;
762 
763  /** @brief Returns pointer to the FiniteElement in the FiniteElementCollection
764  associated with i'th face in the mesh object. Faces in this case refer
765  to the MESHDIM-1 primitive so in 2D they are segments and in 1D they are
766  points.*/
767  const FiniteElement *GetFaceElement(int i) const;
768 
769  /** @brief Returns pointer to the FiniteElement in the FiniteElementCollection
770  associated with i'th edge in the mesh object. */
771  const FiniteElement *GetEdgeElement(int i, int variant = 0) const;
772 
773  /// Return the trace element from element 'i' to the given 'geom_type'
774  const FiniteElement *GetTraceElement(int i, Geometry::Type geom_type) const;
775 
776  /** @brief Mark degrees of freedom associated with boundary elements with
777  the specified boundary attributes (marked in 'bdr_attr_is_ess').
778  For spaces with 'vdim' > 1, the 'component' parameter can be used
779  to restricts the marked vDOFs to the specified component. */
780  virtual void GetEssentialVDofs(const Array<int> &bdr_attr_is_ess,
781  Array<int> &ess_vdofs,
782  int component = -1) const;
783 
784  /** @brief Get a list of essential true dofs, ess_tdof_list, corresponding to the
785  boundary attributes marked in the array bdr_attr_is_ess.
786  For spaces with 'vdim' > 1, the 'component' parameter can be used
787  to restricts the marked tDOFs to the specified component. */
788  virtual void GetEssentialTrueDofs(const Array<int> &bdr_attr_is_ess,
789  Array<int> &ess_tdof_list,
790  int component = -1);
791 
792  /** @brief Get a list of all boundary true dofs, @a boundary_dofs. For spaces
793  with 'vdim' > 1, the 'component' parameter can be used to restricts the
794  marked tDOFs to the specified component. Equivalent to
795  FiniteElementSpace::GetEssentialTrueDofs with all boundary attributes
796  marked as essential. */
797  void GetBoundaryTrueDofs(Array<int> &boundary_dofs, int component = -1);
798 
799  /// Convert a Boolean marker array to a list containing all marked indices.
800  static void MarkerToList(const Array<int> &marker, Array<int> &list);
801 
802  /** @brief Convert an array of indices (list) to a Boolean marker array where all
803  indices in the list are marked with the given value and the rest are set
804  to zero. */
805  static void ListToMarker(const Array<int> &list, int marker_size,
806  Array<int> &marker, int mark_val = -1);
807 
808  /** @brief For a partially conforming FE space, convert a marker array (nonzero
809  entries are true) on the partially conforming dofs to a marker array on
810  the conforming dofs. A conforming dofs is marked iff at least one of its
811  dependent dofs is marked. */
812  void ConvertToConformingVDofs(const Array<int> &dofs, Array<int> &cdofs);
813 
814  /** @brief For a partially conforming FE space, convert a marker array (nonzero
815  entries are true) on the conforming dofs to a marker array on the
816  (partially conforming) dofs. A dof is marked iff it depends on a marked
817  conforming dofs, where dependency is defined by the ConformingRestriction
818  matrix; in other words, a dof is marked iff it corresponds to a marked
819  conforming dof. */
820  void ConvertFromConformingVDofs(const Array<int> &cdofs, Array<int> &dofs);
821 
822  /** @brief Generate the global restriction matrix from a discontinuous
823  FE space to the continuous FE space of the same polynomial degree. */
825 
826  /** @brief Generate the global restriction matrix from a discontinuous
827  FE space to the piecewise constant FE space. */
829 
830  /** @brief Construct the restriction matrix from the FE space given by
831  (*this) to the lower degree FE space given by (*lfes) which
832  is defined on the same mesh. */
834 
835  /** @brief Construct and return an Operator that can be used to transfer
836  GridFunction data from @a coarse_fes, defined on a coarse mesh, to @a
837  this FE space, defined on a refined mesh. */
838  /** It is assumed that the mesh of this FE space is a refinement of the mesh
839  of @a coarse_fes and the CoarseFineTransformations returned by the method
840  Mesh::GetRefinementTransforms() of the refined mesh are set accordingly.
841  The Operator::Type of @a T can be set to request an Operator of the set
842  type. Currently, only Operator::MFEM_SPARSEMAT and Operator::ANY_TYPE
843  (matrix-free) are supported. When Operator::ANY_TYPE is requested, the
844  choice of the particular Operator sub-class is left to the method. This
845  method also works in parallel because the transfer operator is local to
846  the MPI task when the input is a synchronized ParGridFunction. */
847  void GetTransferOperator(const FiniteElementSpace &coarse_fes,
848  OperatorHandle &T) const;
849 
850  /** @brief Construct and return an Operator that can be used to transfer
851  true-dof data from @a coarse_fes, defined on a coarse mesh, to @a this FE
852  space, defined on a refined mesh.
853 
854  This method calls GetTransferOperator() and multiplies the result by the
855  prolongation operator of @a coarse_fes on the right, and by the
856  restriction operator of this FE space on the left.
857 
858  The Operator::Type of @a T can be set to request an Operator of the set
859  type. In serial, the supported types are: Operator::MFEM_SPARSEMAT and
860  Operator::ANY_TYPE (matrix-free). In parallel, the supported types are:
861  Operator::Hypre_ParCSR and Operator::ANY_TYPE. Any other type is treated
862  as Operator::ANY_TYPE: the operator representation choice is made by this
863  method. */
864  virtual void GetTrueTransferOperator(const FiniteElementSpace &coarse_fes,
865  OperatorHandle &T) const;
866 
867  /** @brief Reflect changes in the mesh: update number of DOFs, etc. Also, calculate
868  GridFunction transformation operator (unless want_transform is false).
869  Safe to call multiple times, does nothing if space already up to date. */
870  virtual void Update(bool want_transform = true);
871 
872  /// Get the GridFunction update operator.
873  const Operator* GetUpdateOperator() { Update(); return Th.Ptr(); }
874 
875  /// Return the update operator in the given OperatorHandle, @a T.
877 
878  /** @brief Set the ownership of the update operator: if set to false, the
879  Operator returned by GetUpdateOperator() must be deleted outside the
880  FiniteElementSpace. */
881  /** The update operator ownership is automatically reset to true when a new
882  update operator is created by the Update() method. */
883  void SetUpdateOperatorOwner(bool own) { Th.SetOperatorOwner(own); }
884 
885  /// Specify the Operator::Type to be used by the update operators.
886  /** The default type is Operator::ANY_TYPE which leaves the choice to this
887  class. The other currently supported option is Operator::MFEM_SPARSEMAT
888  which is only guaranteed to be honored for a refinement update operator.
889  Any other type will be treated as Operator::ANY_TYPE.
890  @note This operation destroys the current update operator (if owned). */
892 
893  /// Free the GridFunction update operator (if any), to save memory.
894  virtual void UpdatesFinished() { Th.Clear(); }
895 
896  /** Return update counter, similar to Mesh::GetSequence(). Used by
897  GridFunction to check if it is up to date with the space. */
898  long GetSequence() const { return sequence; }
899 
900  /// Return whether or not the space is discontinuous (L2)
901  bool IsDGSpace() const
902  {
903  return dynamic_cast<const L2_FECollection*>(fec) != NULL;
904  }
905 
906  /** In variable order spaces on nonconforming (NC) meshes, this function
907  controls whether strict conformity is enforced in cases where coarse
908  edges/faces have higher polynomial order than their fine NC neighbors.
909  In the default (strict) case, the coarse side polynomial order is
910  reduced to that of the lowest order fine edge/face, so all fine
911  neighbors can interpolate the coarse side exactly. If relaxed == true,
912  some discontinuities in the solution in such cases are allowed and the
913  coarse side is not restricted. For an example, see
914  https://github.com/mfem/mfem/pull/1423#issuecomment-621340392 */
915  void SetRelaxedHpConformity(bool relaxed = true)
916  {
917  relaxed_hp = relaxed;
918  orders_changed = true; // force update
919  Update(false);
920  }
921 
922  /// Save finite element space to output stream @a out.
923  void Save(std::ostream &out) const;
924 
925  /** @brief Read a FiniteElementSpace from a stream. The returned
926  FiniteElementCollection is owned by the caller. */
927  FiniteElementCollection *Load(Mesh *m, std::istream &input);
928 
929  virtual ~FiniteElementSpace();
930 };
931 
932 
933 /// Class representing the storage layout of a QuadratureFunction.
934 /** Multiple QuadratureFunction%s can share the same QuadratureSpace. */
936 {
937 protected:
938  friend class QuadratureFunction; // Uses the element_offsets.
939 
941  int order;
942  int size;
943 
945  int *element_offsets; // scalar offsets; size = number of elements + 1
946 
947  // protected functions
948 
949  // Assuming mesh and order are set, construct the members: int_rule,
950  // element_offsets, and size.
951  void Construct();
952 
953 public:
954  /// Create a QuadratureSpace based on the global rules from #IntRules.
955  QuadratureSpace(Mesh *mesh_, int order_)
956  : mesh(mesh_), order(order_) { Construct(); }
957 
958  /// Read a QuadratureSpace from the stream @a in.
959  QuadratureSpace(Mesh *mesh_, std::istream &in);
960 
961  virtual ~QuadratureSpace() { delete [] element_offsets; }
962 
963  /// Return the total number of quadrature points.
964  int GetSize() const { return size; }
965 
966  /// Return the order of the quadrature rule(s) used by all elements.
967  int GetOrder() const { return order; }
968 
969  /// Returns the mesh
970  inline Mesh *GetMesh() const { return mesh; }
971 
972  /// Returns number of elements in the mesh.
973  inline int GetNE() const { return mesh->GetNE(); }
974 
975  /// Get the IntegrationRule associated with mesh element @a idx.
976  const IntegrationRule &GetElementIntRule(int idx) const
977  { return *int_rule[mesh->GetElementBaseGeometry(idx)]; }
978 
979  /// Write the QuadratureSpace to the stream @a out.
980  void Save(std::ostream &out) const;
981 };
982 
983 inline bool UsesTensorBasis(const FiniteElementSpace& fes)
984 {
985  // TODO: mixed meshes: return true if there is at least one tensor-product
986  // Geometry in the global mesh and the FE collection returns a
987  // TensorBasisElement for that Geometry?
988 
989  // Potential issue: empty local mesh --> no element 0.
990  return dynamic_cast<const mfem::TensorBasisElement *>(fes.GetFE(0))!=nullptr;
991 }
992 
993 }
994 
995 #endif
SparseMatrix * RefinementMatrix(int old_ndofs, const Table *old_elem_dof, const Table *old_elem_fos)
Definition: fespace.cpp:1476
Abstract class for all finite elements.
Definition: fe_base.hpp:235
VDofTransformation VDoFTrans
Definition: fespace.hpp:144
int GetNFbyType(FaceType type) const
Returns the number of faces according to the requested type.
Definition: fespace.hpp:607
Ordering::Type GetOrdering() const
Return the ordering method.
Definition: fespace.hpp:575
int Size() const
Return the logical size of the array.
Definition: array.hpp:138
Abstract base class for LORDiscretization and ParLORDiscretization classes, which construct low-order...
Definition: lor.hpp:22
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
Definition: fespace.hpp:563
void GetVertexVDofs(int i, Array< int > &vdofs) const
Definition: fespace.cpp:324
int GetAttribute(int i) const
Definition: fespace.hpp:635
SparseMatrix * RefinementMatrix_main(const int coarse_ndofs, const Table &coarse_elem_dof, const Table *coarse_elem_fos, const DenseTensor localP[]) const
Definition: fespace.cpp:1389
int GetNDofs() const
Returns number of degrees of freedom.
Definition: fespace.hpp:560
int ndofs
Number of degrees of freedom. Number of unknowns is ndofs * vdim.
Definition: fespace.hpp:111
Class for an integration rule - an Array of IntegrationPoint.
Definition: intrules.hpp:90
int GetBdrAttribute(int i) const
Return the attribute of boundary element i.
Definition: mesh.hpp:1461
int * bdofs
internal DOFs of elements if mixed/var-order; NULL otherwise
Definition: fespace.hpp:119
const Table & GetBdrElementToDofTable() const
Return a reference to the internal Table that stores the lists of scalar dofs, for each boundary mesh...
Definition: fespace.hpp:731
void GetElementInteriorVDofs(int i, Array< int > &vdofs) const
Definition: fespace.cpp:330
int DofToVDof(int dof, int vd, int ndofs=-1) const
Definition: fespace.cpp:251
const SparseMatrix * GetConformingProlongation() const
The returned SparseMatrix is owned by the FiniteElementSpace.
Definition: fespace.cpp:1234
static void AddDependencies(SparseMatrix &deps, Array< int > &master_dofs, Array< int > &slave_dofs, DenseMatrix &I, int skipfirst=0)
Definition: fespace.cpp:758
virtual const Operator * GetRestrictionTransposeOperator() const
Return an operator that performs the transpose of GetRestrictionOperator.
Definition: fespace.hpp:477
virtual void Update(bool want_transform=true)
Reflect changes in the mesh: update number of DOFs, etc. Also, calculate GridFunction transformation ...
Definition: fespace.cpp:3336
bool IsVariableOrder() const
Returns true if the space contains elements of varying polynomial orders.
Definition: fespace.hpp:455
static int Map(int ndofs, int vdim, int dof, int vd)
void GetElementVertices(int i, Array< int > &vertices) const
Returns the vertices of element i.
Definition: fespace.hpp:615
virtual const SparseMatrix * GetHpRestrictionMatrix() const
The returned SparseMatrix is owned by the FiniteElementSpace.
Definition: fespace.hpp:491
SparseMatrix * DerefinementMatrix(int old_ndofs, const Table *old_elem_dof, const Table *old_elem_fos)
Calculate GridFunction restriction matrix after mesh derefinement.
Definition: fespace.cpp:2040
void BuildElementToDofTable() const
Definition: fespace.cpp:342
const IntegrationRule & GetElementIntRule(int idx) const
Get the IntegrationRule associated with mesh element idx.
Definition: fespace.hpp:976
int MakeDofTable(int ent_dim, const Array< int > &entity_orders, Table &entity_dofs, Array< char > *var_ent_order)
Definition: fespace.cpp:2568
void BuildNURBSFaceToDofTable() const
Generates partial face_dof table for a NURBS space.
Definition: fespace.cpp:2266
const FiniteElement * GetEdgeElement(int i, int variant=0) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i&#39;th edge in the ...
Definition: fespace.cpp:3165
DerefinementOperator(const FiniteElementSpace *f_fes, const FiniteElementSpace *c_fes, BilinearFormIntegrator *mass_integ)
TODO: Implement DofTransformation support.
Definition: fespace.cpp:1881
static const int NumGeom
Definition: geom.hpp:42
const FiniteElement * GetTraceElement(int i, Geometry::Type geom_type) const
Return the trace element from element &#39;i&#39; to the given &#39;geom_type&#39;.
Definition: fespace.cpp:3175
Matrix-free transfer operator between finite element spaces on the same mesh.
Definition: transfer.hpp:385
bool Conforming() const
Definition: mesh.hpp:1625
int GetNBE() const
Returns number of boundary elements.
Definition: mesh.hpp:931
Ordering::Type ordering
Definition: fespace.hpp:108
static int DecodeDof(int dof, double &sign)
Definition: fespace.hpp:257
virtual DofTransformation * GetBdrElementDofs(int bel, Array< int > &dofs) const
Returns indices of degrees of freedom for boundary element &#39;bel&#39;.
Definition: fespace.cpp:2814
void SetElementOrder(int i, int p)
Sets the order of the i&#39;th finite element.
Definition: fespace.cpp:151
static int DecodeDof(int dof)
Helpers to remove encoded sign from a DOF.
Definition: fespace.hpp:254
int GetSize() const
Return the total number of quadrature points.
Definition: fespace.hpp:964
static int MinOrder(VarOrderBits bits)
Return the minimum order (least significant bit set) in the bit mask.
Definition: fespace.cpp:2441
Element::Type GetElementType(int i) const
Returns the type of element i.
Definition: mesh.cpp:6197
Pointer to an Operator of a specified type.
Definition: handle.hpp:33
int VDofToDof(int vdof) const
Definition: fespace.hpp:687
static constexpr int MaxVarOrder
Definition: fespace.hpp:213
Element::Type GetBdrElementType(int i) const
Returns the type of boundary element i.
Definition: mesh.cpp:6202
virtual void GetEssentialVDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_vdofs, int component=-1) const
Mark degrees of freedom associated with boundary elements with the specified boundary attributes (mar...
Definition: fespace.cpp:495
Data type dense matrix using column-major storage.
Definition: densemat.hpp:23
int vdim
Vector dimension (number of unknowns per degree of freedom).
Definition: fespace.hpp:103
void GetRow(int i, Array< int > &row) const
Return row i in array row (the Table must be finalized)
Definition: table.cpp:187
OperatorHandle L2E_lex
Definition: fespace.hpp:160
Mesh * GetMesh() const
Returns the mesh.
Definition: fespace.hpp:970
int GetNumElementInteriorDofs(int i) const
Definition: fespace.cpp:3060
int GetElementOrder(int i) const
Returns the order of the i&#39;th finite element.
Definition: fespace.cpp:178
int GetBdrAttribute(int i) const
Definition: fespace.hpp:637
const SparseMatrix * GetHpConformingRestriction() const
The returned SparseMatrix is owned by the FiniteElementSpace.
Definition: fespace.cpp:1248
virtual void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1)
Get a list of essential true dofs, ess_tdof_list, corresponding to the boundary attributes marked in ...
Definition: fespace.cpp:564
int GetNE() const
Returns number of elements.
Definition: mesh.hpp:928
int GetEdgeDofs(int edge, Array< int > &dofs, int variant=0) const
Returns the indices of the degrees of freedom for the specified edge, including the DOFs for the vert...
Definition: fespace.cpp:2987
int GetBdrElementType(int i) const
Returns the type of boundary element i.
Definition: fespace.hpp:619
MFEM_DEPRECATED void RebuildElementToDofTable()
(
Definition: fespace.cpp:431
int GetNV() const
Returns number of vertices in the mesh.
Definition: fespace.hpp:587
virtual 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: fespace.cpp:1661
const FiniteElement * GetFaceElement(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i&#39;th face in the ...
Definition: fespace.cpp:3135
virtual void GetTrueTransferOperator(const FiniteElementSpace &coarse_fes, OperatorHandle &T) const
Construct and return an Operator that can be used to transfer true-dof data from coarse_fes, defined on a coarse mesh, to this FE space, defined on a refined mesh.
Definition: fespace.cpp:3273
void AddEdgeFaceDependencies(SparseMatrix &deps, Array< int > &master_dofs, const FiniteElement *master_fe, Array< int > &slave_dofs, int slave_face, const DenseMatrix *pm) const
Definition: fespace.cpp:783
FiniteElementCollection * Load(Mesh *m, std::istream &input)
Read a FiniteElementSpace from a stream. The returned FiniteElementCollection is owned by the caller...
Definition: fespace.cpp:3515
bool UsesTensorBasis(const FiniteElementSpace &fes)
Definition: fespace.hpp:983
const IntegrationRule * int_rule[Geometry::NumGeom]
Definition: fespace.hpp:944
virtual void CopyProlongationAndRestriction(const FiniteElementSpace &fes, const Array< int > *perm)
Copies the prolongation and restriction matrices from fes.
Definition: fespace.cpp:100
const FiniteElementCollection * fec
Associated FE collection (not owned).
Definition: fespace.hpp:100
OperatorHandle Th
Transformation to apply to GridFunctions after space Update().
Definition: fespace.hpp:157
virtual int GetFaceDofs(int face, Array< int > &dofs, int variant=0) const
Returns the indices of the degrees of freedom for the specified face, including the DOFs for the edge...
Definition: fespace.cpp:2906
NURBSExtension * GetNURBSext()
Definition: fespace.hpp:436
Geometry::Type GetElementBaseGeometry(int i) const
Definition: mesh.hpp:1062
void GetLocalDerefinementMatrices(Geometry::Type geom, DenseTensor &localR) const
Definition: fespace.cpp:2016
int GetConformingVSize() const
Definition: fespace.hpp:572
std::unordered_map< const key_face, FaceRestriction *, key_hash > map_L2F
Definition: fespace.hpp:173
int GetOrder() const
Return the order (polynomial degree) of the FE collection, corresponding to the order/degree returned...
Definition: fe_coll.hpp:195
std::uint64_t VarOrderBits
Bit-mask representing a set of orders needed by an edge/face.
Definition: fespace.hpp:212
const Table & GetFaceToDofTable() const
Return a reference to the internal Table that stores the lists of scalar dofs, for each face in the m...
Definition: fespace.hpp:739
Array< int > dof_elem_array
Definition: fespace.hpp:137
static void MarkerToList(const Array< int > &marker, Array< int > &list)
Convert a Boolean marker array to a list containing all marked indices.
Definition: fespace.cpp:598
DofTransformation * GetBdrElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom for i&#39;th boundary element.
Definition: fespace.cpp:297
void GetFaceInteriorDofs(int i, Array< int > &dofs) const
Definition: fespace.cpp:3078
Derefinement operator, used by the friend class InterpolationGridTransfer.
Definition: fespace.hpp:316
ElementTransformation * GetBdrElementTransformation(int i)
Returns the transformation defining the i-th boundary element.
Definition: mesh.cpp:431
virtual void UpdateMeshPointer(Mesh *new_mesh)
Definition: fespace.cpp:3441
void ConvertFromConformingVDofs(const Array< int > &cdofs, Array< int > &dofs)
For a partially conforming FE space, convert a marker array (nonzero entries are true) on the conform...
Definition: fespace.cpp:638
const Operator * GetElementRestriction(ElementDofOrdering e_ordering) const
Return an Operator that converts L-vectors to E-vectors.
Definition: fespace.cpp:1261
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
Definition: mesh.cpp:5345
int uni_fdof
of single face DOFs if all faces uniform; -1 otherwise
Definition: fespace.hpp:118
const SparseMatrix * GetConformingRestriction() const
The returned SparseMatrix is owned by the FiniteElementSpace.
Definition: fespace.cpp:1241
virtual void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
Definition: fespace.cpp:1983
int GetNE() const
Returns number of elements in the mesh.
Definition: fespace.hpp:590
int GetNE() const
Returns number of elements in the mesh.
Definition: fespace.hpp:973
void GetVertexDofs(int i, Array< int > &dofs) const
Definition: fespace.cpp:3035
bool Nonconforming() const
Definition: mesh.hpp:1626
FaceType
Definition: mesh.hpp:45
void BuildBdrElementToDofTable() const
Definition: fespace.cpp:383
int FindFaceDof(int face, int ndof) const
Similar to FindEdgeDof, but used for mixed meshes too.
Definition: fespace.hpp:240
DofTransformation * GetElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom in array dofs for i&#39;th element.
Definition: fespace.cpp:281
int GetFaceOrder(int face, int variant=0) const
Returns the polynomial degree of the i&#39;th face finite element.
Definition: fespace.cpp:2651
Array< DofTransformation * > DoFTrans
Definition: fespace.hpp:143
virtual void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
Definition: fespace.cpp:1588
int GetNBE() const
Returns number of boundary elements in the mesh.
Definition: fespace.hpp:599
bool orders_changed
True if at least one element order changed (variable-order space only).
Definition: fespace.hpp:189
Data type sparse matrix.
Definition: sparsemat.hpp:46
Native ordering as defined by the FiniteElement.
int FindEdgeDof(int edge, int ndof) const
Definition: fespace.hpp:236
Mesh * GetMesh() const
Returns the mesh.
Definition: fespace.hpp:433
Array< char > elem_order
Definition: fespace.hpp:115
void GetVDofs(int vd, Array< int > &dofs, int ndofs=-1) const
Returns the indices of all of the VDofs for the specified dimension &#39;vd&#39;.
Definition: fespace.cpp:195
A class that performs interpolation from an E-vector to quadrature point values and/or derivatives (Q...
Type
Ordering methods:
Definition: fespace.hpp:33
SparseMatrix * cR
Conforming restriction matrix such that cR.cP=I.
Definition: fespace.hpp:151
SparseMatrix * D2Const_GlobalRestrictionMatrix(FiniteElementSpace *cfes)
Generate the global restriction matrix from a discontinuous FE space to the piecewise constant FE spa...
Definition: fespace.cpp:679
SparseMatrix * D2C_GlobalRestrictionMatrix(FiniteElementSpace *cfes)
Generate the global restriction matrix from a discontinuous FE space to the continuous FE space of th...
Definition: fespace.cpp:647
void GetBoundaryTrueDofs(Array< int > &boundary_dofs, int component=-1)
Get a list of all boundary true dofs, boundary_dofs. For spaces with &#39;vdim&#39; &gt; 1, the &#39;component&#39; param...
Definition: fespace.cpp:582
T Max() const
Find the maximal element in the array, using the comparison operator &lt; for class T.
Definition: array.cpp:68
virtual const Operator * GetProlongationMatrix() const
The returned Operator is owned by the FiniteElementSpace.
Definition: fespace.hpp:471
void BuildConformingInterpolation() const
Calculate the cP and cR matrices for a nonconforming mesh.
Definition: fespace.cpp:928
NURBSExtension * StealNURBSext()
Definition: fespace.cpp:2231
int GetElementForDof(int i) const
Return the index of the first element that contains dof i.
Definition: fespace.hpp:749
int GetMaxElementOrder() const
Return the maximum polynomial order.
Definition: fespace.hpp:451
FiniteElementSpace & operator=(const FiniteElementSpace &)=delete
Copy assignment not supported.
ElementTransformation * GetBdrElementTransformation(int i) const
Returns ElementTransformation for the i-th boundary element.
Definition: fespace.hpp:632
void GetElementTransformation(int i, IsoparametricTransformation *ElTr)
Returns the transformation defining the i-th element in the user-defined variable ElTr...
Definition: fespace.hpp:628
bool IsDGSpace() const
Return whether or not the space is discontinuous (L2)
Definition: fespace.hpp:901
Array< int > dof_ldof_array
Definition: fespace.hpp:137
virtual int GetTrueVSize() const
Return the number of vector true (conforming) dofs.
Definition: fespace.hpp:566
bool Conforming() const
Definition: fespace.hpp:439
SparseMatrix * cP
Definition: fespace.hpp:149
int GetVDim() const
Returns vector dimension.
Definition: fespace.hpp:557
int GetNF() const
Returns number of faces (i.e. co-dimension 1 entities) in the mesh.
Definition: fespace.hpp:596
static int EncodeDof(int entity_base, int idx)
Helper to encode a sign flip into a DOF index (for Hcurl/Hdiv shapes).
Definition: fespace.hpp:250
virtual const FaceRestriction * GetFaceRestriction(ElementDofOrdering e_ordering, FaceType, L2FaceValues mul=L2FaceValues::DoubleValued) const
Return an Operator that converts L-vectors to E-vectors on each face.
Definition: fespace.cpp:1294
Array< QuadratureInterpolator * > E2Q_array
Definition: fespace.hpp:176
A class that performs interpolation from a face E-vector to quadrature point values and/or derivative...
int GetNumBorderDofs(Geometry::Type geom, int order) const
Definition: fespace.cpp:894
Operator * Ptr() const
Access the underlying Operator pointer.
Definition: handle.hpp:87
int GetEntityDofs(int entity, int index, Array< int > &dofs, Geometry::Type master_geom=Geometry::INVALID, int variant=0) const
Helper to get vertex, edge or face DOFs (entity=0,1,2 resp.).
Definition: fespace.cpp:903
int FirstFaceDof(int face, int variant=0) const
Definition: fespace.hpp:243
OperatorHandle L2E_nat
The element restriction operators, see GetElementRestriction().
Definition: fespace.hpp:160
virtual DofTransformation * GetElementDofs(int elem, Array< int > &dofs) const
Returns indices of degrees of freedom of element &#39;elem&#39;.
Definition: fespace.cpp:2680
void GetTransferOperator(const FiniteElementSpace &coarse_fes, OperatorHandle &T) const
Construct and return an Operator that can be used to transfer GridFunction data from coarse_fes...
Definition: fespace.cpp:3246
void GetElementInteriorDofs(int i, Array< int > &dofs) const
Definition: fespace.cpp:3045
void GetLocalRefinementMatrices(Geometry::Type geom, DenseTensor &localP) const
Definition: fespace.cpp:1453
static void DofsToVDofs(int ndofs, int vdim, Array< int > &dofs)
ElementTransformation * GetElementTransformation(int i) const
Returns ElementTransformation for the i-th element.
Definition: fespace.hpp:623
Type
Enumeration defining IDs for some classes derived from Operator.
Definition: operator.hpp:255
Abstract base class BilinearFormIntegrator.
Definition: bilininteg.hpp:34
const NURBSExtension * GetNURBSext() const
Definition: fespace.hpp:435
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition: fespace.hpp:88
Transfer data between a coarse mesh and an embedded refined mesh using interpolation.
Definition: transfer.hpp:121
int GetLocalDofForDof(int i) const
Return the local dof index in the first element that contains dof i.
Definition: fespace.hpp:753
virtual ~FiniteElementSpace()
Definition: fespace.cpp:3180
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
Definition: fe_coll.hpp:26
SparseMatrix * H2L_GlobalRestrictionMatrix(FiniteElementSpace *lfes)
Construct the restriction matrix from the FE space given by (*this) to the lower degree FE space give...
Definition: fespace.cpp:710
virtual ~QuadratureSpace()
Definition: fespace.hpp:961
void GetUpdateOperator(OperatorHandle &T)
Return the update operator in the given OperatorHandle, T.
Definition: fespace.hpp:876
RefinementOperator(const FiniteElementSpace *fespace, Table *old_elem_dof, Table *old_elem_fos, int old_ndofs)
Definition: fespace.cpp:1496
int GetOrder(int i) const
Returns the polynomial degree of the i&#39;th finite element.
Definition: fespace.hpp:547
void Save(std::ostream &out) const
Write the QuadratureSpace to the stream out.
Definition: fespace.cpp:3663
Array< char > var_face_orders
Definition: fespace.hpp:128
void Clear()
Clear the OperatorHandle, deleting the held Operator (if owned), while leaving the type id unchanged...
Definition: handle.hpp:124
void MakeVDimMatrix(SparseMatrix &mat) const
Replicate &#39;mat&#39; in the vector dimension, according to vdim ordering mode.
Definition: fespace.cpp:1206
The ordering method used when the number of unknowns per mesh node (vector dimension) is bigger than ...
Definition: fespace.hpp:29
void GetEdgeInteriorVDofs(int i, Array< int > &vdofs) const
Definition: fespace.cpp:336
void SetRelaxedHpConformity(bool relaxed=true)
Definition: fespace.hpp:915
int GetNVariants(int entity, int index) const
Return number of possible DOF variants for edge/face (var. order spaces).
Definition: fespace.cpp:2667
int GetOrder() const
Return the order of the quadrature rule(s) used by all elements.
Definition: fespace.hpp:967
int GetElementType(int i) const
Returns the type of element i.
Definition: fespace.hpp:611
FiniteElementSpace(Mesh *mesh, const FiniteElementCollection *fec, int vdim=1, int ordering=Ordering::byNODES)
Definition: fespace.hpp:415
bool Nonconforming() const
Definition: fespace.hpp:440
int GetNV() const
Returns number of vertices. Vertices are only at the corners of elements, where you would expect them...
Definition: mesh.hpp:925
int GetNVDofs() const
Number of all scalar vertex dofs.
Definition: fespace.hpp:580
int GetDegenerateFaceDofs(int index, Array< int > &dofs, Geometry::Type master_geom, int variant) const
Definition: fespace.cpp:852
void ConvertToConformingVDofs(const Array< int > &dofs, Array< int > &cdofs)
For a partially conforming FE space, convert a marker array (nonzero entries are true) on the partial...
Definition: fespace.cpp:630
void SetOperatorOwner(bool own=true)
Set the ownership flag for the held Operator.
Definition: handle.hpp:120
void Swap(Mesh &other, bool non_geometry)
Definition: mesh.cpp:9206
A standard isoparametric element transformation.
Definition: eltrans.hpp:361
Mesh * mesh
The mesh that FE space lives on (not owned).
Definition: fespace.hpp:97
void GetElementTransformation(int i, IsoparametricTransformation *ElTr)
Definition: mesh.cpp:348
void ReorderElementToDofTable()
Reorder the scalar DOFs based on the element ordering.
Definition: fespace.cpp:440
GridFunction interpolation operator applicable after mesh refinement.
Definition: fespace.hpp:290
void CalcEdgeFaceVarOrders(Array< VarOrderBits > &edge_orders, Array< VarOrderBits > &face_orders) const
Definition: fespace.cpp:2452
Array< FaceQuadratureInterpolator * > E2BFQ_array
Definition: fespace.hpp:178
const Table * GetElementToFaceOrientationTable() const
Definition: fespace.hpp:722
int GetNConformingDofs() const
Definition: fespace.cpp:1255
Table var_face_dofs
NOTE: also used for spaces with mixed faces.
Definition: fespace.hpp:124
void GetEdgeInteriorDofs(int i, Array< int > &dofs) const
Definition: fespace.cpp:3066
const QuadratureInterpolator * GetQuadratureInterpolator(const IntegrationRule &ir) const
Return a QuadratureInterpolator that interpolates E-vectors to quadrature point values and/or derivat...
Definition: fespace.cpp:1329
ElementDofOrdering
Constants describing the possible orderings of the DOFs in one element.
Definition: fespace.hpp:66
Array< FaceQuadratureInterpolator * > E2IFQ_array
Definition: fespace.hpp:177
void BuildFaceToDofTable() const
Definition: fespace.cpp:405
void UpdateElementOrders()
Resize the elem_order array on mesh change.
Definition: fespace.cpp:3314
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i&#39;th element in t...
Definition: fespace.cpp:2783
int index(int i, int j, int nx, int ny)
Definition: life.cpp:237
const Operator * GetUpdateOperator()
Get the GridFunction update operator.
Definition: fespace.hpp:873
Array< char > var_edge_orders
Definition: fespace.hpp:128
int GetEdgeOrder(int edge, int variant=0) const
Definition: fespace.cpp:2640
Lexicographic ordering for tensor-product FiniteElements.
FiniteElementSpace()
Default constructor: the object is invalid until initialized using the method Load().
Definition: fespace.cpp:59
QuadratureSpace(Mesh *mesh_, int order_)
Create a QuadratureSpace based on the global rules from IntRules.
Definition: fespace.hpp:955
void Constructor(Mesh *mesh, NURBSExtension *ext, const FiniteElementCollection *fec, int vdim=1, int ordering=Ordering::byNODES)
Help function for constructors + Load().
Definition: fespace.cpp:2141
void SetUpdateOperatorOwner(bool own)
Set the ownership of the update operator: if set to false, the Operator returned by GetUpdateOperator...
Definition: fespace.hpp:883
void GetFaceVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom for i&#39;th face element (2D and 3D).
Definition: fespace.cpp:312
void GetEdgeVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom for i&#39;th edge.
Definition: fespace.cpp:318
static void ListToMarker(const Array< int > &list, int marker_size, Array< int > &marker, int mark_val=-1)
Convert an array of indices (list) to a Boolean marker array where all indices in the list are marked...
Definition: fespace.cpp:617
std::size_t operator()(const key_face &k) const
Definition: fespace.hpp:165
Vector data type.
Definition: vector.hpp:60
const FiniteElementCollection * FEColl() const
Definition: fespace.hpp:577
std::tuple< bool, ElementDofOrdering, FaceType, L2FaceValues > key_face
The face restriction operators, see GetFaceRestriction().
Definition: fespace.hpp:162
virtual int GetNFbyType(FaceType type) const
Returns the number of faces according to the requested type, does not count master nonconforming face...
Definition: mesh.cpp:5361
Array< int > face_to_be
Definition: fespace.hpp:141
virtual void UpdatesFinished()
Free the GridFunction update operator (if any), to save memory.
Definition: fespace.hpp:894
const Table & GetElementToDofTable() const
Return a reference to the internal Table that stores the lists of scalar dofs, for each mesh element...
Definition: fespace.hpp:726
SparseMatrix * cR_hp
A version of the conforming restriction matrix for variable-order spaces.
Definition: fespace.hpp:153
void SetUpdateOperatorType(Operator::Type tid)
Specify the Operator::Type to be used by the update operators.
Definition: fespace.hpp:891
static bool DofFinalizable(int dof, const Array< bool > &finalized, const SparseMatrix &deps)
Definition: fespace.cpp:838
Class representing the storage layout of a QuadratureFunction.
Definition: fespace.hpp:935
const FiniteElement * GetBE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i&#39;th boundary fac...
Definition: fespace.cpp:3102
NURBSExtension * NURBSext
Definition: fespace.hpp:139
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Definition: globals.hpp:66
Base class for operators that extracts Face degrees of freedom.
Abstract operator.
Definition: operator.hpp:24
virtual const SparseMatrix * GetRestrictionMatrix() const
The returned SparseMatrix is owned by the FiniteElementSpace.
Definition: fespace.hpp:487
long GetSequence() const
Definition: fespace.hpp:898
int GetElementOrderImpl(int i) const
Return element order: internal version of GetElementOrder without checks.
Definition: fespace.cpp:189
Rank 3 tensor (array of matrices)
Definition: densemat.hpp:786
virtual const Operator * GetRestrictionOperator() const
An abstract operator that performs the same action as GetRestrictionMatrix.
Definition: fespace.hpp:483
void Save(std::ostream &out) const
Save finite element space to output stream out.
Definition: fespace.cpp:3446
int GetAttribute(int i) const
Return the attribute of element i.
Definition: mesh.hpp:1455
void BuildDofToArrays()
Initialize internal data that enables the use of the methods GetElementForDof() and GetLocalDofForDof...
Definition: fespace.cpp:460
Class representing a function through its values (scalar or vector) at quadrature points...
Definition: gridfunc.hpp:757
int GetNFDofs() const
Number of all scalar face-interior dofs.
Definition: fespace.hpp:584
int GetNEDofs() const
Number of all scalar edge-interior dofs.
Definition: fespace.hpp:582
void GetElementVertices(int i, Array< int > &v) const
Returns the indices of the vertices of element i.
Definition: mesh.hpp:1102
int FindDofs(const Table &var_dof_table, int row, int ndof) const
Search row of a DOF table for a DOF set of size &#39;ndof&#39;, return first DOF.
Definition: fespace.cpp:2623
static void AdjustVDofs(Array< int > &vdofs)
Definition: fespace.cpp:267
void SetType(Operator::Type tid)
Invoke Clear() and set a new type id.
Definition: handle.hpp:132
Arbitrary order &quot;L2-conforming&quot; discontinuous finite elements.
Definition: fe_coll.hpp:284
void DofsToVDofs(Array< int > &dofs, int ndofs=-1) const
Definition: fespace.cpp:215
const FaceQuadratureInterpolator * GetFaceQuadratureInterpolator(const IntegrationRule &ir, FaceType type) const
Return a FaceQuadratureInterpolator that interpolates E-vectors to quadrature point values and/or der...
Definition: fespace.cpp:1358
FiniteElementSpace(Mesh *mesh, NURBSExtension *ext, const FiniteElementCollection *fec, int vdim=1, int ordering=Ordering::byNODES)
Construct a NURBS FE space based on the given NURBSExtension, ext.
Definition: fespace.hpp:424