-
Notifications
You must be signed in to change notification settings - Fork 0
/
handlePwscf.h
167 lines (145 loc) · 5.03 KB
/
handlePwscf.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#ifndef HANDLE_PWSCF_H
#define HANDLE_PWSCF_H
#include "handleTilemats.h"
#include "types.h"
#include "util.h"
#include <iostream>
#include <string>
#include <sstream>
#include <cstring>
#include <fstream>
#include <cmath>
#include <iomanip>
using namespace std;
void genWfn(int argc, char* argv[]) {
string inFileName = "undef";
int ssize;
int sskgrid[3];
int sskshift[3] = {0, 0, 0};
// read necessary info from the command line
for (int i = 1; i < argc; i++) {
if (!strcmp(argv[i],"--infile")) {
inFileName= string(argv[i+1]);
} else if (!strcmp(argv[i],"--supercellsize")) {
ssize = atoi(argv[i+1]);
} else if (!strcmp(argv[i],"--sskgrid")) {
for (int j = 0; j < 3; j++) {
stringstream ss1(argv[i+1+j]);
ss1 >> sskgrid[j];
}
i+=3;
} else if (!strcmp(argv[i],"--sskshift")) {
for (int j = 0; j < 3; j++) {
stringstream ss1(argv[i+1+j]);
ss1 >> sskshift[j];
}
i+=3;
}
}
if (inFileName == "undef") {
cout << "No pwscf input filename was given" << endl;
}
pwscfString ps(inFileName);
pwscfData pd(ps);
threeThreeMat<int> tilemat = getTilemat(pd, ssize);
physSys primcell(pd.ptv, pd.ionNames, pd.atpos);
physSys supercell(primcell, tilemat);
// These are the weighted supercell k-points;
vector<weightedKpt> outks;
supercell.getMesh(sskgrid[0], sskgrid[1], sskgrid[2], sskshift[0], sskshift[1], sskshift[2], outks);
// Now need to find the primitive cell k-points necessary
int numCopies = getDet(tilemat);
vector<weightedKpt> primks;
// loop over supercell kpoints
for (int i = 0; i < outks.size(); i++) {
double weight = outks[i].first;
vector<location> locPrimKs;
getPrimKpts(primcell, supercell, outks[i].second, locPrimKs, numCopies);
// for each found primitive cell kpt, see if it is in primks
// if it is add it's weight to the existing one
// if it is not, add it and its weight
for (int j = 0; j < locPrimKs.size(); j++) {
int found = 0;
for (int k = 0; k < primks.size(); k++) {
if (abs(locPrimKs[j][0] - primks[k].second[0]) < 1e-8 &&
abs(locPrimKs[j][1] - primks[k].second[1]) < 1e-8 &&
abs(locPrimKs[j][2] - primks[k].second[2]) < 1e-8) {
primks[k].first+=weight;
found = 1;
k+= primks.size();
}
}
if (!found) {
weightedKpt kp;
kp.first = weight;
for (int k = 0; k < 3; k++) {
kp.second[k] = locPrimKs[j][k];
}
primks.push_back(kp);
}
}
}
// Now outks has the symmetry independent supercell kpoints
// primks has the necessary primitive cell kpts to generate outks
stringstream ss;
ss << "K_POINTS {CRYSTAL}" << endl;
ss.setf(ios_base::fixed, ios_base::floatfield);
ss.precision(8);
ss << setw(8) << primks.size() << endl;
// ss << setw(16) << "kx" << setw(16) << "ky" << setw(16) << "kz" << setw(16) << "wt" << endl;
for (int i = 0; i < primks.size(); i++) {
ss << setw(16) << primks[i].second[0] << setw(16) << primks[i].second[1] << setw(16) << primks[i].second[2] << setw(16) << primks[i].first;
if (i+1 < primks.size()) {
ss << endl;
}
}
string kpointstring = ss.str();
// now need to replace the pwscfString (ps) object's K_POINTS card with a new
// one using kpointstring (need a pwscfReplaceWholeCard)
// Also need to change the calculation from scf to nscf (pwscfString.changePwscfToken)
// Also need to make sure the output has nosym=.true. and noinv=.true. (need an addToPwscfSection)
ps.changePwscfToken("calculation", "'nscf'");
ps.removePwscfToken("nosym");
ps.removePwscfToken("noinv");
ps.addToPwscfSection("system", "nosym", ".true.");
ps.addToPwscfSection("system", "noinv", ".true.");
ps.replaceWholePwscfCard("K_POINTS", kpointstring);
string nscfstring = ps.getOutput();
stringstream p2xstringss;
p2xstringss << "&inputpp" << endl;
p2xstringss << " outdir = '" << pd.outputDir << "'" << endl;
p2xstringss << " prefix = '" << pd.prefix << "'" << endl;
p2xstringss << " write_psir=.false." << endl;
p2xstringss << "/" << endl;
string nscfFname = inFileName;
// get rid of -scf if file has it
size_t index = nscfFname.find("-scf");
if (index != string::npos) {
nscfFname.erase(index, 4);
}
// get rid of .in if file has it
size_t index2 = nscfFname.find(".in");
if (index2 != string::npos) {
nscfFname.erase(index2,3);
}
stringstream fnss;
fnss << nscfFname;
fnss << "-supertwist" << sskgrid[0] << sskgrid[1] << sskgrid[2];
fnss << "-supershift" << sskshift[0] << sskshift[1] << sskshift[2];
fnss << "-nscf.in";
stringstream p2xss;
p2xss << nscfFname;
p2xss << "-supertwist" << sskgrid[0] << sskgrid[1] << sskgrid[2];
p2xss << "-supershift" << sskshift[0] << sskshift[1] << sskshift[2];
p2xss << "-pw2x.in";
//cout << "nscf filename: " << fnss.str() << endl;
//cout << "pw2x filename: " << p2xss.str() << endl;
// Now write the files themselves
ofstream nscffile(fnss.str().c_str());
nscffile << nscfstring;
nscffile.close();
ofstream pw2xfile(p2xss.str().c_str());
pw2xfile << p2xstringss.str();
pw2xfile.close();
}
#endif