libMesh
Loading...
Searching...
No Matches
Public Member Functions | Protected Member Functions | Protected Attributes | Private Member Functions | Private Attributes | Static Private Attributes | List of all members
libMesh::UNVIO Class Reference

The UNVIO class implements the Ideas UNV universal file format. More...

#include <unv_io.h>

Inheritance diagram for libMesh::UNVIO:
[legend]

Public Member Functions

 UNVIO (MeshBase &mesh)
 Constructor.
 
 UNVIO (const MeshBase &mesh)
 Constructor.
 
virtual ~UNVIO ()
 Destructor.
 
virtual void read (const std::string &) override
 This method implements reading a mesh from a specified file.
 
virtual void write (const std::string &) override
 This method implements writing a mesh to a specified file.
 
bool & verbose ()
 Set the flag indicating if we should be verbose.
 
void read_dataset (std::string file_name)
 Read a UNV data file containing a dataset of type "2414".
 
const std::vector< Number > * get_data (Node *node) const
 
bool is_parallel_format () const
 Returns true iff this mesh file format and input class are parallelized, so that all processors can read their share of the data at once.
 
virtual void write_equation_systems (const std::string &, const EquationSystems &, const std::set< std::string > *system_names=nullptr)
 This method implements writing a mesh with data to a specified file where the data is taken from the EquationSystems object.
 
virtual void write_discontinuous_equation_systems (const std::string &, const EquationSystems &, const std::set< std::string > *system_names=nullptr)
 This method implements writing a mesh with discontinuous data to a specified file where the data is taken from the EquationSystems object.
 
virtual void write_nodal_data (const std::string &, const std::vector< Number > &, const std::vector< std::string > &)
 This method implements writing a mesh with nodal data to a specified file where the nodal data and variable names are provided.
 
virtual void write_nodal_data (const std::string &, const NumericVector< Number > &, const std::vector< std::string > &)
 This method may be overridden by "parallel" output formats for writing nodal data.
 
virtual void write_nodal_data (const std::string &, const EquationSystems &, const std::set< std::string > *)
 This method should be overridden by "parallel" output formats for writing nodal data.
 
virtual void write_nodal_data_discontinuous (const std::string &, const std::vector< Number > &, const std::vector< std::string > &)
 This method implements writing a mesh with discontinuous data to a specified file where the nodal data and variables names are provided.
 
unsigned intascii_precision ()
 Return/set the precision to use when writing ASCII files.
 

Protected Member Functions

MeshBasemesh ()
 
void set_n_partitions (unsigned int n_parts)
 Sets the number of partitions in the mesh.
 
void skip_comment_lines (std::istream &in, const char comment_start)
 Reads input from in, skipping all the lines that start with the character comment_start.
 
const MeshBasemesh () const
 
virtual bool get_add_sides ()
 

Protected Attributes

std::vector< bool > elems_of_dimension
 A vector of bools describing what dimension elements have been encountered when reading a mesh.
 
const bool _is_parallel_format
 Flag specifying whether this format is parallel-capable.
 
const bool _serial_only_needed_on_proc_0
 Flag specifying whether this format can be written by only serializing the mesh to processor zero.
 

Private Member Functions

void read_implementation (std::istream &in_stream)
 The actual implementation of the read function.
 
void write_implementation (std::ostream &out_stream)
 The actual implementation of the write function.
 
void nodes_in (std::istream &in_file)
 Read nodes from file.
 
void elements_in (std::istream &in_file)
 Method reads elements and stores them in std::vector<Elem *> _elements in the same order as they come in.
 
void groups_in (std::istream &in_file)
 Reads the "groups" section of the file.
 
void nodes_out (std::ostream &out_file)
 Outputs nodes to the file out_file.
 
void elements_out (std::ostream &out_file)
 Outputs the element data to the file out_file.
 
unsigned char max_elem_dimension_seen ()
 
bool need_D_to_e (std::string &number)
 Replaces "1.1111D+00" with "1.1111e+00" if necessary.
 

Private Attributes

bool _verbose
 should be be verbose?
 
std::map< dof_id_type, Node * > _unv_node_id_to_libmesh_node_ptr
 Maps UNV node IDs to libMesh Node*s.
 
std::map< unsigned, unsigned > _unv_elem_id_to_libmesh_elem_id
 Map UNV element IDs to libmesh element IDs.
 
std::map< Node *, std::vector< Number > > _node_data
 Map from libMesh Node* to data at that node, as read in by the read_dataset() function.
 
MeshBase_obj
 A pointer to a non-const object object.
 
const bool _is_parallel_format
 Flag specifying whether this format is parallel-capable.
 
unsigned int _ascii_precision
 Precision to use when writing ASCII files.
 

Static Private Attributes

static const std::string _nodes_dataset_label = "2411"
 label for the node dataset
 
static const std::string _elements_dataset_label = "2412"
 label for the element dataset
 
static const std::string _groups_dataset_label = "2467"
 label for the groups dataset
 

Detailed Description

The UNVIO class implements the Ideas UNV universal file format.

This class enables both reading and writing UNV files.

Author history

Author
Tammo Kaschner
Daniel Dreyer
Benjamin S. Kirk
John W. Peterson
Date
2003, 2004, 2014

Definition at line 52 of file unv_io.h.

Constructor & Destructor Documentation

◆ UNVIO() [1/2]

libMesh::UNVIO::UNVIO ( MeshBase mesh)

Constructor.

Takes a writable reference to a mesh object. This is the constructor required to read a mesh.

Definition at line 68 of file unv_io.C.

68 :
69 MeshInput<MeshBase> (mesh),
71 _verbose (false)
72{
73}
bool _verbose
should be be verbose?
Definition unv_io.h:182
template class LIBMESH_EXPORT MeshOutput< MeshBase >

◆ UNVIO() [2/2]

libMesh::UNVIO::UNVIO ( const MeshBase mesh)

Constructor.

Takes a reference to a constant mesh object. This constructor will only allow us to write the mesh.

Definition at line 77 of file unv_io.C.

77 :
79 _verbose (false)
80{
81}

◆ ~UNVIO()

libMesh::UNVIO::~UNVIO ( )
virtualdefault

Destructor.

Member Function Documentation

◆ ascii_precision()

unsigned int & libMesh::MeshOutput< MeshBase >::ascii_precision ( )
inlineinherited

Return/set the precision to use when writing ASCII files.

By default we use numeric_limits<Real>::max_digits10, which should be enough to write out to ASCII and get the exact same Real back when reading in.

Definition at line 160 of file mesh_output.h.

270{
271 return _ascii_precision;
272}
unsigned int _ascii_precision
Precision to use when writing ASCII files.

◆ elements_in()

void libMesh::UNVIO::elements_in ( std::istream &  in_file)
private

Method reads elements and stores them in std::vector<Elem *> _elements in the same order as they come in.

Within UNVIO, element labels are ignored.

Definition at line 583 of file unv_io.C.

