25 #include "libmesh/abaqus_io.h" 
   26 #include "libmesh/point.h" 
   27 #include "libmesh/elem.h" 
   28 #include "libmesh/enum_to_string.h" 
   29 #include "libmesh/boundary_info.h" 
   30 #include "libmesh/utility.h" 
   31 #include <unordered_map> 
   44 bool string_to_num(
const std::string & input, 
dof_id_type & output)
 
   47   output = cast_int<dof_id_type>
 
   48     (std::strtol(input.c_str(), &endptr, 10));
 
   50   return (output != 0 || endptr != input.c_str());
 
   57 void strip_ws(std::string & line)
 
   59   line.erase(std::remove_if(line.begin(), line.end(), isspace), line.end());
 
   66 struct ElementDefinition
 
   69   std::vector<unsigned> abaqus_zero_based_node_id_to_libmesh_node_id;
 
   72   std::vector<unsigned short> abaqus_zero_based_side_id_to_libmesh_side_id;
 
   78 std::map<ElemType, ElementDefinition> eletypes;
 
   83 void add_eletype_entry(
ElemType libmesh_elem_type,
 
   84                        const unsigned * node_map,
 
   85                        unsigned node_map_size,
 
   86                        const unsigned short * side_map,
 
   87                        unsigned side_map_size)
 
   90   ElementDefinition & map_entry = eletypes[libmesh_elem_type];
 
   97     (node_map, node_map+node_map_size).swap
 
   98     (map_entry.abaqus_zero_based_node_id_to_libmesh_node_id);
 
  100   std::vector<unsigned short>
 
  101     (side_map, side_map+side_map_size).swap
 
  102     (map_entry.abaqus_zero_based_side_id_to_libmesh_side_id);
 
  109 void init_eletypes ()
 
  115   if (eletypes.empty())
 
  119         const unsigned int   node_map[] = {0,1}; 
 
  120         const unsigned short side_map[] = {0,1}; 
 
  121         add_eletype_entry(
EDGE2, node_map, 2, side_map, 2);
 
  126         const unsigned int   node_map[] = {0,1,2}; 
 
  127         const unsigned short side_map[] = {0,1,2}; 
 
  128         add_eletype_entry(
TRI3, node_map, 3, side_map, 3);
 
  133         const unsigned int   node_map[] = {0,1,2,3}; 
 
  134         const unsigned short side_map[] = {0,1,2,3}; 
 
  135         add_eletype_entry(
QUAD4, node_map, 4, side_map, 4);
 
  140         const unsigned int   node_map[] = {0,1,2,3}; 
 
  141         const unsigned short side_map[] = {0,1,2,3}; 
 
  142         add_eletype_entry(
TET4, node_map, 4, side_map, 4);
 
  147         const unsigned int   node_map[] = {0,1,2,3,4,5,6,7,8,9}; 
 
  148         const unsigned short side_map[] = {0,1,2,3};             
 
  149         add_eletype_entry(
TET10, node_map, 10, side_map, 4);
 
  154         const unsigned int   node_map[] = {0,1,2,3,4,5,6,7}; 
 
  155         const unsigned short side_map[] = {0,5,1,2,3,4};     
 
  156         add_eletype_entry(
HEX8, node_map, 8, side_map, 6);
 
  161         const unsigned int   node_map[] = 
 
  162           {0,1,2,3,4,5,6,7,8,9,10,11,16,17,18,19,12,13,14,15};
 
  163         const unsigned short side_map[] = 
 
  165         add_eletype_entry(
HEX20, node_map, 20, side_map, 6);
 
  170         const unsigned int   node_map[] = 
 
  171           {0,1,2,3,4,5,6,7,8,9,10,11,16,17,18,19,12,13,14,15,26,20,25,21,22,23,24};
 
  172         const unsigned short side_map[] = 
 
  174         add_eletype_entry(
HEX27, node_map, 27, side_map, 6);
 
  179         const unsigned int   node_map[] = {0,1,2,3,4,5}; 
 
  180         const unsigned short side_map[] = {0,4,1,2,3};   
 
  181         add_eletype_entry(
PRISM6, node_map, 6, side_map, 5);
 
  186         const unsigned int   node_map[] = 
 
  187           {0,1,2,3,4,5,6,7,8,12,13,14,9,10,11};
 
  188         const unsigned short side_map[] = 
 
  190         add_eletype_entry(
PRISM15, node_map, 15, side_map, 5);
 
  195         const unsigned int   node_map[] = 
 
  196           {0,1,2,3,4,5,6,7,8,12,13,14,9,10,11,15,16,17};
 
  197         const unsigned short side_map[] = 
 
  199         add_eletype_entry(
PRISM18, node_map, 18, side_map, 5);
 
  214   build_sidesets_from_nodesets(false),
 
  215   _already_seen_part(false)
 
  238   _in.open(fname.c_str());
 
  253       std::getline(
_in, s);
 
  266           std::string upper(s);
 
  267           std::transform(upper.begin(), upper.end(), upper.begin(), ::toupper);
 
  270           if (upper.find(
"*PART") == static_cast<std::string::size_type>(0))
 
  273                 libmesh_error_msg(
"We currently don't support reading Abaqus files with multiple PART sections");
 
  279           if (upper.find(
"*NODE") == static_cast<std::string::size_type>(0))
 
  286               if (upper.find(
"*NODE OUTPUT") == static_cast<std::string::size_type>(0))
 
  291               std::string nset_name = this->
