20 #include "libmesh/libmesh_config.h" 
   21 #include "libmesh/libmesh_logging.h" 
   22 #include "libmesh/unv_io.h" 
   23 #include "libmesh/mesh_base.h" 
   24 #include "libmesh/edge_edge2.h" 
   25 #include "libmesh/face_quad4.h" 
   26 #include "libmesh/face_tri3.h" 
   27 #include "libmesh/face_tri6.h" 
   28 #include "libmesh/face_quad8.h" 
   29 #include "libmesh/face_quad9.h" 
   30 #include "libmesh/cell_tet4.h" 
   31 #include "libmesh/cell_hex8.h" 
   32 #include "libmesh/cell_hex20.h" 
   33 #include "libmesh/cell_tet10.h" 
   34 #include "libmesh/cell_prism6.h" 
   35 #include "libmesh/utility.h" 
   44 #include <unordered_map> 
   46 #ifdef LIBMESH_HAVE_GZSTREAM 
   47 # include "libmesh/ignore_warnings.h"  
   48 # include "gzstream.h"  
   49 # include "libmesh/restore_warnings.h" 
  100   if (file_name.rfind(
".gz") < file_name.size())
 
  102 #ifdef LIBMESH_HAVE_GZSTREAM 
  104       igzstream in_stream (file_name.c_str());
 
  109       libmesh_error_msg(
"ERROR:  You must have the zlib.h header files and libraries to read and write compressed streams.");
 
  117       std::ifstream in_stream (file_name.c_str());
 
  131     if (!in_stream.good())
 
  132       libmesh_error_msg(
"ERROR: Input file not good.");
 
  149         old_line = current_line;
 
  152         std::getline(in_stream, current_line);
 
  160             current_line.erase(std::remove_if(current_line.begin(), current_line.end(), isspace),
 
  179                   libmesh_error_msg(
"ERROR: The Nodes section must come before the Elements section of the UNV file!");
 
  192                 if (!found_node || !found_elem)
 
  193                   libmesh_error_msg(
"ERROR: The Nodes and Elements sections must come before the Groups section of the UNV file!");
 
  201             if (found_node && found_elem && found_group)
 
  213         libmesh_error_msg(
"Stream is bad! Perhaps the file does not exist?");
 
  219       libmesh_error_msg(
"ERROR: Could not find nodes!");
 
  222       libmesh_error_msg(
"ERROR: Could not find elements!");
 
  233       libmesh_error_msg(
"Cannot open dimension "                        \
 
  235                         << 
" mesh file when configured without "        \
 
  249         if (elem->dim() < max_dim)
 
  264   if (file_name.rfind(
".gz") < file_name.size())
 
  266 #ifdef LIBMESH_HAVE_GZSTREAM 
  268       ogzstream out_stream(file_name.c_str());
 
  273       libmesh_error_msg(
"ERROR:  You must have the zlib.h header files and libraries to read and write compressed streams.");
 
  282       std::ofstream out_stream (file_name.c_str());
 
  293   if (!out_file.good())
 
  294     libmesh_error_msg(
"ERROR: Output file not good.");
 
  306   LOG_SCOPE(
"nodes_in()",
"UNVIO");
 
  321   std::istringstream coords_stream;
 
  328       in_file >> node_label;
 
  331       if (node_label == -1)
 
  339       std::getline(in_file, line);
 
  342       std::getline(in_file, line);
 
  348           last_pos = line.find(
"D", last_pos);
 
  350           if (last_pos != std::string::npos)
 
  351             line.replace(last_pos, 1, 
"E");
 
  358       coords_stream.str(line);
 
  359       coords_stream.clear(); 
 
  363       std::array<Real, 3> xyz;
 
  365       coords_stream >> xyz[0] >> xyz[1] >> xyz[2];
 
  371       libmesh_assert_equal_to(xyz[1], 0);
 
  376       libmesh_assert_equal_to(xyz[2], 0);
 
  392   unsigned char max_dim = 0;
 
  394   unsigned char elem_dimensions_size = cast_int<unsigned char>
 
  397   for (
unsigned char i=1; i<elem_dimensions_size; ++i)
 
  409   std::string::size_type position = number.find(
"D", 6);
 
  411   if (position != std::string::npos)
 
  414       number.replace(position, 1, 
"e");
 
  437   typedef std::unordered_multimap<dof_id_type, Elem *> map_type;
 
  438   map_type provide_bcs;
 
  445       in_file >> group_number;
 
  447       if (group_number == -1)
 
  460       unsigned num_entities;
 
  461       std::string group_name;
 
  464         in_file >> dummy >> dummy >> dummy >> dummy >> dummy >> dummy
 
  468         in_file >> group_name;
 
  474         is_subdomain_group = 
false,
 
  475         is_sideset_group = 
false;
 
  491         unsigned entity_type_code, entity_tag, dummy;
 
  492         for (
unsigned entity=0; entity<num_entities; ++entity)
 
  494             in_file >> entity_type_code >> entity_tag >> dummy >> dummy;
 
  496             if (entity_type_code != 8)
 
  497               libMesh::err << 
"Warning, unrecognized entity type code = " 
  507                 unsigned libmesh_elem_id = it->second;
 
  513                 if (group_elem->
dim() < max_dim)
 
  515                     is_sideset_group = 
true;
 
  521                     if (group_elem->
dim()+1 != max_dim)
 
  522                       libmesh_error_msg(
"ERROR: Expected boundary element of dimension " \
 
  523                                         << max_dim-1 << 
" but got " << group_elem->
dim());
 
  528                       cast_int<subdomain_id_type>(group_number);
 
  531                     provide_bcs.insert(std::make_pair(group_elem->
key(), group_elem));
 
  535                 else if (group_elem->
dim() == max_dim)
 
  537                     is_subdomain_group = 
true;
 
  539                       cast_int<subdomain_id_type>(group_number);
 
  543                   libmesh_error_msg(
"ERROR: Found an elem with dim=" \
 
  544                                     << group_elem->
dim() << 
" > " << 
"max_dim=" << +max_dim);
 
  547               libMesh::err << 
"WARNING: UNV Element " << entity_tag << 
" not found while parsing groups." << std::endl;
 
  552       if (is_sideset_group)
 
  554           (cast_int<boundary_id_type>(group_number)) = group_name;
 
  556       if (is_subdomain_group)
 
  558           (cast_int<subdomain_id_type>(group_number)) = group_name;
 
  564     if (elem->dim() == max_dim)
 
  565       for (
auto sn : elem->side_index_range())
 
  566         for (
const auto & pr : 
as_range(provide_bcs.equal_range (elem->key(sn))))
 
  576             std::unique_ptr<Elem> side (elem->build_side_ptr(sn));
 
  579             Elem * lower_dim_elem = pr.second;
 
  582             if (*lower_dim_elem == *side)
 
  591   LOG_SCOPE(
"elements_in()",
"UNVIO");
 
  609   std::vector<unsigned int> node_labels (21);
 
  623   unsigned int assign_elem_nodes[21];
 
  630       in_file >> element_label;
 
  632       if (element_label == -1)
 
  635       in_file >> fe_descriptor_id        
 
  653       if (fe_descriptor_id < 25)
 
  656           in_file >> dummy >> dummy >> dummy;
 
  660       for (
unsigned int j=1; j<=
n_nodes; j++)
 
  661         in_file >> node_labels[j];
 
  664       Elem * elem = 
nullptr;
 
  666       switch (fe_descriptor_id)
 
  672             assign_elem_nodes[1]=0;
 
  673             assign_elem_nodes[2]=1;
 
  682             assign_elem_nodes[1]=0;
 
  683             assign_elem_nodes[2]=2;
 
  684             assign_elem_nodes[3]=1;
 
  693             assign_elem_nodes[1]=0;
 
  694             assign_elem_nodes[2]=5;
 
  695             assign_elem_nodes[3]=2;
 
  696             assign_elem_nodes[4]=4;
 
  697             assign_elem_nodes[5]=1;
 
  698             assign_elem_nodes[6]=3;
 
  703           libmesh_error_msg(
"ERROR: UNV-element type 43: Plane Stress Cubic Triangle not supported.");
 
  710             assign_elem_nodes[1]=0;
 
  711             assign_elem_nodes[2]=3;
 
  712             assign_elem_nodes[3]=2;
 
  713             assign_elem_nodes[4]=1;
 
  722             assign_elem_nodes[1]=0;
 
  723             assign_elem_nodes[2]=7;
 
  724             assign_elem_nodes[3]=3;
 
  725             assign_elem_nodes[4]=6;
 
  726             assign_elem_nodes[5]=2;
 
  727             assign_elem_nodes[6]=5;
 
  728             assign_elem_nodes[7]=1;
 
  729             assign_elem_nodes[8]=4;
 
  737             assign_elem_nodes[1]=0;
 
  738             assign_elem_nodes[2]=7;
 
  739             assign_elem_nodes[3]=3;
 
  740             assign_elem_nodes[4]=6;
 
  741             assign_elem_nodes[5]=2;
 
  742             assign_elem_nodes[6]=5;
 
  743             assign_elem_nodes[7]=1;
 
  744             assign_elem_nodes[8]=4;
 
  745             assign_elem_nodes[9]=8;
 
  750           libmesh_error_msg(
"ERROR: UNV-element type 46: Plane Stress Cubic Quadrilateral not supported.");
 
  756             assign_elem_nodes[1]=0;
 
  757             assign_elem_nodes[2]=1;
 
  758             assign_elem_nodes[3]=2;
 
  759             assign_elem_nodes[4]=3;
 
  767             assign_elem_nodes[1]=0;
 
  768             assign_elem_nodes[2]=1;
 
  769             assign_elem_nodes[3]=2;
 
  770             assign_elem_nodes[4]=3;
 
  771             assign_elem_nodes[5]=4;
 
  772             assign_elem_nodes[6]=5;
 
  780             assign_elem_nodes[1]=0;
 
  781             assign_elem_nodes[2]=4;
 
  782             assign_elem_nodes[3]=5;
 
  783             assign_elem_nodes[4]=1;
 
  784             assign_elem_nodes[5]=3;
 
  785             assign_elem_nodes[6]=7;
 
  786             assign_elem_nodes[7]=6;
 
  787             assign_elem_nodes[8]=2;
 
  795             assign_elem_nodes[1]=0;
 
  796             assign_elem_nodes[2]=12;
 
  797             assign_elem_nodes[3]=4;
 
  798             assign_elem_nodes[4]=16;
 
  799             assign_elem_nodes[5]=5;
 
  800             assign_elem_nodes[6]=13;
 
  801             assign_elem_nodes[7]=1;
 
  802             assign_elem_nodes[8]=8;
 
  804             assign_elem_nodes[9]=11;
 
  805             assign_elem_nodes[10]=19;
 
  806             assign_elem_nodes[11]=17;
 
  807             assign_elem_nodes[12]=9;
 
  809             assign_elem_nodes[13]=3;
 
  810             assign_elem_nodes[14]=15;
 
  811             assign_elem_nodes[15]=7;
 
  812             assign_elem_nodes[16]=18;
 
  813             assign_elem_nodes[17]=6;
 
  814             assign_elem_nodes[18]=14;
 
  815             assign_elem_nodes[19]=2;
 
  816             assign_elem_nodes[20]=10;
 
  821           libmesh_error_msg(
"Error: UNV-element type 117: Solid Cubic Brick not supported.");
 
  827             assign_elem_nodes[1]=0;
 
  828             assign_elem_nodes[2]=4;
 
  829             assign_elem_nodes[3]=1;
 
  830             assign_elem_nodes[4]=5;
 
  831             assign_elem_nodes[5]=2;
 
  832             assign_elem_nodes[6]=6;
 
  833             assign_elem_nodes[7]=7;
 
  834             assign_elem_nodes[8]=8;
 
  835             assign_elem_nodes[9]=9;
 
  836             assign_elem_nodes[10]=3;
 
  841           libmesh_error_msg(
"ERROR: UNV-element type " << fe_descriptor_id << 
" not supported.");
 
  851           elem->
set_node(assign_elem_nodes[j]) = node_ptr;
 
  888     exp_coord_sys_dummy  = 0, 
 
  889     disp_coord_sys_dummy = 0, 
 
  896   out_file << std::scientific << std::setprecision(this->
ascii_precision()) << std::uppercase;
 
  902       out_file << std::setw(10) << node_id
 
  903                << std::setw(10) << exp_coord_sys_dummy
 
  904                << std::setw(10) << disp_coord_sys_dummy
 
  905                << std::setw(10) << color_dummy
 
  909       Real x = (*current_node)(0);
 
  912       Real y = (*current_node)(1);
 
  918       Real z = (*current_node)(2);
 
  923       out_file << std::setw(25) << x
 
  924                << std::setw(25) << y
 
  925                << std::setw(25) << z
 
  950     fe_descriptor_id = 0,    
 
  951     phys_prop_tab_dummy = 2, 
 
  952     mat_prop_tab_dummy = 1,  
 
  968   unsigned int assign_elem_nodes[20];
 
  970   unsigned int n_elem_written=0;
 
  977       switch (elem->type())
 
  982             fe_descriptor_id = 41; 
 
  983             assign_elem_nodes[0] = 0;
 
  984             assign_elem_nodes[1] = 2;
 
  985             assign_elem_nodes[2] = 1;
 
  991             fe_descriptor_id = 42; 
 
  992             assign_elem_nodes[0] = 0;
 
  993             assign_elem_nodes[1] = 5;
 
  994             assign_elem_nodes[2] = 2;
 
  995             assign_elem_nodes[3] = 4;
 
  996             assign_elem_nodes[4] = 1;
 
  997             assign_elem_nodes[5] = 3;
 
 1003             fe_descriptor_id = 44; 
 
 1004             assign_elem_nodes[0] = 0;
 
 1005             assign_elem_nodes[1] = 3;
 
 1006             assign_elem_nodes[2] = 2;
 
 1007             assign_elem_nodes[3] = 1;
 
 1013             fe_descriptor_id = 45; 
 
 1014             assign_elem_nodes[0] = 0;
 
 1015             assign_elem_nodes[1] = 7;
 
 1016             assign_elem_nodes[2] = 3;
 
 1017             assign_elem_nodes[3] = 6;
 
 1018             assign_elem_nodes[4] = 2;
 
 1019             assign_elem_nodes[5] = 5;
 
 1020             assign_elem_nodes[6] = 1;
 
 1021             assign_elem_nodes[7] = 4;
 
 1027             fe_descriptor_id = 300; 
 
 1028             assign_elem_nodes[0] = 0;
 
 1029             assign_elem_nodes[1] = 7;
 
 1030             assign_elem_nodes[2] = 3;
 
 1031             assign_elem_nodes[3] = 6;
 
 1032             assign_elem_nodes[4] = 2;
 
 1033             assign_elem_nodes[5] = 5;
 
 1034             assign_elem_nodes[6] = 1;
 
 1035             assign_elem_nodes[7] = 4;
 
 1036             assign_elem_nodes[8] = 8;
 
 1042             fe_descriptor_id = 111; 
 
 1043             assign_elem_nodes[0] = 0;
 
 1044             assign_elem_nodes[1] = 1;
 
 1045             assign_elem_nodes[2] = 2;
 
 1046             assign_elem_nodes[3] = 3;
 
 1052             fe_descriptor_id = 112; 
 
 1053             assign_elem_nodes[0] = 0;
 
 1054             assign_elem_nodes[1] = 1;
 
 1055             assign_elem_nodes[2] = 2;
 
 1056             assign_elem_nodes[3] = 3;
 
 1057             assign_elem_nodes[4] = 4;
 
 1058             assign_elem_nodes[5] = 5;
 
 1064             fe_descriptor_id = 115; 
 
 1065             assign_elem_nodes[0] = 0;
 
 1066             assign_elem_nodes[1] = 4;
 
 1067             assign_elem_nodes[2] = 5;
 
 1068             assign_elem_nodes[3] = 1;
 
 1069             assign_elem_nodes[4] = 3;
 
 1070             assign_elem_nodes[5] = 7;
 
 1071             assign_elem_nodes[6] = 6;
 
 1072             assign_elem_nodes[7] = 2;
 
 1078             fe_descriptor_id = 116; 
 
 1079             assign_elem_nodes[ 0] = 0;
 
 1080             assign_elem_nodes[ 1] = 12;
 
 1081             assign_elem_nodes[ 2] = 4;
 
 1082             assign_elem_nodes[ 3] = 16;
 
 1083             assign_elem_nodes[ 4] = 5;
 
 1084             assign_elem_nodes[ 5] = 13;
 
 1085             assign_elem_nodes[ 6] = 1;
 
 1086             assign_elem_nodes[ 7] = 8;
 
 1088             assign_elem_nodes[ 8] = 11;
 
 1089             assign_elem_nodes[ 9] = 19;
 
 1090             assign_elem_nodes[10] = 17;
 
 1091             assign_elem_nodes[11] = 9;
 
 1093             assign_elem_nodes[12] = 3;
 
 1094             assign_elem_nodes[13] = 15;
 
 1095             assign_elem_nodes[14] = 7;
 
 1096             assign_elem_nodes[15] = 18;
 
 1097             assign_elem_nodes[16] = 6;
 
 1098             assign_elem_nodes[17] = 14;
 
 1099             assign_elem_nodes[18] = 2;
 
 1100             assign_elem_nodes[19] = 10;
 
 1108             fe_descriptor_id = 118; 
 
 1109             assign_elem_nodes[0] = 0;
 
 1110             assign_elem_nodes[1] = 4;
 
 1111             assign_elem_nodes[2] = 1;
 
 1112             assign_elem_nodes[3] = 5;
 
 1113             assign_elem_nodes[4] = 2;
 
 1114             assign_elem_nodes[5] = 6;
 
 1115             assign_elem_nodes[6] = 7;
 
 1116             assign_elem_nodes[7] = 8;
 
 1117             assign_elem_nodes[8] = 9;
 
 1118             assign_elem_nodes[9] = 3;
 
 1123           libmesh_error_msg(
"ERROR: Element type = " << elem->type() << 
" not supported in " << 
"UNVIO!");
 
 1128       out_file << std::setw(10) << elem_id             
 
 1129                << std::setw(10) << fe_descriptor_id    
 
 1130                << std::setw(10) << phys_prop_tab_dummy 
 
 1131                << std::setw(10) << mat_prop_tab_dummy  
 
 1132                << std::setw(10) << color_dummy         
 
 1133                << std::setw(10) << elem->n_nodes()     
 
 1136       for (
auto j : elem->node_index_range())
 
 1141           const Node * node_in_unv_order = elem->node_ptr(assign_elem_nodes[j]);
 
 1150           out_file << std::setw(10) << node_id;
 
 1159     libMesh::out << 
"  Finished writing " << n_elem_written << 
" elements" << std::endl;
 
 1162   out_file << 
"    -1\n";
 
 1169   std::ifstream in_stream(file_name.c_str());
 
 1171   if (!in_stream.good())
 
 1172     libmesh_error_msg(
"Error opening UNV data file.");
 
 1174   std::string olds, news, dummy;
 
 1178       in_stream >> olds >> news;
 
 1181       while (((olds != 
"-1") || (news == 
"-1")) && !in_stream.eof())
 
 1187       if (in_stream.eof())
 
 1195           for (
unsigned int i=0; i<3; i++)
 
 1196             std::getline(in_stream, dummy);
 
 1202           unsigned int dataset_location;
 
 1203           in_stream >> dataset_location;
 
 1206           if (dataset_location != 1)
 
 1207             libmesh_error_msg(
"ERROR: Currently only Data at nodes is supported.");
 
 1210           for (
unsigned int i=0; i<6; i++)
 
 1211             std::getline(in_stream, dummy);
 
 1217             data_characteristic,
 
 1222           unsigned int data_type;
 
 1225           unsigned int num_vals_per_node;
 
 1227           in_stream >> model_type           
 
 1229                     >> data_characteristic  
 
 1232                     >> num_vals_per_node;
 
 1235           for (
unsigned int i=0; i<5; i++)
 
 1236             std::getline(in_stream, dummy);
 
 1241           std::vector<Number> values;
 
 1245               in_stream >> f_n_id;
 
 1253               values.resize(num_vals_per_node);
 
 1256               for (
unsigned int data_cnt=0; data_cnt<num_vals_per_node; data_cnt++)
 
 1264                   if (data_type == 2 || data_type == 4)
 
 1269 #ifdef LIBMESH_USE_COMPLEX_NUMBERS 
 1270                       values[data_cnt] = 
Complex(std::atof(buf.c_str()), 0.);
 
 1272                       values[data_cnt] = std::atof(buf.c_str());
 
 1276                   else if (data_type == 5 || data_type == 6)
 
 1278 #ifdef LIBMESH_USE_COMPLEX_NUMBERS 
 1279                       Real re_val, im_val;
 
 1286                           re_val = std::atof(buf.c_str());
 
 1289                           im_val = std::atof(buf.c_str());
 
 1293                           re_val = std::atof(buf.c_str());
 
 1294                           in_stream >> im_val;
 
 1297                       values[data_cnt] = 
Complex(re_val,im_val);
 
 1300                       libmesh_error_msg(
"ERROR: Complex data only supported when libMesh is configured with --enable-complex!");
 
 1305                     libmesh_error_msg(
"ERROR: Data type not supported.");
 
 1324 const std::vector<Number> *
 
 1332     return &(it->second);