1+ // =======================
2+ // AUTHOR : Peize Lin
3+ // DATE : 2021-12-08
4+ // =======================
5+
6+ #include " read_txt_stru.h"
7+ #include " read_txt_tools.h"
8+
9+ #include < algorithm>
10+
11+ namespace Read_Txt_Stru
12+ {
13+ // lat_info:
14+ // {
15+ // Lattice_Constant: [30.0, Bohr],
16+ // Lattice_Vectors:
17+ // [1.0, 0.0, 0.0,
18+ // 0.0, 1.0, 0.0,
19+ // 0.0, 0.0, 1.0],
20+ // Atomic_Positions: [Cartesian, Angstrom]
21+ // }
22+ // elements_info:
23+ // {
24+ // O: {
25+ // Pseudo_Potantial: [O_ONCV_PBE-1.0.upf],
26+ // Numerical_Orbital: [orb_O.dat]
27+ // },
28+ // C: {
29+ // Pseudo_Potantial: [C_ONCV_PBE-1.0.upf]
30+ // }
31+ // }
32+ // atoms:
33+ // [
34+ // [O, 0, 0, 0],
35+ // [H, 0, 0, 3, Force, 1, 1, 1]
36+ // ]
37+ std::tuple<
38+ std::map<std::string, std::vector<std::string>>,
39+ std::map<std::string, std::map<std::string, std::vector<std::string>>>,
40+ std::vector<std::vector<std::string>>>
41+ read_stru (const std::string &file_name)
42+ {
43+ const std::set<std::string> labels_lat = {" Lattice_Constant" , " Lattice_Vectors" , " Atomic_Positions" };
44+ std::set<std::string> labels = {" Element" , " Atoms" };
45+ labels.insert (labels_lat.begin (), labels_lat.end ());
46+
47+ std::vector<std::vector<std::string>> stru = Read_Txt_Tools::read_file_to_vector (file_name, {" #" ," \\ " });
48+
49+ std::map<std::string, std::vector<std::string>> lat_info;
50+ std::map<std::string, std::map<std::string, std::vector<std::string>>> elements_info;
51+ std::vector<std::vector<std::string>> atoms_info;
52+
53+ while (!stru.empty ())
54+ {
55+ std::vector<std::vector<std::string>> stru_one = Read_Txt_Tools::cut_paragraph (stru, labels);
56+ if (stru_one[0 ][0 ]==" Element" )
57+ {
58+ std::map<std::string, std::vector<std::string>> &element_info = elements_info[stru_one[0 ][1 ]];
59+ for (auto ptr=stru_one.begin ()+1 ; ptr<stru_one.end (); ++ptr)
60+ {
61+ element_info[(*ptr)[0 ]] = std::vector<std::string>(ptr->begin ()+1 , ptr->end ());
62+ }
63+ }
64+ else if (stru_one[0 ][0 ]==" Atoms" )
65+ {
66+ // [
67+ // [O, 0, 0, 0],
68+ // [H, 0, 0, 3],
69+ // [Force, 1, 1, 1]
70+ // ]
71+ if (stru_one[0 ].size ()==1 )
72+ {
73+ atoms_info.insert (atoms_info.end (), stru_one.begin ()+1 , stru_one.end ());
74+ }
75+ else
76+ {
77+ std::vector<std::string> atom0 = std::vector<std::string>(stru_one[0 ].begin ()+1 , stru_one[0 ].end ());
78+ atoms_info.push_back (std::move (atom0));
79+ atoms_info.insert (atoms_info.end (), stru_one.begin ()+1 , stru_one.end ());
80+ }
81+
82+ }
83+ else
84+ {
85+ const auto ptr = std::find (labels_lat.begin (), labels_lat.end (), stru_one[0 ][0 ]);
86+ if (ptr!=labels_lat.end ())
87+ {
88+ const std::vector<std::string> data = Read_Txt_Tools::chain (stru_one);
89+ lat_info[data[0 ]] = std::vector<std::string>(data.begin ()+1 , data.end ());
90+ }
91+ else
92+ throw std::invalid_argument (stru_one[0 ][0 ]);
93+ }
94+ }
95+
96+ std::set<std::string> elements_label;
97+ for (const auto & i : elements_info)
98+ elements_label.insert (i.first );
99+ std::vector<std::vector<std::string>> atoms_info_new = Read_Txt_Stru::organize_atom_info (std::move (atoms_info), elements_label);
100+
101+ return make_tuple (std::move (lat_info), std::move (elements_info), std::move (atoms_info_new));
102+ }
103+
104+ // atoms_info_old:
105+ // [
106+ // [H, 0, 0, 0],
107+ // [O, 0, 0, 3],
108+ // [Force, 1, 1, 1]
109+ // ]
110+ // atoms_info_new:
111+ // [
112+ // [H, 0, 0, 0],
113+ // [O, 0, 0, 3, Force, 1, 1, 1]
114+ // ]
115+ std::vector<std::vector<std::string>> organize_atom_info (
116+ std::vector<std::vector<std::string>> &&atoms_info_old,
117+ const std::set<std::string> &elements_label)
118+ {
119+ std::vector<std::vector<std::string>> atoms_info_new;
120+ while (!atoms_info_old.empty ())
121+ {
122+ const std::vector<std::vector<std::string>> atom_one = Read_Txt_Tools::cut_paragraph (atoms_info_old, elements_label);
123+ atoms_info_new.push_back (Read_Txt_Tools::chain (atom_one));
124+ }
125+ return atoms_info_new;
126+ }
127+ }
0 commit comments