MOAB: Mesh Oriented datABase  (version 5.4.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,
00070                                    std::vector< size_t >& handles,
00071                                    bool free_vertices_only,
00072                                    bool single_pass_evaluate,
00073                                    MsqError& err )
00074 {
00075     std::vector< EdgeData > vtx_edges;
00076     size_t n_verts  = free_vertices_only ? pd.num_free_vertices() : pd.num_nodes();
00077     size_t n_cutoff = single_pass_evaluate ? pd.num_nodes() : n_verts;
00078     handles.clear();
00079 
00080     for( size_t i = 0; i < n_verts; ++i )
00081     {
00082         if( pd.vertex_by_index( i ).is_flag_set( MsqVertex::MSQ_PATCH_FIXED ) ) continue;
00083 
00084         vtx_edges.clear();
00085 
00086         size_t n_elems;
00087         const size_t* elems;
00088         elems = pd.get_vertex_element_adjacencies( i, n_elems, err );MSQ_ERRRTN( err );
00089 
00090         for( size_t j = 0; j < n_elems; ++j )
00091         {
00092             MsqMeshEntity& elem = pd.element_by_index( elems[j] );
00093             unsigned n_edges    = TopologyInfo::edges( elem.get_element_type() );
00094             for( unsigned k = 0; k < n_edges; ++k )
00095             {
00096                 const unsigned* edge = TopologyInfo::edge_vertices( elem.get_element_type(), k, err );MSQ_ERRRTN( err );
00097 
00098                 size_t vtx1 = elem.get_vertex_index_array()[edge[0]];
00099                 size_t vtx2 = elem.get_vertex_index_array()[edge[1]];
00100                 size_t other;
00101                 if( vtx1 == i )
00102                     other = vtx2;
00103                 else if( vtx2 == i )
00104                     other = vtx1;
00105                 else
00106                     continue;
00107 
00108                 // If !free_vertices_only, we'll visit every edge twice.
00109                 // The first check below ensures that we only add each edge
00110                 // once.  The second check is never true unless free_vertices_only
00111                 // is true and single_pass_evaluate is false.  In that case, it
00112                 // serves as an exception to the first rule for those cases in which
00113                 // we visit an edge only once.  For single_pass_evaluate (e.g.
00114                 // BCD initialization or QualityAssessor) we want to avoid visiting
00115                 // and edge more than once for every patch rather than just within
00116                 // this patch.
00117                 if( other > i || other > n_cutoff )
00118                 {
00119                     EdgeData d = { other, elems[j], k };
00120                     vtx_edges.push_back( d );
00121                 }
00122             }  // end for each edge in element
00123         }      // end for each element adjacent to vertex
00124 
00125         std::sort( vtx_edges.begin(), vtx_edges.end() );
00126         std::vector< EdgeData >::iterator it, end;
00127         end = std::unique( vtx_edges.begin(), vtx_edges.end() );
00128         for( it = vtx_edges.begin(); it != end; ++it )
00129             handles.push_back( handle( it->elemEdge, it->adjElem ) );
00130     }  // end for each (free) vertex
00131 }
00132 
00133 bool EdgeQM::evaluate_with_indices( PatchData& pd,
00134                                     size_t p_handle,
00135                                     double& value,
00136                                     std::vector< size_t >& indices,
00137                                     MsqError& err )
00138 {
00139     const MsqMeshEntity& element = pd.element_by_index( elem( p_handle ) );
00140     EntityTopology type          = element.get_element_type();
00141     const unsigned* verts        = TopologyInfo::edge_vertices( type, edge( p_handle ) );
00142     const size_t* conn           = element.get_vertex_index_array();
00143     indices.clear();
00144     if( conn[verts[0]] < pd.num_free_vertices() ) indices.push_back( conn[verts[0]] );
00145     if( conn[verts[1]] < pd.num_free_vertices() ) indices.push_back( conn[verts[1]] );
00146     return evaluate( pd, p_handle, value, err );
00147 }
00148 
00149 }  // namespace MBMesquite
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines