1 /* *****************************************************************
2     MESQUITE -- The Mesh Quality Improvement Toolkit
3 
4     Copyright 2007 Sandia National Laboratories.  Developed at the
5     University of Wisconsin--Madison under SNL contract number
6     624796.  The U.S. Government and the University of Wisconsin
7     retain certain rights to 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     (2007) kraftche@cae.wisc.edu
24 
25   ***************************************************************** */
26 
27 
28 /** \file MsqIMesh.hpp
29  *  \brief Adaptor for ITAPS iMesh interface
30  *  \author Jason Kraftcheck
31  */
32 
33 #ifndef MSQ_I_MESH_HPP
34 #define MSQ_I_MESH_HPP
35 
36 #include "MeshInterface.hpp"
37 #include "iMesh.h"
38 
39 namespace MBMesquite {
40 
41 /** The name of the tag (integer) that Mesquite will use
42  *  to store internal data
43  */
44 const char* const VERTEX_BYTE_TAG_NAME  = "MesquiteVertexByte";
45 
46 /**\class MsqIMesh
47  *\brief Mesquite iMesh Adapter
48  *
49  * Adpater for interfacing Mesquite with an application that provides
50  * the ITAPS iMesh interface for interacting with mesh data.
51  */
52 class MsqIMesh : virtual public MBMesquite::Mesh
53 {
54 public:
55 //********* Functions that are NOT inherited ************
56 
57   MsqIMesh();
58   virtual ~MsqIMesh();
59 
60   /**\brief Create iMesh adaptor instance
61    *\param imesh      The iMesh instance to interact with
62    *\param meshset    The set of elements for which to optimize the quality
63    *
64    *\param element_dimension Optimize the subset of the elements in
65    *                  'meshset' with this dimension.  Pass iBase_ALL_TYPES
66    *                  for both iBase_FACE and iBase_REGION elements.
67    *                  If 'meshset' is the root set, then this argument is
68    *                  typically either iBase_FACE or iBase_REGION.
69    *
70    *\param fixed_tag  A pointer to the tag handle designating a tag
71    *                  containing fixed flags for vertices.  The tag must
72    *                  have size==1 and type==iBase_INTEGER or iBase_BYTES.
73    *                  A value of one for a vertex indicates that the vertex
74    *                  position is fixed.  A value of zero indicates a free
75    *                  vertex (a vertex that Mesquite may move to improve
76    *                  mesh quality.)  If this tag is not specified, then
77    *                  the boundary constraints of the optimization must be
78    *                  specified using an MsqIRel instance.
79    *
80    *\param slaved_tag A pointer to the tag handle designating a tag
81    *                  containing slaved flags for vertices.  The tag must
82    *                  have size==1 and type==iBase_INTEGER or iBase_BYTES.
83    *                  This tag value is ignored for corner vertices of
84    *                  elements.  The concept of 'slaved' is applicable only
85    *                  to non-corner vertices in higher-order elements. A
86    *                  value of one for a vertex indicates that the vertex
87    *                  position should is a fucntion of the element shape
88    *                  function, while a zero value indicates that the
89    *                  element shape function is a function of the vertex
90    *                  position.
91    */
92   MsqIMesh( iMesh_Instance imesh,
93             iBase_EntitySetHandle meshset,
94 	    iBase_EntityType element_dimension,
95             MsqError& err,
96 	    const iBase_TagHandle* fixed_tag = 0,
97 	    const iBase_TagHandle* slaved_tag= 0 );
98 
99   /**\brief Create iMesh adaptor instance
100    *
101    * This constructor is provided for the creation of an MsqIMesh instance
102    * that is to be re-used for multiple optimization calls for different
103    * sets of elements.  set_active_set must be called to define the
104    * subset of the mesh to optimize before an instance constructed with
105    * this constructor may be used in an optimization.
106    *
107    *\param imesh      The iMesh instance to interact with
108    *
109    *\param element_dimension Optimize the subset of the elements in
110    *                  root set with this dimension.  Pass iBase_ALL_TYPES
111    *                  for both iBase_FACE and iBase_REGION elements.
112    *                  If 'meshset' is the root set, then this argument is
113    *                  typically either iBase_FACE or iBase_REGION.
114    *
115    *\param fixed_tag  A pointer to the tag handle designating a tag
116    *                  containing fixed flags for vertices.  The tag must
117    *                  have size==1 and type==iBase_INTEGER or iBase_BYTES.
118    *                  A value of one for a vertex indicates that the vertex
119    *                  position is fixed.  A value of zero indicates a free
120    *                  vertex (a vertex that Mesquite may move to improve
121    *                  mesh quality.)  If this tag is not specified, then
122    *                  the boundary constraints of the optimization must be
123    *                  specified using an MsqIRel instance.
124    *
125    *\param slaved_tag A pointer to the tag handle designating a tag
126    *                  containing slaved flags for vertices.  The tag must
127    *                  have size==1 and type==iBase_INTEGER or iBase_BYTES.
128    *                  This tag value is ignored for corner vertices of
129    *                  elements.  The concept of 'slaved' is applicable only
130    *                  to non-corner vertices in higher-order elements. A
131    *                  value of one for a vertex indicates that the vertex
132    *                  position should is a fucntion of the element shape
133    *                  function, while a zero value indicates that the
134    *                  element shape function is a function of the vertex
135    *                  position.
136    */
137   MsqIMesh( iMesh_Instance imesh,
138 	    iBase_EntityType element_dimension,
139             MsqError& err,
140 	    const iBase_TagHandle* fixed_tag = 0,
141 	    const iBase_TagHandle* slaved_tag= 0 );
142 
143   /** \brief set mesh to be smoothed.
144    *
145    * Set the mesh which Mesquite is to smooth.  Optionally
146    * specify fixed vertices.
147    * NOTE: If an active set is not specified, the default
148    *       is to use the global set (the ENTIRE mesh.)
149    *
150    *\param element_set ITAPS entity set handle for set containing
151    *                  mesh elements and vertices for which quality
152    *                  is to be improved.
153    */
154   void set_active_set( iBase_EntitySetHandle meshset,
155                        iBase_EntityType element_dimension,
156                        MsqError& err );
157 
158   void set_fixed_tag( iBase_TagHandle tag, MsqError& err ); //!< Set tag for vertex fixed flag
159   void set_slaved_tag( iBase_TagHandle tag, MsqError& err );//!< Set tag for vertex slaved flag
160   void clear_fixed_tag();  //!< No tag for vertex fixed flag
161   void clear_slaved_tag(); //!< No tag for vertex fixed flag
162   const iBase_TagHandle* get_fixed_tag() const;  //!< Get tag for vertex fixed flag
163   const iBase_TagHandle* get_slaved_tag() const; //!< Get tag for vertex slaved flag
164 
165   virtual iMesh_Instance get_imesh_instance() const;
166   virtual iBase_EntitySetHandle get_entity_set() const;
167 
168 //********* Functions that ARE inherited ************
169 
170       /**\brief Get dimension of vertex coordinates (2D vs. 3D). */
171     virtual int get_geometric_dimension(MBMesquite::MsqError &/*err*/);
172 
173     /** \brief Get handles for all elemnents */
174     virtual void get_all_elements( std::vector<ElementHandle>& elements,
175                                    MsqError& err );
176 
177     /** \brief Get handles for all vertices */
178     virtual void get_all_vertices( std::vector<VertexHandle>& vertices,
179                                    MsqError& err );
180 
181       /**\brief Query "fixed" flag for a vertex */
182     virtual void vertices_get_fixed_flag( const VertexHandle vert_array[],
183                                           std::vector<bool>& fixed_flag_array,
184                                           size_t num_vtx,
185                                           MsqError &err);
186 
187     virtual void vertices_get_slaved_flag( const VertexHandle vert_array[],
188                                            std::vector<bool>& slaved_flag_array,
189                                            size_t num_vtx,
190                                            MsqError &err );
191 
192       /**\brief Get vertex coordinates */
193     virtual void vertices_get_coordinates( const VertexHandle vert_array[],
194                                            MsqVertex* coordinates,
195                                            size_t num_vtx,
196                                            MsqError &err);
197       /**\brief Set vertex coordinates */
198     virtual void vertex_set_coordinates( VertexHandle vertex,
199                                          const Vector3D &coordinates,
200                                          MsqError &err);
201 
202       /**\brief Set vertex mark */
203     virtual void vertex_set_byte( VertexHandle vertex,
204                                   unsigned char byte,
205                                   MsqError &err);
206       /**\brief Set vertex mark */
207     virtual void vertices_set_byte( const VertexHandle *vert_array,
208                                     const unsigned char *byte_array,
209                                     size_t array_size,
210                                     MsqError &err);
211 
212       /**\brief Get vertex mark */
213     virtual void vertex_get_byte( VertexHandle vertex,
214                                   unsigned char *byte,
215                                   MsqError &err);
216       /**\brief Get vertex mark */
217     virtual void vertices_get_byte( const VertexHandle *vert_array,
218                                     unsigned char *byte_array,
219                                     size_t array_size,
220                                     MsqError &err);
221 
222       /**\brief Get vertex-to-element adjacencies */
223     virtual void vertices_get_attached_elements( const VertexHandle* vertex_array,
224                                                  size_t num_vertices,
225                                                  std::vector<ElementHandle>& elements,
226                                                  std::vector<size_t>& offsets,
227                                                  MsqError& err );
228 
229       /**\brief Get element connectivity */
230     virtual void elements_get_attached_vertices( const ElementHandle *elem_handles,
231                                                  size_t num_elems,
232                                                  std::vector<VertexHandle>& vertices,
233                                                  std::vector<size_t>& offsets,
234                                                  MsqError& err );
235 
236 
237       /**\brief Return topology type enum for an array of elements */
238     virtual void elements_get_topologies( const ElementHandle *element_handle_array,
239                                           EntityTopology *element_topologies,
240                                           size_t num_elements,
241                                           MsqError &err );
242 
243 //**************** Memory Management ****************
244       /**\brief no-op */
245     virtual void release_entity_handles( const EntityHandle *handle_array,
246                                          size_t num_handles,
247                                          MsqError &err );
248 
249       // Instead of deleting a Mesh when you think you are done,
250       // call release().  In simple cases, the implementation could
251       // just call the destructor.  More sophisticated implementations
252       // may want to keep the Mesh object to live longer than Mesquite
253       // is using it.
254     virtual void release();
255 
256 //*************** Tags  ***********
257 
258       /** \brief Create a tag
259        *
260        * Create a user-defined data type that can be attached
261        * to any element or vertex in the mesh.  For an opaque or
262        * undefined type, use type=BYTE and length=sizeof(..).
263        *
264        * \param tag_name  A unique name for the data object
265        * \param type      The type of the data
266        * \param length    Number of values per entity (1->scalar, >1 ->vector)
267        * \param default_value Default value to assign to all entities - may be NULL
268        * \return - Handle for tag definition
269        */
270     virtual TagHandle tag_create( const std::string& tag_name,
271                                   TagType type, unsigned length,
272                                   const void* default_value,
273                                   MsqError &err);
274 
275       /** \brief Remove a tag and all corresponding data
276        *
277        * Delete a tag.
278        */
279     virtual void tag_delete( TagHandle handle, MsqError& err );
280 
281 
282       /** \brief Get handle for existing tag, by name. */
283     virtual TagHandle tag_get( const std::string& name,
284                                MsqError& err );
285 
286       /** \brief Get properites of tag
287        *
288        * Get data type and number of values per entity for tag.
289        * \param handle     Tag to get properties of.
290        * \param name_out   Passed back tag name.
291        * \param type_out   Passed back tag type.
292        * \param length_out Passed back number of values per entity.
293        */
294     virtual void tag_properties( TagHandle handle,
295                                  std::string& name_out,
296                                  TagType& type_out,
297                                  unsigned& length_out,
298                                  MsqError& err );
299 
300       /** \brief Set tag values on elements
301        *
302        * Set the value of a tag for a list of mesh elements.
303        * \param handle     The tag
304        * \param num_elems  Length of elem_array
305        * \param elem_array Array of elements for which to set the tag value.
306        * \param tag_data   Tag data for each element, contiguous in memory.
307        *                   This data is expected to be
308 
309        *                   num_elems*tag_length*sizeof(tag_type) bytes.
310        */
311     virtual void tag_set_element_data( TagHandle handle,
312                                        size_t num_elems,
313                                        const ElementHandle* elem_array,
314                                        const void* tag_data,
315                                        MsqError& err );
316 
317       /** \brief Set tag values on vertices
318        *
319        * Set the value of a tag for a list of mesh vertices.
320        * \param handle     The tag
321        * \param num_elems  Length of node_array
322        * \param node_array Array of vertices for which to set the tag value.
323        * \param tag_data   Tag data for each element, contiguous in memory.
324        *                   This data is expected to be
325        *                   num_elems*tag_length*sizeof(tag_type) bytes.
326        */
327     virtual void tag_set_vertex_data ( TagHandle handle,
328                                        size_t num_elems,
329                                        const VertexHandle* node_array,
330                                        const void* tag_data,
331                                        MsqError& err );
332 
333 
334       /** \brief Get tag values on elements
335        *
336        * Get the value of a tag for a list of mesh elements.
337        * \param handle     The tag
338        * \param num_elems  Length of elem_array
339        * \param elem_array Array of elements for which to get the tag value.
340        * \param tag_data   Return buffer in which to copy tag data, contiguous
341        *                   in memory.  This data is expected to be
342        *                   num_elems*tag_length*sizeof(tag_type) bytes.
343        */
344     virtual void tag_get_element_data( TagHandle handle,
345                                        size_t num_elems,
346                                        const ElementHandle* elem_array,
347                                        void* tag_data,
348                                        MsqError& err );
349 
350       /** \brief Get tag values on vertices.
351        *
352        * Get the value of a tag for a list of mesh vertices.
353        * \param handle     The tag
354        * \param num_elems  Length of elem_array
355        * \param elem_array Array of vertices for which to get the tag value.
356        * \param tag_data   Return buffer in which to copy tag data, contiguous
357        *                   in memory.  This data is expected to be
358        *                   num_elems*tag_length*sizeof(tag_type) bytes.
359        */
360     virtual void tag_get_vertex_data ( TagHandle handle,
361                                        size_t num_elems,
362                                        const VertexHandle* node_array,
363                                        void* tag_data,
364                                        MsqError& err );
365 
366 
367 
368   protected:
369 
370     iBase_TagValueType check_valid_flag_tag( iBase_TagHandle tag,
371                                               const char* which_flag,
372                                               MsqError& err );
373 
374     void set_int_tag( void* tag, void* meshset, int value, MsqError& err );
375 
376       /** \brief  Call TSTTM::Arr::getEntArrAdj
377        *
378        * Common code for \ref vertices_get_attached_elements and
379        * \ref elements_get_attached_vertices
380        *
381        *\param source      Array of handles of source entities to query from
382        *\param num_source  The length of \ref source
383        *\param target_type The type of entity to query for
384        *\param target      The output list of adjacent entities
385        *\param offsets     For each entity in \ref source, the offset in
386        *                   \ref target at which the corresponding adjacent
387        *                   entities are stored. (output)
388        */
389     void get_adjacent_entities( const iBase_EntityHandle* source,
390                                 size_t num_source,
391                                 iBase_EntityType target_type,
392                                 std::vector<EntityHandle>& target,
393                                 std::vector<size_t>& offsets,
394                                 MsqError& err );
395 
396     /** The IMesh instance */
397     iMesh_Instance meshInstance;
398 
399   private:
400 
401     void init_active_mesh( iMesh_Instance mesh,
402                            MsqError& err,
403         		   const iBase_TagHandle* fixed_tag,
404         		   const iBase_TagHandle* slaved_tag );
405 
406     void get_flag_data( iBase_TagHandle tag,
407                         bool have_tag,
408                         iBase_TagValueType type,
409                         const VertexHandle vert_array[],
410                         std::vector<bool>& flag_array,
411                         size_t num_vtx,
412                         MsqError& err );
413 
414       /** \brief Set tag values */
415     void tag_set_data ( TagHandle handle,
416                         size_t num_elems,
417                         const EntityHandle* handle_array,
418                         const void* tag_data,
419                         MsqError& err );
420 
421       /** \brief Get tag values */
422     void tag_get_data( TagHandle handle,
423                        size_t num_elems,
424                        const EntityHandle* handle_array,
425                        void* tag_data,
426                        MsqError& err );
427 
428     /** Have mesh */
429     bool haveMesh;
430     /** ITAPS entity set handle for elements to improve */
431     //iBase_EntitySetHandle elementSet;
432     /** ITAPS entity set handle for nodes to move */
433     //iBase_EntitySetHandle nodeSet;
434     /** std::set containing elements in elementSet, used
435      *  to constrain vertex->element adjaceny queries to
436      *  only those elements that are in the input element set.
437      */
438     //std::vector<iBase_EntityHandle> inputElements;
439 
440     /** The type of elements contained in the input element set.
441      * Should be one of:
442      * - iBase_REGION    - volume elements
443      * - iBase_FACE      - face/2d elements
444      * - iBase_ALL_TYPES - mixed volume and face elements
445      */
446     iBase_EntityType inputSetType;
447     /** The meshset containing the elements to optimize */
448     iBase_EntitySetHandle inputSet;
449 
450     /** Handle for tag used to hold vertex byte */
451     iBase_TagHandle byteTag;
452     /** Tag was created in constructor */
453     bool createdByteTag;
454     /** Handle for tag used to hold vertex-fixed flag */
455     iBase_TagHandle fixedTag;
456     /** fixedTag handle is valid */
457     bool haveFixedTag;
458     /** iBase_TYPE for fixed tag */
459     iBase_TagValueType fixedTagType;
460     /** Handle for tag used to hold vertex-slaved flag */
461     iBase_TagHandle slavedTag;
462     /** slavedTag handle is valid */
463     bool haveSlavedTag;
464     /** iBase_TYPE for slaved tag */
465     iBase_TagValueType slavedTagType;
466     /** Dimension is queried once during create and cached */
467     int geometricDimension;
468     /** Map iMesh_EntityTopology to MBMesquite::EntityTopology */
469     EntityTopology topologyMap[iMesh_ALL_TOPOLOGIES+1];
470 };
471 
472 } // namespace Mesquite
473 
474 #endif
475