Branch data Line data Source code
1 : : #include <iostream>
2 : : #include <fstream>
3 : : #include <vector>
4 : : #include <cstdlib>
5 : : #include <sstream>
6 : : #include "assert.h"
7 : :
8 : : #include "ReadIDEAS.hpp"
9 : : #include "moab/Interface.hpp"
10 : : #include "Internals.hpp"
11 : : #include "moab/ReadUtilIface.hpp"
12 : : #include "FileTokenizer.hpp"
13 : : #include "MBTagConventions.hpp"
14 : : #include "moab/Range.hpp"
15 : : #include "moab/CN.hpp"
16 : :
17 : : namespace moab
18 : : {
19 : :
20 : 1 : ReaderIface* ReadIDEAS::factory( Interface* iface )
21 : : {
22 [ + - ]: 1 : return new ReadIDEAS( iface );
23 : : }
24 : :
25 [ + - ][ + - ]: 2 : ReadIDEAS::ReadIDEAS( Interface* impl ) : MBI( impl )
26 : : {
27 [ + - ]: 1 : impl->query_interface( readMeshIface );
28 : 1 : }
29 : :
30 : 0 : ErrorCode ReadIDEAS::read_tag_values( const char* /* file_name */, const char* /* tag_name */,
31 : : const FileOptions& /* opts */, std::vector< int >& /* tag_values_out */,
32 : : const SubsetList* /* subset_list */ )
33 : : {
34 : 0 : return MB_NOT_IMPLEMENTED;
35 : : }
36 : :
37 : 1 : ErrorCode ReadIDEAS::load_file( const char* fname, const EntityHandle*, const FileOptions& /*options*/,
38 : : const ReaderIface::SubsetList* subset_list, const Tag* file_id_tag )
39 : : {
40 [ - + ][ # # ]: 1 : if( subset_list ) { MB_SET_ERR( MB_UNSUPPORTED_OPERATION, "Reading subset of files not supported for IDEAS" ); }
[ # # ][ # # ]
[ # # ][ # # ]
41 : :
42 [ + - ]: 1 : file.open( fname );
43 [ + - ][ - + ]: 1 : if( !file.good() ) { MB_SET_ERR( MB_FILE_DOES_NOT_EXIST, "Failed to open file: " << fname ); }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
44 : :
45 : : ErrorCode rval;
46 : :
47 : : char line[10000];
48 [ + - ]: 1 : file.getline( line, 10000 );
49 : 1 : char* liter = line;
50 [ + - ][ - + ]: 1 : while( *liter && isspace( *liter ) )
51 : 0 : ++liter;
52 [ + - ]: 1 : if( *liter != '-' ) return MB_FAILURE;
53 : 0 : ++liter;
54 [ # # ]: 0 : if( *liter != '1' ) return MB_FAILURE;
55 [ # # ]: 0 : while( *++liter )
56 [ # # ]: 0 : if( !isspace( *liter ) ) return MB_FAILURE;
57 : :
58 : 0 : EntityHandle first_vertex = 0;
59 [ # # ][ # # ]: 0 : while( !file.eof() )
60 : : {
61 [ # # ]: 0 : file.getline( line, 10000 );
62 : 0 : unsigned int header_id = (unsigned int)strtol( line, NULL, 10 );
63 : :
64 : : // Create vertices
65 [ # # ][ # # ]: 0 : if( DOUBLE_PRECISION_NODES0 == header_id || DOUBLE_PRECISION_NODES1 == header_id )
66 : : {
67 [ # # ]: 0 : if( first_vertex ) // multiple vertex blocks?
68 : 0 : return MB_FAILURE;
69 [ # # ][ # # ]: 0 : rval = create_vertices( first_vertex, file_id_tag );MB_CHK_SET_ERR( rval, "Failed to read vertices" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
70 : : }
71 : : // Create elements
72 [ # # ][ # # ]: 0 : else if( ELEMENTS0 == header_id || ELEMENTS1 == header_id || ELEMENTS2 == header_id )
[ # # ]
73 : : {
74 [ # # ]: 0 : if( !first_vertex ) // Need to read vertices first
75 : 0 : return MB_FAILURE;
76 [ # # ][ # # ]: 0 : rval = create_elements( first_vertex, file_id_tag );MB_CHK_SET_ERR( rval, "Failed to read elements" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
77 : : }
78 : : // Skip everything else
79 : : else
80 : : {
81 [ # # ]: 0 : rval = skip_header();
82 [ # # ]: 0 : if( MB_SUCCESS != rval ) return MB_FAILURE;
83 : : }
84 : : }
85 : :
86 [ # # ]: 0 : file.close();
87 : 1 : return MB_SUCCESS;
88 : : }
89 : :
90 : 0 : ErrorCode ReadIDEAS::skip_header()
91 : : {
92 : : // Go until finding a pair of -1 lines
93 : : char* ctmp;
94 : : char line[10000];
95 [ # # ]: 0 : std::string s;
96 : :
97 : 0 : int end_of_block = 0;
98 : :
99 : : long int il;
100 : :
101 [ # # ][ # # ]: 0 : while( file.getline( line, 10000 ) )
[ # # ]
102 : : {
103 : 0 : il = std::strtol( line, &ctmp, 10 );
104 [ # # ]: 0 : if( il == -1 )
105 : : {
106 [ # # ]: 0 : s = ctmp;
107 [ # # ]: 0 : if( s.empty() ) end_of_block++;
108 : : }
109 : : else
110 : 0 : end_of_block = 0;
111 : :
112 [ # # ]: 0 : if( end_of_block >= 2 ) return MB_SUCCESS;
113 : : }
114 : :
115 : 0 : return MB_SUCCESS;
116 : : }
117 : :
118 : 0 : ErrorCode ReadIDEAS::create_vertices( EntityHandle& first_vertex, const Tag* file_id_tag )
119 : : {
120 : : // Read two lines: first has some data, second has coordinates
121 : : char line1[10000], line2[10000];
122 : : int il1, il2;
123 : : char *ctmp1, *ctmp2;
124 [ # # ][ # # ]: 0 : std::string s1, s2;
125 : :
126 : : ErrorCode rval;
127 : :
128 [ # # ]: 0 : std::streampos top_of_block = file.tellg();
129 : 0 : unsigned int num_verts = 0;
130 : :
131 : : for( ;; )
132 : : {
133 : : // Read both lines
134 [ # # ][ # # ]: 0 : if( !file.getline( line1, 10000 ) ) return MB_FAILURE;
[ # # ]
135 [ # # ][ # # ]: 0 : if( !file.getline( line2, 10000 ) ) return MB_FAILURE;
[ # # ]
136 : :
137 : : // Check if we are at the end of the block
138 : 0 : il1 = std::strtol( line1, &ctmp1, 10 );
139 : 0 : il2 = std::strtol( line2, &ctmp2, 10 );
140 [ # # ][ # # ]: 0 : if( ( il1 == -1 ) && ( il2 == -1 ) )
141 : : {
142 [ # # ]: 0 : s1 = ctmp1;
143 [ # # ]: 0 : s2 = ctmp2;
144 [ # # ][ # # ]: 0 : if( ( s1.empty() ) && ( s2.empty() ) ) break;
[ # # ]
145 : : }
146 : 0 : num_verts++;
147 : : }
148 : :
149 [ # # ]: 0 : file.seekg( top_of_block );
150 : :
151 [ # # ]: 0 : std::vector< double* > arrays;
152 [ # # ]: 0 : rval = readMeshIface->get_node_coords( 3, num_verts, 0, first_vertex, arrays );
153 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
154 : :
155 [ # # ]: 0 : Range verts;
156 [ # # ]: 0 : verts.insert( first_vertex, first_vertex + num_verts - 1 );
157 : :
158 [ # # ]: 0 : double* x = arrays[0];
159 [ # # ]: 0 : double* y = arrays[1];
160 [ # # ]: 0 : double* z = arrays[2];
161 : :
162 : : // For now, assume ids are sequential and begin with 1
163 [ # # ]: 0 : Tag id_tag = MBI->globalId_tag();
164 : 0 : const int beginning_node_id = 1;
165 : 0 : int node_id = beginning_node_id;
166 : :
167 [ # # ]: 0 : for( unsigned int i = 0; i < num_verts; i++ )
168 : : {
169 [ # # ][ # # ]: 0 : if( !file.getline( line1, 10000 ) ) return MB_FAILURE;
[ # # ]
170 [ # # ][ # # ]: 0 : if( !file.getline( line2, 10000 ) ) return MB_FAILURE;
[ # # ]
171 : :
172 : : // Get the id out of the 1st line. Check the assumption that node ids are
173 : : // sequential and begin with 1.
174 [ # # ]: 0 : if( node_id != std::strtol( line1, &ctmp1, 10 ) )
175 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "node_id " << node_id << " line2:" << line2 << " ctmp1:" << ctmp1 );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
176 : : else
177 : 0 : ++node_id;
178 : :
179 : : // Get the doubles out of the 2nd line
180 : 0 : x[i] = std::strtod( line2, &ctmp2 );
181 : 0 : y[i] = std::strtod( ctmp2 + 1, &ctmp2 );
182 : 0 : z[i] = std::strtod( ctmp2 + 1, NULL );
183 : : }
184 : :
185 [ # # ][ # # ]: 0 : if( !file.getline( line1, 10000 ) ) MB_SET_ERR( MB_FAILURE, " expect more lines" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
186 [ # # ][ # # ]: 0 : if( !file.getline( line2, 10000 ) ) MB_SET_ERR( MB_FAILURE, " expect more lines 2" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
187 : :
188 : : // Tag the nodes with ids
189 [ # # ][ # # ]: 0 : rval = readMeshIface->assign_ids( id_tag, verts, beginning_node_id );MB_CHK_SET_ERR( rval, "Failed to assign IDs" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
190 [ # # ]: 0 : if( file_id_tag )
191 : : {
192 [ # # ][ # # ]: 0 : rval = readMeshIface->assign_ids( *file_id_tag, verts, beginning_node_id );MB_CHK_SET_ERR( rval, "Failed to assign file IDs" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
193 : : }
194 : :
195 : 0 : return MB_SUCCESS;
196 : : }
197 : :
198 : 0 : ErrorCode ReadIDEAS::create_elements( EntityHandle vstart, const Tag* file_id_tag )
199 : : {
200 : : char line1[10000], line2[10000];
201 : : int il1, il2;
202 : : char *ctmp1, *ctmp2;
203 [ # # ][ # # ]: 0 : std::string s1, s2;
204 : : ErrorCode rval;
205 : : EntityHandle handle;
206 : :
207 : : Tag mat_tag, phys_tag, id_tag;
208 [ # # ]: 0 : rval = MBI->tag_get_handle( MAT_PROP_TABLE_TAG, 1, MB_TYPE_INTEGER, mat_tag, MB_TAG_DENSE | MB_TAG_CREAT );
209 [ # # ][ # # ]: 0 : if( MB_SUCCESS != rval && MB_ALREADY_ALLOCATED != rval ) return rval;
210 [ # # ]: 0 : rval = MBI->tag_get_handle( PHYS_PROP_TABLE_TAG, 1, MB_TYPE_INTEGER, phys_tag, MB_TAG_DENSE | MB_TAG_CREAT );
211 [ # # ][ # # ]: 0 : if( MB_SUCCESS != rval && MB_ALREADY_ALLOCATED != rval ) return rval;
212 [ # # ]: 0 : id_tag = MBI->globalId_tag();
213 : :
214 : : for( ;; )
215 : : {
216 [ # # ][ # # ]: 0 : if( !file.getline( line1, 10000 ) || !file.getline( line2, 10000 ) ) return MB_FAILURE;
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
217 : :
218 : : // Check if we are at the end of the block
219 : 0 : il1 = std::strtol( line1, &ctmp1, 10 );
220 : 0 : il2 = std::strtol( line2, &ctmp2, 10 );
221 [ # # ][ # # ]: 0 : if( ( il1 == -1 ) && ( il2 == -1 ) )
222 : : {
223 [ # # ]: 0 : s1 = ctmp1;
224 [ # # ]: 0 : s2 = ctmp2;
225 [ # # ][ # # ]: 0 : if( ( s1.empty() ) && ( s2.empty() ) ) return MB_SUCCESS;
[ # # ]
226 : : }
227 : :
228 : : // The first line describes attributes of the element other than connectivity.
229 : 0 : const int element_id = strtol( line1 + 1, &ctmp1, 10 );
230 : 0 : const int ideas_type = strtol( line1 + 11, &ctmp1, 10 );
231 : 0 : const int phys_table = strtol( line1 + 21, &ctmp1, 10 );
232 : 0 : const int mat_table = strtol( line1 + 31, &ctmp1, 10 );
233 : :
234 : : // Determine the element type.
235 : : EntityType mb_type;
236 [ # # ][ # # ]: 0 : if( TRI0 == ideas_type || TRI1 == ideas_type )
237 : 0 : mb_type = MBTRI;
238 [ # # ][ # # ]: 0 : else if( QUAD0 == ideas_type || QUAD1 == ideas_type )
239 : 0 : mb_type = MBQUAD;
240 [ # # ]: 0 : else if( TET == ideas_type )
241 : 0 : mb_type = MBTET;
242 [ # # ]: 0 : else if( HEX == ideas_type )
243 : 0 : mb_type = MBHEX;
244 [ # # ]: 0 : else if( WEDGE == ideas_type )
245 : 0 : mb_type = MBPRISM;
246 : : else
247 : : {
248 [ # # ][ # # ]: 0 : std::cout << "IDEAS element type not yet added to MOAB reader." << std::endl;
249 : 0 : return MB_NOT_IMPLEMENTED;
250 : : }
251 : :
252 : : // Get the connectivity out of the 2nd line
253 [ # # ][ # # ]: 0 : std::stringstream ss( line2 );
[ # # ]
254 [ # # ]: 0 : const int n_conn = CN::VerticesPerEntity( mb_type );
255 : : EntityHandle conn[CN::MAX_NODES_PER_ELEMENT];
256 : : EntityHandle vert;
257 [ # # ]: 0 : for( int i = 0; i < n_conn; ++i )
258 : : {
259 [ # # ]: 0 : ss >> vert;
260 : 0 : conn[i] = vstart + vert - 1;
261 : : }
262 : :
263 : : // Make the element. According to the Gmsh 2.2.3 source code, the IDEAS
264 : : // canonical numbering is the same as MBCN.
265 [ # # ][ # # ]: 0 : rval = MBI->create_element( mb_type, conn, n_conn, handle );MB_CHK_SET_ERR( rval, "can't create elements of type " << mb_type );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
266 : :
267 : : // If the phys set does not already exist, create it.
268 [ # # ][ # # ]: 0 : Range phys_sets;
269 : : EntityHandle phys_set;
270 : 0 : const void* const phys_set_id_val[] = { &phys_table };
271 [ # # ][ # # ]: 0 : rval = MBI->get_entities_by_type_and_tag( 0, MBENTITYSET, &phys_tag, phys_set_id_val, 1, phys_sets );MB_CHK_SET_ERR( rval, "can't get phys sets" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
272 [ # # ][ # # ]: 0 : if( phys_sets.empty() )
273 : : {
274 [ # # ][ # # ]: 0 : rval = MBI->create_meshset( MESHSET_SET, phys_set );MB_CHK_SET_ERR( rval, "can't create phys set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
275 [ # # ][ # # ]: 0 : rval = MBI->tag_set_data( phys_tag, &phys_set, 1, &phys_table );MB_CHK_SET_ERR( rval, "can't set tag to phys set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
276 : : }
277 [ # # ][ # # ]: 0 : else if( 1 == phys_sets.size() )
278 : : {
279 [ # # ]: 0 : phys_set = phys_sets.front();
280 : : }
281 : : else
282 : : {
283 : 0 : return MB_MULTIPLE_ENTITIES_FOUND;
284 : : }
285 [ # # ][ # # ]: 0 : rval = MBI->add_entities( phys_set, &handle, 1 );MB_CHK_SET_ERR( rval, "can't add entities to phys set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
286 : :
287 : : // If the material set does not already exist, create it.
288 [ # # ][ # # ]: 0 : Range mat_sets;
289 : : EntityHandle mat_set;
290 : 0 : const void* const mat_set_id_val[] = { &mat_table };
291 [ # # ]: 0 : rval = MBI->get_entities_by_type_and_tag( 0, MBENTITYSET, &mat_tag, mat_set_id_val, 1, mat_sets );
292 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
293 [ # # ][ # # ]: 0 : if( mat_sets.empty() )
294 : : {
295 [ # # ]: 0 : rval = MBI->create_meshset( MESHSET_SET, mat_set );
296 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
297 [ # # ]: 0 : rval = MBI->tag_set_data( mat_tag, &mat_set, 1, &mat_table );
298 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
299 : : }
300 [ # # ][ # # ]: 0 : else if( 1 == mat_sets.size() )
301 : : {
302 [ # # ]: 0 : mat_set = mat_sets.front();
303 : : }
304 : : else
305 : : {
306 : 0 : return MB_MULTIPLE_ENTITIES_FOUND;
307 : : }
308 [ # # ]: 0 : rval = MBI->add_entities( mat_set, &handle, 1 );
309 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
310 : :
311 : : // Tag the element with its id
312 [ # # ][ # # ]: 0 : rval = MBI->tag_set_data( id_tag, &handle, 1, &element_id );MB_CHK_SET_ERR( rval, "Failed to assign IDs" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
313 [ # # ]: 0 : if( file_id_tag )
314 : : {
315 [ # # ][ # # ]: 0 : rval = MBI->tag_set_data( *file_id_tag, &handle, 1, &element_id );MB_CHK_SET_ERR( rval, "Failed to assign file IDs" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
316 : : }
317 : 0 : }
318 : :
319 : 0 : return MB_SUCCESS;
320 : : }
321 : :
322 [ + - ][ + - ]: 228 : } // namespace moab
|