MOAB: Mesh Oriented datABase  (version 5.3.0)
EdgeQM.cpp
Go to the documentation of this file.
00001 /* *****************************************************************
00002     MESQUITE -- The Mesh Quality Improvement Toolkit
00003 
00004     Copyright 2009 Sandia National Laboratories.  Developed at the
00005     University of Wisconsin--Madison under SNL contract number
00006     624796.  The U.S. Government and the University of Wisconsin
00007     retain certain rights to this software.
00008 
00009     This library is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU Lesser General Public
00011     License as published by the Free Software Foundation; either
00012     version 2.1 of the License, or (at your option) any later version.
00013 
00014     This library is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017     Lesser General Public License for more details.
00018 
00019     You should have received a copy of the GNU Lesser General Public License
00020     (lgpl.txt) along with this library; if not, write to the Free Software
00021     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 
00023     (2009) kraftche@cae.wisc.edu
00024 
00025   ***************************************************************** */
00026 
00027 /** \file EdgeQM.cpp
00028  *  \brief
00029  *  \author Jason Kraftcheck
00030  */
00031 
00032 #include "Mesquite.hpp"
00033 #include "EdgeQM.hpp"
00034 #include "ElemSampleQM.hpp"
00035 #include "PatchData.hpp"
00036 #include "TopologyInfo.hpp"
00037 
00038 namespace MBMesquite
00039 {
00040 
00041 EdgeQM::~EdgeQM() {}
00042 
00043 void EdgeQM::get_evaluations( PatchData& pd, std::vector< size_t >& handles, bool free_vertices_only, MsqError& err )
00044 {
00045     get_edge_evaluations( pd, handles, free_vertices_only, false, err );
00046 }
00047 
00048 void EdgeQM::get_single_pass( PatchData& pd, std::vector< size_t >& handles, bool free_vertices_only, MsqError& err )
00049 {
00050     get_edge_evaluations( pd, handles, free_vertices_only, true, err );
00051 }
00052 
00053 struct EdgeData
00054 {
00055     size_t endVtx;
00056     size_t adjElem;
00057     unsigned elemEdge;
00058 };
00059 
00060 inline bool operator<( const EdgeData& e1, const EdgeData& e2 )
00061 {
00062     return e1.endVtx < e2.endVtx;
00063 }
00064 inline bool operator==( const EdgeData& e1, const EdgeData& e2 )
00065 {
00066     return e1.endVtx == e2.endVtx;
00067 }
00068 
00069 void EdgeQM::get_edge_evaluations( PatchData& pd, std::vector< size_t >& handles, bool free_vertices_only,
00070                                    bool single_pass_evaluate, MsqError& err )
00071 {
00072     std::vector< EdgeData > vtx_edges;
00073     size_t n_verts  = free_vertices_only ? pd.num_free_vertices() : pd.num_nodes();
00074     size_t n_cutoff = single_pass_evaluate ? pd.num_nodes() : n_verts;
00075     handles.clear();
00076 
00077     for( size_t i = 0; i < n_verts; ++i )
00078     {
00079         if( pd.vertex_by_index( i ).is_flag_set( MsqVertex::MSQ_PATCH_FIXED ) ) continue;
00080 
00081         vtx_edges.clear();
00082 
00083         size_t n_elems;
00084         const size_t* elems;
00085         elems = pd.get_vertex_element_adjacencies( i, n_elems, err );MSQ_ERRRTN( err );
00086 
00087         for( size_t j = 0; j < n_elems; ++j )
00088         {
00089             MsqMeshEntity& elem = pd.element_by_index( elems[j] );
00090             unsigned n_edges    = TopologyInfo::edges( elem.get_element_type() );
00091             for( unsigned k = 0; k < n_edges; ++k )
00092             {
00093                 const unsigned* edge = TopologyInfo::edge_vertices( elem.get_element_type(), k, err );MSQ_ERRRTN( err );
00094 
00095                 size_t vtx1 = elem.get_vertex_index_array()[edge[0]];
00096                 size_t vtx2 = elem.get_vertex_index_array()[edge[1]];
00097                 size_t other;
00098                 if( vtx1 == i )
00099                     other = vtx2;
00100                 else if( vtx2 == i )
00101                     other = vtx1;
00102                 else
00103                     continue;
00104 
00105                 // If !free_vertices_only, we'll visit every edge twice.
00106                 // The first check below ensures that we only add each edge
00107                 // once.  The second check is never true unless free_vertices_only
00108                 // is true and single_pass_evaluate is false.  In that case, it
00109                 // serves as an exception to the first rule for those cases in which
00110                 // we visit an edge only once.  For single_pass_evaluate (e.g.
00111                 // BCD initialization or QualityAssessor) we want to avoid visiting
00112                 // and edge more than once for every patch rather than just within
00113                 // this patch.
00114                 if( other > i || other > n_cutoff )
00115                 {
00116                     EdgeData d = { other, elems[j], k };
00117                     vtx_edges.push_back( d );
00118                 }
00119             }  // end for each edge in element
00120         }      // end for each element adjacent to vertex
00121 
00122         std::sort( vtx_edges.begin(), vtx_edges.end() );
00123         std::vector< EdgeData >::iterator it, end;
00124         end = std::unique( vtx_edges.begin(), vtx_edges.end() );
00125         for( it = vtx_edges.begin(); it != end; ++it )
00126             handles.push_back( handle( it->elemEdge, it->adjElem ) );
00127     }  // end for each (free) vertex
00128 }
00129 
00130 bool EdgeQM::evaluate_with_indices( PatchData& pd, size_t p_handle, double& value, std::vector< size_t >& indices,
00131                                     MsqError& err )
00132 {
00133     const MsqMeshEntity& element = pd.element_by_index( elem( p_handle ) );
00134     EntityTopology type          = element.get_element_type();
00135     const unsigned* verts        = TopologyInfo::edge_vertices( type, edge( p_handle ) );
00136     const size_t* conn           = element.get_vertex_index_array();
00137     indices.clear();
00138     if( conn[verts[0]] < pd.num_free_vertices() ) indices.push_back( conn[verts[0]] );
00139     if( conn[verts[1]] < pd.num_free_vertices() ) indices.push_back( conn[verts[1]] );
00140     return evaluate( pd, p_handle, value, err );
00141 }
00142 
00143 }  // namespace MBMesquite
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines