https://mooseframework.inl.gov
MFEMQuadratureFunctionCoefficientBase.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #ifdef MOOSE_MFEM_ENABLED
11 
13 #include "MooseError.h"
14 
15 #include "libmesh/ignore_warnings.h"
16 #include "mfem.hpp"
17 #include "libmesh/restore_warnings.h"
18 
19 namespace
20 {
21 
22 bool
23 SamePoint(const mfem::IntegrationPoint & a, const mfem::IntegrationPoint & b, const int dim)
24 {
25  constexpr mfem::real_t tol = 1e-12;
26  mfem::real_t pa[3], pb[3];
27  a.Get(pa, dim);
28  b.Get(pb, dim);
29  for (int d = 0; d < dim; ++d)
30  if (std::abs(pa[d] - pb[d]) > tol)
31  return false;
32  return std::abs(a.weight - b.weight) < tol;
33 }
34 }
35 
36 void
38  mfem::ElementTransformation & T,
39  const mfem::IntegrationPoint & ip) const
40 {
41  const mfem::QuadratureSpaceBase & qspace = *qf.GetSpace();
42  const int el_idx = qspace.GetEntityIndex(T);
43  // Entity not in this space (e.g. a boundary evaluation)
44  if (el_idx < 0)
45  return;
46 
47  const mfem::Geometry::Type geom = qspace.GetGeometry(el_idx);
48  const int dim = mfem::Geometry::Dimension[geom];
49  const mfem::IntegrationRule & stored_rule = qspace.GetIntRule(el_idx);
50  // Fast path: the consuming integrator's point at this index coincides with the stored rule's,
51  // so the rules match.
52  if (ip.index < stored_rule.Size() && SamePoint(stored_rule.IntPoint(ip.index), ip, dim))
53  return;
54 
55  // Rules differ. Recover the quadrature order the coefficient should have used by finding the
56  // lowest order whose rule for this geometry reproduces the consuming integrator's point at
57  // ip.index. This runs only on the error path.
58  const int stored_order = qspace.GetOrder();
59  int suggested_order = -1;
60  // The consuming integrator's order is not known here, but is realistically bounded. The upper
61  // limit is just a generous finite cap so this error-path search always terminates: a multiple
62  // of the stored order, plus a constant so low-order stored rules still search far enough. If the
63  // true order somehow exceeds the cap, suggested_order stays -1 and a generic message is emitted.
64  for (int order = 0; order <= 2 * stored_order + 64; ++order)
65  {
66  const mfem::IntegrationRule & candidate = mfem::IntRules.Get(geom, order);
67  if (ip.index < candidate.Size() && SamePoint(candidate.IntPoint(ip.index), ip, dim))
68  {
69  suggested_order = order;
70  break;
71  }
72  }
73 
74  if (suggested_order >= 0)
75  mooseError("MFEM quadrature function '",
76  _name,
77  "' stores values on the order-",
78  stored_order,
79  " quadrature rule (",
80  stored_rule.Size(),
81  " points on this element), but it is being evaluated by an integrator using a "
82  "different quadrature rule (",
83  mfem::IntRules.Get(geom, suggested_order).Size(),
84  " points). The stored values are indexed by quadrature point, so the orders must "
85  "match. Set 'order = ",
86  suggested_order,
87  "' on '",
88  _name,
89  "'.");
90  else
91  mooseError("MFEM quadrature function '",
92  _name,
93  "' stores values on the order-",
94  stored_order,
95  " quadrature rule, but it is being evaluated by an integrator using a different "
96  "quadrature rule. The stored values are indexed by quadrature point, so the orders "
97  "must match; adjust 'order' on '",
98  _name,
99  "' to match the consuming integrator.");
100 }
101 
102 #endif
MetaPhysicL::DualNumber< V, D, asd > abs(const MetaPhysicL::DualNumber< V, D, asd > &a)
Definition: EigenADReal.h:50
void CheckIntegrationRule(const mfem::QuadratureFunction &qf, mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip) const
Verify that the integration point ip supplied by a consuming integrator belongs to the same quadratur...
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:311
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
Definition: Moose.h:165
const std::string _name
Name of the owning MOOSE object, used in error messages.