MFEM v4.10.0
Finite element discretization library
Loading...
Searching...
No Matches
pfespace.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_PFESPACE
13#define MFEM_PFESPACE
14
15#include "../config/config.hpp"
16
17#ifdef MFEM_USE_MPI
18
19#include "../linalg/hypre.hpp"
20#include "../mesh/pmesh.hpp"
21#include "../mesh/nurbs.hpp"
22#include "fespace.hpp"
23
24namespace mfem
25{
26
27struct ParDerefineMatrixOp;
28
29/// Abstract parallel finite element space.
31{
32 friend struct ParDerefineMatrixOp;
33private:
34 /// MPI data.
35 MPI_Comm MyComm;
36 int NRanks, MyRank;
37
38 /// Parallel mesh; @a mesh points to this object as well. Not owned.
39 ParMesh *pmesh;
40 /** Parallel non-conforming mesh extension object; same as pmesh->pncmesh.
41 Not owned. */
42 ParNCMesh *pncmesh;
43
44 /// GroupCommunicator on the local VDofs. Owned.
45 GroupCommunicator *gcomm;
46
47 /// Number of true dofs in this processor (local true dofs).
48 mutable int ltdof_size;
49
50 /// Number of vertex/edge/face/total ghost DOFs (nonconforming case).
51 int ngvdofs, ngedofs, ngfdofs, ngdofs;
52
53 struct VarOrderDofInfo
54 {
55 unsigned int index; // Index of the entity (edge or face)
56 unsigned short int edof; // Dof index within the entity
57 };
58
59 Array<VarOrderDofInfo> var_edge_dofmap, var_face_dofmap;
60
61 /// For each true DOF on edges and faces, store data about the edge or face.
62 struct TdofLdofInfo
63 {
64 bool set; // Whether the members of this instance are set.
65 int minOrder; // Minimum order for the mesh entity containing this DOF.
66 bool isEdge; // Whether the containing mesh entity is an edge.
67 int idx; // Index of the containing mesh entity in pmesh.
68 };
69
70 /// Data for each true DOF on edges and faces.
71 Array<TdofLdofInfo> tdof2ldof;
72
73 /// The group of each local dof.
74 Array<int> ldof_group;
75
76 /// For a local dof: the local true dof number in the master of its group.
77 mutable Array<int> ldof_ltdof;
78
79 /// Offsets for the dofs in each processor in global numbering.
80 mutable Array<HYPRE_BigInt> dof_offsets;
81
82 /// Offsets for the true dofs in each processor in global numbering.
83 mutable Array<HYPRE_BigInt> tdof_offsets;
84
85 /// Offsets for the true dofs in neighbor processor in global numbering.
86 mutable Array<HYPRE_BigInt> tdof_nb_offsets;
87
88 /// Previous 'dof_offsets' (before Update()), column partition of T.
89 Array<HYPRE_BigInt> old_dof_offsets;
90
91 /// The sign of the basis functions at the scalar local dofs.
92 Array<int> ldof_sign;
93
94 /// The matrix P (interpolation from true dof to dof). Owned.
95 mutable HypreParMatrix *P;
96 /// Optimized action-only prolongation operator for conforming meshes. Owned.
97 mutable Operator *Pconf;
98
99 /** Used to indicate that the space is nonconforming (even if the underlying
100 mesh has NULL @a ncmesh). This occurs in low-order preconditioning on
101 nonconforming meshes. */
102 bool nonconf_P;
103
104 /// The (block-diagonal) matrix R (restriction of dof to true dof). Owned.
105 mutable SparseMatrix *R;
106 /// Optimized action-only restriction operator for conforming meshes. Owned.
107 mutable Operator *Rconf;
108
109 /// Flag indicating the existence of shared triangles with interior ND dofs
110 bool nd_strias;
111
112 /** Stores the previous ParFiniteElementSpace, before p-refinement, in the
113 case that @a PTh is constructed by PRefineAndUpdate(). */
114 std::unique_ptr<ParFiniteElementSpace> pfes_prev;
115
116 /// Ghost element order data, set by CommunicateGhostOrder().
117 Array<ParNCMesh::VarOrderElemInfo> ghost_orders;
118
119 /// Resets nd_strias flag at construction or after rebalancing
120 void CheckNDSTriaDofs();
121
122 ParNURBSExtension *pNURBSext() const
123 { return dynamic_cast<ParNURBSExtension *>(NURBSext); }
124
125 static ParNURBSExtension *MakeLocalNURBSext(
126 const NURBSExtension *globNURBSext, const NURBSExtension *parNURBSext);
127
128 GroupTopology &GetGroupTopo() const
129 { return (NURBSext) ? pNURBSext()->gtopo : pmesh->gtopo; }
130
131 // Auxiliary method used in constructors
132 void ParInit(ParMesh *pm);
133
134 /// Set ghost_orders.
135 void CommunicateGhostOrder();
136
137 /// Sets @a tdof2ldof. See documentation of @a tdof2ldof for details.
138 void SetTDOF2LDOFinfo(int ntdofs, int vdim_factor, int dof_stride,
139 int allnedofs);
140
141 /** Set the rows of the restriction matrix @a R in a variable-order space,
142 corresponding to true DOFs on edges and faces. */
143 void SetRestrictionMatrixEdgesFaces(int vdim_factor, int dof_stride,
144 int tdof_stride,
145 const Array<int> &dof_tdof,
146 const Array<HYPRE_BigInt> &dof_offs);
147
148 /// Helper function to set var_edge_dofmap or var_face_dofmap
149 void SetVarDofMap(const Table & dofs, Array<VarOrderDofInfo> & dmap);
150
151 void Construct();
152 void Destroy();
153
154 // ldof_type = 0 : DOFs communicator, otherwise VDOFs communicator
155 void GetGroupComm(GroupCommunicator &gcomm, int ldof_type,
156 Array<int> *ldof_sign = NULL);
157
158 /// Construct dof_offsets and tdof_offsets using global communication.
159 void GenerateGlobalOffsets() const;
160
161 /// Construct ldof_group and ldof_ltdof.
162 void ConstructTrueDofs();
163 void ConstructTrueNURBSDofs();
164
165 void ApplyLDofSigns(Array<int> &dofs) const;
166 void ApplyLDofSigns(Table &el_dof) const;
167
168 typedef NCMesh::MeshId MeshId;
169 typedef ParNCMesh::GroupId GroupId;
170
171 void GetGhostVertexDofs(const MeshId &id, Array<int> &dofs) const;
172 void GetGhostEdgeDofs(const MeshId &edge_id, Array<int> &dofs,
173 int variant) const;
174 void GetGhostFaceDofs(const MeshId &face_id, Array<int> &dofs) const;
175 void GetGhostDofs(int entity, const MeshId &id, Array<int> &dofs,
176 int variant) const;
177
178 /// Return the dofs associated with the interior of the given mesh entity.
179 void GetBareDofs(int entity, int index, Array<int> &dofs) const;
180 void GetBareDofsVar(int entity, int index, Array<int> &dofs) const;
181
182 /** @brief Return the local space DOF index for the DOF with index @a edof
183 with respect to the mesh entity @a index of type @a entity (0: vertex,
184 1: edge, 2: face). In the variable-order case, use variant @a var. */
185 int PackDof(int entity, int index, int edof, int var = 0) const;
186 /// Inverse of function @a PackDof, setting order instead of variant.
187 void UnpackDof(int dof, int &entity, int &index, int &edof, int &order) const;
188
189 /// Implementation of function @a PackDof for the variable-order case.
190 int PackDofVar(int entity, int index, int edof, int var = 0) const;
191 /// Implementation of function @a UnpackDof for the variable-order case.
192 void UnpackDofVar(int dof, int &entity, int &index, int &edof,
193 int &order) const;
194
195#ifdef MFEM_PMATRIX_STATS
196 mutable int n_msgs_sent, n_msgs_recv;
197 mutable int n_rows_sent, n_rows_recv, n_rows_fwd;
198#endif
199
200 void ScheduleSendOrder(int ent, int idx, int order,
201 GroupId group_id,
202 std::map<int, class NeighborOrderMessage> &send_msg) const;
203
204 void ScheduleSendRow(const struct PMatrixRow &row, int dof, GroupId group_id,
205 std::map<int, class NeighborRowMessage> &send_msg) const;
206
207 void ForwardRow(const struct PMatrixRow &row, int dof,
208 GroupId group_sent_id, GroupId group_id,
209 std::map<int, class NeighborRowMessage> &send_msg) const;
210
211#ifdef MFEM_DEBUG_PMATRIX
212 void DebugDumpDOFs(std::ostream &os,
213 const SparseMatrix &deps,
214 const Array<GroupId> &dof_group,
215 const Array<GroupId> &dof_owner,
216 const Array<bool> &finalized) const;
217#endif
218
219 /// Helper: create a HypreParMatrix from a list of PMatrixRows.
220 HypreParMatrix*
221 MakeVDimHypreMatrix(const std::vector<struct PMatrixRow> &rows,
222 int local_rows, int local_cols,
223 Array<HYPRE_BigInt> &row_starts,
224 Array<HYPRE_BigInt> &col_starts) const;
225
226 /// Build the P and R matrices.
227 void Build_Dof_TrueDof_Matrix() const;
228
229 /** Used when the ParMesh is non-conforming, i.e. pmesh->pncmesh != NULL.
230 Constructs the matrices P and R, the DOF and true DOF offset arrays,
231 and the DOF -> true DOF map ('dof_tdof'). Returns the number of
232 vector true DOFs. All pointer arguments are optional and can be NULL. */
233 int BuildParallelConformingInterpolation(HypreParMatrix **P, SparseMatrix **R,
234 Array<HYPRE_BigInt> &dof_offs,
235 Array<HYPRE_BigInt> &tdof_offs,
236 Array<int> *dof_tdof,
237 bool partial = false);
238
239 /** Calculate a GridFunction migration matrix after mesh load balancing.
240 The result is a parallel permutation matrix that can be used to update
241 all grid functions defined on this space. */
242 HypreParMatrix* RebalanceMatrix(int old_ndofs,
243 const Table* old_elem_dof,
244 const Table* old_elem_fos);
245
246 /** Calculate a GridFunction restriction matrix after mesh derefinement.
247 The matrix is constructed so that the new grid function interpolates
248 the original function, i.e., the original function is evaluated at the
249 nodes of the coarse function. */
250 HypreParMatrix* ParallelDerefinementMatrix(int old_ndofs,
251 const Table *old_elem_dof,
252 const Table *old_elem_fos);
253
254 /// Updates the internal mesh pointer. @warning @a new_mesh must be
255 /// <b>topologically identical</b> to the existing mesh. Used if the address
256 /// of the Mesh object has changed, e.g. in @a Mesh::Swap.
257 void UpdateMeshPointer(Mesh *new_mesh) override;
258
259 /// Copies the prolongation and restriction matrices from @a fes.
260 ///
261 /// Used for low order preconditioning on non-conforming meshes. If the DOFs
262 /// require a permutation, it will be supplied by non-NULL @a perm. NULL @a
263 /// perm indicates that no permutation is required.
264 void CopyProlongationAndRestriction(const FiniteElementSpace &fes,
265 const Array<int> *perm) override;
266
267public:
268 // Face-neighbor data
269 // Number of face-neighbor dofs
271 // Face-neighbor-element to face-neighbor dof
273 // Face-neighbor-element face orientations
275 // Face-neighbor to ldof in the face-neighbor numbering
277 // The global ldof indices of the face-neighbor dofs
279 // Local face-neighbor data: face-neighbor to ldof
281
282 /** @brief Copy constructor: deep copy all data from @a orig except the
283 ParMesh, the FiniteElementCollection, and some derived data. */
284 /** If the @a pmesh or @a fec pointers are NULL (default), then the new
285 ParFiniteElementSpace will reuse the respective pointers from @a orig. If
286 any of these pointers is not NULL, the given pointer will be used instead
287 of the one used by @a orig.
288
289 @note The objects pointed to by the @a pmesh and @a fec parameters must
290 be either the same objects as the ones used by @a orig, or copies of
291 them. Otherwise, the behavior is undefined.
292
293 @note Derived data objects, such as the parallel prolongation and
294 restriction operators, the update operator, and any of the face-neighbor
295 data, will not be copied, even if they are created in the @a orig object.
296 */
298 ParMesh *pmesh = NULL,
299 const FiniteElementCollection *fec = NULL);
300
301 /** @brief Convert/copy the *local* (Par)FiniteElementSpace @a orig to
302 ParFiniteElementSpace: deep copy all data from @a orig except the Mesh,
303 the FiniteElementCollection, and some derived data. */
305 const FiniteElementCollection *fec = NULL);
306
307 /** @brief Construct the *local* ParFiniteElementSpace corresponding to the
308 global FE space, @a global_fes. */
309 /** The parameter @a pm is the *local* ParMesh obtained by decomposing the
310 global Mesh used by @a global_fes. The array @a partitioning represents
311 the parallel decomposition - it maps global element ids to MPI ranks.
312 If the FiniteElementCollection, @a f, is NULL (default), the FE
313 collection used by @a global_fes will be reused. If @a f is not NULL, it
314 must be the same as, or a copy of, the FE collection used by
315 @a global_fes.
316
317 @note Currently the @a partitioning array is not used by this
318 constructor, it is required for general parallel variable-order support.
319 */
320 ParFiniteElementSpace(ParMesh *pm, const FiniteElementSpace *global_fes,
321 const int *partitioning,
322 const FiniteElementCollection *f = NULL);
323
325 int dim = 1, int ordering = Ordering::byNODES);
326
327 /// Construct a NURBS FE space based on the given NURBSExtension, @a ext.
328 /** The parameter @a ext will be deleted by this constructor, replaced by a
329 ParNURBSExtension owned by the ParFiniteElementSpace.
330 @note If the pointer @a ext is NULL, this constructor is equivalent to
331 the standard constructor with the same arguments minus the
332 NURBSExtension, @a ext. */
335 int dim = 1, int ordering = Ordering::byNODES);
336
337 MPI_Comm GetComm() const { return MyComm; }
338 int GetNRanks() const { return NRanks; }
339 int GetMyRank() const { return MyRank; }
340
341 inline ParMesh *GetParMesh() const { return pmesh; }
342
343 /** @brief Return true if the parallel FE space has DOFs with signs opposite
344 of the DOFs in the respective serial FE space. */
345 bool HaveDofSigns() const { return ldof_sign.Size() != 0; }
346
347 /** @brief Apply the DOF signs to the given host data @a h_data which must be
348 of size GetVSize() if HaveDofSigns() is true. If HaveDofSigns() is false,
349 this method is no-op and returns immediately. */
350 void ApplyDofSigns(real_t *h_data) const;
351
352 /** @brief Return -1 if the given (vector) DOF @a i has a sign opposite of
353 the DOF in the respective serial FE space. Otherwise, return 1. */
354 int GetDofSign(int i) const
355 { return !HaveDofSigns() ? 1 : ldof_sign[VDofToDof(i)]; }
356
357 HYPRE_BigInt *GetDofOffsets() const { return dof_offsets; }
358 HYPRE_BigInt *GetTrueDofOffsets() const { return tdof_offsets; }
363
364 /// Return the number of local vector true dofs.
365 int GetTrueVSize() const override { return ltdof_size; }
366
367 /// Returns indexes of degrees of freedom in array dofs for i'th element and
368 /// returns the DofTransformation data in a user-provided object.
370 void GetElementDofs(int i, Array<int> &dofs,
371 DofTransformation &doftrans) const override;
372
373 /// Returns indexes of degrees of freedom for i'th boundary element and
374 /// returns the DofTransformation data in a user-provided object.
376 void GetBdrElementDofs(int i, Array<int> &dofs,
377 DofTransformation &doftrans) const override;
378
379 /** Returns the indexes of the degrees of freedom for i'th face
380 including the dofs for the edges and the vertices of the face. */
381 int GetFaceDofs(int i, Array<int> &dofs, int variant = 0) const override;
382
383 /** Returns pointer to the FiniteElement in the FiniteElementCollection
384 associated with i'th element in the mesh object. If @a i is greater than
385 or equal to the number of local mesh elements, @a i will be interpreted
386 as a shifted index of a face neighbor element. */
387 const FiniteElement *GetFE(int i) const override;
388
389 /** Returns an Operator that converts L-vectors to E-vectors on each face.
390 The parallel version is different from the serial one because of the
391 presence of shared faces. Shared faces are treated as interior faces,
392 the returned operator handles the communication needed to get the
393 shared face values from other MPI ranks */
395 ElementDofOrdering f_ordering, FaceType type,
396 L2FaceValues mul = L2FaceValues::DoubleValued) const override;
397
398 void GetSharedEdgeDofs(int group, int ei, Array<int> &dofs) const;
399 void GetSharedTriangleDofs(int group, int fi, Array<int> &dofs) const;
400 void GetSharedQuadrilateralDofs(int group, int fi, Array<int> &dofs) const;
401
402 /// The true dof-to-dof interpolation matrix
404 { if (!P) { Build_Dof_TrueDof_Matrix(); } return P; }
405
406 /** @brief For a non-conforming mesh, construct and return the interpolation
407 matrix from the partially conforming true dofs to the local dofs. */
408 /** @note The returned pointer must be deleted by the caller. */
410
411 /** Create and return a new HypreParVector on the true dofs, which is
412 owned by (i.e. it must be destroyed by) the calling function. */
415
416 /// Scale a vector of true dofs
417 void DivideByGroupSize(real_t *vec);
418
419 /// Return a reference to the internal GroupCommunicator (on VDofs)
420 GroupCommunicator &GroupComm() { return *gcomm; }
421
422 /// Return a const reference to the internal GroupCommunicator (on VDofs)
423 const GroupCommunicator &GroupComm() const { return *gcomm; }
424
425 /// Return a new GroupCommunicator on scalar dofs, i.e. for VDim = 1.
426 /** @note The returned pointer must be deleted by the caller. */
428
429 /** @brief Given an integer array on the local degrees of freedom, perform
430 a bitwise OR between the shared dofs. */
431 /** For non-conforming mesh, synchronization is performed on the cut (aka
432 "partially conforming") space. */
433 void Synchronize(Array<int> &ldof_marker) const;
434
435 /// Determine the boundary degrees of freedom
436 void GetEssentialVDofs(const Array<int> &bdr_attr_is_ess,
437 Array<int> &ess_dofs,
438 int component = -1) const override;
439
440 /** Get a list of essential true dofs, ess_tdof_list, corresponding to the
441 boundary attributes marked in the array bdr_attr_is_ess. */
442 void GetEssentialTrueDofs(const Array<int> &bdr_attr_is_ess,
444 int component = -1) const override;
445
446 /** Helper function for GetEssentialTrueDofs(), in the case of a
447 variable-order H1 space. */
449 &bdr_attr_is_ess,
450 const Array<int> &ess_dofs,
451 Array<int> &true_ess_dofs,
452 int component) const;
453
454 /// Determine the external degrees of freedom
455 void GetExteriorVDofs(Array<int> &ext_dofs,
456 int component = -1) const override;
457
458 /** Get a list of external true dofs, ext_tdof_list, corresponding to the
459 face on the exterior of the mesh. */
460 void GetExteriorTrueDofs(Array<int> &ext_tdof_list,
461 int component = -1) const override;
462
463 /** @brief Extract the edge degrees of freedom of a boundary "loop" on a
464 parallel mesh (see the serial FiniteElementSpace::GetBoundaryLoopEdgeDofs
465 for the definition of a loop). This version removes the artificial
466 boundary edges that appear at processor boundaries, so the selected DOFs
467 are independent of the mesh partitioning.
468
469 As in the serial version, the @a boundary_edge_dofs_out, @a dof_edges and
470 @a dof_boundary_elements outputs share a single indexing describing the
471 same local DOF at each position.
472
473 Requirements:
474 - Mesh must be conforming (no hanging nodes)
475 - Mesh dimension must be >= 2
476 @param[in] boundary_element_indices Array of boundary element indices.
477 @param[out] ess_tdof_list Essential true DOF indices, sorted ascending.
478 @param[out] boundary_edge_dofs_out Local boundary-loop DOF indices.
479 @param[out] ldof_marker Optional; marker of the boundary edge DOFs,
480 derivable from @a boundary_edge_dofs_out via ListToMarker().
481 @param[out] dof_edges Optional; local edge index of each DOF.
482 @param[out] dof_boundary_elements Optional; a boundary element containing
483 each DOF.
484 @param[out] ess_edge_list Optional array of edge indices, in one-to-one
485 correspondence with @a ess_tdof_list. An entry
486 is -1 when the true DOF is owned by this rank
487 but no local edge can be associated with it,
488 which can happen for a shared vertex DOF whose
489 boundary elements are all on other ranks. */
490 void GetBoundaryLoopEdgeDofs(const Array<int> &boundary_element_indices,
492 Array<int> &boundary_edge_dofs_out,
493 Array<int> *ldof_marker = nullptr,
494 Array<int> *dof_edges = nullptr,
495 Array<int> *dof_boundary_elements = nullptr,
496 Array<int> *ess_edge_list = nullptr);
497
498 /** If the given ldof is owned by the current processor, return its local
499 tdof number, otherwise return -1 */
500 int GetLocalTDofNumber(int ldof) const;
501 /// Returns the global tdof number of the given local degree of freedom
502 HYPRE_BigInt GetGlobalTDofNumber(int ldof) const;
503 /** Returns the global tdof number of the given local degree of freedom in
504 the scalar version of the current finite element space. The input should
505 be a scalar local dof. */
507
510
511 const Operator *GetProlongationMatrix() const override;
512 /** Get an Operator that performs the action of GetRestrictionMatrix(),
513 but potentially with a non-assembled optimized matrix-free
514 implementation. */
515 const Operator *GetRestrictionOperator() const override;
516 /// Get the R matrix which restricts a local dof vector to true dof vector.
517 const SparseMatrix *GetRestrictionMatrix() const override
518 { Dof_TrueDof_Matrix(); return R; }
519
520 // Face-neighbor functions
521 void ExchangeFaceNbrData();
522 int GetFaceNbrVSize() const { return num_face_nbr_dofs; }
523 void GetFaceNbrElementVDofs(int i, Array<int> &vdofs,
524 DofTransformation &doftrans) const;
526 void GetFaceNbrFaceVDofs(int i, Array<int> &vdofs) const;
527 /** In the variable-order case with @a ndofs > 0, the order is taken such
528 that the number of DOFs is @a ndofs. */
529 const FiniteElement *GetFaceNbrFE(int i, int ndofs = 0) const;
530 const FiniteElement *GetFaceNbrFaceFE(int i) const;
537
539 void LoseDofOffsets() { dof_offsets.LoseData(); }
540 void LoseTrueDofOffsets() { tdof_offsets.LoseData(); }
541
542 bool Conforming() const { return pmesh->pncmesh == NULL && !nonconf_P; }
543 bool Nonconforming() const { return pmesh->pncmesh != NULL || nonconf_P; }
544
545 bool SharedNDTriangleDofs() const { return nd_strias; }
546
547 // Transfer parallel true-dof data from coarse_fes, defined on a coarse mesh,
548 // to this FE space, defined on a refined mesh. See full documentation in the
549 // base class, FiniteElementSpace::GetTrueTransferOperator.
550 void GetTrueTransferOperator(const FiniteElementSpace &coarse_fes,
551 OperatorHandle &T) const override;
552
553 /** Reflect changes in the mesh. Calculate one of the refinement/derefinement
554 /rebalance matrices, unless want_transform is false. */
555 void Update(bool want_transform = true) override;
556
557 /** P-refine and update the space. If @a want_transfer, also maintain the old
558 space and a transfer operator accessible by GetPrefUpdateOperator(). */
559 void PRefineAndUpdate(const Array<pRefinement> & refs,
560 bool want_transfer = true) override;
561
562 /// Free ParGridFunction transformation matrix (if any), to save memory.
563 void UpdatesFinished() override
564 {
566 old_dof_offsets.DeleteAll();
567 }
568
569 /// Returns the maximum polynomial order over all elements globally.
570 int GetMaxElementOrder() const override;
571
572 virtual ~ParFiniteElementSpace() { Destroy(); }
573
574 void PrintPartitionStats();
575
576 /// Obsolete, kept for backward compatibility
577 int TrueVSize() const { return ltdof_size; }
578
579protected:
580 /** Helper function for finalizing intermediate DOFs on edges and faces in a
581 variable-order space, with order strictly between the minimum and
582 maximum. */
583 void MarkIntermediateEntityDofs(int entity, Array<bool> & intermediate) const;
584
585 /** Helper function for variable-order spaces, to apply the order on each
586 ghost element to its edges and faces. */
588 Array<VarOrderBits> &edge_orders,
589 Array<VarOrderBits> &face_orders) const override;
590
591 /** Helper function for variable-order spaces, to apply the lowest order on
592 each ghost face to its edges. */
593 void GhostFaceOrderToEdges(const Array<VarOrderBits> &face_orders,
594 Array<VarOrderBits> &edge_orders)
595 const override;
596
597 /** Performs parallel order propagation, for variable-order spaces. Returns
598 true if order propagation is done. */
599 bool OrderPropagation(const std::set<int> &edges,
600 const std::set<int> &faces,
601 Array<VarOrderBits> &edge_orders,
602 Array<VarOrderBits> &face_orders) const override;
603
604 /// Returns the number of ghost edges.
605 int NumGhostEdges() const override
606 { return pncmesh ? pncmesh->GetNGhostEdges() : 0; }
607
608 /// Returns the number of ghost faces.
609 int NumGhostFaces() const override
610 { return pncmesh ? pncmesh->GetNGhostFaces() : 0; }
611};
612
613
614/// Auxiliary class used by ParFiniteElementSpace.
616{
617protected:
620 bool local;
621
622public:
624 bool local_=false);
625
627 bool local_=false);
628
630
631 void Mult(const Vector &x, Vector &y) const override;
632
633 void AbsMult(const Vector &x, Vector &y) const override
634 { Mult(x,y); }
635
636 void MultTranspose(const Vector &x, Vector &y) const override;
637
638 void AbsMultTranspose(const Vector &x, Vector &y) const override
639 { MultTranspose(x,y); }
640};
641
642/// Auxiliary device class used by ParFiniteElementSpace.
645{
646public:
648 int lsize, const GroupCommunicator &gc_, bool local_=false);
649
651 const GroupCommunicator &gc_, const SparseMatrix *R, bool local_=false);
652
654 bool local_=false);
655
656 void Mult(const Vector &x, Vector &y) const override;
657
658 void AbsMult(const Vector &x, Vector &y) const override
659 { Mult(x,y); }
660
661 void MultTranspose(const Vector &x, Vector &y) const override;
662
663 void AbsMultTranspose(const Vector &x, Vector &y) const override
664 { MultTranspose(x,y); }
665};
666
667}
668
669#endif // MFEM_USE_MPI
670
671#endif
const T * HostRead() const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), false).
Definition array.hpp:414
Auxiliary class used by ParFiniteElementSpace.
Definition pfespace.hpp:616
void MultTranspose(const Vector &x, Vector &y) const override
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
const GroupCommunicator & GetGroupCommunicator() const
ConformingProlongationOperator(int lsize, const GroupCommunicator &gc_, bool local_=false)
void AbsMultTranspose(const Vector &x, Vector &y) const override
Action of the transpose absolute-value operator: y=|A|^t(x). The default behavior in class Operator i...
Definition pfespace.hpp:638
void AbsMult(const Vector &x, Vector &y) const override
Action of the absolute-value operator: y=|A|(x). The default behavior in class Operator is to generat...
Definition pfespace.hpp:633
void Mult(const Vector &x, Vector &y) const override
Operator application: y=A(x).
const GroupCommunicator & gc
Definition pfespace.hpp:619
Auxiliary device class used by ParFiniteElementSpace.
Definition pfespace.hpp:645
void AbsMultTranspose(const Vector &x, Vector &y) const override
Action of the transpose absolute-value operator: y=|A|^t(x). The default behavior in class Operator i...
Definition pfespace.hpp:663
void Mult(const Vector &x, Vector &y) const override
Operator application: y=A(x).
void AbsMult(const Vector &x, Vector &y) const override
Action of the absolute-value operator: y=|A|(x). The default behavior in class Operator is to generat...
Definition pfespace.hpp:658
void MultTranspose(const Vector &x, Vector &y) const override
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
DeviceConformingProlongationOperator(int lsize, const GroupCommunicator &gc_, bool local_=false)
Base class for operators that extracts Face degrees of freedom.
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
Definition fe_coll.hpp:27
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition fespace.hpp:210
DofTransformation * GetElementDofs(int elem, Array< int > &dofs) const
Returns indices of degrees of freedom of element 'elem'. The returned indices are offsets into an ldo...
Definition fespace.cpp:3538
NURBSExtension * NURBSext
Definition fespace.hpp:286
FiniteElementSpace()
Default constructor: the object is invalid until initialized using the method Load().
Definition fespace.cpp:33
const FiniteElementCollection * fec
Associated FE collection (not owned).
Definition fespace.hpp:222
int VDofToDof(int vdof) const
Compute the inverse of the Dof to VDof mapping for a single index vdof.
Definition fespace.hpp:1131
virtual void UpdatesFinished()
Free the GridFunction update operator (if any), to save memory.
Definition fespace.hpp:1577
int ndofs
Number of degrees of freedom. Number of unknowns is ndofs * vdim.
Definition fespace.hpp:233
Ordering::Type ordering
Definition fespace.hpp:230
DofTransformation * GetBdrElementDofs(int bel, Array< int > &dofs) const
Returns indices of degrees of freedom for boundary element 'bel'. The returned indices are offsets in...
Definition fespace.cpp:3643
Abstract class for all finite elements.
Definition fe_base.hpp:294
Communicator performing operations within groups defined by a GroupTopology with arbitrary-size data ...
Wrapper for hypre's ParCSR matrix class.
Definition hypre.hpp:419
HYPRE_BigInt GetGlobalNumRows() const
Return the global number of rows.
Definition hypre.hpp:713
HYPRE_BigInt GetGlobalNumCols() const
Return the global number of columns.
Definition hypre.hpp:717
Wrapper for hypre's parallel vector class.
Definition hypre.hpp:230
NURBSExtension generally contains multiple NURBSPatch objects spanning an entire Mesh....
Definition nurbs.hpp:575
Pointer to an Operator of a specified type.
Definition handle.hpp:34
Abstract operator.
Definition operator.hpp:27
Abstract parallel finite element space.
Definition pfespace.hpp:31
void GetTrueTransferOperator(const FiniteElementSpace &coarse_fes, OperatorHandle &T) const override
Construct and return an Operator that can be used to transfer true-dof data from coarse_fes,...
HYPRE_BigInt GetGlobalScalarTDofNumber(int sldof)
void GetBoundaryLoopEdgeDofs(const Array< int > &boundary_element_indices, Array< int > &ess_tdof_list, Array< int > &boundary_edge_dofs_out, Array< int > *ldof_marker=nullptr, Array< int > *dof_edges=nullptr, Array< int > *dof_boundary_elements=nullptr, Array< int > *ess_edge_list=nullptr)
Extract the edge degrees of freedom of a boundary "loop" on a parallel mesh (see the serial FiniteEle...
const GroupCommunicator & GroupComm() const
Return a const reference to the internal GroupCommunicator (on VDofs)
Definition pfespace.hpp:423
void GetSharedTriangleDofs(int group, int fi, Array< int > &dofs) const
Definition pfespace.cpp:739
void GetSharedEdgeDofs(int group, int ei, Array< int > &dofs) const
Definition pfespace.cpp:715
int NumGhostEdges() const override
Returns the number of ghost edges.
Definition pfespace.hpp:605
MPI_Comm GetComm() const
Definition pfespace.hpp:337
int GetMaxElementOrder() const override
Returns the maximum polynomial order over all elements globally.
const FaceRestriction * GetFaceRestriction(ElementDofOrdering f_ordering, FaceType type, L2FaceValues mul=L2FaceValues::DoubleValued) const override
Definition pfespace.cpp:670
HYPRE_BigInt * GetTrueDofOffsets() const
Definition pfespace.hpp:358
void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1) const override
void GetExteriorTrueDofs(Array< int > &ext_tdof_list, int component=-1) const override
void GetExteriorVDofs(Array< int > &ext_dofs, int component=-1) const override
Determine the external degrees of freedom.
HYPRE_BigInt GlobalVSize() const
Definition pfespace.hpp:359
const Operator * GetRestrictionOperator() const override
int GetLocalTDofNumber(int ldof) const
void UpdatesFinished() override
Free ParGridFunction transformation matrix (if any), to save memory.
Definition pfespace.hpp:563
friend struct ParDerefineMatrixOp
Definition pfespace.hpp:32
void Synchronize(Array< int > &ldof_marker) const
Given an integer array on the local degrees of freedom, perform a bitwise OR between the shared dofs.
int GetDofSign(int i) const
Return -1 if the given (vector) DOF i has a sign opposite of the DOF in the respective serial FE spac...
Definition pfespace.hpp:354
void ApplyGhostElementOrdersToEdgesAndFaces(Array< VarOrderBits > &edge_orders, Array< VarOrderBits > &face_orders) const override
bool SharedNDTriangleDofs() const
Definition pfespace.hpp:545
ParFiniteElementSpace(const ParFiniteElementSpace &orig, ParMesh *pmesh=NULL, const FiniteElementCollection *fec=NULL)
Copy constructor: deep copy all data from orig except the ParMesh, the FiniteElementCollection,...
Definition pfespace.cpp:34
void DivideByGroupSize(real_t *vec)
Scale a vector of true dofs.
HYPRE_BigInt GlobalTrueVSize() const
Definition pfespace.hpp:361
HypreParVector * NewTrueDofVector()
Definition pfespace.hpp:413
int GetTrueVSize() const override
Return the number of local vector true dofs.
Definition pfespace.hpp:365
const FiniteElement * GetFaceNbrFE(int i, int ndofs=0) const
void GhostFaceOrderToEdges(const Array< VarOrderBits > &face_orders, Array< VarOrderBits > &edge_orders) const override
HYPRE_BigInt GetMyDofOffset() const
HYPRE_BigInt * GetDofOffsets() const
Definition pfespace.hpp:357
Array< HYPRE_BigInt > face_nbr_glob_dof_map
Definition pfespace.hpp:278
GroupCommunicator & GroupComm()
Return a reference to the internal GroupCommunicator (on VDofs)
Definition pfespace.hpp:420
void GetEssentialTrueDofsVar(const Array< int > &bdr_attr_is_ess, const Array< int > &ess_dofs, Array< int > &true_ess_dofs, int component) const
void GetFaceNbrFaceVDofs(int i, Array< int > &vdofs) const
const Operator * GetProlongationMatrix() const override
const Array< HYPRE_BigInt > & GetFaceNbrGlobalDofMapArray() const
Definition pfespace.hpp:531
bool HaveDofSigns() const
Return true if the parallel FE space has DOFs with signs opposite of the DOFs in the respective seria...
Definition pfespace.hpp:345
GroupCommunicator * ScalarGroupComm()
Return a new GroupCommunicator on scalar dofs, i.e. for VDim = 1.
bool OrderPropagation(const std::set< int > &edges, const std::set< int > &faces, Array< VarOrderBits > &edge_orders, Array< VarOrderBits > &face_orders) const override
void GetEssentialVDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_dofs, int component=-1) const override
Determine the boundary degrees of freedom.
HypreParMatrix * Dof_TrueDof_Matrix() const
The true dof-to-dof interpolation matrix.
Definition pfespace.hpp:403
void GetFaceNbrElementVDofs(int i, Array< int > &vdofs, DofTransformation &doftrans) const
int GetFaceDofs(int i, Array< int > &dofs, int variant=0) const override
Definition pfespace.cpp:647
int NumGhostFaces() const override
Returns the number of ghost faces.
Definition pfespace.hpp:609
void ApplyDofSigns(real_t *h_data) const
Apply the DOF signs to the given host data h_data which must be of size GetVSize() if HaveDofSigns() ...
Definition pfespace.cpp:575
HYPRE_BigInt GetMyTDofOffset() const
void GetSharedQuadrilateralDofs(int group, int fi, Array< int > &dofs) const
Definition pfespace.cpp:764
void GetElementDofs(int i, Array< int > &dofs, DofTransformation &doftrans) const override
The same as GetElementDofs(), but with a user-provided DofTransformation object.
Definition pfespace.cpp:593
void PRefineAndUpdate(const Array< pRefinement > &refs, bool want_transfer=true) override
const SparseMatrix * GetRestrictionMatrix() const override
Get the R matrix which restricts a local dof vector to true dof vector.
Definition pfespace.hpp:517
HYPRE_BigInt GetGlobalTDofNumber(int ldof) const
Returns the global tdof number of the given local degree of freedom.
const HYPRE_BigInt * GetFaceNbrGlobalDofMap() const
Definition pfespace.hpp:533
ParMesh * GetParMesh() const
Definition pfespace.hpp:341
void Update(bool want_transform=true) override
HypreParMatrix * GetPartialConformingInterpolation()
For a non-conforming mesh, construct and return the interpolation matrix from the partially conformin...
int TrueVSize() const
Obsolete, kept for backward compatibility.
Definition pfespace.hpp:577
void MarkIntermediateEntityDofs(int entity, Array< bool > &intermediate) const
const FiniteElement * GetFaceNbrFaceFE(int i) const
const FiniteElement * GetFE(int i) const override
Definition pfespace.cpp:663
ElementTransformation * GetFaceNbrElementTransformation(int i) const
Definition pfespace.hpp:535
void GetBdrElementDofs(int i, Array< int > &dofs, DofTransformation &doftrans) const override
The same as GetBdrElementDofs(), but with a user-provided DofTransformation object.
Definition pfespace.cpp:620
Class for parallel meshes.
Definition pmesh.hpp:35
ElementTransformation * GetFaceNbrElementTransformation(int FaceNo)
Returns a pointer to the transformation defining the i-th face neighbor.
Definition pmesh.cpp:3127
GroupTopology gtopo
Definition pmesh.hpp:457
ParNCMesh * pncmesh
Definition pmesh.hpp:470
A parallel extension of the NCMesh class.
Definition pncmesh.hpp:63
int GetNGhostEdges() const
Definition pncmesh.hpp:123
int GetNGhostFaces() const
Definition pncmesh.hpp:124
GroupTopology gtopo
Definition nurbs.hpp:1167
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
Vector data type.
Definition vector.hpp:82
const int * ess_tdof_list
int dim
Definition ex24.cpp:53
HYPRE_Int HYPRE_BigInt
int index(int i, int j, int nx, int ny)
Definition life.cpp:236
float real_t
Definition config.hpp:46
ElementDofOrdering
Constants describing the possible orderings of the DOFs in one element.
Definition fespace.hpp:49
std::function< real_t(const Vector &)> f(real_t mass_coeff)
Definition lor_mms.hpp:30
FaceType
Definition mesh.hpp:49