MOAB: Mesh Oriented datABase  (version 5.4.0)
ReadABAQUS.cpp
Go to the documentation of this file.
00001 /**
00002  * MOAB, a Mesh-Oriented datABase, is a software component for creating,
00003  * storing and accessing finite element mesh data.
00004  *
00005  * Copyright 2004 Sandia Corporation.  Under the terms of Contract
00006  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
00007  * retains certain rights in this software.
00008  *
00009  * This library is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Lesser General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 2.1 of the License, or (at your option) any later version.
00013  *
00014  */
00015 
00016 #ifdef WIN32
00017 #pragma warning( disable : 4786 )
00018 #endif
00019 
00020 #include "ReadABAQUS.hpp"
00021 
00022 #include <algorithm>
00023 #include <ctime>
00024 #include <string>
00025 #include <cassert>
00026 #include <cstdio>
00027 #include <cmath>
00028 
00029 #include "moab/Range.hpp"
00030 #include "moab/Interface.hpp"
00031 #include "MBTagConventions.hpp"
00032 #include "Internals.hpp"
00033 #include "moab/ReadUtilIface.hpp"
00034 #include "AffineXform.hpp"
00035 // #include "abaqus_order.h"
00036 #include "moab/FileOptions.hpp"
00037 
00038 namespace moab
00039 {
00040 
00041 #define ABQ_AMBIGUOUS "AMBIGUOUS"
00042 #define ABQ_UNDEFINED "UNDEFINED"
00043 #define DEG2RAD       0.017453292519943295769236907684886
00044 
00045 #define MB_RETURN_IF_FAIL \
00046     if( MB_SUCCESS != status ) return status
00047 
00048 ReaderIface* ReadABAQUS::factory( Interface* iface )
00049 {
00050     return new ReadABAQUS( iface );
00051 }
00052 
00053 ReadABAQUS::ReadABAQUS( Interface* impl )
00054     : mdbImpl( impl ), readMeshIface( NULL ), lineNo( 0 ), next_line_type( abq_undefined_line ), mat_id( 0 )
00055 {
00056     assert( impl != NULL );
00057     reset();
00058 
00059     impl->query_interface( readMeshIface );
00060 
00061     // Initialize in case tag_get_handle fails below
00062     mMaterialSetTag  = 0;
00063     mDirichletSetTag = 0;
00064     mNeumannSetTag   = 0;
00065     mHasMidNodesTag  = 0;
00066 
00067     mSetTypeTag        = 0;
00068     mPartHandleTag     = 0;
00069     mInstancePIDTag    = 0;
00070     mInstanceGIDTag    = 0;
00071     mLocalIDTag        = 0;
00072     mInstanceHandleTag = 0;
00073     mAssemblyHandleTag = 0;
00074     mSetNameTag        = 0;
00075     mMatNameTag        = 0;
00076 
00077     //! Get and cache predefined tag handles
00078     int negone = -1, negonearr[] = { -1, -1, -1, -1 };
00079     mMaterialSetTag  = get_tag( MATERIAL_SET_TAG_NAME, 1, MB_TAG_SPARSE, MB_TYPE_INTEGER, &negone );
00080     mDirichletSetTag = get_tag( DIRICHLET_SET_TAG_NAME, 1, MB_TAG_SPARSE, MB_TYPE_INTEGER, &negone );
00081     mNeumannSetTag   = get_tag( NEUMANN_SET_TAG_NAME, 1, MB_TAG_SPARSE, MB_TYPE_INTEGER, &negone );
00082     mHasMidNodesTag  = get_tag( HAS_MID_NODES_TAG_NAME, 4, MB_TAG_SPARSE, MB_TYPE_INTEGER, negonearr );
00083 
00084     mSetTypeTag        = get_tag( ABAQUS_SET_TYPE_TAG_NAME, 1, MB_TAG_SPARSE, MB_TYPE_INTEGER );
00085     mPartHandleTag     = get_tag( ABAQUS_PART_HANDLE_TAG_NAME, 1, MB_TAG_SPARSE, MB_TYPE_HANDLE );
00086     mInstanceHandleTag = get_tag( ABAQUS_INSTANCE_HANDLE_TAG_NAME, 1, MB_TAG_DENSE, MB_TYPE_HANDLE );
00087     mAssemblyHandleTag = get_tag( ABAQUS_ASSEMBLY_HANDLE_TAG_NAME, 1, MB_TAG_DENSE, MB_TYPE_HANDLE );
00088     mInstancePIDTag    = get_tag( ABAQUS_INSTANCE_PART_ID_TAG_NAME, 1, MB_TAG_SPARSE, MB_TYPE_INTEGER );
00089     mInstanceGIDTag    = get_tag( ABAQUS_INSTANCE_GLOBAL_ID_TAG_NAME, 1, MB_TAG_SPARSE, MB_TYPE_INTEGER, &negone );
00090     mLocalIDTag        = get_tag( ABAQUS_LOCAL_ID_TAG_NAME, 1, MB_TAG_DENSE, MB_TYPE_INTEGER );
00091     mSetNameTag        = get_tag( ABAQUS_SET_NAME_TAG_NAME, ABAQUS_SET_NAME_LENGTH, MB_TAG_SPARSE, MB_TYPE_OPAQUE, 0 );
00092     mMatNameTag        = get_tag( ABAQUS_MAT_NAME_TAG_NAME, ABAQUS_MAT_NAME_LENGTH, MB_TAG_SPARSE, MB_TYPE_OPAQUE, 0 );
00093 }
00094 
00095 void ReadABAQUS::reset() {}
00096 
00097 ReadABAQUS::~ReadABAQUS()
00098 {
00099     mdbImpl->release_interface( readMeshIface );
00100     if( abFile.fail() ) abFile.close();
00101 }
00102 
00103 /*
00104 
00105 ErrorCode ReadABAQUS::check_file_stats()
00106 * check for existence of file
00107 * initialize meshsets, and offsets if necessary
00108 
00109 */
00110 
00111 ErrorCode ReadABAQUS::read_tag_values( const char* /* file_name */,
00112                                        const char* /* tag_name */,
00113                                        const FileOptions& /* opts */,
00114                                        std::vector< int >& /* tag_values_out */,
00115                                        const SubsetList* /* subset_list */ )
00116 {
00117     return MB_NOT_IMPLEMENTED;
00118 }
00119 
00120 ErrorCode ReadABAQUS::load_file( const char* abaqus_file_name,
00121                                  const EntityHandle* file_set_ptr,
00122                                  const FileOptions& /*opts*/,
00123                                  const ReaderIface::SubsetList* subset_list,
00124                                  const Tag* /*file_id_tag*/ )
00125 {
00126     ErrorCode status;
00127 
00128     if( subset_list )
00129     {
00130         MB_SET_ERR( MB_UNSUPPORTED_OPERATION, "Reading subset of files not supported for ABAQUS data" );
00131     }
00132 
00133     // Open file
00134     lineNo = 0;
00135     abFile.open( abaqus_file_name );
00136     if( !abFile ) return MB_FILE_DOES_NOT_EXIST;
00137 
00138     bool in_unsupported = false;
00139 
00140     EntityHandle file_set;
00141     status = mdbImpl->create_meshset( MESHSET_SET, file_set );
00142     if( MB_SUCCESS != status ) return status;
00143 
00144     next_line_type = get_next_line_type();
00145     while( next_line_type != abq_eof )
00146     {
00147         switch( next_line_type )
00148         {
00149             case abq_keyword_line:
00150                 in_unsupported = false;
00151                 switch( get_keyword() )
00152                 {
00153                     case abq_heading:
00154                         // Read header
00155                         status = read_heading( file_set );
00156                         break;
00157                     case abq_part:
00158                         // Read parts until done
00159                         status = read_part( file_set );
00160                         break;
00161                     case abq_assembly:
00162                         // Read assembly (or assemblies?)
00163                         status = read_assembly( file_set );
00164                         break;
00165                     default:
00166                         // Skip reading other content for now
00167                         // (e.g. material properties, loads, surface interactions, etc)
00168                         in_unsupported = true;
00169                         // std::cout << "Ignoring unsupported keyword: " << readline << std::endl;
00170                 }
00171                 MB_RETURN_IF_FAIL;
00172                 break;
00173             case abq_comment_line:
00174                 break;
00175             case abq_data_line:
00176                 if( !in_unsupported )
00177                 {
00178                     MB_SET_ERR( MB_FAILURE, "Expected Keyword" );
00179                 }
00180                 break;
00181             default:
00182                 MB_SET_ERR( MB_FAILURE, "Invalid/unrecognized line" );
00183         }
00184 
00185         next_line_type = get_next_line_type();
00186     }
00187 
00188     // Temporary??? delete parts
00189     // Get all node sets in part
00190     Range part_sets;
00191     int tag_val      = ABQ_PART_SET;
00192     void* tag_data[] = { &tag_val };
00193     status = mdbImpl->get_entities_by_type_and_tag( file_set, MBENTITYSET, &mSetTypeTag, tag_data, 1, part_sets );
00194     MB_RETURN_IF_FAIL;
00195 
00196     for( Range::iterator part_set = part_sets.begin(); part_set != part_sets.end(); ++part_set )
00197     {
00198         Range ent_sets;
00199         tag_val     = ABQ_NODE_SET;
00200         tag_data[0] = &tag_val;
00201 
00202         status = mdbImpl->get_entities_by_type_and_tag( *part_set, MBENTITYSET, &mSetTypeTag, tag_data, 1, ent_sets );
00203         MB_RETURN_IF_FAIL;
00204 
00205         status = mdbImpl->delete_entities( ent_sets );
00206         MB_RETURN_IF_FAIL;
00207 
00208         tag_val     = ABQ_ELEMENT_SET;
00209         tag_data[0] = &tag_val;
00210 
00211         status = mdbImpl->get_entities_by_type_and_tag( *part_set, MBENTITYSET, &mSetTypeTag, tag_data, 1, ent_sets );
00212         MB_RETURN_IF_FAIL;
00213 
00214         status = mdbImpl->delete_entities( ent_sets );
00215         MB_RETURN_IF_FAIL;
00216 
00217         Range node_list, ele_list;
00218         status = get_set_elements( *part_set, ele_list );
00219         MB_RETURN_IF_FAIL;
00220 
00221         status = mdbImpl->delete_entities( ele_list );
00222         MB_RETURN_IF_FAIL;
00223 
00224         status = mdbImpl->get_entities_by_dimension( *part_set, 0, node_list );
00225         MB_RETURN_IF_FAIL;
00226 
00227         status = mdbImpl->delete_entities( node_list );
00228         MB_RETURN_IF_FAIL;
00229     }
00230 
00231     if( file_set_ptr )
00232     {
00233         status = mdbImpl->unite_meshset( *file_set_ptr, file_set );
00234         MB_RETURN_IF_FAIL;
00235     }
00236 
00237     return mdbImpl->delete_entities( &file_set, 1 );
00238 }
00239 
00240 ErrorCode ReadABAQUS::read_heading( EntityHandle /*file_set*/ )
00241 {
00242     // Current line is only heading token. get next line
00243     next_line_type = get_next_line_type();
00244 
00245     // Perhaps keep first line and tag geometry with title?
00246 
00247     while( abq_data_line == next_line_type || abq_comment_line == next_line_type )
00248         next_line_type = get_next_line_type();
00249 
00250     return MB_SUCCESS;
00251 }
00252 
00253 ErrorCode ReadABAQUS::read_assembly( EntityHandle file_set )
00254 {
00255     ErrorCode status = MB_SUCCESS;
00256 
00257     std::vector< std::string > tokens;
00258     std::map< std::string, std::string > params;
00259     std::map< std::string, abaqus_assembly_params > requiredParams;
00260     requiredParams["NAME"] = abq_assembly_name;
00261 
00262     std::map< std::string, abaqus_assembly_params > allowableParams;
00263     allowableParams[ABQ_AMBIGUOUS] = abq_assembly_ambiguous;
00264 
00265     abaqus_assembly_params param;
00266 
00267     std::string assembly_name;
00268 
00269     // Tokenize last line read
00270     tokenize( readline, tokens, ",\n" );
00271     extract_keyword_parameters( tokens, params );
00272 
00273     // Search for required parameters
00274     for( std::map< std::string, abaqus_assembly_params >::iterator thisParam = requiredParams.begin();
00275          thisParam != requiredParams.end(); ++thisParam )
00276     {
00277         std::string param_key = match( ( *thisParam ).first, params );
00278         param                 = requiredParams[param_key];
00279         switch( param )
00280         {
00281             case abq_assembly_name:
00282                 assembly_name = params[param_key];
00283                 params.erase( param_key );
00284                 // std::cout << "Adding ASSEMBLY with name: " << assembly_name << std::endl; //
00285                 // REMOVE
00286                 break;
00287             default:
00288                 // std::cout << "Missing required ASSEMBLY parameter " << (*thisParam).first <<
00289                 // std::endl;
00290                 return MB_FAILURE;
00291         }
00292     }
00293 
00294     // Process parameters
00295     for( std::map< std::string, std::string >::iterator thisParam = params.begin(); thisParam != params.end();
00296          ++thisParam )
00297     {
00298         // Look for unambiguous match with this node parameter
00299         param = allowableParams[match( ( *thisParam ).first, allowableParams )];
00300         switch( param )
00301         {
00302             case abq_assembly_ambiguous:
00303                 // std::cout << "\tIgnoring ambiguous ASSEMBLY parameter: " << (*thisParam).first
00304                 //          << "=" << (*thisParam).second << std::endl;
00305                 break;
00306             default:
00307                 // std::cout << "\tIgnoring unsupported ASSEMBLY parameter: " << (*thisParam).first
00308                 //          << "=" << (*thisParam).second << std::endl;
00309                 break;
00310         }
00311     }
00312 
00313     EntityHandle assembly_set;
00314 
00315     status = add_entity_set( file_set, ABQ_ASSEMBLY_SET, assembly_name, assembly_set );
00316 
00317     next_line_type = get_next_line_type();
00318 
00319     bool end_assembly   = false;
00320     bool in_unsupported = false;
00321 
00322     while( next_line_type != abq_eof && !end_assembly )
00323     {
00324         switch( next_line_type )
00325         {
00326             case abq_keyword_line:
00327                 in_unsupported = false;
00328                 switch( get_keyword() )
00329                 {
00330                     case abq_end_assembly:
00331                         end_assembly = true;
00332                         break;
00333                     case abq_instance:
00334                         status = read_instance( assembly_set, file_set );
00335                         break;
00336                     case abq_nset:
00337                         status = read_node_set( assembly_set, file_set );
00338                         break;
00339                     default:
00340                         in_unsupported = true;
00341                         // std::cout << "\tIgnoring unsupported keyword in this ASSEMBLY: "
00342                         //          << readline << std::endl;
00343                         next_line_type = get_next_line_type();
00344                         break;
00345                 }
00346                 break;
00347             case abq_comment_line:
00348                 next_line_type = get_next_line_type();
00349                 break;
00350             case abq_data_line:
00351                 if( !in_unsupported )
00352                 {
00353                     // std::cout << "Internal Error: Data lines not allowed in ASSEMBLY keyword."
00354                     //          << std::endl << readline << std::endl;
00355                     return MB_FAILURE;
00356                 }
00357                 next_line_type = get_next_line_type();
00358                 break;
00359             case abq_blank_line:
00360                 // std::cout << "Error: Blank lines are not allowed." << std::endl;
00361                 return MB_FAILURE;
00362             default:
00363                 // std::cout << "Error reading ASSEMBLY " << assembly_name << std::endl;
00364                 return MB_FAILURE;
00365         }
00366         MB_RETURN_IF_FAIL;
00367     }
00368 
00369     num_assembly_instances[assembly_set] = 0;
00370 
00371     return MB_SUCCESS;
00372 }
00373 
00374 ErrorCode ReadABAQUS::read_instance( EntityHandle assembly_set, EntityHandle file_set )
00375 {
00376     ErrorCode status = MB_SUCCESS;
00377 
00378     std::vector< std::string > tokens;
00379     std::map< std::string, std::string > params;
00380     std::map< std::string, abaqus_instance_params > requiredParams;
00381     requiredParams["NAME"] = abq_instance_name;
00382     requiredParams["PART"] = abq_instance_part;
00383 
00384     std::map< std::string, abaqus_instance_params > allowableParams;
00385     allowableParams[ABQ_AMBIGUOUS] = abq_instance_ambiguous;
00386 
00387     abaqus_instance_params param;
00388 
00389     std::string instance_name, part_name;
00390 
00391     // Tokenize last line read
00392     tokenize( readline, tokens, ",\n" );
00393     extract_keyword_parameters( tokens, params );
00394 
00395     // Search for required parameters
00396     for( std::map< std::string, abaqus_instance_params >::iterator thisParam = requiredParams.begin();
00397          thisParam != requiredParams.end(); ++thisParam )
00398     {
00399         std::string param_key = match( ( *thisParam ).first, params );
00400         param                 = requiredParams[param_key];
00401         switch( param )
00402         {
00403             case abq_instance_name:
00404                 instance_name = params[param_key];
00405                 params.erase( param_key );
00406                 break;
00407             case abq_instance_part:
00408                 part_name = params[param_key];
00409                 params.erase( param_key );
00410                 break;
00411             default:
00412                 // std::cout << "Missing required INSTANCE parameter " << (*thisParam).first <<
00413                 // std::endl;
00414                 return MB_FAILURE;
00415         }
00416     }
00417     // std::cout << "\tAdding INSTANCE with name: " << instance_name << " of PART wit name: " <<
00418     // part_name <<  std::endl; // REMOVE
00419 
00420     // Process parameters
00421     for( std::map< std::string, std::string >::iterator thisParam = params.begin(); thisParam != params.end();
00422          ++thisParam )
00423     {
00424         // Look for unambiguous match with this node parameter
00425         param = allowableParams[match( ( *thisParam ).first, allowableParams )];
00426         switch( param )
00427         {
00428             case abq_instance_ambiguous:
00429                 // std::cout << "\t\tIgnoring ambiguous INSTANCE parameter: " << (*thisParam).first
00430                 //          << "=" << (*thisParam).second << std::endl;
00431                 break;
00432             default:
00433                 // std::cout << "\t\tIgnoring unsupported INSTANCE parameter: " <<
00434                 // (*thisParam).first
00435                 //          << "=" << (*thisParam).second << std::endl;
00436                 break;
00437         }
00438     }
00439 
00440     next_line_type = get_next_line_type();
00441 
00442     bool read_translation = false;
00443     bool read_rotation    = false;
00444     std::vector< double > translation( 3, 0 );
00445     std::vector< double > rotation( 7, 0 );
00446     bool end_instance   = false;
00447     bool in_unsupported = false;
00448 
00449     EntityHandle instance_set;
00450     status = add_entity_set( assembly_set, ABQ_INSTANCE_SET, instance_name, instance_set );
00451     MB_RETURN_IF_FAIL;
00452 
00453     while( next_line_type != abq_eof && !end_instance )
00454     {
00455         switch( next_line_type )
00456         {
00457             case abq_keyword_line:
00458                 in_unsupported = false;
00459                 switch( get_keyword() )
00460                 {
00461                     case abq_end_instance:
00462                         end_instance   = true;
00463                         next_line_type = get_next_line_type();
00464                         break;
00465                     case abq_node:
00466                         status = read_node_list( instance_set, assembly_set );
00467                         break;
00468                     case abq_element:
00469                         status = read_element_list( instance_set, assembly_set );
00470                         break;
00471                     case abq_nset:
00472                         status = read_node_set( instance_set, file_set, assembly_set );
00473                         break;
00474                     case abq_elset:
00475                         status = read_element_set( instance_set, file_set, assembly_set );
00476                         break;
00477                     case abq_solid_section:
00478                         status = read_solid_section( instance_set );
00479                         break;
00480                     default:
00481                         in_unsupported = true;
00482                         // std::cout << "\t\tIgnoring unsupported keyword in this INSTANCE: "
00483                         //          << readline << std::endl;
00484                         next_line_type = get_next_line_type();
00485                         break;
00486                 }
00487                 break;
00488             case abq_comment_line:
00489                 next_line_type = get_next_line_type();
00490                 break;
00491             case abq_data_line:
00492                 if( !in_unsupported )
00493                 {
00494                     tokenize( readline, tokens, ", \n" );
00495                     if( !read_translation )
00496                     {
00497                         if( tokens.size() != 3 )
00498                         {
00499                             MB_SET_ERR( MB_FAILURE, "Wrong number of entries on INSTANCE translation line" );
00500                         }
00501 
00502                         for( unsigned int i = 0; i < 3; i++ )
00503                             translation[i] = atof( tokens[i].c_str() );
00504 
00505                         read_translation = true;
00506                     }
00507                     else if( !read_rotation )
00508                     {
00509                         if( tokens.size() != 7 )
00510                         {
00511                             MB_SET_ERR( MB_FAILURE, "Wrong number of entries on INSTANCE rotation line" );
00512                         }
00513                         for( unsigned int i = 0; i < 7; i++ )
00514                             rotation[i] = atof( tokens[i].c_str() );
00515 
00516                         read_rotation = true;
00517                     }
00518                     else
00519                     {
00520                         MB_SET_ERR( MB_FAILURE, "Too many data lines for this INSTANCE" );
00521                     }
00522                 }  // if (!in_unsupported)
00523                 next_line_type = get_next_line_type();
00524                 break;
00525             case abq_blank_line:
00526                 MB_SET_ERR( MB_FAILURE, "Error: Blank lines are not allowed" );
00527             default:
00528                 MB_SET_ERR( MB_FAILURE, "Error reading INSTANCE" );
00529         }  // switch (next_line_type)
00530     }      // while (next_line_type != abq_eof && !end_instance)
00531 
00532     status = create_instance_of_part( file_set, assembly_set, part_name, instance_name, instance_set, translation,
00533                                       rotation );
00534     MB_RETURN_IF_FAIL;
00535 
00536     return MB_SUCCESS;
00537 }
00538 
00539 ErrorCode ReadABAQUS::read_part( EntityHandle file_set )
00540 {
00541     ErrorCode status = MB_SUCCESS;
00542 
00543     std::vector< std::string > tokens;
00544     std::map< std::string, std::string > params;
00545     std::map< std::string, abaqus_part_params > requiredParams;
00546     requiredParams["NAME"] = abq_part_name;
00547 
00548     std::map< std::string, abaqus_part_params > allowableParams;
00549     allowableParams[ABQ_AMBIGUOUS] = abq_part_ambiguous;
00550 
00551     abaqus_part_params param;
00552 
00553     std::string part_name;
00554 
00555     // Tokenize last line read
00556     tokenize( readline, tokens, ",\n" );
00557     extract_keyword_parameters( tokens, params );
00558 
00559     // Search for required parameters
00560     for( std::map< std::string, abaqus_part_params >::iterator thisParam = requiredParams.begin();
00561          thisParam != requiredParams.end(); ++thisParam )
00562     {
00563         std::string param_key = match( ( *thisParam ).first, params );
00564         param                 = requiredParams[param_key];
00565         switch( param )
00566         {
00567             case abq_part_name:
00568                 part_name = params[param_key];
00569                 params.erase( param_key );
00570                 // std::cout << "Adding PART with name: " << part_name << std::endl; // REMOVE
00571                 break;
00572             default:
00573                 MB_SET_ERR( MB_FAILURE, "Missing required PART parameter" );
00574         }
00575     }
00576 
00577     // Process parameters
00578     for( std::map< std::string, std::string >::iterator thisParam = params.begin(); thisParam != params.end();
00579          ++thisParam )
00580     {
00581         // Look for unambiguous match with this node parameter
00582         param = allowableParams[match( ( *thisParam ).first, allowableParams )];
00583         switch( param )
00584         {
00585             case abq_part_ambiguous:
00586                 // std::cout << "\tIgnoring ambiguous PART parameter: " << (*thisParam).first
00587                 //          << "=" << (*thisParam).second << std::endl;
00588                 break;
00589             default:
00590                 // std::cout << "\tIgnoring unsupported PART parameter: " << (*thisParam).first
00591                 //          << "=" << (*thisParam).second << std::endl;
00592                 break;
00593         }
00594     }
00595 
00596     EntityHandle part_set;
00597 
00598     status = add_entity_set( file_set, ABQ_PART_SET, part_name, part_set );
00599 
00600     next_line_type = get_next_line_type();
00601 
00602     bool end_part       = false;
00603     bool in_unsupported = false;
00604 
00605     while( next_line_type != abq_eof && !end_part )
00606     {
00607         switch( next_line_type )
00608         {
00609             case abq_keyword_line:
00610                 in_unsupported = false;
00611                 switch( get_keyword() )
00612                 {
00613                     case abq_end_part:
00614                         end_part = true;
00615                         break;
00616                     case abq_node:
00617                         status = read_node_list( part_set );
00618                         break;
00619                     case abq_element:
00620                         status = read_element_list( part_set );
00621                         break;
00622                     case abq_nset:
00623                         status = read_node_set( part_set );
00624                         break;
00625                     case abq_elset:
00626                         status = read_element_set( part_set );
00627                         break;
00628                     case abq_solid_section:
00629                         status = read_solid_section( part_set );
00630                         break;
00631                     default:
00632                         in_unsupported = true;
00633                         // std::cout << "\tIgnoring unsupported keyword in this PART: "
00634                         //          << readline << std::endl;
00635                         next_line_type = get_next_line_type();
00636                         break;
00637                 }
00638                 MB_RETURN_IF_FAIL;
00639                 break;
00640             case abq_comment_line:
00641                 next_line_type = get_next_line_type();
00642                 break;
00643             case abq_data_line:
00644                 if( !in_unsupported )
00645                 {
00646                     MB_SET_ERR( MB_FAILURE, "Data lines not allowed in PART keyword" );
00647                 }
00648                 next_line_type = get_next_line_type();
00649                 break;
00650             case abq_blank_line:
00651                 MB_SET_ERR( MB_FAILURE, "Blank lines are not allowed" );
00652             default:
00653                 MB_SET_ERR( MB_FAILURE, "Error reading PART" );
00654         }
00655     }
00656 
00657     num_part_instances[part_set] = 0;
00658 
00659     return MB_SUCCESS;
00660 }
00661 
00662 ErrorCode ReadABAQUS::read_solid_section( EntityHandle parent_set )
00663 {
00664     ErrorCode status;
00665 
00666     std::vector< std::string > tokens;
00667     std::map< std::string, std::string > params;
00668     std::map< std::string, abaqus_solid_section_params > requiredParams;
00669     requiredParams["ELSET"]    = abq_solid_section_elset;
00670     requiredParams["MATERIAL"] = abq_solid_section_matname;
00671 
00672     std::map< std::string, abaqus_solid_section_params > allowableParams;
00673     allowableParams[ABQ_AMBIGUOUS] = abq_solid_section_ambiguous;
00674 
00675     abaqus_solid_section_params param;
00676 
00677     // Tokenize last line read
00678     tokenize( readline, tokens, ",\n" );
00679     extract_keyword_parameters( tokens, params );
00680 
00681     std::string elset_name, mat_name;
00682 
00683     // Search for required parameters
00684     for( std::map< std::string, abaqus_solid_section_params >::iterator thisParam = requiredParams.begin();
00685          thisParam != requiredParams.end(); ++thisParam )
00686     {
00687         std::string param_key = match( ( *thisParam ).first, params );
00688         param                 = requiredParams[param_key];
00689         switch( param )
00690         {
00691             case abq_solid_section_elset:
00692                 elset_name = params[param_key];
00693                 params.erase( param_key );
00694                 break;
00695             case abq_solid_section_matname:
00696                 mat_name = params[param_key];
00697                 params.erase( param_key );
00698                 break;
00699             default:
00700                 MB_SET_ERR( MB_FAILURE, "Missing required SOLID SECTION parameter" );
00701         }
00702     }
00703     // std::cout << "\tAdding SOLID SECTION with to ELEMENT SET: " << elset_name << " with material:
00704     // " << mat_name << std::endl; // REMOVE
00705 
00706     // Process parameters
00707     for( std::map< std::string, std::string >::iterator thisParam = params.begin(); thisParam != params.end();
00708          ++thisParam )
00709     {
00710         // Look for unambiguous match with this node parameter
00711         param = allowableParams[match( ( *thisParam ).first, allowableParams )];
00712         switch( param )
00713         {
00714             case abq_solid_section_ambiguous:
00715                 // std::cout << "\t\tIgnoring ambiguous SOLID_SECTION parameter: " <<
00716                 // (*thisParam).first
00717                 //          << "=" << (*thisParam).second << std::endl;
00718                 break;
00719             default:
00720                 // std::cout << "\t\tIgnoring unsupported SOLID_SECTION parameter: " <<
00721                 // (*thisParam).first
00722                 //          << "=" << (*thisParam).second << std::endl;
00723                 break;
00724         }
00725     }
00726 
00727     EntityHandle set_handle;
00728     status = get_set_by_name( parent_set, ABQ_ELEMENT_SET, elset_name, set_handle );
00729     MB_RETURN_IF_FAIL;
00730 
00731     status = mdbImpl->tag_set_data( mMatNameTag, &set_handle, 1, mat_name.c_str() );
00732     MB_RETURN_IF_FAIL;
00733 
00734     if( 0 == matIDmap[mat_name] ) matIDmap[mat_name] = ++mat_id;
00735 
00736     status = mdbImpl->tag_set_data( mMaterialSetTag, &set_handle, 1, &( matIDmap[mat_name] ) );
00737     MB_RETURN_IF_FAIL;
00738 
00739     next_line_type = get_next_line_type();
00740 
00741     while( next_line_type != abq_eof && next_line_type != abq_keyword_line )
00742         next_line_type = get_next_line_type();
00743 
00744     return MB_SUCCESS;
00745 }
00746 
00747 ErrorCode ReadABAQUS::read_element_set( EntityHandle parent_set, EntityHandle file_set, EntityHandle assembly_set )
00748 {
00749     ErrorCode status;
00750 
00751     std::vector< std::string > tokens;
00752     std::map< std::string, std::string > params;
00753     std::map< std::string, abaqus_elset_params > requiredParams;
00754     requiredParams["ELSET"] = abq_elset_elset;
00755 
00756     std::map< std::string, abaqus_elset_params > allowableParams;
00757     allowableParams[ABQ_AMBIGUOUS] = abq_elset_ambiguous;
00758     allowableParams["GENERATE"]    = abq_elset_generate;
00759     allowableParams["INSTANCE"]    = abq_elset_instance;
00760 
00761     abaqus_elset_params param;
00762 
00763     std::string elset_name;
00764     bool generate_elset = false;
00765     std::string instance_name;
00766     EntityHandle element_container_set = parent_set;
00767 
00768     // Tokenize last line read
00769     tokenize( readline, tokens, ",\n" );
00770     extract_keyword_parameters( tokens, params );
00771 
00772     Range element_range;
00773 
00774     // Search for required parameters
00775     for( std::map< std::string, abaqus_elset_params >::iterator thisParam = requiredParams.begin();
00776          thisParam != requiredParams.end(); ++thisParam )
00777     {
00778         std::string param_key = match( ( *thisParam ).first, params );
00779         param                 = requiredParams[param_key];
00780         switch( param )
00781         {
00782             case abq_elset_elset:
00783                 elset_name = params[param_key];
00784                 params.erase( param_key );
00785                 // std::cout << "\tAdding ELSET with name: " << elset_name << std::endl; // REMOVE
00786                 break;
00787             default:
00788                 MB_SET_ERR( MB_FAILURE, "Missing required ELSET parameter" );
00789         }
00790     }
00791 
00792     // Process parameters
00793     for( std::map< std::string, std::string >::iterator thisParam = params.begin(); thisParam != params.end();
00794          ++thisParam )
00795     {
00796         // Look for unambiguous match with this node parameter
00797         param = allowableParams[match( ( *thisParam ).first, allowableParams )];
00798         switch( param )
00799         {
00800             case abq_elset_generate:
00801                 generate_elset = true;
00802                 break;
00803             case abq_elset_instance:
00804                 instance_name = ( *thisParam ).second;
00805                 status        = get_set_by_name( parent_set, ABQ_INSTANCE_SET, instance_name, element_container_set );
00806                 MB_RETURN_IF_FAIL;
00807                 break;
00808             case abq_elset_ambiguous:
00809                 // std::cout << "\t\tIgnoring ambiguous ELSET parameter: " << (*thisParam).first
00810                 //          << "=" << (*thisParam).second << std::endl;
00811                 break;
00812             default:
00813                 // std::cout << "\t\tIgnoring unsupported ELSET parameter: " << (*thisParam).first
00814                 //          << "=" << (*thisParam).second << std::endl;
00815                 break;
00816         }
00817     }
00818 
00819     std::vector< int > element_list;
00820     Range tmp_element_range;
00821 
00822     next_line_type = get_next_line_type();
00823 
00824     while( next_line_type != abq_eof && next_line_type != abq_keyword_line )
00825     {
00826         if( abq_data_line == next_line_type )
00827         {
00828             tokenize( readline, tokens, ", \n" );
00829             if( generate_elset )
00830             {
00831                 if( tokens.size() != 3 )
00832                 {
00833                     MB_SET_ERR( MB_FAILURE, "Wrong number of entries on GENERATE element set data line" );
00834                 }
00835                 int e1   = atoi( tokens[0].c_str() );
00836                 int e2   = atoi( tokens[1].c_str() );
00837                 int incr = atoi( tokens[2].c_str() );
00838                 if( ( incr == 0 ) || ( ( ( e2 - e1 ) % incr ) != 0 ) )
00839                 {
00840                     MB_SET_ERR( MB_FAILURE, "Invalid data on GENERATE element set data line" );
00841                 }
00842                 for( int element_id = e1; element_id <= e2; element_id += incr )
00843                     element_list.push_back( element_id );
00844             }
00845             else
00846             {
00847                 for( unsigned int idx = 0; idx < tokens.size(); idx++ )
00848                 {
00849                     if( isalpha( tokens[idx][0] ) )
00850                     {
00851                         tmp_element_range.clear();
00852                         status = get_set_elements_by_name( element_container_set, ABQ_ELEMENT_SET, tokens[idx],
00853                                                            tmp_element_range );
00854                         MB_RETURN_IF_FAIL;
00855 
00856                         element_range.merge( tmp_element_range );
00857                     }
00858                     else
00859                         element_list.push_back( atoi( tokens[idx].c_str() ) );
00860                 }
00861             }
00862         }  // if (abq_data_line == next_line_type)
00863 
00864         next_line_type = get_next_line_type();
00865     }  // while (next_line_type != abq_eof && next_line_type != abq_keyword_line)
00866 
00867     tmp_element_range.clear();
00868     status = get_elements_by_id( element_container_set, element_list, tmp_element_range );
00869     MB_RETURN_IF_FAIL;
00870 
00871     element_range.merge( tmp_element_range );
00872 
00873     EntityHandle element_set;
00874 
00875     status = add_entity_set( parent_set, ABQ_ELEMENT_SET, elset_name, element_set );
00876     MB_RETURN_IF_FAIL;
00877 
00878     status = mdbImpl->add_entities( element_set, element_range );
00879     MB_RETURN_IF_FAIL;
00880 
00881     // SHOULD WE EVER DO THIS???
00882     if( file_set )
00883     {
00884         status = mdbImpl->add_entities( file_set, &element_set, 1 );
00885         MB_RETURN_IF_FAIL;
00886     }
00887 
00888     // SHOULD WE EVER DO THIS???
00889     if( assembly_set )
00890     {
00891         status = mdbImpl->add_entities( assembly_set, &element_set, 1 );
00892         MB_RETURN_IF_FAIL;
00893 
00894         status = mdbImpl->tag_set_data( mAssemblyHandleTag, &element_set, 1, &assembly_set );
00895         MB_RETURN_IF_FAIL;
00896     }
00897 
00898     return MB_SUCCESS;
00899 }
00900 
00901 ErrorCode ReadABAQUS::read_node_set( EntityHandle parent_set, EntityHandle file_set, EntityHandle assembly_set )
00902 {
00903     ErrorCode status;
00904 
00905     std::vector< std::string > tokens;
00906     std::map< std::string, std::string > params;
00907     std::map< std::string, abaqus_nset_params > requiredParams;
00908     requiredParams["NSET"] = abq_nset_nset;
00909 
00910     std::map< std::string, abaqus_nset_params > allowableParams;
00911     allowableParams[ABQ_AMBIGUOUS] = abq_nset_ambiguous;
00912     allowableParams["ELSET"]       = abq_nset_elset;
00913     allowableParams["GENERATE"]    = abq_nset_generate;
00914     allowableParams["INSTANCE"]    = abq_nset_instance;
00915 
00916     abaqus_nset_params param;
00917 
00918     std::string nset_name;
00919     bool make_from_elset = false;
00920     bool generate_nset   = false;
00921     std::string elset_name, instance_name;
00922     EntityHandle node_container_set = parent_set;
00923 
00924     // Tokenize last line read
00925     tokenize( readline, tokens, ",\n" );
00926     extract_keyword_parameters( tokens, params );
00927 
00928     Range node_range;
00929 
00930     // Search for required parameters
00931     for( std::map< std::string, abaqus_nset_params >::iterator thisParam = requiredParams.begin();
00932          thisParam != requiredParams.end(); ++thisParam )
00933     {
00934         std::string param_key = match( ( *thisParam ).first, params );
00935         param                 = requiredParams[param_key];
00936         switch( param )
00937         {
00938             case abq_nset_nset:
00939                 nset_name = params[param_key];
00940                 params.erase( param_key );
00941                 // std::cout << "\tAdding NSET with name: " << nset_name << std::endl; // REMOVE
00942                 break;
00943             default:
00944                 MB_SET_ERR( MB_FAILURE, "Missing required NSET parameter" );
00945         }
00946     }
00947 
00948     // Process parameters
00949     for( std::map< std::string, std::string >::iterator thisParam = params.begin(); thisParam != params.end();
00950          ++thisParam )
00951     {
00952         // Look for unambiguous match with this node parameter
00953         param = allowableParams[match( ( *thisParam ).first, allowableParams )];
00954         switch( param )
00955         {
00956             case abq_nset_elset:
00957                 make_from_elset = true;
00958                 elset_name      = ( *thisParam ).second;
00959                 break;
00960             case abq_nset_generate:
00961                 generate_nset = true;
00962                 break;
00963             case abq_nset_instance:
00964                 instance_name = ( *thisParam ).second;
00965                 status        = get_set_by_name( parent_set, ABQ_INSTANCE_SET, instance_name, node_container_set );
00966                 MB_RETURN_IF_FAIL;
00967                 break;
00968             case abq_nset_ambiguous:
00969                 // std::cout << "\t\tIgnoring ambiguous NSET parameter: " << (*thisParam).first
00970                 //          << "=" << (*thisParam).second << std::endl;
00971                 break;
00972             default:
00973                 // std::cout << "\t\tIgnoring unsupported NSET parameter: " << (*thisParam).first
00974                 //          << "=" << (*thisParam).second << std::endl;
00975                 break;
00976         }
00977     }
00978 
00979     if( make_from_elset && generate_nset )
00980     {
00981         MB_SET_ERR( MB_FAILURE, "Incompatible NSET parameters ELSET & GENERATE" );
00982     }
00983 
00984     if( make_from_elset )
00985     {
00986         status = get_set_nodes( parent_set, ABQ_ELEMENT_SET, elset_name, node_range );
00987         MB_RETURN_IF_FAIL;
00988     }
00989     else
00990     {
00991         std::vector< int > node_list;
00992         Range tmp_node_range;
00993 
00994         next_line_type = get_next_line_type();
00995 
00996         while( next_line_type != abq_eof && next_line_type != abq_keyword_line )
00997         {
00998             if( abq_data_line == next_line_type )
00999             {
01000                 tokenize( readline, tokens, ", \n" );
01001                 if( generate_nset )
01002                 {
01003                     if( tokens.size() != 3 )
01004                     {
01005                         MB_SET_ERR( MB_FAILURE, "Wrong number of entries on GENERATE node set data line" );
01006                     }
01007                     int n1   = atoi( tokens[0].c_str() );
01008                     int n2   = atoi( tokens[1].c_str() );
01009                     int incr = atoi( tokens[2].c_str() );
01010                     if( ( incr == 0 ) || ( ( ( n2 - n1 ) % incr ) != 0 ) )
01011                     {
01012                         MB_SET_ERR( MB_FAILURE, "Invalid data on GENERATE node set data line" );
01013                     }
01014                     for( int node_id = n1; node_id <= n2; node_id += incr )
01015                         node_list.push_back( node_id );
01016                 }
01017                 else
01018                 {
01019                     for( unsigned int idx = 0; idx < tokens.size(); idx++ )
01020                     {
01021                         if( isalpha( tokens[idx][0] ) )
01022                         {
01023                             tmp_node_range.clear();
01024                             status = get_set_nodes( parent_set, ABQ_NODE_SET, tokens[idx], tmp_node_range );
01025                             MB_RETURN_IF_FAIL;
01026 
01027                             node_range.merge( tmp_node_range );
01028                         }
01029                         else
01030                             node_list.push_back( atoi( tokens[idx].c_str() ) );
01031                     }
01032                 }
01033             }  // if (abq_data_line == next_line_type)
01034 
01035             next_line_type = get_next_line_type();
01036         }  // while (next_line_type != abq_eof && next_line_type != abq_keyword_line)
01037 
01038         tmp_node_range.clear();
01039 
01040         status = get_nodes_by_id( node_container_set, node_list, tmp_node_range );
01041         MB_RETURN_IF_FAIL;
01042 
01043         node_range.merge( tmp_node_range );
01044     }
01045 
01046     EntityHandle node_set;
01047 
01048     status = add_entity_set( parent_set, ABQ_NODE_SET, nset_name, node_set );
01049     MB_RETURN_IF_FAIL;
01050 
01051     status = mdbImpl->add_entities( node_set, node_range );
01052     MB_RETURN_IF_FAIL;
01053 
01054     if( file_set )
01055     {
01056         status = mdbImpl->add_entities( file_set, &node_set, 1 );
01057         MB_RETURN_IF_FAIL;
01058     }
01059 
01060     if( assembly_set )
01061     {
01062         status = mdbImpl->add_entities( assembly_set, &node_set, 1 );
01063         MB_RETURN_IF_FAIL;
01064 
01065         status = mdbImpl->tag_set_data( mAssemblyHandleTag, &node_set, 1, &assembly_set );
01066         MB_RETURN_IF_FAIL;
01067     }
01068 
01069     return MB_SUCCESS;
01070 }
01071 
01072 ErrorCode ReadABAQUS::read_element_list( EntityHandle parent_set, EntityHandle assembly_set )
01073 {
01074     ErrorCode status;
01075 
01076     std::vector< std::string > tokens;
01077     std::map< std::string, std::string > params;
01078     std::map< std::string, abaqus_element_params > requiredParams;
01079     requiredParams["TYPE"] = abq_element_type;
01080 
01081     std::map< std::string, abaqus_element_params > allowableParams;
01082     allowableParams[ABQ_AMBIGUOUS] = abq_element_ambiguous;
01083     allowableParams["ELSET"]       = abq_element_elset;
01084 
01085     abaqus_element_params param;
01086 
01087     std::map< std::string, abaqus_element_type > elementTypes;
01088     std::map< abaqus_element_type, unsigned int > nodes_per_element;
01089     std::map< abaqus_element_type, EntityType > entityTypeMap;
01090     elementTypes["DC3D8"]                = abq_eletype_dc3d8;
01091     nodes_per_element[abq_eletype_dc3d8] = 8;
01092     entityTypeMap[abq_eletype_dc3d8]     = MBHEX;
01093 
01094     elementTypes["DCC3D8"]                = abq_eletype_dcc3d8;
01095     nodes_per_element[abq_eletype_dcc3d8] = 8;
01096     entityTypeMap[abq_eletype_dcc3d8]     = MBHEX;
01097 
01098     elementTypes["C3D4"]                = abq_eletype_c3d4;
01099     nodes_per_element[abq_eletype_c3d4] = 4;
01100     entityTypeMap[abq_eletype_c3d4]     = MBTET;
01101 
01102     elementTypes["DC3D4"]                = abq_eletype_dc3d4;
01103     nodes_per_element[abq_eletype_dc3d4] = 4;
01104     entityTypeMap[abq_eletype_dc3d4]     = MBTET;
01105 
01106     elementTypes["C3D8R"]                = abq_eletype_c3d8r;
01107     nodes_per_element[abq_eletype_c3d8r] = 8;
01108     entityTypeMap[abq_eletype_c3d8r]     = MBHEX;
01109 
01110     elementTypes["DS4"]                = abq_eletype_ds4;
01111     nodes_per_element[abq_eletype_ds4] = 4;
01112     entityTypeMap[abq_eletype_ds4]     = MBQUAD;
01113 
01114     abaqus_element_type element_type = abq_eletype_dc3d8;
01115 
01116     bool make_element_set = false;
01117     std::string element_set_name;
01118 
01119     // Tokenize last line read
01120     tokenize( readline, tokens, ",\n" );
01121     extract_keyword_parameters( tokens, params );
01122 
01123     // Search for required parameters
01124     for( std::map< std::string, abaqus_element_params >::iterator thisParam = requiredParams.begin();
01125          thisParam != requiredParams.end(); ++thisParam )
01126     {
01127         std::string param_key = match( ( *thisParam ).first, params );
01128         param                 = requiredParams[param_key];
01129         switch( param )
01130         {
01131             case abq_element_type:
01132                 element_type = elementTypes[params[param_key]];
01133                 if( abq_eletype_unsupported == element_type )
01134                 {
01135                     MB_SET_ERR( MB_FAILURE, "MOAB doesn't currently support this element type" );
01136                 }
01137                 // std::cout << "\tAdding ELEMENTS of type: " << params[param_key] << std::endl; //
01138                 // REMOVE
01139                 params.erase( param_key );
01140                 break;
01141             case abq_element_undefined:
01142                 MB_SET_ERR( MB_FAILURE, "Missing required ELEMENT parameter" );
01143             default:
01144                 break;
01145         }
01146     }
01147 
01148     // Process parameters
01149     for( std::map< std::string, std::string >::iterator thisParam = params.begin(); thisParam != params.end();
01150          ++thisParam )
01151     {
01152         // Look for unambiguous match with this node parameter
01153         param = allowableParams[match( ( *thisParam ).first, allowableParams )];
01154         switch( param )
01155         {
01156             case abq_element_elset:
01157                 make_element_set = true;
01158                 element_set_name = ( *thisParam ).second;
01159                 break;
01160             case abq_element_ambiguous:
01161                 // std::cout << "\t\tIgnoring ambiguous ELEMENT parameter: " << (*thisParam).first
01162                 //          << "=" << (*thisParam).second << std::endl;
01163                 break;
01164             default:
01165                 // std::cout << "\t\tIgnoring unsupported ELEMENT parameter: " << (*thisParam).first
01166                 //          << "=" << (*thisParam).second << std::endl;
01167                 break;
01168         }
01169     }
01170 
01171     std::vector< int > connect_list, element_ids;
01172 
01173     next_line_type = get_next_line_type();
01174 
01175     while( next_line_type != abq_eof && next_line_type != abq_keyword_line )
01176     {
01177         if( abq_data_line == next_line_type )
01178         {
01179             tokenize( readline, tokens, ", \n" );
01180             if( tokens.size() < nodes_per_element[element_type] + 1 )
01181             {
01182                 MB_SET_ERR( MB_FAILURE, "Not enough data on node data line" );
01183             }
01184             element_ids.push_back( atoi( tokens[0].c_str() ) );
01185             for( unsigned int i = 1; i < nodes_per_element[element_type] + 1; i++ )
01186                 connect_list.push_back( atoi( tokens[i].c_str() ) );
01187         }
01188 
01189         next_line_type = get_next_line_type();
01190     }
01191 
01192     int num_elements = element_ids.size();
01193 
01194     // Get and fill element arrays
01195     EntityHandle start_element = 0;
01196     EntityHandle* connect;
01197 
01198     status = readMeshIface->get_element_connect( num_elements, nodes_per_element[element_type],
01199                                                  entityTypeMap[element_type], MB_START_ID, start_element, connect );
01200     MB_RETURN_IF_FAIL;
01201     if( 0 == start_element ) return MB_FAILURE;
01202 
01203     // ASSUME: elements must be defined after nodes!
01204     // Get list of node entity handles and node IDs
01205     Range node_list;
01206     status = mdbImpl->get_entities_by_dimension( parent_set, 0, node_list );
01207     MB_RETURN_IF_FAIL;
01208 
01209     std::vector< int > node_ids( node_list.size() );
01210     status = mdbImpl->tag_get_data( mLocalIDTag, node_list, &node_ids[0] );
01211     MB_RETURN_IF_FAIL;
01212 
01213     std::map< int, EntityHandle > nodeIdMap;
01214     for( unsigned int idx = 0; idx < node_list.size(); idx++ )
01215         nodeIdMap[node_ids[idx]] = node_list[idx];
01216 
01217     for( unsigned int node = 0; node < connect_list.size(); node++ )
01218         connect[node] = nodeIdMap[connect_list[node]];
01219 
01220     Range element_range( start_element, start_element + num_elements - 1 );
01221 
01222     // Add elements to file_set
01223     // status = mdbImpl->add_entities(file_set, element_range);
01224     // MB_RETURN_IF_FAIL;
01225 
01226     // Add elements to this parent_set
01227     status = mdbImpl->add_entities( parent_set, element_range );
01228     MB_RETURN_IF_FAIL;
01229 
01230     // Tag elements with their local ID's
01231     status = mdbImpl->tag_set_data( mLocalIDTag, element_range, &element_ids[0] );
01232     MB_RETURN_IF_FAIL;
01233 
01234     if( assembly_set )
01235     {
01236         status = mdbImpl->add_entities( assembly_set, element_range );
01237         MB_RETURN_IF_FAIL;
01238 
01239         std::vector< EntityHandle > tmp_assembly_handles;
01240         tmp_assembly_handles.assign( element_range.size(), assembly_set );
01241         status = mdbImpl->tag_set_data( mAssemblyHandleTag, element_range, &( tmp_assembly_handles[0] ) );
01242         MB_RETURN_IF_FAIL;
01243     }
01244 
01245     // These elements don't know their instance_set (probably not defined)
01246 
01247     if( make_element_set )
01248     {
01249         EntityHandle element_set;
01250 
01251         status = add_entity_set( parent_set, ABQ_ELEMENT_SET, element_set_name, element_set );
01252         MB_RETURN_IF_FAIL;
01253 
01254         status = mdbImpl->add_entities( element_set, element_range );
01255         MB_RETURN_IF_FAIL;
01256 
01257         // This ad-hoc element set doesn't know its:
01258         // * part_set (probably parent_set)
01259         // * instance_set (probably not defined)
01260         // * assembly_set (probably not defined)
01261     }
01262 
01263     return MB_SUCCESS;
01264 }
01265 
01266 ErrorCode ReadABAQUS::read_node_list( EntityHandle parent_set, EntityHandle assembly_set )
01267 {
01268     ErrorCode status;
01269 
01270     std::vector< std::string > tokens;
01271     std::map< std::string, std::string > params;
01272     std::map< std::string, abaqus_node_params > allowableParams;
01273 
01274     allowableParams[ABQ_AMBIGUOUS] = abq_node_ambiguous;
01275     allowableParams["NSET"]        = abq_node_nset;
01276     allowableParams["SYSTEM"]      = abq_node_system;
01277 
01278     abaqus_node_params param;
01279 
01280     bool make_node_set = false;
01281     std::string node_set_name;
01282 
01283     char coord_system = 'R';
01284 
01285     // Tokenize last line read
01286     tokenize( readline, tokens, ",\n" );
01287     extract_keyword_parameters( tokens, params );
01288 
01289     // std::cout << "\tAdding NODES"  << std::endl; // REMOVE
01290 
01291     // Process parameters
01292     for( std::map< std::string, std::string >::iterator thisParam = params.begin(); thisParam != params.end();
01293          ++thisParam )
01294     {
01295         // Look for unambiguous match with this node parameter
01296         param = allowableParams[match( ( *thisParam ).first, allowableParams )];
01297         switch( param )
01298         {
01299             case abq_node_nset:
01300                 make_node_set = true;
01301                 node_set_name = ( *thisParam ).second;
01302                 break;
01303             case abq_node_system:
01304                 // Store coordinate system
01305                 coord_system = ( *thisParam ).second[0];
01306                 break;
01307             case abq_node_ambiguous:
01308                 // std::cout << "\t\tIgnoring ambiguous NODE parameter: " << (*thisParam).first
01309                 //          << "=" << (*thisParam).second << std::endl;
01310                 break;
01311             default:
01312                 // std::cout << "\t\tIgnoring unsupported NODE parameter: " << (*thisParam).first
01313                 //          << "=" << (*thisParam).second << std::endl;
01314                 break;
01315         }
01316     }
01317 
01318     std::vector< double > coord_list;
01319     std::vector< int > node_ids;
01320 
01321     next_line_type = get_next_line_type();
01322 
01323     while( next_line_type != abq_eof && next_line_type != abq_keyword_line )
01324     {
01325         if( abq_data_line == next_line_type )
01326         {
01327             tokenize( readline, tokens, ", \n" );
01328             if( tokens.size() < 4 )
01329             {
01330                 MB_SET_ERR( MB_FAILURE, "Not enough data on node data line" );
01331             }
01332             node_ids.push_back( atoi( tokens[0].c_str() ) );
01333             for( unsigned int i = 1; i < 4; i++ )
01334                 coord_list.push_back( atof( tokens[i].c_str() ) );
01335         }
01336 
01337         next_line_type = get_next_line_type();
01338     }
01339 
01340     unsigned int num_nodes = node_ids.size();
01341 
01342     // Transform coordinate systems
01343     switch( coord_system )
01344     {
01345         case 'R':
01346             break;
01347         case 'C':
01348             cyl2rect( coord_list );
01349             break;
01350         case 'S':
01351             sph2rect( coord_list );
01352             break;
01353         default:
01354             // std::cout << "Treating undefined coordinate system: " << coord_system
01355             //          << " as rectangular/Cartesian." << std::endl;
01356             break;
01357     }
01358 
01359     // Get and fill coordinate arrays
01360     std::vector< double* > coord_arrays( 3 );
01361     EntityHandle start_node = 0;
01362     status                  = readMeshIface->get_node_coords( 3, num_nodes, MB_START_ID, start_node, coord_arrays );
01363     MB_RETURN_IF_FAIL;
01364 
01365     if( 0 == start_node ) return MB_FAILURE;
01366 
01367     // Cppcheck warning (false positive): variable coord_arrays is assigned a value that is never
01368     // used
01369     for( unsigned int idx = 0; idx < num_nodes; idx++ )
01370     {
01371         coord_arrays[0][idx] = coord_list[idx * 3];
01372         coord_arrays[1][idx] = coord_list[idx * 3 + 1];
01373         coord_arrays[2][idx] = coord_list[idx * 3 + 2];
01374     }
01375 
01376     Range node_range( start_node, start_node + num_nodes - 1 );
01377     // Add nodes to file_set
01378     // status = mdbImpl->add_entities(file_set, node_range);
01379     // MB_RETURN_IF_FAIL;
01380 
01381     // Add nodes to this parent_set
01382     status = mdbImpl->add_entities( parent_set, node_range );
01383     MB_RETURN_IF_FAIL;
01384 
01385     // Tag nodes with their local ID's
01386     status = mdbImpl->tag_set_data( mLocalIDTag, node_range, &node_ids[0] );
01387     MB_RETURN_IF_FAIL;
01388 
01389     if( assembly_set )
01390     {
01391         status = mdbImpl->add_entities( assembly_set, node_range );
01392         MB_RETURN_IF_FAIL;
01393 
01394         std::vector< EntityHandle > tmp_assembly_handles;
01395         tmp_assembly_handles.assign( node_range.size(), assembly_set );
01396         status = mdbImpl->tag_set_data( mAssemblyHandleTag, node_range, &( tmp_assembly_handles[0] ) );
01397         MB_RETURN_IF_FAIL;
01398     }
01399 
01400     // These nodes don't know their instance_set (probably not defined)
01401 
01402     if( make_node_set )
01403     {
01404         EntityHandle node_set;
01405 
01406         status = add_entity_set( parent_set, ABQ_NODE_SET, node_set_name, node_set );
01407         MB_RETURN_IF_FAIL;
01408 
01409         status = mdbImpl->add_entities( node_set, node_range );
01410         MB_RETURN_IF_FAIL;
01411 
01412         // This ad-hoc node set doesn't know its:
01413         // * part_set (probably parent_set)
01414         // * instance_set (probably not defined)
01415         // * assembly_set (probably not defined)
01416     }
01417 
01418     return MB_SUCCESS;
01419 }
01420 
01421 // SET CREATION & ACCESS UTILITIES
01422 
01423 ErrorCode ReadABAQUS::get_elements_by_id( EntityHandle parent_set,
01424                                           std::vector< int > element_ids_subset,
01425                                           Range& element_range )
01426 {
01427     ErrorCode status;
01428     Range all_elements;
01429 
01430     status = get_set_elements( parent_set, all_elements );
01431     MB_RETURN_IF_FAIL;
01432 
01433     std::vector< int > element_ids( all_elements.size() );
01434     status = mdbImpl->tag_get_data( mLocalIDTag, all_elements, &element_ids[0] );
01435     MB_RETURN_IF_FAIL;
01436 
01437     std::map< int, EntityHandle > elementIdMap;
01438     for( unsigned int idx = 0; idx < all_elements.size(); idx++ )
01439         elementIdMap[element_ids[idx]] = all_elements[idx];
01440 
01441     for( std::vector< int >::iterator element = element_ids_subset.begin(); element != element_ids_subset.end();
01442          ++element )
01443         element_range.insert( elementIdMap[*element] );
01444 
01445     return MB_SUCCESS;
01446 }
01447 
01448 ErrorCode ReadABAQUS::get_nodes_by_id( EntityHandle parent_set, std::vector< int > node_ids_subset, Range& node_range )
01449 {
01450     ErrorCode status;
01451 
01452     Range all_nodes;
01453     status = mdbImpl->get_entities_by_type( parent_set, MBVERTEX, all_nodes );
01454     MB_RETURN_IF_FAIL;
01455 
01456     std::vector< int > node_ids( all_nodes.size() );
01457     status = mdbImpl->tag_get_data( mLocalIDTag, all_nodes, &node_ids[0] );
01458     MB_RETURN_IF_FAIL;
01459 
01460     std::map< int, EntityHandle > nodeIdMap;
01461     for( unsigned int idx = 0; idx < all_nodes.size(); idx++ )
01462         nodeIdMap[node_ids[idx]] = all_nodes[idx];
01463 
01464     for( std::vector< int >::iterator node = node_ids_subset.begin(); node != node_ids_subset.end(); ++node )
01465         node_range.insert( nodeIdMap[*node] );
01466 
01467     return MB_SUCCESS;
01468 }
01469 
01470 ErrorCode ReadABAQUS::get_set_by_name( EntityHandle parent_set,
01471                                        int ABQ_set_type,
01472                                        const std::string& set_name,
01473                                        EntityHandle& set_handle )
01474 {
01475     ErrorCode status;
01476 
01477     char this_set_name[ABAQUS_SET_NAME_LENGTH];
01478 
01479     set_handle = 0;
01480 
01481     Range sets;
01482     void* tag_data[] = { &ABQ_set_type };
01483     status = mdbImpl->get_entities_by_type_and_tag( parent_set, MBENTITYSET, &mSetTypeTag, tag_data, 1, sets );MB_CHK_SET_ERR( status, "Did not find any sets of that type" );
01484 
01485     for( Range::iterator this_set = sets.begin(); this_set != sets.end() && 0 == set_handle; ++this_set )
01486     {
01487         std::fill( this_set_name, this_set_name + ABAQUS_SET_NAME_LENGTH, '\0' );
01488         status = mdbImpl->tag_get_data( mSetNameTag, &( *this_set ), 1, &this_set_name[0] );
01489         if( MB_SUCCESS != status && MB_TAG_NOT_FOUND != status ) return status;
01490 
01491         if( set_name == std::string( this_set_name ) ) set_handle = *this_set;
01492     }
01493 
01494     if( 0 == set_handle )
01495     {
01496         MB_SET_ERR( MB_FAILURE, "Did not find requested set" );
01497     }
01498 
01499     return MB_SUCCESS;
01500 }
01501 
01502 ErrorCode ReadABAQUS::get_set_elements( EntityHandle set_handle, Range& element_range )
01503 {
01504     ErrorCode status;
01505 
01506     Range dim_ent_list;
01507 
01508     // Could have elements of multiple dimensions in this set???
01509     for( int dim = 1; dim <= 3; dim++ )
01510     {
01511         dim_ent_list.clear();
01512         status = mdbImpl->get_entities_by_dimension( set_handle, dim, dim_ent_list );
01513         MB_RETURN_IF_FAIL;
01514 
01515         element_range.merge( dim_ent_list );
01516     }
01517 
01518     return MB_SUCCESS;
01519 }
01520 
01521 ErrorCode ReadABAQUS::get_set_elements_by_name( EntityHandle parent_set,
01522                                                 int ABQ_set_type,
01523                                                 const std::string& set_name,
01524                                                 Range& element_range )
01525 {
01526     ErrorCode status;
01527 
01528     EntityHandle set_handle;
01529     status = get_set_by_name( parent_set, ABQ_set_type, set_name, set_handle );
01530     MB_RETURN_IF_FAIL;
01531 
01532     status = get_set_elements( set_handle, element_range );
01533     MB_RETURN_IF_FAIL;
01534 
01535     if( element_range.size() == 0 )
01536     {
01537         // std::cout << "No elements were found in set " << set_name << std::endl;
01538     }
01539 
01540     return MB_SUCCESS;
01541 }
01542 
01543 ErrorCode ReadABAQUS::get_set_nodes( EntityHandle parent_set,
01544                                      int ABQ_set_type,
01545                                      const std::string& set_name,
01546                                      Range& node_range )
01547 {
01548     ErrorCode status;
01549 
01550     EntityHandle set_handle;
01551     status = get_set_by_name( parent_set, ABQ_set_type, set_name, set_handle );
01552     MB_RETURN_IF_FAIL;
01553 
01554     Range ent_list;
01555     Range dim_ent_list;
01556     // Could have elements of multiple dimensions in this set???
01557     for( int dim = 0; dim <= 3; dim++ )
01558     {
01559         dim_ent_list.clear();
01560         status = mdbImpl->get_entities_by_dimension( set_handle, dim, dim_ent_list );
01561         MB_RETURN_IF_FAIL;
01562 
01563         ent_list.merge( dim_ent_list );
01564     }
01565 
01566     status = mdbImpl->get_adjacencies( ent_list, 0, false, node_range );
01567     MB_RETURN_IF_FAIL;
01568 
01569     if( node_range.size() == 0 )
01570     {
01571         std::cout << "No nodes were found in set " << set_name << std::endl;
01572     }
01573 
01574     return MB_SUCCESS;
01575 }
01576 
01577 Tag ReadABAQUS::get_tag( const char* tag_name,
01578                          int tag_size,
01579                          TagType tag_type,
01580                          DataType tag_data_type,
01581                          const void* def_val )
01582 {
01583     Tag retval;
01584 
01585     ErrorCode rval =
01586         mdbImpl->tag_get_handle( tag_name, tag_size, tag_data_type, retval, tag_type | MB_TAG_CREAT, def_val );
01587     assert( MB_SUCCESS == rval );
01588     return MB_SUCCESS == rval ? retval : 0;
01589 }
01590 
01591 ErrorCode ReadABAQUS::create_instance_of_part( const EntityHandle file_set,
01592                                                const EntityHandle assembly_set,
01593                                                const std::string& part_name,
01594                                                const std::string& /*instance_name*/,
01595                                                EntityHandle& instance_set,
01596                                                const std::vector< double >& translation,
01597                                                const std::vector< double >& rotation )
01598 {
01599     ErrorCode status;
01600 
01601     EntityHandle part_set;
01602     status = get_set_by_name( file_set, ABQ_PART_SET, part_name, part_set );
01603     MB_RETURN_IF_FAIL;
01604 
01605     // Cross-reference
01606     status = mdbImpl->tag_set_data( mPartHandleTag, &instance_set, 1, &part_set );
01607     MB_RETURN_IF_FAIL;
01608 
01609     int instance_id = ++num_part_instances[part_set];
01610     status          = mdbImpl->tag_set_data( mInstancePIDTag, &instance_set, 1, &instance_id );
01611     MB_RETURN_IF_FAIL;
01612 
01613     status = mdbImpl->tag_set_data( mAssemblyHandleTag, &instance_set, 1, &assembly_set );
01614     MB_RETURN_IF_FAIL;
01615 
01616     instance_id = ++num_assembly_instances[assembly_set];
01617     status      = mdbImpl->tag_set_data( mInstanceGIDTag, &instance_set, 1, &instance_id );
01618     MB_RETURN_IF_FAIL;
01619 
01620     // Create maps to cross-reference the part and instance versions of each entity
01621     std::map< EntityHandle, EntityHandle > p2i_nodes, p2i_elements;
01622 
01623     // ---- NODES ----
01624 
01625     // Get all nodes and IDs
01626     Range part_node_list;
01627     status = mdbImpl->get_entities_by_dimension( part_set, 0, part_node_list );
01628     MB_RETURN_IF_FAIL;
01629 
01630     if( 0 < part_node_list.size() )
01631     {
01632         std::vector< int > node_ids( part_node_list.size() );
01633         status = mdbImpl->tag_get_data( mLocalIDTag, part_node_list, &node_ids[0] );
01634         MB_RETURN_IF_FAIL;
01635 
01636         // std::map<int, EntityHandle> nodeIdMap;
01637         // for (unsigned int idx = 0; idx < part_node_list.size(); idx++)
01638         // nodeIdMap[node_ids[idx]] = part_node_list[idx];
01639 
01640         // Create new nodes
01641         std::vector< double* > coord_arrays( 3 );
01642         EntityHandle start_node = 0;
01643         status = readMeshIface->get_node_coords( 3, part_node_list.size(), MB_START_ID, start_node, coord_arrays );
01644         MB_RETURN_IF_FAIL;
01645 
01646         if( 0 == start_node ) return MB_FAILURE;
01647 
01648         // Copy coordinates into new coord_arrays
01649         status = mdbImpl->get_coords( part_node_list, coord_arrays[0], coord_arrays[1], coord_arrays[2] );
01650 
01651         // Rotate to new position
01652         double rot_axis[3];
01653         rot_axis[0] = rotation[3] - rotation[0];
01654         rot_axis[1] = rotation[4] - rotation[1];
01655         rot_axis[2] = rotation[5] - rotation[2];
01656 
01657         AffineXform rotationXform;
01658         if( rotation[6] != 0 ) rotationXform = AffineXform::rotation( rotation[6] * DEG2RAD, rot_axis );
01659 
01660         // Translate to new position
01661         for( unsigned int idx = 0; idx < part_node_list.size(); idx++ )
01662         {
01663             double coords[3];
01664 
01665             // Transform to new location and then shift origin of rotation
01666             for( unsigned int dim = 0; dim < 3; dim++ )
01667                 coords[dim] = coord_arrays[dim][idx] + translation[dim] - rotation[dim];
01668 
01669             // Rotate around this origin
01670             if( rotation[6] != 0 ) rotationXform.xform_vector( coords );
01671 
01672             // Transform origin of rotation back
01673             for( unsigned int dim = 0; dim < 3; dim++ )
01674                 coord_arrays[dim][idx] = coords[dim] + rotation[dim];
01675         }
01676 
01677         Range instance_node_list( start_node, start_node + part_node_list.size() - 1 );
01678 
01679         // (DO NOT) add nodes to file_set
01680         // status = mdbImpl->add_entities(file_set, instance_node_list);
01681         // MB_RETURN_IF_FAIL;
01682 
01683         // Add nodes to this instance_set
01684         status = mdbImpl->add_entities( instance_set, instance_node_list );
01685         MB_RETURN_IF_FAIL;
01686 
01687         // Add nodes to this assembly_set
01688         status = mdbImpl->add_entities( assembly_set, instance_node_list );
01689         MB_RETURN_IF_FAIL;
01690 
01691         // Tag nodes with their local ID's
01692         status = mdbImpl->tag_set_data( mLocalIDTag, instance_node_list, &node_ids[0] );
01693         MB_RETURN_IF_FAIL;
01694 
01695         // Create a map of old handles to new handles!!!
01696         for( unsigned int idx = 0; idx < part_node_list.size(); idx++ )
01697             p2i_nodes[part_node_list[idx]] = instance_node_list[idx];
01698     }
01699 
01700     //  ---- ELEMENTS ----
01701 
01702     Range part_element_list;
01703     status = get_set_elements( part_set, part_element_list );
01704     MB_RETURN_IF_FAIL;
01705 
01706     if( 0 < part_element_list.size() )
01707     {
01708         std::vector< int > part_element_ids( part_element_list.size() );
01709         status = mdbImpl->tag_get_data( mLocalIDTag, part_element_list, &part_element_ids[0] );
01710         MB_RETURN_IF_FAIL;
01711 
01712         // std::map<int, EntityHandle> elementIdMap;
01713         // for (unsigned int idx = 0; idx < part_element_list.size(); idx++)
01714         // elementIdMap[part_element_ids[idx]] = part_element_list[idx];
01715 
01716         // Create new elements
01717         Range instance_element_list;
01718         instance_element_list.clear();
01719 
01720         // Cross-referencing storage and pointers/iterators
01721         std::vector< int > instance_element_ids;
01722         std::vector< int >::iterator part_element_id = part_element_ids.begin();
01723 
01724         for( Range::iterator part_element = part_element_list.begin(); part_element != part_element_list.end();
01725              ++part_element, ++part_element_id )
01726         {
01727             EntityType element_type = mdbImpl->type_from_handle( *part_element );
01728             std::vector< EntityHandle > part_connectivity, instance_connectivity;
01729             EntityHandle new_element;
01730             status = mdbImpl->get_connectivity( &( *part_element ), 1, part_connectivity );
01731             MB_RETURN_IF_FAIL;
01732 
01733             instance_connectivity.clear();
01734             for( std::vector< EntityHandle >::iterator connectivity_node = part_connectivity.begin();
01735                  connectivity_node != part_connectivity.end(); ++connectivity_node )
01736                 instance_connectivity.push_back( p2i_nodes[*connectivity_node] );
01737 
01738             status = mdbImpl->create_element( element_type, &instance_connectivity[0], instance_connectivity.size(),
01739                                               new_element );
01740             MB_RETURN_IF_FAIL;
01741 
01742             instance_element_list.insert( new_element );
01743             p2i_elements[*part_element] = new_element;
01744             instance_element_ids.push_back( *part_element_id );
01745         }
01746 
01747         // (DO NOT) add elements to file_set
01748         // status = mdbImpl->add_entities(file_set, instance_element_list);
01749         // MB_RETURN_IF_FAIL;
01750 
01751         // Add elements to this instance_set
01752         status = mdbImpl->add_entities( instance_set, instance_element_list );
01753         MB_RETURN_IF_FAIL;
01754 
01755         // Add elements to this assembly_set
01756         status = mdbImpl->add_entities( assembly_set, instance_element_list );
01757         MB_RETURN_IF_FAIL;
01758 
01759         // Tag elements with their local ID's
01760         status = mdbImpl->tag_set_data( mLocalIDTag, instance_element_list, &( instance_element_ids[0] ) );
01761         MB_RETURN_IF_FAIL;
01762     }
01763 
01764     // ----- NODE SETS -----
01765 
01766     // Get all node sets in part
01767     Range part_node_sets;
01768     int tag_val      = ABQ_NODE_SET;
01769     void* tag_data[] = { &tag_val };
01770     status = mdbImpl->get_entities_by_type_and_tag( part_set, MBENTITYSET, &mSetTypeTag, tag_data, 1, part_node_sets );
01771     MB_RETURN_IF_FAIL;
01772 
01773     Range part_node_set_list, instance_node_set_list;
01774     for( Range::iterator part_node_set = part_node_sets.begin(); part_node_set != part_node_sets.end();
01775          ++part_node_set )
01776     {
01777         char node_set_name[ABAQUS_SET_NAME_LENGTH];
01778         std::fill( node_set_name, node_set_name + ABAQUS_SET_NAME_LENGTH, '\0' );
01779         status = mdbImpl->tag_get_data( mSetNameTag, &( *part_node_set ), 1, &node_set_name[0] );
01780         if( MB_SUCCESS != status && MB_TAG_NOT_FOUND != status ) return status;
01781 
01782         part_node_set_list.clear();
01783         status = mdbImpl->get_entities_by_dimension( *part_node_set, 0, part_node_set_list );
01784 
01785         instance_node_set_list.clear();
01786         for( Range::iterator set_node = part_node_set_list.begin(); set_node != part_node_set_list.end(); ++set_node )
01787             instance_node_set_list.insert( p2i_nodes[*set_node] );
01788 
01789         EntityHandle instance_node_set;
01790 
01791         status = add_entity_set( instance_set, ABQ_NODE_SET, node_set_name, instance_node_set );
01792         MB_RETURN_IF_FAIL;
01793 
01794         status = mdbImpl->add_entities( instance_node_set, instance_node_set_list );
01795         MB_RETURN_IF_FAIL;
01796 
01797         status = mdbImpl->add_entities( assembly_set, &instance_node_set, 1 );
01798         MB_RETURN_IF_FAIL;
01799 
01800         status = mdbImpl->tag_set_data( mPartHandleTag, &instance_node_set, 1, &part_set );
01801         MB_RETURN_IF_FAIL;
01802 
01803         status = mdbImpl->tag_set_data( mAssemblyHandleTag, &instance_node_set, 1, &assembly_set );
01804         MB_RETURN_IF_FAIL;
01805     }
01806 
01807     // ----- ELEMENT SETS -----
01808 
01809     // Get all element sets in part
01810     Range part_element_sets;
01811     tag_val     = ABQ_ELEMENT_SET;
01812     tag_data[0] = &tag_val;
01813     status =
01814         mdbImpl->get_entities_by_type_and_tag( part_set, MBENTITYSET, &mSetTypeTag, tag_data, 1, part_element_sets );
01815     MB_RETURN_IF_FAIL;
01816 
01817     Range part_element_set_list, instance_element_set_list;
01818     for( Range::iterator part_element_set = part_element_sets.begin(); part_element_set != part_element_sets.end();
01819          ++part_element_set )
01820     {
01821         char element_set_name[ABAQUS_SET_NAME_LENGTH];
01822         std::fill( element_set_name, element_set_name + ABAQUS_SET_NAME_LENGTH, '\0' );
01823         status = mdbImpl->tag_get_data( mSetNameTag, &( *part_element_set ), 1, &element_set_name[0] );
01824         if( MB_SUCCESS != status && MB_TAG_NOT_FOUND != status ) return status;
01825 
01826         part_element_set_list.clear();
01827         status = get_set_elements( *part_element_set, part_element_set_list );
01828 
01829         instance_element_set_list.clear();
01830         for( Range::iterator set_element = part_element_set_list.begin(); set_element != part_element_set_list.end();
01831              ++set_element )
01832             instance_element_set_list.insert( p2i_elements[*set_element] );
01833 
01834         EntityHandle instance_element_set;
01835         status = add_entity_set( instance_set, ABQ_ELEMENT_SET, element_set_name, instance_element_set );
01836         MB_RETURN_IF_FAIL;
01837 
01838         // std::cerr << instance_set << "\t" << instance_element_set << std::endl;
01839         status = mdbImpl->add_entities( instance_element_set, instance_element_set_list );
01840         MB_RETURN_IF_FAIL;
01841 
01842         status = mdbImpl->add_entities( assembly_set, &instance_element_set, 1 );
01843         MB_RETURN_IF_FAIL;
01844 
01845         // status = mdbImpl->add_entities(file_set, &instance_element_set, 1);
01846         // MB_RETURN_IF_FAIL;
01847 
01848         status = mdbImpl->tag_set_data( mPartHandleTag, &instance_element_set, 1, &part_set );
01849         MB_RETURN_IF_FAIL;
01850 
01851         status = mdbImpl->tag_set_data( mAssemblyHandleTag, &instance_element_set, 1, &assembly_set );
01852         MB_RETURN_IF_FAIL;
01853 
01854         char element_set_matname[ABAQUS_SET_NAME_LENGTH];
01855         std::fill( element_set_matname, element_set_matname + ABAQUS_SET_NAME_LENGTH, '\0' );
01856         status = mdbImpl->tag_get_data( mMatNameTag, &( *part_element_set ), 1, &element_set_matname[0] );
01857         if( MB_SUCCESS != status && MB_TAG_NOT_FOUND != status ) return status;
01858 
01859         if( MB_TAG_NOT_FOUND != status )
01860         {
01861             status = mdbImpl->tag_set_data( mMatNameTag, &instance_element_set, 1, element_set_matname );
01862             MB_RETURN_IF_FAIL;
01863         }
01864 
01865         int element_set_mat_id;
01866         status = mdbImpl->tag_get_data( mMaterialSetTag, &( *part_element_set ), 1, &element_set_mat_id );
01867         if( MB_SUCCESS != status && MB_TAG_NOT_FOUND != status ) return status;
01868 
01869         if( MB_TAG_NOT_FOUND != status )
01870         {
01871             status = mdbImpl->tag_set_data( mMaterialSetTag, &instance_element_set, 1, &element_set_mat_id );
01872             MB_RETURN_IF_FAIL;
01873         }
01874     }
01875 
01876     // Tag everything with their instance handle
01877     // some nodes are assigned outside of this routine so query final list of all
01878     // instance nodes, elements, etc
01879     Range instance_entity_list;
01880     status = mdbImpl->get_entities_by_dimension( instance_set, 0, instance_entity_list );
01881     MB_RETURN_IF_FAIL;
01882 
01883     std::vector< EntityHandle > tmp_instance_handles;
01884     tmp_instance_handles.assign( instance_entity_list.size(), instance_set );
01885     status = mdbImpl->tag_set_data( mInstanceHandleTag, instance_entity_list, &tmp_instance_handles[0] );
01886     MB_RETURN_IF_FAIL;
01887 
01888     instance_entity_list.clear();
01889     status = get_set_elements( instance_set, instance_entity_list );
01890     MB_RETURN_IF_FAIL;
01891 
01892     tmp_instance_handles.clear();
01893     tmp_instance_handles.assign( instance_entity_list.size(), instance_set );
01894     status = mdbImpl->tag_set_data( mInstanceHandleTag, instance_entity_list, &tmp_instance_handles[0] );
01895     MB_RETURN_IF_FAIL;
01896 
01897     // Get all node sets in instance
01898     instance_entity_list.clear();
01899     tag_val     = ABQ_NODE_SET;
01900     tag_data[0] = &tag_val;
01901     status      = mdbImpl->get_entities_by_type_and_tag( instance_set, MBENTITYSET, &mSetTypeTag, tag_data, 1,
01902                                                          instance_entity_list );
01903     MB_RETURN_IF_FAIL;
01904 
01905     tmp_instance_handles.clear();
01906     tmp_instance_handles.assign( instance_entity_list.size(), instance_set );
01907     status = mdbImpl->tag_set_data( mInstanceHandleTag, instance_entity_list, &tmp_instance_handles[0] );
01908     MB_RETURN_IF_FAIL;
01909 
01910     // Get all element sets in part
01911     instance_entity_list.clear();
01912     tag_val     = ABQ_ELEMENT_SET;
01913     tag_data[0] = &tag_val;
01914     status      = mdbImpl->get_entities_by_type_and_tag( instance_set, MBENTITYSET, &mSetTypeTag, tag_data, 1,
01915                                                          instance_entity_list );
01916     MB_RETURN_IF_FAIL;
01917 
01918     tmp_instance_handles.clear();
01919     tmp_instance_handles.assign( instance_entity_list.size(), instance_set );
01920     status = mdbImpl->tag_set_data( mInstanceHandleTag, instance_entity_list, &tmp_instance_handles[0] );
01921     MB_RETURN_IF_FAIL;
01922 
01923     return MB_SUCCESS;
01924 }
01925 
01926 ErrorCode ReadABAQUS::add_entity_set( EntityHandle parent_set,
01927                                       int ABQ_Set_Type,
01928                                       const std::string& set_name,
01929                                       EntityHandle& entity_set )
01930 {
01931     ErrorCode status;
01932 
01933     status = mdbImpl->create_meshset( MESHSET_SET, entity_set );
01934     MB_RETURN_IF_FAIL;
01935 
01936     status = mdbImpl->tag_set_data( mSetTypeTag, &entity_set, 1, &ABQ_Set_Type );
01937     MB_RETURN_IF_FAIL;
01938 
01939     status = mdbImpl->tag_set_data( mSetNameTag, &entity_set, 1, set_name.c_str() );
01940     MB_RETURN_IF_FAIL;
01941 
01942     status = mdbImpl->add_entities( parent_set, &entity_set, 1 );
01943     MB_RETURN_IF_FAIL;
01944 
01945     return MB_SUCCESS;
01946 }
01947 
01948 void ReadABAQUS::cyl2rect( std::vector< double > coord_list )
01949 {
01950     int num_nodes = coord_list.size() / 3;
01951     double x, y, r, t;
01952 
01953     for( int node = 0; node < num_nodes; node++ )
01954     {
01955         r = coord_list[3 * node];
01956         t = coord_list[3 * node + 1] * DEG2RAD;
01957 
01958         x = r * cos( t );
01959         y = r * sin( t );
01960 
01961         coord_list[3 * node]     = x;
01962         coord_list[3 * node + 1] = y;
01963     }
01964 }
01965 
01966 void ReadABAQUS::sph2rect( std::vector< double > coord_list )
01967 {
01968     int num_nodes = coord_list.size() / 3;
01969     double x, y, z, r, t, p;
01970 
01971     for( int node = 0; node < num_nodes; node++ )
01972     {
01973         r = coord_list[3 * node];
01974         t = coord_list[3 * node + 1] * DEG2RAD;
01975         p = coord_list[3 * node + 2] * DEG2RAD;
01976 
01977         x = r * cos( p ) * cos( t );
01978         y = r * cos( p ) * sin( t );
01979         z = r * sin( p );
01980 
01981         coord_list[3 * node]     = x;
01982         coord_list[3 * node + 1] = y;
01983         coord_list[3 * node + 2] = z;
01984     }
01985 }
01986 
01987 // PARSING RECOGNITION
01988 
01989 abaqus_line_types ReadABAQUS::get_next_line_type()
01990 {
01991     readline.clear();
01992     std::getline( abFile, readline );
01993     ++lineNo;
01994 
01995     if( abFile.eof() ) return abq_eof;
01996 
01997     std::string::size_type pos = readline.find_first_not_of( ' ' );
01998 
01999     if( std::string::npos == pos ) return abq_blank_line;
02000 
02001     if( '*' == readline[pos] )
02002         if( '*' == readline[pos + 1] )
02003             return abq_comment_line;
02004         else
02005             return abq_keyword_line;
02006     else
02007         return abq_data_line;
02008 }
02009 
02010 abaqus_keyword_type ReadABAQUS::get_keyword()
02011 {
02012     std::vector< std::string > tokens;
02013     std::map< std::string, abaqus_keyword_type > keywords;
02014 
02015     // Set up list of supported keywords
02016     // Note: any attempt to match something not in the keyword list
02017     //       using the [] operator will create a new entry in the map
02018     //       but that entry will have value abq_undefined based on the
02019     //       definition of the abaqus_keyword_type enum.
02020     keywords[ABQ_AMBIGUOUS]   = abq_ambiguous;
02021     keywords["HEADING"]       = abq_heading;
02022     keywords["PART"]          = abq_part;
02023     keywords["END PART"]      = abq_end_part;
02024     keywords["ASSEMBLY"]      = abq_assembly;
02025     keywords["END ASSEMBLY"]  = abq_end_assembly;
02026     keywords["NODE"]          = abq_node;
02027     keywords["ELEMENT"]       = abq_element;
02028     keywords["NSET"]          = abq_nset;
02029     keywords["ELSET"]         = abq_elset;
02030     keywords["SOLID SECTION"] = abq_solid_section;
02031     keywords["INSTANCE"]      = abq_instance;
02032     keywords["END INSTANCE"]  = abq_end_instance;
02033 
02034     tokenize( readline, tokens, "*,\n" );
02035 
02036     // Convert to upper case and test for unambiguous match/partial match
02037     stringToUpper( tokens[0], tokens[0] );
02038     return keywords[match( tokens[0], keywords )];
02039 }
02040 
02041 // PARSING UTILITY FUNCTIONS
02042 
02043 // For a map of strings to values of type T
02044 // search the key list of the map for an unambiguous partial match with the token
02045 template < typename T >
02046 std::string ReadABAQUS::match( const std::string& token, std::map< std::string, T >& tokenList )
02047 {
02048     // Initialize with no match and ABQ_UNDEFINED as return string
02049     bool found_match       = false;
02050     std::string best_match = ABQ_UNDEFINED;
02051 
02052     // Search the map
02053     for( typename std::map< std::string, T >::iterator thisToken = tokenList.begin(); thisToken != tokenList.end();
02054          ++thisToken )
02055     {
02056         // If a perfect match break the loop (assume keyword list is unambiguous)
02057         if( token == ( *thisToken ).first )
02058         {
02059             best_match = token;
02060             break;
02061         }
02062         else
02063         {
02064             int short_length =
02065                 ( token.length() < ( *thisToken ).first.length() ? token.length() : ( *thisToken ).first.length() );
02066             // If the token matches the first token.length() characters of the keyword
02067             // consider this a match
02068             if( token.substr( short_length ) == ( *thisToken ).first.substr( short_length ) )
02069             {
02070                 if( !found_match )
02071                 {
02072                     // If no match already, record match and matching keyword
02073                     found_match = true;
02074                     best_match  = ( *thisToken ).first;
02075                 }
02076                 else
02077                     // If match already set matching keyword to ABQ_AMBIGUOUS
02078                     best_match = ABQ_AMBIGUOUS;
02079             }
02080         }
02081     }
02082 
02083     // Possible return values: ABQ_UNDEFINED, keyword from list, ABQ_AMBIGUOUS
02084     return best_match;
02085 }
02086 
02087 // Convert a string to upper case
02088 void ReadABAQUS::stringToUpper( const std::string& toBeConverted, std::string& converted )
02089 {
02090     converted = toBeConverted;
02091 
02092     for( unsigned int i = 0; i < toBeConverted.length(); i++ )
02093         converted[i] = toupper( toBeConverted[i] );
02094 }
02095 
02096 // Extract key/value pairs from parameter list
02097 void ReadABAQUS::extract_keyword_parameters( const std::vector< std::string >& tokens,
02098                                              std::map< std::string, std::string >& params )
02099 {
02100     std::string key, value;
02101 
02102     // NOTE: skip first token - it is the keyword
02103     for( std::vector< std::string >::const_iterator token = tokens.begin() + 1; token != tokens.end(); ++token )
02104     {
02105         std::string::size_type pos = token->find( '=' );
02106         stringToUpper( token->substr( 0, pos ), key );
02107         if( std::string::npos != pos )
02108             value = token->substr( pos + 1 );
02109         else
02110             value = "";
02111         pos         = key.find_first_not_of( ' ', 0 );
02112         key         = key.substr( pos );
02113         params[key] = value;
02114     }
02115 }
02116 
02117 // Tokenize a string based on a set of possible delimiters
02118 void ReadABAQUS::tokenize( const std::string& str, std::vector< std::string >& tokens, const char* delimiters )
02119 {
02120     tokens.clear();
02121 
02122     std::string::size_type pos, last = str.find_first_not_of( delimiters, 0 );
02123 
02124     while( std::string::npos != last )
02125     {
02126         pos = str.find_first_of( delimiters, last );
02127         if( std::string::npos == pos )
02128         {
02129             tokens.push_back( str.substr( last ) );
02130             last = std::string::npos;
02131         }
02132         else
02133         {
02134             tokens.push_back( str.substr( last, pos - last ) );
02135             last = str.find_first_not_of( delimiters, pos );
02136         }
02137     }
02138 }
02139 
02140 }  // namespace moab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines