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