584{
585 LOG_SCOPE("elements_in()","UNVIO");
586
587 if (this->verbose())
588 libMesh::out << " Reading elements" << std::endl;
589
590 MeshBase & mesh = MeshInput<MeshBase>::mesh();
591
592 // node label, we use an int here so we can read in a -1
593 int element_label;
594
595 unsigned
596 n_nodes, // number of nodes on element
597 fe_descriptor_id, // FE descriptor id
598 phys_prop_tab_num, // physical property table number (not supported yet)
599 mat_prop_tab_num, // material property table number (not supported yet)
600 color; // color (not supported yet)
601
602 // vector that temporarily holds the node labels defining element
603 std::vector<unsigned int> node_labels (21);
604
605 // vector that assigns element nodes to their correct position
606 // for example:
607 // 44:plane stress | QUAD4
608 // linear quadrilateral |
609 // position in UNV-file | position in libmesh
610 // assign_elem_node[1] = 0
611 // assign_elem_node[2] = 3
612 // assign_elem_node[3] = 2
613 // assign_elem_node[4] = 1
614 //
615 // UNV is 1-based, we leave the 0th element of the vectors unused in order
616 // to prevent confusion, this way we can store elements with up to 20 nodes
617 unsigned int assign_elem_nodes[21];
618
619 // Read elements until there are none left
620 unsigned ctr = 0;
621 while (true)
622 {
623 // read element label, break out when we read -1
624 in_file >> element_label;
625
626 if (element_label == -1)
627 break;
628
629 in_file >> fe_descriptor_id // read FE descriptor id
630 >> phys_prop_tab_num // (not supported yet)
631 >> mat_prop_tab_num // (not supported yet)
632 >> color // (not supported yet)
633 >> n_nodes; // read number of nodes on element
634
635 // For "beam" type elements, the next three numbers are:
636 // .) beam orientation node number
637 // .) beam fore-end cross section number
638 // .) beam aft-end cross section number
639 // which we discard in libmesh. The "beam" type elements:
640 // 11 Rod
641 // 21 Linear beam
642 // 22 Tapered beam
643 // 23 Curved beam
644 // 24 Parabolic beam
645 // all have fe_descriptor_id < 25.
646 // http://www.sdrl.uc.edu/universal-file-formats-for-modal-analysis-testing-1/file-format-storehouse/unv_2412.htm
647 if (fe_descriptor_id < 25)
648 {
649 unsigned dummy;
650 in_file >> dummy >> dummy >> dummy;
651 }
652
653 // read node labels (1-based)
654 for (unsigned int j=1; j<=n_nodes; j++)
655 in_file >> node_labels[j];
656
657 // element pointer, to be allocated
658 std::unique_ptr<Elem> elem;
659
660 switch (fe_descriptor_id)
661 {
662 case 11: // Rod
663 {
664 elem = Elem::build(EDGE2);
665
666 assign_elem_nodes[1]=0;
667 assign_elem_nodes[2]=1;
668 break;
669 }
670
671 case 41: // Plane Stress Linear Triangle
672 case 91: // Thin Shell Linear Triangle
673 {
674 elem = Elem::build(TRI3); // create new element
675
676 assign_elem_nodes[1]=0;
677 assign_elem_nodes[2]=2;
678 assign_elem_nodes[3]=1;
679 break;
680 }
681
682 case 42: // Plane Stress Quadratic Triangle
683 case 92: // Thin Shell Quadratic Triangle
684 {
685 elem = Elem::build(TRI6); // create new element
686
687 assign_elem_nodes[1]=0;
688 assign_elem_nodes[2]=5;
689 assign_elem_nodes[3]=2;
690 assign_elem_nodes[4]=4;
691 assign_elem_nodes[5]=1;
692 assign_elem_nodes[6]=3;
693 break;
694 }
695
696 case 43: // Plane Stress Cubic Triangle
697 libmesh_error_msg("ERROR: UNV-element type 43: Plane Stress Cubic Triangle not supported.");
698
699 case 44: // Plane Stress Linear Quadrilateral
700 case 94: // Thin Shell Linear Quadrilateral
701 {
702 elem = Elem::build(QUAD4); // create new element
703
704 assign_elem_nodes[1]=0;
705 assign_elem_nodes[2]=3;
706 assign_elem_nodes[3]=2;
707 assign_elem_nodes[4]=1;
708 break;
709 }
710
711 case 45: // Plane Stress Quadratic Quadrilateral
712 case 95: // Thin Shell Quadratic Quadrilateral
713 {
714 elem = Elem::build(QUAD8); // create new element
715
716 assign_elem_nodes[1]=0;
717 assign_elem_nodes[2]=7;
718 assign_elem_nodes[3]=3;
719 assign_elem_nodes[4]=6;
720 assign_elem_nodes[5]=2;
721 assign_elem_nodes[6]=5;
722 assign_elem_nodes[7]=1;
723 assign_elem_nodes[8]=4;
724 break;
725 }
726
727 case 300: // Thin Shell Quadratic Quadrilateral (nine nodes)
728 {
729 elem = Elem::build(QUAD9); // create new element
730
731 assign_elem_nodes[1]=0;
732 assign_elem_nodes[2]=7;
733 assign_elem_nodes[3]=3;
734 assign_elem_nodes[4]=6;
735 assign_elem_nodes[5]=2;
736 assign_elem_nodes[6]=5;
737 assign_elem_nodes[7]=1;
738 assign_elem_nodes[8]=4;
739 assign_elem_nodes[9]=8;
740 break;
741 }
742
743 case 46: // Plane Stress Cubic Quadrilateral
744 libmesh_error_msg("ERROR: UNV-element type 46: Plane Stress Cubic Quadrilateral not supported.");
745
746 case 111: // Solid Linear Tetrahedron
747 {
748 elem = Elem::build(TET4); // create new element
749
750 assign_elem_nodes[1]=0;
751 assign_elem_nodes[2]=1;
752 assign_elem_nodes[3]=2;
753 assign_elem_nodes[4]=3;
754 break;
755 }
756
757 case 112: // Solid Linear Prism
758 {
759 elem = Elem::build(PRISM6); // create new element
760
761 assign_elem_nodes[1]=0;
762 assign_elem_nodes[2]=1;
763 assign_elem_nodes[3]=2;
764 assign_elem_nodes[4]=3;
765 assign_elem_nodes[5]=4;
766 assign_elem_nodes[6]=5;
767 break;
768 }
769
770 case 115: // Solid Linear Brick
771 {
772 elem = Elem::build(HEX8); // create new element
773
774 assign_elem_nodes[1]=0;
775 assign_elem_nodes[2]=4;
776 assign_elem_nodes[3]=5;
777 assign_elem_nodes[4]=1;
778 assign_elem_nodes[5]=3;
779 assign_elem_nodes[6]=7;
780 assign_elem_nodes[7]=6;
781 assign_elem_nodes[8]=2;
782 break;
783 }
784
785 case 116: // Solid Quadratic Brick
786 {
787 elem = Elem::build(HEX20); // create new element
788
789 assign_elem_nodes[1]=0;
790 assign_elem_nodes[2]=12;
791 assign_elem_nodes[3]=4;
792 assign_elem_nodes[4]=16;
793 assign_elem_nodes[5]=5;
794 assign_elem_nodes[6]=13;
795 assign_elem_nodes[7]=1;
796 assign_elem_nodes[8]=8;
797
798 assign_elem_nodes[9]=11;
799 assign_elem_nodes[10]=19;
800 assign_elem_nodes[11]=17;
801 assign_elem_nodes[12]=9;
802
803 assign_elem_nodes[13]=3;
804 assign_elem_nodes[14]=15;
805 assign_elem_nodes[15]=7;
806 assign_elem_nodes[16]=18;
807 assign_elem_nodes[17]=6;
808 assign_elem_nodes[18]=14;
809 assign_elem_nodes[19]=2;
810 assign_elem_nodes[20]=10;
811 break;
812 }
813
814 case 117: // Solid Cubic Brick
815 libmesh_error_msg("Error: UNV-element type 117: Solid Cubic Brick not supported.");
816
817 case 118: // Solid Quadratic Tetrahedron
818 {
819 elem = Elem::build(TET10); // create new element
820
821 assign_elem_nodes[1]=0;
822 assign_elem_nodes[2]=4;
823 assign_elem_nodes[3]=1;
824 assign_elem_nodes[4]=5;
825 assign_elem_nodes[5]=2;
826 assign_elem_nodes[6]=6;
827 assign_elem_nodes[7]=7;
828 assign_elem_nodes[8]=8;
829 assign_elem_nodes[9]=9;
830 assign_elem_nodes[10]=3;
831 break;
832 }
833
834 default: // Unrecognized element type
835 libmesh_error_msg("ERROR: UNV-element type " << fe_descriptor_id << " not supported.");
836 }
837
838 // nodes are being stored in element
839 for (dof_id_type j=1; j<=n_nodes; j++)
840 {
841 // Map the UNV node ID to the libmesh node ID
842 auto & node_ptr =
843 libmesh_map_find(_unv_node_id_to_libmesh_node_ptr, node_labels[j]);
844
845 elem->set_node(assign_elem_nodes[j], node_ptr);
846 }
847
848 elems_of_dimension[elem->dim()] = true;
849
850 // Set the element's ID
851 elem->set_id(ctr);
852
853 // Maintain a map from the libmesh (0-based) numbering to the
854 // UNV numbering.
855 _unv_elem_id_to_libmesh_elem_id[element_label] = ctr;
856
857 // Add the element to the Mesh
858 mesh.add_elem(std::move(elem));
859
860 // Increment the counter for the next iteration
861 ctr++;
862 } // end while (true)
863}
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
Definition elem.C:442
virtual Elem * add_elem(Elem *e)=0
Add elem e to the end of the element array.
std::vector< bool > elems_of_dimension
A vector of bools describing what dimension elements have been encountered when reading a mesh.
Definition mesh_input.h:107
std::map< unsigned, unsigned > _unv_elem_id_to_libmesh_elem_id
Map UNV element IDs to libmesh element IDs.
Definition unv_io.h:208
bool & verbose()
Set the flag indicating if we should be verbose.
Definition unv_io.C:89
std::map< dof_id_type, Node * > _unv_node_id_to_libmesh_node_ptr
Maps UNV node IDs to libMesh Node*s.
Definition unv_io.h:188
OStreamProxy out
uint8_t dof_id_type
Definition id_types.h:67
const dof_id_type n_nodes
Definition tecplot_io.C:67

References _unv_elem_id_to_libmesh_elem_id, _unv_node_id_to_libmesh_node_ptr, libMesh::MeshBase::add_elem(), libMesh::Elem::build(), libMesh::EDGE2, libMesh::MeshInput< MeshBase >::elems_of_dimension, libMesh::HEX20, libMesh::HEX8, libMesh::MeshInput< MT >::mesh(), libMesh::MeshInput< MeshBase >::mesh(), n_nodes, libMesh::out, libMesh::PRISM6, libMesh::QUAD4, libMesh::QUAD8, libMesh::QUAD9, libMesh::TET10, libMesh::TET4, libMesh::TRI3, libMesh::TRI6, and verbose().

