moab
|
00001 #include <iostream> 00002 #include <fstream> 00003 #include <vector> 00004 #include <cstdlib> 00005 #include <sstream> 00006 #include "assert.h" 00007 00008 #include "ReadIDEAS.hpp" 00009 #include "moab/Interface.hpp" 00010 #include "Internals.hpp" 00011 #include "moab/ReadUtilIface.hpp" 00012 #include "FileTokenizer.hpp" 00013 #include "MBTagConventions.hpp" 00014 #include "moab/Range.hpp" 00015 #include "moab/CN.hpp" 00016 00017 namespace moab { 00018 00019 ReaderIface* ReadIDEAS::factory( Interface* iface ) 00020 { return new ReadIDEAS( iface ); } 00021 00022 ReadIDEAS::ReadIDEAS(Interface* impl) 00023 : MBI(impl) 00024 { 00025 impl->query_interface(readMeshIface); 00026 } 00027 00028 00029 ErrorCode ReadIDEAS::read_tag_values( const char* /* file_name */, 00030 const char* /* tag_name */, 00031 const FileOptions& /* opts */, 00032 std::vector<int>& /* tag_values_out */, 00033 const SubsetList* /* subset_list */ ) 00034 { 00035 return MB_NOT_IMPLEMENTED; 00036 } 00037 00038 00039 ErrorCode ReadIDEAS::load_file(const char* fname, 00040 const EntityHandle* , 00041 const FileOptions& /*options*/, 00042 const ReaderIface::SubsetList* subset_list, 00043 const Tag* file_id_tag ) { 00044 00045 if (subset_list) { 00046 readMeshIface->report_error( "Reading subset of files not supported for IDEAS." ); 00047 return MB_UNSUPPORTED_OPERATION; 00048 } 00049 00050 file.open( fname ); 00051 if (!file.good()) { 00052 readMeshIface->report_error("Failed to open file: %s", fname); 00053 return MB_FILE_DOES_NOT_EXIST; 00054 } 00055 00056 ErrorCode rval; 00057 00058 char line[10000]; 00059 file.getline(line, 10000); 00060 char* liter = line; 00061 while (*liter && isspace(*liter)) 00062 ++liter; 00063 if (*liter != '-') return MB_FAILURE; 00064 ++liter; 00065 if (*liter != '1') return MB_FAILURE; 00066 while (*++liter) 00067 if (!isspace(*liter)) 00068 return MB_FAILURE; 00069 00070 EntityHandle first_vertex = 0; 00071 std::string s; 00072 while (! file.eof() ) { 00073 file.getline(line, 10000); 00074 s = line; 00075 unsigned int header_id = (unsigned int) strtol(line, NULL, 10); 00076 00077 // create vertices 00078 if( DOUBLE_PRECISION_NODES0==header_id || 00079 DOUBLE_PRECISION_NODES1==header_id ) { 00080 if (first_vertex) // multiple vertex blocks? 00081 return MB_FAILURE; 00082 rval = create_vertices( first_vertex, file_id_tag ); 00083 } 00084 // create elements 00085 else if(ELEMENTS0==header_id || 00086 ELEMENTS1==header_id || 00087 ELEMENTS2==header_id) { 00088 if (!first_vertex) // need to read vertices first 00089 return MB_FAILURE; 00090 rval = create_elements( first_vertex, file_id_tag ); 00091 } 00092 // skip everything else 00093 else { 00094 rval = skip_header(); 00095 if (MB_SUCCESS != rval) 00096 return MB_FAILURE; 00097 } 00098 } 00099 00100 file.close(); 00101 return MB_SUCCESS; 00102 } 00103 00104 ErrorCode ReadIDEAS::skip_header() { 00105 00106 // Go until finding a pair of -1 lines 00107 char *ctmp; 00108 char line[10000]; 00109 std::string s; 00110 00111 int end_of_block = 0; 00112 00113 long int il; 00114 00115 while (file.getline(line, 10000)) { 00116 00117 il = std::strtol(line, &ctmp, 10); 00118 if (il == -1) { 00119 s = ctmp; 00120 if (s.empty()) end_of_block++; 00121 } 00122 else end_of_block = 0; 00123 00124 if (end_of_block >= 2) 00125 return MB_SUCCESS; 00126 00127 } 00128 00129 return MB_SUCCESS; 00130 } 00131 00132 00133 00134 ErrorCode ReadIDEAS::create_vertices(EntityHandle& first_vertex, 00135 const Tag* file_id_tag) { 00136 00137 // Read two lines: first has some data, second has coordinates 00138 char line1[10000], line2[10000]; 00139 int il1, il2; 00140 char *ctmp1, *ctmp2; 00141 std::string s1, s2; 00142 00143 ErrorCode rval; 00144 00145 int top_of_block = file.tellg(); 00146 unsigned int num_verts = 0; 00147 00148 for (;;) { 00149 00150 // read both lines 00151 if (!file.getline(line1, 10000)) 00152 return MB_FAILURE; 00153 if (!file.getline(line2, 10000)) 00154 return MB_FAILURE; 00155 00156 // Check if we are at the end of the block 00157 il1 = std::strtol(line1, &ctmp1, 10); 00158 il2 = std::strtol(line2, &ctmp2, 10); 00159 if ((il1 == -1) && (il2 == -1)) { 00160 s1 = ctmp1; 00161 s2 = ctmp2; 00162 if ((s1.empty()) && (s2.empty())) break; 00163 } 00164 num_verts++; 00165 } 00166 00167 file.seekg( top_of_block ); 00168 00169 std::vector<double*> arrays; 00170 rval = readMeshIface->get_node_coords( 3, num_verts, 0, first_vertex, arrays ); 00171 if (MB_SUCCESS != rval) 00172 return rval; 00173 00174 Range verts; 00175 verts.insert( first_vertex, first_vertex + num_verts - 1 ); 00176 00177 double *x = arrays[0]; 00178 double *y = arrays[1]; 00179 double *z = arrays[2]; 00180 00181 // For now, assume ids are sequential and begin with 1 00182 Tag id_tag; 00183 int zero = 0; 00184 rval = MBI->tag_get_handle( GLOBAL_ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag, 00185 MB_TAG_DENSE|MB_TAG_CREAT, &zero); 00186 if (MB_SUCCESS != rval && MB_ALREADY_ALLOCATED != rval) 00187 return rval; 00188 const int beginning_node_id = 1; 00189 int node_id = beginning_node_id;; 00190 00191 for (unsigned int i = 0; i < num_verts; i++) { 00192 00193 if (!file.getline(line1, 10000)) 00194 return MB_FAILURE; 00195 if (!file.getline(line2, 10000)) 00196 return MB_FAILURE; 00197 00198 // Get the id out of the 1st line. Check the assumption that node ids are 00199 // sequential and begin with 1. 00200 if(node_id != std::strtol(line1, &ctmp1, 10)) 00201 return MB_NOT_IMPLEMENTED; 00202 else 00203 ++node_id; 00204 00205 // Get the doubles out of the 2nd line 00206 x[i] = std::strtod(line2, &ctmp2); 00207 y[i] = std::strtod(ctmp2+1, &ctmp2); 00208 z[i] = std::strtod(ctmp2+1, NULL); 00209 } 00210 00211 if (!file.getline(line1, 10000)) 00212 return MB_FAILURE; 00213 if (!file.getline(line2, 10000)) 00214 return MB_FAILURE; 00215 00216 // Tag the nodes with ids 00217 rval = readMeshIface->assign_ids( id_tag, verts, beginning_node_id ); 00218 if (MB_SUCCESS != rval) 00219 return rval; 00220 if (file_id_tag) { 00221 rval = readMeshIface->assign_ids( *file_id_tag, verts, beginning_node_id ); 00222 if (MB_SUCCESS != rval) 00223 return rval; 00224 } 00225 00226 return MB_SUCCESS; 00227 } 00228 00229 00230 ErrorCode ReadIDEAS::create_elements(EntityHandle vstart, 00231 const Tag* file_id_tag) { 00232 00233 char line1[10000], line2[10000]; 00234 int il1, il2; 00235 char *ctmp1, *ctmp2; 00236 std::string s1, s2; 00237 ErrorCode rval; 00238 EntityHandle handle; 00239 00240 Tag mat_tag, phys_tag, id_tag; 00241 rval = MBI->tag_get_handle( MAT_PROP_TABLE_TAG , 1, MB_TYPE_INTEGER, mat_tag, MB_TAG_DENSE|MB_TAG_CREAT); 00242 if (MB_SUCCESS != rval && MB_ALREADY_ALLOCATED != rval) return rval; 00243 rval = MBI->tag_get_handle( PHYS_PROP_TABLE_TAG, 1, MB_TYPE_INTEGER, phys_tag, MB_TAG_DENSE|MB_TAG_CREAT); 00244 if (MB_SUCCESS != rval && MB_ALREADY_ALLOCATED != rval) return rval; 00245 const int zero = 0; 00246 rval = MBI->tag_get_handle( GLOBAL_ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag, MB_TAG_DENSE|MB_TAG_CREAT, &zero); 00247 if (MB_SUCCESS != rval && MB_ALREADY_ALLOCATED != rval) return rval; 00248 00249 for (;;) { 00250 00251 if (!file.getline(line1, 10000) || !file.getline(line2, 10000)) 00252 return MB_FAILURE; 00253 00254 // Check if we are at the end of the block 00255 il1 = std::strtol(line1, &ctmp1, 10); 00256 il2 = std::strtol(line2, &ctmp2, 10); 00257 if ((il1 == -1) && (il2 == -1)) { 00258 s1 = ctmp1; 00259 s2 = ctmp2; 00260 if ((s1.empty()) && (s2.empty())) 00261 return MB_SUCCESS; 00262 } 00263 00264 // The first line describes attributes of the element other than connectivity. 00265 const int element_id = strtol(line1+1, &ctmp1, 10); 00266 const int ideas_type = strtol(line1+11, &ctmp1, 10); 00267 const int phys_table = strtol(line1+21, &ctmp1, 10); 00268 const int mat_table = strtol(line1+31, &ctmp1, 10); 00269 00270 // Determine the element type. 00271 EntityType mb_type; 00272 if (TRI0 ==ideas_type || TRI1 ==ideas_type) mb_type = MBTRI; 00273 else if(QUAD0==ideas_type || QUAD1==ideas_type) mb_type = MBQUAD; 00274 else if(TET ==ideas_type) mb_type = MBTET; 00275 else if(HEX ==ideas_type) mb_type = MBHEX; 00276 else if(WEDGE==ideas_type) mb_type = MBPRISM; 00277 else { 00278 std::cout << "IDEAS element type not yet added to MOAB reader." << std::endl; 00279 return MB_NOT_IMPLEMENTED; 00280 } 00281 00282 // Get the connectivity out of the 2nd line 00283 std::stringstream ss(line2); 00284 const int n_conn = CN::VerticesPerEntity(mb_type); 00285 EntityHandle conn[CN::MAX_NODES_PER_ELEMENT]; 00286 EntityHandle vert; 00287 for(int i=0; i<n_conn; ++i) { 00288 ss >> vert; 00289 conn[i] = vstart + vert - 1; 00290 } 00291 00292 // Make the element. According to the Gmsh 2.2.3 source code, the IDEAS 00293 // canonical numbering is the same as MBCN. 00294 rval = MBI->create_element( mb_type, conn, n_conn, handle); 00295 if(MB_SUCCESS != rval) return rval; 00296 00297 // If the phys set does not already exist, create it. 00298 Range phys_sets; 00299 EntityHandle phys_set; 00300 const void* const phys_set_id_val[] = {&phys_table}; 00301 rval = MBI->get_entities_by_type_and_tag( 0, MBENTITYSET, &phys_tag, 00302 phys_set_id_val, 1, phys_sets ); 00303 if(MB_SUCCESS != rval) return rval; 00304 if(phys_sets.empty()) { 00305 rval = MBI->create_meshset( MESHSET_SET, phys_set ); 00306 if(MB_SUCCESS != rval) return rval; 00307 rval = MBI->tag_set_data( phys_tag, &phys_set, 1, &phys_table); 00308 if(MB_SUCCESS != rval) return rval; 00309 } else if(1==phys_sets.size()) { 00310 phys_set = phys_sets.front(); 00311 } else { 00312 return MB_MULTIPLE_ENTITIES_FOUND; 00313 } 00314 rval = MBI->add_entities( phys_set, &handle, 1 ); 00315 if(MB_SUCCESS != rval) return rval; 00316 00317 // If the material set does not already exist, create it. 00318 Range mat_sets; 00319 EntityHandle mat_set; 00320 const void* const mat_set_id_val[] = {&mat_table}; 00321 rval = MBI->get_entities_by_type_and_tag( 0, MBENTITYSET, &mat_tag, 00322 mat_set_id_val, 1, mat_sets ); 00323 if(MB_SUCCESS != rval) return rval; 00324 if(mat_sets.empty()) { 00325 rval = MBI->create_meshset( MESHSET_SET, mat_set ); 00326 if(MB_SUCCESS != rval) return rval; 00327 rval = MBI->tag_set_data( mat_tag, &mat_set, 1, &mat_table); 00328 if(MB_SUCCESS != rval) return rval; 00329 } else if(1==mat_sets.size()) { 00330 mat_set = mat_sets.front(); 00331 } else { 00332 return MB_MULTIPLE_ENTITIES_FOUND; 00333 } 00334 rval = MBI->add_entities( mat_set, &handle, 1 ); 00335 if(MB_SUCCESS != rval) return rval; 00336 00337 // Tag the element with its id 00338 rval = MBI->tag_set_data( id_tag, &handle, 1, &element_id); 00339 if(MB_SUCCESS != rval) return rval; 00340 if (file_id_tag) { 00341 rval = MBI->tag_set_data( *file_id_tag, &handle, 1, &element_id ); 00342 if(MB_SUCCESS != rval) return rval; 00343 } 00344 } 00345 00346 //return MB_FAILURE; 00347 } 00348 00349 } // namespace moab