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);