Referenced by read_implementation().

◆ elements_out()

void libMesh::UNVIO::elements_out ( std::ostream &  out_file)
private

Outputs the element data to the file out_file.

Do not use this directly, but through the proper write method.

Definition at line 932 of file unv_io.C.

933{
934 if (this->verbose())
935 libMesh::out << " Writing elements" << std::endl;
936
937 // Write beginning of dataset
938 out_file << " -1\n"
939 << " "
941 << "\n";
942
943 unsigned
944 fe_descriptor_id = 0, // FE descriptor id
945 phys_prop_tab_dummy = 2, // physical property (not supported yet)
946 mat_prop_tab_dummy = 1, // material property (not supported yet)
947 color_dummy = 7; // color (not supported yet)
948
949 // vector that assigns element nodes to their correct position
950 // currently only elements with up to 20 nodes
951 //
952 // Example:
953 // QUAD4 | 44:plane stress
954 // | linear quad
955 // position in libMesh | UNV numbering
956 // (note: 0-based) | (note: 1-based)
957 //
958 // assign_elem_node[0] = 0
959 // assign_elem_node[1] = 3
960 // assign_elem_node[2] = 2
961 // assign_elem_node[3] = 1
962 unsigned int assign_elem_nodes[20];
963
964 unsigned int n_elem_written=0;
965
966 // A reference to the parent class's mesh
967 const MeshBase & mesh = MeshOutput<MeshBase>::mesh();
968
969 for (const auto & elem : mesh.element_ptr_range())
970 {
971 switch (elem->type())
972 {
973
974 case TRI3:
975 {
976 fe_descriptor_id = 41; // Plane Stress Linear Triangle
977 assign_elem_nodes[0] = 0;
978 assign_elem_nodes[1] = 2;
979 assign_elem_nodes[2] = 1;
980 break;
981 }
982
983 case TRI6:
984 {
985 fe_descriptor_id = 42; // Plane Stress Quadratic Triangle
986 assign_elem_nodes[0] = 0;
987 assign_elem_nodes[1] = 5;
988 assign_elem_nodes[2] = 2;
989 assign_elem_nodes[3] = 4;
990 assign_elem_nodes[4] = 1;
991 assign_elem_nodes[5] = 3;
992 break;
993 }
994
995 case QUAD4:
996 {
997 fe_descriptor_id = 44; // Plane Stress Linear Quadrilateral
998 assign_elem_nodes[0] = 0;
999 assign_elem_nodes[1] = 3;
1000 assign_elem_nodes[2] = 2;
1001 assign_elem_nodes[3] = 1;
1002 break;
1003 }
1004
1005 case QUAD8:
1006 {
1007 fe_descriptor_id = 45; // Plane Stress Quadratic Quadrilateral
1008 assign_elem_nodes[0] = 0;
1009 assign_elem_nodes[1] = 7;
1010 assign_elem_nodes[2] = 3;
1011 assign_elem_nodes[3] = 6;
1012 assign_elem_nodes[4] = 2;
1013 assign_elem_nodes[5] = 5;
1014 assign_elem_nodes[6] = 1;
1015 assign_elem_nodes[7] = 4;
1016 break;
1017 }
1018
1019 case QUAD9:
1020 {
1021 fe_descriptor_id = 300; // Plane Stress Quadratic Quadrilateral
1022 assign_elem_nodes[0] = 0;
1023 assign_elem_nodes[1] = 7;
1024 assign_elem_nodes[2] = 3;
1025 assign_elem_nodes[3] = 6;
1026 assign_elem_nodes[4] = 2;
1027 assign_elem_nodes[5] = 5;
1028 assign_elem_nodes[6] = 1;
1029 assign_elem_nodes[7] = 4;
1030 assign_elem_nodes[8] = 8;
1031 break;
1032 }
1033
1034 case TET4:
1035 {
1036 fe_descriptor_id = 111; // Solid Linear Tetrahedron
1037 assign_elem_nodes[0] = 0;
1038 assign_elem_nodes[1] = 1;
1039 assign_elem_nodes[2] = 2;
1040 assign_elem_nodes[3] = 3;
1041 break;
1042 }
1043
1044 case PRISM6:
1045 {
1046 fe_descriptor_id = 112; // Solid Linear Prism
1047 assign_elem_nodes[0] = 0;
1048 assign_elem_nodes[1] = 1;
1049 assign_elem_nodes[2] = 2;
1050 assign_elem_nodes[3] = 3;
1051 assign_elem_nodes[4] = 4;
1052 assign_elem_nodes[5] = 5;
1053 break;
1054 }
1055
1056 case HEX8:
1057 {
1058 fe_descriptor_id = 115; // Solid Linear Brick
1059 assign_elem_nodes[0] = 0;
1060 assign_elem_nodes[1] = 4;
1061 assign_elem_nodes[2] = 5;
1062 assign_elem_nodes[3] = 1;
1063 assign_elem_nodes[4] = 3;
1064 assign_elem_nodes[5] = 7;
1065 assign_elem_nodes[6] = 6;
1066 assign_elem_nodes[7] = 2;
1067 break;
1068 }
1069
1070 case HEX20:
1071 {
1072 fe_descriptor_id = 116; // Solid Quadratic Brick
1073 assign_elem_nodes[ 0] = 0;
1074 assign_elem_nodes[ 1] = 12;
1075 assign_elem_nodes[ 2] = 4;
1076 assign_elem_nodes[ 3] = 16;
1077 assign_elem_nodes[ 4] = 5;
1078 assign_elem_nodes[ 5] = 13;
1079 assign_elem_nodes[ 6] = 1;
1080 assign_elem_nodes[ 7] = 8;
1081
1082 assign_elem_nodes[ 8] = 11;
1083 assign_elem_nodes[ 9] = 19;
1084 assign_elem_nodes[10] = 17;
1085 assign_elem_nodes[11] = 9;
1086
1087 assign_elem_nodes[12] = 3;
1088 assign_elem_nodes[13] = 15;
1089 assign_elem_nodes[14] = 7;
1090 assign_elem_nodes[15] = 18;
1091 assign_elem_nodes[16] = 6;
1092 assign_elem_nodes[17] = 14;
1093 assign_elem_nodes[18] = 2;
1094 assign_elem_nodes[19] = 10;
1095
1096
1097 break;
1098 }
1099
1100 case TET10:
1101 {
1102 fe_descriptor_id = 118; // Solid Quadratic Tetrahedron
1103 assign_elem_nodes[0] = 0;
1104 assign_elem_nodes[1] = 4;
1105 assign_elem_nodes[2] = 1;
1106 assign_elem_nodes[3] = 5;
1107 assign_elem_nodes[4] = 2;
1108 assign_elem_nodes[5] = 6;
1109 assign_elem_nodes[6] = 7;
1110 assign_elem_nodes[7] = 8;
1111 assign_elem_nodes[8] = 9;
1112 assign_elem_nodes[9] = 3;
1113 break;
1114 }
1115
1116 default:
1117 libmesh_error_msg("ERROR: Element type = " << Utility::enum_to_string(elem->type()) << " not supported in " << "UNVIO!");
1118 }
1119
1120 dof_id_type elem_id = elem->id();
1121
1122 out_file << std::setw(10) << elem_id // element ID
1123 << std::setw(10) << fe_descriptor_id // type of element
1124 << std::setw(10) << phys_prop_tab_dummy // not supported
1125 << std::setw(10) << mat_prop_tab_dummy // not supported
1126 << std::setw(10) << color_dummy // not supported
1127 << std::setw(10) << elem->n_nodes() // No. of nodes per element
1128 << '\n';
1129
1130 for (auto j : elem->node_index_range())
1131 {
1132 // assign_elem_nodes[j]-th node: i.e., j loops over the
1133 // libMesh numbering, and assign_elem_nodes[j] over the
1134 // UNV numbering.
1135 const Node * node_in_unv_order = elem->node_ptr(assign_elem_nodes[j]);
1136
1137 // new record after 8 id entries
1138 if (j==8 || j==16)
1139 out_file << '\n';
1140
1141 // Write foreign label for this node
1142 dof_id_type node_id = node_in_unv_order->id();
1143
1144 out_file << std::setw(10) << node_id;
1145 }
1146
1147 out_file << '\n';
1148
1149 n_elem_written++;
1150 }
1151
1152 if (this->verbose())
1153 libMesh::out << " Finished writing " << n_elem_written << " elements" << std::endl;
1154
1155 // Write end of dataset
1156 out_file << " -1\n";
1157}
const MT & mesh() const
static const std::string _elements_dataset_label
label for the element dataset
Definition unv_io.h:198
std::string enum_to_string(const T e)

