-
Notifications
You must be signed in to change notification settings - Fork 93
/
anaddbnc.py
195 lines (162 loc) · 6.56 KB
/
anaddbnc.py
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
# coding: utf-8
"""
AnaddbNcFile provides a high-level interface to the data stored in the anaddb.nc file.
"""
from __future__ import print_function, division, unicode_literals, absolute_import
from monty.functools import lazy_property
from monty.string import marquee
from monty.termcolor import cprint
from abipy.core.tensor import Tensor
from abipy.core.mixins import AbinitNcFile, Has_Structure, NotebookWriter
from abipy.iotools import ETSF_Reader
from abipy.dfpt.phonons import InteratomicForceConstants
from abipy.dfpt.ddb import Becs
from abipy.dfpt.tensors import NLOpticalSusceptibilityTensor
class AnaddbNcFile(AbinitNcFile, Has_Structure, NotebookWriter):
"""
AnaddbNcFile provides a high-level interface to the data stored in the anaddb.nc file.
This object is usually instanciated with `abiopen("anaddb.nc")`.
.. attribute:: structure
|Structure| object.
.. attribute:: emacro
Macroscopic dielectric tensor. None if the file does not contain this information.
.. attribute:: becs
Born effective charges. None if the file does not contain this inf
.. attribute:: ifc
:class:`InteratomicForceConstants` object with the interatomic force constants calculated by anaddb.
None, if the netcdf file does not contain the IFCs.
.. rubric:: Inheritance Diagram
.. inheritance-diagram:: AnaddbNcFile
"""
@classmethod
def from_file(cls, filepath):
"""Initialize the object from file."""
return cls(filepath)
def __init__(self, filepath):
super(AnaddbNcFile, self).__init__(filepath)
self.reader = ETSF_Reader(filepath)
self._structure = self.reader.read_structure()
def close(self):
self.reader.close()
@lazy_property
def params(self):
return {}
def __str__(self):
return self.to_string()
def to_string(self, verbose=0):
"""
String representation
Args:
verbose: verbosity level.
"""
lines = []; app = lines.append
app(marquee("File Info", mark="="))
app(self.filestat(as_string=True))
app("")
app(self.structure.to_string(verbose=verbose, title="Structure"))
return "\n".join(lines)
@property
def structure(self):
return self._structure
@lazy_property
def emacro(self):
"""
Macroscopic dielectric tensor. None if the file does not contain this information.
"""
try:
return Tensor.from_cartesian_tensor(self.reader.read_value("emacro_cart"),
self.structure.lattice, space="r")
except Exception as exc:
print(exc, "Returning None", sep="\n")
return None
@lazy_property
def emacro_rlx(self):
"""
Relaxed ion Macroscopic dielectric tensor. None if the file does not contain this information.
"""
try:
return Tensor.from_cartesian_tensor(self.reader.read_value("emacro_cart_rlx"),
self.structure.lattice, space="r")
except Exception as exc:
print(exc, "Requires dieflag > 0", "Returning None", sep="\n")
return None
@lazy_property
def becs(self):
"""
Born effective charges. None if the file does not contain this information.
"""
try:
chneut = -666 # TODO: anaddb.nc should contain the input file.
return Becs(self.reader.read_value("becs_cart"), self.structure, chneut=chneut, order="f")
except Exception as exc:
print(exc, "Returning None", sep="\n")
return None
@lazy_property
def ifc(self):
"""
The interatomic force constants calculated by anaddb.
The following anaddb variables should be used in the run: ``ifcflag``, ``natifc``, ``atifc``, ``ifcout``.
Return None, if the netcdf_ file does not contain the IFCs,
"""
try:
return InteratomicForceConstants.from_file(self.filepath)
except Exception as exc:
print(exc)
cprint("Interatomic force constants have not been calculated. Returning None", "red")
return None
@lazy_property
def dchide(self):
"""
Non-linear optical susceptibility tensor.
Returns a :class:`NLOpticalSusceptibilityTensor` or None if the file does not contain this information.
"""
try:
return NLOpticalSusceptibilityTensor(self.reader.read_value("dchide"))
except Exception as exc:
print(exc, "Requires nlflag > 0", "Returning None", sep="\n")
return None
@lazy_property
def dchidt(self):
"""
First-order change in the linear dielectric susceptibility.
Returns a list of lists of 3x3 Tensor object with shape (number of atoms, 3).
The [i][j] element of the list contains the Tensor representing the change due to the
displacement of the ith atom in the jth direction.
None if the file does not contain this information.
"""
try:
a = self.reader.read_value("dchidt").T
dchidt = []
for i in a:
d = []
for j in i:
d.append(Tensor.from_cartesian_tensor(j, self.structure.lattice, space="r"))
dchidt.append(d)
return dchidt
except Exception as exc:
print(exc, "Requires 0 < nlflag < 3", "Returning None", sep="\n")
return None
@lazy_property
def oscillator_strength(self):
"""
A complex |numpy-array| containing the oscillator strengths with shape (number of phonon modes, 3, 3),
in a.u. (1 a.u.=253.2638413 m3/s2).
None if the file does not contain this information.
"""
try:
return self.reader.read_value("oscillator_strength", cmode="c")
except Exception as exc:
print(exc, "Oscillator strengths require dieflag == 1, 3 or 4", "Returning None", sep="\n")
raise
return None
def write_notebook(self, nbpath=None):
"""
Write an jupyter_ notebook to nbpath. If ``nbpath`` is None, a temporay file in the current
working directory is created. Return path to the notebook.
"""
nbformat, nbv, nb = self.get_nbformat_nbv_nb(title=None)
nb.cells.extend([
nbv.new_code_cell("ananc = abilab.abiopen('%s')" % self.filepath),
nbv.new_code_cell("print(ananc)"),
])
return self._write_nb_nbpath(nb, nbpath)