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