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 : : #ifdef WIN32
17 : : #ifdef _DEBUG
18 : : // turn off warnings that say they debugging identifier has been truncated
19 : : // this warning comes up when using some STL containers
20 : : #pragma warning( disable : 4786 )
21 : : #endif
22 : : #endif
23 : :
24 : : #include "ReadUtil.hpp"
25 : : #include "moab/Core.hpp"
26 : : #include "AEntityFactory.hpp"
27 : : #include "moab/Error.hpp"
28 : : #include "SequenceManager.hpp"
29 : : #include "VertexSequence.hpp"
30 : : #include "ElementSequence.hpp"
31 : :
32 : : namespace moab
33 : : {
34 : :
35 : : #define RR \
36 : : if( MB_SUCCESS != result ) return result
37 : :
38 : 340 : ReadUtil::ReadUtil( Core* mdb, Error* /*error_handler*/ ) : ReadUtilIface(), mMB( mdb ) {}
39 : :
40 : 234 : ErrorCode ReadUtil::get_node_coords( const int /*num_arrays*/, const int num_nodes, const int preferred_start_id,
41 : : EntityHandle& actual_start_handle, std::vector< double* >& arrays,
42 : : int sequence_size )
43 : : {
44 : : ErrorCode error;
45 : 234 : EntitySequence* seq = 0;
46 : :
47 [ + + ]: 234 : if( num_nodes < 1 )
48 : : {
49 : 1 : actual_start_handle = 0;
50 : 1 : arrays.clear();
51 : 1 : return MB_INDEX_OUT_OF_RANGE;
52 : : }
53 : :
54 : : // Create an entity sequence for these nodes
55 : : error = mMB->sequence_manager()->create_entity_sequence( MBVERTEX, num_nodes, 0, preferred_start_id,
56 [ + - ][ + - ]: 233 : actual_start_handle, seq, sequence_size );
57 : :
58 [ - + ]: 233 : if( error != MB_SUCCESS ) return error;
59 : :
60 [ + - ][ + - ]: 466 : if( seq->start_handle() > actual_start_handle || seq->end_handle() < actual_start_handle ||
[ + - ][ + - ]
[ - + ][ - + ]
61 [ + - ]: 233 : seq->end_handle() - actual_start_handle + 1 < (unsigned)num_nodes )
62 : 0 : return MB_FAILURE;
63 : :
64 [ + - ]: 233 : arrays.resize( 3 );
65 : :
66 [ + - ][ + - ]: 233 : error = static_cast< VertexSequence* >( seq )->get_coordinate_arrays( arrays[0], arrays[1], arrays[2] );
[ + - ][ + - ]
67 [ + + ]: 932 : for( unsigned i = 0; i < arrays.size(); ++i )
68 [ + - ][ + - ]: 699 : if( arrays[i] ) arrays[i] += ( actual_start_handle - seq->start_handle() );
[ + - ][ + - ]
69 : :
70 : 234 : return error;
71 : : }
72 : :
73 : 314 : ErrorCode ReadUtil::get_element_connect( const int num_elements, const int verts_per_element, const EntityType mdb_type,
74 : : const int preferred_start_id, EntityHandle& actual_start_handle,
75 : : EntityHandle*& array, int sequence_size )
76 : : {
77 : : ErrorCode error;
78 : : EntitySequence* seq;
79 : :
80 [ - + ]: 314 : if( num_elements < 1 )
81 : : {
82 : 0 : actual_start_handle = 0;
83 : 0 : array = 0;
84 : 0 : return MB_INDEX_OUT_OF_RANGE;
85 : : }
86 : :
87 : : // if (mdb_type <= MBVERTEX || mdb_type >= MBPOLYHEDRON || mdb_type == MBPOLYGON)
88 : : // return MB_TYPE_OUT_OF_RANGE;
89 : :
90 : : // Make an entity sequence to hold these elements
91 : : error =
92 : : mMB->sequence_manager()->create_entity_sequence( mdb_type, num_elements, verts_per_element, preferred_start_id,
93 [ + - ][ + - ]: 314 : actual_start_handle, seq, sequence_size );
94 [ - + ]: 314 : if( MB_SUCCESS != error ) return error;
95 : :
96 [ + - ][ + - ]: 628 : if( seq->start_handle() > actual_start_handle || seq->end_handle() < actual_start_handle ||
[ + - ][ + - ]
[ - + ][ - + ]
97 [ + - ]: 314 : seq->end_handle() - actual_start_handle + 1 < (unsigned)num_elements )
98 : 0 : return MB_FAILURE;
99 : :
100 : : // Get an array for the connectivity
101 [ + - ]: 314 : array = static_cast< ElementSequence* >( seq )->get_connectivity_array();
102 [ - + ]: 314 : if( !array ) return MB_FAILURE;
103 : 314 : array +=
104 [ + - ][ + - ]: 314 : ( actual_start_handle - seq->start_handle() ) * static_cast< ElementSequence* >( seq )->nodes_per_element();
105 : :
106 : 314 : return error;
107 : : }
108 : :
109 : 67 : ErrorCode ReadUtil::create_entity_sets( EntityID num_sets, const unsigned* flags, EntityID start_id,
110 : : EntityHandle& start_handle )
111 : : {
112 [ - + ]: 67 : if( num_sets < 1 )
113 : : {
114 : 0 : start_handle = 0;
115 : 0 : return MB_INDEX_OUT_OF_RANGE;
116 : : }
117 : :
118 : : ErrorCode error;
119 : : EntitySequence* seq;
120 [ + - ][ + - ]: 67 : error = mMB->sequence_manager()->create_meshset_sequence( num_sets, start_id, flags, start_handle, seq );
121 [ - + ]: 67 : if( MB_SUCCESS != error ) return error;
122 : :
123 [ + - ][ + - ]: 134 : if( seq->start_handle() > start_handle || seq->end_handle() < start_handle ||
[ + - ][ + - ]
[ - + ][ - + ]
124 [ + - ]: 67 : seq->end_handle() - start_handle + 1 < (EntityHandle)num_sets )
125 : 0 : return MB_FAILURE;
126 : :
127 : 67 : return MB_SUCCESS;
128 : : }
129 : :
130 : 304 : ErrorCode ReadUtil::update_adjacencies( const EntityHandle start_handle, const int number_elements,
131 : : const int number_vertices_per_element, const EntityHandle* conn_array )
132 : : {
133 : 304 : EntityHandle tmp_hndl = start_handle;
134 : 304 : AEntityFactory* adj_fact = mMB->a_entity_factory();
135 : :
136 : : // Iterate over the elements and update adjacency information
137 [ + - ][ + + ]: 304 : if( adj_fact != NULL && adj_fact->vert_elem_adjacencies() )
[ + + ]
138 : : {
139 : 29 : int j = 0;
140 [ + + ]: 58512 : for( int i = 0; i < number_elements; i++ )
141 : : {
142 : 58483 : adj_fact->notify_create_entity( tmp_hndl, ( conn_array + j ), number_vertices_per_element );
143 : 58483 : tmp_hndl++;
144 : 58483 : j += number_vertices_per_element;
145 : : }
146 : : }
147 : :
148 : 304 : return MB_SUCCESS;
149 : : }
150 : :
151 : 19 : ErrorCode ReadUtil::gather_related_ents( Range& partition, Range& related_ents, EntityHandle* file_set )
152 : : {
153 : : // Loop over any sets, getting contained ents
154 [ + - ]: 19 : std::pair< Range::const_iterator, Range::const_iterator > pair_it = partition.equal_range( MBENTITYSET );
155 : :
156 : 19 : ErrorCode result = MB_SUCCESS;
157 [ + - ][ + - ]: 38 : for( Range::const_iterator rit = pair_it.first; rit != pair_it.second; ++rit )
[ + + ]
158 : : {
159 [ + - ][ + - ]: 19 : ErrorCode tmp_result = mMB->get_entities_by_handle( *rit, related_ents, Interface::UNION );
160 [ - + ]: 19 : if( MB_SUCCESS != tmp_result ) result = tmp_result;
161 : : }
162 [ - + ]: 19 : RR;
163 : :
164 : : // Gather adjacent ents of other dimensions
165 [ + - ]: 19 : Range tmp_ents;
166 [ + + ]: 95 : for( int dim = 3; dim >= 0; dim-- )
167 : : {
168 [ + - ]: 76 : tmp_ents.clear();
169 [ + - ]: 76 : ErrorCode tmp_result = mMB->get_adjacencies( related_ents, dim, false, tmp_ents, Interface::UNION );
170 [ - + ]: 76 : if( MB_SUCCESS != tmp_result )
171 : 0 : result = tmp_result;
172 : : else
173 [ + - ]: 76 : related_ents.merge( tmp_ents );
174 : : }
175 [ - + ]: 19 : RR;
176 : :
177 : : // Related ents includes the partition itself
178 [ + - ]: 19 : related_ents.merge( partition );
179 : :
180 : : // Get contains-related sets
181 [ + - ][ + - ]: 38 : Range tmp_ents3, last_related;
182 [ + - ]: 19 : if( file_set )
183 [ + - ]: 19 : result = mMB->get_entities_by_type( *file_set, MBENTITYSET, tmp_ents3 );
184 : : else
185 [ # # ][ - + ]: 19 : result = mMB->get_entities_by_type( 0, MBENTITYSET, tmp_ents3 );RR;
186 : :
187 [ + - ][ + - ]: 57 : while( related_ents.size() != last_related.size() )
[ + + ]
188 : : {
189 [ + - ]: 38 : last_related = related_ents;
190 [ + - ][ + - ]: 152 : for( Range::iterator rit = tmp_ents3.begin(); rit != tmp_ents3.end(); ++rit )
[ + - ][ + - ]
[ + + ]
191 : : {
192 [ + - ][ + - ]: 114 : if( related_ents.find( *rit ) != related_ents.end() ) continue;
[ + - ][ + - ]
[ + + ]
193 : :
194 [ + - ]: 38 : tmp_ents.clear();
195 [ + - ][ + - ]: 38 : result = mMB->get_entities_by_handle( *rit, tmp_ents, true );RR;
[ - + ]
196 [ + - ]: 38 : Range tmp_ents2 = intersect( tmp_ents, related_ents );
197 : :
198 : : // If the intersection is not empty, set is related
199 [ + - ][ + - ]: 38 : if( !tmp_ents2.empty() ) related_ents.insert( *rit );
[ + - ][ + - ]
200 : 38 : }
201 : : }
202 : :
203 : : // Get child-related sets
204 [ + - ]: 19 : last_related.clear();
205 [ + - ][ + - ]: 38 : while( related_ents.size() != last_related.size() )
[ + + ]
206 : : {
207 [ + - ]: 19 : last_related = related_ents;
208 [ + - ]: 19 : std::pair< Range::const_iterator, Range::const_iterator > it_pair = last_related.equal_range( MBENTITYSET );
209 : :
210 [ + - ][ + - ]: 76 : for( Range::const_iterator rit = it_pair.first; rit != it_pair.second; ++rit )
[ + + ]
211 : : {
212 : : // Get all children and add to related ents
213 [ + - ]: 57 : tmp_ents.clear();
214 [ + - ][ + - ]: 57 : result = mMB->get_child_meshsets( *rit, tmp_ents, 0 );RR;
[ - + ]
215 [ + - ]: 57 : related_ents.merge( tmp_ents );
216 : : }
217 : : }
218 : :
219 : : // Get parent-related sets
220 [ + - ]: 19 : last_related.clear();
221 [ + - ][ + - ]: 38 : while( related_ents.size() != last_related.size() )
[ + + ]
222 : : {
223 [ + - ]: 19 : last_related = related_ents;
224 [ + - ]: 19 : std::pair< Range::const_iterator, Range::const_iterator > it_pair = last_related.equal_range( MBENTITYSET );
225 : :
226 [ + - ][ + - ]: 76 : for( Range::const_iterator rit = it_pair.first; rit != it_pair.second; ++rit )
[ + + ]
227 : : {
228 : : // Get all parents and add to related ents
229 [ + - ]: 57 : tmp_ents.clear();
230 [ + - ][ + - ]: 57 : result = mMB->get_parent_meshsets( *rit, tmp_ents, 0 );RR;
[ - + ]
231 [ + - ]: 57 : related_ents.merge( tmp_ents );
232 : : }
233 : : }
234 : :
235 : 38 : return MB_SUCCESS;
236 : : }
237 : :
238 : 0 : ErrorCode ReadUtil::get_ordered_vertices( EntityHandle* bound_ents, int* sense, int bound_size, int dim,
239 : : EntityHandle* bound_verts, EntityType& etype )
240 : : {
241 : : // Get dimension of bounding entities
242 [ # # ][ # # ]: 0 : int bound_dim = CN::Dimension( TYPE_FROM_HANDLE( bound_ents[0] ) );
243 : : int indices[MAX_SUB_ENTITY_VERTICES];
244 : 0 : const EntityHandle* connect = NULL;
245 [ # # ]: 0 : std::vector< EntityHandle > tmp_connect;
246 : :
247 : : // Find the right entity type based on # bounding ents
248 : 0 : int numv = 0, num_connect = 0;
249 : : ErrorCode result;
250 [ # # ][ # # ]: 0 : for( EntityType t = MBEDGE; t < MBENTITYSET; t++ )
251 : : {
252 [ # # ]: 0 : int nindex = CN::NumSubEntities( t, bound_dim );
253 [ # # ][ # # ]: 0 : if( CN::Dimension( t ) != dim || nindex != bound_size ) continue;
[ # # ][ # # ]
254 : :
255 : : // Fill in vertices from bounding entity vertices
256 [ # # ]: 0 : int nverts = CN::VerticesPerEntity( t );
257 [ # # ]: 0 : std::fill( bound_verts, bound_verts + nverts, 0 );
258 [ # # ]: 0 : for( int index = 0; index < nindex; index++ )
259 : : {
260 [ # # ]: 0 : result = mMB->get_connectivity( bound_ents[index], connect, num_connect, false, &tmp_connect );
261 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
262 : :
263 [ # # ]: 0 : CN::SubEntityVertexIndices( t, bound_dim, index, indices );
264 : :
265 [ # # ]: 0 : for( int c = 0; c < num_connect; c++ )
266 : : {
267 [ # # ]: 0 : if( !bound_verts[indices[c]] )
268 : : {
269 [ # # ]: 0 : bound_verts[indices[c]] = ( sense[index] > 0 ) ? connect[c] : connect[num_connect - c - 1];
270 : 0 : numv++;
271 : : }
272 : : }
273 [ # # ]: 0 : if( numv == nverts )
274 : : {
275 : 0 : etype = t;
276 : 0 : return MB_SUCCESS;
277 : : }
278 : : }
279 : : }
280 : :
281 : : // If we get here, we didn't get full connectivity
282 : 0 : etype = MBMAXTYPE;
283 : 0 : return MB_FAILURE;
284 : : }
285 : :
286 : 48 : static ErrorCode check_int_tag( Interface* mb, Tag tag )
287 : : {
288 : : int size;
289 : : DataType type;
290 [ + - ]: 48 : ErrorCode rval = mb->tag_get_bytes( tag, size );
291 [ - + ]: 48 : if( MB_SUCCESS != rval ) return rval;
292 [ - + ]: 48 : if( size != sizeof( int ) ) return MB_TYPE_OUT_OF_RANGE;
293 [ + - ]: 48 : rval = mb->tag_get_data_type( tag, type );
294 [ + - ][ - + ]: 48 : if( type != MB_TYPE_OPAQUE && type != MB_TYPE_INTEGER ) return MB_TYPE_OUT_OF_RANGE;
295 : :
296 : 48 : return MB_SUCCESS;
297 : : }
298 : :
299 : 48 : ErrorCode ReadUtil::assign_ids( Tag id_tag, const Range& ents, int start )
300 : : {
301 [ + - ]: 48 : ErrorCode rval = check_int_tag( mMB, id_tag );
302 [ - + ]: 48 : if( MB_SUCCESS != rval ) return rval;
303 : :
304 [ + - ]: 48 : Range tmp_range;
305 [ + - ]: 96 : std::vector< int > data;
306 [ + - ][ + - ]: 96 : for( Range::const_pair_iterator i = ents.pair_begin(); i != ents.pair_end(); ++i )
[ + - ][ + - ]
[ + + ]
307 : : {
308 [ + - ][ + - ]: 48 : data.resize( i->second + 1 - i->first );
[ + - ]
309 [ + - ][ + - ]: 51474 : for( std::vector< int >::iterator j = data.begin(); j != data.end(); ++j )
[ + + ]
310 [ + - ]: 51426 : *j = start++;
311 [ + - ]: 48 : tmp_range.clear();
312 [ + - ][ + - ]: 48 : tmp_range.insert( i->first, i->second );
[ + - ]
313 [ + - ][ + - ]: 48 : rval = mMB->tag_set_data( id_tag, tmp_range, &data[0] );
314 [ - + ]: 48 : if( MB_SUCCESS != rval ) return rval;
315 : : }
316 : :
317 : 96 : return MB_SUCCESS;
318 : : }
319 : :
320 : 0 : ErrorCode ReadUtil::assign_ids( Tag id_tag, const EntityHandle* ents, size_t num_ents, int start )
321 : : {
322 [ # # ]: 0 : ErrorCode rval = check_int_tag( mMB, id_tag );
323 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
324 : :
325 [ # # ]: 0 : std::vector< int > data;
326 : 0 : const EntityHandle* const end = ents + num_ents;
327 : 0 : const EntityHandle* i = ents;
328 [ # # ]: 0 : while( i != end )
329 : : {
330 [ # # ]: 0 : const EntityHandle* next = std::find( i, end, 0u );
331 : 0 : size_t size = next - i;
332 [ # # ]: 0 : if( !size )
333 : : {
334 : 0 : ++i;
335 : 0 : continue;
336 : : }
337 : :
338 : 0 : int id = start + ( i - ents );
339 [ # # ]: 0 : data.resize( size );
340 [ # # ][ # # ]: 0 : for( std::vector< int >::iterator j = data.begin(); j != data.end(); ++j )
[ # # ]
341 [ # # ]: 0 : *j = id++;
342 : :
343 [ # # ][ # # ]: 0 : rval = mMB->tag_set_data( id_tag, i, size, &data[0] );
344 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
345 : : }
346 : :
347 : 0 : return MB_SUCCESS;
348 : : }
349 : :
350 : 0 : ErrorCode ReadUtil::create_gather_set( EntityHandle& gather_set )
351 : : {
352 [ # # ]: 0 : ErrorCode rval = mMB->create_meshset( MESHSET_SET, gather_set );
353 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
354 : :
355 : : Tag gather_set_tag;
356 [ # # ]: 0 : rval = mMB->tag_get_handle( "GATHER_SET", 1, MB_TYPE_INTEGER, gather_set_tag, MB_TAG_CREAT | MB_TAG_SPARSE );
357 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
358 : :
359 : 0 : int gather_val = 1;
360 [ # # ]: 0 : rval = mMB->tag_set_data( gather_set_tag, &gather_set, 1, &gather_val );
361 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
362 : :
363 : 0 : return MB_SUCCESS;
364 : : }
365 : :
366 : 39 : ErrorCode ReadUtil::get_gather_set( EntityHandle& gather_set )
367 : : {
368 : : Tag gather_set_tag;
369 [ + - ]: 39 : ErrorCode rval = mMB->tag_get_handle( "GATHER_SET", 1, MB_TYPE_INTEGER, gather_set_tag, MB_TAG_SPARSE );
370 [ + - ]: 39 : if( MB_SUCCESS != rval ) return rval;
371 : :
372 : 0 : int gather_val = 1;
373 : 0 : void* vals[] = { &gather_val };
374 [ # # ]: 0 : Range gather_sets;
375 [ # # ]: 0 : rval = mMB->get_entities_by_type_and_tag( 0, MBENTITYSET, &gather_set_tag, vals, 1, gather_sets );
376 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
377 : :
378 [ # # ][ # # ]: 0 : if( gather_sets.empty() ) return MB_ENTITY_NOT_FOUND;
379 : :
380 [ # # ]: 0 : gather_set = gather_sets[0];
381 : :
382 : 39 : return MB_SUCCESS;
383 : : }
384 : :
385 [ + - ][ + - ]: 228 : } // namespace moab
|