$extrastylesheet
fourth_error_estimators.C
Go to the documentation of this file.
00001 // The libMesh Finite Element Library.
00002 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
00003 
00004 // This library is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public
00006 // License as published by the Free Software Foundation; either
00007 // version 2.1 of the License, or (at your option) any later version.
00008 
00009 // This library is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // Lesser General Public License for more details.
00013 
00014 // You should have received a copy of the GNU Lesser General Public
00015 // License along with this library; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 
00018 
00019 #include "libmesh/libmesh_config.h"
00020 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
00021 
00022 
00023 // C++ includes
00024 #include <algorithm> // for std::fill
00025 #include <cstdlib> // *must* precede <cmath> for proper std:abs() on PGI, Sun Studio CC
00026 #include <cmath>    // for sqrt
00027 
00028 
00029 // Local Includes
00030 #include "libmesh/libmesh_common.h"
00031 #include "libmesh/fourth_error_estimators.h"
00032 #include "libmesh/error_vector.h"
00033 #include "libmesh/fe_base.h"
00034 #include "libmesh/libmesh_logging.h"
00035 #include "libmesh/elem.h"
00036 #include "libmesh/system.h"
00037 
00038 #include "libmesh/dense_vector.h"
00039 #include "libmesh/tensor_tools.h"
00040 
00041 
00042 namespace libMesh
00043 {
00044 
00045 
00046 void
00047 LaplacianErrorEstimator::initialize(const System&,
00048                                     ErrorVector&,
00049                                     bool)
00050 {
00051   // We'll need second derivatives for Laplacian jump computation
00052   fe_fine->get_d2phi();
00053   fe_coarse->get_d2phi();
00054 }
00055 
00056 
00057 
00058 void
00059 LaplacianErrorEstimator::internal_side_integration ()
00060 {
00061   Real error = 1.e-30;
00062   unsigned int n_qp = fe_fine->n_quadrature_points();
00063   unsigned int n_fine_dofs = Ufine.size();
00064   unsigned int n_coarse_dofs = Ucoarse.size();
00065 
00066   unsigned int dim = fine_elem->dim();
00067 
00068   std::vector<std::vector<RealTensor> > d2phi_coarse = fe_coarse->get_d2phi();
00069   std::vector<std::vector<RealTensor> > d2phi_fine = fe_fine->get_d2phi();
00070   std::vector<Real> JxW_face = fe_fine->get_JxW();
00071 
00072   for (unsigned int qp=0; qp != n_qp; ++qp)
00073     {
00074       // Calculate solution gradients on fine and coarse elements
00075       // at this quadrature point
00076       Number laplacian_fine = 0., laplacian_coarse = 0.;
00077 
00078       for (unsigned int i=0; i != n_coarse_dofs; ++i)
00079         {
00080           laplacian_coarse += d2phi_coarse[i][qp](0,0) * Ucoarse(i);
00081           if (dim > 1)
00082             laplacian_coarse += d2phi_coarse[i][qp](1,1) * Ucoarse(i);
00083           if (dim > 2)
00084             laplacian_coarse += d2phi_coarse[i][qp](2,2) * Ucoarse(i);
00085         }
00086 
00087       for (unsigned int i=0; i != n_fine_dofs; ++i)
00088         {
00089           laplacian_fine += d2phi_fine[i][qp](0,0) * Ufine(i);
00090           if (dim > 1)
00091             laplacian_fine += d2phi_fine[i][qp](1,1) * Ufine(i);
00092           if (dim > 2)
00093             laplacian_fine += d2phi_fine[i][qp](2,2) * Ufine(i);
00094         }
00095 
00096 
00097       // Find the jump in the Laplacian
00098       // at this quadrature point
00099       const Number jump = laplacian_fine - laplacian_coarse;
00100       const Real jump2 = TensorTools::norm_sq(jump);
00101 
00102       // Accumulate the jump integral
00103       error += JxW_face[qp] * jump2;
00104     }
00105 
00106   // Add the h-weighted jump integral to each error term
00107   fine_error =
00108     error * fine_elem->hmax() * error_norm.weight(var);
00109   coarse_error =
00110     error * coarse_elem->hmax() * error_norm.weight(var);
00111 }
00112 
00113 } // namespace libMesh
00114 
00115 #else // defined (LIBMESH_ENABLE_SECOND_DERIVATIVES)
00116 
00117 #include "libmesh/fourth_error_estimators.h"
00118 
00119 namespace libMesh
00120 {
00121 
00122 void
00123 LaplacianErrorEstimator::initialize(const System&,
00124                                     ErrorVector&,
00125                                     bool)
00126 {
00127   libmesh_error_msg("Error: LaplacianErrorEstimator requires second " \
00128                     << "derivative support; try configuring libmesh with " \
00129                     << "--enable-second");
00130 }
00131 
00132 
00133 void
00134 LaplacianErrorEstimator::internal_side_integration ()
00135 {
00136   libmesh_error_msg("Error: LaplacianErrorEstimator requires second "   \
00137                     << "derivative support; try configuring libmesh with " \
00138                     << "--enable-second");
00139 }
00140 
00141 } // namespace libMesh
00142 
00143 #endif // defined (LIBMESH_ENABLE_SECOND_DERIVATIVES)