parse_label(s, 
"nset");
 
  303           else if (upper.find(
"*ELEMENT,") == static_cast<std::string::size_type>(0))
 
  310               if (upper.find(
"*ELEMENT OUTPUT") == static_cast<std::string::size_type>(0))
 
  315               std::string elset_name = this->
parse_label(s, 
"elset");
 
  327           else if (upper.find(
"*NSET") == static_cast<std::string::size_type>(0))
 
  329               std::string nset_name = this->
parse_label(s, 
"nset");
 
  334                 libmesh_error_msg(
"Unnamed nset encountered!");
 
  353           else if (upper.find(
"*ELSET") == static_cast<std::string::size_type>(0))
 
  355               std::string elset_name = this->
parse_label(s, 
"elset");
 
  359               if (elset_name == 
"")
 
  360                 libmesh_error_msg(
"Unnamed elset encountered!");
 
  381           else if (upper.find(
"*SURFACE,") == static_cast<std::string::size_type>(0))
 
  384               std::string sideset_name = this->
parse_label(s, 
"name");
 
  402       libmesh_error_msg(
"Stream is bad! Perhaps the file: " << fname << 
" does not exist?");
 
  431       if (elem->dim() < max_dim)
 
  468   std::vector<dof_id_type> * id_storage = 
nullptr;
 
  475   while (
_in.peek() != 
'*' && 
_in.peek() != EOF)
 
  479       std::getline(
_in, line);
 
  488       std::stringstream ss(line);
 
  496       ss >> abaqus_node_id >> c >> x >> c >> y;
 
  500       if (ss.peek() == 
',')
 
  505         id_storage->push_back(abaqus_node_id);
 
  530   unsigned n_nodes_per_elem = 0;
 
  533   if (upper.find(
"T3D2") != std::string::npos ||
 
  534       upper.find(
"B31") != std::string::npos)
 
  537       n_nodes_per_elem = 2;
 
  540   else if (upper.find(
"B32") != std::string::npos)
 
  543       n_nodes_per_elem = 3;
 
  546   else if (upper.find(
"S3") != std::string::npos ||
 
  547            upper.find(
"CPE3") != std::string::npos ||
 
  548            upper.find(
"2D3") != std::string::npos)
 
  551       n_nodes_per_elem = 3;
 
  554   else if (upper.find(
"CPE4") != std::string::npos ||
 
  555            upper.find(
"S4") != std::string::npos ||
 
  556            upper.find(
"CPEG4") != std::string::npos ||
 
  557            upper.find(
"2D4") != std::string::npos)
 
  560       n_nodes_per_elem = 4;
 
  563   else if (upper.find(
"CPE6") != std::string::npos ||
 
  564            upper.find(
"S6") != std::string::npos ||
 
  565            upper.find(
"CPEG6") != std::string::npos ||
 
  566            upper.find(
"2D6") != std::string::npos)
 
  569       n_nodes_per_elem = 6;
 
  572   else if (upper.find(
"CPE8") != std::string::npos ||
 
  573            upper.find(
"S8") != std::string::npos ||
 
  574            upper.find(
"CPEG8") != std::string::npos ||
 
  575            upper.find(
"2D8") != std::string::npos)
 
  578       n_nodes_per_elem = 8;
 
  581   else if (upper.find(
"3D8") != std::string::npos)
 
  584       n_nodes_per_elem = 8;
 
  587   else if (upper.find(
"3D4") != std::string::npos)
 
  590       n_nodes_per_elem = 4;
 
  593   else if (upper.find(
"3D20") != std::string::npos)
 
  596       n_nodes_per_elem = 20;
 
  599   else if (upper.find(
"3D27") != std::string::npos)
 
  602       n_nodes_per_elem = 27;
 
  605   else if (upper.find(
"3D6") != std::string::npos)
 
  608       n_nodes_per_elem = 6;
 
  611   else if (upper.find(
"3D15") != std::string::npos)
 
  614       n_nodes_per_elem = 15;
 
  617   else if (upper.find(
"3D10") != std::string::npos)
 
  620       n_nodes_per_elem = 10;
 
  624     libmesh_error_msg(
"Unrecognized element type: " << upper);
 
  630   const ElementDefinition & eledef = eletypes[elem_type];
 
  634   if (eledef.abaqus_zero_based_node_id_to_libmesh_node_id.size() == 0)
 
  635     libmesh_error_msg(
"No Abaqus->LibMesh mapping information for ElemType " \
 
  641   while (
_in.peek() != 
'*' && 
_in.peek() != EOF)
 
  648       _in >> abaqus_elem_id >> c;
 
  661       while (id_count < n_nodes_per_elem)
 
  664           std::string csv_line;
 
  665           std::getline(
_in, csv_line);
 
  668           std::stringstream line_stream(csv_line);
 
  672           while (std::getline(line_stream, cell, 
','))
 
  675               bool success = string_to_num(cell, abaqus_global_node_id);
 
  683                   Node * node = the_mesh.
node_ptr(libmesh_global_node_id);
 
  688                     libmesh_error_msg(
"Error!  Mesh::node_ptr() returned nullptr.  Either no node exists with ID " \
 
  689                                       << libmesh_global_node_id         \
 
  690                                       << 
" or perhaps this input file has *Elements defined before *Nodes?");
 
  694                   unsigned libmesh_elem_local_node_id =
 
  695                     eledef.abaqus_zero_based_node_id_to_libmesh_node_id[id_count];
 
  698                   elem->
set_node(libmesh_elem_local_node_id) = node;
 
  707       if (id_count != n_nodes_per_elem)
 
  708         libmesh_error_msg(
"Error: Needed to read " \
 
  709                           << n_nodes_per_elem      \
 
  710                           << 
" nodes, but read "   \
 
  716       if (elset_name != 
"")
 
  741     upper_label_name(label_name);
 
  742   std::transform(upper_line.begin(), upper_line.end(), upper_line.begin(), ::toupper);
 
  743   std::transform(upper_label_name.begin(), upper_label_name.end(), upper_label_name.begin(), ::toupper);
 
  746   size_t label_index = upper_line.find(upper_label_name + 
"=");
 
  748   if (label_index != std::string::npos)
 
  751       size_t comma_index = upper_line.find(
",", label_index);
 
  755       std::string::iterator
 
  756         beg = line.begin() + label_name.size() + 1 + label_index,
 
  757         end = (comma_index == std::string::npos) ? line.end() : line.begin() + comma_index;
 
  759       return std::string(beg, 
end);
 
  763   return std::string(
"");
 
  776   std::stringstream line_stream(upper);
 
  777   while (std::getline(line_stream, cell, 
','))
 
  778     if (cell == 
"GENERATE")
 
  789   std::vector<dof_id_type> & id_storage = container[set_name];
 
  792   while (
_in.peek() != 
'*' && 
_in.peek() != EOF)
 
  795       std::string csv_line;
 
  796       std::getline(
_in, csv_line);
 
  801       std::stringstream line_stream(csv_line);
 
  802       while (std::getline(line_stream, cell, 
','))
 
  805           bool success = string_to_num(cell, 
id);
 
  811             id_storage.push_back(
id);
 
  822   std::vector<dof_id_type> & id_storage = container[set_name];
 
  827   while (
_in.peek() != 
'*' && 
_in.peek() != EOF)
 
  830       std::string csv_line;
 
  831       std::getline(
_in, csv_line);
 
  840       std::stringstream line_stream(csv_line);
 
  841       line_stream >> start >> c >> 
end >> c >> stride;
 
  848       for (
dof_id_type current = start; current <= 
end; current += stride)
 
  849         id_storage.push_back(current);
 
  859   std::vector<std::pair<dof_id_type, unsigned>> & id_storage = container[sideset_name];
 
  864   std::string elem_id_or_set, dummy;
 
  867   while (
_in.peek() != 
'*' && 
_in.peek() != EOF)
 
  872       std::getline(
_in, elem_id_or_set, 
',');
 
  876       strip_ws(elem_id_or_set);
 
  885       bool success = string_to_num(elem_id_or_set, elem_id);
 
  890           id_storage.push_back( std::make_pair(elem_id, side_id) );
 
  895           const auto & vec = libmesh_map_find(
_elemset_ids, elem_id_or_set);
 
  896           for (
const auto & elem_id_in_elset : vec)
 
  897             id_storage.push_back( std::make_pair(elem_id_in_elset, side_id) );
 
  901       std::getline(
_in, dummy);
 
  918   std::map<ElemType, unsigned> elem_types_map;
 
  922       elem_types_map[type] = ctr++;
 
  932     for (
unsigned elemset_id=0; it != 
end; ++it, ++elemset_id)
 
  935         std::vector<dof_id_type> & id_vector = it->second;
 
  938         for (
const auto & 
id : id_vector)
 
  952             if (elem.
dim() < max_dim)
 
  958               (elemset_id + (elem_types_map[elem.
type()] * n_elemsets));
 
  984   for (
unsigned short current_id=0; it != 
end; ++it, ++current_id)
 
  990       std::vector<dof_id_type> & nodeset_ids = it->second;
 
  992       for (
const auto & 
id : nodeset_ids)
 
  998           Node * node = the_mesh.
node_ptr(libmesh_global_node_id);
 
 1000           if (node == 
nullptr)
 
 1001             libmesh_error_msg(
"Error! Mesh::node_ptr() returned nullptr!");
 
 1024     for (
unsigned short current_id=0; it != 
end; ++it, ++current_id)
 
 1030         std::vector<std::pair<dof_id_type,unsigned>> & sideset_ids = it->second;
 
 1032         for (
const auto & 
id : sideset_ids)
 
 1037             unsigned abaqus_side_number = 
id.second;
 
 1046             const ElementDefinition & eledef = eletypes[elem.
type()];
 
 1050             if (eledef.abaqus_zero_based_side_id_to_libmesh_side_id.size() == 0)
 
 1051               libmesh_error_msg(
"No Abaqus->LibMesh mapping information for ElemType " \
 
 1061                eledef.abaqus_zero_based_side_id_to_libmesh_side_id[abaqus_side_number-1],
 
 1082     std::unordered_multimap<dof_id_type, std::pair<Elem *, boundary_id_type>> provide_bcs;
 
 1091         std::vector<dof_id_type> & id_vector = it->second;
 
 1094         for (
const auto & 
id : id_vector)
 
 1105             if (elem.
dim() == max_dim)
 
 1112             if (elem.
dim()+1 != max_dim)
 
 1113               libmesh_error_msg(
"ERROR: Expected boundary element of dimension " << max_dim-1 << 
" but got " << elem.
dim());
 
 1116             provide_bcs.insert(std::make_pair(elem.
key(),
 
 1117                                               std::make_pair(&elem,
 
 1130       if (elem->dim() == max_dim)
 
 1131         for (
auto sn : elem->side_index_range())
 
 1139             auto bounds = provide_bcs.equal_range (elem->key(sn));
 
 1142             for (
const auto & pr : 
as_range(bounds))
 
 1145                 std::unique_ptr<Elem> side (elem->build_side_ptr(sn));
 
 1148                 Elem * lower_dim_elem = pr.second.first;
 
 1152                 if (*lower_dim_elem == *side)
 
 1170       if (
_in.peek() == 
'*')
 
 1176           if (
_in.peek() == 
'*')
 
 1180               std::getline(
_in, dummy);
 
 1206   unsigned char max_dim = 0;
 
 1208   unsigned char elem_dimensions_size = cast_int<unsigned char>
 
 1211   for (
unsigned char i=1; i<elem_dimensions_size; ++i)