MOAB: Mesh Oriented datABase  (version 5.2.1)
WriteUtilIface.hpp
Go to the documentation of this file.
00001 /**
00002  * MOAB, a Mesh-Oriented datABase, is a software component for creating,
00003  * storing and accessing finite element mesh data.
00004  *
00005  * Copyright 2004 Sandia Corporation.  Under the terms of Contract
00006  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
00007  * retains certain rights in 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  */
00015 
00016 #ifndef MOAB_WRITE_UTIL_IFACE_HPP
00017 #define MOAB_WRITE_UTIL_IFACE_HPP
00018 
00019 #include "moab/Range.hpp"
00020 #include "moab/Compiler.hpp"
00021 #include <vector>
00022 
00023 namespace moab
00024 {
00025 
00026 //! Interface implemented in MOAB which provides memory for mesh reading utilities
00027 class WriteUtilIface
00028 {
00029   public:
00030     //! Constructor
00031     WriteUtilIface() {}
00032 
00033     //! Destructor
00034     virtual ~WriteUtilIface() {}
00035 
00036     //! Check if the specified file already exists.
00037     //! Returns MB_SUCCESS if file does not exist, MB_ALREADY_ALLOCATED
00038     //! if file does exist, or MB_FAILURE for some other error condition.
00039     virtual ErrorCode check_doesnt_exist( const char* file_name ) = 0;
00040 
00041     //! Gather all entities in the mesh, or in the sets specified
00042     virtual ErrorCode gather_entities(
00043         Range& all_ents,                     /**< range in which entities are returned */
00044         const EntityHandle* ent_sets = NULL, /**< entity sets whose contents are to be gathered */
00045         int num_sets                 = 0 /**< number of sets in list */ ) = 0;
00046 
00047     //! Given information about the nodes to be written, and pointers to memory
00048     //! to which coordinates will be written, writes coordinate data there, and
00049     //! also assigns global ids to nodes & writes to a tag, if a tag is specified
00050     //! \param num_arrays Number of coordinate arrays requested
00051     //! \param num_nodes Number of nodes to be written
00052     //! \param entities Range of nodes to be written
00053     //! \param node_id_tag Tag used to write ids to nodes
00054     //! \param start_node_id Starting value for node ids
00055     //! \param arrays Pointers to memory where coordinate data will be written
00056     //! \return status Return status
00057     virtual ErrorCode get_node_coords( const int num_arrays, const int num_nodes, const Range& entities,
00058                                        Tag node_id_tag, const int start_node_id, std::vector< double* >& arrays ) = 0;
00059 
00060     /** Get array of coordinate values for nodes
00061      *
00062      * Given a range of node handles, retrieve a single or multiple coordinate
00063      * value(s) for each.
00064      *
00065      * Failure conditions:
00066      *  - invalid entity handles (not vertices, non-existent entity, etc.)
00067      *  - range is empty (<code>iter == end</code>)
00068      *  - <code>output_array</code> is null
00069      *  - insufficient space in <code>output_array</code>
00070      *
00071      *\param which_array  The coordinate to retrieve (0-&gt;X, 1-&gt;Y, 2-&gt;Z, -1-&gt;all)
00072      *\param begin        The first node handle.
00073      *\param end          One past the last node handle.
00074      *\param output_size  The size of <code>output_array</code>.
00075      *\param output_array The memory in which to write the node coordinates.
00076      *\author Jason Kraftcheck
00077      */
00078     virtual ErrorCode get_node_coords( const int which_array, Range::const_iterator begin,
00079                                        const Range::const_iterator& end, const size_t output_size,
00080                                        double* const output_array ) = 0;
00081 
00082     //! Given information about elements to be written and a pointer to memory
00083     //! where connectivity for those elements should be written, writes connectivity
00084     //! to that memory; uses node ids stored in a tag during call to <em>get_node_coords</em>
00085     //! function
00086     //! \param num_elements Number of elements to be written
00087     //! \param verts_per_element Number of vertices per element
00088     //! \param node_id_tag Tag used to store node ids
00089     //! \param entities Range of elements to be written
00090     //! \param element_id_tag Tag which should be used to store element ids
00091     //! \param start_element_id Starting value for element ids
00092     //! \param array Pointer to memory where connectivity data will be written
00093     //! \return status Return status
00094     virtual ErrorCode get_element_connect( const int num_elements, const int verts_per_element, Tag node_id_tag,
00095                                            const Range& entities, Tag element_id_tag, int start_element_id, int* array,
00096                                            bool add_sizes = false ) = 0;
00097 
00098     /** Get connectivity for elements
00099      *
00100      * Get the connectivity list for a range of elements.
00101      *
00102      * Failure cases:
00103      *  - Passed range is empty (<code>begin == end</code>).
00104      *  - <code>vertices_per_elem</code> is less than one
00105      *  - <code>element_array</code> is null.
00106      *  - The range contains invalid handles (non-existent entities,
00107      *      not an element, etc.)
00108      *  - Retrieving ID tag for an entity failed.
00109      *  - Insufficient space in passed array.
00110      *
00111      *\param begin        The first element handle
00112      *\param end          One past the last element handle
00113      *\param vertices_per_elem Number of vertices to retrieve for each
00114      *                    element. If the element has more vertices, the
00115      *                    element connectivity will be truncated. If
00116      *                    <code>vertices_per_elem</code> is greater than the
00117      *                    number of nodes for an element, the data will be
00118      *                    padded with zeros.
00119      *\param node_id_tag  A tag with integer values.
00120      *\param array_size   The length of <code>element_array</code>
00121      *\param element_array The memory location at which to store the
00122      *                    connectivity list.
00123      *\param add_sizes If true, writes size of connect array before connectivity in array
00124      *\author Jason Kraftcheck
00125      */
00126     virtual ErrorCode get_element_connect( Range::const_iterator begin, const Range::const_iterator& end,
00127                                            const int vertices_per_elem, Tag node_id_tag, const size_t array_size,
00128                                            int* const element_array, bool add_sizes = false ) = 0;
00129 
00130     /** Get connectivity for elements
00131      *
00132      * Get the connectivity list for a range of elements.
00133      *
00134      * Failure cases:
00135      *  - Passed range is empty (<code>begin == end</code>).
00136      *  - <code>vertices_per_elem</code> is less than one
00137      *  - <code>element_array</code> is null.
00138      *  - The range contains invalid handles (non-existent entities,
00139      *      not an element, etc.)
00140      *  - Insufficient space in passed array.
00141      *
00142      *\param begin        The first element handle
00143      *\param end          One past the last element handle
00144      *\param vertices_per_elem Number of vertices to retrieve for each
00145      *                    element. If the element has more vertices, the
00146      *                    element connectivity will be truncated. If
00147      *                    <code>vertices_per_elem</code> is greater than the
00148      *                    number of nodes for an element, the data will be
00149      *                    padded with zeros.
00150      *\param array_size   The length of <code>element_array</code>
00151      *\param element_array The memory location at which to store the
00152      *                    connectivity list.
00153      *\author Jason Kraftcheck
00154      */
00155     virtual ErrorCode get_element_connect( Range::const_iterator begin, const Range::const_iterator& end,
00156                                            const int vertices_per_elem, const size_t array_size,
00157                                            EntityHandle* const element_array ) = 0;
00158 
00159     /** Get poly (polygon or polyhedron) connectivity size
00160      *\param begin  First iterator in range of poly
00161      *\param end    One past last in range of poly.
00162      *\param connectivity_size  The length of the connectivity list
00163      *              For the specified range of polyhedra.
00164      *\author Jason Kraftcheck
00165      */
00166     virtual ErrorCode get_poly_connect_size( Range::const_iterator begin, const Range::const_iterator& end,
00167                                              int& connectivity_size ) = 0;
00168 
00169     /** Get poly (polygon or polyhedron) connectivity.
00170      *
00171      * Connectivity is returned in two arrays. The first is
00172      * an array of global IDs that is the concatenation of the
00173      * connectivity for the entire range of polys. The second
00174      * is the last index of the connectivity data for each poly
00175      * in the global ID array.
00176      *
00177      * This function will add as many polys as possible to the
00178      * passed arrays given the sizes of those arrays. It will
00179      * then pass back position at which it stopped and the sizes
00180      * of the data written to the arrays.
00181      *
00182      * Failure cases:
00183      *  - Passed range is empty (<code>begin == end</code>).
00184      *  - <code>element_array</code> or <code>index_array</code> is null.
00185      *  - The range contains invalid handles (non-existent entities,
00186      *      not an poly, etc.)
00187      *  - Retrieving ID tag for an entity failed.
00188      *
00189      *\param iter               As input, the first element handle.
00190      *                          As output, one past the last element handle
00191      *                          for which data was written to the arrays.
00192      *\param end                The iterator at which to stop.
00193      *\param node_id_tag        A tag with integer values.
00194      *\param element_array_len  As input, length of <code>element_array</code>.
00195      *                          As output, the number of entries written in that
00196      *                          array.
00197      *\param element_array      The memory location at which to store the
00198      *                          connectivity list.
00199      *\param index_array_len    As input, the length of <code>index_array</code>.
00200      *                          As output, the number of entries written in that
00201      *                          array.
00202      *\param index_array        The memory location at which to store offsets.
00203      *\param index_offset       Value to offset (add to) index values. As output
00204      *                          the input value plus the amount of data
00205      *                          written to the element array. (The value you
00206      *                          presumably want to pass to the next call.)
00207      *\author Jason Kraftcheck
00208      */
00209     virtual ErrorCode get_poly_connect( Range::const_iterator& iter, const Range::const_iterator& end,
00210                                         const Tag node_id_tag, size_t& element_array_len, int* const element_array,
00211                                         size_t& index_array_len, int* const index_array, int& index_offset ) = 0;
00212 
00213     //! Given elements to be written, gather all the nodes which define those elements
00214     //! \param elements Range of elements to be written
00215     //! \param node_bit_mark_tag Bit tag to use to identify nodes
00216     //! \param nodes Range of nodes gathered from elements (returned)
00217     //! \return status Return status
00218     virtual ErrorCode gather_nodes_from_elements( const Range& elements, const Tag node_bit_mark_tag,
00219                                                   Range& nodes ) = 0;
00220 
00221     //! assign ids to input entities starting with start_id, written to id_tag
00222     //! if id_tag is zero, assigns to GLOBAL_ID_TAG_NAME
00223     //! \param elements Entities to be written
00224     //! \param id_tag Tag used to store entity id
00225     //! \param start_id Starting value for entity ids
00226     //! \return status Return status
00227     virtual ErrorCode assign_ids( Range& elements, Tag id_tag, const int start_id ) = 0;
00228 
00229     /** Get explicit adjacencies
00230      *
00231      * Get explicit adjacences stored in database.
00232      * Does not create any explicit adjacencies or search for
00233      * implicit ones.
00234      *
00235      *\param entity  The entity to retrieve adjacencies for.
00236      *\param id_tag  The global ID tag
00237      *\param adj     The output list of global IDs of adjacent entities.
00238      *\author Jason Kraftcheck
00239      */
00240     virtual ErrorCode get_adjacencies( EntityHandle entity, Tag id_tag, std::vector< int >& adj ) = 0;
00241 
00242     virtual ErrorCode get_adjacencies( EntityHandle entity, const EntityHandle*& adj_array, int& num_adj ) = 0;
00243 
00244     /**\brief Re-order outgoing element connectivity
00245      *
00246      * Permute the connectivity of each element such that the node
00247      * order is that of the target file format rather than that of MBCN.
00248      *\param order The permutation to use. Must be an array of 'node_per_elem'
00249      *             integers and be a permutation of the values [0..node_per_elem-1].
00250      *             Such that for a single element:
00251      *             target_conn[i] == mbcn_conn[order[i]]
00252      *\param conn  The connectivity array to re-order
00253      *\param num_elem  The number of elements in the connectivity array
00254      *\param node_per_elem The number of nodes in each element's connectivity list.
00255      */
00256     template < typename T >
00257     static inline void reorder( const int* order, T* conn, int num_elem, int node_per_elem );
00258 
00259     /**\brief Get list of tags to write.
00260      *
00261      * Get the list of tags to write to the file, possibly using
00262      * an optional user-specified tag list. This function consolidates
00263      * some common code for file writers to use to figure out what
00264      * tag data to write to the file. It provides the following features:
00265      *  o filter list based on user-specified array of tag handles
00266      *  o filter internal tags (those for which the name is prefixed with
00267      *    two underscore characters)
00268      *  o filter anonymous tags
00269      *  o optionally filter variable-length tags.
00270      *
00271      *\author Jason Kraftcheck
00272      *\param result_list List of tag handles for which to write data
00273      *\param user_tag_list Optional array of tag handles passed by user
00274      *                     to write to file.
00275      *\param include_variable_length_tags If false, return only fixed-length
00276      *                                    tags.
00277      */
00278     virtual ErrorCode get_tag_list( std::vector< Tag >& result_list, const Tag* user_tag_list = 0,
00279                                     int user_tag_list_length = 0, bool include_variable_length_tags = true ) = 0;
00280 
00281     enum EntityListType
00282     {
00283         CONTENTS    = 0,
00284         CHILDREN    = 1,
00285         PARENTS     = 2,
00286         TOPOLOGICAL = 1
00287     };
00288 
00289     /*\brief Get pointers to internal storage of entity data
00290      *
00291      * Get pointers to element connectivity or set content storage.
00292      *\param query_begin Start of range of entities for which to return results
00293      *\param query_end   End of range of entities for which to return results.
00294      *\param output_pointer_array Result list of pointers. Points to either
00295      *          element connectivity or set contents. Note: set contents
00296      *          may be in range-compacted format.
00297      *\param lengths Optional per-entity length of list. If passed, then
00298      *          always set, for each entity, to the number of values in the
00299      *          array passed back in \c output_pointer_array
00300      *\param relation If entity is entity set, which set data to return
00301      *          (contents array, parent array, or child array). If
00302      *          entity is an element, then CONTENTS for complete connectivity
00303      *          or TOPOLOGICAL for only corner vertices.
00304      *\param flags Optional per-entity flag values. If passed, then
00305      *          always set to zero for elements and set to set creation
00306      *          flags for entity sets.
00307      *\return MB_STRUCTURED_MESH if one or more input elements are stored as
00308      *          structured mesh and therefore do not have explicit storage.
00309      *        MB_TYPE_OUT_OF_RANGE if called for vertices.
00310      */
00311     virtual ErrorCode get_entity_list_pointers( Range::const_iterator query_begin, Range::const_iterator query_end,
00312                                                 EntityHandle const** output_pointer_array,
00313                                                 EntityListType relation = CONTENTS, int* lengths = 0,
00314                                                 unsigned char* flags = 0 ) = 0;
00315 
00316     /*\brief Get pointers to internal storage of entity data
00317      *
00318      * Get pointers to element connectivity or set content storage.
00319      *\param entities Pointer to list of entities for which to return results
00320      *\param num_entities Number of entities in list
00321      *\param output_pointer_array Result list of pointers. Points to either
00322      *          element connectivity or set contents. Note: set contents
00323      *          may be in range-compacted format.
00324      *\param lengths Optional per-entity length of list. If passed, then
00325      *          always set, for each entity, to the number of values in the
00326      *          array passed back in \c output_pointer_array
00327      *\param relation If entity is entity set, which set data to return
00328      *          (contents array, parent array, or child array). If
00329      *          entity is an element, then CONTENTS for complete connectivity
00330      *          or TOPOLOGICAL for only corner vertices.
00331      *\param flags Optional per-entity flag values. If passed, then
00332      *          always set to zero for elements and set to set creation
00333      *          flags for entity sets.
00334      *\return MB_STRUCTURED_MESH if one or more input elements are stored as
00335      *          structured mesh and therefore do not have explicit storage.
00336      *        MB_TYPE_OUT_OF_RANGE if called for vertices.
00337      */
00338     virtual ErrorCode get_entity_list_pointers( EntityHandle const* entities, int num_entities,
00339                                                 EntityHandle const** output_pointer_array,
00340                                                 EntityListType relation = CONTENTS, int* lengths = 0,
00341                                                 unsigned char* flags = 0 ) = 0;
00342 };
00343 
00344 template < typename T >
00345 inline void WriteUtilIface::reorder( const int* order, T* conn, int num_elem, int node_per_elem )
00346 {
00347     std::vector< T > elem( node_per_elem );
00348     T* const end = conn + num_elem * node_per_elem;
00349     while( conn != end )
00350     {
00351         std::copy( conn, conn + node_per_elem, elem.begin() );
00352         for( int j = 0; j < node_per_elem; ++j, ++conn )
00353             *conn = elem[order[j]];
00354     }
00355 }
00356 
00357 }  // namespace moab
00358 
00359 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines