Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
WriteUtilIface.hpp
Go to the documentation of this file.
1 /**
2  * MOAB, a Mesh-Oriented datABase, is a software component for creating,
3  * storing and accessing finite element mesh data.
4  *
5  * Copyright 2004 Sandia Corporation. Under the terms of Contract
6  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
7  * retains certain 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  */
15 
16 #ifndef MOAB_WRITE_UTIL_IFACE_HPP
17 #define MOAB_WRITE_UTIL_IFACE_HPP
18 
19 #include "moab/Range.hpp"
20 #include "moab/Compiler.hpp"
21 #include <vector>
22 
23 namespace moab
24 {
25 
26 //! Interface implemented in MOAB which provides memory for mesh reading utilities
28 {
29  public:
30  //! Constructor
32 
33  //! Destructor
34  virtual ~WriteUtilIface() {}
35 
36  //! Check if the specified file already exists.
37  //! Returns MB_SUCCESS if file does not exist, MB_ALREADY_ALLOCATED
38  //! if file does exist, or MB_FAILURE for some other error condition.
39  virtual ErrorCode check_doesnt_exist( const char* file_name ) = 0;
40 
41  //! Gather all entities in the mesh, or in the sets specified
43  Range& all_ents, /**< range in which entities are returned */
44  const EntityHandle* ent_sets = NULL, /**< entity sets whose contents are to be gathered */
45  int num_sets = 0 /**< number of sets in list */ ) = 0;
46 
47  //! Given information about the nodes to be written, and pointers to memory
48  //! to which coordinates will be written, writes coordinate data there, and
49  //! also assigns global ids to nodes & writes to a tag, if a tag is specified
50  //! \param num_arrays Number of coordinate arrays requested
51  //! \param num_nodes Number of nodes to be written
52  //! \param entities Range of nodes to be written
53  //! \param node_id_tag Tag used to write ids to nodes
54  //! \param start_node_id Starting value for node ids
55  //! \param arrays Pointers to memory where coordinate data will be written
56  //! \return status Return status
57  virtual ErrorCode get_node_coords( const int num_arrays,
58  const int num_nodes,
59  const Range& entities,
60  Tag node_id_tag,
61  const int start_node_id,
62  std::vector< double* >& arrays ) = 0;
63 
64  /** Get array of coordinate values for nodes
65  *
66  * Given a range of node handles, retrieve a single or multiple coordinate
67  * value(s) for each.
68  *
69  * Failure conditions:
70  * - invalid entity handles (not vertices, non-existent entity, etc.)
71  * - range is empty (<code>iter == end</code>)
72  * - <code>output_array</code> is null
73  * - insufficient space in <code>output_array</code>
74  *
75  *\param which_array The coordinate to retrieve (0-&gt;X, 1-&gt;Y, 2-&gt;Z, -1-&gt;all)
76  *\param begin The first node handle.
77  *\param end One past the last node handle.
78  *\param output_size The size of <code>output_array</code>.
79  *\param output_array The memory in which to write the node coordinates.
80  *\author Jason Kraftcheck
81  */
82  virtual ErrorCode get_node_coords( const int which_array,
84  const Range::const_iterator& end,
85  const size_t output_size,
86  double* const output_array ) = 0;
87 
88  //! Given information about elements to be written and a pointer to memory
89  //! where connectivity for those elements should be written, writes connectivity
90  //! to that memory; uses node ids stored in a tag during call to <em>get_node_coords</em>
91  //! function
92  //! \param num_elements Number of elements to be written
93  //! \param verts_per_element Number of vertices per element
94  //! \param node_id_tag Tag used to store node ids
95  //! \param entities Range of elements to be written
96  //! \param element_id_tag Tag which should be used to store element ids
97  //! \param start_element_id Starting value for element ids
98  //! \param array Pointer to memory where connectivity data will be written
99  //! \return status Return status
100  virtual ErrorCode get_element_connect( const int num_elements,
101  const int verts_per_element,
102  Tag node_id_tag,
103  const Range& entities,
104  Tag element_id_tag,
105  int start_element_id,
106  int* array,
107  bool add_sizes = false ) = 0;
108 
109  /** Get connectivity for elements
110  *
111  * Get the connectivity list for a range of elements.
112  *
113  * Failure cases:
114  * - Passed range is empty (<code>begin == end</code>).
115  * - <code>vertices_per_elem</code> is less than one
116  * - <code>element_array</code> is null.
117  * - The range contains invalid handles (non-existent entities,
118  * not an element, etc.)
119  * - Retrieving ID tag for an entity failed.
120  * - Insufficient space in passed array.
121  *
122  *\param begin The first element handle
123  *\param end One past the last element handle
124  *\param vertices_per_elem Number of vertices to retrieve for each
125  * element. If the element has more vertices, the
126  * element connectivity will be truncated. If
127  * <code>vertices_per_elem</code> is greater than the
128  * number of nodes for an element, the data will be
129  * padded with zeros.
130  *\param node_id_tag A tag with integer values.
131  *\param array_size The length of <code>element_array</code>
132  *\param element_array The memory location at which to store the
133  * connectivity list.
134  *\param add_sizes If true, writes size of connect array before connectivity in array
135  *\author Jason Kraftcheck
136  */
138  const Range::const_iterator& end,
139  const int vertices_per_elem,
140  Tag node_id_tag,
141  const size_t array_size,
142  int* const element_array,
143  bool add_sizes = false ) = 0;
144 
145  /** Get connectivity for elements
146  *
147  * Get the connectivity list for a range of elements.
148  *
149  * Failure cases:
150  * - Passed range is empty (<code>begin == end</code>).
151  * - <code>vertices_per_elem</code> is less than one
152  * - <code>element_array</code> is null.
153  * - The range contains invalid handles (non-existent entities,
154  * not an element, etc.)
155  * - Insufficient space in passed array.
156  *
157  *\param begin The first element handle
158  *\param end One past the last element handle
159  *\param vertices_per_elem Number of vertices to retrieve for each
160  * element. If the element has more vertices, the
161  * element connectivity will be truncated. If
162  * <code>vertices_per_elem</code> is greater than the
163  * number of nodes for an element, the data will be
164  * padded with zeros.
165  *\param array_size The length of <code>element_array</code>
166  *\param element_array The memory location at which to store the
167  * connectivity list.
168  *\author Jason Kraftcheck
169  */
171  const Range::const_iterator& end,
172  const int vertices_per_elem,
173  const size_t array_size,
174  EntityHandle* const element_array ) = 0;
175 
176  /** Get poly (polygon or polyhedron) connectivity size
177  *\param begin First iterator in range of poly
178  *\param end One past last in range of poly.
179  *\param connectivity_size The length of the connectivity list
180  * For the specified range of polyhedra.
181  *\author Jason Kraftcheck
182  */
184  const Range::const_iterator& end,
185  int& connectivity_size ) = 0;
186 
187  /** Get poly (polygon or polyhedron) connectivity.
188  *
189  * Connectivity is returned in two arrays. The first is
190  * an array of global IDs that is the concatenation of the
191  * connectivity for the entire range of polys. The second
192  * is the last index of the connectivity data for each poly
193  * in the global ID array.
194  *
195  * This function will add as many polys as possible to the
196  * passed arrays given the sizes of those arrays. It will
197  * then pass back position at which it stopped and the sizes
198  * of the data written to the arrays.
199  *
200  * Failure cases:
201  * - Passed range is empty (<code>begin == end</code>).
202  * - <code>element_array</code> or <code>index_array</code> is null.
203  * - The range contains invalid handles (non-existent entities,
204  * not an poly, etc.)
205  * - Retrieving ID tag for an entity failed.
206  *
207  *\param iter As input, the first element handle.
208  * As output, one past the last element handle
209  * for which data was written to the arrays.
210  *\param end The iterator at which to stop.
211  *\param node_id_tag A tag with integer values.
212  *\param element_array_len As input, length of <code>element_array</code>.
213  * As output, the number of entries written in that
214  * array.
215  *\param element_array The memory location at which to store the
216  * connectivity list.
217  *\param index_array_len As input, the length of <code>index_array</code>.
218  * As output, the number of entries written in that
219  * array.
220  *\param index_array The memory location at which to store offsets.
221  *\param index_offset Value to offset (add to) index values. As output
222  * the input value plus the amount of data
223  * written to the element array. (The value you
224  * presumably want to pass to the next call.)
225  *\author Jason Kraftcheck
226  */
228  const Range::const_iterator& end,
229  const Tag node_id_tag,
230  size_t& element_array_len,
231  int* const element_array,
232  size_t& index_array_len,
233  int* const index_array,
234  int& index_offset ) = 0;
235 
236  //! Given elements to be written, gather all the nodes which define those elements
237  //! \param elements Range of elements to be written
238  //! \param node_bit_mark_tag Bit tag to use to identify nodes
239  //! \param nodes Range of nodes gathered from elements (returned)
240  //! \return status Return status
241  virtual ErrorCode gather_nodes_from_elements( const Range& elements,
242  const Tag node_bit_mark_tag,
243  Range& nodes ) = 0;
244 
245  //! assign ids to input entities starting with start_id, written to id_tag
246  //! if id_tag is zero, assigns to GLOBAL_ID_TAG_NAME
247  //! \param elements Entities to be written
248  //! \param id_tag Tag used to store entity id
249  //! \param start_id Starting value for entity ids
250  //! \return status Return status
251  virtual ErrorCode assign_ids( Range& elements, Tag id_tag, const int start_id ) = 0;
252 
253  /** Get explicit adjacencies
254  *
255  * Get explicit adjacences stored in database.
256  * Does not create any explicit adjacencies or search for
257  * implicit ones.
258  *
259  *\param entity The entity to retrieve adjacencies for.
260  *\param id_tag The global ID tag
261  *\param adj The output list of global IDs of adjacent entities.
262  *\author Jason Kraftcheck
263  */
264  virtual ErrorCode get_adjacencies( EntityHandle entity, Tag id_tag, std::vector< int >& adj ) = 0;
265 
266  virtual ErrorCode get_adjacencies( EntityHandle entity, const EntityHandle*& adj_array, int& num_adj ) = 0;
267 
268  /**\brief Re-order outgoing element connectivity
269  *
270  * Permute the connectivity of each element such that the node
271  * order is that of the target file format rather than that of MBCN.
272  *\param order The permutation to use. Must be an array of 'node_per_elem'
273  * integers and be a permutation of the values [0..node_per_elem-1].
274  * Such that for a single element:
275  * target_conn[i] == mbcn_conn[order[i]]
276  *\param conn The connectivity array to re-order
277  *\param num_elem The number of elements in the connectivity array
278  *\param node_per_elem The number of nodes in each element's connectivity list.
279  */
280  template < typename T >
281  static inline void reorder( const int* order, T* conn, int num_elem, int node_per_elem );
282 
283  /**\brief Get list of tags to write.
284  *
285  * Get the list of tags to write to the file, possibly using
286  * an optional user-specified tag list. This function consolidates
287  * some common code for file writers to use to figure out what
288  * tag data to write to the file. It provides the following features:
289  * o filter list based on user-specified array of tag handles
290  * o filter internal tags (those for which the name is prefixed with
291  * two underscore characters)
292  * o filter anonymous tags
293  * o optionally filter variable-length tags.
294  *
295  *\author Jason Kraftcheck
296  *\param result_list List of tag handles for which to write data
297  *\param user_tag_list Optional array of tag handles passed by user
298  * to write to file.
299  *\param include_variable_length_tags If false, return only fixed-length
300  * tags.
301  */
302  virtual ErrorCode get_tag_list( std::vector< Tag >& result_list,
303  const Tag* user_tag_list = 0,
304  int user_tag_list_length = 0,
305  bool include_variable_length_tags = true ) = 0;
306 
308  {
309  CONTENTS = 0,
310  CHILDREN = 1,
311  PARENTS = 2,
312  TOPOLOGICAL = 1
313  };
314 
315  /*\brief Get pointers to internal storage of entity data
316  *
317  * Get pointers to element connectivity or set content storage.
318  *\param query_begin Start of range of entities for which to return results
319  *\param query_end End of range of entities for which to return results.
320  *\param output_pointer_array Result list of pointers. Points to either
321  * element connectivity or set contents. Note: set contents
322  * may be in range-compacted format.
323  *\param lengths Optional per-entity length of list. If passed, then
324  * always set, for each entity, to the number of values in the
325  * array passed back in \c output_pointer_array
326  *\param relation If entity is entity set, which set data to return
327  * (contents array, parent array, or child array). If
328  * entity is an element, then CONTENTS for complete connectivity
329  * or TOPOLOGICAL for only corner vertices.
330  *\param flags Optional per-entity flag values. If passed, then
331  * always set to zero for elements and set to set creation
332  * flags for entity sets.
333  *\return MB_STRUCTURED_MESH if one or more input elements are stored as
334  * structured mesh and therefore do not have explicit storage.
335  * MB_TYPE_OUT_OF_RANGE if called for vertices.
336  */
338  Range::const_iterator query_end,
339  EntityHandle const** output_pointer_array,
340  EntityListType relation = CONTENTS,
341  int* lengths = 0,
342  unsigned char* flags = 0 ) = 0;
343 
344  /*\brief Get pointers to internal storage of entity data
345  *
346  * Get pointers to element connectivity or set content storage.
347  *\param entities Pointer to list of entities for which to return results
348  *\param num_entities Number of entities in list
349  *\param output_pointer_array Result list of pointers. Points to either
350  * element connectivity or set contents. Note: set contents
351  * may be in range-compacted format.
352  *\param lengths Optional per-entity length of list. If passed, then
353  * always set, for each entity, to the number of values in the
354  * array passed back in \c output_pointer_array
355  *\param relation If entity is entity set, which set data to return
356  * (contents array, parent array, or child array). If
357  * entity is an element, then CONTENTS for complete connectivity
358  * or TOPOLOGICAL for only corner vertices.
359  *\param flags Optional per-entity flag values. If passed, then
360  * always set to zero for elements and set to set creation
361  * flags for entity sets.
362  *\return MB_STRUCTURED_MESH if one or more input elements are stored as
363  * structured mesh and therefore do not have explicit storage.
364  * MB_TYPE_OUT_OF_RANGE if called for vertices.
365  */
367  int num_entities,
368  EntityHandle const** output_pointer_array,
369  EntityListType relation = CONTENTS,
370  int* lengths = 0,
371  unsigned char* flags = 0 ) = 0;
372 };
373 
374 template < typename T >
375 inline void WriteUtilIface::reorder( const int* order, T* conn, int num_elem, int node_per_elem )
376 {
377  std::vector< T > elem( node_per_elem );
378  T* const end = conn + num_elem * node_per_elem;
379  while( conn != end )
380  {
381  std::copy( conn, conn + node_per_elem, elem.begin() );
382  for( int j = 0; j < node_per_elem; ++j, ++conn )
383  *conn = elem[order[j]];
384  }
385 }
386 
387 } // namespace moab
388 
389 #endif