$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 // C++ includes 00020 #include <limits> 00021 00022 // Local includes 00023 #include "libmesh/elem.h" 00024 #include "libmesh/error_vector.h" 00025 #include "libmesh/libmesh_logging.h" 00026 00027 #include "libmesh/dof_map.h" 00028 #include "libmesh/equation_systems.h" 00029 #include "libmesh/explicit_system.h" 00030 #include "libmesh/mesh_base.h" 00031 #include "libmesh/numeric_vector.h" 00032 #include "libmesh/gmv_io.h" 00033 #include "libmesh/tecplot_io.h" 00034 #include "libmesh/exodusII_io.h" 00035 00036 namespace libMesh 00037 { 00038 00039 00040 00041 // ------------------------------------------------------------ 00042 // ErrorVector class member functions 00043 ErrorVectorReal ErrorVector::minimum() const 00044 { 00045 START_LOG ("minimum()", "ErrorVector"); 00046 00047 const dof_id_type n = cast_int<dof_id_type>(this->size()); 00048 ErrorVectorReal min = std::numeric_limits<ErrorVectorReal>::max(); 00049 00050 for (dof_id_type i=0; i<n; i++) 00051 { 00052 // Only positive (or zero) values in the error vector 00053 libmesh_assert_greater_equal ((*this)[i], 0.); 00054 if (this->is_active_elem(i)) 00055 min = std::min (min, (*this)[i]); 00056 } 00057 STOP_LOG ("minimum()", "ErrorVector"); 00058 00059 // ErrorVectors are for positive values 00060 libmesh_assert_greater_equal (min, 0.); 00061 00062 return min; 00063 } 00064 00065 00066 00067 Real ErrorVector::mean() const 00068 { 00069 START_LOG ("mean()", "ErrorVector"); 00070 00071 const dof_id_type n = cast_int<dof_id_type>(this->size()); 00072 00073 Real the_mean = 0; 00074 dof_id_type nnz = 0; 00075 00076 for (dof_id_type i=0; i<n; i++) 00077 if (this->is_active_elem(i)) 00078 { 00079 the_mean += ( static_cast<Real>((*this)[i]) - the_mean ) / (nnz + 1); 00080 00081 nnz++; 00082 } 00083 00084 STOP_LOG ("mean()", "ErrorVector"); 00085 00086 return the_mean; 00087 } 00088 00089 00090 00091 00092 Real ErrorVector::median() 00093 { 00094 const dof_id_type n = cast_int<dof_id_type>(this->size()); 00095 00096 if (n == 0) 00097 return 0.; 00098 00099 00100 // Build a StatisticsVector<ErrorVectorReal> containing 00101 // only our active entries and take its mean 00102 StatisticsVector<ErrorVectorReal> sv; 00103 00104 sv.reserve (n); 00105 00106 for (dof_id_type i=0; i<n; i++) 00107 if(this->is_active_elem(i)) 00108 sv.push_back((*this)[i]); 00109 00110 return sv.median(); 00111 } 00112 00113 00114 00115 00116 Real ErrorVector::median() const 00117 { 00118 ErrorVector ev = (*this); 00119 00120 return ev.median(); 00121 } 00122 00123 00124 00125 00126 Real ErrorVector::variance(const Real mean_in) const 00127 { 00128 const dof_id_type n = cast_int<dof_id_type>(this->size()); 00129 00130 START_LOG ("variance()", "ErrorVector"); 00131 00132 Real the_variance = 0; 00133 dof_id_type nnz = 0; 00134 00135 for (dof_id_type i=0; i<n; i++) 00136 if (this->is_active_elem(i)) 00137 { 00138 const Real delta = ( static_cast<Real>((*this)[i]) - mean_in ); 00139 the_variance += (delta * delta - the_variance) / (nnz + 1); 00140 00141 nnz++; 00142 } 00143 00144 STOP_LOG ("variance()", "ErrorVector"); 00145 00146 return the_variance; 00147 } 00148 00149 00150 00151 00152 std::vector<dof_id_type> ErrorVector::cut_below(Real cut) const 00153 { 00154 START_LOG ("cut_below()", "ErrorVector"); 00155 00156 const dof_id_type n = cast_int<dof_id_type>(this->size()); 00157 00158 std::vector<dof_id_type> cut_indices; 00159 cut_indices.reserve(n/2); // Arbitrary 00160 00161 for (dof_id_type i=0; i<n; i++) 00162 if (this->is_active_elem(i)) 00163 { 00164 if ((*this)[i] < cut) 00165 { 00166 cut_indices.push_back(i); 00167 } 00168 } 00169 00170 STOP_LOG ("cut_below()", "ErrorVector"); 00171 00172 return cut_indices; 00173 } 00174 00175 00176 00177 00178 std::vector<dof_id_type> ErrorVector::cut_above(Real cut) const 00179 { 00180 START_LOG ("cut_above()", "ErrorVector"); 00181 00182 const dof_id_type n = cast_int<dof_id_type>(this->size()); 00183 00184 std::vector<dof_id_type> cut_indices; 00185 cut_indices.reserve(n/2); // Arbitrary 00186 00187 for (dof_id_type i=0; i<n; i++) 00188 if (this->is_active_elem(i)) 00189 { 00190 if ((*this)[i] > cut) 00191 { 00192 cut_indices.push_back(i); 00193 } 00194 } 00195 00196 STOP_LOG ("cut_above()", "ErrorVector"); 00197 00198 return cut_indices; 00199 } 00200 00201 00202 00203 bool ErrorVector::is_active_elem (dof_id_type i) const 00204 { 00205 libmesh_assert_less (i, this->size()); 00206 00207 if (_mesh) 00208 { 00209 libmesh_assert(_mesh->elem(i)); 00210 return _mesh->elem(i)->active(); 00211 } 00212 else 00213 return ((*this)[i] != 0.); 00214 } 00215 00216 00217 void ErrorVector::plot_error(const std::string& filename, 00218 const MeshBase& oldmesh) const 00219 { 00220 UniquePtr<MeshBase> meshptr = oldmesh.clone(); 00221 MeshBase &mesh = *meshptr; 00222 00223 // The all_first_order routine requires that renumbering be allowed 00224 mesh.allow_renumbering(true); 00225 00226 mesh.all_first_order(); 00227 EquationSystems temp_es (mesh); 00228 ExplicitSystem& error_system 00229 = temp_es.add_system<ExplicitSystem> ("Error"); 00230 error_system.add_variable("error", CONSTANT, MONOMIAL); 00231 temp_es.init(); 00232 00233 const DofMap& error_dof_map = error_system.get_dof_map(); 00234 00235 MeshBase::const_element_iterator el = 00236 mesh.active_local_elements_begin(); 00237 const MeshBase::const_element_iterator end_el = 00238 mesh.active_local_elements_end(); 00239 std::vector<dof_id_type> dof_indices; 00240 00241 for ( ; el != end_el; ++el) 00242 { 00243 const Elem* elem = *el; 00244 00245 error_dof_map.dof_indices(elem, dof_indices); 00246 00247 const dof_id_type elem_id = elem->id(); 00248 00249 //0 for the monomial basis 00250 const dof_id_type solution_index = dof_indices[0]; 00251 00252 // libMesh::out << "elem_number=" << elem_number << std::endl; 00253 libmesh_assert_less (elem_id, (*this).size()); 00254 00255 // We may have zero error values in special circumstances 00256 // libmesh_assert_greater ((*this)[elem_id], 0.); 00257 error_system.solution->set(solution_index, (*this)[elem_id]); 00258 } 00259 00260 // We may have to renumber if the original numbering was not 00261 // contiguous. Since this is just a temporary mesh, that's probably 00262 // fine. 00263 if (mesh.max_elem_id() != mesh.n_elem() || 00264 mesh.max_node_id() != mesh.n_nodes()) 00265 { 00266 mesh.allow_renumbering(true); 00267 mesh.renumber_nodes_and_elements(); 00268 } 00269 00270 if (filename.rfind(".gmv") < filename.size()) 00271 { 00272 GMVIO(mesh).write_discontinuous_gmv(filename, 00273 temp_es, false); 00274 } 00275 else if (filename.rfind(".plt") < filename.size()) 00276 { 00277 TecplotIO (mesh).write_equation_systems 00278 (filename, temp_es); 00279 } 00280 #ifdef LIBMESH_HAVE_EXODUS_API 00281 else if( (filename.rfind(".exo") < filename.size()) || 00282 (filename.rfind(".e") < filename.size()) ) 00283 { 00284 ExodusII_IO io(mesh); 00285 io.write(filename); 00286 io.write_element_data(temp_es); 00287 } 00288 #endif 00289 else 00290 { 00291 libmesh_here(); 00292 libMesh::err << "Warning: ErrorVector::plot_error currently only" 00293 << " supports .gmv and .plt and .exo/.e (if enabled) output;" << std::endl; 00294 libMesh::err << "Could not recognize filename: " << filename 00295 << std::endl; 00296 } 00297 } 00298 00299 } // namespace libMesh