/* ***************************************************************** MESQUITE -- The Mesh Quality Improvement Toolkit Copyright 2007 Sandia National Laboratories. Developed at the University of Wisconsin--Madison under SNL contract number 624796. The U.S. Government and the University of Wisconsin retain certain rights to this software. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License (lgpl.txt) along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA (2007) kraftche@cae.wisc.edu ***************************************************************** */ /** \file MsqIMesh.hpp * \brief Adaptor for ITAPS iMesh interface * \author Jason Kraftcheck */ #ifndef MSQ_I_MESH_HPP #define MSQ_I_MESH_HPP #include "MeshInterface.hpp" #include "iMesh.h" namespace MBMesquite { /** The name of the tag (integer) that Mesquite will use * to store internal data */ const char* const VERTEX_BYTE_TAG_NAME = "MesquiteVertexByte"; /**\class MsqIMesh *\brief Mesquite iMesh Adapter * * Adpater for interfacing Mesquite with an application that provides * the ITAPS iMesh interface for interacting with mesh data. */ class MsqIMesh : virtual public MBMesquite::Mesh { public: //********* Functions that are NOT inherited ************ MsqIMesh(); virtual ~MsqIMesh(); /**\brief Create iMesh adaptor instance *\param imesh The iMesh instance to interact with *\param meshset The set of elements for which to optimize the quality * *\param element_dimension Optimize the subset of the elements in * 'meshset' with this dimension. Pass iBase_ALL_TYPES * for both iBase_FACE and iBase_REGION elements. * If 'meshset' is the root set, then this argument is * typically either iBase_FACE or iBase_REGION. * *\param fixed_tag A pointer to the tag handle designating a tag * containing fixed flags for vertices. The tag must * have size==1 and type==iBase_INTEGER or iBase_BYTES. * A value of one for a vertex indicates that the vertex * position is fixed. A value of zero indicates a free * vertex (a vertex that Mesquite may move to improve * mesh quality.) If this tag is not specified, then * the boundary constraints of the optimization must be * specified using an MsqIRel instance. * *\param slaved_tag A pointer to the tag handle designating a tag * containing slaved flags for vertices. The tag must * have size==1 and type==iBase_INTEGER or iBase_BYTES. * This tag value is ignored for corner vertices of * elements. The concept of 'slaved' is applicable only * to non-corner vertices in higher-order elements. A * value of one for a vertex indicates that the vertex * position should is a fucntion of the element shape * function, while a zero value indicates that the * element shape function is a function of the vertex * position. */ MsqIMesh( iMesh_Instance imesh, iBase_EntitySetHandle meshset, iBase_EntityType element_dimension, MsqError& err, const iBase_TagHandle* fixed_tag = 0, const iBase_TagHandle* slaved_tag= 0 ); /**\brief Create iMesh adaptor instance * * This constructor is provided for the creation of an MsqIMesh instance * that is to be re-used for multiple optimization calls for different * sets of elements. set_active_set must be called to define the * subset of the mesh to optimize before an instance constructed with * this constructor may be used in an optimization. * *\param imesh The iMesh instance to interact with * *\param element_dimension Optimize the subset of the elements in * root set with this dimension. Pass iBase_ALL_TYPES * for both iBase_FACE and iBase_REGION elements. * If 'meshset' is the root set, then this argument is * typically either iBase_FACE or iBase_REGION. * *\param fixed_tag A pointer to the tag handle designating a tag * containing fixed flags for vertices. The tag must * have size==1 and type==iBase_INTEGER or iBase_BYTES. * A value of one for a vertex indicates that the vertex * position is fixed. A value of zero indicates a free * vertex (a vertex that Mesquite may move to improve * mesh quality.) If this tag is not specified, then * the boundary constraints of the optimization must be * specified using an MsqIRel instance. * *\param slaved_tag A pointer to the tag handle designating a tag * containing slaved flags for vertices. The tag must * have size==1 and type==iBase_INTEGER or iBase_BYTES. * This tag value is ignored for corner vertices of * elements. The concept of 'slaved' is applicable only * to non-corner vertices in higher-order elements. A * value of one for a vertex indicates that the vertex * position should is a fucntion of the element shape * function, while a zero value indicates that the * element shape function is a function of the vertex * position. */ MsqIMesh( iMesh_Instance imesh, iBase_EntityType element_dimension, MsqError& err, const iBase_TagHandle* fixed_tag = 0, const iBase_TagHandle* slaved_tag= 0 ); /** \brief set mesh to be smoothed. * * Set the mesh which Mesquite is to smooth. Optionally * specify fixed vertices. * NOTE: If an active set is not specified, the default * is to use the global set (the ENTIRE mesh.) * *\param element_set ITAPS entity set handle for set containing * mesh elements and vertices for which quality * is to be improved. */ void set_active_set( iBase_EntitySetHandle meshset, iBase_EntityType element_dimension, MsqError& err ); void set_fixed_tag( iBase_TagHandle tag, MsqError& err ); //!< Set tag for vertex fixed flag void set_slaved_tag( iBase_TagHandle tag, MsqError& err );//!< Set tag for vertex slaved flag void clear_fixed_tag(); //!< No tag for vertex fixed flag void clear_slaved_tag(); //!< No tag for vertex fixed flag const iBase_TagHandle* get_fixed_tag() const; //!< Get tag for vertex fixed flag const iBase_TagHandle* get_slaved_tag() const; //!< Get tag for vertex slaved flag virtual iMesh_Instance get_imesh_instance() const; virtual iBase_EntitySetHandle get_entity_set() const; //********* Functions that ARE inherited ************ /**\brief Get dimension of vertex coordinates (2D vs. 3D). */ virtual int get_geometric_dimension(MBMesquite::MsqError &/*err*/); /** \brief Get handles for all elemnents */ virtual void get_all_elements( std::vector& elements, MsqError& err ); /** \brief Get handles for all vertices */ virtual void get_all_vertices( std::vector& vertices, MsqError& err ); /**\brief Query "fixed" flag for a vertex */ virtual void vertices_get_fixed_flag( const VertexHandle vert_array[], std::vector& fixed_flag_array, size_t num_vtx, MsqError &err); virtual void vertices_get_slaved_flag( const VertexHandle vert_array[], std::vector& slaved_flag_array, size_t num_vtx, MsqError &err ); /**\brief Get vertex coordinates */ virtual void vertices_get_coordinates( const VertexHandle vert_array[], MsqVertex* coordinates, size_t num_vtx, MsqError &err); /**\brief Set vertex coordinates */ virtual void vertex_set_coordinates( VertexHandle vertex, const Vector3D &coordinates, MsqError &err); /**\brief Set vertex mark */ virtual void vertex_set_byte( VertexHandle vertex, unsigned char byte, MsqError &err); /**\brief Set vertex mark */ virtual void vertices_set_byte( const VertexHandle *vert_array, const unsigned char *byte_array, size_t array_size, MsqError &err); /**\brief Get vertex mark */ virtual void vertex_get_byte( VertexHandle vertex, unsigned char *byte, MsqError &err); /**\brief Get vertex mark */ virtual void vertices_get_byte( const VertexHandle *vert_array, unsigned char *byte_array, size_t array_size, MsqError &err); /**\brief Get vertex-to-element adjacencies */ virtual void vertices_get_attached_elements( const VertexHandle* vertex_array, size_t num_vertices, std::vector& elements, std::vector& offsets, MsqError& err ); /**\brief Get element connectivity */ virtual void elements_get_attached_vertices( const ElementHandle *elem_handles, size_t num_elems, std::vector& vertices, std::vector& offsets, MsqError& err ); /**\brief Return topology type enum for an array of elements */ virtual void elements_get_topologies( const ElementHandle *element_handle_array, EntityTopology *element_topologies, size_t num_elements, MsqError &err ); //**************** Memory Management **************** /**\brief no-op */ virtual void release_entity_handles( const EntityHandle *handle_array, size_t num_handles, MsqError &err ); // Instead of deleting a Mesh when you think you are done, // call release(). In simple cases, the implementation could // just call the destructor. More sophisticated implementations // may want to keep the Mesh object to live longer than Mesquite // is using it. virtual void release(); //*************** Tags *********** /** \brief Create a tag * * Create a user-defined data type that can be attached * to any element or vertex in the mesh. For an opaque or * undefined type, use type=BYTE and length=sizeof(..). * * \param tag_name A unique name for the data object * \param type The type of the data * \param length Number of values per entity (1->scalar, >1 ->vector) * \param default_value Default value to assign to all entities - may be NULL * \return - Handle for tag definition */ virtual TagHandle tag_create( const std::string& tag_name, TagType type, unsigned length, const void* default_value, MsqError &err); /** \brief Remove a tag and all corresponding data * * Delete a tag. */ virtual void tag_delete( TagHandle handle, MsqError& err ); /** \brief Get handle for existing tag, by name. */ virtual TagHandle tag_get( const std::string& name, MsqError& err ); /** \brief Get properites of tag * * Get data type and number of values per entity for tag. * \param handle Tag to get properties of. * \param name_out Passed back tag name. * \param type_out Passed back tag type. * \param length_out Passed back number of values per entity. */ virtual void tag_properties( TagHandle handle, std::string& name_out, TagType& type_out, unsigned& length_out, MsqError& err ); /** \brief Set tag values on elements * * Set the value of a tag for a list of mesh elements. * \param handle The tag * \param num_elems Length of elem_array * \param elem_array Array of elements for which to set the tag value. * \param tag_data Tag data for each element, contiguous in memory. * This data is expected to be * num_elems*tag_length*sizeof(tag_type) bytes. */ virtual void tag_set_element_data( TagHandle handle, size_t num_elems, const ElementHandle* elem_array, const void* tag_data, MsqError& err ); /** \brief Set tag values on vertices * * Set the value of a tag for a list of mesh vertices. * \param handle The tag * \param num_elems Length of node_array * \param node_array Array of vertices for which to set the tag value. * \param tag_data Tag data for each element, contiguous in memory. * This data is expected to be * num_elems*tag_length*sizeof(tag_type) bytes. */ virtual void tag_set_vertex_data ( TagHandle handle, size_t num_elems, const VertexHandle* node_array, const void* tag_data, MsqError& err ); /** \brief Get tag values on elements * * Get the value of a tag for a list of mesh elements. * \param handle The tag * \param num_elems Length of elem_array * \param elem_array Array of elements for which to get the tag value. * \param tag_data Return buffer in which to copy tag data, contiguous * in memory. This data is expected to be * num_elems*tag_length*sizeof(tag_type) bytes. */ virtual void tag_get_element_data( TagHandle handle, size_t num_elems, const ElementHandle* elem_array, void* tag_data, MsqError& err ); /** \brief Get tag values on vertices. * * Get the value of a tag for a list of mesh vertices. * \param handle The tag * \param num_elems Length of elem_array * \param elem_array Array of vertices for which to get the tag value. * \param tag_data Return buffer in which to copy tag data, contiguous * in memory. This data is expected to be * num_elems*tag_length*sizeof(tag_type) bytes. */ virtual void tag_get_vertex_data ( TagHandle handle, size_t num_elems, const VertexHandle* node_array, void* tag_data, MsqError& err ); protected: iBase_TagValueType check_valid_flag_tag( iBase_TagHandle tag, const char* which_flag, MsqError& err ); void set_int_tag( void* tag, void* meshset, int value, MsqError& err ); /** \brief Call TSTTM::Arr::getEntArrAdj * * Common code for \ref vertices_get_attached_elements and * \ref elements_get_attached_vertices * *\param source Array of handles of source entities to query from *\param num_source The length of \ref source *\param target_type The type of entity to query for *\param target The output list of adjacent entities *\param offsets For each entity in \ref source, the offset in * \ref target at which the corresponding adjacent * entities are stored. (output) */ void get_adjacent_entities( const iBase_EntityHandle* source, size_t num_source, iBase_EntityType target_type, std::vector& target, std::vector& offsets, MsqError& err ); /** The IMesh instance */ iMesh_Instance meshInstance; private: void init_active_mesh( iMesh_Instance mesh, MsqError& err, const iBase_TagHandle* fixed_tag, const iBase_TagHandle* slaved_tag ); void get_flag_data( iBase_TagHandle tag, bool have_tag, iBase_TagValueType type, const VertexHandle vert_array[], std::vector& flag_array, size_t num_vtx, MsqError& err ); /** \brief Set tag values */ void tag_set_data ( TagHandle handle, size_t num_elems, const EntityHandle* handle_array, const void* tag_data, MsqError& err ); /** \brief Get tag values */ void tag_get_data( TagHandle handle, size_t num_elems, const EntityHandle* handle_array, void* tag_data, MsqError& err ); /** Have mesh */ bool haveMesh; /** ITAPS entity set handle for elements to improve */ //iBase_EntitySetHandle elementSet; /** ITAPS entity set handle for nodes to move */ //iBase_EntitySetHandle nodeSet; /** std::set containing elements in elementSet, used * to constrain vertex->element adjaceny queries to * only those elements that are in the input element set. */ //std::vector inputElements; /** The type of elements contained in the input element set. * Should be one of: * - iBase_REGION - volume elements * - iBase_FACE - face/2d elements * - iBase_ALL_TYPES - mixed volume and face elements */ iBase_EntityType inputSetType; /** The meshset containing the elements to optimize */ iBase_EntitySetHandle inputSet; /** Handle for tag used to hold vertex byte */ iBase_TagHandle byteTag; /** Tag was created in constructor */ bool createdByteTag; /** Handle for tag used to hold vertex-fixed flag */ iBase_TagHandle fixedTag; /** fixedTag handle is valid */ bool haveFixedTag; /** iBase_TYPE for fixed tag */ iBase_TagValueType fixedTagType; /** Handle for tag used to hold vertex-slaved flag */ iBase_TagHandle slavedTag; /** slavedTag handle is valid */ bool haveSlavedTag; /** iBase_TYPE for slaved tag */ iBase_TagValueType slavedTagType; /** Dimension is queried once during create and cached */ int geometricDimension; /** Map iMesh_EntityTopology to MBMesquite::EntityTopology */ EntityTopology topologyMap[iMesh_ALL_TOPOLOGIES+1]; }; } // namespace Mesquite #endif