1 /* ***************************************************************** 2 MESQUITE -- The Mesh Quality Improvement Toolkit 3 4 Copyright 2008 Lawrence Livermore National Laboratory. Under 5 the terms of Contract B545069 with the University of Wisconsin -- 6 Madison, Lawrence Livermore National Laboratory retains certain 7 rights in this software. 8 9 This library is free software; you can redistribute it and/or 10 modify it under the terms of the GNU Lesser General Public 11 License as published by the Free Software Foundation; either 12 version 2.1 of the License, or (at your option) any later version. 13 14 This library is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 Lesser General Public License for more details. 18 19 You should have received a copy of the GNU Lesser General Public License 20 (lgpl.txt) along with this library; if not, write to the Free Software 21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 23 (2008) kraftche@cae.wisc.edu 24 25 ***************************************************************** */ 26 27 #ifndef MSQ_DOMAIN_CLASSIFIER_HPP 28 #define MSQ_DOMAIN_CLASSIFIER_HPP 29 30 /** \file DomainClassifier.hpp 31 * \brief 32 * \author Jason Kraftcheck 33 */ 34 35 #include "Mesquite.hpp" 36 #include "MeshInterface.hpp" 37 38 namespace MBMesquite { 39 40 /**\brief Assign subsets of a mesh do different domains. 41 * 42 * Provide classification of mesh entities to domain(s). For 43 * example, given a domain defined by multiple surfaces and 44 * curves of intersection, associate the appropriate elements 45 * and vertices to the appropriate geometric entities. 46 */ 47 class DomainClassifier : public MeshDomain 48 { 49 public: 50 51 /**\brief Check that classification maps to B-Rep topology */ 52 MESQUITE_EXPORT void test_valid_classification( Mesh* mesh, MsqError& err ); 53 54 /**\brief Classify mesh entities using tag values 55 * 56 * Given a list of MeshDomain instances, a unique 57 * integer ID for each MeshDomain, and a tag name: 58 * classify mesh entities by matching the tag value 59 * on each mesh entity to the list of MeshDomain IDs. 60 * 61 *\param result DomainClassifier to popupate 62 *\param mesh The MBMesquite::Mesh instance 63 *\param tag_name Tag containing integer domain ID for each mesh entity. 64 *\param domain_array Array of MeshDomain instances. 65 *\param id_array Array of integer MeshDomain IDs. 66 *\param array_length Length of 'domain_array' and 'id_array' 67 */ 68 static MESQUITE_EXPORT 69 void classify_by_tag( DomainClassifier& result, 70 Mesh* mesh, 71 const char* tag_name, 72 MeshDomain** domain_array, 73 const int* id_array, 74 unsigned array_length, 75 MsqError& err ); 76 77 /**\brief Skin mesh and classify skin entities geometrically. 78 * 79 * Calculate the boundary of the mesh, and classify boundary 80 * entities by calculating the distance from the mesh domain 81 * to each vertex. 82 * 83 * NOTE: Mesquite's limited MeshDomain callback interface 84 * is not sufficient for robust geometric classification. If 85 * the mesh is not sufficiently refined, this method may produce 86 * invalid results. 87 * 88 * NOTE: This method should not be used for surface meshes. 89 * Everything in a surface mesh should be classified to a domain. 90 * not just the skin. Use classify_geometrically instead. 91 * 92 *\param result DomainClassifier to popupate 93 *\param mesh The MBMesquite::Mesh instance 94 *\param tolerance Maximum distance a vertex may deviate from its domain. 95 *\param domain_array Array of MeshDomain instances. 96 *\param dimension_array Topological dimensiono of each MeshDomain 97 *\param array_length Length of 'domain_array' and 'dimension_array' 98 */ 99 MESQUITE_EXPORT static 100 void classify_skin_geometrically( DomainClassifier& result, 101 Mesh* mesh, 102 double tolerance, 103 MeshDomain** domain_array, 104 const int* dimension_array, 105 unsigned array_length, 106 MsqError& err ); 107 108 /**\brief Classify all mesh entities geometrically. 109 * 110 * Classify entities by distance from vertex coordiantes to 111 * mesh domain instances. 112 * 113 * NOTE: Mesquite's limited MeshDomain callback interface 114 * is not sufficient for robust geometric classification. If 115 * the mesh is not sufficiently refined, this method may produce 116 * invalid results. 117 * 118 * NOTE: This method is likely to fail for many domains for 119 * volume meshes. Use classify_skin_geometrically for 120 * volume meshes. 121 * 122 *\param result DomainClassifier to popupate 123 *\param mesh The MBMesquite::Mesh instance 124 *\param tolerance Maximum distance a vertex may deviate from its domain. 125 *\param domain_array Array of MeshDomain instances. 126 *\param dimension_array Topological dimensiono of each MeshDomain 127 *\param array_length Length of 'domain_array' and 'dimension_array' 128 */ 129 MESQUITE_EXPORT static 130 void classify_geometrically( DomainClassifier& result, 131 Mesh* mesh, 132 double tolerance, 133 MeshDomain** domain_array, 134 const int* dimension_array, 135 unsigned array_length, 136 MsqError& err ); 137 138 struct DomainSet { DomainSetMBMesquite::DomainClassifier::DomainSet139 MESQUITE_EXPORT DomainSet( MeshDomain* dom ) : domain(dom) {} DomainSetMBMesquite::DomainClassifier::DomainSet140 MESQUITE_EXPORT DomainSet() : domain(0) {} 141 MeshDomain* domain; set_verticesMBMesquite::DomainClassifier::DomainSet142 MESQUITE_EXPORT void set_vertices( const std::vector<Mesh::VertexHandle>& verts ) 143 { vertices = verts; } set_elementsMBMesquite::DomainClassifier::DomainSet144 MESQUITE_EXPORT void set_elements( const std::vector<Mesh::ElementHandle>& elems ) 145 { elements = elems; } get_verticesMBMesquite::DomainClassifier::DomainSet146 MESQUITE_EXPORT void get_vertices( std::vector<Mesh::VertexHandle>& verts ) const 147 { verts = vertices; } get_elementsMBMesquite::DomainClassifier::DomainSet148 MESQUITE_EXPORT void get_elements( std::vector<Mesh::ElementHandle>& elems ) const 149 { elems = elements; } 150 std::vector<Mesh::VertexHandle> vertices; 151 std::vector<Mesh::ElementHandle> elements; 152 }; 153 154 /**\brief Specify classification explicitly for each entity. 155 * 156 * For each mesh element and vertex that is classified to 157 * a domain, specify that classification explicitly. 158 * 159 *\param result DomainClassifier to popupate 160 *\param mesh The MBMesquite::Mesh instance 161 *\param domain_set_array Array of DomainClassifier::DomainSet structs 162 * specifying for each MeshDomain: the 163 * domain instance and the elements and 164 * vertices associated with the domain. 165 *\param array_length Length of 'domain_set_array' 166 */ 167 MESQUITE_EXPORT static 168 void classify_by_handle( DomainClassifier& result, 169 Mesh* mesh, 170 DomainSet* domain_set_array, 171 unsigned array_length, 172 MsqError& err ); 173 DomainClassifier()174 MESQUITE_EXPORT DomainClassifier() : deleteSubDomains(false) 175 {} 176 177 MESQUITE_EXPORT virtual ~DomainClassifier(); 178 179 MESQUITE_EXPORT 180 virtual void snap_to( Mesh::VertexHandle entity_handle, 181 Vector3D &coordinate) const; 182 183 MESQUITE_EXPORT 184 virtual void vertex_normal_at( Mesh::VertexHandle entity_handle, 185 Vector3D &coordinate) const; 186 MESQUITE_EXPORT 187 virtual void element_normal_at( Mesh::ElementHandle entity_handle, 188 Vector3D &coordinate) const; 189 190 MESQUITE_EXPORT 191 virtual void vertex_normal_at( const Mesh::VertexHandle* handles, 192 Vector3D coordinates[], 193 unsigned count, 194 MsqError& err ) const; 195 196 MESQUITE_EXPORT 197 virtual void closest_point( Mesh::VertexHandle handle, 198 const Vector3D& position, 199 Vector3D& closest, 200 Vector3D& normal, 201 MsqError& err ) const; 202 203 MESQUITE_EXPORT 204 virtual void domain_DoF( const Mesh::VertexHandle* handle_array, 205 unsigned short* dof_array, 206 size_t num_handles, 207 MsqError& err ) const; 208 209 /**\brief Clear all data, including MeshDomain list */ 210 MESQUITE_EXPORT clear()211 void clear() { 212 vertexList.clear(); 213 elementList.clear(); 214 } 215 216 struct DomainBlock { 217 Mesh::EntityHandle firstHandle; 218 Mesh::EntityHandle lastHandle; 219 MeshDomain* domain; 220 }; 221 222 MESQUITE_EXPORT find_vertex_domain(Mesh::VertexHandle vertex) const223 MeshDomain* find_vertex_domain( Mesh::VertexHandle vertex ) const 224 { return find_domain( vertex, vertexList ); } 225 MESQUITE_EXPORT find_element_domain(Mesh::ElementHandle element) const226 MeshDomain* find_element_domain( Mesh::ElementHandle element ) const 227 { return find_domain( element, elementList ); } 228 229 MESQUITE_EXPORT delete_sub_domains(bool yesno)230 void delete_sub_domains(bool yesno) 231 { deleteSubDomains = yesno; } 232 233 MESQUITE_EXPORT 234 void delete_all_sub_domains(); 235 236 private: 237 bool deleteSubDomains; 238 239 static MeshDomain* find_domain( Mesh::EntityHandle handle, 240 const std::vector<DomainBlock>& list ); 241 242 std::vector<DomainBlock> vertexList; 243 std::vector<DomainBlock> elementList; 244 }; 245 246 } // namespace MBMesquite 247 248 #endif // MSQ_DOMAIN_CLASSIFIER_HPP 249