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