libMesh
fourth_error_estimators.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2019 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 #include "libmesh/libmesh_config.h"
20 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
21 
22 
23 // C++ includes
24 #include <algorithm> // for std::fill
25 #include <cstdlib> // *must* precede <cmath> for proper std:abs() on PGI, Sun Studio CC
26 #include <cmath> // for sqrt
27 
28 
29 // Local Includes
30 #include "libmesh/libmesh_common.h"
31 #include "libmesh/fourth_error_estimators.h"
32 #include "libmesh/error_vector.h"
33 #include "libmesh/fe_base.h"
34 #include "libmesh/libmesh_logging.h"
35 #include "libmesh/elem.h"
36 #include "libmesh/system.h"
37 #include "libmesh/dense_vector.h"
38 #include "libmesh/tensor_tools.h"
39 #include "libmesh/enum_error_estimator_type.h"
40 #include "libmesh/enum_norm_type.h"
41 
42 namespace libMesh
43 {
44 
45 
48 {
50 }
51 
52 
53 
56 {
57  return LAPLACIAN;
58 }
59 
60 
61 
62 void
64 {
65  const unsigned int n_vars = c.n_vars();
66  for (unsigned int v=0; v<n_vars; v++)
67  {
68  // Possibly skip this variable
69  if (error_norm.weight(v) == 0.0) continue;
70 
71  // FIXME: Need to generalize this to vector-valued elements. [PB]
72  FEBase * side_fe = nullptr;
73 
74  const std::set<unsigned char> & elem_dims =
75  c.elem_dimensions();
76 
77  for (const auto & dim : elem_dims)
78  {
79  fine_context->get_side_fe( v, side_fe, dim );
80 
81  // We'll need hessians on both sides for flux jump computation
82  side_fe->get_d2phi();
83  }
84  }
85 }
86 
87 
88 
89 void
91 {
92  const Elem & coarse_elem = coarse_context->get_elem();
93  const Elem & fine_elem = fine_context->get_elem();
94 
95  const DenseVector<Number> & Ucoarse = coarse_context->get_elem_solution();
96  const DenseVector<Number> & Ufine = fine_context->get_elem_solution();
97 
98  unsigned short dim = fine_elem.dim();
99 
100  FEBase * fe_fine = nullptr;
101  fine_context->get_side_fe( var, fe_fine, dim );
102 
103  FEBase * fe_coarse = nullptr;
104  coarse_context->get_side_fe( var, fe_coarse, dim );
105 
106  Real error = 1.e-30;
107  unsigned int n_qp = fe_fine->n_quadrature_points();
108 
109  std::vector<std::vector<RealTensor>> d2phi_coarse = fe_coarse->get_d2phi();
110  std::vector<std::vector<RealTensor>> d2phi_fine = fe_fine->get_d2phi();
111  std::vector<Real> JxW_face = fe_fine->get_JxW();
112 
113  for (unsigned int qp=0; qp != n_qp; ++qp)
114  {
115  // Calculate solution gradients on fine and coarse elements
116  // at this quadrature point
117  Number laplacian_fine = 0., laplacian_coarse = 0.;
118 
119  const unsigned int n_coarse_dofs = Ucoarse.size();
120  for (unsigned int i=0; i != n_coarse_dofs; ++i)
121  {
122  laplacian_coarse += d2phi_coarse[i][qp](0,0) * Ucoarse(i);
123  if (dim > 1)
124  laplacian_coarse += d2phi_coarse[i][qp](1,1) * Ucoarse(i);
125  if (dim > 2)
126  laplacian_coarse += d2phi_coarse[i][qp](2,2) * Ucoarse(i);
127  }
128 
129  const unsigned int n_fine_dofs = Ufine.size();
130  for (unsigned int i=0; i != n_fine_dofs; ++i)
131  {
132  laplacian_fine += d2phi_fine[i][qp](0,0) * Ufine(i);
133  if (dim > 1)
134  laplacian_fine += d2phi_fine[i][qp](1,1) * Ufine(i);
135  if (dim > 2)
136  laplacian_fine += d2phi_fine[i][qp](2,2) * Ufine(i);
137  }
138 
139 
140  // Find the jump in the Laplacian
141  // at this quadrature point
142  const Number jump = laplacian_fine - laplacian_coarse;
143  const Real jump2 = TensorTools::norm_sq(jump);
144 
145  // Accumulate the jump integral
146  error += JxW_face[qp] * jump2;
147  }
148 
149  // Add the h-weighted jump integral to each error term
150  fine_error =
151  error * fine_elem.hmax() * error_norm.weight(var);
152  coarse_error =
153  error * coarse_elem.hmax() * error_norm.weight(var);
154 }
155 
156 } // namespace libMesh
157 
158 #else // defined (LIBMESH_ENABLE_SECOND_DERIVATIVES)
159 
160 #include "libmesh/fourth_error_estimators.h"
161 
162 namespace libMesh
163 {
164 
165 void
167 {
168  libmesh_error_msg("Error: LaplacianErrorEstimator requires second " \
169  << "derivative support; try configuring libmesh with " \
170  << "--enable-second");
171 }
172 
173 
174 void
176 {
177  libmesh_error_msg("Error: LaplacianErrorEstimator requires second " \
178  << "derivative support; try configuring libmesh with " \
179  << "--enable-second");
180 }
181 
182 } // namespace libMesh
183 
184 #endif // defined (LIBMESH_ENABLE_SECOND_DERIVATIVES)
libMesh::JumpErrorEstimator::coarse_context
std::unique_ptr< FEMContext > coarse_context
Definition: jump_error_estimator.h:158
libMesh::Number
Real Number
Definition: libmesh_common.h:195
libMesh::ErrorEstimator::error_norm
SystemNorm error_norm
When estimating the error in a single system, the error_norm is used to control the scaling and norm ...
Definition: error_estimator.h:164
n_vars
unsigned int n_vars
Definition: adaptivity_ex3.C:116
libMesh::ErrorEstimatorType
ErrorEstimatorType
Defines an enum for the different types of error estimators which are available.
Definition: enum_error_estimator_type.h:33
libMesh::LaplacianErrorEstimator::init_context
virtual void init_context(FEMContext &c) override
An initialization function, for requesting specific data from the FE objects.
Definition: fourth_error_estimators.C:63
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
libMesh::Elem::dim
virtual unsigned short dim() const =0
libMesh::DiffContext::n_vars
unsigned int n_vars() const
Number of variables in solution.
Definition: diff_context.h:99
libMesh::JumpErrorEstimator::var
unsigned int var
The variable number currently being evaluated.
Definition: jump_error_estimator.h:168
libMesh::FEGenericBase
This class forms the foundation from which generic finite elements may be derived.
Definition: exact_error_estimator.h:39
libMesh::JumpErrorEstimator::fine_error
Real fine_error
The fine and coarse error values to be set by each side_integration();.
Definition: jump_error_estimator.h:163
libMesh::FEAbstract::get_JxW
const std::vector< Real > & get_JxW() const
Definition: fe_abstract.h:244
libMesh::FEGenericBase::get_d2phi
const std::vector< std::vector< OutputTensor > > & get_d2phi() const
Definition: fe_base.h:288
libMesh::SystemNorm::weight
Real weight(unsigned int var) const
Definition: system_norm.C:133
libMesh::LAPLACIAN
Definition: enum_error_estimator_type.h:40
dim
unsigned int dim
Definition: adaptivity_ex3.C:113
libMesh::LaplacianErrorEstimator::internal_side_integration
virtual void internal_side_integration() override
The function which calculates a laplacian jump based error term on an internal side.
Definition: fourth_error_estimators.C:90
libMesh::JumpErrorEstimator::coarse_error
Real coarse_error
Definition: jump_error_estimator.h:163
libMesh::LaplacianErrorEstimator::LaplacianErrorEstimator
LaplacianErrorEstimator()
Constructor.
Definition: fourth_error_estimators.C:46
libMesh::JumpErrorEstimator::fine_context
std::unique_ptr< FEMContext > fine_context
Context objects for integrating on the fine and coarse elements sharing a face.
Definition: jump_error_estimator.h:158
libMesh::FEAbstract::n_quadrature_points
virtual unsigned int n_quadrature_points() const =0
libMesh::JumpErrorEstimator
This abstract base class implements utility functions for error estimators which are based on integra...
Definition: jump_error_estimator.h:48
libMesh::DenseVector::size
virtual unsigned int size() const override
Definition: dense_vector.h:92
libMesh::H2_SEMINORM
Definition: enum_norm_type.h:44
libMesh::TensorTools::norm_sq
T norm_sq(std::complex< T > a)
Definition: tensor_tools.h:85
libMesh::Elem::hmax
virtual Real hmax() const
Definition: elem.C:379
libMesh::Elem
This is the base class from which all geometric element types are derived.
Definition: elem.h:100
libMesh::FEMContext::elem_dimensions
const std::set< unsigned char > & elem_dimensions() const
Definition: fem_context.h:938
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition: libmesh_common.h:121
libMesh::LaplacianErrorEstimator::type
virtual ErrorEstimatorType type() const override
Definition: fourth_error_estimators.C:55
libMesh::DenseVector< Number >
libMesh::FEMContext
This class provides all data required for a physics package (e.g.
Definition: fem_context.h:62