Skip to content

Commit ead9d47

Browse files
authored
Patch locpot (#182)
* sc locpot * ccd bug * volumetric data
1 parent 045346b commit ead9d47

File tree

4 files changed

+23
-9
lines changed

4 files changed

+23
-9
lines changed

pymatgen/analysis/defects/core.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,12 @@ def get_charge_states(self, padding: int = 1) -> list[int]:
164164
if isinstance(self.oxi_state, int) or self.oxi_state.is_integer():
165165
oxi_state = int(self.oxi_state)
166166
else: # pragma: no cover
167-
raise ValueError("Oxidation state must be an integer")
167+
sign = -1 if self.oxi_state < 0 else 1
168+
oxi_state = sign * int(np.ceil(abs(self.oxi_state)))
169+
_logger.warn(
170+
"Non-integer oxidation state detected."
171+
f"Rounding to integer with larger absolute value: {self.oxi_state} -> {oxi_state}"
172+
)
168173

169174
if oxi_state >= 0:
170175
charges = [*range(-padding, oxi_state + padding + 1)]

pymatgen/analysis/defects/corrections/freysoldt.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
generate_reciprocal_vectors_squared,
1919
hart_to_ev,
2020
)
21-
from pymatgen.io.vasp.outputs import Locpot
21+
from pymatgen.io.vasp.outputs import Locpot, VolumetricData
2222
from scipy import stats
2323

2424
if TYPE_CHECKING:
@@ -104,7 +104,7 @@ def get_freysoldt_correction(
104104

105105
q_model = QModel() if q_model is None else q_model
106106

107-
if isinstance(defect_locpot, Locpot):
107+
if isinstance(defect_locpot, VolumetricData):
108108
list_axis_grid = [*map(defect_locpot.get_axis_grid, [0, 1, 2])]
109109
list_defect_plnr_avg_esp = [
110110
*map(defect_locpot.get_average_along_axis, [0, 1, 2])
@@ -130,7 +130,7 @@ def get_freysoldt_correction(
130130
raise ValueError("defect_locpot must be of type Locpot or dict")
131131

132132
# TODO this can be done with regridding later
133-
if isinstance(bulk_locpot, Locpot):
133+
if isinstance(bulk_locpot, VolumetricData):
134134
list_bulk_plnr_avg_esp = [*map(bulk_locpot.get_average_along_axis, [0, 1, 2])]
135135
elif isinstance(bulk_locpot, dict):
136136
bulk_locpot_ = {int(k): v for k, v in bulk_locpot.items()}

pymatgen/analysis/defects/supercells.py

+11-2
Original file line numberDiff line numberDiff line change
@@ -161,11 +161,15 @@ def _cubic_cell(
161161
try:
162162
cst.apply_transformation(base_struct)
163163
except BaseException:
164-
return _ase_cubic(base_struct, min_atoms, max_atoms)
164+
return _ase_cubic(
165+
base_struct, min_atoms=min_atoms, max_atoms=max_atoms, min_length=min_length
166+
)
165167
return cst.transformation_matrix
166168

167169

168-
def _ase_cubic(base_structure, min_atoms: int = 80, max_atoms: int = 240):
170+
def _ase_cubic(
171+
base_structure, min_atoms: int = 80, max_atoms: int = 240, min_length=10.0
172+
):
169173
"""Generate the best supercell from a unit cell.
170174
171175
Use ASE's find_optimal_cell_shape function to find the best supercell.
@@ -174,6 +178,7 @@ def _ase_cubic(base_structure, min_atoms: int = 80, max_atoms: int = 240):
174178
base_structure: structure of the unit cell
175179
max_atoms: Maximum number of atoms allowed in the supercell.
176180
min_atoms: Minimum number of atoms allowed in the supercell.
181+
min_length: Minimum length of the smallest supercell lattice vector.
177182
178183
Returns:
179184
3x3 matrix: supercell matrix
@@ -194,6 +199,10 @@ def _ase_cubic(base_structure, min_atoms: int = 80, max_atoms: int = 240):
194199
ase_atoms.cell, target_size=size, target_shape="sc"
195200
)
196201
sc_cell = aaa.get_atoms(base_structure * sc).cell
202+
lattice_lens = np.linalg.norm(sc_cell, axis=1)
203+
_logger.warn(f"{lattice_lens}, {min_length}, {min_dev}")
204+
if min(lattice_lens) < min_length:
205+
continue
197206
deviation = get_deviation_from_optimal_cell_shape(sc_cell, target_shape="sc")
198207
min_dev = min(min_dev, (deviation, sc))
199208
if min_dev[1] is None:

pymatgen/analysis/defects/thermo.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from pymatgen.core import Composition, Element
2424
from pymatgen.electronic_structure.dos import FermiDos
2525
from pymatgen.entries.computed_entries import ComputedEntry
26-
from pymatgen.io.vasp import Locpot, Vasprun
26+
from pymatgen.io.vasp import Chgcar, Locpot, Vasprun, VolumetricData
2727
from pyrho.charge_density import get_volumetric_like_sc
2828
from scipy.constants import value as _cd
2929
from scipy.optimize import bisect
@@ -148,12 +148,12 @@ def get_freysoldt_correction(
148148
else: # pragma: no cover
149149
defect_fpos = self.sc_defect_frac_coords
150150

151-
if isinstance(defect_locpot, Locpot):
151+
if isinstance(defect_locpot, VolumetricData):
152152
defect_gn = defect_locpot.dim
153153
elif isinstance(defect_locpot, dict):
154154
defect_gn = tuple(map(len, (defect_locpot for k in ["0", "1", "2"])))
155155

156-
if isinstance(bulk_locpot, Locpot):
156+
if isinstance(bulk_locpot, VolumetricData):
157157
bulk_sc_locpot = get_sc_locpot(
158158
uc_locpot=bulk_locpot,
159159
defect_struct=defect_struct,

0 commit comments

Comments
 (0)