MFEM v4.9.0
Finite element discretization library
Loading...
Searching...
No Matches
gridfunc.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, 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_GRIDFUNC
13#define MFEM_GRIDFUNC
14
15#include "../config/config.hpp"
16#include "fespace.hpp"
17#include "coefficient.hpp"
18#include "bilininteg.hpp"
19#include "bounds.hpp"
20#ifdef MFEM_USE_ADIOS2
22#endif
23#include <limits>
24#include <ostream>
25#include <string>
26
27namespace mfem
28{
29
30/// Class for grid function - Vector with associated FE space.
31class GridFunction : public Vector
32{
33protected:
34 /// FE space on which the grid function lives. Owned if #fec_owned is not NULL.
36
37 /** @brief Used when the grid function is read from a file. It can also be
38 set explicitly, see MakeOwner().
39
40 If not NULL, this pointer is owned by the GridFunction. */
42
43 long fes_sequence; // see FiniteElementSpace::sequence, Mesh::sequence
44
45 /** Optional, internal true-dof vector: if the FiniteElementSpace #fes has a
46 non-trivial (i.e. not NULL) prolongation operator, this Vector may hold
47 associated true-dof values - either owned or external. */
49
50 void SaveSTLTri(std::ostream &out, real_t p1[], real_t p2[], real_t p3[]);
51
52 // Project the delta coefficient without scaling and return the (local)
53 // integral of the projection.
55 real_t &integral);
56
57 // Sum fluxes to vertices and count element contributions
59 GridFunction &flux,
60 Array<int>& counts,
61 bool wcoef,
62 int subdomain);
63
64 /** Project a discontinuous vector coefficient in a continuous space and
65 return in dof_attr the maximal attribute of the elements containing each
66 degree of freedom. */
68
69 /// Loading helper.
70 void LegacyNCReorder();
71
72 void Destroy();
73
74public:
75
76 GridFunction() { fes = NULL; fec_owned = NULL; fes_sequence = 0; UseDevice(true); }
77
78 /// Copy constructor. The internal true-dof vector #t_vec is not copied.
80 : Vector(orig), fes(orig.fes), fec_owned(NULL), fes_sequence(orig.fes_sequence)
81 { UseDevice(true); }
82
83 /// Construct a GridFunction associated with the FiniteElementSpace @a *f.
85 { fes = f; fec_owned = NULL; fes_sequence = f->GetSequence(); UseDevice(true); }
86
87 /// Construct a GridFunction using previously allocated array @a data.
88 /** The GridFunction does not assume ownership of @a data which is assumed to
89 be of size at least `f->GetVSize()`. Similar to the Vector constructor
90 for externally allocated array, the pointer @a data can be NULL. The data
91 array can be replaced later using the method SetData().
92 */
94 : Vector(data, f->GetVSize())
95 { fes = f; fec_owned = NULL; fes_sequence = f->GetSequence(); UseDevice(true); }
96
97 /** @brief Construct a GridFunction using previously allocated Vector @a base
98 starting at the given offset, @a base_offset. */
99 GridFunction(FiniteElementSpace *f, Vector &base, int base_offset = 0)
100 : Vector(base, base_offset, f->GetVSize())
101 { fes = f; fec_owned = NULL; fes_sequence = f->GetSequence(); UseDevice(true); }
102
103 /// Construct a GridFunction on the given Mesh, using the data from @a input.
104 /** The content of @a input should be in the format created by the method
105 Save(). The reconstructed FiniteElementSpace and FiniteElementCollection
106 are owned by the GridFunction. */
107 GridFunction(Mesh *m, std::istream &input);
108
109 GridFunction(Mesh *m, GridFunction *gf_array[], int num_pieces);
110
111 /// Copy assignment. Only the data of the base class Vector is copied.
112 /** It is assumed that this object and @a rhs use FiniteElementSpace%s that
113 have the same size.
114
115 @note Defining this method overwrites the implicitly defined copy
116 assignment operator. */
118 { return operator=((const Vector &)rhs); }
119
120 /// Make the GridFunction the owner of #fec_owned and #fes.
121 /** If the new FiniteElementCollection, @a fec_, is NULL, ownership of #fec_owned
122 and #fes is taken away. */
124
126
127 /// Shortcut for calling FiniteElementSpace::GetVectorDim() on the underlying #fes
128 int VectorDim() const;
129
130 /// Shortcut for calling FiniteElementSpace::GetCurlDim() on the underlying #fes
131 int CurlDim() const;
132
133 /// Read only access to the (optional) internal true-dof Vector.
134 const Vector &GetTrueVector() const
135 {
136 MFEM_VERIFY(t_vec.Size() > 0, "SetTrueVector() before GetTrueVector()");
137 return t_vec;
138 }
139 /// Read and write access to the (optional) internal true-dof Vector.
140 /** Note that @a t_vec is set if it is not allocated or set already.*/
142 { if (t_vec.Size() == 0) { SetTrueVector(); } return t_vec; }
143
144 /// Extract the true-dofs from the GridFunction.
145 void GetTrueDofs(Vector &tv) const;
146
147 /// Shortcut for calling GetTrueDofs() with GetTrueVector() as argument.
149
150 /// Set the GridFunction from the given true-dof vector.
151 virtual void SetFromTrueDofs(const Vector &tv);
152
153 /// Shortcut for calling SetFromTrueDofs() with GetTrueVector() as argument.
155
156 /** @brief Returns the values at the vertices of element @a i for the 1-based
157 dimension vdim. */
158 void GetNodalValues(int i, Array<real_t> &nval, int vdim = 1) const;
159
160 /** @name Element index Get Value Methods
161
162 These methods take an element index and return the interpolated value of
163 the field at a given reference point within the element.
164
165 @warning These methods retrieve and use the ElementTransformation object
166 from the mfem::Mesh. This can alter the state of the element
167 transformation object and can also lead to unexpected results when the
168 ElementTransformation object is already in use such as when these methods
169 are called from within an integration loop. Consider using
170 GetValue(ElementTransformation &T, ...) instead.
171 */
172 ///@{
173 /** Return a scalar value from within the given element. */
174 virtual real_t GetValue(int i, const IntegrationPoint &ip,
175 int vdim = 1) const;
176
177 /** Return a vector value from within the given element. */
178 virtual void GetVectorValue(int i, const IntegrationPoint &ip,
179 Vector &val) const;
180 ///@}
181
182 /** @name Element Index Get Values Methods
183
184 These are convenience methods for repeatedly calling GetValue for
185 multiple points within a given element. The GetValues methods are
186 optimized and should perform better than repeatedly calling GetValue. The
187 GetVectorValues method simply calls GetVectorValue repeatedly.
188
189 @warning These methods retrieve and use the ElementTransformation object
190 from the mfem::Mesh. This can alter the state of the element
191 transformation object and can also lead to unexpected results when the
192 ElementTransformation object is already in use such as when these methods
193 are called from within an integration loop. Consider using
194 GetValues(ElementTransformation &T, ...) instead.
195 */
196 ///@{
197 /** Compute a collection of scalar values from within the element indicated
198 by the index i. */
199 void GetValues(int i, const IntegrationRule &ir, Vector &vals,
200 int vdim = 1) const;
201
202 /** Compute a collection of vector values from within the element indicated
203 by the index i. */
204 void GetValues(int i, const IntegrationRule &ir, Vector &vals,
205 DenseMatrix &tr, int vdim = 1) const;
206
207 void GetVectorValues(int i, const IntegrationRule &ir,
208 DenseMatrix &vals, DenseMatrix &tr) const;
209 ///@}
210
211 /** @name ElementTransformation Get Value Methods
212
213 These member functions are designed for use within
214 GridFunctionCoefficient objects. These can be used with
215 ElementTransformation objects coming from either
216 Mesh::GetElementTransformation() or Mesh::GetBdrElementTransformation().
217
218 @note These methods do not reset the ElementTransformation object so they
219 should be safe to use within integration loops or other contexts where
220 the ElementTransformation is already in use.
221 */
222 ///@{
223 /** Return a scalar value from within the element indicated by the
224 ElementTransformation Object. */
226 int comp = 0, Vector *tr = NULL) const;
227
228 /** Return a vector value from within the element indicated by the
229 ElementTransformation Object. */
231 const IntegrationPoint &ip,
232 Vector &val, Vector *tr = NULL) const;
233 ///@}
234
235 /** @name ElementTransformation Get Values Methods
236
237 These are convenience methods for repeatedly calling GetValue for
238 multiple points within a given element. They work by calling either the
239 ElementTransformation or FaceElementTransformations versions described
240 above. Consequently, these methods should not be expected to run faster
241 than calling the above methods in an external loop.
242
243 @note These methods do not reset the ElementTransformation object so they
244 should be safe to use within integration loops or other contexts where
245 the ElementTransformation is already in use.
246
247 @note These methods can also be used with FaceElementTransformations
248 objects.
249 */
250 ///@{
251 /** Compute a collection of scalar values from within the element indicated
252 by the ElementTransformation object. */
254 Vector &vals, int comp = 0, DenseMatrix *tr = NULL) const;
255
256 /** Compute a collection of vector values from within the element indicated
257 by the ElementTransformation object. */
259 DenseMatrix &vals, DenseMatrix *tr = NULL) const;
260 ///@}
261
262 /** @name Face Index Get Values Methods
263
264 These methods are designed to work with Discontinuous Galerkin basis
265 functions. They compute field values on the interface between elements,
266 or on boundary elements, by interpolating the field in a neighboring
267 element. The \a side argument indices which neighboring element should be
268 used: 0, 1, or 2 (automatically chosen).
269
270 @warning These methods retrieve and use the FaceElementTransformations
271 object from the mfem::Mesh. This can alter the state of the face element
272 transformations object and can also lead to unexpected results when the
273 FaceElementTransformations object is already in use such as when these
274 methods are called from within an integration loop. Consider using
275 GetValues(ElementTransformation &T, ...) instead.
276 */
277 ///@{
278 /** Compute a collection of scalar values from within the face
279 indicated by the index i. */
280 int GetFaceValues(int i, int side, const IntegrationRule &ir, Vector &vals,
281 DenseMatrix &tr, int vdim = 1) const;
282
283 /** Compute a collection of vector values from within the face
284 indicated by the index i. */
285 int GetFaceVectorValues(int i, int side, const IntegrationRule &ir,
286 DenseMatrix &vals, DenseMatrix &tr) const;
287 ///@}
288
289 void GetLaplacians(int i, const IntegrationRule &ir, Vector &laps,
290 int vdim = 1) const;
291
292 void GetLaplacians(int i, const IntegrationRule &ir, Vector &laps,
293 DenseMatrix &tr, int vdim = 1) const;
294
295 void GetHessians(int i, const IntegrationRule &ir, DenseMatrix &hess,
296 int vdim = 1) const;
297
298 void GetHessians(int i, const IntegrationRule &ir, DenseMatrix &hess,
299 DenseMatrix &tr, int vdim = 1) const;
300
301 void GetValuesFrom(const GridFunction &orig_func);
302
303 void GetBdrValuesFrom(const GridFunction &orig_func);
304
305 void GetVectorFieldValues(int i, const IntegrationRule &ir,
306 DenseMatrix &vals,
307 DenseMatrix &tr, int comp = 0) const;
308
309 /// For a vector grid function, makes sure that the ordering is byNODES.
310 void ReorderByNodes();
311
312 /** @brief Returns the values as a vector at mesh vertices, for the 1-based
313 dimension vdim. */
314 void GetNodalValues(Vector &nval, int vdim = 1) const;
315
316 void GetVectorFieldNodalValues(Vector &val, int comp) const;
317
318 void ProjectVectorFieldOn(GridFunction &vec_field, int comp = 0);
319
320 /** @brief Compute a certain derivative of a function's component.
321 Derivatives of the function are computed at the DOF locations of @a der,
322 and averaged over overlapping DOFs. Thus this function projects the
323 derivative to the FiniteElementSpace of @a der.
324 @param[in] comp Index of the function's component to be differentiated.
325 The index is 1-based, i.e., use 1 for scalar functions.
326 @param[in] der_comp Use 0/1/2 for derivatives in x/y/z directions.
327 @param[out] der The resulting derivative (scalar function). The
328 FiniteElementSpace of this function must be set
329 before the call. */
330 void GetDerivative(int comp, int der_comp, GridFunction &der) const;
331
333
334 void GetCurl(ElementTransformation &tr, Vector &curl) const;
335
336 /** @brief Gradient of a scalar function at a quadrature point.
337
338 @note It is assumed that the IntegrationPoint of interest has been
339 specified by ElementTransformation::SetIntPoint() before calling
340 GetGradient().
341
342 @note Can be used from a ParGridFunction when @a tr is an
343 ElementTransformation of a face-neighbor element and face-neighbor data
344 has been exchanged. */
345 void GetGradient(ElementTransformation &tr, Vector &grad) const;
346
347 /// Extension of GetGradient(...) for a collection of IntegrationPoints.
349 DenseMatrix &grad) const;
350
351 /// Extension of GetGradient(...) for a collection of IntegrationPoints.
352 void GetGradients(const int elem, const IntegrationRule &ir,
353 DenseMatrix &grad) const
354 { GetGradients(*fes->GetElementTransformation(elem), ir, grad); }
355
356 /** @brief Compute the vector gradient with respect to the physical element
357 variable. */
359
360 /** @brief Compute the vector gradient with respect to the reference element
361 variable. */
363
364 /** @brief Evaluate the gradients of the GridFunction at the given quadrature
365 points, @a ir, in all mesh elements. */
366 /** This method assumes that all mesh elements are the same type and that the
367 IntegrationRule @a ir is consistent with that type of element.
368
369 @param[in] ir Quadrature points at which the gradients are to be
370 evaluated.
371 @param[out] grad Output vector of size `SDIM*VDIM*NQ*NE` where `SDIM` is
372 the spatial dimention of the mesh, `VDIM` is the vector
373 dimension of the GridFunction, `NQ` is the number of
374 quadrature points in @a ir, and `NE` is the number of
375 elements in the mesh. The layout of @a grad is
376 determined by the parameter @a ql: when @a ql is
377 QVectorLayout::byNODES, the layout is
378 `NQ x VDIM x SDIM x NE`; when @a ql is
379 QVectorLayout::byVDIM, the layout is
380 `VDIM x SDIM x NQ x NE`.
381 @param[in] ql Determines the layout of the output vector @a grad; see
382 the description of @a grad for details.
383 @param[in] d_mt MemoryType to use for allocating the output vector
384 @a grad, as well the GeometricFactors and temporary
385 vector used by the method. By default, the current
386 device memory type is used. */
387 void GetGradients(const IntegrationRule &ir, Vector &grad,
389 MemoryType d_mt = MemoryType::DEFAULT) const;
390
391 /** Compute $ (\int_{\Omega} (*this) \psi_i)/(\int_{\Omega} \psi_i) $,
392 where $ \psi_i $ are the basis functions for the FE space of avgs.
393 Both FE spaces should be scalar and on the same mesh. */
394 void GetElementAverages(GridFunction &avgs) const;
395
396 /** Sets the output vector @a dof_vals to the values of the degrees of
397 freedom of element @a el. */
398 virtual void GetElementDofValues(int el, Vector &dof_vals) const;
399
400 /** Impose the given bounds on the function's DOFs while preserving its local
401 * integral (described in terms of the given weights) on the i'th element
402 * through SLBPQ optimization.
403 * Intended to be used for discontinuous FE functions. */
404 void ImposeBounds(int i, const Vector &weights,
405 const Vector &lo_, const Vector &hi_);
406 void ImposeBounds(int i, const Vector &weights,
407 real_t min_ = 0.0, real_t max_ = infinity());
408
409 /** On a non-conforming mesh, make sure the function lies in the conforming
410 space by multiplying with R and then with P, the conforming restriction
411 and prolongation matrices of the space, respectively. */
412 void RestrictConforming();
413
414 /** @brief Project the @a src GridFunction to @a this GridFunction, both of
415 which must be on the same mesh. */
416 /** The current implementation assumes that all elements use the same
417 projection matrix. */
418 void ProjectGridFunction(const GridFunction &src);
419
420 /** @brief Project @a coeff Coefficient to @a this GridFunction. The
421 projection computation depends on the choice of the FiniteElementSpace
422 #fes. Note that this is usually interpolation at the degrees of freedom
423 in each element (not L2 projection). For NURBS spaces these degrees of
424 freedom are not available and L2 projection is resorted to as fallback. */
425 virtual void ProjectCoefficient(Coefficient &coeff);
426
427 /** @brief Project @a coeff Coefficient to @a this GridFunction, using one
428 element for each degree of freedom in @a dofs and nodal interpolation on
429 that element. */
430 void ProjectCoefficient(Coefficient &coeff, Array<int> &dofs, int vd = 0);
431
432 /** @brief Project @a vcoeff VectorCoefficient to @a this GridFunction. The
433 projection computation depends on the choice of the FiniteElementSpace
434 #fes. Note that this is usually interpolation at the degrees of freedom
435 in each element (not L2 projection). For NURBS spaces these degrees of
436 freedom are not available and L2 projection is resorted to as fallback. */
438
439 /** @brief Project @a vcoeff VectorCoefficient to @a this GridFunction, using
440 one element for each degree of freedom in @a dofs and nodal interpolation
441 on that element. */
443
444 /** @brief Project @a vcoeff VectorCoefficient to @a this GridFunction, only
445 projecting onto elements with the given @a attribute */
446 void ProjectCoefficient(VectorCoefficient &vcoeff, int attribute);
447
448 /** @brief Analogous to the version with argument @a vcoeff VectorCoefficient
449 but using an array of scalar coefficients for each component. */
450 void ProjectCoefficient(Coefficient *coeff[]);
451
452 /** @brief Project a discontinuous vector coefficient as a grid function on
453 a continuous finite element space. The values in shared dofs are
454 determined from the element with maximal attribute. */
455 virtual void ProjectDiscCoefficient(VectorCoefficient &coeff);
456
458 /** @brief Projects a discontinuous coefficient so that the values in shared
459 vdofs are computed by taking an average of the possible values. */
460 virtual void ProjectDiscCoefficient(Coefficient &coeff, AvgType type);
461 /** @brief Projects a discontinuous _vector_ coefficient so that the values
462 in shared vdofs are computed by taking an average of the possible values.
463 */
464 virtual void ProjectDiscCoefficient(VectorCoefficient &coeff, AvgType type);
465
466 /** @brief Return a GridFunction with the values of this, prolongated to the
467 maximum order of all elements in the mesh. */
468 std::unique_ptr<GridFunction> ProlongateToMaxOrder() const;
469
470protected:
471 /** @brief Accumulates (depending on @a type) the values of @a coeff at all
472 shared vdofs and counts in how many zones each vdof appears. */
474 Array<int> &zones_per_vdof);
475
476 /** @brief Accumulates (depending on @a type) the values of @a vcoeff at all
477 shared vdofs and counts in how many zones each vdof appears. */
479 Array<int> &zones_per_vdof);
480
481 /** @brief Used for the serial and parallel implementations of the
482 GetDerivative() method; see its documentation. */
483 void AccumulateAndCountDerivativeValues(int comp, int der_comp,
484 GridFunction &der,
485 Array<int> &zones_per_dof) const;
486
488 VectorCoefficient *vcoeff,
489 const Array<int> &attr,
490 Array<int> &values_counter);
491
493 const Array<int> &bdr_attr,
494 Array<int> &values_counter);
495
496 // Complete the computation of averages; called e.g. after
497 // AccumulateAndCountZones().
498 void ComputeMeans(AvgType type, Array<int> &zones_per_vdof);
499
500 /// P-refinement version of Update().
501 void UpdatePRef();
502
503public:
504 /** @brief For each vdof, counts how many elements contain the vdof,
505 as containment is determined by FiniteElementSpace::GetElementVDofs(). */
506 virtual void CountElementsPerVDof(Array<int> &elem_per_vdof) const;
507
508 /** @brief Project a Coefficient on the GridFunction, modifying only DOFs on
509 the boundary associated with the boundary attributes marked in the
510 @a attr array. */
512 {
513 Coefficient *coeff_p = &coeff;
514 ProjectBdrCoefficient(&coeff_p, attr);
515 }
516
517 /** @brief Project a VectorCoefficient on the GridFunction, modifying only
518 DOFs on the boundary associated with the boundary attributes marked in
519 the @a attr array. */
520 virtual void ProjectBdrCoefficient(VectorCoefficient &vcoeff,
521 const Array<int> &attr);
522
523 /** @brief Project a set of Coefficient%s on the components of the
524 GridFunction, modifying only DOFs on the boundary associated with the
525 boundary attributed marked in the @a attr array. */
526 /** If a Coefficient pointer in the array @a coeff is NULL, that component
527 will not be touched. */
528 virtual void ProjectBdrCoefficient(Coefficient *coeff[],
529 const Array<int> &attr);
530
531 /** Project the normal component of the given VectorCoefficient on
532 the boundary. Only boundary attributes that are marked in
533 'bdr_attr' are projected. Assumes RT-type VectorFE GridFunction. */
535 const Array<int> &bdr_attr);
536
537 /** @brief Project the tangential components of the given VectorCoefficient
538 on the boundary. Only boundary attributes that are marked in @a bdr_attr
539 are projected. Assumes ND-type VectorFE GridFunction. */
541 const Array<int> &bdr_attr);
542
543 /// @brief Returns ||exsol - u_h||_L2 for scalar or vector H1 or L2 elements
544 ///
545 /// @param[in] exsol Pointer to an array of scalar Coefficient objects,
546 /// one for each component of the vector field. The
547 /// length of the array should be at least equal to
548 /// FiniteElementSpace::GetVDim().
549 /// @param[in] irs Optional pointer to an array of custom integration
550 /// rules e.g. higher order than the default rules. If
551 /// present the array will be indexed by Geometry::Type.
552 /// @param[in] elems Optional pointer to a marker array, with a length
553 /// equal to the number of local elements, indicating
554 /// which elements to integrate over. Only those elements
555 /// corresponding to non-zero entries in @a elems will
556 /// contribute to the computed L2 error.
557 ///
558 /// @note If an array of integration rules is provided through @a irs, be
559 /// sure to include valid rules for each element type that may occur
560 /// in the list of elements.
561 ///
562 /// @note Quadratures with negative weights (as in some simplex integration
563 /// rules in MFEM) can produce negative integrals even with
564 /// non-negative integrands. To avoid returning negative errors this
565 /// function uses the absolute values of the element-wise integrals.
566 /// This may lead to results which are not entirely consistent with
567 /// such integration rules.
568 virtual real_t ComputeL2Error(Coefficient *exsol[],
569 const IntegrationRule *irs[] = NULL,
570 const Array<int> *elems = NULL) const;
571
572 /// @brief Returns ||grad u_ex - grad u_h||_L2 in element ielem for
573 /// H1 or L2 elements
574 ///
575 /// @param[in] ielem Index of the element in which to compute the L2 error.
576 /// @param[in] exgrad Pointer to a VectorCoefficient object reproducing the
577 /// expected gradient of the scalar field, grad u_ex.
578 /// @param[in] irs Optional pointer to an array of custom integration
579 /// rules e.g. higher order than the default rules. If
580 /// present the array will be indexed by Geometry::Type.
581 ///
582 /// @note If an array of integration rules is provided through @a irs, be
583 /// sure to include valid rules for each element type that may occur
584 /// in the list of elements.
585 ///
586 /// @note Quadratures with negative weights (as in some simplex integration
587 /// rules in MFEM) can produce negative integrals even with
588 /// non-negative integrands. To avoid returning negative errors this
589 /// function uses the absolute values of the element-wise integrals.
590 /// This may lead to results which are not entirely consistent with
591 /// such integration rules.
592 virtual real_t ComputeElementGradError(int ielem, VectorCoefficient *exgrad,
593 const IntegrationRule *irs[] = NULL) const;
594
595 /// @brief Returns ||u_ex - u_h||_L2 for H1 or L2 elements
596 ///
597 /// @param[in] exsol Coefficient object reproducing the anticipated values
598 /// of the scalar field, u_ex.
599 /// @param[in] irs Optional pointer to an array of custom integration
600 /// rules e.g. higher order than the default rules. If
601 /// present the array will be indexed by Geometry::Type.
602 /// @param[in] elems Optional pointer to a marker array, with a length
603 /// equal to the number of local elements, indicating
604 /// which elements to integrate over. Only those elements
605 /// corresponding to non-zero entries in @a elems will
606 /// contribute to the computed L2 error.
607 ///
608 /// @note If an array of integration rules is provided through @a irs, be
609 /// sure to include valid rules for each element type that may occur
610 /// in the list of elements.
611 ///
612 /// @note Quadratures with negative weights (as in some simplex integration
613 /// rules in MFEM) can produce negative integrals even with
614 /// non-negative integrands. To avoid returning negative errors this
615 /// function uses the absolute values of the element-wise integrals.
616 /// This may lead to results which are not entirely consistent with
617 /// such integration rules.
619 const IntegrationRule *irs[] = NULL,
620 const Array<int> *elems = NULL) const
621 { return GridFunction::ComputeLpError(2.0, exsol, NULL, irs, elems); }
622
623 /// @brief Returns ||u_ex - u_h||_L2 for vector fields
624 ///
625 /// @param[in] exsol VectorCoefficient object reproducing the anticipated
626 /// values of the vector field, u_ex.
627 /// @param[in] irs Optional pointer to an array of custom integration
628 /// rules e.g. higher order than the default rules. If
629 /// present the array will be indexed by Geometry::Type.
630 /// @param[in] elems Optional pointer to a marker array, with a length
631 /// equal to the number of local elements, indicating
632 /// which elements to integrate over. Only those elements
633 /// corresponding to non-zero entries in @a elems will
634 /// contribute to the computed L2 error.
635 ///
636 /// @note If an array of integration rules is provided through @a irs, be
637 /// sure to include valid rules for each element type that may occur
638 /// in the list of elements.
639 ///
640 /// @note Quadratures with negative weights (as in some simplex integration
641 /// rules in MFEM) can produce negative integrals even with
642 /// non-negative integrands. To avoid returning negative errors this
643 /// function uses the absolute values of the element-wise integrals.
644 /// This may lead to results which are not entirely consistent with
645 /// such integration rules.
647 const IntegrationRule *irs[] = NULL,
648 const Array<int> *elems = NULL) const;
649
650 /// @brief Returns ||grad u_ex - grad u_h||_L2 for H1 or L2 elements
651 ///
652 /// @param[in] exgrad Pointer to a VectorCoefficient object reproducing the
653 /// expected gradient of the scalar field, grad u_ex.
654 /// @param[in] irs Optional pointer to an array of custom integration
655 /// rules e.g. higher order than the default rules. If
656 /// present the array will be indexed by Geometry::Type.
657 ///
658 /// @note This function only computes the error of the gradient in the
659 /// interior of the elements. In the context of discontinuous
660 /// Galerkin (DG) methods it may also be desirable to compute the
661 /// error in the jumps across element interfaces using
662 /// ComputeDGFaceJumpError().
663 ///
664 /// @note If an array of integration rules is provided through @a irs, be
665 /// sure to include valid rules for each element type that may occur
666 /// in the list of elements.
667 ///
668 /// @note Quadratures with negative weights (as in some simplex integration
669 /// rules in MFEM) can produce negative integrals even with
670 /// non-negative integrands. To avoid returning negative errors this
671 /// function uses the absolute values of the element-wise integrals.
672 /// This may lead to results which are not entirely consistent with
673 /// such integration rules.
675 const IntegrationRule *irs[] = NULL) const;
676
677 /// @brief Returns ||curl u_ex - curl u_h||_L2 for ND elements
678 ///
679 /// @param[in] excurl Pointer to a VectorCoefficient object reproducing the
680 /// expected curl of the vector field, curl u_ex.
681 /// @param[in] irs Optional pointer to an array of custom integration
682 /// rules e.g. higher order than the default rules. If
683 /// present the array will be indexed by Geometry::Type.
684 ///
685 /// @note If an array of integration rules is provided through @a irs, be
686 /// sure to include valid rules for each element type that may occur
687 /// in the list of elements.
688 ///
689 /// @note Quadratures with negative weights (as in some simplex integration
690 /// rules in MFEM) can produce negative integrals even with
691 /// non-negative integrands. To avoid returning negative errors this
692 /// function uses the absolute values of the element-wise integrals.
693 /// This may lead to results which are not entirely consistent with
694 /// such integration rules.
696 const IntegrationRule *irs[] = NULL) const;
697
698 /// @brief Returns ||div u_ex - div u_h||_L2 for RT elements
699 ///
700 /// @param[in] exdiv Pointer to a Coefficient object reproducing the
701 /// expected divergence of the vector field, div u_ex.
702 /// @param[in] irs Optional pointer to an array of custom integration
703 /// rules e.g. higher order than the default rules. If
704 /// present the array will be indexed by Geometry::Type.
705 ///
706 /// @note If an array of integration rules is provided through @a irs, be
707 /// sure to include valid rules for each element type that may occur
708 /// in the list of elements.
709 ///
710 /// @note Quadratures with negative weights (as in some simplex integration
711 /// rules in MFEM) can produce negative integrals even with
712 /// non-negative integrands. To avoid returning negative errors this
713 /// function uses the absolute values of the element-wise integrals.
714 /// This may lead to results which are not entirely consistent with
715 /// such integration rules.
716 virtual real_t ComputeDivError(Coefficient *exdiv,
717 const IntegrationRule *irs[] = NULL) const;
718
719 /// @brief Returns the Face Jumps error for L2 elements.
720 ///
721 /// Computes:
722 /// $$\sqrt{\sum_{f\in faces}\int_f js(f) ell(f)
723 /// (2 u_{ex} - u_1 - u_2)^2}$$
724 ///
725 /// Where js[f] is the jump_scaling evaluated on the face f and ell is the
726 /// average of ell_coef evaluated in the two elements sharing the face f.
727 ///
728 /// @param[in] exsol Pointer to a Coefficient object reproducing the
729 /// anticipated values of the scalar field, u_ex.
730 /// @param[in] ell_coeff Pointer to a Coefficient object used to compute
731 /// the averaged value ell in the above integral.
732 /// @param[in] jump_scaling Can be configured to provide scaling by
733 /// nu, nu/h, or nu*p^2/h
734 /// @param[in] irs Optional pointer to an array of custom
735 /// integration rules e.g. higher order than the
736 /// default rules. If present the array will be
737 /// indexed by Geometry::Type.
738 ///
739 /// @note If an array of integration rules is provided through @a irs, be
740 /// sure to include valid rules for each element type that may occur
741 /// in the list of faces.
742 ///
743 /// @note Quadratures with negative weights (as in some simplex integration
744 /// rules in MFEM) can produce negative integrals even with
745 /// non-negative integrands. To avoid returning negative errors this
746 /// function uses the absolute values of the element-wise integrals.
747 /// This may lead to results which are not entirely consistent with
748 /// such integration rules.
750 Coefficient *ell_coeff,
751 class JumpScaling jump_scaling,
752 const IntegrationRule *irs[] = NULL)
753 const;
754
755 /// @brief Returns the Face Jumps error for L2 elements, with 1/h scaling.
756 ///
757 /// @note Quadratures with negative weights (as in some simplex integration
758 /// rules in MFEM) can produce negative integrals even with
759 /// non-negative integrands. To avoid returning negative errors this
760 /// function uses the absolute values of the element-wise integrals.
761 /// This may lead to results which are not entirely consistent with
762 /// such integration rules.
763 ///
764 /// @deprecated See @ref ComputeDGFaceJumpError(Coefficient *exsol,
765 /// Coefficient *ell_coeff,
766 /// class JumpScaling jump_scaling,
767 /// const IntegrationRule *irs[]) const
768 /// for the preferred implementation.
769 MFEM_DEPRECATED
771 Coefficient *ell_coeff,
772 real_t Nu,
773 const IntegrationRule *irs[] = NULL) const;
774
775 /** This method is kept for backward compatibility.
776
777 Returns either the H1-seminorm, or the DG face jumps error, or both
778 depending on norm_type = 1, 2, 3. Additional arguments for the DG face
779 jumps norm: ell_coeff: mesh-depended coefficient (weight) Nu: scalar
780 constant weight */
781 virtual real_t ComputeH1Error(Coefficient *exsol, VectorCoefficient *exgrad,
782 Coefficient *ell_coef, real_t Nu,
783 int norm_type) const;
784
785 /// @brief Returns the error measured in H1-norm for H1 or L2 elements
786 ///
787 /// Computes the norm using the $L^2$ norms of the function and its gradient
788 /// $$\sqrt{norm\_u^2 + norm\_du^2}$$
789 /// Where
790 /// $$norm\_u = \|u_{ex} - u_h\|_{L^2}$$
791 /// and
792 /// $$norm\_du = \|du_{ex} - \nabla u_h\|_{L^2}$$
793 ///
794 /// @param[in] exsol Coefficient object reproducing the anticipated values
795 /// of the scalar field, u_ex.
796 /// @param[in] exgrad VectorCoefficient object reproducing the anticipated
797 /// values of the gradient of the scalar field, du_ex.
798 /// @param[in] irs Optional pointer to an array of custom integration
799 /// rules e.g. higher order than the default rules. If
800 /// present the array will be indexed by Geometry::Type.
801 ///
802 /// @note If an array of integration rules is provided through @a irs, be
803 /// sure to include valid rules for each element type that may occur
804 /// in the list of elements.
805 ///
806 /// @note Quadratures with negative weights (as in some simplex integration
807 /// rules in MFEM) can produce negative integrals even with
808 /// non-negative integrands. To avoid returning negative errors this
809 /// function uses the absolute values of the element-wise integrals.
810 /// This may lead to results which are not entirely consistent with
811 /// such integration rules.
812 ///
813 /// @note For L2 elements this returns what could be called a "broken"
814 /// H1-norm.
815 virtual real_t ComputeH1Error(Coefficient *exsol, VectorCoefficient *exgrad,
816 const IntegrationRule *irs[] = NULL) const;
817
818 /// @brief Returns the error measured in H(div)-norm for RT elements
819 ///
820 /// Computes the norm using the $L^2$ norms of the function and its
821 /// divergence
822 /// $$\sqrt{norm\_u^2 + norm\_du^2}$$
823 /// Where
824 /// $$norm\_u = \|u_{ex} - u_h\|_{L^2}$$
825 /// and
826 /// $$norm\_du = \|du_{ex} - \nabla\cdot u_h\|_{L^2}$$
827 ///
828 /// @param[in] exsol VectorCoefficient object reproducing the anticipated
829 /// values of the vector field, u_ex.
830 /// @param[in] exdiv VectorCoefficient object reproducing the anticipated
831 /// values of the divergence of the vector field, du_ex.
832 /// @param[in] irs Optional pointer to an array of custom integration
833 /// rules e.g. higher order than the default rules. If
834 /// present the array will be indexed by Geometry::Type.
835 ///
836 /// @note If an array of integration rules is provided through @a irs, be
837 /// sure to include valid rules for each element type that may occur
838 /// in the list of elements.
839 ///
840 /// @note Quadratures with negative weights (as in some simplex integration
841 /// rules in MFEM) can produce negative integrals even with
842 /// non-negative integrands. To avoid returning negative errors this
843 /// function uses the absolute values of the element-wise integrals.
844 /// This may lead to results which are not entirely consistent with
845 /// such integration rules.
847 Coefficient *exdiv,
848 const IntegrationRule *irs[] = NULL) const;
849
850 /// @brief Returns the error measured in H(curl)-norm for ND elements
851 ///
852 /// Computes the norm using the $L^2$ norms of the function and its curl
853 /// $$\sqrt{norm\_u^2 + norm\_du^2}$$
854 /// Where
855 /// $$norm\_u = \|u_{ex} - u_h\|_{L^2}$$
856 /// and
857 /// $$norm\_du = \|du_{ex} - \nabla\times u_h\|_{L^2}$$
858 ///
859 /// @param[in] exsol VectorCoefficient object reproducing the anticipated
860 /// values of the vector field, u_ex.
861 /// @param[in] excurl VectorCoefficient object reproducing the anticipated
862 /// values of the curl of the vector field, du_ex.
863 /// @param[in] irs Optional pointer to an array of custom integration
864 /// rules e.g. higher order than the default rules. If
865 /// present the array will be indexed by Geometry::Type.
866 ///
867 /// @note If an array of integration rules is provided through @a irs, be
868 /// sure to include valid rules for each element type that may occur
869 /// in the list of elements.
870 ///
871 /// @note Quadratures with negative weights (as in some simplex integration
872 /// rules in MFEM) can produce negative integrals even with
873 /// non-negative integrands. To avoid returning negative errors this
874 /// function uses the absolute values of the element-wise integrals.
875 /// This may lead to results which are not entirely consistent with
876 /// such integration rules.
878 VectorCoefficient *excurl,
879 const IntegrationRule *irs[] = NULL) const;
880
881 /// @brief Returns Max|u_ex - u_h| error for H1 or L2 elements
882 ///
883 /// Compute the $L^\infty$ error across the entire domain.
884 ///
885 /// @param[in] exsol Coefficient object reproducing the anticipated
886 /// values of the scalar field, u_ex.
887 /// @param[in] irs Optional pointer to an array of custom integration
888 /// rules e.g. higher order than the default rules. If
889 /// present the array will be indexed by
890 /// Geometry::Type.
891 ///
892 /// @note Uses ComputeLpError internally. See the ComputeLpError
893 /// documentation for generalizations of this error computation.
894 ///
895 /// @note If an array of integration rules is provided through @a irs, be
896 /// sure to include valid rules for each element type that may occur
897 /// in the list of elements.
898 ///
900 const IntegrationRule *irs[] = NULL) const
901 {
902 return ComputeLpError(infinity(), exsol, NULL, irs);
903 }
904
905 /// @brief Returns Max|u_ex - u_h| error for scalar or vector fields
906 ///
907 /// Compute the $L^\infty$ error across the entire domain.
908 ///
909 /// Computes:
910 /// $$max_{elems} (max_{elem} |scalar\_error|)$$
911 ///
912 /// Where
913 /// $$scalar\_error = max_{d=0\ldots vdim}|u_{ex}[d] - u_h[d]|$$
914 ///
915 /// @param[in] exsol Pointer to an array of scalar Coefficient objects,
916 /// one for each component of the vector field. The
917 /// length of the array should be at least equal to
918 /// FiniteElementSpace::GetVDim().
919 /// @param[in] irs Optional pointer to an array of custom integration
920 /// rules e.g. higher order than the default rules. If
921 /// present the array will be indexed by Geometry::Type.
922 ///
923 /// @note This implementation of the max error of a vector field computes
924 /// the max norm over vector components rather than the magnitude of
925 /// the vector.
926 ///
927 /// @note If an array of integration rules is provided through @a irs, be
928 /// sure to include valid rules for each element type that may occur
929 /// in the list of elements.
930 ///
931 virtual real_t ComputeMaxError(Coefficient *exsol[],
932 const IntegrationRule *irs[] = NULL) const;
933
934 /// @brief Returns Max|u_ex - u_h| error for vector fields
935 ///
936 /// Compute the $L^\infty$ error across the entire domain.
937 ///
938 /// Computes:
939 /// $$max_{elems} (max_{elem} |scalar\_error|)$$
940 ///
941 /// Where
942 /// $$scalar\_error = \sqrt{(u_{ex} - u_h) \cdot (u_{ex} - u_h)}$$
943 ///
944 /// @param[in] exsol VectorCoefficient object reproducing the
945 /// anticipated values of the vector field, u_ex.
946 /// @param[in] irs Optional pointer to an array of custom integration
947 /// rules e.g. higher order than the default rules. If
948 /// present the array will be indexed by
949 /// Geometry::Type.
950 ///
951 /// @note Uses ComputeLpError internally. See the ComputeLpError
952 /// documentation for generalizations of this error computation.
953 ///
954 /// @note Computes the maximum magnitude of the difference vector not the
955 /// component-wise maximum difference of the vector fields.
956 ///
957 /// @note If an array of integration rules is provided through @a irs, be
958 /// sure to include valid rules for each element type that may occur
959 /// in the list of elements.
960 ///
962 const IntegrationRule *irs[] = NULL) const
963 {
964 return ComputeLpError(infinity(), exsol, NULL, NULL, irs);
965 }
966
967 /// @brief Returns ||u_ex - u_h||_L1 for H1 or L2 elements
968 ///
969 /// Computes:
970 /// $$\sum_{elems} \int_{elem} |u_{ex} - u_h|$$
971 ///
972 /// @param[in] exsol Coefficient object reproducing the anticipated values
973 /// of the scalar field, u_ex.
974 /// @param[in] irs Optional pointer to an array of custom integration
975 /// rules e.g. higher order than the default rules. If
976 /// present the array will be indexed by Geometry::Type.
977 ///
978 /// @note Quadratures with negative weights (as in some simplex integration
979 /// rules in MFEM) can produce negative integrals even with
980 /// non-negative integrands. To avoid returning negative errors this
981 /// function uses the absolute values of the element-wise integrals.
982 /// This may lead to results which are not entirely consistent with
983 /// such integration rules.
984 ///
985 /// @note Uses ComputeLpError internally. See the ComputeLpError
986 /// documentation for generalizations of this error computation.
987 ///
988 /// @note If an array of integration rules is provided through @a irs, be
989 /// sure to include valid rules for each element type that may occur
990 /// in the list of elements.
991 ///
993 const IntegrationRule *irs[] = NULL) const
994 { return ComputeLpError(1.0, exsol, NULL, irs); }
995
996 /// @brief Returns ||u_ex - u_h||_L1 for H1 or L2 elements
997 ///
998 /// Computes:
999 /// $$\sum_{elems} \int_{elem} |u_{ex} - u_h|$$
1000 ///
1001 /// @param[in] exsol Pointer to an array of Coefficient objects
1002 /// reproducing the anticipated values of the scalar
1003 /// field, u_ex. Only the first entry of this array will
1004 /// be accessed.
1005 /// @param[in] irs Optional pointer to an array of custom integration
1006 /// rules e.g. higher order than the default rules. If
1007 /// present the array will be indexed by Geometry::Type.
1008 ///
1009 /// @note If an array of integration rules is provided through @a irs, be
1010 /// sure to include valid rules for each element type that may occur
1011 /// in the list of elements.
1012 ///
1013 /// @note Quadratures with negative weights (as in some simplex integration
1014 /// rules in MFEM) can produce negative integrals even with
1015 /// non-negative integrands. To avoid returning negative errors this
1016 /// function uses the absolute values of the element-wise integrals.
1017 /// This may lead to results which are not entirely consistent with
1018 /// such integration rules.
1019 ///
1020 /// @note Uses ComputeW11Error internally. See the ComputeW11Error
1021 /// documentation for generalizations of this error computation.
1022 ///
1023 /// @warning While this function is nominally equivalent to ComputeLpError,
1024 /// with appropriate arguments, the returned errors may differ
1025 /// noticeably because ComputeLpError uses a higher order
1026 /// integration rule by default.
1027 ///
1028 /// @deprecated See @ref ComputeL1Error(Coefficient &exsol,
1029 /// const IntegrationRule *irs[]) const
1030 /// for the preferred implementation.
1031 MFEM_DEPRECATED
1033 const IntegrationRule *irs[] = NULL) const
1034 { return ComputeW11Error(*exsol, NULL, 1, NULL, irs); }
1035
1036 /// @brief Returns $W^1_1$ norm (or portions thereof) for H1 or L2 elements
1037 ///
1038 /// Computes for norm_type == 1 the $L^1$ norm of $u$:
1039 /// $$(\sum_{elems} \int_{elem} |u_{ex} - u_h|$$
1040 ///
1041 /// Computes for norm_type == 2 the $L^1$ semi-norm of $\nabla u$:
1042 /// $$(\sum_{elems} \int_{elem} |du_{ex} - \nabla u_h|$$
1043 ///
1044 /// Computes for norm_type == 3 the $W^1_1$ norm of $u$:
1045 /// $$(\sum_{elems} \int_{elem} |u_{ex} - u_h| + |du_{ex} - \nabla u_h|$$
1046 ///
1047 /// @param[in] exsol Pointer to Coefficient object reproducing the
1048 /// anticipated values of the scalar field, u_ex.
1049 /// @param[in] exgrad Pointer to VectorCoefficient object reproducing the
1050 /// anticipated values of the gradient of the scalar
1051 /// field, du_ex.
1052 /// @param[in] norm_type Integer value of 1, 2, or 3 indicating the type of
1053 /// norm to compute (see above).
1054 /// @param[in] elems Optional pointer to a marker array, with a length
1055 /// equal to the number of local elements, indicating
1056 /// which elements to integrate over. Only those
1057 /// elements corresponding to non-zero entries in
1058 /// @a elems will contribute to the computed $W^1_1$
1059 /// error.
1060 /// @param[in] irs Optional pointer to an array of custom integration
1061 /// rules e.g. higher order than the default rules. If
1062 /// present the array will be indexed by Geometry::Type.
1063 ///
1064 /// @note If an array of integration rules is provided through @a irs, be
1065 /// sure to include valid rules for each element type that may occur
1066 /// in the list of elements.
1067 ///
1068 /// @note Quadratures with negative weights (as in some simplex integration
1069 /// rules in MFEM) can produce negative integrals even with
1070 /// non-negative integrands. To avoid returning negative errors this
1071 /// function uses the absolute values of the element-wise integrals.
1072 /// This may lead to results which are not entirely consistent with
1073 /// such integration rules.
1074 virtual real_t ComputeW11Error(Coefficient *exsol, VectorCoefficient *exgrad,
1075 int norm_type, const Array<int> *elems = NULL,
1076 const IntegrationRule *irs[] = NULL) const;
1077
1078 /// @brief Returns ||u_ex - u_h||_L1 for vector fields
1079 ///
1080 /// Computes:
1081 /// $$\sum_{elems} \int_{elem} |scalar\_error|$$
1082 ///
1083 /// Where
1084 /// $$scalar\_error = \sqrt{(u_{ex} - u_h) \cdot (u_{ex} - u_h)}$$
1085 ///
1086 /// @param[in] exsol VectorCoefficient object reproducing the anticipated
1087 /// values of the vector field, u_ex.
1088 /// @param[in] irs Optional pointer to an array of custom integration
1089 /// rules e.g. higher order than the default rules. If
1090 /// present the array will be indexed by Geometry::Type.
1091 ///
1092 /// @note If an array of integration rules is provided through @a irs, be
1093 /// sure to include valid rules for each element type that may occur
1094 /// in the list of elements.
1095 ///
1096 /// @note Quadratures with negative weights (as in some simplex integration
1097 /// rules in MFEM) can produce negative integrals even with
1098 /// non-negative integrands. To avoid returning negative errors this
1099 /// function uses the absolute values of the element-wise integrals.
1100 /// This may lead to results which are not entirely consistent with
1101 /// such integration rules.
1102 ///
1103 /// @note Uses ComputeLpError internally. See the ComputeLpError
1104 /// documentation for generalizations of this error computation.
1106 const IntegrationRule *irs[] = NULL) const
1107 { return ComputeLpError(1.0, exsol, NULL, NULL, irs); }
1108
1109 /// @brief Returns ||u_ex - u_h||_Lp for H1 or L2 elements
1110 ///
1111 /// Computes:
1112 /// $$(\sum_{elems} \int_{elem} w \, |u_{ex} - u_h|^p)^{1/p}$$
1113 ///
1114 /// @param[in] p Real value indicating the exponent of the $L^p$ norm.
1115 /// To avoid domain errors p should have a positive value,
1116 /// either finite or infinite.
1117 /// @param[in] exsol Coefficient object reproducing the anticipated values
1118 /// of the scalar field, u_ex.
1119 /// @param[in] weight Optional pointer to a Coefficient object reproducing
1120 /// a weighting function, w.
1121 /// @param[in] irs Optional pointer to an array of custom integration
1122 /// rules e.g. higher order than the default rules. If
1123 /// present the array will be indexed by Geometry::Type.
1124 /// @param[in] elems Optional pointer to a marker array, with a length
1125 /// equal to the number of local elements, indicating
1126 /// which elements to integrate over. Only those elements
1127 /// corresponding to non-zero entries in @a elems will
1128 /// contribute to the computed L2 error.
1129 ///
1130 /// @note If an array of integration rules is provided through @a irs, be
1131 /// sure to include valid rules for each element type that may occur
1132 /// in the list of elements.
1133 ///
1134 /// @note Quadratures with negative weights (as in some simplex integration
1135 /// rules in MFEM) can produce negative integrals even with
1136 /// non-negative integrands. To avoid returning negative errors this
1137 /// function uses the absolute values of the element-wise integrals.
1138 /// This may lead to results which are not entirely consistent with
1139 /// such integration rules.
1140 virtual real_t ComputeLpError(const real_t p, Coefficient &exsol,
1141 Coefficient *weight = NULL,
1142 const IntegrationRule *irs[] = NULL,
1143 const Array<int> *elems = NULL) const;
1144
1145 /// @brief Returns ||u_ex - u_h||_Lp elementwise for H1 or L2 elements
1146 ///
1147 /// Compute the Lp error in each element of the mesh and store the results in
1148 /// the Vector @a error. The result should be of length number of elements,
1149 /// for example an L2 GridFunction of order zero using map type @ref
1150 /// map_type_value "VALUE".
1151 ///
1152 /// Computes:
1153 /// $$(\int_{elem} w \, |u_{ex} - u_h|^p)^{1/p}$$
1154 ///
1155 /// @param[in] p Real value indicating the exponent of the $L^p$
1156 /// norm. To avoid domain errors p should have a
1157 /// positive value, either finite or infinite.
1158 /// @param[in] exsol Coefficient object reproducing the anticipated
1159 /// values of the scalar field, u_ex.
1160 /// @param[in,out] error Vector to contain the element-wise $L^p$ errors
1161 /// @param[in] weight Optional pointer to a Coefficient object
1162 /// reproducing a weighting function, w.
1163 /// @param[in] irs Optional pointer to an array of custom integration
1164 /// rules e.g. higher order than the default rules. If
1165 /// present the array will be indexed by
1166 /// Geometry::Type.
1167 ///
1168 /// @note If an array of integration rules is provided through @a irs, be
1169 /// sure to include valid rules for each element type that may occur
1170 /// in the list of elements.
1171 ///
1172 /// @note Quadratures with negative weights (as in some simplex integration
1173 /// rules in MFEM) can produce negative integrals even with
1174 /// non-negative integrands. To avoid returning negative errors this
1175 /// function uses the absolute values of the element-wise integrals.
1176 /// This may lead to results which are not entirely consistent with
1177 /// such integration rules.
1178 virtual void ComputeElementLpErrors(const real_t p, Coefficient &exsol,
1179 Vector &error,
1180 Coefficient *weight = NULL,
1181 const IntegrationRule *irs[] = NULL
1182 ) const;
1183
1184 /// @brief Returns ||u_ex - u_h||_L1 elementwise for H1 or L2 elements
1185 ///
1186 /// Compute the $L^1$ error in each element of the mesh and store the
1187 /// results in the Vector @a error. The result should be of length number of
1188 /// elements, for example an L2 GridFunction of order zero using map type
1189 /// @ref map_type_value "VALUE".
1190 ///
1191 /// @param[in] exsol Coefficient object reproducing the anticipated
1192 /// values of the scalar field, u_ex.
1193 /// @param[in,out] error Vector to contain the element-wise $L^1$ errors
1194 /// @param[in] irs Optional pointer to an array of custom integration
1195 /// rules e.g. higher order than the default rules. If
1196 /// present the array will be indexed by
1197 /// Geometry::Type.
1198 ///
1199 /// @note If an array of integration rules is provided through @a irs, be
1200 /// sure to include valid rules for each element type that may occur
1201 /// in the list of elements.
1202 ///
1203 /// @note Quadratures with negative weights (as in some simplex integration
1204 /// rules in MFEM) can produce negative integrals even with
1205 /// non-negative integrands. To avoid returning negative errors this
1206 /// function uses the absolute values of the element-wise integrals.
1207 /// This may lead to results which are not entirely consistent with
1208 /// such integration rules.
1209 ///
1210 /// @note Uses ComputeElementLpError internally. See the
1211 /// ComputeElementLpError documentation for generalizations of this
1212 /// error computation.
1214 Vector &error,
1215 const IntegrationRule *irs[] = NULL
1216 ) const
1217 { ComputeElementLpErrors(1.0, exsol, error, NULL, irs); }
1218
1219 /// @brief Returns ||u_ex - u_h||_L2 elementwise for H1 or L2 elements
1220 ///
1221 /// Compute the $L^2$ error in each element of the mesh and store the results
1222 /// in the Vector @a error. The result should be of length number of
1223 /// elements, for example an L2 GridFunction of order zero using map type
1224 /// @ref map_type_value "VALUE".
1225 ///
1226 /// Computes:
1227 /// $$(\int_{elem} |u_{ex} - u_h|^2)^{1/2}$$
1228 ///
1229 /// @param[in] exsol Coefficient object reproducing the anticipated
1230 /// values of the scalar field, u_ex.
1231 /// @param[in,out] error Vector to contain the element-wise $L^2$ errors
1232 /// @param[in] irs Optional pointer to an array of custom integration
1233 /// rules e.g. higher order than the default rules. If
1234 /// present the array will be indexed by
1235 /// Geometry::Type.
1236 ///
1237 /// @note If an array of integration rules is provided through @a irs, be
1238 /// sure to include valid rules for each element type that may occur
1239 /// in the list of elements.
1240 ///
1241 /// @note Quadratures with negative weights (as in some simplex integration
1242 /// rules in MFEM) can produce negative integrals even with
1243 /// non-negative integrands. To avoid returning negative errors this
1244 /// function uses the absolute values of the element-wise integrals.
1245 /// This may lead to results which are not entirely consistent with
1246 /// such integration rules.
1247 ///
1248 /// @note Uses ComputeElementLpError internally. See the
1249 /// ComputeElementLpError documentation for generalizations of this
1250 /// error computation.
1252 Vector &error,
1253 const IntegrationRule *irs[] = NULL
1254 ) const
1255 { ComputeElementLpErrors(2.0, exsol, error, NULL, irs); }
1256
1257 /// @brief Returns Max|u_ex - u_h| elementwise for H1 or L2 elements
1258 ///
1259 /// Compute the $L^\infty$ error in each element of the mesh and store the
1260 /// results in the Vector @a error. The result should be of length number of
1261 /// elements, for example an L2 GridFunction of order zero using map type
1262 /// @ref map_type_value "VALUE".
1263 ///
1264 /// @param[in] exsol Coefficient object reproducing the anticipated
1265 /// values of the scalar field, u_ex.
1266 /// @param[in,out] error Vector to contain the element-wise $L^\infty$
1267 /// errors
1268 /// @param[in] irs Optional pointer to an array of custom integration
1269 /// rules e.g. higher order than the default rules. If
1270 /// present the array will be indexed by
1271 /// Geometry::Type.
1272 ///
1273 /// @note If an array of integration rules is provided through @a irs, be
1274 /// sure to include valid rules for each element type that may occur
1275 /// in the list of elements.
1276 ///
1277 /// @note Uses ComputeElementLpError internally. See the
1278 /// ComputeElementLpError documentation for generalizations of this
1279 /// error computation.
1281 Vector &error,
1282 const IntegrationRule *irs[] = NULL
1283 ) const
1284 { ComputeElementLpErrors(infinity(), exsol, error, NULL, irs); }
1285
1286 /// @brief Returns ||u_ex - u_h||_Lp for vector fields
1287 ///
1288 /// When given a vector weight, compute the pointwise (scalar) error as the
1289 /// dot product of the vector error with the vector weight. Otherwise, the
1290 /// scalar error is the l_2 norm of the vector error.
1291 ///
1292 /// Computes:
1293 /// $$(\sum_{elems} \int_{elem} w \, |scalar\_error|^p)^{1/p}$$
1294 ///
1295 /// Where
1296 /// $$scalar\_error = |v\_weight \cdot (u_{ex} - u_h)|$$
1297 /// or
1298 /// $$scalar\_error = \sqrt{(u_{ex} - u_h) \cdot (u_{ex} - u_h)}$$
1299 ///
1300 /// @param[in] p Real value indicating the exponent of the $L^p$
1301 /// norm. To avoid domain errors p should have a
1302 /// positive value, either finite or infinite.
1303 /// @param[in] exsol VectorCoefficient object reproducing the anticipated
1304 /// values of the vector field, u_ex.
1305 /// @param[in] weight Optional pointer to a Coefficient object reproducing
1306 /// a weighting function, w.
1307 /// @param[in] v_weight Optional pointer to a VectorCoefficient object
1308 /// reproducing a weighting vector as shown above.
1309 /// @param[in] irs Optional pointer to an array of custom integration
1310 /// rules e.g. higher order than the default rules. If
1311 /// present the array will be indexed by Geometry::Type.
1312 ///
1313 /// @note If an array of integration rules is provided through @a irs, be
1314 /// sure to include valid rules for each element type that may occur
1315 /// in the list of elements.
1316 ///
1317 /// @note Quadratures with negative weights (as in some simplex integration
1318 /// rules in MFEM) can produce negative integrals even with
1319 /// non-negative integrands. To avoid returning negative errors this
1320 /// function uses the absolute values of the element-wise integrals.
1321 /// This may lead to results which are not entirely consistent with
1322 /// such integration rules.
1323 virtual real_t ComputeLpError(const real_t p, VectorCoefficient &exsol,
1324 Coefficient *weight = NULL,
1325 VectorCoefficient *v_weight = NULL,
1326 const IntegrationRule *irs[] = NULL) const;
1327
1328 /// @brief Returns ||u_ex - u_h||_Lp elementwise for vector fields
1329 ///
1330 /// Compute the $L^p$ error in each element of the mesh and store the results
1331 /// in the Vector @a error. The result should be of length number of
1332 /// elements, for example an L2 GridFunction of order zero using map type
1333 /// @ref map_type_value "VALUE".
1334 ///
1335 /// Computes:
1336 /// $$(\int_{elem} w \, |scalar\_error|^p)^{1/p}$$
1337 ///
1338 /// Where
1339 /// $$scalar\_error = |v\_weight \cdot (u_{ex} - u_h)|$$
1340 /// or
1341 /// $$scalar\_error = \sqrt{(u_{ex} - u_h) \cdot (u_{ex} - u_h)}$$
1342 ///
1343 /// @param[in] p Real value indicating the exponent of the $L^p$
1344 /// norm. To avoid domain errors p should have a
1345 /// positive value, either finite or infinite.
1346 /// @param[in] exsol VectorCoefficient object reproducing the
1347 /// anticipated values of the vector field, u_ex.
1348 /// @param[in,out] error Vector to contain the element-wise $L^p$ errors
1349 /// @param[in] weight Optional pointer to a Coefficient object
1350 /// reproducing a weighting function, w.
1351 /// @param[in] v_weight Optional pointer to a VectorCoefficient object
1352 /// reproducing a weighting vector as shown above.
1353 /// @param[in] irs Optional pointer to an array of custom integration
1354 /// rules e.g. higher order than the default rules. If
1355 /// present the array will be indexed by
1356 /// Geometry::Type.
1357 ///
1358 /// @note If an array of integration rules is provided through @a irs, be
1359 /// sure to include valid rules for each element type that may occur
1360 /// in the list of elements.
1361 ///
1362 /// @note Quadratures with negative weights (as in some simplex integration
1363 /// rules in MFEM) can produce negative integrals even with
1364 /// non-negative integrands. To avoid returning negative errors this
1365 /// function uses the absolute values of the element-wise integrals.
1366 /// This may lead to results which are not entirely consistent with
1367 /// such integration rules.
1368 virtual void ComputeElementLpErrors(const real_t p, VectorCoefficient &exsol,
1369 Vector &error,
1370 Coefficient *weight = NULL,
1371 VectorCoefficient *v_weight = NULL,
1372 const IntegrationRule *irs[] = NULL
1373 ) const;
1374
1375 /// @brief Returns ||u_ex - u_h||_L1 elementwise for vector fields
1376 ///
1377 /// Compute the $L^1$ error in each element of the mesh and store the
1378 /// results in the Vector @a error. The result should be of length number of
1379 /// elements, for example an L2 GridFunction of order zero using map type
1380 /// @ref map_type_value "VALUE".
1381 ///
1382 /// Computes:
1383 /// $$\int_{elem} |scalar\_error|$$
1384 ///
1385 /// Where
1386 /// $$scalar\_error = \sqrt{(u_{ex} - u_h) \cdot (u_{ex} - u_h)}$$
1387 ///
1388 /// @param[in] exsol VectorCoefficient object reproducing the
1389 /// anticipated values of the vector field, u_ex.
1390 /// @param[in,out] error Vector to contain the element-wise $L^1$ errors
1391 /// @param[in] irs Optional pointer to an array of custom integration
1392 /// rules e.g. higher order than the default rules. If
1393 /// present the array will be indexed by
1394 /// Geometry::Type.
1395 ///
1396 /// @note If an array of integration rules is provided through @a irs, be
1397 /// sure to include valid rules for each element type that may occur
1398 /// in the list of elements.
1399 ///
1400 /// @note Quadratures with negative weights (as in some simplex integration
1401 /// rules in MFEM) can produce negative integrals even with
1402 /// non-negative integrands. To avoid returning negative errors this
1403 /// function uses the absolute values of the element-wise integrals.
1404 /// This may lead to results which are not entirely consistent with
1405 /// such integration rules.
1406 ///
1407 /// @note Uses ComputeElementLpError internally. See the
1408 /// ComputeElementLpError documentation for generalizations of this
1409 /// error computation.
1411 Vector &error,
1412 const IntegrationRule *irs[] = NULL
1413 ) const
1414 { ComputeElementLpErrors(1.0, exsol, error, NULL, NULL, irs); }
1415
1416 /// @brief Returns ||u_ex - u_h||_L2 elementwise for vector fields
1417 ///
1418 /// Compute the $L^2$ error in each element of the mesh and store the
1419 /// results in the Vector @a error. The result should be of length number of
1420 /// elements, for example an L2 GridFunction of order zero using map type
1421 /// @ref map_type_value "VALUE".
1422 ///
1423 /// Computes:
1424 /// $$(\int_{elem} |scalar\_error|^2)^{1/2}$$
1425 ///
1426 /// Where
1427 /// $$scalar\_error = \sqrt{(u_{ex} - u_h) \cdot (u_{ex} - u_h)}$$
1428 ///
1429 /// @param[in] exsol VectorCoefficient object reproducing the
1430 /// anticipated values of the vector field, u_ex.
1431 /// @param[in,out] error Vector to contain the element-wise $L^2$ errors
1432 /// @param[in] irs Optional pointer to an array of custom integration
1433 /// rules e.g. higher order than the default rules. If
1434 /// present the array will be indexed by
1435 /// Geometry::Type.
1436 ///
1437 /// @note If an array of integration rules is provided through @a irs, be
1438 /// sure to include valid rules for each element type that may occur
1439 /// in the list of elements.
1440 ///
1441 /// @note Quadratures with negative weights (as in some simplex integration
1442 /// rules in MFEM) can produce negative integrals even with
1443 /// non-negative integrands. To avoid returning negative errors this
1444 /// function uses the absolute values of the element-wise integrals.
1445 /// This may lead to results which are not entirely consistent with
1446 /// such integration rules.
1447 ///
1448 /// @note Uses ComputeElementLpError internally. See the
1449 /// ComputeElementLpError documentation for generalizations of this
1450 /// error computation.
1452 Vector &error,
1453 const IntegrationRule *irs[] = NULL
1454 ) const
1455 { ComputeElementLpErrors(2.0, exsol, error, NULL, NULL, irs); }
1456
1457 /// @brief Returns Max|u_ex - u_h| elementwise for vector fields
1458 ///
1459 /// Compute the $L^\infty$ error in each element of the mesh and store the
1460 /// results in the Vector @a error. The result should be of length number of
1461 /// elements, for example an L2 GridFunction of order zero using map type
1462 /// @ref map_type_value "VALUE".
1463 ///
1464 /// Computes:
1465 /// $$max_{elem} |scalar\_error|$$
1466 ///
1467 /// Where
1468 /// $$scalar\_error = \sqrt{(u_{ex} - u_h) \cdot (u_{ex} - u_h)}$$
1469 ///
1470 /// @param[in] exsol VectorCoefficient object reproducing the
1471 /// anticipated values of the vector field, u_ex.
1472 /// @param[in,out] error Vector to contain the element-wise $L^\infty$
1473 /// errors
1474 /// @param[in] irs Optional pointer to an array of custom integration
1475 /// rules e.g. higher order than the default rules. If
1476 /// present the array will be indexed by
1477 /// Geometry::Type.
1478 ///
1479 /// @note If an array of integration rules is provided through @a irs, be
1480 /// sure to include valid rules for each element type that may occur
1481 /// in the list of elements.
1482 ///
1483 /// @note Uses ComputeElementLpError internally. See the
1484 /// ComputeElementLpError documentation for generalizations of this
1485 /// error computation.
1486 ///
1487 /// @note Computes the maximum magnitude of the difference vector not the
1488 /// component-wise maximum difference of the vector fields.
1490 Vector &error,
1491 const IntegrationRule *irs[] = NULL
1492 ) const
1493 { ComputeElementLpErrors(infinity(), exsol, error, NULL, NULL, irs); }
1494
1495 virtual void ComputeFlux(BilinearFormIntegrator &blfi,
1496 GridFunction &flux,
1497 bool wcoef = true, int subdomain = -1);
1498
1499 /// Redefine '=' for GridFunction = constant.
1501
1502 /// Copy the data from @a v.
1503 /** The size of @a v must be equal to the size of the associated
1504 FiniteElementSpace #fes. */
1505 GridFunction &operator=(const Vector &v);
1506
1507 /// Transform by the Space UpdateMatrix (e.g., on Mesh change).
1508 virtual void Update();
1509
1510 /** Return update counter, similar to Mesh::GetSequence(). Used to
1511 check if it is up to date with the space. */
1512 long GetSequence() const { return fes_sequence; }
1513
1515 const FiniteElementSpace *FESpace() const { return fes; }
1516
1517 /// Associate a new FiniteElementSpace with the GridFunction.
1518 /** The GridFunction is resized using the SetSize() method. */
1519 virtual void SetSpace(FiniteElementSpace *f);
1520
1521 using Vector::MakeRef;
1522
1523 /** @brief Make the GridFunction reference external data on a new
1524 FiniteElementSpace. */
1525 /** This method changes the FiniteElementSpace associated with the
1526 GridFunction and sets the pointer @a v as external data in the
1527 GridFunction. */
1528 virtual void MakeRef(FiniteElementSpace *f, real_t *v);
1529
1530 /** @brief Make the GridFunction reference external data on a new
1531 FiniteElementSpace. */
1532 /** This method changes the FiniteElementSpace associated with the
1533 GridFunction and sets the data of the Vector @a v (plus the @a v_offset)
1534 as external data in the GridFunction.
1535 @note This version of the method will also perform bounds checks when
1536 the build option MFEM_DEBUG is enabled. */
1537 virtual void MakeRef(FiniteElementSpace *f, Vector &v, int v_offset);
1538
1539 /** @brief Associate a new FiniteElementSpace and new true-dof data with the
1540 GridFunction. */
1541 /** - If the prolongation matrix of @a f is trivial (i.e. its method
1542 FiniteElementSpace::GetProlongationMatrix() returns NULL), then the
1543 method MakeRef() is called with the same arguments.
1544 - Otherwise, the method SetSpace() is called with argument @a f.
1545 - The internal true-dof vector is set to reference @a tv. */
1546 void MakeTRef(FiniteElementSpace *f, real_t *tv);
1547
1548 /** @brief Associate a new FiniteElementSpace and new true-dof data with the
1549 GridFunction. */
1550 /** - If the prolongation matrix of @a f is trivial (i.e. its method
1551 FiniteElementSpace::GetProlongationMatrix() returns NULL), this method
1552 calls MakeRef() with the same arguments.
1553 - Otherwise, this method calls SetSpace() with argument @a f.
1554 - The internal true-dof vector is set to reference the sub-vector of
1555 @a tv starting at the offset @a tv_offset. */
1556 void MakeTRef(FiniteElementSpace *f, Vector &tv, int tv_offset);
1557
1558 /// Save the GridFunction to an output stream.
1559 virtual void Save(std::ostream &out) const;
1560
1561 /// Save the GridFunction to a file. The given @a precision will be used for
1562 /// ASCII output.
1563 virtual void Save(const char *fname, int precision=16) const;
1564
1565#ifdef MFEM_USE_ADIOS2
1566 /// Save the GridFunction to a binary output stream using adios2 bp format.
1567 virtual void Save(adios2stream &out, const std::string& variable_name,
1570#endif
1571
1572 /** @brief Write the GridFunction in VTK format. Note that Mesh::PrintVTK
1573 must be called first. The parameter ref > 0 must match the one used in
1574 Mesh::PrintVTK. */
1575 void SaveVTK(std::ostream &out, const std::string &field_name, int ref);
1576
1577#ifdef MFEM_USE_HDF5
1578 /// @brief Save the GridFunction in %VTKHDF format.
1579 ///
1580 /// If @a high-order is true, then @a ref controls the order of output. If
1581 /// @a ref is -1, then the order of the grid function will be used.
1582 ///
1583 /// If @a high-order is false, then low-order output will be used. @a ref
1584 /// controls the number of mesh refinements; if @a ref is -1, no refinements
1585 /// will be performed.
1586 void SaveVTKHDF(const std::string &fname, const std::string &name="u",
1587 bool high_order=true, int ref=-1);
1588#endif
1589
1590 /** @brief Write the GridFunction in STL format. Note that the mesh dimension
1591 must be 2 and that quad elements will be broken into two triangles.*/
1592 void SaveSTL(std::ostream &out, int TimesToRefine = 1);
1593
1594 /** @name Methods to compute bounds on the grid function
1595 \brief See bounds.hpp for \ref PLBound that constructs piecewise linear
1596 bounds for a given set of bases. These piecewise bounds can be used to compute bounds on a grid function. Currently tensor-product elements are
1597 supported with Lagrange interpolants on Gauss Legendre nodes and Gauss Lobatto Legendre nodes, and Bernstein bases.
1598 */
1599 ///@{
1600 /// Computes the \ref PLBound for the gridfunction with number of control
1601 /// points based on @a ref_factor, and returns the overall bounds for each
1602 /// vdim (across all elements) in @b lower and @b upper. We also return the
1603 /// PLBound object used to compute the bounds.
1604 /// We compute the bounds for each vdim if @a vdim < 1.
1605 /// Note: For most cases, this method/interface will be sufficient.
1606 virtual PLBound GetBounds(Vector &lower, Vector &upper,
1607 const int ref_factor=1, const int vdim=-1) const;
1608
1609 /// Computes the \ref PLBound for the gridfunction with number of control
1610 /// points based on @a ref_factor, and returns the bounds for each element
1611 /// ordered byVDim:
1612 /// lower_{0,0}, lower_{1,0}, ..., lower_{ne-1,0},
1613 /// lower_{0,1}, ..., lower_{ne-1,vdim-1}. We also return the
1614 /// PLBound object used to compute the bounds.
1615 /// We compute the bounds for each vdim if @a vdim < 1.
1616 PLBound GetElementBounds(Vector &lower, Vector &upper,
1617 const int ref_factor=1, const int vdim=-1) const;
1618
1619 /// Compute piecewise linear bounds on the given element at the grid of
1620 /// [plb.ncp x plb.ncp x plb.ncp] control points for each of the vdim
1621 /// components of the gridfunction.
1622 void GetElementBoundsAtControlPoints(const int elem, const PLBound &plb,
1623 Vector &lower, Vector &upper,
1624 const int vdim = -1) const;
1625
1626 /// Compute bounds on the grid function for the given element.
1627 /// The bounds are stored in @b lower and @b upper.
1628 void GetElementBounds(const int elem, const PLBound &plb,
1629 Vector &lower, Vector &upper,
1630 const int vdim = -1) const;
1631
1632 /// Compute bounds on the grid function for all the elements. The bounds
1633 /// are returned in @b lower and @b upper, ordered byVDim:
1634 /// lower_{0,0}, lower_{1,0}, ..., lower_{ne-1,0},
1635 /// lower_{0,1}, ..., lower_{ne-1,vdim-1}
1636 void GetElementBounds(const PLBound &plb, Vector &lower, Vector &upper,
1637 const int vdim=-1) const;
1638 ///@}
1639
1640 /// Destroys grid function.
1641 virtual ~GridFunction() { Destroy(); }
1642};
1643
1644/** Overload operator<< for std::ostream and GridFunction; valid also for the
1645 derived class ParGridFunction */
1646std::ostream &operator<<(std::ostream &out, const GridFunction &sol);
1647
1648/// Class used to specify how the jump terms in
1649/// GridFunction::ComputeDGFaceJumpError are scaled.
1651{
1652public:
1659private:
1660 real_t nu;
1661 JumpScalingType type;
1662public:
1664 : nu(nu_), type(type_) { }
1665 real_t Eval(real_t h, int p) const
1666 {
1667 real_t val = nu;
1668 if (type != CONSTANT) { val /= h; }
1669 if (type == P_SQUARED_OVER_H) { val *= p*p; }
1670 return val;
1671 }
1672};
1673
1674/// Overload operator<< for std::ostream and QuadratureFunction.
1675std::ostream &operator<<(std::ostream &out, const QuadratureFunction &qf);
1676
1677
1679 GridFunction &u,
1680 GridFunction &flux,
1681 Vector &error_estimates,
1682 Array<int> *aniso_flags = NULL,
1683 int with_subdomains = 1,
1684 bool with_coeff = false);
1685
1686/// Defines the global tensor product polynomial space used by NewZZErorrEstimator
1687/**
1688 * See BoundingBox(...) for a description of @a angle and @a midpoint
1689 */
1690void TensorProductLegendre(int dim, // input
1691 int order, // input
1692 const Vector &x_in, // input
1693 const Vector &xmax, // input
1694 const Vector &xmin, // input
1695 Vector &poly, // output
1696 real_t angle=0.0, // input (optional)
1697 const Vector *midpoint=NULL); // input (optional)
1698
1699/// Defines the bounding box for the face patches used by NewZZErorrEstimator
1700/**
1701 * By default, BoundingBox(...) computes the parameters of a minimal bounding box
1702 * for the given @a face_patch that is aligned with the physical (i.e. global)
1703 * Cartesian axes. This means that the size of the bounding box will depend on the
1704 * orientation of the patch. It is better to construct an orientation-independent box.
1705 * This is implemented for 2D patches. The parameters @a angle and @a midpoint encode
1706 * the necessary additional geometric information.
1707 *
1708 * @a iface : Index of the face that the patch corresponds to.
1709 * This is used to compute @a angle and @a midpoint.
1710 *
1711 * @a angle : The angle the patch face makes with the x-axis.
1712 * @a midpoint : The midpoint of the face.
1713 */
1714void BoundingBox(const Array<int> &face_patch, // input
1715 FiniteElementSpace *ufes, // input
1716 int order, // input
1717 Vector &xmin, // output
1718 Vector &xmax, // output
1719 real_t &angle, // output
1720 Vector &midpoint, // output
1721 int iface=-1); // input (optional)
1722
1723/// A ``true'' ZZ error estimator that uses face-based patches for flux reconstruction.
1724/**
1725 * Only two-element face patches are ever used:
1726 * - For conforming faces, the face patch consists of its two neighboring elements.
1727 * - In the non-conforming setting, only the face patches associated to fine-scale
1728 * element faces are used. These face patches always consist of two elements
1729 * delivered by mesh::GetFaceElements(Face, *Elem1, *Elem2).
1730 */
1732 GridFunction &u, // input
1733 Vector &error_estimates, // output
1734 bool subdomain_reconstruction = true, // input (optional)
1735 bool with_coeff = false, // input (optional)
1736 real_t tichonov_coeff = 0.0); // input (optional)
1737
1738/// Compute the Lp distance between two grid functions on the given element.
1740 GridFunction& gf1, GridFunction& gf2);
1741
1742
1743/// Class used for extruding scalar GridFunctions
1745{
1746private:
1747 int n;
1748 Mesh *mesh_in;
1749 Coefficient &sol_in;
1750public:
1752 : n(n_), mesh_in(m), sol_in(s) { }
1753 real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
1755};
1756
1757/// Extrude a scalar 1D GridFunction, after extruding the mesh with Extrude1D.
1758GridFunction *Extrude1DGridFunction(Mesh *mesh, Mesh *mesh2d,
1759 GridFunction *sol, const int ny);
1760
1761} // namespace mfem
1762
1763#endif
Abstract base class BilinearFormIntegrator.
Base class Coefficients that optionally depend on space and time. These are used by the BilinearFormI...
Delta function coefficient optionally multiplied by a weight coefficient and a scaled time dependent ...
Data type dense matrix using column-major storage.
Definition densemat.hpp:24
Class used for extruding scalar GridFunctions.
ExtrudeCoefficient(Mesh *m, Coefficient &s, int n_)
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override
Evaluate the coefficient in the element described by T at the point ip.
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:208
ElementTransformation * GetElementTransformation(int i) const
Definition fespace.hpp:905
Class for grid function - Vector with associated FE space.
Definition gridfunc.hpp:32
GridFunction(const GridFunction &orig)
Copy constructor. The internal true-dof vector t_vec is not copied.
Definition gridfunc.hpp:79
void ComputeMeans(AvgType type, Array< int > &zones_per_vdof)
void GetLaplacians(int i, const IntegrationRule &ir, Vector &laps, int vdim=1) const
Definition gridfunc.cpp:562
void AccumulateAndCountBdrTangentValues(VectorCoefficient &vcoeff, const Array< int > &bdr_attr, Array< int > &values_counter)
GridFunction(FiniteElementSpace *f, real_t *data)
Construct a GridFunction using previously allocated array data.
Definition gridfunc.hpp:93
virtual real_t ComputeL2Error(Coefficient &exsol, const IntegrationRule *irs[]=NULL, const Array< int > *elems=NULL) const
Returns ||u_ex - u_h||_L2 for H1 or L2 elements.
Definition gridfunc.hpp:618
void ProjectVectorFieldOn(GridFunction &vec_field, int comp=0)
virtual void CountElementsPerVDof(Array< int > &elem_per_vdof) const
For each vdof, counts how many elements contain the vdof, as containment is determined by FiniteEleme...
virtual real_t GetValue(int i, const IntegrationPoint &ip, int vdim=1) const
Definition gridfunc.cpp:449
virtual void ComputeElementL1Errors(Coefficient &exsol, Vector &error, const IntegrationRule *irs[]=NULL) const
Returns ||u_ex - u_h||_L1 elementwise for H1 or L2 elements.
void SaveVTK(std::ostream &out, const std::string &field_name, int ref)
Write the GridFunction in VTK format. Note that Mesh::PrintVTK must be called first....
virtual real_t ComputeDGFaceJumpError(Coefficient *exsol, Coefficient *ell_coeff, class JumpScaling jump_scaling, const IntegrationRule *irs[]=NULL) const
Returns the Face Jumps error for L2 elements.
void GetValues(int i, const IntegrationRule &ir, Vector &vals, int vdim=1) const
Definition gridfunc.cpp:517
virtual real_t ComputeHCurlError(VectorCoefficient *exsol, VectorCoefficient *excurl, const IntegrationRule *irs[]=NULL) const
Returns the error measured in H(curl)-norm for ND elements.
void UpdatePRef()
P-refinement version of Update().
Definition gridfunc.cpp:206
virtual real_t ComputeH1Error(Coefficient *exsol, VectorCoefficient *exgrad, Coefficient *ell_coef, real_t Nu, int norm_type) const
void GetGradients(ElementTransformation &tr, const IntegrationRule &ir, DenseMatrix &grad) const
Extension of GetGradient(...) for a collection of IntegrationPoints.
virtual ~GridFunction()
Destroys grid function.
void AccumulateAndCountBdrValues(Coefficient *coeff[], VectorCoefficient *vcoeff, const Array< int > &attr, Array< int > &values_counter)
void GetDerivative(int comp, int der_comp, GridFunction &der) const
Compute a certain derivative of a function's component. Derivatives of the function are computed at t...
virtual void ComputeElementL2Errors(Coefficient &exsol, Vector &error, const IntegrationRule *irs[]=NULL) const
Returns ||u_ex - u_h||_L2 elementwise for H1 or L2 elements.
void GetVectorGradient(ElementTransformation &tr, DenseMatrix &grad) const
Compute the vector gradient with respect to the physical element variable.
virtual real_t ComputeMaxError(Coefficient &exsol, const IntegrationRule *irs[]=NULL) const
Returns Max|u_ex - u_h| error for H1 or L2 elements.
Definition gridfunc.hpp:899
virtual void Update()
Transform by the Space UpdateMatrix (e.g., on Mesh change).
Definition gridfunc.cpp:168
FiniteElementCollection * OwnFEC()
Definition gridfunc.hpp:125
virtual PLBound GetBounds(Vector &lower, Vector &upper, const int ref_factor=1, const int vdim=-1) const
virtual void MakeRef(FiniteElementSpace *f, real_t *v)
Make the GridFunction reference external data on a new FiniteElementSpace.
Definition gridfunc.cpp:234
void ImposeBounds(int i, const Vector &weights, const Vector &lo_, const Vector &hi_)
void SetTrueVector()
Shortcut for calling GetTrueDofs() with GetTrueVector() as argument.
Definition gridfunc.hpp:148
virtual void Save(std::ostream &out) const
Save the GridFunction to an output stream.
virtual real_t ComputeL2Error(Coefficient *exsol[], const IntegrationRule *irs[]=NULL, const Array< int > *elems=NULL) const
Returns ||exsol - u_h||_L2 for scalar or vector H1 or L2 elements.
void MakeTRef(FiniteElementSpace *f, real_t *tv)
Associate a new FiniteElementSpace and new true-dof data with the GridFunction.
Definition gridfunc.cpp:252
virtual real_t ComputeL1Error(Coefficient &exsol, const IntegrationRule *irs[]=NULL) const
Returns ||u_ex - u_h||_L1 for H1 or L2 elements.
Definition gridfunc.hpp:992
void SetFromTrueVector()
Shortcut for calling SetFromTrueDofs() with GetTrueVector() as argument.
Definition gridfunc.hpp:154
GridFunction(FiniteElementSpace *f, Vector &base, int base_offset=0)
Construct a GridFunction using previously allocated Vector base starting at the given offset,...
Definition gridfunc.hpp:99
void GetVectorFieldValues(int i, const IntegrationRule &ir, DenseMatrix &vals, DenseMatrix &tr, int comp=0) const
virtual real_t ComputeL1Error(VectorCoefficient &exsol, const IntegrationRule *irs[]=NULL) const
Returns ||u_ex - u_h||_L1 for vector fields.
virtual void ProjectBdrCoefficientTangent(VectorCoefficient &vcoeff, const Array< int > &bdr_attr)
Project the tangential components of the given VectorCoefficient on the boundary. Only boundary attri...
PLBound GetElementBounds(Vector &lower, Vector &upper, const int ref_factor=1, const int vdim=-1) const
const Vector & GetTrueVector() const
Read only access to the (optional) internal true-dof Vector.
Definition gridfunc.hpp:134
void GetElementAverages(GridFunction &avgs) const
virtual real_t ComputeElementGradError(int ielem, VectorCoefficient *exgrad, const IntegrationRule *irs[]=NULL) const
Returns ||grad u_ex - grad u_h||_L2 in element ielem for H1 or L2 elements.
void MakeOwner(FiniteElementCollection *fec_)
Make the GridFunction the owner of fec_owned and fes.
Definition gridfunc.hpp:123
Vector & GetTrueVector()
Read and write access to the (optional) internal true-dof Vector.
Definition gridfunc.hpp:141
void SaveSTL(std::ostream &out, int TimesToRefine=1)
Write the GridFunction in STL format. Note that the mesh dimension must be 2 and that quad elements w...
const FiniteElementSpace * FESpace() const
virtual void ComputeElementLpErrors(const real_t p, Coefficient &exsol, Vector &error, Coefficient *weight=NULL, const IntegrationRule *irs[]=NULL) const
Returns ||u_ex - u_h||_Lp elementwise for H1 or L2 elements.
virtual void SetFromTrueDofs(const Vector &tv)
Set the GridFunction from the given true-dof vector.
Definition gridfunc.cpp:383
virtual void GetElementDofValues(int el, Vector &dof_vals) const
virtual real_t ComputeLpError(const real_t p, Coefficient &exsol, Coefficient *weight=NULL, const IntegrationRule *irs[]=NULL, const Array< int > *elems=NULL) const
Returns ||u_ex - u_h||_Lp for H1 or L2 elements.
FiniteElementSpace * FESpace()
GridFunction(FiniteElementSpace *f)
Construct a GridFunction associated with the FiniteElementSpace *f.
Definition gridfunc.hpp:84
void GetGradients(const int elem, const IntegrationRule &ir, DenseMatrix &grad) const
Extension of GetGradient(...) for a collection of IntegrationPoints.
Definition gridfunc.hpp:352
void SaveSTLTri(std::ostream &out, real_t p1[], real_t p2[], real_t p3[])
virtual void ProjectCoefficient(Coefficient &coeff)
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
virtual void ComputeElementMaxErrors(VectorCoefficient &exsol, Vector &error, const IntegrationRule *irs[]=NULL) const
Returns Max|u_ex - u_h| elementwise for vector fields.
int GetFaceVectorValues(int i, int side, const IntegrationRule &ir, DenseMatrix &vals, DenseMatrix &tr) const
virtual void ComputeElementL2Errors(VectorCoefficient &exsol, Vector &error, const IntegrationRule *irs[]=NULL) const
Returns ||u_ex - u_h||_L2 elementwise for vector fields.
virtual void ComputeElementL1Errors(VectorCoefficient &exsol, Vector &error, const IntegrationRule *irs[]=NULL) const
Returns ||u_ex - u_h||_L1 elementwise for vector fields.
void GetValuesFrom(const GridFunction &orig_func)
void SaveVTKHDF(const std::string &fname, const std::string &name="u", bool high_order=true, int ref=-1)
Save the GridFunction in VTKHDF format.
void LegacyNCReorder()
Loading helper.
void ProjectDeltaCoefficient(DeltaCoefficient &delta_coeff, real_t &integral)
void ProjectDiscCoefficient(VectorCoefficient &coeff, Array< int > &dof_attr)
virtual void ComputeFlux(BilinearFormIntegrator &blfi, GridFunction &flux, bool wcoef=true, int subdomain=-1)
Definition gridfunc.cpp:332
FiniteElementSpace * fes
FE space on which the grid function lives. Owned if fec_owned is not NULL.
Definition gridfunc.hpp:35
virtual real_t ComputeCurlError(VectorCoefficient *excurl, const IntegrationRule *irs[]=NULL) const
Returns ||curl u_ex - curl u_h||_L2 for ND elements.
void GetBdrValuesFrom(const GridFunction &orig_func)
virtual real_t ComputeHDivError(VectorCoefficient *exsol, Coefficient *exdiv, const IntegrationRule *irs[]=NULL) const
Returns the error measured in H(div)-norm for RT elements.
int VectorDim() const
Shortcut for calling FiniteElementSpace::GetVectorDim() on the underlying fes.
Definition gridfunc.cpp:347
long GetSequence() const
virtual real_t ComputeW11Error(Coefficient *exsol, VectorCoefficient *exgrad, int norm_type, const Array< int > *elems=NULL, const IntegrationRule *irs[]=NULL) const
Returns norm (or portions thereof) for H1 or L2 elements.
std::unique_ptr< GridFunction > ProlongateToMaxOrder() const
Return a GridFunction with the values of this, prolongated to the maximum order of all elements in th...
int GetFaceValues(int i, int side, const IntegrationRule &ir, Vector &vals, DenseMatrix &tr, int vdim=1) const
Definition gridfunc.cpp:657
FiniteElementCollection * fec_owned
Used when the grid function is read from a file. It can also be set explicitly, see MakeOwner().
Definition gridfunc.hpp:41
int CurlDim() const
Shortcut for calling FiniteElementSpace::GetCurlDim() on the underlying fes.
Definition gridfunc.cpp:358
virtual real_t ComputeMaxError(VectorCoefficient &exsol, const IntegrationRule *irs[]=NULL) const
Returns Max|u_ex - u_h| error for vector fields.
Definition gridfunc.hpp:961
void SumFluxAndCount(BilinearFormIntegrator &blfi, GridFunction &flux, Array< int > &counts, bool wcoef, int subdomain)
Definition gridfunc.cpp:282
GridFunction & operator=(const GridFunction &rhs)
Copy assignment. Only the data of the base class Vector is copied.
Definition gridfunc.hpp:117
virtual real_t ComputeDivError(Coefficient *exdiv, const IntegrationRule *irs[]=NULL) const
Returns ||div u_ex - div u_h||_L2 for RT elements.
virtual void ComputeElementMaxErrors(Coefficient &exsol, Vector &error, const IntegrationRule *irs[]=NULL) const
Returns Max|u_ex - u_h| elementwise for H1 or L2 elements.
void GetElementBoundsAtControlPoints(const int elem, const PLBound &plb, Vector &lower, Vector &upper, const int vdim=-1) const
void GetTrueDofs(Vector &tv) const
Extract the true-dofs from the GridFunction.
Definition gridfunc.cpp:368
void AccumulateAndCountDerivativeValues(int comp, int der_comp, GridFunction &der, Array< int > &zones_per_dof) const
Used for the serial and parallel implementations of the GetDerivative() method; see its documentation...
virtual real_t ComputeGradError(VectorCoefficient *exgrad, const IntegrationRule *irs[]=NULL) const
Returns ||grad u_ex - grad u_h||_L2 for H1 or L2 elements.
void GetNodalValues(int i, Array< real_t > &nval, int vdim=1) const
Returns the values at the vertices of element i for the 1-based dimension vdim.
Definition gridfunc.cpp:397
virtual void GetVectorValue(int i, const IntegrationPoint &ip, Vector &val) const
Definition gridfunc.cpp:474
virtual MFEM_DEPRECATED real_t ComputeL1Error(Coefficient *exsol[], const IntegrationRule *irs[]=NULL) const
Returns ||u_ex - u_h||_L1 for H1 or L2 elements.
real_t GetDivergence(ElementTransformation &tr) const
void AccumulateAndCountZones(Coefficient &coeff, AvgType type, Array< int > &zones_per_vdof)
Accumulates (depending on type) the values of coeff at all shared vdofs and counts in how many zones ...
void ProjectBdrCoefficientNormal(VectorCoefficient &vcoeff, const Array< int > &bdr_attr)
void GetCurl(ElementTransformation &tr, Vector &curl) const
void GetGradient(ElementTransformation &tr, Vector &grad) const
Gradient of a scalar function at a quadrature point.
void GetVectorGradientHat(ElementTransformation &T, DenseMatrix &gh) const
Compute the vector gradient with respect to the reference element variable.
virtual void SetSpace(FiniteElementSpace *f)
Associate a new FiniteElementSpace with the GridFunction.
Definition gridfunc.cpp:226
void GetHessians(int i, const IntegrationRule &ir, DenseMatrix &hess, int vdim=1) const
Definition gridfunc.cpp:601
void GetVectorValues(int i, const IntegrationRule &ir, DenseMatrix &vals, DenseMatrix &tr) const
Definition gridfunc.cpp:707
void ProjectGridFunction(const GridFunction &src)
Project the src GridFunction to this GridFunction, both of which must be on the same mesh.
void GetVectorFieldNodalValues(Vector &val, int comp) const
void ProjectBdrCoefficient(Coefficient &coeff, const Array< int > &attr)
Project a Coefficient on the GridFunction, modifying only DOFs on the boundary associated with the bo...
Definition gridfunc.hpp:511
void ReorderByNodes()
For a vector grid function, makes sure that the ordering is byNODES.
Class for integration point with weight.
Definition intrules.hpp:35
Class for an integration rule - an Array of IntegrationPoint.
Definition intrules.hpp:100
JumpScaling(real_t nu_=1.0, JumpScalingType type_=CONSTANT)
real_t Eval(real_t h, int p) const
Mesh data type.
Definition mesh.hpp:65
Represents values or vectors of values at quadrature points on a mesh.
Definition qfunction.hpp:24
Base class for vector Coefficients that optionally depend on time and space.
Vector data type.
Definition vector.hpp:82
Memory< real_t > data
Definition vector.hpp:85
virtual bool UseDevice() const
Return the device flag of the Memory object used by the Vector.
Definition vector.hpp:148
int Size() const
Returns the size of the vector.
Definition vector.hpp:234
void MakeRef(Vector &base, int offset, int size)
Reset the Vector to be a reference to a sub-vector of base.
Definition vector.hpp:660
int dim
Definition ex24.cpp:53
std::ostream & operator<<(std::ostream &os, SparseMatrix const &mat)
void TensorProductLegendre(int dim, int order, const Vector &x_in, const Vector &xmax, const Vector &xmin, Vector &poly, real_t angle, const Vector *midpoint)
Defines the global tensor product polynomial space used by NewZZErorrEstimator.
real_t infinity()
Define a shortcut for std::numeric_limits<double>::infinity()
Definition vector.hpp:47
GridFunction * Extrude1DGridFunction(Mesh *mesh, Mesh *mesh2d, GridFunction *sol, const int ny)
Extrude a scalar 1D GridFunction, after extruding the mesh with Extrude1D.
real_t u(const Vector &xvec)
Definition lor_mms.hpp:22
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
real_t ZZErrorEstimator(BilinearFormIntegrator &blfi, GridFunction &u, GridFunction &flux, Vector &error_estimates, Array< int > *aniso_flags, int with_subdomains, bool with_coeff)
real_t LSZZErrorEstimator(BilinearFormIntegrator &blfi, GridFunction &u, Vector &error_estimates, bool subdomain_reconstruction, bool with_coeff, real_t tichonov_coeff)
A `‘true’' ZZ error estimator that uses face-based patches for flux reconstruction.
void BoundingBox(const Array< int > &patch, FiniteElementSpace *ufes, int order, Vector &xmin, Vector &xmax, real_t &angle, Vector &midpoint, int iface)
Defines the bounding box for the face patches used by NewZZErorrEstimator.
real_t ComputeElementLpDistance(real_t p, int i, GridFunction &gf1, GridFunction &gf2)
Compute the Lp distance between two grid functions on the given element.
QVectorLayout
Type describing possible layouts for Q-vectors.
Definition fespace.hpp:31
float real_t
Definition config.hpp:46
MemoryType
Memory types supported by MFEM.
std::function< real_t(const Vector &)> f(real_t mass_coeff)
Definition lor_mms.hpp:30
real_t p(const Vector &x, real_t t)