References _elements_dataset_label, libMesh::Utility::enum_to_string(), libMesh::HEX20, libMesh::HEX8, libMesh::DofObject::id(), libMesh::MeshInput< MeshBase >::mesh(), libMesh::MeshOutput< MT >::mesh(), libMesh::out, libMesh::PRISM6, libMesh::QUAD4, libMesh::QUAD8, libMesh::QUAD9, libMesh::TET10, libMesh::TET4, libMesh::TRI3, libMesh::TRI6, and verbose().

Referenced by write_implementation().

◆ get_add_sides()

virtual bool libMesh::MeshOutput< MeshBase >::get_add_sides ( )
inlineprotectedvirtualinherited
Returns
Whether or not added sides are expected to be output, to plot SIDE_DISCONTINUOUS data. Subclasses should override this if they are capable of plotting such data.

Reimplemented in libMesh::ExodusII_IO.

Definition at line 176 of file mesh_output.h.

176{ return false; }

◆ get_data()

const std::vector< Number > * libMesh::UNVIO::get_data ( Node node) const
Returns
A pointer the values associated with the node node, as read in by the read_dataset() method.

If no values exist for the node in question, a nullptr is returned instead. It is up to the user to check the return value before using it.

Definition at line 1317 of file unv_io.C.

1318{
1319 if (const auto it = _node_data.find(node);
1320 it == _node_data.end())
1321 return nullptr;
1322 else
1323 return &(it->second);
1324}
std::map< Node *, std::vector< Number > > _node_data
Map from libMesh Node* to data at that node, as read in by the read_dataset() function.
Definition unv_io.h:214

References _node_data.

Referenced by main().

◆ groups_in()

void libMesh::UNVIO::groups_in ( std::istream &  in_file)
private

Reads the "groups" section of the file.

The format of the groups section is described here: http://www.sdrl.uc.edu/universal-file-formats-for-modal-analysis-testing-1/file-format-storehouse/unv_2467.htm

Definition at line 417 of file unv_io.C.

