Mesh Oriented datABase  (version 5.5.0)
An array-based unstructured mesh library
ReadABAQUS.cpp
Go to the documentation of this file.
1 /**
2  * MOAB, a Mesh-Oriented datABase, is a software component for creating,
3  * storing and accessing finite element mesh data.
4  *
5  * Copyright 2004 Sandia Corporation. Under the terms of Contract
6  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
7  * retains certain rights in this software.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  */
15 
16 #ifdef WIN32
17 #pragma warning( disable : 4786 )
18 #endif
19 
20 #include "ReadABAQUS.hpp"
21 
22 #include <algorithm>
23 #include <ctime>
24 #include <string>
25 #include <cassert>
26 #include <cstdio>
27 #include <cmath>
28 
29 #include "moab/Range.hpp"
30 #include "moab/Interface.hpp"
31 #include "MBTagConventions.hpp"
32 #include "Internals.hpp"
33 #include "moab/ReadUtilIface.hpp"
34 #include "AffineXform.hpp"
35 // #include "abaqus_order.h"
36 #include "moab/FileOptions.hpp"
37 
38 namespace moab
39 {
40 
41 #define ABQ_AMBIGUOUS "AMBIGUOUS"
42 #define ABQ_UNDEFINED "UNDEFINED"
43 #define DEG2RAD 0.017453292519943295769236907684886
44 
45 #define MB_RETURN_IF_FAIL \
46  if( MB_SUCCESS != status ) return status
47 
49 {
50  return new ReadABAQUS( iface );
51 }
52 
54  : mdbImpl( impl ), readMeshIface( NULL ), lineNo( 0 ), next_line_type( abq_undefined_line ), mat_id( 0 )
55 {
56  assert( impl != NULL );
57  reset();
58 
60 
61  // Initialize in case tag_get_handle fails below
62  mMaterialSetTag = 0;
63  mDirichletSetTag = 0;
64  mNeumannSetTag = 0;
65  mHasMidNodesTag = 0;
66 
67  mSetTypeTag = 0;
68  mPartHandleTag = 0;
69  mInstancePIDTag = 0;
70  mInstanceGIDTag = 0;
71  mLocalIDTag = 0;
74  mSetNameTag = 0;
75  mMatNameTag = 0;
76 
77  //! Get and cache predefined tag handles
78  int negone = -1, negonearr[] = { -1, -1, -1, -1 };
83 
93 }
94 
96 
98 {
100  if( abFile.fail() ) abFile.close();
101 }
102 
103 /*
104 
105 ErrorCode ReadABAQUS::check_file_stats()
106 * check for existence of file
107 * initialize meshsets, and offsets if necessary
108 
109 */
110 
111 ErrorCode ReadABAQUS::read_tag_values( const char* /* file_name */,
112  const char* /* tag_name */,
113  const FileOptions& /* opts */,
114  std::vector< int >& /* tag_values_out */,
115  const SubsetList* /* subset_list */ )
116 {
117  return MB_NOT_IMPLEMENTED;
118 }
119 
120 ErrorCode ReadABAQUS::load_file( const char* abaqus_file_name,
121  const EntityHandle* file_set_ptr,
122  const FileOptions& /*opts*/,
123  const ReaderIface::SubsetList* subset_list,
124  const Tag* /*file_id_tag*/ )
125 {
126  ErrorCode status;
127 
128  if( subset_list )
129  {
130  MB_SET_ERR( MB_UNSUPPORTED_OPERATION, "Reading subset of files not supported for ABAQUS data" );
131  }
132 
133  // Open file
134  lineNo = 0;
135  abFile.open( abaqus_file_name );
136  if( !abFile ) return MB_FILE_DOES_NOT_EXIST;
137 
138  bool in_unsupported = false;
139 
140  EntityHandle file_set;
141  status = mdbImpl->create_meshset( MESHSET_SET, file_set );
142  if( MB_SUCCESS != status ) return status;
143 
145  while( next_line_type != abq_eof )
146  {
147  switch( next_line_type )
148  {
149  case abq_keyword_line:
150  in_unsupported = false;
151  switch( get_keyword() )
152  {
153  case abq_heading:
154  // Read header
155  status = read_heading( file_set );
156  break;
157  case abq_part:
158  // Read parts until done
159  status = read_part( file_set );
160  break;
161  case abq_assembly:
162  // Read assembly (or assemblies?)
163  status = read_assembly( file_set );
164  break;
165  default:
166  // Skip reading other content for now
167  // (e.g. material properties, loads, surface interactions, etc)
168  in_unsupported = true;
169  // std::cout << "Ignoring unsupported keyword: " << readline << std::endl;
170  }
172  break;
173  case abq_comment_line:
174  break;
175  case abq_data_line:
176  if( !in_unsupported )
177  {
178  MB_SET_ERR( MB_FAILURE, "Expected Keyword" );
179  }
180  break;
181  default:
182  MB_SET_ERR( MB_FAILURE, "Invalid/unrecognized line" );
183  }
184 
186  }
187 
188  // Temporary??? delete parts
189  // Get all node sets in part
190  Range part_sets;
191  int tag_val = ABQ_PART_SET;
192  void* tag_data[] = { &tag_val };
193  status = mdbImpl->get_entities_by_type_and_tag( file_set, MBENTITYSET, &mSetTypeTag, tag_data, 1, part_sets );
195 
196  for( Range::iterator part_set = part_sets.begin(); part_set != part_sets.end(); ++part_set )
197  {
198  Range ent_sets;
199  tag_val = ABQ_NODE_SET;
200  tag_data[0] = &tag_val;
201 
202  status = mdbImpl->get_entities_by_type_and_tag( *part_set, MBENTITYSET, &mSetTypeTag, tag_data, 1, ent_sets );
204 
205  status = mdbImpl->delete_entities( ent_sets );
207 
208  tag_val = ABQ_ELEMENT_SET;
209  tag_data[0] = &tag_val;
210 
211  status = mdbImpl->get_entities_by_type_and_tag( *part_set, MBENTITYSET, &mSetTypeTag, tag_data, 1, ent_sets );
213 
214  status = mdbImpl->delete_entities( ent_sets );
216 
217  Range node_list, ele_list;
218  status = get_set_elements( *part_set, ele_list );
220 
221  status = mdbImpl->delete_entities( ele_list );
223 
224  status = mdbImpl->get_entities_by_dimension( *part_set, 0, node_list );
226 
227  status = mdbImpl->delete_entities( node_list );
229  }
230 
231  if( file_set_ptr )
232  {
233  status = mdbImpl->unite_meshset( *file_set_ptr, file_set );
235  }
236 
237  return mdbImpl->delete_entities( &file_set, 1 );
238 }
239 
241 {
242  // Current line is only heading token. get next line
244 
245  // Perhaps keep first line and tag geometry with title?
246 
249 
250  return MB_SUCCESS;
251 }
252 
254 {
255  ErrorCode status = MB_SUCCESS;
256 
257  std::vector< std::string > tokens;
258  std::map< std::string, std::string > params;
259  std::map< std::string, abaqus_assembly_params > requiredParams;
260  requiredParams["NAME"] = abq_assembly_name;
261 
262  std::map< std::string, abaqus_assembly_params > allowableParams;
263  allowableParams[ABQ_AMBIGUOUS] = abq_assembly_ambiguous;
264 
266 
267  std::string assembly_name;
268 
269  // Tokenize last line read
270  tokenize( readline, tokens, ",\n" );
271  extract_keyword_parameters( tokens, params );
272 
273  // Search for required parameters
274  for( std::map< std::string, abaqus_assembly_params >::iterator thisParam = requiredParams.begin();
275  thisParam != requiredParams.end(); ++thisParam )
276  {
277  std::string param_key = match( ( *thisParam ).first, params );
278  param = requiredParams[param_key];
279  switch( param )
280  {
281  case abq_assembly_name:
282  assembly_name = params[param_key];
283  params.erase( param_key );
284  // std::cout << "Adding ASSEMBLY with name: " << assembly_name << std::endl; //
285  // REMOVE
286  break;
287  default:
288  // std::cout << "Missing required ASSEMBLY parameter " << (*thisParam).first <<
289  // std::endl;
290  return MB_FAILURE;
291  }
292  }
293 
294  // Process parameters
295  for( std::map< std::string, std::string >::iterator thisParam = params.begin(); thisParam != params.end();
296  ++thisParam )
297  {
298  // Look for unambiguous match with this node parameter
299  param = allowableParams[match( ( *thisParam ).first, allowableParams )];
300  switch( param )
301  {
303  // std::cout << "\tIgnoring ambiguous ASSEMBLY parameter: " << (*thisParam).first
304  // << "=" << (*thisParam).second << std::endl;
305  break;
306  default:
307  // std::cout << "\tIgnoring unsupported ASSEMBLY parameter: " << (*thisParam).first
308  // << "=" << (*thisParam).second << std::endl;
309  break;
310  }
311  }
312 
313  EntityHandle assembly_set;
314 
315  status = add_entity_set( file_set, ABQ_ASSEMBLY_SET, assembly_name, assembly_set );
316 
318 
319  bool end_assembly = false;
320  bool in_unsupported = false;
321 
322  while( next_line_type != abq_eof && !end_assembly )
323  {
324  switch( next_line_type )
325  {
326  case abq_keyword_line:
327  in_unsupported = false;
328  switch( get_keyword() )
329  {
330  case abq_end_assembly:
331  end_assembly = true;
332  break;
333  case abq_instance:
334  status = read_instance( assembly_set, file_set );
335  break;
336  case abq_nset:
337  status = read_node_set( assembly_set, file_set );
338  break;
339  default:
340  in_unsupported = true;
341  // std::cout << "\tIgnoring unsupported keyword in this ASSEMBLY: "
342  // << readline << std::endl;
344  break;
345  }
346  break;
347  case abq_comment_line:
349  break;
350  case abq_data_line:
351  if( !in_unsupported )
352  {
353  // std::cout << "Internal Error: Data lines not allowed in ASSEMBLY keyword."
354  // << std::endl << readline << std::endl;
355  return MB_FAILURE;
356  }
358  break;
359  case abq_blank_line:
360  // std::cout << "Error: Blank lines are not allowed." << std::endl;
361  return MB_FAILURE;
362  default:
363  // std::cout << "Error reading ASSEMBLY " << assembly_name << std::endl;
364  return MB_FAILURE;
365  }
367  }
368 
369  num_assembly_instances[assembly_set] = 0;
370 
371  return MB_SUCCESS;
372 }
373 
375 {
376  ErrorCode status = MB_SUCCESS;
377 
378  std::vector< std::string > tokens;
379  std::map< std::string, std::string > params;
380  std::map< std::string, abaqus_instance_params > requiredParams;
381  requiredParams["NAME"] = abq_instance_name;
382  requiredParams["PART"] = abq_instance_part;
383 
384  std::map< std::string, abaqus_instance_params > allowableParams;
385  allowableParams[ABQ_AMBIGUOUS] = abq_instance_ambiguous;
386 
388 
389  std::string instance_name, part_name;
390 
391  // Tokenize last line read
392  tokenize( readline, tokens, ",\n" );
393  extract_keyword_parameters( tokens, params );
394 
395  // Search for required parameters
396  for( std::map< std::string, abaqus_instance_params >::iterator thisParam = requiredParams.begin();
397  thisParam != requiredParams.end(); ++thisParam )
398  {
399  std::string param_key = match( ( *thisParam ).first, params );
400  param = requiredParams[param_key];
401  switch( param )
402  {
403  case abq_instance_name:
404  instance_name = params[param_key];
405  params.erase( param_key );
406  break;
407  case abq_instance_part:
408  part_name = params[param_key];
409  params.erase( param_key );
410  break;
411  default:
412  // std::cout << "Missing required INSTANCE parameter " << (*thisParam).first <<
413  // std::endl;
414  return MB_FAILURE;
415  }
416  }
417  // std::cout << "\tAdding INSTANCE with name: " << instance_name << " of PART wit name: " <<
418  // part_name << std::endl; // REMOVE
419 
420  // Process parameters
421  for( std::map< std::string, std::string >::iterator thisParam = params.begin(); thisParam != params.end();
422  ++thisParam )
423  {
424  // Look for unambiguous match with this node parameter
425  param = allowableParams[match( ( *thisParam ).first, allowableParams )];
426  switch( param )
427  {
429  // std::cout << "\t\tIgnoring ambiguous INSTANCE parameter: " << (*thisParam).first
430  // << "=" << (*thisParam).second << std::endl;
431  break;
432  default:
433  // std::cout << "\t\tIgnoring unsupported INSTANCE parameter: " <<
434  // (*thisParam).first
435  // << "=" << (*thisParam).second << std::endl;
436  break;
437  }
438  }
439 
441 
442  bool read_translation = false;
443  bool read_rotation = false;
444  std::vector< double > translation( 3, 0 );
445  std::vector< double > rotation( 7, 0 );
446  bool end_instance = false;
447  bool in_unsupported = false;
448 
449  EntityHandle instance_set;
450  status = add_entity_set( assembly_set, ABQ_INSTANCE_SET, instance_name, instance_set );
452 
453  while( next_line_type != abq_eof && !end_instance )
454  {
455  switch( next_line_type )
456  {
457  case abq_keyword_line:
458  in_unsupported = false;
459  switch( get_keyword() )
460  {
461  case abq_end_instance:
462  end_instance = true;
464  break;
465  case abq_node:
466  status = read_node_list( instance_set, assembly_set );
467  break;
468  case abq_element:
469  status = read_element_list( instance_set, assembly_set );
470  break;
471  case abq_nset:
472  status = read_node_set( instance_set, file_set, assembly_set );
473  break;
474  case abq_elset:
475  status = read_element_set( instance_set, file_set, assembly_set );
476  break;
477  case abq_solid_section:
478  status = read_solid_section( instance_set );
479  break;
480  default:
481  in_unsupported = true;
482  // std::cout << "\t\tIgnoring unsupported keyword in this INSTANCE: "
483  // << readline << std::endl;
485  break;
486  }
487  break;
488  case abq_comment_line:
490  break;
491  case abq_data_line:
492  if( !in_unsupported )
493  {
494  tokenize( readline, tokens, ", \n" );
495  if( !read_translation )
496  {
497  if( tokens.size() != 3 )
498  {
499  MB_SET_ERR( MB_FAILURE, "Wrong number of entries on INSTANCE translation line" );
500  }
501 
502  for( unsigned int i = 0; i < 3; i++ )
503  translation[i] = atof( tokens[i].c_str() );
504 
505  read_translation = true;
506  }
507  else if( !read_rotation )
508  {
509  if( tokens.size() != 7 )
510  {
511  MB_SET_ERR( MB_FAILURE, "Wrong number of entries on INSTANCE rotation line" );
512  }
513  for( unsigned int i = 0; i < 7; i++ )
514  rotation[i] = atof( tokens[i].c_str() );
515 
516  read_rotation = true;
517  }
518  else
519  {
520  MB_SET_ERR( MB_FAILURE, "Too many data lines for this INSTANCE" );
521  }
522  } // if (!in_unsupported)
524  break;
525  case abq_blank_line:
526  MB_SET_ERR( MB_FAILURE, "Error: Blank lines are not allowed" );
527  default:
528  MB_SET_ERR( MB_FAILURE, "Error reading INSTANCE" );
529  } // switch (next_line_type)
530  } // while (next_line_type != abq_eof && !end_instance)
531 
532  status = create_instance_of_part( file_set, assembly_set, part_name, instance_name, instance_set, translation,
533  rotation );
535 
536  return MB_SUCCESS;
537 }
538 
540 {
541  ErrorCode status = MB_SUCCESS;
542 
543  std::vector< std::string > tokens;
544  std::map< std::string, std::string > params;
545  std::map< std::string, abaqus_part_params > requiredParams;
546  requiredParams["NAME"] = abq_part_name;
547 
548  std::map< std::string, abaqus_part_params > allowableParams;
549  allowableParams[ABQ_AMBIGUOUS] = abq_part_ambiguous;
550 
551  abaqus_part_params param;
552 
553  std::string part_name;
554 
555  // Tokenize last line read
556  tokenize( readline, tokens, ",\n" );
557  extract_keyword_parameters( tokens, params );
558 
559  // Search for required parameters
560  for( std::map< std::string, abaqus_part_params >::iterator thisParam = requiredParams.begin();
561  thisParam != requiredParams.end(); ++thisParam )
562  {
563  std::string param_key = match( ( *thisParam ).first, params );
564  param = requiredParams[param_key];
565  switch( param )
566  {
567  case abq_part_name:
568  part_name = params[param_key];
569  params.erase( param_key );
570  // std::cout << "Adding PART with name: " << part_name << std::endl; // REMOVE
571  break;
572  default:
573  MB_SET_ERR( MB_FAILURE, "Missing required PART parameter" );
574  }
575  }
576 
577  // Process parameters
578  for( std::map< std::string, std::string >::iterator thisParam = params.begin(); thisParam != params.end();
579  ++thisParam )
580  {
581  // Look for unambiguous match with this node parameter
582  param = allowableParams[match( ( *thisParam ).first, allowableParams )];
583  switch( param )
584  {
585  case abq_part_ambiguous:
586  // std::cout << "\tIgnoring ambiguous PART parameter: " << (*thisParam).first
587  // << "=" << (*thisParam).second << std::endl;
588  break;
589  default:
590  // std::cout << "\tIgnoring unsupported PART parameter: " << (*thisParam).first
591  // << "=" << (*thisParam).second << std::endl;
592  break;
593  }
594  }
595 
596  EntityHandle part_set;
597 
598  status = add_entity_set( file_set, ABQ_PART_SET, part_name, part_set );
599 
601 
602  bool end_part = false;
603  bool in_unsupported = false;
604 
605  while( next_line_type != abq_eof && !end_part )
606  {
607  switch( next_line_type )
608  {
609  case abq_keyword_line:
610  in_unsupported = false;
611  switch( get_keyword() )
612  {
613  case abq_end_part:
614  end_part = true;
615  break;
616  case abq_node:
617  status = read_node_list( part_set );
618  break;
619  case abq_element:
620  status = read_element_list( part_set );
621  break;
622  case abq_nset:
623  status = read_node_set( part_set );
624  break;
625  case abq_elset:
626  status = read_element_set( part_set );
627  break;
628  case abq_solid_section:
629  status = read_solid_section( part_set );
630  break;
631  default:
632  in_unsupported = true;
633  // std::cout << "\tIgnoring unsupported keyword in this PART: "
634  // << readline << std::endl;
636  break;
637  }
639  break;
640  case abq_comment_line:
642  break;
643  case abq_data_line:
644  if( !in_unsupported )
645  {
646  MB_SET_ERR( MB_FAILURE, "Data lines not allowed in PART keyword" );
647  }
649  break;
650  case abq_blank_line:
651  MB_SET_ERR( MB_FAILURE, "Blank lines are not allowed" );
652  default:
653  MB_SET_ERR( MB_FAILURE, "Error reading PART" );
654  }
655  }
656 
657  num_part_instances[part_set] = 0;
658 
659  return MB_SUCCESS;
660 }
661 
663 {
664  ErrorCode status;
665 
666  std::vector< std::string > tokens;
667  std::map< std::string, std::string > params;
668  std::map< std::string, abaqus_solid_section_params > requiredParams;
669  requiredParams["ELSET"] = abq_solid_section_elset;
670  requiredParams["MATERIAL"] = abq_solid_section_matname;
671 
672  std::map< std::string, abaqus_solid_section_params > allowableParams;
673  allowableParams[ABQ_AMBIGUOUS] = abq_solid_section_ambiguous;
674 
676 
677  // Tokenize last line read
678  tokenize( readline, tokens, ",\n" );
679  extract_keyword_parameters( tokens, params );
680 
681  std::string elset_name, mat_name;
682 
683  // Search for required parameters
684  for( std::map< std::string, abaqus_solid_section_params >::iterator thisParam = requiredParams.begin();
685  thisParam != requiredParams.end(); ++thisParam )
686  {
687  std::string param_key = match( ( *thisParam ).first, params );
688  param = requiredParams[param_key];
689  switch( param )
690  {
692  elset_name = params[param_key];
693  params.erase( param_key );
694  break;
696  mat_name = params[param_key];
697  params.erase( param_key );
698  break;
699  default:
700  MB_SET_ERR( MB_FAILURE, "Missing required SOLID SECTION parameter" );
701  }
702  }
703  // std::cout << "\tAdding SOLID SECTION with to ELEMENT SET: " << elset_name << " with material:
704  // " << mat_name << std::endl; // REMOVE
705 
706  // Process parameters
707  for( std::map< std::string, std::string >::iterator thisParam = params.begin(); thisParam != params.end();
708  ++thisParam )
709  {
710  // Look for unambiguous match with this node parameter
711  param = allowableParams[match( ( *thisParam ).first, allowableParams )];
712  switch( param )
713  {
715  // std::cout << "\t\tIgnoring ambiguous SOLID_SECTION parameter: " <<
716  // (*thisParam).first
717  // << "=" << (*thisParam).second << std::endl;
718  break;
719  default:
720  // std::cout << "\t\tIgnoring unsupported SOLID_SECTION parameter: " <<
721  // (*thisParam).first
722  // << "=" << (*thisParam).second << std::endl;
723  break;
724  }
725  }
726 
727  EntityHandle set_handle;
728  status = get_set_by_name( parent_set, ABQ_ELEMENT_SET, elset_name, set_handle );
730 
731  status = mdbImpl->tag_set_data( mMatNameTag, &set_handle, 1, mat_name.c_str() );
733 
734  if( 0 == matIDmap[mat_name] ) matIDmap[mat_name] = ++mat_id;
735 
736  status = mdbImpl->tag_set_data( mMaterialSetTag, &set_handle, 1, &( matIDmap[mat_name] ) );
738 
740 
743 
744  return MB_SUCCESS;
745 }
746 
748 {
749  ErrorCode status;
750 
751  std::vector< std::string > tokens;
752  std::map< std::string, std::string > params;
753  std::map< std::string, abaqus_elset_params > requiredParams;
754  requiredParams["ELSET"] = abq_elset_elset;
755 
756  std::map< std::string, abaqus_elset_params > allowableParams;
757  allowableParams[ABQ_AMBIGUOUS] = abq_elset_ambiguous;
758  allowableParams["GENERATE"] = abq_elset_generate;
759  allowableParams["INSTANCE"] = abq_elset_instance;
760 
761  abaqus_elset_params param;
762 
763  std::string elset_name;
764  bool generate_elset = false;
765  std::string instance_name;
766  EntityHandle element_container_set = parent_set;
767 
768  // Tokenize last line read
769  tokenize( readline, tokens, ",\n" );
770  extract_keyword_parameters( tokens, params );
771 
772  Range element_range;
773 
774  // Search for required parameters
775  for( std::map< std::string, abaqus_elset_params >::iterator thisParam = requiredParams.begin();
776  thisParam != requiredParams.end(); ++thisParam )
777  {
778  std::string param_key = match( ( *thisParam ).first, params );
779  param = requiredParams[param_key];
780  switch( param )
781  {
782  case abq_elset_elset:
783  elset_name = params[param_key];
784  params.erase( param_key );
785  // std::cout << "\tAdding ELSET with name: " << elset_name << std::endl; // REMOVE
786  break;
787  default:
788  MB_SET_ERR( MB_FAILURE, "Missing required ELSET parameter" );
789  }
790  }
791 
792  // Process parameters
793  for( std::map< std::string, std::string >::iterator thisParam = params.begin(); thisParam != params.end();
794  ++thisParam )
795  {
796  // Look for unambiguous match with this node parameter
797  param = allowableParams[match( ( *thisParam ).first, allowableParams )];
798  switch( param )
799  {
800  case abq_elset_generate:
801  generate_elset = true;
802  break;
803  case abq_elset_instance:
804  instance_name = ( *thisParam ).second;
805  status = get_set_by_name( parent_set, ABQ_INSTANCE_SET, instance_name, element_container_set );
807  break;
808  case abq_elset_ambiguous:
809  // std::cout << "\t\tIgnoring ambiguous ELSET parameter: " << (*thisParam).first
810  // << "=" << (*thisParam).second << std::endl;
811  break;
812  default:
813  // std::cout << "\t\tIgnoring unsupported ELSET parameter: " << (*thisParam).first
814  // << "=" << (*thisParam).second << std::endl;
815  break;
816  }
817  }
818 
819  std::vector< int > element_list;
820  Range tmp_element_range;
821 
823 
825  {
827  {
828  tokenize( readline, tokens, ", \n" );
829  if( generate_elset )
830  {
831  if( tokens.size() != 3 )
832  {
833  MB_SET_ERR( MB_FAILURE, "Wrong number of entries on GENERATE element set data line" );
834  }
835  int e1 = atoi( tokens[0].c_str() );
836  int e2 = atoi( tokens[1].c_str() );
837  int incr = atoi( tokens[2].c_str() );
838  if( ( incr == 0 ) || ( ( ( e2 - e1 ) % incr ) != 0 ) )
839  {
840  MB_SET_ERR( MB_FAILURE, "Invalid data on GENERATE element set data line" );
841  }
842  for( int element_id = e1; element_id <= e2; element_id += incr )
843  element_list.push_back( element_id );
844  }
845  else
846  {
847  for( unsigned int idx = 0; idx < tokens.size(); idx++ )
848  {
849  if( isalpha( tokens[idx][0] ) )
850  {
851  tmp_element_range.clear();
852  status = get_set_elements_by_name( element_container_set, ABQ_ELEMENT_SET, tokens[idx],
853  tmp_element_range );
855 
856  element_range.merge( tmp_element_range );
857  }
858  else
859  element_list.push_back( atoi( tokens[idx].c_str() ) );
860  }
861  }
862  } // if (abq_data_line == next_line_type)
863 
865  } // while (next_line_type != abq_eof && next_line_type != abq_keyword_line)
866 
867  tmp_element_range.clear();
868  status = get_elements_by_id( element_container_set, element_list, tmp_element_range );
870 
871  element_range.merge( tmp_element_range );
872 
873  EntityHandle element_set;
874 
875  status = add_entity_set( parent_set, ABQ_ELEMENT_SET, elset_name, element_set );
877 
878  status = mdbImpl->add_entities( element_set, element_range );
880 
881  // SHOULD WE EVER DO THIS???
882  if( file_set )
883  {
884  status = mdbImpl->add_entities( file_set, &element_set, 1 );
886  }
887 
888  // SHOULD WE EVER DO THIS???
889  if( assembly_set )
890  {
891  status = mdbImpl->add_entities( assembly_set, &element_set, 1 );
893 
894  status = mdbImpl->tag_set_data( mAssemblyHandleTag, &element_set, 1, &assembly_set );
896  }
897 
898  return MB_SUCCESS;
899 }
900 
902 {
903  ErrorCode status;
904 
905  std::vector< std::string > tokens;
906  std::map< std::string, std::string > params;
907  std::map< std::string, abaqus_nset_params > requiredParams;
908  requiredParams["NSET"] = abq_nset_nset;
909 
910  std::map< std::string, abaqus_nset_params > allowableParams;
911  allowableParams[ABQ_AMBIGUOUS] = abq_nset_ambiguous;
912  allowableParams["ELSET"] = abq_nset_elset;
913  allowableParams["GENERATE"] = abq_nset_generate;
914  allowableParams["INSTANCE"] = abq_nset_instance;
915 
916  abaqus_nset_params param;
917 
918  std::string nset_name;
919  bool make_from_elset = false;
920  bool generate_nset = false;
921  std::string elset_name, instance_name;
922  EntityHandle node_container_set = parent_set;
923 
924  // Tokenize last line read
925  tokenize( readline, tokens, ",\n" );
926  extract_keyword_parameters( tokens, params );
927 
928  Range node_range;
929 
930  // Search for required parameters
931  for( std::map< std::string, abaqus_nset_params >::iterator thisParam = requiredParams.begin();
932  thisParam != requiredParams.end(); ++thisParam )
933  {
934  std::string param_key = match( ( *thisParam ).first, params );
935  param = requiredParams[param_key];
936  switch( param )
937  {
938  case abq_nset_nset:
939  nset_name = params[param_key];
940  params.erase( param_key );
941  // std::cout << "\tAdding NSET with name: " << nset_name << std::endl; // REMOVE
942  break;
943  default:
944  MB_SET_ERR( MB_FAILURE, "Missing required NSET parameter" );
945  }
946  }
947 
948  // Process parameters
949  for( std::map< std::string, std::string >::iterator thisParam = params.begin(); thisParam != params.end();
950  ++thisParam )
951  {
952  // Look for unambiguous match with this node parameter
953  param = allowableParams[match( ( *thisParam ).first, allowableParams )];
954  switch( param )
955  {
956  case abq_nset_elset:
957  make_from_elset = true;
958  elset_name = ( *thisParam ).second;
959  break;
960  case abq_nset_generate:
961  generate_nset = true;
962  break;
963  case abq_nset_instance:
964  instance_name = ( *thisParam ).second;
965  status = get_set_by_name( parent_set, ABQ_INSTANCE_SET, instance_name, node_container_set );
967  break;
968  case abq_nset_ambiguous:
969  // std::cout << "\t\tIgnoring ambiguous NSET parameter: " << (*thisParam).first
970  // << "=" << (*thisParam).second << std::endl;
971  break;
972  default:
973  // std::cout << "\t\tIgnoring unsupported NSET parameter: " << (*thisParam).first
974  // << "=" << (*thisParam).second << std::endl;
975  break;
976  }
977  }
978 
979  if( make_from_elset && generate_nset )
980  {
981  MB_SET_ERR( MB_FAILURE, "Incompatible NSET parameters ELSET & GENERATE" );
982  }
983 
984  if( make_from_elset )
985  {
986  status = get_set_nodes( parent_set, ABQ_ELEMENT_SET, elset_name, node_range );
988  }
989  else
990  {
991  std::vector< int > node_list;
992  Range tmp_node_range;
993 
995 
997  {
999  {
1000  tokenize( readline, tokens, ", \n" );
1001  if( generate_nset )
1002  {
1003  if( tokens.size() != 3 )
1004  {
1005  MB_SET_ERR( MB_FAILURE, "Wrong number of entries on GENERATE node set data line" );
1006  }
1007  int n1 = atoi( tokens[0].c_str() );
1008  int n2 = atoi( tokens[1].c_str() );
1009  int incr = atoi( tokens[2].c_str() );
1010  if( ( incr == 0 ) || ( ( ( n2 - n1 ) % incr ) != 0 ) )
1011  {
1012  MB_SET_ERR( MB_FAILURE, "Invalid data on GENERATE node set data line" );
1013  }
1014  for( int node_id = n1; node_id <= n2; node_id += incr )
1015  node_list.push_back( node_id );
1016  }
1017  else
1018  {
1019  for( unsigned int idx = 0; idx < tokens.size(); idx++ )
1020  {
1021  if( isalpha( tokens[idx][0] ) )
1022  {
1023  tmp_node_range.clear();
1024  status = get_set_nodes( parent_set, ABQ_NODE_SET, tokens[idx], tmp_node_range );
1026 
1027  node_range.merge( tmp_node_range );
1028  }
1029  else
1030  node_list.push_back( atoi( tokens[idx].c_str() ) );
1031  }
1032  }
1033  } // if (abq_data_line == next_line_type)
1034 
1036  } // while (next_line_type != abq_eof && next_line_type != abq_keyword_line)
1037 
1038  tmp_node_range.clear();
1039 
1040  status = get_nodes_by_id( node_container_set, node_list, tmp_node_range );
1042 
1043  node_range.merge( tmp_node_range );
1044  }
1045 
1046  EntityHandle node_set;
1047 
1048  status = add_entity_set( parent_set, ABQ_NODE_SET, nset_name, node_set );
1050 
1051  status = mdbImpl->add_entities( node_set, node_range );
1053 
1054  if( file_set )
1055  {
1056  status = mdbImpl->add_entities( file_set, &node_set, 1 );
1058  }
1059 
1060  if( assembly_set )
1061  {
1062  status = mdbImpl->add_entities( assembly_set, &node_set, 1 );
1064 
1065  status = mdbImpl->tag_set_data( mAssemblyHandleTag, &node_set, 1, &assembly_set );
1067  }
1068 
1069  return MB_SUCCESS;
1070 }
1071 
1073 {
1074  ErrorCode status;
1075 
1076  std::vector< std::string > tokens;
1077  std::map< std::string, std::string > params;
1078  std::map< std::string, abaqus_element_params > requiredParams;
1079  requiredParams["TYPE"] = abq_element_type;
1080 
1081  std::map< std::string, abaqus_element_params > allowableParams;
1082  allowableParams[ABQ_AMBIGUOUS] = abq_element_ambiguous;
1083  allowableParams["ELSET"] = abq_element_elset;
1084 
1085  abaqus_element_params param;
1086 
1087  std::map< std::string, abaqus_element_type > elementTypes;
1088  std::map< abaqus_element_type, unsigned int > nodes_per_element;
1089  std::map< abaqus_element_type, EntityType > entityTypeMap;
1090  elementTypes["DC3D8"] = abq_eletype_dc3d8;
1091  nodes_per_element[abq_eletype_dc3d8] = 8;
1092  entityTypeMap[abq_eletype_dc3d8] = MBHEX;
1093 
1094  elementTypes["DCC3D8"] = abq_eletype_dcc3d8;
1095  nodes_per_element[abq_eletype_dcc3d8] = 8;
1096  entityTypeMap[abq_eletype_dcc3d8] = MBHEX;
1097 
1098  elementTypes["C3D4"] = abq_eletype_c3d4;
1099  nodes_per_element[abq_eletype_c3d4] = 4;
1100  entityTypeMap[abq_eletype_c3d4] = MBTET;
1101 
1102  elementTypes["DC3D4"] = abq_eletype_dc3d4;
1103  nodes_per_element[abq_eletype_dc3d4] = 4;
1104  entityTypeMap[abq_eletype_dc3d4] = MBTET;
1105 
1106  elementTypes["C3D8R"] = abq_eletype_c3d8r;
1107  nodes_per_element[abq_eletype_c3d8r] = 8;
1108  entityTypeMap[abq_eletype_c3d8r] = MBHEX;
1109 
1110  elementTypes["DS4"] = abq_eletype_ds4;
1111  nodes_per_element[abq_eletype_ds4] = 4;
1112  entityTypeMap[abq_eletype_ds4] = MBQUAD;
1113 
1114  abaqus_element_type element_type = abq_eletype_dc3d8;
1115 
1116  bool make_element_set = false;
1117  std::string element_set_name;
1118 
1119  // Tokenize last line read
1120  tokenize( readline, tokens, ",\n" );
1121  extract_keyword_parameters( tokens, params );
1122 
1123  // Search for required parameters
1124  for( std::map< std::string, abaqus_element_params >::iterator thisParam = requiredParams.begin();
1125  thisParam != requiredParams.end(); ++thisParam )
1126  {
1127  std::string param_key = match( ( *thisParam ).first, params );
1128  param = requiredParams[param_key];
1129  switch( param )
1130  {
1131  case abq_element_type:
1132  element_type = elementTypes[params[param_key]];
1133  if( abq_eletype_unsupported == element_type )
1134  {
1135  MB_SET_ERR( MB_FAILURE, "MOAB doesn't currently support this element type" );
1136  }
1137  // std::cout << "\tAdding ELEMENTS of type: " << params[param_key] << std::endl; //
1138  // REMOVE
1139  params.erase( param_key );
1140  break;
1141  case abq_element_undefined:
1142  MB_SET_ERR( MB_FAILURE, "Missing required ELEMENT parameter" );
1143  default:
1144  break;
1145  }
1146  }
1147 
1148  // Process parameters
1149  for( std::map< std::string, std::string >::iterator thisParam = params.begin(); thisParam != params.end();
1150  ++thisParam )
1151  {
1152  // Look for unambiguous match with this node parameter
1153  param = allowableParams[match( ( *thisParam ).first, allowableParams )];
1154  switch( param )
1155  {
1156  case abq_element_elset:
1157  make_element_set = true;
1158  element_set_name = ( *thisParam ).second;
1159  break;
1160  case abq_element_ambiguous:
1161  // std::cout << "\t\tIgnoring ambiguous ELEMENT parameter: " << (*thisParam).first
1162  // << "=" << (*thisParam).second << std::endl;
1163  break;
1164  default:
1165  // std::cout << "\t\tIgnoring unsupported ELEMENT parameter: " << (*thisParam).first
1166  // << "=" << (*thisParam).second << std::endl;
1167  break;
1168  }
1169  }
1170 
1171  std::vector< int > connect_list, element_ids;
1172 
1174 
1176  {
1177  if( abq_data_line == next_line_type )
1178  {
1179  tokenize( readline, tokens, ", \n" );
1180  if( tokens.size() < nodes_per_element[element_type] + 1 )
1181  {
1182  MB_SET_ERR( MB_FAILURE, "Not enough data on node data line" );
1183  }
1184  element_ids.push_back( atoi( tokens[0].c_str() ) );
1185  for( unsigned int i = 1; i < nodes_per_element[element_type] + 1; i++ )
1186  connect_list.push_back( atoi( tokens[i].c_str() ) );
1187  }
1188 
1190  }
1191 
1192  int num_elements = element_ids.size();
1193 
1194  // Get and fill element arrays
1195  EntityHandle start_element = 0;
1196  EntityHandle* connect;
1197 
1198  status = readMeshIface->get_element_connect( num_elements, nodes_per_element[element_type],
1199  entityTypeMap[element_type], MB_START_ID, start_element, connect );
1201  if( 0 == start_element ) return MB_FAILURE;
1202 
1203  // ASSUME: elements must be defined after nodes!
1204  // Get list of node entity handles and node IDs
1205  Range node_list;
1206  status = mdbImpl->get_entities_by_dimension( parent_set, 0, node_list );
1208 
1209  std::vector< int > node_ids( node_list.size() );
1210  status = mdbImpl->tag_get_data( mLocalIDTag, node_list, &node_ids[0] );
1212 
1213  std::map< int, EntityHandle > nodeIdMap;
1214  for( unsigned int idx = 0; idx < node_list.size(); idx++ )
1215  nodeIdMap[node_ids[idx]] = node_list[idx];
1216 
1217  for( unsigned int node = 0; node < connect_list.size(); node++ )
1218  connect[node] = nodeIdMap[connect_list[node]];
1219 
1220  Range element_range( start_element, start_element + num_elements - 1 );
1221 
1222  // Add elements to file_set
1223  // status = mdbImpl->add_entities(file_set, element_range);
1224  // MB_RETURN_IF_FAIL;
1225 
1226  // Add elements to this parent_set
1227  status = mdbImpl->add_entities( parent_set, element_range );
1229 
1230  // Tag elements with their local ID's
1231  status = mdbImpl->tag_set_data( mLocalIDTag, element_range, &element_ids[0] );
1233 
1234  if( assembly_set )
1235  {
1236  status = mdbImpl->add_entities( assembly_set, element_range );
1238 
1239  std::vector< EntityHandle > tmp_assembly_handles;
1240  tmp_assembly_handles.assign( element_range.size(), assembly_set );
1241  status = mdbImpl->tag_set_data( mAssemblyHandleTag, element_range, &( tmp_assembly_handles[0] ) );
1243  }
1244 
1245  // These elements don't know their instance_set (probably not defined)
1246 
1247  if( make_element_set )
1248  {
1249  EntityHandle element_set;
1250 
1251  status = add_entity_set( parent_set, ABQ_ELEMENT_SET, element_set_name, element_set );
1253 
1254  status = mdbImpl->add_entities( element_set, element_range );
1256 
1257  // This ad-hoc element set doesn't know its:
1258  // * part_set (probably parent_set)
1259  // * instance_set (probably not defined)
1260  // * assembly_set (probably not defined)
1261  }
1262 
1263  return MB_SUCCESS;
1264 }
1265 
1267 {
1268  ErrorCode status;
1269 
1270  std::vector< std::string > tokens;
1271  std::map< std::string, std::string > params;
1272  std::map< std::string, abaqus_node_params > allowableParams;
1273 
1274  allowableParams[ABQ_AMBIGUOUS] = abq_node_ambiguous;
1275  allowableParams["NSET"] = abq_node_nset;
1276  allowableParams["SYSTEM"] = abq_node_system;
1277 
1278  abaqus_node_params param;
1279 
1280  bool make_node_set = false;
1281  std::string node_set_name;
1282 
1283  char coord_system = 'R';
1284 
1285  // Tokenize last line read
1286  tokenize( readline, tokens, ",\n" );
1287  extract_keyword_parameters( tokens, params );
1288 
1289  // std::cout << "\tAdding NODES" << std::endl; // REMOVE
1290 
1291  // Process parameters
1292  for( std::map< std::string, std::string >::iterator thisParam = params.begin(); thisParam != params.end();
1293  ++thisParam )
1294  {
1295  // Look for unambiguous match with this node parameter
1296  param = allowableParams[match( ( *thisParam ).first, allowableParams )];
1297  switch( param )
1298  {
1299  case abq_node_nset:
1300  make_node_set = true;
1301  node_set_name = ( *thisParam ).second;
1302  break;
1303  case abq_node_system:
1304  // Store coordinate system
1305  coord_system = ( *thisParam ).second[0];
1306  break;
1307  case abq_node_ambiguous:
1308  // std::cout << "\t\tIgnoring ambiguous NODE parameter: " << (*thisParam).first
1309  // << "=" << (*thisParam).second << std::endl;
1310  break;
1311  default:
1312  // std::cout << "\t\tIgnoring unsupported NODE parameter: " << (*thisParam).first
1313  // << "=" << (*thisParam).second << std::endl;
1314  break;
1315  }
1316  }
1317 
1318  std::vector< double > coord_list;
1319  std::vector< int > node_ids;
1320 
1322 
1324  {
1325  if( abq_data_line == next_line_type )
1326  {
1327  tokenize( readline, tokens, ", \n" );
1328  if( tokens.size() < 4 )
1329  {
1330  MB_SET_ERR( MB_FAILURE, "Not enough data on node data line" );
1331  }
1332  node_ids.push_back( atoi( tokens[0].c_str() ) );
1333  for( unsigned int i = 1; i < 4; i++ )
1334  coord_list.push_back( atof( tokens[i].c_str() ) );
1335  }
1336 
1338  }
1339 
1340  unsigned int num_nodes = node_ids.size();
1341 
1342  // Transform coordinate systems
1343  switch( coord_system )
1344  {
1345  case 'R':
1346  break;
1347  case 'C':
1348  cyl2rect( coord_list );
1349  break;
1350  case 'S':
1351  sph2rect( coord_list );
1352  break;
1353  default:
1354  // std::cout << "Treating undefined coordinate system: " << coord_system
1355  // << " as rectangular/Cartesian." << std::endl;
1356  break;
1357  }
1358 
1359  // Get and fill coordinate arrays
1360  std::vector< double* > coord_arrays( 3 );
1361  EntityHandle start_node = 0;
1362  status = readMeshIface->get_node_coords( 3, num_nodes, MB_START_ID, start_node, coord_arrays );
1364 
1365  if( 0 == start_node ) return MB_FAILURE;
1366 
1367  // Cppcheck warning (false positive): variable coord_arrays is assigned a value that is never
1368  // used
1369  for( unsigned int idx = 0; idx < num_nodes; idx++ )
1370  {
1371  coord_arrays[0][idx] = coord_list[idx * 3];
1372  coord_arrays[1][idx] = coord_list[idx * 3 + 1];
1373  coord_arrays[2][idx] = coord_list[idx * 3 + 2];
1374  }
1375 
1376  Range node_range( start_node, start_node + num_nodes - 1 );
1377  // Add nodes to file_set
1378  // status = mdbImpl->add_entities(file_set, node_range);
1379  // MB_RETURN_IF_FAIL;
1380 
1381  // Add nodes to this parent_set
1382  status = mdbImpl->add_entities( parent_set, node_range );
1384 
1385  // Tag nodes with their local ID's
1386  status = mdbImpl->tag_set_data( mLocalIDTag, node_range, &node_ids[0] );
1388 
1389  if( assembly_set )
1390  {
1391  status = mdbImpl->add_entities( assembly_set, node_range );
1393 
1394  std::vector< EntityHandle > tmp_assembly_handles;
1395  tmp_assembly_handles.assign( node_range.size(), assembly_set );
1396  status = mdbImpl->tag_set_data( mAssemblyHandleTag, node_range, &( tmp_assembly_handles[0] ) );
1398  }
1399 
1400  // These nodes don't know their instance_set (probably not defined)
1401 
1402  if( make_node_set )
1403  {
1404  EntityHandle node_set;
1405 
1406  status = add_entity_set( parent_set, ABQ_NODE_SET, node_set_name, node_set );
1408 
1409  status = mdbImpl->add_entities( node_set, node_range );
1411 
1412  // This ad-hoc node set doesn't know its:
1413  // * part_set (probably parent_set)
1414  // * instance_set (probably not defined)
1415  // * assembly_set (probably not defined)
1416  }
1417 
1418  return MB_SUCCESS;
1419 }
1420 
1421 // SET CREATION & ACCESS UTILITIES
1422 
1424  std::vector< int > element_ids_subset,
1425  Range& element_range )
1426 {
1427  ErrorCode status;
1428  Range all_elements;
1429 
1430  status = get_set_elements( parent_set, all_elements );
1432 
1433  std::vector< int > element_ids( all_elements.size() );
1434  status = mdbImpl->tag_get_data( mLocalIDTag, all_elements, &element_ids[0] );
1436 
1437  std::map< int, EntityHandle > elementIdMap;
1438  for( unsigned int idx = 0; idx < all_elements.size(); idx++ )
1439  elementIdMap[element_ids[idx]] = all_elements[idx];
1440 
1441  for( std::vector< int >::iterator element = element_ids_subset.begin(); element != element_ids_subset.end();
1442  ++element )
1443  element_range.insert( elementIdMap[*element] );
1444 
1445  return MB_SUCCESS;
1446 }
1447 
1448 ErrorCode ReadABAQUS::get_nodes_by_id( EntityHandle parent_set, std::vector< int > node_ids_subset, Range& node_range )
1449 {
1450  ErrorCode status;
1451 
1452  Range all_nodes;
1453  status = mdbImpl->get_entities_by_type( parent_set, MBVERTEX, all_nodes );
1455 
1456  std::vector< int > node_ids( all_nodes.size() );
1457  status = mdbImpl->tag_get_data( mLocalIDTag, all_nodes, &node_ids[0] );
1459 
1460  std::map< int, EntityHandle > nodeIdMap;
1461  for( unsigned int idx = 0; idx < all_nodes.size(); idx++ )
1462  nodeIdMap[node_ids[idx]] = all_nodes[idx];
1463 
1464  for( std::vector< int >::iterator node = node_ids_subset.begin(); node != node_ids_subset.end(); ++node )
1465  node_range.insert( nodeIdMap[*node] );
1466 
1467  return MB_SUCCESS;
1468 }
1469 
1471  int ABQ_set_type,
1472  const std::string& set_name,
1473  EntityHandle& set_handle )
1474 {
1475  ErrorCode status;
1476 
1477  char this_set_name[ABAQUS_SET_NAME_LENGTH];
1478 
1479  set_handle = 0;
1480 
1481  Range sets;
1482  void* tag_data[] = { &ABQ_set_type };
1483  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" );
1484 
1485  for( Range::iterator this_set = sets.begin(); this_set != sets.end() && 0 == set_handle; ++this_set )
1486  {
1487  std::fill( this_set_name, this_set_name + ABAQUS_SET_NAME_LENGTH, '\0' );
1488  status = mdbImpl->tag_get_data( mSetNameTag, &( *this_set ), 1, &this_set_name[0] );
1489  if( MB_SUCCESS != status && MB_TAG_NOT_FOUND != status ) return status;
1490 
1491  if( set_name == std::string( this_set_name ) ) set_handle = *this_set;
1492  }
1493 
1494  if( 0 == set_handle )
1495  {
1496  MB_SET_ERR( MB_FAILURE, "Did not find requested set" );
1497  }
1498 
1499  return MB_SUCCESS;
1500 }
1501 
1503 {
1504  ErrorCode status;
1505 
1506  Range dim_ent_list;
1507 
1508  // Could have elements of multiple dimensions in this set???
1509  for( int dim = 1; dim <= 3; dim++ )
1510  {
1511  dim_ent_list.clear();
1512  status = mdbImpl->get_entities_by_dimension( set_handle, dim, dim_ent_list );
1514 
1515  element_range.merge( dim_ent_list );
1516  }
1517 
1518  return MB_SUCCESS;
1519 }
1520 
1522  int ABQ_set_type,
1523  const std::string& set_name,
1524  Range& element_range )
1525 {
1526  ErrorCode status;
1527 
1528  EntityHandle set_handle;
1529  status = get_set_by_name( parent_set, ABQ_set_type, set_name, set_handle );
1531 
1532  status = get_set_elements( set_handle, element_range );
1534 
1535  if( element_range.size() == 0 )
1536  {
1537  // std::cout << "No elements were found in set " << set_name << std::endl;
1538  }
1539 
1540  return MB_SUCCESS;
1541 }
1542 
1544  int ABQ_set_type,
1545  const std::string& set_name,
1546  Range& node_range )
1547 {
1548  ErrorCode status;
1549 
1550  EntityHandle set_handle;
1551  status = get_set_by_name( parent_set, ABQ_set_type, set_name, set_handle );
1553 
1554  Range ent_list;
1555  Range dim_ent_list;
1556  // Could have elements of multiple dimensions in this set???
1557  for( int dim = 0; dim <= 3; dim++ )
1558  {
1559  dim_ent_list.clear();
1560  status = mdbImpl->get_entities_by_dimension( set_handle, dim, dim_ent_list );
1562 
1563  ent_list.merge( dim_ent_list );
1564  }
1565 
1566  status = mdbImpl->get_adjacencies( ent_list, 0, false, node_range );
1568 
1569  if( node_range.size() == 0 )
1570  {
1571  std::cout << "No nodes were found in set " << set_name << std::endl;
1572  }
1573 
1574  return MB_SUCCESS;
1575 }
1576 
1577 Tag ReadABAQUS::get_tag( const char* tag_name,
1578  int tag_size,
1579  TagType tag_type,
1580  DataType tag_data_type,
1581  const void* def_val )
1582 {
1583  Tag retval;
1584 
1585  ErrorCode rval =
1586  mdbImpl->tag_get_handle( tag_name, tag_size, tag_data_type, retval, tag_type | MB_TAG_CREAT, def_val );
1587  assert( MB_SUCCESS == rval );
1588  return MB_SUCCESS == rval ? retval : 0;
1589 }
1590 
1592  const EntityHandle assembly_set,
1593  const std::string& part_name,
1594  const std::string& /*instance_name*/,
1595  EntityHandle& instance_set,
1596  const std::vector< double >& translation,
1597  const std::vector< double >& rotation )
1598 {
1599  ErrorCode status;
1600 
1601  EntityHandle part_set;
1602  status = get_set_by_name( file_set, ABQ_PART_SET, part_name, part_set );
1604 
1605  // Cross-reference
1606  status = mdbImpl->tag_set_data( mPartHandleTag, &instance_set, 1, &part_set );
1608 
1609  int instance_id = ++num_part_instances[part_set];
1610  status = mdbImpl->tag_set_data( mInstancePIDTag, &instance_set, 1, &instance_id );
1612 
1613  status = mdbImpl->tag_set_data( mAssemblyHandleTag, &instance_set, 1, &assembly_set );
1615 
1616  instance_id = ++num_assembly_instances[assembly_set];
1617  status = mdbImpl->tag_set_data( mInstanceGIDTag, &instance_set, 1, &instance_id );
1619 
1620  // Create maps to cross-reference the part and instance versions of each entity
1621  std::map< EntityHandle, EntityHandle > p2i_nodes, p2i_elements;
1622 
1623  // ---- NODES ----
1624 
1625  // Get all nodes and IDs
1626  Range part_node_list;
1627  status = mdbImpl->get_entities_by_dimension( part_set, 0, part_node_list );
1629 
1630  if( 0 < part_node_list.size() )
1631  {
1632  std::vector< int > node_ids( part_node_list.size() );
1633  status = mdbImpl->tag_get_data( mLocalIDTag, part_node_list, &node_ids[0] );
1635 
1636  // std::map<int, EntityHandle> nodeIdMap;
1637  // for (unsigned int idx = 0; idx < part_node_list.size(); idx++)
1638  // nodeIdMap[node_ids[idx]] = part_node_list[idx];
1639 
1640  // Create new nodes
1641  std::vector< double* > coord_arrays( 3 );
1642  EntityHandle start_node = 0;
1643  status = readMeshIface->get_node_coords( 3, part_node_list.size(), MB_START_ID, start_node, coord_arrays );
1645 
1646  if( 0 == start_node ) return MB_FAILURE;
1647 
1648  // Copy coordinates into new coord_arrays
1649  status = mdbImpl->get_coords( part_node_list, coord_arrays[0], coord_arrays[1], coord_arrays[2] );
1650 
1651  // Rotate to new position
1652  double rot_axis[3];
1653  rot_axis[0] = rotation[3] - rotation[0];
1654  rot_axis[1] = rotation[4] - rotation[1];
1655  rot_axis[2] = rotation[5] - rotation[2];
1656 
1657  AffineXform rotationXform;
1658  if( rotation[6] != 0 ) rotationXform = AffineXform::rotation( rotation[6] * DEG2RAD, rot_axis );
1659 
1660  // Translate to new position
1661  for( unsigned int idx = 0; idx < part_node_list.size(); idx++ )
1662  {
1663  double coords[3];
1664 
1665  // Transform to new location and then shift origin of rotation
1666  for( unsigned int dim = 0; dim < 3; dim++ )
1667  coords[dim] = coord_arrays[dim][idx] + translation[dim] - rotation[dim];
1668 
1669  // Rotate around this origin
1670  if( rotation[6] != 0 ) rotationXform.xform_vector( coords );
1671 
1672  // Transform origin of rotation back
1673  for( unsigned int dim = 0; dim < 3; dim++ )
1674  coord_arrays[dim][idx] = coords[dim] + rotation[dim];
1675  }
1676 
1677  Range instance_node_list( start_node, start_node + part_node_list.size() - 1 );
1678 
1679  // (DO NOT) add nodes to file_set
1680  // status = mdbImpl->add_entities(file_set, instance_node_list);
1681  // MB_RETURN_IF_FAIL;
1682 
1683  // Add nodes to this instance_set
1684  status = mdbImpl->add_entities( instance_set, instance_node_list );
1686 
1687  // Add nodes to this assembly_set
1688  status = mdbImpl->add_entities( assembly_set, instance_node_list );
1690 
1691  // Tag nodes with their local ID's
1692  status = mdbImpl->tag_set_data( mLocalIDTag, instance_node_list, &node_ids[0] );
1694 
1695  // Create a map of old handles to new handles!!!
1696  for( unsigned int idx = 0; idx < part_node_list.size(); idx++ )
1697  p2i_nodes[part_node_list[idx]] = instance_node_list[idx];
1698  }
1699 
1700  // ---- ELEMENTS ----
1701 
1702  Range part_element_list;
1703  status = get_set_elements( part_set, part_element_list );
1705 
1706  if( 0 < part_element_list.size() )
1707  {
1708  std::vector< int > part_element_ids( part_element_list.size() );
1709  status = mdbImpl->tag_get_data( mLocalIDTag, part_element_list, &part_element_ids[0] );
1711 
1712  // std::map<int, EntityHandle> elementIdMap;
1713  // for (unsigned int idx = 0; idx < part_element_list.size(); idx++)
1714  // elementIdMap[part_element_ids[idx]] = part_element_list[idx];
1715 
1716  // Create new elements
1717  Range instance_element_list;
1718  instance_element_list.clear();
1719 
1720  // Cross-referencing storage and pointers/iterators
1721  std::vector< int > instance_element_ids;
1722  std::vector< int >::iterator part_element_id = part_element_ids.begin();
1723 
1724  for( Range::iterator part_element = part_element_list.begin(); part_element != part_element_list.end();
1725  ++part_element, ++part_element_id )
1726  {
1727  EntityType element_type = mdbImpl->type_from_handle( *part_element );
1728  std::vector< EntityHandle > part_connectivity, instance_connectivity;
1729  EntityHandle new_element;
1730  status = mdbImpl->get_connectivity( &( *part_element ), 1, part_connectivity );
1732 
1733  instance_connectivity.clear();
1734  for( std::vector< EntityHandle >::iterator connectivity_node = part_connectivity.begin();
1735  connectivity_node != part_connectivity.end(); ++connectivity_node )
1736  instance_connectivity.push_back( p2i_nodes[*connectivity_node] );
1737 
1738  status = mdbImpl->create_element( element_type, &instance_connectivity[0], instance_connectivity.size(),
1739  new_element );
1741 
1742  instance_element_list.insert( new_element );
1743  p2i_elements[*part_element] = new_element;
1744  instance_element_ids.push_back( *part_element_id );
1745  }
1746 
1747  // (DO NOT) add elements to file_set
1748  // status = mdbImpl->add_entities(file_set, instance_element_list);
1749  // MB_RETURN_IF_FAIL;
1750 
1751  // Add elements to this instance_set
1752  status = mdbImpl->add_entities( instance_set, instance_element_list );
1754 
1755  // Add elements to this assembly_set
1756  status = mdbImpl->add_entities( assembly_set, instance_element_list );
1758 
1759  // Tag elements with their local ID's
1760  status = mdbImpl->tag_set_data( mLocalIDTag, instance_element_list, &( instance_element_ids[0] ) );
1762  }
1763 
1764  // ----- NODE SETS -----
1765 
1766  // Get all node sets in part
1767  Range part_node_sets;
1768  int tag_val = ABQ_NODE_SET;
1769  void* tag_data[] = { &tag_val };
1770  status = mdbImpl->get_entities_by_type_and_tag( part_set, MBENTITYSET, &mSetTypeTag, tag_data, 1, part_node_sets );
1772 
1773  Range part_node_set_list, instance_node_set_list;
1774  for( Range::iterator part_node_set = part_node_sets.begin(); part_node_set != part_node_sets.end();
1775  ++part_node_set )
1776  {
1777  char node_set_name[ABAQUS_SET_NAME_LENGTH];
1778  std::fill( node_set_name, node_set_name + ABAQUS_SET_NAME_LENGTH, '\0' );
1779  status = mdbImpl->tag_get_data( mSetNameTag, &( *part_node_set ), 1, &node_set_name[0] );
1780  if( MB_SUCCESS != status && MB_TAG_NOT_FOUND != status ) return status;
1781 
1782  part_node_set_list.clear();
1783  status = mdbImpl->get_entities_by_dimension( *part_node_set, 0, part_node_set_list );
1784 
1785  instance_node_set_list.clear();
1786  for( Range::iterator set_node = part_node_set_list.begin(); set_node != part_node_set_list.end(); ++set_node )
1787  instance_node_set_list.insert( p2i_nodes[*set_node] );
1788 
1789  EntityHandle instance_node_set;
1790 
1791  status = add_entity_set( instance_set, ABQ_NODE_SET, node_set_name, instance_node_set );
1793 
1794  status = mdbImpl->add_entities( instance_node_set, instance_node_set_list );
1796 
1797  status = mdbImpl->add_entities( assembly_set, &instance_node_set, 1 );
1799 
1800  status = mdbImpl->tag_set_data( mPartHandleTag, &instance_node_set, 1, &part_set );
1802 
1803  status = mdbImpl->tag_set_data( mAssemblyHandleTag, &instance_node_set, 1, &assembly_set );
1805  }
1806 
1807  // ----- ELEMENT SETS -----
1808 
1809  // Get all element sets in part
1810  Range part_element_sets;
1811  tag_val = ABQ_ELEMENT_SET;
1812  tag_data[0] = &tag_val;
1813  status =
1814  mdbImpl->get_entities_by_type_and_tag( part_set, MBENTITYSET, &mSetTypeTag, tag_data, 1, part_element_sets );
1816 
1817  Range part_element_set_list, instance_element_set_list;
1818  for( Range::iterator part_element_set = part_element_sets.begin(); part_element_set != part_element_sets.end();
1819  ++part_element_set )
1820  {
1821  char element_set_name[ABAQUS_SET_NAME_LENGTH];
1822  std::fill( element_set_name, element_set_name + ABAQUS_SET_NAME_LENGTH, '\0' );
1823  status = mdbImpl->tag_get_data( mSetNameTag, &( *part_element_set ), 1, &element_set_name[0] );
1824  if( MB_SUCCESS != status && MB_TAG_NOT_FOUND != status ) return status;
1825 
1826  part_element_set_list.clear();
1827  status = get_set_elements( *part_element_set, part_element_set_list );
1828 
1829  instance_element_set_list.clear();
1830  for( Range::iterator set_element = part_element_set_list.begin(); set_element != part_element_set_list.end();
1831  ++set_element )
1832  instance_element_set_list.insert( p2i_elements[*set_element] );
1833 
1834  EntityHandle instance_element_set;
1835  status = add_entity_set( instance_set, ABQ_ELEMENT_SET, element_set_name, instance_element_set );
1837 
1838  // std::cerr << instance_set << "\t" << instance_element_set << std::endl;
1839  status = mdbImpl->add_entities( instance_element_set, instance_element_set_list );
1841 
1842  status = mdbImpl->add_entities( assembly_set, &instance_element_set, 1 );
1844 
1845  // status = mdbImpl->add_entities(file_set, &instance_element_set, 1);
1846  // MB_RETURN_IF_FAIL;
1847 
1848  status = mdbImpl->tag_set_data( mPartHandleTag, &instance_element_set, 1, &part_set );
1850 
1851  status = mdbImpl->tag_set_data( mAssemblyHandleTag, &instance_element_set, 1, &assembly_set );
1853 
1854  char element_set_matname[ABAQUS_SET_NAME_LENGTH];
1855  std::fill( element_set_matname, element_set_matname + ABAQUS_SET_NAME_LENGTH, '\0' );
1856  status = mdbImpl->tag_get_data( mMatNameTag, &( *part_element_set ), 1, &element_set_matname[0] );
1857  if( MB_SUCCESS != status && MB_TAG_NOT_FOUND != status ) return status;
1858 
1859  if( MB_TAG_NOT_FOUND != status )
1860  {
1861  status = mdbImpl->tag_set_data( mMatNameTag, &instance_element_set, 1, element_set_matname );
1863  }
1864 
1865  int element_set_mat_id;
1866  status = mdbImpl->tag_get_data( mMaterialSetTag, &( *part_element_set ), 1, &element_set_mat_id );
1867  if( MB_SUCCESS != status && MB_TAG_NOT_FOUND != status ) return status;
1868 
1869  if( MB_TAG_NOT_FOUND != status )
1870  {
1871  status = mdbImpl->tag_set_data( mMaterialSetTag, &instance_element_set, 1, &element_set_mat_id );
1873  }
1874  }
1875 
1876  // Tag everything with their instance handle
1877  // some nodes are assigned outside of this routine so query final list of all
1878  // instance nodes, elements, etc
1879  Range instance_entity_list;
1880  status = mdbImpl->get_entities_by_dimension( instance_set, 0, instance_entity_list );
1882 
1883  std::vector< EntityHandle > tmp_instance_handles;
1884  tmp_instance_handles.assign( instance_entity_list.size(), instance_set );
1885  status = mdbImpl->tag_set_data( mInstanceHandleTag, instance_entity_list, &tmp_instance_handles[0] );
1887 
1888  instance_entity_list.clear();
1889  status = get_set_elements( instance_set, instance_entity_list );
1891 
1892  tmp_instance_handles.clear();
1893  tmp_instance_handles.assign( instance_entity_list.size(), instance_set );
1894  status = mdbImpl->tag_set_data( mInstanceHandleTag, instance_entity_list, &tmp_instance_handles[0] );
1896 
1897  // Get all node sets in instance
1898  instance_entity_list.clear();
1899  tag_val = ABQ_NODE_SET;
1900  tag_data[0] = &tag_val;
1901  status = mdbImpl->get_entities_by_type_and_tag( instance_set, MBENTITYSET, &mSetTypeTag, tag_data, 1,
1902  instance_entity_list );
1904 
1905  tmp_instance_handles.clear();
1906  tmp_instance_handles.assign( instance_entity_list.size(), instance_set );
1907  status = mdbImpl->tag_set_data( mInstanceHandleTag, instance_entity_list, &tmp_instance_handles[0] );
1909 
1910  // Get all element sets in part
1911  instance_entity_list.clear();
1912  tag_val = ABQ_ELEMENT_SET;
1913  tag_data[0] = &tag_val;
1914  status = mdbImpl->get_entities_by_type_and_tag( instance_set, MBENTITYSET, &mSetTypeTag, tag_data, 1,
1915  instance_entity_list );
1917 
1918  tmp_instance_handles.clear();
1919  tmp_instance_handles.assign( instance_entity_list.size(), instance_set );
1920  status = mdbImpl->tag_set_data( mInstanceHandleTag, instance_entity_list, &tmp_instance_handles[0] );
1922 
1923  return MB_SUCCESS;
1924 }
1925 
1927  int ABQ_Set_Type,
1928  const std::string& set_name,
1929  EntityHandle& entity_set )
1930 {
1931  ErrorCode status;
1932 
1933  status = mdbImpl->create_meshset( MESHSET_SET, entity_set );
1935 
1936  status = mdbImpl->tag_set_data( mSetTypeTag, &entity_set, 1, &ABQ_Set_Type );
1938 
1939  status = mdbImpl->tag_set_data( mSetNameTag, &entity_set, 1, set_name.c_str() );
1941 
1942  status = mdbImpl->add_entities( parent_set, &entity_set, 1 );
1944 
1945  return MB_SUCCESS;
1946 }
1947 
1948 void ReadABAQUS::cyl2rect( std::vector< double > coord_list )
1949 {
1950  int num_nodes = coord_list.size() / 3;
1951  double x, y, r, t;
1952 
1953  for( int node = 0; node < num_nodes; node++ )
1954  {
1955  r = coord_list[3 * node];
1956  t = coord_list[3 * node + 1] * DEG2RAD;
1957 
1958  x = r * cos( t );
1959  y = r * sin( t );
1960 
1961  coord_list[3 * node] = x;
1962  coord_list[3 * node + 1] = y;
1963  }
1964 }
1965 
1966 void ReadABAQUS::sph2rect( std::vector< double > coord_list )
1967 {
1968  int num_nodes = coord_list.size() / 3;
1969  double x, y, z, r, t, p;
1970 
1971  for( int node = 0; node < num_nodes; node++ )
1972  {
1973  r = coord_list[3 * node];
1974  t = coord_list[3 * node + 1] * DEG2RAD;
1975  p = coord_list[3 * node + 2] * DEG2RAD;
1976 
1977  x = r * cos( p ) * cos( t );
1978  y = r * cos( p ) * sin( t );
1979  z = r * sin( p );
1980 
1981  coord_list[3 * node] = x;
1982  coord_list[3 * node + 1] = y;
1983  coord_list[3 * node + 2] = z;
1984  }
1985 }
1986 
1987 // PARSING RECOGNITION
1988 
1990 {
1991  readline.clear();
1992  std::getline( abFile, readline );
1993  ++lineNo;
1994 
1995  if( abFile.eof() ) return abq_eof;
1996 
1997  std::string::size_type pos = readline.find_first_not_of( ' ' );
1998 
1999  if( std::string::npos == pos ) return abq_blank_line;
2000 
2001  if( '*' == readline[pos] )
2002  if( '*' == readline[pos + 1] )
2003  return abq_comment_line;
2004  else
2005  return abq_keyword_line;
2006  else
2007  return abq_data_line;
2008 }
2009 
2011 {
2012  std::vector< std::string > tokens;
2013  std::map< std::string, abaqus_keyword_type > keywords;
2014 
2015  // Set up list of supported keywords
2016  // Note: any attempt to match something not in the keyword list
2017  // using the [] operator will create a new entry in the map
2018  // but that entry will have value abq_undefined based on the
2019  // definition of the abaqus_keyword_type enum.
2020  keywords[ABQ_AMBIGUOUS] = abq_ambiguous;
2021  keywords["HEADING"] = abq_heading;
2022  keywords["PART"] = abq_part;
2023  keywords["END PART"] = abq_end_part;
2024  keywords["ASSEMBLY"] = abq_assembly;
2025  keywords["END ASSEMBLY"] = abq_end_assembly;
2026  keywords["NODE"] = abq_node;
2027  keywords["ELEMENT"] = abq_element;
2028  keywords["NSET"] = abq_nset;
2029  keywords["ELSET"] = abq_elset;
2030  keywords["SOLID SECTION"] = abq_solid_section;
2031  keywords["INSTANCE"] = abq_instance;
2032  keywords["END INSTANCE"] = abq_end_instance;
2033 
2034  tokenize( readline, tokens, "*,\n" );
2035 
2036  // Convert to upper case and test for unambiguous match/partial match
2037  stringToUpper( tokens[0], tokens[0] );
2038  return keywords[match( tokens[0], keywords )];
2039 }
2040 
2041 // PARSING UTILITY FUNCTIONS
2042 
2043 // For a map of strings to values of type T
2044 // search the key list of the map for an unambiguous partial match with the token
2045 template < typename T >
2046 std::string ReadABAQUS::match( const std::string& token, std::map< std::string, T >& tokenList )
2047 {
2048  // Initialize with no match and ABQ_UNDEFINED as return string
2049  bool found_match = false;
2050  std::string best_match = ABQ_UNDEFINED;
2051 
2052  // Search the map
2053  for( typename std::map< std::string, T >::iterator thisToken = tokenList.begin(); thisToken != tokenList.end();
2054  ++thisToken )
2055  {
2056  // If a perfect match break the loop (assume keyword list is unambiguous)
2057  if( token == ( *thisToken ).first )
2058  {
2059  best_match = token;
2060  break;
2061  }
2062  else
2063  {
2064  int short_length =
2065  ( token.length() < ( *thisToken ).first.length() ? token.length() : ( *thisToken ).first.length() );
2066  // If the token matches the first token.length() characters of the keyword
2067  // consider this a match
2068  if( token.substr( short_length ) == ( *thisToken ).first.substr( short_length ) )
2069  {
2070  if( !found_match )
2071  {
2072  // If no match already, record match and matching keyword
2073  found_match = true;
2074  best_match = ( *thisToken ).first;
2075  }
2076  else
2077  // If match already set matching keyword to ABQ_AMBIGUOUS
2078  best_match = ABQ_AMBIGUOUS;
2079  }
2080  }
2081  }
2082 
2083  // Possible return values: ABQ_UNDEFINED, keyword from list, ABQ_AMBIGUOUS
2084  return best_match;
2085 }
2086 
2087 // Convert a string to upper case
2088 void ReadABAQUS::stringToUpper( const std::string& toBeConverted, std::string& converted )
2089 {
2090  converted = toBeConverted;
2091 
2092  for( unsigned int i = 0; i < toBeConverted.length(); i++ )
2093  converted[i] = toupper( toBeConverted[i] );
2094 }
2095 
2096 // Extract key/value pairs from parameter list
2097 void ReadABAQUS::extract_keyword_parameters( const std::vector< std::string >& tokens,
2098  std::map< std::string, std::string >& params )
2099 {
2100  std::string key, value;
2101 
2102  // NOTE: skip first token - it is the keyword
2103  for( std::vector< std::string >::const_iterator token = tokens.begin() + 1; token != tokens.end(); ++token )
2104  {
2105  std::string::size_type pos = token->find( '=' );
2106  stringToUpper( token->substr( 0, pos ), key );
2107  if( std::string::npos != pos )
2108  value = token->substr( pos + 1 );
2109  else
2110  value = "";
2111  pos = key.find_first_not_of( ' ', 0 );
2112  key = key.substr( pos );
2113  params[key] = value;
2114  }
2115 }
2116 
2117 // Tokenize a string based on a set of possible delimiters
2118 void ReadABAQUS::tokenize( const std::string& str, std::vector< std::string >& tokens, const char* delimiters )
2119 {
2120  tokens.clear();
2121 
2122  std::string::size_type pos, last = str.find_first_not_of( delimiters, 0 );
2123 
2124  while( std::string::npos != last )
2125  {
2126  pos = str.find_first_of( delimiters, last );
2127  if( std::string::npos == pos )
2128  {
2129  tokens.push_back( str.substr( last ) );
2130  last = std::string::npos;
2131  }
2132  else
2133  {
2134  tokens.push_back( str.substr( last, pos - last ) );
2135  last = str.find_first_not_of( delimiters, pos );
2136  }
2137  }
2138 }
2139 
2140 } // namespace moab