MOAB: Mesh Oriented datABase
(version 5.4.1)
|
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) [email protected] 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