418{
419 // Grab reference to the Mesh, so we can add boundary info data to it
420 MeshBase & mesh = MeshInput<MeshBase>::mesh();
421
422 // Record the max and min element dimension seen while reading the file.
423 unsigned char max_dim = this->max_elem_dimension_seen();
424
425 // Container which stores lower-dimensional elements (based on
426 // Elem::key()) for later assignment of boundary conditions. We
427 // could use e.g. an unordered_set with Elems as keys for this, but
428 // this turns out to be much slower on the search side, since we
429 // have to build an entire side in order to search, rather than just
430 // calling elem->key(side) to compute a key.
431 typedef std::unordered_multimap<dof_id_type, Elem *> map_type;
432 map_type provide_bcs;
433
434 // Read groups until there aren't any more to read...
435 while (true)
436 {
437 // If we read a -1, it means there is nothing else to read in this section.
438 int group_number;
439 in_file >> group_number;
440
441 if (group_number == -1)
442 break;
443
444 // The first record consists of 8 entries:
445 // Field 1 -- group number (that we just read)
446 // Field 2 -- active constraint set no. for group
447 // Field 3 -- active restraint set no. for group
448 // Field 4 -- active load set no. for group
449 // Field 5 -- active dof set no. for group
450 // Field 6 -- active temperature set no. for group
451 // Field 7 -- active contact set no. for group
452 // Field 8 -- number of entities in group
453 // Only the first and last of these are relevant to us...
454 unsigned num_entities;
455 std::string group_name;
456 {
457 unsigned dummy;
458 in_file >> dummy >> dummy >> dummy >> dummy >> dummy >> dummy
459 >> num_entities;
460
461 // The second record has 1 field, the group name
462 in_file >> group_name;
463 }
464
465 // The dimension of the elements in the group will determine
466 // whether this is a sideset group or a subdomain group.
467 bool
468 is_subdomain_group = false,
469 is_sideset_group = false;
470
471 // Each subsequent line has 8 entries, there are two entity type
472 // codes and two tags per line that we need to read. In all my
473 // examples, the entity type code was always "8", which stands for
474 // "finite elements" but it's possible that we could eventually
475 // support other entity type codes...
476 // Field 1 -- entity type code
477 // Field 2 -- entity tag
478 // Field 3 -- entity node leaf id.
479 // Field 4 -- entity component/ ham id.
480 // Field 5 -- entity type code
481 // Field 6 -- entity tag
482 // Field 7 -- entity node leaf id.
483 // Field 8 -- entity component/ ham id.
484 {
485 unsigned entity_type_code, entity_tag, dummy;
486 for (unsigned entity=0; entity<num_entities; ++entity)
487 {
488 in_file >> entity_type_code >> entity_tag >> dummy >> dummy;
489
490 if (entity_type_code != 8)
491 libMesh::err << "Warning, unrecognized entity type code = "
492 << entity_type_code
493 << " in group "
494 << group_name
495 << std::endl;
496
497 // Try to find this ID in the map from UNV element ids to libmesh ids.
498 if (const auto it = _unv_elem_id_to_libmesh_elem_id.find(entity_tag);
500 {
501 unsigned libmesh_elem_id = it->second;
502
503 // Attempt to get a pointer to the elem listed in the group
504 Elem * group_elem = mesh.elem_ptr(libmesh_elem_id);
505
506 // dim < max_dim means the Elem defines a boundary condition
507 if (group_elem->dim() < max_dim)
508 {
509 is_sideset_group = true;
510
511 // We can only handle elements that are *exactly*
512 // one dimension lower than the max element
513 // dimension. Not sure if "edge" BCs in 3D
514 // actually make sense/are required...
515 libmesh_error_msg_if(group_elem->dim()+1 != max_dim,
516 "ERROR: Expected boundary element of dimension "
517 << max_dim-1 << " but got " << group_elem->dim());
518
519 // Set the current group number as the lower-dimensional element's subdomain ID.
520 // We will use this later to set a boundary ID.
521 group_elem->subdomain_id() =
522 restrict_int<subdomain_id_type>(group_number);
523
524 // Store the lower-dimensional element in the provide_bcs container.
525 provide_bcs.emplace(group_elem->key(), group_elem);
526 }
527
528 // dim == max_dim means this group defines a subdomain ID
529 else if (group_elem->dim() == max_dim)
530 {
531 is_subdomain_group = true;
532 group_elem->subdomain_id() =
533 restrict_int<subdomain_id_type>(group_number);
534 }
535
536 else
537 libmesh_error_msg("ERROR: Found an elem with dim=" \
538 << group_elem->dim() << " > " << "max_dim=" << +max_dim);
539 }
540 else
541 libMesh::err << "WARNING: UNV Element " << entity_tag << " not found while parsing groups." << std::endl;
542 } // end for (entity)
543 } // end scope
544
545 // Associate this group_number with the group_name in the BoundaryInfo object.
546 if (is_sideset_group)
548 (cast_int<boundary_id_type>(group_number)) = group_name;
549
550 if (is_subdomain_group)
552 (cast_int<subdomain_id_type>(group_number), group_name);
553
554 } // end while (true)
555
556 // Loop over elements and try to assign boundary information
557 for (auto & elem : mesh.active_element_ptr_range())
558 if (elem->dim() == max_dim)
559 for (auto sn : elem->side_index_range())
560 for (const auto & pr : as_range(provide_bcs.equal_range (elem->key(sn))))
561 {
562 // This is a max-dimension element that may require BCs.
563 // For each of its sides, including internal sides, we'll
564 // see if a lower-dimensional element provides boundary
565 // information for it. Note that we have not yet called
566 // find_neighbors(), so we can't use elem->neighbor(sn) in
567 // this algorithm...
568
569 // Build a side to confirm the hash mapped to the correct side.
570 std::unique_ptr<Elem> side (elem->build_side_ptr(sn));
571
572 // Get a pointer to the lower-dimensional element
573 Elem * lower_dim_elem = pr.second;
574
575 // This was a hash, so it might not be perfect. Let's verify...
576 if (*lower_dim_elem == *side)
577 mesh.get_boundary_info().add_side(elem, sn, lower_dim_elem->subdomain_id());
578 }
579}
unsigned int dim
std::string & sideset_name(boundary_id_type id)
void add_side(const dof_id_type elem, const unsigned short int side, const boundary_id_type id)
Add side side of element number elem with boundary id id to the boundary information data structure.
void set_subdomain_name(subdomain_id_type id, const std::string &name, bool synchronous=false)
Sets the name for the provided id.
Definition mesh_base.C:1914
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Definition mesh_base.h:170
virtual const Elem * elem_ptr(const dof_id_type i) const =0
unsigned char max_elem_dimension_seen()
Definition unv_io.C:384
OStreamProxy err
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.

References _unv_elem_id_to_libmesh_elem_id, libMesh::BoundaryInfo::add_side(), libMesh::as_range(), libMesh::Elem::dim(), libMesh::MeshBase::elem_ptr(), libMesh::err, libMesh::MeshBase::get_boundary_info(), libMesh::Elem::key(), max_elem_dimension_seen(), libMesh::MeshInput< MeshBase >::mesh(), libMesh::MeshInput< MT >::mesh(), libMesh::MeshBase::set_subdomain_name(), libMesh::BoundaryInfo::sideset_name(), and libMesh::Elem::subdomain_id().

Referenced by read_implementation().

◆ is_parallel_format()

bool libMesh::MeshInput< MeshBase >::is_parallel_format ( ) const
inlineinherited

Returns true iff this mesh file format and input class are parallelized, so that all processors can read their share of the data at once.

Definition at line 87 of file mesh_input.h.

87{ return this->_is_parallel_format; }
const bool _is_parallel_format
Flag specifying whether this format is parallel-capable.
Definition mesh_input.h:130

◆ max_elem_dimension_seen()

unsigned char libMesh::UNVIO::max_elem_dimension_seen ( )
private
Returns
The maximum geometric element dimension encountered while reading the Mesh. Only valid after the elements have been read in and the elems_of_dimension array has been populated.

Definition at line 384 of file unv_io.C.

385{
386 unsigned char max_dim = 0;
387
388 unsigned char elem_dimensions_size = cast_int<unsigned char>
389 (elems_of_dimension.size());
390 // The elems_of_dimension array is 1-based in the UNV reader
391 for (unsigned char i=1; i<elem_dimensions_size; ++i)
392 if (elems_of_dimension[i])
393 max_dim = i;
394
395 return max_dim;
396}

References libMesh::MeshInput< MeshBase >::elems_of_dimension.

Referenced by groups_in(), and read_implementation().

◆ mesh() [1/2]

MeshBase & libMesh::MeshInput< MeshBase >::mesh ( )
inlineprotectedinherited
Returns
The object as a writable reference.

Definition at line 94 of file mesh_input.h.

179{
180 libmesh_error_msg_if(_obj == nullptr, "ERROR: _obj should not be nullptr!");
181 return *_obj;
182}
MeshBase * _obj
A pointer to a non-const object object.
Definition mesh_input.h:123

◆ mesh() [2/2]

const MeshBase & libMesh::MeshOutput< MeshBase >::mesh ( ) const
inlineprotectedinherited
Returns
The object as a read-only reference.

Definition at line 168 of file mesh_output.h.

260{
261 libmesh_assert(_obj);
262 return *_obj;
263}
const MeshBase *const _obj
A pointer to a constant object.
libmesh_assert(ctx)

◆ need_D_to_e()

bool libMesh::UNVIO::need_D_to_e ( std::string &  number)
private

Replaces "1.1111D+00" with "1.1111e+00" if necessary.

This function only needs to be called once per stream, one can assume that if one number needs rewriting, they all do.

Returns
true if the replacement occurs, false otherwise.

Definition at line 400 of file unv_io.C.

401{
402 // find "D" in string, start looking at 6th element since dont expect a "D" earlier.
403 std::string::size_type position = number.find("D", 6);
404
405 if (position != std::string::npos)
406 {
407 // replace "D" in string
408 number.replace(position, 1, "e");
409 return true;
410 }
411 else
412 return false;
413}

Referenced by read_dataset().

◆ nodes_in()

void libMesh::UNVIO::nodes_in ( std::istream &  in_file)
private

Read nodes from file.

Definition at line 298 of file unv_io.C.

299{
300 LOG_SCOPE("nodes_in()","UNVIO");
301
302 if (this->verbose())
303 libMesh::out << " Reading nodes" << std::endl;
304
305 MeshBase & mesh = MeshInput<MeshBase>::mesh();
306
307 // node label, we use an int here so we can read in a -1
308 int node_label;
309
310 // We'll just read the floating point values as strings even when
311 // there are no "D" characters in the file. This will make parsing
312 // the file a bit slower but the logic to do so will all be
313 // simplified and in one place...
314 std::string line;
315 std::istringstream coords_stream;
316
317 // Continue reading nodes until there are none left
318 unsigned ctr = 0;
319 while (true)
320 {
321 // Read the node label
322 in_file >> node_label;
323
324 // Break out of the while loop when we hit -1
325 if (node_label == -1)
326 break;
327
328 // Read and discard the the rest of the node data on this line
329 // which we do not currently use:
330 // .) exp_coord_sys_num
331 // .) disp_coord_sys_num
332 // .) color
333 std::getline(in_file, line);
334
335 // read the floating-point data
336 std::getline(in_file, line);
337
338 // Replace any "D" characters used for exponents with "E"
339 size_t last_pos = 0;
340 while (true)
341 {
342 last_pos = line.find("D", last_pos);
343
344 if (last_pos != std::string::npos)
345 line.replace(last_pos, 1, "E");
346 else
347 break;
348 }
349
350 // Construct a stream object from the current line and then
351 // stream in the xyz values.
352 coords_stream.str(line);
353 coords_stream.clear(); // clear iostate bits! Important!
354
355 // always 3 coordinates in the UNV file, no matter
356 // what LIBMESH_DIM is.
357 std::array<Real, 3> xyz;
358
359 coords_stream >> xyz[0] >> xyz[1] >> xyz[2];
360
361 Point p(xyz[0]);
362#if LIBMESH_DIM > 1
363 p(1) = xyz[1];
364#else
365 libmesh_assert_equal_to(xyz[1], 0);
366#endif
367#if LIBMESH_DIM > 2
368 p(2) = xyz[2];
369#else
370 libmesh_assert_equal_to(xyz[2], 0);
371#endif
372
373 // Add node to the Mesh, bump the counter.
374 Node * added_node = mesh.add_point(p, ctr++);
375
376 // Maintain the mapping between UNV node ids and libmesh Node
377 // pointers.
378 _unv_node_id_to_libmesh_node_ptr[node_label] = added_node;
379 }
380}
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
Add a new Node at Point p to the end of the vertex array, with processor_id procid.

References _unv_node_id_to_libmesh_node_ptr, libMesh::MeshBase::add_point(), libMesh::MeshInput< MT >::mesh(), libMesh::MeshInput< MeshBase >::mesh(), libMesh::out, and verbose().

Referenced by read_implementation().

◆ nodes_out()

void libMesh::UNVIO::nodes_out ( std::ostream &  out_file)
private

Outputs nodes to the file out_file.

Do not use this directly, but through the proper write method.

Definition at line 870 of file unv_io.C.

871{
872 if (this->verbose())
873 libMesh::out << " Writing " << MeshOutput<MeshBase>::mesh().n_nodes() << " nodes" << std::endl;
874
875 // Write beginning of dataset
876 out_file << " -1\n"
877 << " "
879 << '\n';
880
881 unsigned int
882 exp_coord_sys_dummy = 0, // export coordinate sys. (not supported yet)
883 disp_coord_sys_dummy = 0, // displacement coordinate sys. (not supp. yet)
884 color_dummy = 0; // color(not supported yet)
885
886 // A reference to the parent class's mesh
887 const MeshBase & mesh = MeshOutput<MeshBase>::mesh();
888
889 // Use scientific notation with capital E and default 17 digits for printing out the coordinates
890 out_file << std::scientific << std::setprecision(this->ascii_precision()) << std::uppercase;
891
892 for (const auto & current_node : mesh.node_ptr_range())
893 {
894 dof_id_type node_id = current_node->id();
895
896 out_file << std::setw(10) << node_id
897 << std::setw(10) << exp_coord_sys_dummy
898 << std::setw(10) << disp_coord_sys_dummy
899 << std::setw(10) << color_dummy
900 << '\n';
901
902 // The coordinates - always write out three coords regardless of LIBMESH_DIM
903 Real x = (*current_node)(0);
904
905#if LIBMESH_DIM > 1
906 Real y = (*current_node)(1);
907#else
908 Real y = 0.;
909#endif
910
911#if LIBMESH_DIM > 2
912 Real z = (*current_node)(2);
913#else
914 Real z = 0.;
915#endif
916
917 out_file << std::setw(25) << x
918 << std::setw(25) << y
919 << std::setw(25) << z
920 << '\n';
921 }
922
923 // Write end of dataset
924 out_file << " -1\n";
925}
unsigned int & ascii_precision()
Return/set the precision to use when writing ASCII files.
static const std::string _nodes_dataset_label
label for the node dataset
Definition unv_io.h:193
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

References _nodes_dataset_label, libMesh::MeshOutput< MeshBase >::ascii_precision(), libMesh::MeshInput< MeshBase >::mesh(), libMesh::MeshOutput< MT >::mesh(), libMesh::out, libMesh::Real, and verbose().

Referenced by write_implementation().

◆ read()

void libMesh::UNVIO::read ( const std::string &  file_name)
overridevirtual

This method implements reading a mesh from a specified file.

Implements libMesh::MeshInput< MeshBase >.

Definition at line 96 of file unv_io.C.

97{
98 if (Utility::contains(file_name, ".gz"))
99 {
100#ifdef LIBMESH_HAVE_GZSTREAM
101
102 igzstream in_stream (file_name.c_str());
103 this->read_implementation (in_stream);
104
105#else
106
107 libmesh_error_msg("ERROR: You must have the zlib.h header files and libraries to read and write compressed streams.");
108
109#endif
110 return;
111 }
112
113 else
114 {
115 std::ifstream in_stream (file_name.c_str());
116 this->read_implementation (in_stream);
117 return;
118 }
119}
void read_implementation(std::istream &in_stream)
The actual implementation of the read function.
Definition unv_io.C:122
bool contains(std::string_view superstring, std::string_view substring)
Look for a substring within a string.
Definition utility.C:205

References libMesh::Utility::contains(), and read_implementation().

Referenced by main(), and libMesh::NameBasedIO::read().

◆ read_dataset()

void libMesh::UNVIO::read_dataset ( std::string  file_name)

Read a UNV data file containing a dataset of type "2414".

For more info, see http://tinyurl.com/htcf6zm

Definition at line 1161 of file unv_io.C.

1162{
1163 std::ifstream in_stream(file_name.c_str());
1164
1165 libmesh_error_msg_if(!in_stream.good(), "Error opening UNV data file.");
1166
1167 std::string olds, news, dummy;
1168
1169 while (true)
1170 {
1171 in_stream >> olds >> news;
1172
1173 // A "-1" followed by a number means the beginning of a dataset.
1174 while (((olds != "-1") || (news == "-1")) && !in_stream.eof())
1175 {
1176 olds = news;
1177 in_stream >> news;
1178 }
1179
1180 if (in_stream.eof())
1181 break;
1182
1183 // We only support reading datasets in the "2414" format.
1184 if (news == "2414")
1185 {
1186 // Ignore the rest of the current line and the next two
1187 // lines that contain analysis dataset label and name.
1188 for (unsigned int i=0; i<3; i++)
1189 std::getline(in_stream, dummy);
1190
1191 // Read the dataset location, where
1192 // 1: Data at nodes
1193 // 2: Data on elements
1194 // Currently only data on nodes is supported.
1195 unsigned int dataset_location;
1196 in_stream >> dataset_location;
1197
1198 // Currently only nodal datasets are supported.
1199 libmesh_error_msg_if(dataset_location != 1, "ERROR: Currently only Data at nodes is supported.");
1200
1201 // Ignore the rest of this line and the next five records.
1202 for (unsigned int i=0; i<6; i++)
1203 std::getline(in_stream, dummy);
1204
1205 // These data are all of no interest to us...
1206 unsigned int
1207 model_type,
1208 analysis_type,
1209 data_characteristic,
1210 result_type;
1211
1212 // The type of data (complex, real, float, double etc, see
1213 // below).
1214 unsigned int data_type;
1215
1216 // The number of floating-point values per entity.
1217 unsigned int num_vals_per_node;
1218
1219 in_stream >> model_type // not used here
1220 >> analysis_type // not used here
1221 >> data_characteristic // not used here
1222 >> result_type // not used here
1223 >> data_type
1224 >> num_vals_per_node;
1225
1226 // Ignore the rest of record 9, and records 10-13.
1227 for (unsigned int i=0; i<5; i++)
1228 std::getline(in_stream, dummy);
1229
1230 // Now get the foreign (aka UNV node) node number and
1231 // the respective nodal data.
1232 int f_n_id;
1233 std::vector<Number> values;
1234
1235 while (true)
1236 {
1237 in_stream >> f_n_id;
1238
1239 // If -1 then we have reached the end of the dataset.
1240 if (f_n_id == -1)
1241 break;
1242
1243 // Resize the values vector (usually data in three
1244 // principle directions, i.e. num_vals_per_node = 3).
1245 values.resize(num_vals_per_node);
1246
1247 // Read the values for the respective node.
1248 for (unsigned int data_cnt=0; data_cnt<num_vals_per_node; data_cnt++)
1249 {
1250 // Check what data type we are reading.
1251 // 2,4: Real
1252 // 5,6: Complex
1253 // other data types are not supported yet.
1254 // As again, these floats may also be written
1255 // using a 'D' instead of an 'e'.
1256 if (data_type == 2 || data_type == 4)
1257 {
1258 std::string buf;
1259 in_stream >> buf;
1260 this->need_D_to_e(buf);
1261#ifdef LIBMESH_USE_COMPLEX_NUMBERS
1262 values[data_cnt] = Complex(std::atof(buf.c_str()), 0.);
1263#else
1264 values[data_cnt] = std::atof(buf.c_str());
1265#endif
1266 }
1267
1268 else if (data_type == 5 || data_type == 6)
1269 {
1270#ifdef LIBMESH_USE_COMPLEX_NUMBERS
1271 Real re_val, im_val;
1272
1273 std::string buf;
1274 in_stream >> buf;
1275
1276 if (this->need_D_to_e(buf))
1277 {
1278 re_val = std::atof(buf.c_str());
1279 in_stream >> buf;
1280 this->need_D_to_e(buf);
1281 im_val = std::atof(buf.c_str());
1282 }
1283 else
1284 {
1285 re_val = std::atof(buf.c_str());
1286 in_stream >> im_val;
1287 }
1288
1289 values[data_cnt] = Complex(re_val,im_val);
1290#else
1291
1292 libmesh_error_msg("ERROR: Complex data only supported when libMesh is configured with --enable-complex!");
1293#endif
1294 }
1295
1296 else
1297 libmesh_error_msg("ERROR: Data type not supported.");
1298
1299 } // end loop data_cnt
1300
1301 // Get a pointer to the Node associated with the UNV node id.
1302 auto & node_ptr = libmesh_map_find(_unv_node_id_to_libmesh_node_ptr, f_n_id);
1303
1304 // Store the nodal values in our map which uses the
1305 // libMesh Node* as the key. We use operator[] here
1306 // because we want to create an empty vector if the
1307 // entry does not already exist.
1308 _node_data[node_ptr] = values;
1309 } // end while (true)
1310 } // end if (news == "2414")
1311 } // end while (true)
1312}
bool need_D_to_e(std::string &number)
Replaces "1.1111D+00" with "1.1111e+00" if necessary.
Definition unv_io.C:400
MPI_Datatype data_type
std::complex< Real > Complex

References _node_data, _unv_node_id_to_libmesh_node_ptr, need_D_to_e(), and libMesh::Real.

Referenced by main().

◆ read_implementation()

void libMesh::UNVIO::read_implementation ( std::istream &  in_stream)
private

The actual implementation of the read function.

The public read interface simply decides which type of stream to pass the implementation.

Definition at line 122 of file unv_io.C.

123{
124 // Keep track of what kinds of elements this file contains
125 elems_of_dimension.clear();
126 elems_of_dimension.resize(4, false);
127
128 {
129 libmesh_error_msg_if(!in_stream.good(), "ERROR: Input file not good.");
130
131 // Flags to be set when certain sections are encountered
132 bool
133 found_node = false,
134 found_elem = false,
135 found_group = false;
136
137 // strings for reading the file line by line
138 std::string
139 old_line,
140 current_line;
141
142 while (true)
143 {
144 // Save off the old_line. This will provide extra reliability
145 // for detecting the beginnings of the different sections.
146 old_line = current_line;
147
148 // Try to read something. This may set EOF!
149 std::getline(in_stream, current_line);
150
151 // If the stream is still "valid", parse the line
152 if (in_stream)
153 {
154 // UNV files always have some amount of leading
155 // whitespace, let's not rely on exactly how much... This
156 // command deletes it.
157 current_line.erase(std::remove_if(current_line.begin(), current_line.end(),
158 [](unsigned char const c){return std::isspace(c);}),
159 current_line.end());
160
161 // Parse the nodes section
162 if (current_line == _nodes_dataset_label &&
163 old_line == "-1")
164 {
165 found_node = true;
166 this->nodes_in(in_stream);
167 }
168
169 // Parse the elements section
170 else if (current_line == _elements_dataset_label &&
171 old_line == "-1")
172 {
173 // The current implementation requires the nodes to
174 // have been read before reaching the elements
175 // section.
176 libmesh_error_msg_if(!found_node,
177 "ERROR: The Nodes section must come before the Elements section of the UNV file!");
178
179 found_elem = true;
180 this->elements_in(in_stream);
181 }
182
183 // Parse the groups section
184 else if (current_line == _groups_dataset_label &&
185 old_line == "-1")
186 {
187 // The current implementation requires the nodes and
188 // elements to have already been read before reaching
189 // the groups section.
190 libmesh_error_msg_if(!found_node || !found_elem,
191 "ERROR: The Nodes and Elements sections must come before the Groups section of the UNV file!");
192
193 found_group = true;
194 this->groups_in(in_stream);
195 }
196
197 // We can stop reading once we've found the nodes, elements,
198 // and group sections.
199 if (found_node && found_elem && found_group)
200 break;
201
202 // If we made it here, we're not done yet, so keep reading
203 continue;
204 }
205
206 // if (!in_stream) check to see if EOF was set. If so, break out of while loop.
207 if (in_stream.eof())
208 break;
209
210 // If !in_stream and !in_stream.eof(), stream is in a bad state!
211 libmesh_error_msg("Stream is bad! Perhaps the file does not exist?");
212 } // end while (true)
213
214 // By now we better have found the datasets for nodes and elements,
215 // otherwise the unv file is bad!
216 libmesh_error_msg_if(!found_node, "ERROR: Could not find nodes!");
217 libmesh_error_msg_if(!found_elem, "ERROR: Could not find elements!");
218 }
219
220
221
222 {
223 // Set the mesh dimension to the largest element dimension encountered
225
226#if LIBMESH_DIM < 3
227 libmesh_error_msg_if(MeshInput<MeshBase>::mesh().mesh_dimension() > LIBMESH_DIM,
228 "Cannot open dimension "
229 << MeshInput<MeshBase>::mesh().mesh_dimension()
230 << " mesh file when configured without "
231 << MeshInput<MeshBase>::mesh().mesh_dimension()
232 << "D support." );
233#endif
234
235 // Delete any lower-dimensional elements that might have been
236 // added to the mesh strictly for setting BCs.
237 {
238 // Grab reference to the Mesh
239 MeshBase & mesh = MeshInput<MeshBase>::mesh();
240
241 unsigned char max_dim = this->max_elem_dimension_seen();
242
243 for (const auto & elem : mesh.element_ptr_range())
244 if (elem->dim() < max_dim)
245 mesh.delete_elem(elem);
246 }
247
248 if (this->verbose())
249 libMesh::out << " Finished." << std::endl << std::endl;
250 }
251}
static const std::string _groups_dataset_label
label for the groups dataset
Definition unv_io.h:203
void groups_in(std::istream &in_file)
Reads the "groups" section of the file.
Definition unv_io.C:417
void nodes_in(std::istream &in_file)
Read nodes from file.
Definition unv_io.C:298
void elements_in(std::istream &in_file)
Method reads elements and stores them in std::vector<Elem *> _elements in the same order as they come...
Definition unv_io.C:583

References _elements_dataset_label, _groups_dataset_label, _nodes_dataset_label, libMesh::MeshBase::delete_elem(), elements_in(), libMesh::MeshInput< MeshBase >::elems_of_dimension, groups_in(), max_elem_dimension_seen(), libMesh::MeshInput< MT >::mesh(), libMesh::MeshInput< MeshBase >::mesh(), nodes_in(), libMesh::out, and verbose().

Referenced by read().

◆ set_n_partitions()

void libMesh::MeshInput< MeshBase >::set_n_partitions ( unsigned int  n_parts)
inlineprotectedinherited

Sets the number of partitions in the mesh.

Typically this gets done by the partitioner, but some parallel file formats begin "pre-partitioned".

Definition at line 101 of file mesh_input.h.

101{ this->mesh().set_n_partitions() = n_parts; }
MeshBase & mesh

◆ skip_comment_lines()

void libMesh::MeshInput< MeshBase >::skip_comment_lines ( std::istream &  in,
const char  comment_start 
)
protectedinherited

Reads input from in, skipping all the lines that start with the character comment_start.

Definition at line 113 of file mesh_input.h.

189{
190 char c, line[256];
191
192 while (in.get(c), c==comment_start)
193 in.getline (line, 255);
194
195 // put back first character of
196 // first non-comment line
197 in.putback (c);
198}

◆ verbose()

bool & libMesh::UNVIO::verbose ( )

Set the flag indicating if we should be verbose.

Definition at line 89 of file unv_io.C.

90{
91 return _verbose;
92}

References _verbose.

Referenced by elements_in(), elements_out(), nodes_in(), nodes_out(), and read_implementation().

◆ write()

void libMesh::UNVIO::write ( const std::string &  file_name)
overridevirtual

This method implements writing a mesh to a specified file.

Implements libMesh::MeshOutput< MeshBase >.

Definition at line 257 of file unv_io.C.

258{
259 if (Utility::contains(file_name, ".gz"))
260 {
261#ifdef LIBMESH_HAVE_GZSTREAM
262
263 ogzstream out_stream(file_name.c_str());
264 this->write_implementation (out_stream);
265
266#else
267
268 libmesh_error_msg("ERROR: You must have the zlib.h header files and libraries to read and write compressed streams.");
269
270#endif
271
272 return;
273 }
274
275 else
276 {
277 std::ofstream out_stream (file_name.c_str());
278 this->write_implementation (out_stream);
279 return;
280 }
281}
void write_implementation(std::ostream &out_stream)
The actual implementation of the write function.
Definition unv_io.C:286

References libMesh::Utility::contains(), and write_implementation().

Referenced by libMesh::NameBasedIO::write().

◆ write_discontinuous_equation_systems()

void libMesh::MeshOutput< MeshBase >::write_discontinuous_equation_systems ( const std::string &  fname,
const EquationSystems es,
const std::set< std::string > *  system_names = nullptr 
)
virtualinherited

This method implements writing a mesh with discontinuous data to a specified file where the data is taken from the EquationSystems object.

Definition at line 101 of file mesh_output.C.

92{
93 LOG_SCOPE("write_discontinuous_equation_systems()", "MeshOutput");
94
95 // We may need to gather and/or renumber a DistributedMesh to output
96 // it, making that const qualifier in our constructor a dirty lie
97 MT & my_mesh = const_cast<MT &>(*_obj);
98
99 // If we're asked to write data that's associated with a different
100 // mesh, output files full of garbage are the result.
101 libmesh_assert_equal_to(&es.get_mesh(), _obj);
102
103 // A non-renumbered mesh may not have a contiguous numbering, and
104 // that needs to be fixed before we can build a solution vector.
105 if (my_mesh.max_elem_id() != my_mesh.n_elem() ||
106 my_mesh.max_node_id() != my_mesh.n_nodes())
107 {
108 // If we were allowed to renumber then we should have already
109 // been properly renumbered...
110 libmesh_assert(!my_mesh.allow_renumbering());
111
112 libmesh_do_once(libMesh::out <<
113 "Warning: This MeshOutput subclass only supports meshes which are contiguously renumbered!"
114 << std::endl;);
115
116 my_mesh.allow_renumbering(true);
117
118 my_mesh.renumber_nodes_and_elements();
119
120 // Not sure what good going back to false will do here, the
121 // renumbering horses have already left the barn...
122 my_mesh.allow_renumbering(false);
123 }
124
125 MeshSerializer serialize(const_cast<MT &>(*_obj), !_is_parallel_format, _serial_only_needed_on_proc_0);
126
127 // Build the list of variable names that will be written.
128 std::vector<std::string> names;
129 es.build_variable_names (names, nullptr, system_names);
130
131 if (!_is_parallel_format)
132 {
133 // Build the nodal solution values & get the variable
134 // names from the EquationSystems object
135 std::vector<Number> soln;
136 es.build_discontinuous_solution_vector (soln, system_names,
137 nullptr, false, /* defaults */
138 this->get_add_sides());
139
140 this->write_nodal_data_discontinuous (fname, soln, names);
141 }
142 else // _is_parallel_format
143 {
144 libmesh_not_implemented();
145 }
146}
virtual void write_nodal_data_discontinuous(const std::string &, const std::vector< Number > &, const std::vector< std::string > &)
This method implements writing a mesh with discontinuous data to a specified file where the nodal dat...

◆ write_equation_systems()

void libMesh::MeshOutput< MeshBase >::write_equation_systems ( const std::string &  fname,
const EquationSystems es,
const std::set< std::string > *  system_names = nullptr 
)
virtualinherited

This method implements writing a mesh with data to a specified file where the data is taken from the EquationSystems object.

Reimplemented in libMesh::NameBasedIO, and libMesh::ExodusII_IO.

Definition at line 92 of file mesh_output.C.

34{
35 LOG_SCOPE("write_equation_systems()", "MeshOutput");
36
37 // We may need to gather and/or renumber a DistributedMesh to output
38 // it, making that const qualifier in our constructor a dirty lie
39 MT & my_mesh = const_cast<MT &>(*_obj);
40
41 // If we're asked to write data that's associated with a different
42 // mesh, output files full of garbage are the result.
43 libmesh_assert_equal_to(&es.get_mesh(), _obj);
44
45 // A non-parallel format, non-renumbered mesh may not have a contiguous
46 // numbering, and that needs to be fixed before we can build a solution vector.
47 if (!_is_parallel_format &&
48 (my_mesh.max_elem_id() != my_mesh.n_elem() ||
49 my_mesh.max_node_id() != my_mesh.n_nodes()))
50 {
51 // If we were allowed to renumber then we should have already
52 // been properly renumbered...
53 libmesh_assert(!my_mesh.allow_renumbering());
54
55 libmesh_do_once(libMesh::out <<
56 "Warning: This MeshOutput subclass only supports meshes which are contiguously renumbered!"
57 << std::endl;);
58
59 my_mesh.allow_renumbering(true);
60
61 my_mesh.renumber_nodes_and_elements();
62
63 // Not sure what good going back to false will do here, the
64 // renumbering horses have already left the barn...
65 my_mesh.allow_renumbering(false);
66 }
67
68 if (!_is_parallel_format)
69 {
70 MeshSerializer serialize(const_cast<MT &>(*_obj), !_is_parallel_format, _serial_only_needed_on_proc_0);
71
72 // Build the list of variable names that will be written.
73 std::vector<std::string> names;
74 es.build_variable_names (names, nullptr, system_names);
75
76 // Build the nodal solution values & get the variable
77 // names from the EquationSystems object
78 std::vector<Number> soln;
79 es.build_solution_vector (soln, system_names,
80 this->get_add_sides());
81
82 this->write_nodal_data (fname, soln, names);
83 }
84 else // _is_parallel_format
85 this->write_nodal_data (fname, es, system_names);
86}
virtual void write_nodal_data(const std::string &, const std::vector< Number > &, const std::vector< std::string > &)
This method implements writing a mesh with nodal data to a specified file where the nodal data and va...

◆ write_implementation()

void libMesh::UNVIO::write_implementation ( std::ostream &  out_stream)
private

The actual implementation of the write function.

The public write interface simply decides which type of stream to pass the implementation.

Definition at line 286 of file unv_io.C.

287{
288 libmesh_error_msg_if(!out_file.good(), "ERROR: Output file not good.");
289
290 // write the nodes, then the elements
291 this->nodes_out (out_file);
292 this->elements_out (out_file);
293}
void elements_out(std::ostream &out_file)
Outputs the element data to the file out_file.
Definition unv_io.C:932
void nodes_out(std::ostream &out_file)
Outputs nodes to the file out_file.
Definition unv_io.C:870

References elements_out(), and nodes_out().

Referenced by write().

◆ write_nodal_data() [1/3]

void libMesh::MeshOutput< MeshBase >::write_nodal_data ( const std::string &  fname,
const EquationSystems es,
const std::set< std::string > *  system_names 
)
virtualinherited

This method should be overridden by "parallel" output formats for writing nodal data.

Instead of getting a localized copy of the nodal solution vector, it directly uses EquationSystems current_local_solution vectors to look up nodal values.

If not implemented, reorders the solutions into a nodal-only NumericVector and calls the above version of this function.

Reimplemented in libMesh::Nemesis_IO.

Definition at line 149 of file mesh_output.C.

165{
166 std::vector<std::string> names;
167 es.build_variable_names (names, nullptr, system_names);
168
169 std::unique_ptr<NumericVector<Number>> parallel_soln =
170 es.build_parallel_solution_vector(system_names);
171
172 this->write_nodal_data (fname, *parallel_soln, names);
173}

◆ write_nodal_data() [2/3]

void libMesh::MeshOutput< MeshBase >::write_nodal_data ( const std::string &  fname,
const NumericVector< Number > &  parallel_soln,
const std::vector< std::string > &  names 
)
virtualinherited

This method may be overridden by "parallel" output formats for writing nodal data.

Instead of getting a localized copy of the nodal solution vector, it is passed a NumericVector of type=PARALLEL which is in node-major order i.e. (u0,v0,w0, u1,v1,w1, u2,v2,w2, u3,v3,w3, ...) and contains n_nodes*n_vars total entries. Then, it is up to the individual I/O class to extract the required solution values from this vector and write them in parallel.

If not implemented, localizes the parallel vector into a std::vector and calls the other version of this function.

Reimplemented in libMesh::Nemesis_IO.

Definition at line 136 of file mesh_output.C.

152{
153 // This is the fallback implementation for parallel I/O formats that
154 // do not yet implement proper writing in parallel, and instead rely
155 // on the full solution vector being available on all processors.
156 std::vector<Number> soln;
157 parallel_soln.localize(soln);
158 this->write_nodal_data(fname, soln, names);
159}
virtual void localize(std::vector< T > &v_local) const =0
Creates a copy of the global vector in the local vector v_local.

◆ write_nodal_data() [3/3]

virtual void libMesh::MeshOutput< MeshBase >::write_nodal_data ( const std::string &  ,
const std::vector< Number > &  ,
const std::vector< std::string > &   
)
inlinevirtualinherited

This method implements writing a mesh with nodal data to a specified file where the nodal data and variable names are provided.

Reimplemented in libMesh::ExodusII_IO, libMesh::GmshIO, libMesh::GMVIO, libMesh::GnuPlotIO, libMesh::MEDITIO, libMesh::NameBasedIO, libMesh::TecplotIO, libMesh::VTKIO, libMesh::Nemesis_IO, and libMesh::UCDIO.

Definition at line 109 of file mesh_output.h.

112 { libmesh_not_implemented(); }

◆ write_nodal_data_discontinuous()

virtual void libMesh::MeshOutput< MeshBase >::write_nodal_data_discontinuous ( const std::string &  ,
const std::vector< Number > &  ,
const std::vector< std::string > &   
)
inlinevirtualinherited

This method implements writing a mesh with discontinuous data to a specified file where the nodal data and variables names are provided.

Reimplemented in libMesh::ExodusII_IO.

Definition at line 118 of file mesh_output.h.

121 { libmesh_not_implemented(); }

Member Data Documentation

◆ _ascii_precision

unsigned int libMesh::MeshOutput< MeshBase >::_ascii_precision
privateinherited

Precision to use when writing ASCII files.

Definition at line 207 of file mesh_output.h.

◆ _elements_dataset_label

const std::string libMesh::UNVIO::_elements_dataset_label = "2412"
staticprivate

label for the element dataset

Definition at line 198 of file unv_io.h.

Referenced by elements_out(), and read_implementation().

◆ _groups_dataset_label

const std::string libMesh::UNVIO::_groups_dataset_label = "2467"
staticprivate

label for the groups dataset

Definition at line 203 of file unv_io.h.

Referenced by read_implementation().

◆ _is_parallel_format [1/2]

const bool libMesh::MeshInput< MeshBase >::_is_parallel_format
privateinherited

Flag specifying whether this format is parallel-capable.

If this is false (default) I/O is only permitted when the mesh has been serialized.

Definition at line 130 of file mesh_input.h.

◆ _is_parallel_format [2/2]

const bool libMesh::MeshOutput< MeshBase >::_is_parallel_format
protectedinherited

Flag specifying whether this format is parallel-capable.

If this is false (default) I/O is only permitted when the mesh has been serialized.

Definition at line 184 of file mesh_output.h.

◆ _node_data

std::map<Node *, std::vector<Number> > libMesh::UNVIO::_node_data
private

Map from libMesh Node* to data at that node, as read in by the read_dataset() function.

Definition at line 214 of file unv_io.h.

Referenced by get_data(), and read_dataset().

◆ _nodes_dataset_label

const std::string libMesh::UNVIO::_nodes_dataset_label = "2411"
staticprivate

label for the node dataset

Definition at line 193 of file unv_io.h.

Referenced by nodes_out(), and read_implementation().

◆ _obj

MeshBase * libMesh::MeshInput< MeshBase >::_obj
privateinherited

A pointer to a non-const object object.

This allows us to read the object from file.

Definition at line 123 of file mesh_input.h.

◆ _serial_only_needed_on_proc_0

const bool libMesh::MeshOutput< MeshBase >::_serial_only_needed_on_proc_0
protectedinherited

Flag specifying whether this format can be written by only serializing the mesh to processor zero.

If this is false (default) the mesh will be serialized to all processors

Definition at line 193 of file mesh_output.h.

◆ _unv_elem_id_to_libmesh_elem_id

std::map<unsigned, unsigned> libMesh::UNVIO::_unv_elem_id_to_libmesh_elem_id
private

Map UNV element IDs to libmesh element IDs.

Definition at line 208 of file unv_io.h.

Referenced by elements_in(), and groups_in().

◆ _unv_node_id_to_libmesh_node_ptr

std::map<dof_id_type, Node *> libMesh::UNVIO::_unv_node_id_to_libmesh_node_ptr
private

Maps UNV node IDs to libMesh Node*s.

Used when reading. Even if the libMesh Mesh is renumbered, this map should continue to be valid.

Definition at line 188 of file unv_io.h.

Referenced by elements_in(), nodes_in(), and read_dataset().

◆ _verbose

bool libMesh::UNVIO::_verbose
private

should be be verbose?

Definition at line 182 of file unv_io.h.

Referenced by verbose().

◆ elems_of_dimension

std::vector<bool> libMesh::MeshInput< MeshBase >::elems_of_dimension
protectedinherited

A vector of bools describing what dimension elements have been encountered when reading a mesh.

Definition at line 107 of file mesh_input.h.


The documentation for this class was generated from the following files: