MFEM  v4.5.2
Finite element discretization library
lor.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2023, 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 #include "lor.hpp"
13 #include "lor_batched.hpp"
14 #include "../restriction.hpp"
15 #include "../pbilinearform.hpp"
16 #include "../../general/forall.hpp"
17 
18 namespace mfem
19 {
20 
21 void LORBase::AddIntegrators(BilinearForm &a_from,
22  BilinearForm &a_to,
23  GetIntegratorsFn get_integrators,
24  AddIntegratorFn add_integrator,
25  const IntegrationRule *ir)
26 {
27  Array<BilinearFormIntegrator*> *integrators = (a_from.*get_integrators)();
28  for (int i=0; i<integrators->Size(); ++i)
29  {
30  BilinearFormIntegrator *integrator = (*integrators)[i];
31  (a_to.*add_integrator)(integrator);
32  ir_map[integrator] = integrator->GetIntegrationRule();
33  if (ir) { integrator->SetIntegrationRule(*ir); }
34  }
35 }
36 
37 void LORBase::AddIntegratorsAndMarkers(BilinearForm &a_from,
38  BilinearForm &a_to,
39  GetIntegratorsFn get_integrators,
40  GetMarkersFn get_markers,
41  AddIntegratorMarkersFn add_integrator_marker,
42  AddIntegratorFn add_integrator,
43  const IntegrationRule *ir)
44 {
45  Array<BilinearFormIntegrator*> *integrators = (a_from.*get_integrators)();
46  Array<Array<int>*> *markers = (a_from.*get_markers)();
47 
48  for (int i=0; i<integrators->Size(); ++i)
49  {
50  BilinearFormIntegrator *integrator = (*integrators)[i];
51  if (*markers[i])
52  {
53  (a_to.*add_integrator_marker)(integrator, *(*markers[i]));
54  }
55  else
56  {
57  (a_to.*add_integrator)(integrator);
58  }
59  ir_map[integrator] = integrator->GetIntegrationRule();
60  if (ir) { integrator->SetIntegrationRule(*ir); }
61  }
62 }
63 
64 void LORBase::ResetIntegrationRules(GetIntegratorsFn get_integrators)
65 {
66  Array<BilinearFormIntegrator*> *integrators = (a->*get_integrators)();
67  for (int i=0; i<integrators->Size(); ++i)
68  {
69  ((*integrators)[i])->SetIntRule(ir_map[(*integrators)[i]]);
70  }
71 }
72 
74 {
75  const FiniteElementCollection *fec_ho = fes_ho.FEColl();
76  if (dynamic_cast<const H1_FECollection*>(fec_ho)) { return H1; }
77  else if (dynamic_cast<const ND_FECollection*>(fec_ho)) { return ND; }
78  else if (dynamic_cast<const RT_FECollection*>(fec_ho)) { return RT; }
79  else if (dynamic_cast<const L2_FECollection*>(fec_ho)) { return L2; }
80  else { MFEM_ABORT("Bad LOR space type."); }
81  return INVALID;
82 }
83 
85 {
86  FESpaceType type = GetFESpaceType();
87  return (type == L2 || type == RT) ? 0 : 1;
88 }
89 
91 {
92  FESpaceType type = GetFESpaceType();
93  MFEM_VERIFY(type != H1 && type != L2, "");
94 
95  auto get_dof_map = [](FiniteElementSpace &fes_, int i)
96  {
97  const FiniteElement *fe = fes_.GetFE(i);
98  auto tfe = dynamic_cast<const TensorBasisElement*>(fe);
99  MFEM_ASSERT(tfe != NULL, "");
100  return tfe->GetDofMap();
101  };
102 
103  FiniteElementSpace &fes_lor = GetFESpace();
104  Mesh &mesh_lor = *fes_lor.GetMesh();
105  int dim = mesh_lor.Dimension();
106  const CoarseFineTransformations &cf_tr = mesh_lor.GetRefinementTransforms();
107 
108  using GeomRef = std::pair<Geometry::Type, int>;
109  std::map<GeomRef, int> point_matrices_offsets;
110  perm_.SetSize(fes_lor.GetVSize());
111 
112  Array<int> vdof_ho, vdof_lor;
113  for (int ilor=0; ilor<mesh_lor.GetNE(); ++ilor)
114  {
115  int iho = cf_tr.embeddings[ilor].parent;
116  int p = fes_ho.GetOrder(iho);
117  int lor_index = cf_tr.embeddings[ilor].matrix;
118  // We use the point matrix index to identify the local LOR element index
119  // within the high-order coarse element.
120  //
121  // In variable-order spaces, the point matrices for each order are
122  // concatenated sequentially, so for the given element order, we need to
123  // find the offset that will give us the point matrix index relative to
124  // the current element order only.
125  GeomRef id(mesh_lor.GetElementBaseGeometry(ilor), p);
126  if (point_matrices_offsets.find(id) == point_matrices_offsets.end())
127  {
128  point_matrices_offsets[id] = lor_index;
129  }
130  lor_index -= point_matrices_offsets[id];
131 
132  fes_ho.GetElementVDofs(iho, vdof_ho);
133  fes_lor.GetElementVDofs(ilor, vdof_lor);
134 
135  if (type == L2)
136  {
137  perm_[vdof_lor[0]] = vdof_ho[lor_index];
138  continue;
139  }
140 
141  int p1 = p+1;
142  int ndof_per_dim = (dim == 2) ? p*p1 : type == ND ? p*p1*p1 : p*p*p1;
143 
144  const Array<int> &dofmap_ho = get_dof_map(fes_ho, iho);
145  const Array<int> &dofmap_lor = get_dof_map(fes_lor, ilor);
146 
147  int off_x = lor_index % p;
148  int off_y = (lor_index / p) % p;
149  int off_z = (lor_index / p) / p;
150 
151  auto set_perm = [&](int off_lor, int off_ho, int n1, int n2)
152  {
153  for (int i1=0; i1<2; ++i1)
154  {
155  int m = (dim == 2 || type == RT) ? 1 : 2;
156  for (int i2=0; i2<m; ++i2)
157  {
158  int i;
159  i = dofmap_lor[off_lor + i1 + i2*2];
160  int s1 = i < 0 ? -1 : 1;
161  int idof_lor = vdof_lor[absdof(i)];
162  i = dofmap_ho[off_ho + i1*n1 + i2*n2];
163  int s2 = i < 0 ? -1 : 1;
164  int idof_ho = vdof_ho[absdof(i)];
165  int s3 = idof_lor < 0 ? -1 : 1;
166  int s4 = idof_ho < 0 ? -1 : 1;
167  int s = s1*s2*s3*s4;
168  i = absdof(idof_ho);
169  perm_[absdof(idof_lor)] = s < 0 ? -1-absdof(i) : absdof(i);
170  }
171  }
172  };
173 
174  int offset;
175 
176  if (type == ND)
177  {
178  // x
179  offset = off_x + off_y*p + off_z*p*p1;
180  set_perm(0, offset, p, p*p1);
181  // y
182  offset = ndof_per_dim + off_x + off_y*(p1) + off_z*p1*p;
183  set_perm(dim == 2 ? 2 : 4, offset, 1, p*p1);
184  // z
185  if (dim == 3)
186  {
187  offset = 2*ndof_per_dim + off_x + off_y*p1 + off_z*p1*p1;
188  set_perm(8, offset, 1, p+1);
189  }
190  }
191  else if (type == RT)
192  {
193  // x
194  offset = off_x + off_y*p1 + off_z*p*p1;
195  set_perm(0, offset, 1, 0);
196  // y
197  offset = ndof_per_dim + off_x + off_y*p + off_z*p1*p;
198  set_perm(2, offset, p, 0);
199  // z
200  if (dim == 3)
201  {
202  offset = 2*ndof_per_dim + off_x + off_y*p + off_z*p*p;
203  set_perm(4, offset, p*p, 0);
204  }
205  }
206  }
207 }
208 
210 {
211  FESpaceType type = GetFESpaceType();
212  if (type == H1 || type == L2)
213  {
214  // H1 and L2: no permutation necessary, return identity
216  for (int i=0; i<perm.Size(); ++i) { perm[i] = i; }
217  return;
218  }
219 
220 #ifdef MFEM_USE_MPI
221  ParFiniteElementSpace *pfes_ho
222  = dynamic_cast<ParFiniteElementSpace*>(&fes_ho);
223  ParFiniteElementSpace *pfes_lor
224  = dynamic_cast<ParFiniteElementSpace*>(&GetFESpace());
225  if (pfes_ho && pfes_lor)
226  {
227  Array<int> l_perm;
229  perm.SetSize(pfes_lor->GetTrueVSize());
230  for (int i=0; i<l_perm.Size(); ++i)
231  {
232  int j = l_perm[i];
233  int s = j < 0 ? -1 : 1;
234  int t_i = pfes_lor->GetLocalTDofNumber(i);
235  int t_j = pfes_ho->GetLocalTDofNumber(absdof(j));
236  // Either t_i and t_j both -1, or both non-negative
237  if ((t_i < 0 && t_j >=0) || (t_j < 0 && t_i >= 0))
238  {
239  MFEM_ABORT("Inconsistent DOF numbering");
240  }
241  if (t_i < 0) { continue; }
242  perm[t_i] = s < 0 ? -1 - t_j : t_j;
243  }
244  }
245  else
246 #endif
247  {
249  }
250 }
251 
253 {
254  if (perm.Size() == 0) { ConstructDofPermutation(); }
255  return perm;
256 }
257 
259 {
260  FESpaceType type = GetFESpaceType();
261  return type == H1 || type == L2;
262 }
263 
265 {
266  MFEM_VERIFY(A.Ptr() != NULL, "No LOR system assembled");
267  return A;
268 }
269 
271 {
272  MFEM_VERIFY(A.Ptr() != NULL, "No LOR system assembled");
273  return A;
274 }
275 
277 {
278  if (!HasSameDofNumbering())
279  {
280  Array<int> p;
283  }
284  else
285  {
287  }
288 }
289 
290 template <typename FEC>
292 {
293  const FEC *fec = dynamic_cast<const FEC*>(fes.FEColl());
294  if (fec)
295  {
296  int btype = fec->GetBasisType();
297  if (btype != BasisType::GaussLobatto)
298  {
299  mfem::err << "\nWARNING: Constructing low-order refined "
300  << "discretization with basis type\n"
301  << BasisType::Name(btype) << ". "
302  << "The LOR discretization is only spectrally equivalent\n"
303  << "with Gauss-Lobatto basis.\n" << std::endl;
304  }
305  }
306 }
307 
308 template <typename FEC>
310 {
311  const FEC *fec = dynamic_cast<const FEC*>(fes.FEColl());
312  if (fec)
313  {
314  int cbtype = fec->GetClosedBasisType();
315  int obtype = fec->GetOpenBasisType();
316  if (cbtype != BasisType::GaussLobatto || obtype != BasisType::IntegratedGLL)
317  {
318  mfem::err << "\nWARNING: Constructing vector low-order refined "
319  << "discretization with basis type \npair ("
320  << BasisType::Name(cbtype) << ", "
321  << BasisType::Name(obtype) << "). "
322  << "The LOR discretization is only spectrally\nequivalent "
323  << "with basis types (Gauss-Lobatto, IntegratedGLL).\n"
324  << std::endl;
325  }
326  }
327 }
328 
330 {
331  CheckScalarBasisType<H1_FECollection>(fes);
332  CheckVectorBasisType<ND_FECollection>(fes);
333  CheckVectorBasisType<RT_FECollection>(fes);
334  // L2 is a bit more complicated, for now don't verify basis type
335 }
336 
337 LORBase::LORBase(FiniteElementSpace &fes_ho_, int ref_type_)
338  : irs(0, Quadrature1D::GaussLobatto), ref_type(ref_type_), fes_ho(fes_ho_)
339 {
340  Mesh &mesh_ = *fes_ho_.GetMesh();
341  int dim = mesh_.Dimension();
342  Array<Geometry::Type> geoms;
343  mesh_.GetGeometries(dim, geoms);
344  if (geoms.Size() == 1 && Geometry::IsTensorProduct(geoms[0]))
345  {
346  ir_el = &irs.Get(geoms[0], 1);
347  ir_face = &irs.Get(Geometry::TensorProductGeometry(dim-1), 1);
348  }
349  else
350  {
351  ir_el = NULL;
352  ir_face = NULL;
353  }
354  a = NULL;
355 }
356 
358 {
359  // In the case of "batched assembly", the creation of the LOR mesh and
360  // space can be completely omitted (for efficiency). In this case, the
361  // fes object is NULL, and we need to create it when requested.
362  if (fes == NULL) { const_cast<LORBase*>(this)->FormLORSpace(); }
363  return *fes;
364 }
365 
366 void LORBase::AssembleSystem(BilinearForm &a_ho, const Array<int> &ess_dofs)
367 {
368  A.Clear();
369  delete a;
371  {
372  // Skip forming the space
373  a = nullptr;
374  if (batched_lor == nullptr)
375  {
377  }
378  batched_lor->Assemble(a_ho, ess_dofs, A);
379  }
380  else
381  {
382  LegacyAssembleSystem(a_ho, ess_dofs);
383  }
384 }
385 
387  const Array<int> &ess_dofs)
388 {
389  // TODO: use AssemblyLevel::FULL here instead of AssemblyLevel::LEGACY.
390  // This is waiting for parallel assembly + BCs with AssemblyLevel::FULL.
391  // In that case, maybe "LegacyAssembleSystem" is not a very clear name.
392 
393  // If the space is not formed already, it will be constructed lazily in
394  // GetFESpace.
395  FiniteElementSpace &fes_lor = GetFESpace();
396 #ifdef MFEM_USE_MPI
397  if (auto *pfes = dynamic_cast<ParFiniteElementSpace*>(&fes_lor))
398  {
399  a = new ParBilinearForm(pfes);
400  }
401  else
402 #endif
403  {
404  a = new BilinearForm(&fes_lor);
405  }
406 
408  AddIntegrators(a_ho, *a, &BilinearForm::GetDBFI,
410  AddIntegrators(a_ho, *a, &BilinearForm::GetFBFI,
412  AddIntegratorsAndMarkers(a_ho, *a, &BilinearForm::GetBBFI,
416  AddIntegratorsAndMarkers(a_ho, *a, &BilinearForm::GetBFBFI,
420 
421  a->Assemble();
422  a->FormSystemMatrix(ess_dofs, A);
423 
424  ResetIntegrationRules(&BilinearForm::GetDBFI);
425  ResetIntegrationRules(&BilinearForm::GetFBFI);
426  ResetIntegrationRules(&BilinearForm::GetBBFI);
427  ResetIntegrationRules(&BilinearForm::GetBFBFI);
428 }
429 
431 {
432  delete batched_lor;
433  delete a;
434  delete fes;
435  delete fec;
436  delete mesh;
437 }
438 
440  const Array<int> &ess_tdof_list,
441  int ref_type_)
442  : LORBase(*a_ho_.FESpace(), ref_type_)
443 {
446  AssembleSystem(a_ho_, ess_tdof_list);
447 }
448 
450  int ref_type_) : LORBase(fes_ho, ref_type_)
451 {
454 }
455 
457 {
458  Mesh &mesh_ho = *fes_ho.GetMesh();
459  // For H1, ND and RT spaces, use refinement = element order, for DG spaces,
460  // use refinement = element order + 1 (since LOR is p = 0 in this case).
461  int increment = (GetFESpaceType() == L2) ? 1 : 0;
462  Array<int> refinements(mesh_ho.GetNE());
463  for (int i=0; i<refinements.Size(); ++i)
464  {
465  refinements[i] = fes_ho.GetOrder(i) + increment;
466  }
467  mesh = new Mesh(Mesh::MakeRefined(mesh_ho, refinements, ref_type));
468 
470  const int vdim = fes_ho.GetVDim();
471  const Ordering::Type ordering = fes_ho.GetOrdering();
472  fes = new FiniteElementSpace(mesh, fec, vdim, ordering);
474 }
475 
477 {
478  MFEM_VERIFY(A.Ptr() != nullptr, "No LOR system assembled");
479  return *A.As<SparseMatrix>();
480 }
481 
482 #ifdef MFEM_USE_MPI
483 
485  const Array<int> &ess_tdof_list,
486  int ref_type_) : LORBase(*a_ho_.ParFESpace(), ref_type_)
487 {
488  ParFiniteElementSpace *pfes_ho = a_ho_.ParFESpace();
489  if (pfes_ho->GetMyRank() == 0) { CheckBasisType(fes_ho); }
491  AssembleSystem(a_ho_, ess_tdof_list);
492 }
493 
495  ParFiniteElementSpace &fes_ho, int ref_type_) : LORBase(fes_ho, ref_type_)
496 {
497  if (fes_ho.GetMyRank() == 0) { CheckBasisType(fes_ho); }
499 }
500 
502 {
503  ParFiniteElementSpace &pfes_ho = static_cast<ParFiniteElementSpace&>(fes_ho);
504  // TODO: support variable-order spaces in parallel
505  MFEM_VERIFY(!pfes_ho.IsVariableOrder(),
506  "Cannot construct LOR operators on variable-order spaces");
507 
508  int order = pfes_ho.GetMaxElementOrder();
509  if (GetFESpaceType() == L2) { ++order; }
510 
511  ParMesh &mesh_ho = *pfes_ho.GetParMesh();
512  ParMesh *pmesh = new ParMesh(ParMesh::MakeRefined(mesh_ho, order, ref_type));
513  mesh = pmesh;
514 
515  fec = pfes_ho.FEColl()->Clone(GetLOROrder());
516  const int vdim = fes_ho.GetVDim();
517  const Ordering::Type ordering = fes_ho.GetOrdering();
518  fes = new ParFiniteElementSpace(pmesh, fec, vdim, ordering);
520 }
521 
523 {
524  MFEM_VERIFY(A.Ptr() != nullptr, "No LOR system assembled");
525  return *A.As<HypreParMatrix>();
526 }
527 
529 {
530  return static_cast<ParFiniteElementSpace&>(GetFESpace());
531 }
532 
533 #endif // MFEM_USE_MPI
534 
535 } // namespace mfem
Abstract class for all finite elements.
Definition: fe_base.hpp:232
class BatchedLORAssembly * batched_lor
Definition: lor.hpp:71
Abstract base class for LORDiscretization and ParLORDiscretization classes, which construct low-order...
Definition: lor.hpp:22
LORDiscretization(BilinearForm &a_ho, const Array< int > &ess_tdof_list, int ref_type=BasisType::GaussLobatto)
Construct the low-order refined version of a_ho using the given list of essential DOFs...
Definition: lor.cpp:439
Array< BilinearFormIntegrator * > * GetBBFI()
Access all the integrators added with AddBoundaryIntegrator().
ParFiniteElementSpace * ParFESpace() const
Return the parallel FE space associated with the ParBilinearForm.
bool IsVariableOrder() const
Returns true if the space contains elements of varying polynomial orders.
Definition: fespace.hpp:463
static Type TensorProductGeometry(int dim)
Definition: geom.hpp:113
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
Definition: intrules.cpp:923
void Assemble(int skip_zeros=1)
Assembles the form i.e. sums over all domain/bdr integrators.
OutStream err(std::cerr)
Global stream used by the library for standard error output. Initially it uses the same std::streambu...
Definition: globals.hpp:71
virtual ~LORBase()
Definition: lor.cpp:430
Geometry::Type GetElementBaseGeometry(int i) const
Definition: mesh.hpp:1108
static ParMesh MakeRefined(ParMesh &orig_mesh, int ref_factor, int ref_type)
Create a uniformly refined (by any factor) version of orig_mesh.
Definition: pmesh.cpp:1367
ParFiniteElementSpace & GetParFESpace() const
Return the LOR ParFiniteElementSpace.
Definition: lor.cpp:528
int Dimension() const
Definition: mesh.hpp:1047
void LegacyAssembleSystem(BilinearForm &a_ho, const Array< int > &ess_dofs)
Assembles the LOR system corresponding to a_ho using the legacy method.
Definition: lor.cpp:386
Array< BilinearFormIntegrator * > * GetDBFI()
Access all the integrators added with AddDomainIntegrator().
int GetLOROrder() const
Returns the order of the LOR space. 1 for H1 or ND, 0 for L2 or RT.
Definition: lor.cpp:84
Array< BilinearFormIntegrator * > * GetBFBFI()
Access all integrators added with AddBdrFaceIntegrator().
Efficient batched assembly of LOR discretizations on device.
Definition: lor_batched.hpp:33
Pointer to an Operator of a specified type.
Definition: handle.hpp:33
FiniteElementSpace & fes_ho
Definition: lor.hpp:66
static Mesh MakeRefined(Mesh &orig_mesh, int ref_factor, int ref_type)
Create a refined (by any factor) version of orig_mesh.
Definition: mesh.cpp:3746
Array< Array< int > * > * GetBFBFI_Marker()
Access all boundary markers added with AddBdrFaceIntegrator(). If no marker was specified when the in...
Abstract parallel finite element space.
Definition: pfespace.hpp:28
A class container for 1D quadrature type constants.
Definition: intrules.hpp:289
void FormLORSpace() override
Construct the LOR space (overridden for serial and parallel versions).
Definition: lor.cpp:456
static const char * Name(int b_type)
Check and convert a BasisType constant to a string identifier.
Definition: fe_base.hpp:91
Array< BilinearFormIntegrator * > * GetFBFI()
Access all integrators added with AddInteriorFaceIntegrator().
virtual void CopyProlongationAndRestriction(const FiniteElementSpace &fes, const Array< int > *perm)
Copies the prolongation and restriction matrices from fes.
Definition: fespace.cpp:100
static bool FormIsSupported(BilinearForm &a)
Returns true if the form a supports batched assembly, false otherwise.
Definition: lor_batched.cpp:49
Array< Array< int > * > * GetBBFI_Marker()
Access all boundary markers added with AddBoundaryIntegrator(). If no marker was specified when the i...
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
const Array< int > & GetDofPermutation() const
Returns the permutation that maps LOR DOFs to high-order DOFs.
Definition: lor.cpp:252
void CheckScalarBasisType(const FiniteElementSpace &fes)
Definition: lor.cpp:291
virtual FiniteElementCollection * Clone(int p) const
Instantiate a new collection of the same type with a different order.
Definition: fe_coll.cpp:361
ID for class SparseMatrix.
Definition: operator.hpp:286
int ref_type
Definition: lor.hpp:65
FiniteElementSpace * fes
Definition: lor.hpp:69
const OperatorHandle & GetAssembledSystem() const
Returns the assembled LOR system (const version).
Definition: lor.cpp:270
int GetMaxElementOrder() const
Return the maximum polynomial order.
Definition: fespace.hpp:459
Data type sparse matrix.
Definition: sparsemat.hpp:50
const FiniteElementCollection * FEColl() const
Definition: fespace.hpp:601
Mesh * mesh
Definition: lor.hpp:67
Type
Ordering methods:
Definition: fespace.hpp:33
LORBase(FiniteElementSpace &fes_ho_, int ref_type_)
Construct the LORBase object for the given FE space and refinement type.
Definition: lor.cpp:337
ParMesh * GetParMesh() const
Definition: pfespace.hpp:277
void SetupProlongationAndRestriction()
Definition: lor.cpp:276
void CheckBasisType(const FiniteElementSpace &fes)
Definition: lor.cpp:329
Array< Embedding > embeddings
Fine element positions in their parents.
Definition: ncmesh.hpp:73
Array< int > perm
Definition: lor.hpp:73
virtual void FormSystemMatrix(const Array< int > &ess_tdof_list, OperatorHandle &A)
Form the linear system matrix A, see FormLinearSystem() for details.
virtual void FormLORSpace()=0
Construct the LOR space (overridden for serial and parallel versions).
bool HasSameDofNumbering() const
Definition: lor.cpp:258
BilinearForm * a
Definition: lor.hpp:70
int GetVDim() const
Returns vector dimension.
Definition: fespace.hpp:581
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
void UseExternalIntegrators()
Indicate that integrators are not owned by the BilinearForm.
HypreParMatrix & GetAssembledMatrix() const
Return the assembled LOR operator as a HypreParMatrix.
Definition: lor.cpp:522
virtual int GetTrueVSize() const
Return the number of vector true (conforming) dofs.
Definition: fespace.hpp:590
Mesh * GetMesh() const
Returns the mesh.
Definition: fespace.hpp:441
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition: fespace.hpp:96
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
Definition: fe_coll.hpp:26
int GetOrder(int i) const
Returns the polynomial degree of the i&#39;th finite element.
Definition: fespace.hpp:571
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
Definition: array.hpp:684
void Assemble(BilinearForm &a, const Array< int > ess_dofs, OperatorHandle &A)
Assemble the given form as a matrix and place the result in A.
int GetLocalTDofNumber(int ldof) const
Definition: pfespace.cpp:1062
void Clear()
Clear the OperatorHandle, deleting the held Operator (if owned), while leaving the type id unchanged...
Definition: handle.hpp:124
void ConstructDofPermutation() const
Definition: lor.cpp:209
const CoarseFineTransformations & GetRefinementTransforms()
Definition: mesh.cpp:9990
void GetGeometries(int dim, Array< Geometry::Type > &el_geoms) const
Return all element geometries of the given dimension present in the mesh.
Definition: mesh.cpp:5932
SparseMatrix & GetAssembledMatrix() const
Return the assembled LOR operator as a SparseMatrix.
Definition: lor.cpp:476
Integrated GLL indicator functions.
Definition: fe_base.hpp:38
int GetNE() const
Returns number of elements.
Definition: mesh.hpp:936
virtual int GetTrueVSize() const
Return the number of local vector true dofs.
Definition: pfespace.hpp:289
A "square matrix" operator for the associated FE space and BLFIntegrators The sum of all the BLFInteg...
static bool IsTensorProduct(Type geom)
Definition: geom.hpp:108
OpType * As() const
Return the Operator pointer statically cast to a specified OpType. Similar to the method Get()...
Definition: handle.hpp:104
Ordering::Type GetOrdering() const
Return the ordering method.
Definition: fespace.hpp:599
FiniteElementCollection * fec
Definition: lor.hpp:68
void AddBoundaryIntegrator(BilinearFormIntegrator *bfi)
Adds new Boundary Integrator. Assumes ownership of bfi.
ParLORDiscretization(ParBilinearForm &a_ho, const Array< int > &ess_tdof_list, int ref_type=BasisType::GaussLobatto)
Construct the low-order refined version of a_ho using the given list of essential DOFs...
Definition: lor.cpp:484
int dim
Definition: ex24.cpp:53
void AddInteriorFaceIntegrator(BilinearFormIntegrator *bfi)
Adds new interior Face Integrator. Assumes ownership of bfi.
void AssembleSystem(BilinearForm &a_ho, const Array< int > &ess_dofs)
Assembles the LOR system corresponding to a_ho.
Definition: lor.cpp:366
void AddDomainIntegrator(BilinearFormIntegrator *bfi)
Adds new Domain Integrator. Assumes ownership of bfi.
FESpaceType GetFESpaceType() const
Returns the type of finite element space: H1, ND, RT or L2.
Definition: lor.cpp:73
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
Definition: fespace.hpp:587
Class for parallel bilinear form.
Operator * Ptr() const
Access the underlying Operator pointer.
Definition: handle.hpp:87
void CheckVectorBasisType(const FiniteElementSpace &fes)
Definition: lor.cpp:309
int Size() const
Return the logical size of the array.
Definition: array.hpp:141
ID for class HypreParMatrix.
Definition: operator.hpp:287
Defines the coarse-fine transformations of all fine elements.
Definition: ncmesh.hpp:70
RefCoord s[3]
FiniteElementSpace & GetFESpace() const
Returns the low-order refined finite element space.
Definition: lor.cpp:357
void FormLORSpace() override
Construct the LOR space (overridden for serial and parallel versions).
Definition: lor.cpp:501
void ConstructLocalDofPermutation(Array< int > &perm_) const
Definition: lor.cpp:90
Wrapper for hypre&#39;s ParCSR matrix class.
Definition: hypre.hpp:343
OperatorHandle A
Definition: lor.hpp:72
Class for parallel meshes.
Definition: pmesh.hpp:32
void SetType(Operator::Type tid)
Invoke Clear() and set a new type id.
Definition: handle.hpp:132
void AddBdrFaceIntegrator(BilinearFormIntegrator *bfi)
Adds new boundary Face Integrator. Assumes ownership of bfi.