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