moab
ReadIDEAS.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines