1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2020 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 
18 
19 
20 #ifndef LIBMESH_ERROR_VECTOR_H
21 #define LIBMESH_ERROR_VECTOR_H
22 
23 // Local Includes
24 #include "libmesh/statistics.h"
25 
26 // C++ includes
27 #include <cstddef>
28 
29 namespace libMesh
30 {
31 
32 // Forward Declarations
33 class MeshBase;
34 class Mesh;
35 
36 /**
37  * The \p ErrorVector is a specialization of the
38  * \p StatisticsVector for error data computed on a finite element
39  * mesh.  In general, when computing the error on a mesh only the
40  * active elements are considered, but the \p ErrorVector is sized
41  * according to the total number of elements in the mesh.  The
42  * \p ErrorVector is thus padded with zeros for all the inactive
43  * elements, and this must be taken into account when calculating
44  * the statistics.  Since the error is a positive quantity this class
45  * assumes it contains positive data (i.e. min_val >= 0.).
46  *
47  * \author Benjamin S. Kirk
48  * \date 2003
49  */
50 class ErrorVector : public StatisticsVector<ErrorVectorReal>
51 {
52 public:
53 
54   /**
55    * ErrorVector constructor; sets initial length to \p i.
56    *
57    * If mesh is not null, MeshBase::elem() and Elem::is_active() will
58    * be used to distinguish active and inactive elements.  If mesh is null,
59    * ErrorVector will assume that all 0.0 error values correspond to inactive
60    * elements and all non-zero error values correspond to active elements.
61    */
62   ErrorVector(dof_id_type i=0, MeshBase * mesh = nullptr) :
63     StatisticsVector<ErrorVectorReal> (i),
64     _mesh(mesh)
65   {}
66 
67   /**
68    * ErrorVector constructor; sets initial length to \p i and initial values to \p val.
69    *
70    * If mesh is not null, MeshBase::elem() and Elem::is_active() will
71    * be used to distinguish active and inactive elements.  If mesh is null,
72    * ErrorVector will assume that all 0.0 error values correspond to inactive
73    * elements and all non-zero error values correspond to active elements.
74    */
ErrorVector(dof_id_type i,ErrorVectorReal val)75   ErrorVector(dof_id_type i, ErrorVectorReal val) :
76     StatisticsVector<ErrorVectorReal> (i,val) {}
77 
78   /**
79    * \returns The minimum nonzero value in the data set.
80    */
81   virtual ErrorVectorReal minimum() const override;
82 
83   /**
84    * \returns The mean value of the data set. Ignores
85    * zero values.
86    */
87   virtual Real mean() const override;
88 
89   /**
90    * \returns The median (e.g. the middle) value of the data set,
91    * ignoring inactive elements.
92    *
93    * This function modifies the original data by sorting, so it can't
94    * be called on const objects.  Source: GNU Scientific Library
95    */
96   virtual Real median() override;
97 
98   /**
99    * A const version of the median function.
100    * Requires twice the memory of original
101    * data set but does not change the original.
102    */
103   virtual Real median() const override;
104 
105   /**
106    * \returns The variance of the data set ignoring inactive elements.
107    *
108    * Uses a recurrence relation to prevent data overflow for large
109    * sums.
110    *
111    * \note The variance is equal to the standard deviation squared.
112    * The variance is normalized by N in this case.  Source: GNU
113    * Scientific Library.
114    */
variance()115   virtual Real variance() const override
116   { return this->variance(this->mean()); }
117 
118   /**
119    * \returns The variance of the data set ignoring inactive elements
120    * and given the \p mean.
121    *
122    * This is useful for efficiency when you have already calculated
123    * the mean. Uses a recurrence relation to prevent data overflow for
124    * large sums.
125    *
126    * \note The variance is equal to the standard deviation squared.
127    * Source: GNU Scientific Library.
128    */
129   virtual Real variance(const Real mean) const override;
130 
131   /**
132    * \returns A vector of dof_id_types which correspond
133    * to the indices of every member of the data set
134    * below the cutoff value cut ignoring inactive elements.
135    */
136   virtual std::vector<dof_id_type> cut_below(Real cut) const override;
137 
138   /**
139    * \returns A vector of dof_id_types which correspond
140    * to the indices of every member of the data set
141    * above the cutoff value cut ignoring inactive elements.
142    */
143   virtual std::vector<dof_id_type> cut_above(Real cut) const override;
144 
145   /**
146    * Plots a data file, of a type determined by looking at
147    * the file extension in \p filename, of the error values on
148    * the active elements of \p mesh.
149    */
150   void plot_error(const std::string & filename,
151                   const MeshBase & mesh) const;
152 
153 protected:
154   /**
155    * Utility function to decide whether element i is active
156    */
157   bool is_active_elem (dof_id_type i) const;
158 
159   /**
160    * Pointer to the mesh, which may be used to decide which
161    * elements are active
162    */
163   MeshBase * _mesh;
164 };
165 
166 } // namespace libMesh
167 
168 #endif // LIBMESH_ERROR_VECTOR_H
169