$extrastylesheet
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)