$extrastylesheet
error_vector.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 // 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