FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
abacus-develop/source/source_cell/read_pp_vwr.cpp at develop · pplab/abacus-develop · GitHub
pplab
/
abacus-develop
Public
forked from
deepmodeling/abacus-develop
Notifications
You must be signed in to change notification settings
Fork
0
Star
1
Code
Pull requests
0
Actions
Projects
Security and quality
0
Insights
Additional navigation options
Code
Pull requests
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
abacus-develop
/
source
/
source_cell
/
read_pp_vwr.cpp
Copy path
More file actions
More file actions
Latest commit
History
History
History
380 lines (353 loc) · 13.2 KB
Breadcrumbs
abacus-develop
/
source
/
source_cell
/
read_pp_vwr.cpp
Copy path
File metadata and controls
380 lines (353 loc) · 13.2 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
#
include
"
read_pp.h
"
//
----------------------------------------------------------
//
This code is used to read in vwr pseudopotential format,
//
Now we only use LDA, so if PBE or other functionals are used,
//
one needs to change the following code. The vwr format
//
needs we to generate NL projectors by ourself.
//
One way to check this is correct
//
is to use opium to generate .ncpp pseudopotential first,
//
which contains the same informaiton in vwr, then we had
//
both UPF format from upftools in Quantum Espresso and
//
we can write a short code to transform ncpp to vwr.
//
Then compare the two results.
//
mohan 2013-05-25
//
-----------------------------------------------------------
int
Pseudopot_upf::read_pseudo_vwr
(std::ifstream &ifs, Atom_pseudo& pp)
{
GlobalV::ofs_running <<
"
-------------------------------------------------
"
<< std::endl;
std::cout <<
"
READ IN VWR TYPE PSEUDOPOTENTIALS.
"
<< std::endl;
GlobalV::ofs_running <<
"
Read in vwr type pseudopotentials
"
<< std::endl;
//
--------------------------------------
//
(1) read in data
//
--------------------------------------
pp.
xc_func
=
"
PZ
"
;
pp.
pp_type
=
"
NC
"
;
pp.
tvanp
=
false
;
//
(1) read in mesh
std::string value;
size_t
length=
0
;
ifs >> value; length = value.
find
(
"
,
"
); value.
erase
(length,
1
);
pp.
mesh
=
std::atoi
( value.
c_str
() );
//
the mesh should be odd, which is forced in Simpson integration
this
->
mesh_changed
=
false
;
if
(pp.
mesh
%
2
==
0
)
{
pp.
mesh
=pp.
mesh
-
1
;
this
->
mesh_changed
=
true
;
GlobalV::ofs_running <<
"
Mesh number - 1, we need odd number,
\n
this may affect some polar atomic orbitals.
"
<< std::endl;
}
GlobalV::ofs_running <<
std::setw
(
15
) <<
"
MESH
"
<<
std::setw
(
15
) << pp.
mesh
<< std::endl;
//
(2) read in nlcc: nonlinear core correction
ifs >> value; length = value.
find
(
"
,
"
); value.
erase
(length,
1
);
pp.
nlcc
=
std::atoi
( value.
c_str
() );
GlobalV::ofs_running <<
std::setw
(
15
) <<
"
NLCC
"
<<
std::setw
(
15
) << pp.
nlcc
<< std::endl;
//
(3) iatom : index for atom
ifs >> value; length = value.
find
(
"
,
"
); value.
erase
(length,
1
);
pp.
psd
= value;
GlobalV::ofs_running <<
std::setw
(
15
) <<
"
ATOM
"
<<
std::setw
(
15
) << pp.
psd
<< std::endl;
//
(4) valence electron number
ifs >> value; length = value.
find
(
"
,
"
); value.
erase
(length,
1
);
pp.
zv
=
std::stod
( value );
GlobalV::ofs_running <<
std::setw
(
15
) <<
"
Z(VALENCE)
"
<<
std::setw
(
15
) << pp.
zv
<< std::endl;
//
(5) spd_loc, which local pseudopotential should I choose
ifs >> value; length = value.
find
(
"
,
"
); value.
erase
(length,
1
);
spd_loc =
std::atoi
( value.
c_str
() );
GlobalV::ofs_running <<
std::setw
(
15
) <<
"
LOC(spd)
"
<<
std::setw
(
15
) << spd_loc << std::endl;
//
(6) read in the occupations
std::vector<
double
>
tmp_oc
(
3
,
0.0
);
ifs >> value; length = value.
find
(
"
,
"
); value.
erase
(length,
1
);
tmp_oc[
0
]=
std::atoi
( value.
c_str
() );
ifs >> value; length = value.
find
(
"
,
"
); value.
erase
(length,
1
);
tmp_oc[
1
]=
std::atoi
( value.
c_str
() );
ifs >> value; length = value.
find
(
"
,
"
); value.
erase
(length,
1
);
tmp_oc[
2
]=
std::atoi
( value.
c_str
() );
GlobalV::ofs_running <<
std::setw
(
15
) <<
"
OCCUPATION
"
<<
std::setw
(
15
) << tmp_oc[
0
]
<<
std::setw
(
15
) << tmp_oc[
1
] <<
std::setw
(
15
) << tmp_oc[
2
] << std::endl;
//
(7) spin orbital
ifs >> pp.
has_so
;
//
label to count the projector or atomic wave functions
getline
(ifs,value);
int
iref_s, iref_p, iref_d;
ifs >> iref_s >> iref_p >> iref_d;
GlobalV::ofs_running <<
std::setw
(
15
) <<
"
Vnl_USED
"
<<
std::setw
(
15
) << iref_s
<<
std::setw
(
15
) << iref_p <<
std::setw
(
15
) << iref_d << std::endl;
if
(spd_loc==
1
) { iref_s=
0
;
}
else
if
(spd_loc==
2
) { iref_p=
0
;
}
else
if
(spd_loc==
3
) { iref_d=
0
;
}
ifs >> iTB_s >> iTB_p >> iTB_d;
GlobalV::ofs_running <<
std::setw
(
15
) <<
"
Orb_USED
"
<<
std::setw
(
15
) << iTB_s
<<
std::setw
(
15
) << iTB_p <<
std::setw
(
15
) << iTB_d << std::endl;
//
calculate the number of wave functions
pp.
nchi
=
0
;
if
(iTB_s) { ++pp.
nchi
;
}
if
(iTB_p) { ++pp.
nchi
;
}
if
(iTB_d) { ++pp.
nchi
;
}
GlobalV::ofs_running <<
std::setw
(
15
) <<
"
NWFC
"
<<
std::setw
(
15
) << pp.
nchi
<< std::endl;
//
allocate occupation number array for wave functions
pp.
oc
= std::vector<
double
>(pp.
nchi
,
0.0
);
pp.
els
= std::vector<std::string>(pp.
nchi
,
"
"
);
//
set the value of occupations
pp.
lchi
= std::vector<
int
>(pp.
nchi
,
0
);
int
iwfc=
0
;
if
(iTB_s){pp.
oc
[iwfc]=tmp_oc[
0
];pp.
lchi
[iwfc]=
0
;pp.
els
[iwfc]=
"
S
"
;++iwfc;}
if
(iTB_p){pp.
oc
[iwfc]=tmp_oc[
1
];pp.
lchi
[iwfc]=
1
;pp.
els
[iwfc]=
"
P
"
;++iwfc;}
if
(iTB_d){pp.
oc
[iwfc]=tmp_oc[
2
];pp.
lchi
[iwfc]=
2
;pp.
els
[iwfc]=
"
D
"
;++iwfc;}
getline
(ifs,value);
//
global variables that will be used
//
in other classes.
pp.
r
= std::vector<
double
>(pp.
mesh
,
0.0
);
pp.
rab
= std::vector<
double
>(pp.
mesh
,
0.0
);
pp.
vloc_at
= std::vector<
double
>(pp.
mesh
,
0.0
);
pp.
rho_at
= std::vector<
double
>(pp.
mesh
,
0.0
);
pp.
rho_atc
= std::vector<
double
>(pp.
mesh
,
0.0
);
//
local variables in this function
std::vector<
double
> vs = std::vector<
double
>(pp.
mesh
,
0.0
);
//
local pseudopotential for s, unit is Hartree
std::vector<
double
> vp = std::vector<
double
>(pp.
mesh
,
0.0
);
//
local pseudopotential for p
std::vector<
double
> vd = std::vector<
double
>(pp.
mesh
,
0.0
);
//
local pseudopotential for d
std::vector<
double
> ws = std::vector<
double
>(pp.
mesh
,
0.0
);
//
wave function for s
std::vector<
double
> wp = std::vector<
double
>(pp.
mesh
,
0.0
);
//
wave function for p
std::vector<
double
> wd = std::vector<
double
>(pp.
mesh
,
0.0
);
//
wave function for d
std::string line;
if
(spd_loc>
0
&& pp.
nlcc
==
0
)
{
for
(
int
ir=
0
; ir<pp.
mesh
; ++ir)
{
//
it's an interesting question whether
//
ws[ir] has 1/sqrt(4pi)
ifs >> pp.
r
[ir] >> vs[ir] >> vp[ir] >> vd[ir]
>> ws[ir] >> wp[ir] >> wd[ir];
getline
(ifs, line);
}
}
else
if
(spd_loc==
0
&& pp.
nlcc
==
0
)
{
for
(
int
ir=
0
; ir<pp.
mesh
; ++ir)
{
ifs >> pp.
r
[ir] >> vs[ir] >> vp[ir] >> vd[ir]
>> ws[ir] >> wp[ir] >> wd[ir] >> pp.
vloc_at
[ir];
getline
(ifs, line);
}
}
else
if
(spd_loc>
0
&& pp.
nlcc
==
1
)
{
for
(
int
ir=
0
; ir<pp.
mesh
; ++ir)
{
ifs >> pp.
r
[ir] >> vs[ir] >> vp[ir] >> vd[ir]
>> ws[ir] >> wp[ir] >> wd[ir] >> pp.
rho_atc
[ir];
getline
(ifs, line);
}
}
else
if
(spd_loc==
0
&& pp.
nlcc
==
1
)
{
for
(
int
ir=
0
; ir<pp.
mesh
; ++ir)
{
ifs >> pp.
r
[ir] >> vs[ir] >> vp[ir] >> vd[ir]
>> ws[ir] >> wp[ir] >> wd[ir] >> pp.
vloc_at
[ir] >> pp.
rho_atc
[ir];
getline
(ifs, line);
}
}
//
Hartree to Rydberg
for
(
int
ir=
0
; ir<pp.
mesh
; ++ir)
{
vs[ir] *=
2.0
;
vp[ir] *=
2.0
;
vd[ir] *=
2.0
;
pp.
vloc_at
[ir] *=
2.0
;
}
//
--------------------------------------
//
(2) check unit
//
--------------------------------------
//
calculate rab;
//
rab may not be accurate enough
pp.
rab
[
0
] = pp.
r
[
0
];
for
(
int
ir=
1
; ir<pp.
mesh
-
1
; ++ir)
{
pp.
rab
[ir]=(pp.
r
[ir+
1
]-pp.
r
[ir-
1
])/
2.0
;
}
//
check unit of vs, vp, vd
double
units =
0.0
;
double
unitp =
0.0
;
double
unitd =
0.0
;
for
(
int
ir=
1
; ir<pp.
mesh
-
1
; ++ir)
{
double
dr = (pp.
r
[ir+
1
]-pp.
r
[ir-
1
])/
2.0
;
units += ws[ir] * ws[ir] * pp.
r
[ir] * pp.
r
[ir] * dr;
unitp += wp[ir] * wp[ir] * pp.
r
[ir] * pp.
r
[ir] * dr;
unitd += wd[ir] * wd[ir] * pp.
r
[ir] * pp.
r
[ir] * dr;
}
GlobalV::ofs_running <<
std::setw
(
15
) <<
"
WFC_UNIT
"
<<
std::setw
(
15
) << units
<<
std::setw
(
15
) << unitp <<
std::setw
(
15
) << unitd << std::endl;
//
because only the rank=0 procesor read the pseudopotential
//
information, in order to make all the processors to stop
//
the job, we need to return the error information first.
//
we need to choose a threshold for the deviation of the
//
norm of pseudo atomic orbitals, I set 0.2
//
mohan 2013-06-28
if
(
std::abs
(units-
1.0
) >
0.2
&& (iTB_s==
1
|| iref_s==
1
)) {
return
3
;}
if
(
std::abs
(unitp-
1.0
) >
0.2
&& (iTB_p==
1
|| iref_p==
1
)) {
return
3
;}
if
(
std::abs
(unitd-
1.0
) >
0.2
&& (iTB_d==
1
|| iref_d==
1
)) {
return
3
;}
//
calculate the phi*r*sqrt(4pi)
pp.
chi
.
create
(pp.
nchi
,pp.
mesh
);
for
(
int
ir=
0
; ir<pp.
mesh
; ++ir)
{
int
iwfc=
0
;
if
(iTB_s==
1
){pp.
chi
(iwfc,ir) = ws[ir]*pp.
r
[ir];++iwfc;}
if
(iTB_p==
1
){pp.
chi
(iwfc,ir) = wp[ir]*pp.
r
[ir];++iwfc;}
if
(iTB_d==
1
){pp.
chi
(iwfc,ir) = wd[ir]*pp.
r
[ir];++iwfc;}
}
//
rho atom
for
(
int
ir=
0
; ir<pp.
mesh
; ++ir)
{
for
(
int
iwfc=
0
; iwfc<pp.
nchi
; ++iwfc)
{
pp.
rho_at
[ir] += pp.
oc
[iwfc]*pp.
chi
(iwfc,ir)*pp.
chi
(iwfc,ir);
}
}
//
--------------------------------------
//
(4) local pseudopotential
//
--------------------------------------
if
(spd_loc==
0
) {
for
(
int
ir=
0
; ir<pp.
mesh
; ++ir)
{
//
do nothing
}
}
else
if
(spd_loc==
1
) {
for
(
int
ir=
0
; ir<pp.
mesh
; ++ir) { pp.
vloc_at
[ir] = vs[ir];
}
}
else
if
(spd_loc==
2
) {
for
(
int
ir=
0
; ir<pp.
mesh
; ++ir) { pp.
vloc_at
[ir] = vp[ir];
}
}
else
if
(spd_loc==
3
) {
for
(
int
ir=
0
; ir<pp.
mesh
; ++ir) { pp.
vloc_at
[ir] = vd[ir];
}
}
else
if
(spd_loc==
12
) {
for
(
int
ir=
0
; ir<pp.
mesh
; ++ir) { pp.
vloc_at
[ir] = (vs[ir]+vp[ir])/
2.0
;
}
}
else
if
(spd_loc==
13
) {
for
(
int
ir=
0
; ir<pp.
mesh
; ++ir) { pp.
vloc_at
[ir] = (vs[ir]+vd[ir])/
2.0
;
}
}
else
if
(spd_loc==
23
) {
for
(
int
ir=
0
; ir<pp.
mesh
; ++ir) { pp.
vloc_at
[ir] = (vp[ir]+vd[ir])/
2.0
;
}
}
//
--------------------------------------
//
(5) setup nonlocal pseudopotentials
//
--------------------------------------
//
for non-local pseudopotentials.
if
(iref_d==
1
) { pp.
lmax
=
2
;
}
else
if
(iref_p==
1
) { pp.
lmax
=
1
;
}
else
if
(iref_s==
1
) { pp.
lmax
=
0
;
}
else
{
std::cout <<
"
\n
!!! READ THIS FIRST !!!
"
<< std::endl;
std::cout <<
"
Could not decide which is the max angular momentum from .vwr pseudopotential file.
"
<< std::endl;
std::cout <<
"
No reference states in .vwr pseudopotential file.
"
<< std::endl;
std::cout <<
"
That's incorrect, please check the refenrece states in .vwr file.
"
;
std::cout <<
"
\n
!!! READ THIS FIRST !!!
"
<< std::endl;
return
3
;
}
//
no projectors now
pp.
nbeta
=
0
;
if
(iref_s==
1
) { ++pp.
nbeta
;
//
add one s projector
}
if
(iref_p==
1
) { ++pp.
nbeta
;
//
add one p projector
}
if
(iref_d==
1
) { ++pp.
nbeta
;
//
add one p projector
}
GlobalV::ofs_running <<
std::setw
(
15
) <<
"
NPROJ
"
<<
std::setw
(
15
) << pp.
nbeta
<< std::endl;
this
->
nd
= pp.
nbeta
;
GlobalV::ofs_running <<
std::setw
(
15
) <<
"
N-Dij
"
<<
std::setw
(
15
) << nd << std::endl;
//
calculate the angular momentum for each pp.betar
pp.
lll
= std::vector<
int
>(pp.
nbeta
,
0
);
int
icount=
0
;
if
(iref_s==
1
) {pp.
lll
[icount]=
0
; ++icount;}
//
s projector
if
(iref_p==
1
) {pp.
lll
[icount]=
1
; ++icount;}
//
p projector
if
(iref_d==
1
) {pp.
lll
[icount]=
2
; ++icount;}
//
p projector
for
(
int
i=
0
; i<pp.
nbeta
; ++i)
{
GlobalV::ofs_running <<
"
lll[
"
<< i <<
"
]=
"
<< pp.
lll
[i] << std::endl;
}
//
this->kbeta(pp.nbeta): number of mesh points for projector i (must be .le.mesh )
this
->
kbeta
= std::vector<
int
>(pp.
nbeta
,
0
);
pp.
kkbeta
=
0
;
for
(
int
ib =
0
; ib < pp.
nbeta
; ++ib)
{
this
->
kbeta
[ib] = pp.
mesh
;
pp.
kkbeta
= (
this
->
kbeta
[ib] > pp.
kkbeta
) ?
this
->
kbeta
[ib] : pp.
kkbeta
;
}
//
nonlocal projector
pp.
betar
.
create
(pp.
nbeta
,pp.
mesh
);
//
coefficients
pp.
dion
.
create
(pp.
nbeta
,pp.
nbeta
);
//
--------------------------------------
//
(6) generate nonlocal pseudopotentials
//
--------------------------------------
//
tmp function to evaluate < pp.betar | delta_v | pp.betar>
std::vector<
double
> func = std::vector<
double
>(pp.
mesh
,
0.0
);
//
tmp value (vs, vp or vd)
std::vector<
double
> vl = std::vector<
double
>(pp.
mesh
,
0.0
);
//
tmp wave function (ws, wp or wd with r)
std::vector<
double
> wlr = std::vector<
double
>(pp.
mesh
,
0.0
);
double
rcut =
5.0
/
1.03
;
GlobalV::ofs_running <<
std::setw
(
15
) <<
"
RCUT_NL
"
<<
std::setw
(
15
) << rcut << std::endl;
for
(
int
ib=
0
; ib<pp.
nbeta
; ++ib)
{
double
coef =
0.0
;
const
int
lnow = pp.
lll
[ib];
if
(lnow==
0
) {
for
(
int
ir=
0
; ir<pp.
mesh
; ++ir){vl[ir]=vs[ir]; wlr[ir]=ws[ir]*pp.
r
[ir];}
}
else
if
(lnow==
1
) {
for
(
int
ir=
0
; ir<pp.
mesh
; ++ir){vl[ir]=vp[ir]; wlr[ir]=wp[ir]*pp.
r
[ir];}
}
else
if
(lnow==
2
) {
for
(
int
ir=
0
; ir<pp.
mesh
; ++ir){vl[ir]=vd[ir]; wlr[ir]=wd[ir]*pp.
r
[ir];}
}
//
for non-local projectors
//
note that < phi | dV | phi > integration must have 4pi,
//
this 4pi is also needed in < phi | phi > = 1 integration.
//
However, this phi has sqrt(sphi) already because I
//
found < phi | phi > = 1 directly.
GlobalV::ofs_running <<
"
Projector index =
"
<< ib+
1
<<
"
, L =
"
<< lnow << std::endl;
for
(
int
ir=
2
; ir<pp.
mesh
-
1
; ++ir)
{
//
p nl
pp.
betar
(ib,ir)=(vl[ir]-pp.
vloc_at
[ir])*wlr[ir];
if
(pp.
r
[ir]<rcut)
{
coef=coef+(vl[ir]-pp.
vloc_at
[ir])*wlr[ir]*wlr[ir]*(pp.
r
[ir+
1
]-pp.
r
[ir-
1
])/
2.0
;
}
}
//
In pw they did this:
//
pp.dion(ib,ib)=1.0/coef;
if
(coef<
0.0
) { pp.
dion
(ib,ib) = -
1.0
;
}
if
(coef>=
0.0
) { pp.
dion
(ib,ib) =
1.0
;
}
//
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
suppose wave function have sqrt(4pi) already
//
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
coef=
1.0
/
sqrt
(
std::abs
(coef));
GlobalV::ofs_running <<
std::setw
(
25
) <<
"
1/sqrt(<phi|deltaV|phi>)
"
<<
std::setw
(
15
) << coef << std::endl;
for
(
int
ir=
0
; ir<pp.
mesh
; ++ir)
{
pp.
betar
(ib,ir) *= coef;
//
--------- FOR TEST ---------
if
(ib>
2
)
{
//
pp.betar(ib,ir) *= 0.0; // for test, disable Non-local
}
//
--------- FOR TEST ---------
}
}
//
print out the projector.
/*
GlobalV::ofs_running << " Nonlocal projector : " << std::endl;
for(int ir=0; ir<mesh; ++ir)
{
if(r[ir]<rcut)
{
GlobalV::ofs_running << " " << std::setw(15) << r[ir];
for(int ib=0; ib<pp.nbeta; ++ib)
{
GlobalV::ofs_running << std::setw(25) << pp.betar(ib,ir);
}
GlobalV::ofs_running << std::endl;
}
}
*/
GlobalV::ofs_running <<
"
-------------------------------------------------
"
<< std::endl;
return
0
;
}
Back
|
FazBrowse Home
|
New Git URL