Mesh Oriented datABase  (version 5.6.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" );
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" );
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" );
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" );
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" );
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" );
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" );
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" );
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 );
1484  MB_CHK_SET_ERR( status, "Did not find any sets of that type" );
1485 
1486  for( Range::iterator this_set = sets.begin(); this_set != sets.end() && 0 == set_handle; ++this_set )
1487  {
1488  std::fill( this_set_name, this_set_name + ABAQUS_SET_NAME_LENGTH, '\0' );
1489  status = mdbImpl->tag_get_data( mSetNameTag, &( *this_set ), 1, &this_set_name[0] );
1490  if( MB_SUCCESS != status && MB_TAG_NOT_FOUND != status ) return status;
1491 
1492  if( set_name == std::string( this_set_name ) ) set_handle = *this_set;
1493  }
1494 
1495  if( 0 == set_handle )
1496  {
1497  MB_SET_ERR( MB_FAILURE, "Did not find requested set" );
1498  }
1499 
1500  return MB_SUCCESS;
1501 }
1502 
1504 {
1505  ErrorCode status;
1506 
1507  Range dim_ent_list;
1508 
1509  // Could have elements of multiple dimensions in this set???
1510  for( int dim = 1; dim <= 3; dim++ )
1511  {
1512  dim_ent_list.clear();
1513  status = mdbImpl->get_entities_by_dimension( set_handle, dim, dim_ent_list );
1515 
1516  element_range.merge( dim_ent_list );
1517  }
1518 
1519  return MB_SUCCESS;
1520 }
1521 
1523  int ABQ_set_type,
1524  const std::string& set_name,
1525  Range& element_range )
1526 {
1527  ErrorCode status;
1528 
1529  EntityHandle set_handle;
1530  status = get_set_by_name( parent_set, ABQ_set_type, set_name, set_handle );
1532 
1533  status = get_set_elements( set_handle, element_range );
1535 
1536  if( element_range.size() == 0 )
1537  {
1538  // std::cout << "No elements were found in set " << set_name << std::endl;
1539  }
1540 
1541  return MB_SUCCESS;
1542 }
1543 
1545  int ABQ_set_type,
1546  const std::string& set_name,
1547  Range& node_range )
1548 {
1549  ErrorCode status;
1550 
1551  EntityHandle set_handle;
1552  status = get_set_by_name( parent_set, ABQ_set_type, set_name, set_handle );
1554 
1555  Range ent_list;
1556  Range dim_ent_list;
1557  // Could have elements of multiple dimensions in this set???
1558  for( int dim = 0; dim <= 3; dim++ )
1559  {
1560  dim_ent_list.clear();
1561  status = mdbImpl->get_entities_by_dimension( set_handle, dim, dim_ent_list );
1563 
1564  ent_list.merge( dim_ent_list );
1565  }
1566 
1567  status = mdbImpl->get_adjacencies( ent_list, 0, false, node_range );
1569 
1570  if( node_range.size() == 0 )
1571  {
1572  std::cout << "No nodes were found in set " << set_name << std::endl;
1573  }
1574 
1575  return MB_SUCCESS;
1576 }
1577 
1578 Tag ReadABAQUS::get_tag( const char* tag_name,
1579  int tag_size,
1580  TagType tag_type,
1581  DataType tag_data_type,
1582  const void* def_val )
1583 {
1584  Tag retval;
1585 
1586  ErrorCode rval =
1587  mdbImpl->tag_get_handle( tag_name, tag_size, tag_data_type, retval, tag_type | MB_TAG_CREAT, def_val );
1588  assert( MB_SUCCESS == rval );
1589  return MB_SUCCESS == rval ? retval : 0;
1590 }
1591 
1593  const EntityHandle assembly_set,
1594  const std::string& part_name,
1595  const std::string& /*instance_name*/,
1596  EntityHandle& instance_set,
1597  const std::vector< double >& translation,
1598  const std::vector< double >& rotation )
1599 {
1600  ErrorCode status;
1601 
1602  EntityHandle part_set;
1603  status = get_set_by_name( file_set, ABQ_PART_SET, part_name, part_set );
1605 
1606  // Cross-reference
1607  status = mdbImpl->tag_set_data( mPartHandleTag, &instance_set, 1, &part_set );
1609 
1610  int instance_id = ++num_part_instances[part_set];
1611  status = mdbImpl->tag_set_data( mInstancePIDTag, &instance_set, 1, &instance_id );
1613 
1614  status = mdbImpl->tag_set_data( mAssemblyHandleTag, &instance_set, 1, &assembly_set );
1616 
1617  instance_id = ++num_assembly_instances[assembly_set];
1618  status = mdbImpl->tag_set_data( mInstanceGIDTag, &instance_set, 1, &instance_id );
1620 
1621  // Create maps to cross-reference the part and instance versions of each entity
1622  std::map< EntityHandle, EntityHandle > p2i_nodes, p2i_elements;
1623 
1624  // ---- NODES ----
1625 
1626  // Get all nodes and IDs
1627  Range part_node_list;
1628  status = mdbImpl->get_entities_by_dimension( part_set, 0, part_node_list );
1630 
1631  if( 0 < part_node_list.size() )
1632  {
1633  std::vector< int > node_ids( part_node_list.size() );
1634  status = mdbImpl->tag_get_data( mLocalIDTag, part_node_list, &node_ids[0] );
1636 
1637  // std::map<int, EntityHandle> nodeIdMap;
1638  // for (unsigned int idx = 0; idx < part_node_list.size(); idx++)
1639  // nodeIdMap[node_ids[idx]] = part_node_list[idx];
1640 
1641  // Create new nodes
1642  std::vector< double* > coord_arrays( 3 );
1643  EntityHandle start_node = 0;
1644  status = readMeshIface->get_node_coords( 3, part_node_list.size(), MB_START_ID, start_node, coord_arrays );
1646 
1647  if( 0 == start_node ) return MB_FAILURE;
1648 
1649  // Copy coordinates into new coord_arrays
1650  status = mdbImpl->get_coords( part_node_list, coord_arrays[0], coord_arrays[1], coord_arrays[2] );
1651 
1652  // Rotate to new position
1653  double rot_axis[3];
1654  rot_axis[0] = rotation[3] - rotation[0];
1655  rot_axis[1] = rotation[4] - rotation[1];
1656  rot_axis[2] = rotation[5] - rotation[2];
1657 
1658  AffineXform rotationXform;
1659  if( rotation[6] != 0 ) rotationXform = AffineXform::rotation( rotation[6] * DEG2RAD, rot_axis );
1660 
1661  // Translate to new position
1662  for( unsigned int idx = 0; idx < part_node_list.size(); idx++ )
1663  {
1664  double coords[3];
1665 
1666  // Transform to new location and then shift origin of rotation
1667  for( unsigned int dim = 0; dim < 3; dim++ )
1668  coords[dim] = coord_arrays[dim][idx] + translation[dim] - rotation[dim];
1669 
1670  // Rotate around this origin
1671  if( rotation[6] != 0 ) rotationXform.xform_vector( coords );
1672 
1673  // Transform origin of rotation back
1674  for( unsigned int dim = 0; dim < 3; dim++ )
1675  coord_arrays[dim][idx] = coords[dim] + rotation[dim];
1676  }
1677 
1678  Range instance_node_list( start_node, start_node + part_node_list.size() - 1 );
1679 
1680  // (DO NOT) add nodes to file_set
1681  // status = mdbImpl->add_entities(file_set, instance_node_list);
1682  // MB_RETURN_IF_FAIL;
1683 
1684  // Add nodes to this instance_set
1685  status = mdbImpl->add_entities( instance_set, instance_node_list );
1687 
1688  // Add nodes to this assembly_set
1689  status = mdbImpl->add_entities( assembly_set, instance_node_list );
1691 
1692  // Tag nodes with their local ID's
1693  status = mdbImpl->tag_set_data( mLocalIDTag, instance_node_list, &node_ids[0] );
1695 
1696  // Create a map of old handles to new handles!!!
1697  for( unsigned int idx = 0; idx < part_node_list.size(); idx++ )
1698  p2i_nodes[part_node_list[idx]] = instance_node_list[idx];
1699  }
1700 
1701  // ---- ELEMENTS ----
1702 
1703  Range part_element_list;
1704  status = get_set_elements( part_set, part_element_list );
1706 
1707  if( 0 < part_element_list.size() )
1708  {
1709  std::vector< int > part_element_ids( part_element_list.size() );
1710  status = mdbImpl->tag_get_data( mLocalIDTag, part_element_list, &part_element_ids[0] );
1712 
1713  // std::map<int, EntityHandle> elementIdMap;
1714  // for (unsigned int idx = 0; idx < part_element_list.size(); idx++)
1715  // elementIdMap[part_element_ids[idx]] = part_element_list[idx];
1716 
1717  // Create new elements
1718  Range instance_element_list;
1719  instance_element_list.clear();
1720 
1721  // Cross-referencing storage and pointers/iterators
1722  std::vector< int > instance_element_ids;
1723  std::vector< int >::iterator part_element_id = part_element_ids.begin();
1724 
1725  for( Range::iterator part_element = part_element_list.begin(); part_element != part_element_list.end();
1726  ++part_element, ++part_element_id )
1727  {
1728  EntityType element_type = mdbImpl->type_from_handle( *part_element );
1729  std::vector< EntityHandle > part_connectivity, instance_connectivity;
1730  EntityHandle new_element;
1731  status = mdbImpl->get_connectivity( &( *part_element ), 1, part_connectivity );
1733 
1734  instance_connectivity.clear();
1735  for( std::vector< EntityHandle >::iterator connectivity_node = part_connectivity.begin();
1736  connectivity_node != part_connectivity.end(); ++connectivity_node )
1737  instance_connectivity.push_back( p2i_nodes[*connectivity_node] );
1738 
1739  status = mdbImpl->create_element( element_type, &instance_connectivity[0], instance_connectivity.size(),
1740  new_element );
1742 
1743  instance_element_list.insert( new_element );
1744  p2i_elements[*part_element] = new_element;
1745  instance_element_ids.push_back( *part_element_id );
1746  }
1747 
1748  // (DO NOT) add elements to file_set
1749  // status = mdbImpl->add_entities(file_set, instance_element_list);
1750  // MB_RETURN_IF_FAIL;
1751 
1752  // Add elements to this instance_set
1753  status = mdbImpl->add_entities( instance_set, instance_element_list );
1755 
1756  // Add elements to this assembly_set
1757  status = mdbImpl->add_entities( assembly_set, instance_element_list );
1759 
1760  // Tag elements with their local ID's
1761  status = mdbImpl->tag_set_data( mLocalIDTag, instance_element_list, &( instance_element_ids[0] ) );
1763  }
1764 
1765  // ----- NODE SETS -----
1766 
1767  // Get all node sets in part
1768  Range part_node_sets;
1769  int tag_val = ABQ_NODE_SET;
1770  void* tag_data[] = { &tag_val };
1771  status = mdbImpl->get_entities_by_type_and_tag( part_set, MBENTITYSET, &mSetTypeTag, tag_data, 1, part_node_sets );
1773 
1774  Range part_node_set_list, instance_node_set_list;
1775  for( Range::iterator part_node_set = part_node_sets.begin(); part_node_set != part_node_sets.end();
1776  ++part_node_set )
1777  {
1778  char node_set_name[ABAQUS_SET_NAME_LENGTH];
1779  std::fill( node_set_name, node_set_name + ABAQUS_SET_NAME_LENGTH, '\0' );
1780  status = mdbImpl->tag_get_data( mSetNameTag, &( *part_node_set ), 1, &node_set_name[0] );
1781  if( MB_SUCCESS != status && MB_TAG_NOT_FOUND != status ) return status;
1782 
1783  part_node_set_list.clear();
1784  status = mdbImpl->get_entities_by_dimension( *part_node_set, 0, part_node_set_list );
1785 
1786  instance_node_set_list.clear();
1787  for( Range::iterator set_node = part_node_set_list.begin(); set_node != part_node_set_list.end(); ++set_node )
1788  instance_node_set_list.insert( p2i_nodes[*set_node] );
1789 
1790  EntityHandle instance_node_set;
1791 
1792  status = add_entity_set( instance_set, ABQ_NODE_SET, node_set_name, instance_node_set );
1794 
1795  status = mdbImpl->add_entities( instance_node_set, instance_node_set_list );
1797 
1798  status = mdbImpl->add_entities( assembly_set, &instance_node_set, 1 );
1800 
1801  status = mdbImpl->tag_set_data( mPartHandleTag, &instance_node_set, 1, &part_set );
1803 
1804  status = mdbImpl->tag_set_data( mAssemblyHandleTag, &instance_node_set, 1, &assembly_set );
1806  }
1807 
1808  // ----- ELEMENT SETS -----
1809 
1810  // Get all element sets in part
1811  Range part_element_sets;
1812  tag_val = ABQ_ELEMENT_SET;
1813  tag_data[0] = &tag_val;
1814  status =
1815  mdbImpl->get_entities_by_type_and_tag( part_set, MBENTITYSET, &mSetTypeTag, tag_data, 1, part_element_sets );
1817 
1818  Range part_element_set_list, instance_element_set_list;
1819  for( Range::iterator part_element_set = part_element_sets.begin(); part_element_set != part_element_sets.end();
1820  ++part_element_set )
1821  {
1822  char element_set_name[ABAQUS_SET_NAME_LENGTH];
1823  std::fill( element_set_name, element_set_name + ABAQUS_SET_NAME_LENGTH, '\0' );
1824  status = mdbImpl->tag_get_data( mSetNameTag, &( *part_element_set ), 1, &element_set_name[0] );
1825  if( MB_SUCCESS != status && MB_TAG_NOT_FOUND != status ) return status;
1826 
1827  part_element_set_list.clear();
1828  status = get_set_elements( *part_element_set, part_element_set_list );
1829 
1830  instance_element_set_list.clear();
1831  for( Range::iterator set_element = part_element_set_list.begin(); set_element != part_element_set_list.end();
1832  ++set_element )
1833  instance_element_set_list.insert( p2i_elements[*set_element] );
1834 
1835  EntityHandle instance_element_set;
1836  status = add_entity_set( instance_set, ABQ_ELEMENT_SET, element_set_name, instance_element_set );
1838 
1839  // std::cerr << instance_set << "\t" << instance_element_set << std::endl;
1840  status = mdbImpl->add_entities( instance_element_set, instance_element_set_list );
1842 
1843  status = mdbImpl->add_entities( assembly_set, &instance_element_set, 1 );
1845 
1846  // status = mdbImpl->add_entities(file_set, &instance_element_set, 1);
1847  // MB_RETURN_IF_FAIL;
1848 
1849  status = mdbImpl->tag_set_data( mPartHandleTag, &instance_element_set, 1, &part_set );
1851 
1852  status = mdbImpl->tag_set_data( mAssemblyHandleTag, &instance_element_set, 1, &assembly_set );
1854 
1855  char element_set_matname[ABAQUS_SET_NAME_LENGTH];
1856  std::fill( element_set_matname, element_set_matname + ABAQUS_SET_NAME_LENGTH, '\0' );
1857  status = mdbImpl->tag_get_data( mMatNameTag, &( *part_element_set ), 1, &element_set_matname[0] );
1858  if( MB_SUCCESS != status && MB_TAG_NOT_FOUND != status ) return status;
1859 
1860  if( MB_TAG_NOT_FOUND != status )
1861  {
1862  status = mdbImpl->tag_set_data( mMatNameTag, &instance_element_set, 1, element_set_matname );
1864  }
1865 
1866  int element_set_mat_id;
1867  status = mdbImpl->tag_get_data( mMaterialSetTag, &( *part_element_set ), 1, &element_set_mat_id );
1868  if( MB_SUCCESS != status && MB_TAG_NOT_FOUND != status ) return status;
1869 
1870  if( MB_TAG_NOT_FOUND != status )
1871  {
1872  status = mdbImpl->tag_set_data( mMaterialSetTag, &instance_element_set, 1, &element_set_mat_id );
1874  }
1875  }
1876 
1877  // Tag everything with their instance handle
1878  // some nodes are assigned outside of this routine so query final list of all
1879  // instance nodes, elements, etc
1880  Range instance_entity_list;
1881  status = mdbImpl->get_entities_by_dimension( instance_set, 0, instance_entity_list );
1883 
1884  std::vector< EntityHandle > tmp_instance_handles;
1885  tmp_instance_handles.assign( instance_entity_list.size(), instance_set );
1886  status = mdbImpl->tag_set_data( mInstanceHandleTag, instance_entity_list, &tmp_instance_handles[0] );
1888 
1889  instance_entity_list.clear();
1890  status = get_set_elements( instance_set, instance_entity_list );
1892 
1893  tmp_instance_handles.clear();
1894  tmp_instance_handles.assign( instance_entity_list.size(), instance_set );
1895  status = mdbImpl->tag_set_data( mInstanceHandleTag, instance_entity_list, &tmp_instance_handles[0] );
1897 
1898  // Get all node sets in instance
1899  instance_entity_list.clear();
1900  tag_val = ABQ_NODE_SET;
1901  tag_data[0] = &tag_val;
1902  status = mdbImpl->get_entities_by_type_and_tag( instance_set, MBENTITYSET, &mSetTypeTag, tag_data, 1,
1903  instance_entity_list );
1905 
1906  tmp_instance_handles.clear();
1907  tmp_instance_handles.assign( instance_entity_list.size(), instance_set );
1908  status = mdbImpl->tag_set_data( mInstanceHandleTag, instance_entity_list, &tmp_instance_handles[0] );
1910 
1911  // Get all element sets in part
1912  instance_entity_list.clear();
1913  tag_val = ABQ_ELEMENT_SET;
1914  tag_data[0] = &tag_val;
1915  status = mdbImpl->get_entities_by_type_and_tag( instance_set, MBENTITYSET, &mSetTypeTag, tag_data, 1,
1916  instance_entity_list );
1918 
1919  tmp_instance_handles.clear();
1920  tmp_instance_handles.assign( instance_entity_list.size(), instance_set );
1921  status = mdbImpl->tag_set_data( mInstanceHandleTag, instance_entity_list, &tmp_instance_handles[0] );
1923 
1924  return MB_SUCCESS;
1925 }
1926 
1928  int ABQ_Set_Type,
1929  const std::string& set_name,
1930  EntityHandle& entity_set )
1931 {
1932  ErrorCode status;
1933 
1934  status = mdbImpl->create_meshset( MESHSET_SET, entity_set );
1936 
1937  status = mdbImpl->tag_set_data( mSetTypeTag, &entity_set, 1, &ABQ_Set_Type );
1939 
1940  status = mdbImpl->tag_set_data( mSetNameTag, &entity_set, 1, set_name.c_str() );
1942 
1943  status = mdbImpl->add_entities( parent_set, &entity_set, 1 );
1945 
1946  return MB_SUCCESS;
1947 }
1948 
1949 void ReadABAQUS::cyl2rect( std::vector< double > coord_list )
1950 {
1951  int num_nodes = coord_list.size() / 3;
1952  double x, y, r, t;
1953 
1954  for( int node = 0; node < num_nodes; node++ )
1955  {
1956  r = coord_list[3 * node];
1957  t = coord_list[3 * node + 1] * DEG2RAD;
1958 
1959  x = r * cos( t );
1960  y = r * sin( t );
1961 
1962  coord_list[3 * node] = x;
1963  coord_list[3 * node + 1] = y;
1964  }
1965 }
1966 
1967 void ReadABAQUS::sph2rect( std::vector< double > coord_list )
1968 {
1969  int num_nodes = coord_list.size() / 3;
1970  double x, y, z, r, t, p;
1971 
1972  for( int node = 0; node < num_nodes; node++ )
1973  {
1974  r = coord_list[3 * node];
1975  t = coord_list[3 * node + 1] * DEG2RAD;
1976  p = coord_list[3 * node + 2] * DEG2RAD;
1977 
1978  x = r * cos( p ) * cos( t );
1979  y = r * cos( p ) * sin( t );
1980  z = r * sin( p );
1981 
1982  coord_list[3 * node] = x;
1983  coord_list[3 * node + 1] = y;
1984  coord_list[3 * node + 2] = z;
1985  }
1986 }
1987 
1988 // PARSING RECOGNITION
1989 
1991 {
1992  readline.clear();
1993  std::getline( abFile, readline );
1994  ++lineNo;
1995 
1996  if( abFile.eof() ) return abq_eof;
1997 
1998  std::string::size_type pos = readline.find_first_not_of( ' ' );
1999 
2000  if( std::string::npos == pos ) return abq_blank_line;
2001 
2002  if( '*' == readline[pos] )
2003  if( '*' == readline[pos + 1] )
2004  return abq_comment_line;
2005  else
2006  return abq_keyword_line;
2007  else
2008  return abq_data_line;
2009 }
2010 
2012 {
2013  std::vector< std::string > tokens;
2014  std::map< std::string, abaqus_keyword_type > keywords;
2015 
2016  // Set up list of supported keywords
2017  // Note: any attempt to match something not in the keyword list
2018  // using the [] operator will create a new entry in the map
2019  // but that entry will have value abq_undefined based on the
2020  // definition of the abaqus_keyword_type enum.
2021  keywords[ABQ_AMBIGUOUS] = abq_ambiguous;
2022  keywords["HEADING"] = abq_heading;
2023  keywords["PART"] = abq_part;
2024  keywords["END PART"] = abq_end_part;
2025  keywords["ASSEMBLY"] = abq_assembly;
2026  keywords["END ASSEMBLY"] = abq_end_assembly;
2027  keywords["NODE"] = abq_node;
2028  keywords["ELEMENT"] = abq_element;
2029  keywords["NSET"] = abq_nset;
2030  keywords["ELSET"] = abq_elset;
2031  keywords["SOLID SECTION"] = abq_solid_section;
2032  keywords["INSTANCE"] = abq_instance;
2033  keywords["END INSTANCE"] = abq_end_instance;
2034 
2035  tokenize( readline, tokens, "*,\n" );
2036 
2037  // Convert to upper case and test for unambiguous match/partial match
2038  stringToUpper( tokens[0], tokens[0] );
2039  return keywords[match( tokens[0], keywords )];
2040 }
2041 
2042 // PARSING UTILITY FUNCTIONS
2043 
2044 // For a map of strings to values of type T
2045 // search the key list of the map for an unambiguous partial match with the token
2046 template < typename T >
2047 std::string ReadABAQUS::match( const std::string& token, std::map< std::string, T >& tokenList )
2048 {
2049  // Initialize with no match and ABQ_UNDEFINED as return string
2050  bool found_match = false;
2051  std::string best_match = ABQ_UNDEFINED;
2052 
2053  // Search the map
2054  for( typename std::map< std::string, T >::iterator thisToken = tokenList.begin(); thisToken != tokenList.end();
2055  ++thisToken )
2056  {
2057  // If a perfect match break the loop (assume keyword list is unambiguous)
2058  if( token == ( *thisToken ).first )
2059  {
2060  best_match = token;
2061  break;
2062  }
2063  else
2064  {
2065  int short_length =
2066  ( token.length() < ( *thisToken ).first.length() ? token.length() : ( *thisToken ).first.length() );
2067  // If the token matches the first token.length() characters of the keyword
2068  // consider this a match
2069  if( token.substr( short_length ) == ( *thisToken ).first.substr( short_length ) )
2070  {
2071  if( !found_match )
2072  {
2073  // If no match already, record match and matching keyword
2074  found_match = true;
2075  best_match = ( *thisToken ).first;
2076  }
2077  else
2078  // If match already set matching keyword to ABQ_AMBIGUOUS
2079  best_match = ABQ_AMBIGUOUS;
2080  }
2081  }
2082  }
2083 
2084  // Possible return values: ABQ_UNDEFINED, keyword from list, ABQ_AMBIGUOUS
2085  return best_match;
2086 }
2087 
2088 // Convert a string to upper case
2089 void ReadABAQUS::stringToUpper( const std::string& toBeConverted, std::string& converted )
2090 {
2091  converted = toBeConverted;
2092 
2093  for( unsigned int i = 0; i < toBeConverted.length(); i++ )
2094  converted[i] = toupper( toBeConverted[i] );
2095 }
2096 
2097 // Extract key/value pairs from parameter list
2098 void ReadABAQUS::extract_keyword_parameters( const std::vector< std::string >& tokens,
2099  std::map< std::string, std::string >& params )
2100 {
2101  std::string key, value;
2102 
2103  // NOTE: skip first token - it is the keyword
2104  for( std::vector< std::string >::const_iterator token = tokens.begin() + 1; token != tokens.end(); ++token )
2105  {
2106  std::string::size_type pos = token->find( '=' );
2107  stringToUpper( token->substr( 0, pos ), key );
2108  if( std::string::npos != pos )
2109  value = token->substr( pos + 1 );
2110  else
2111  value = "";
2112  pos = key.find_first_not_of( ' ', 0 );
2113  key = key.substr( pos );
2114  params[key] = value;
2115  }
2116 }
2117 
2118 // Tokenize a string based on a set of possible delimiters
2119 void ReadABAQUS::tokenize( const std::string& str, std::vector< std::string >& tokens, const char* delimiters )
2120 {
2121  tokens.clear();
2122 
2123  std::string::size_type pos, last = str.find_first_not_of( delimiters, 0 );
2124 
2125  while( std::string::npos != last )
2126  {
2127  pos = str.find_first_of( delimiters, last );
2128  if( std::string::npos == pos )
2129  {
2130  tokens.push_back( str.substr( last ) );
2131  last = std::string::npos;
2132  }
2133  else
2134  {
2135  tokens.push_back( str.substr( last, pos - last ) );
2136  last = str.find_first_not_of( delimiters, pos );
2137  }
2138  }
2139 }
2140 
2141 } // namespace moab