Skip to content

Commit

Permalink
Merge branch 'materialsproject:master' into beautifulsoup-optional
Browse files Browse the repository at this point in the history
  • Loading branch information
ab5424 authored Apr 19, 2024
2 parents 4a655c4 + 666e1d7 commit cd69def
Show file tree
Hide file tree
Showing 1,519 changed files with 868 additions and 1,494 deletions.
17 changes: 17 additions & 0 deletions .coderabbit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
language: "en-US"
early_access: false
reviews:
request_changes_workflow: false
high_level_summary: false
poem: false
review_status: false
collapse_walkthrough: false
auto_review:
enabled: true
ignore_title_keywords:
- "WIP"
- "DO NOT MERGE"
drafts: false
chat:
auto_reply: true
4 changes: 4 additions & 0 deletions pymatgen/analysis/local_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -3794,6 +3794,10 @@ class CrystalNN(NearNeighbors):
algorithm can also modify probability using smooth distance cutoffs as well as Pauling
electronegativity differences. The output can either be the most probable coordination
environment or a weighted list of coordination environments.
Please note that the default weights have been benchmarked for inorganic crystal structures.
For MOFs or molecular crystals, weights and cutoffs likely will need to be adapted.
A starting point could be:
CrystalNN(x_diff_weight = 1.5, search_cutoff = 4.5)
"""

NNData = namedtuple("NNData", ["all_nninfo", "cn_weights", "cn_nninfo"])
Expand Down
2 changes: 2 additions & 0 deletions pymatgen/io/vasp/inputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,8 @@ def get_str(self, direct: bool = True, vasp4_compatible: bool = False, significa

return "\n".join(lines) + "\n"

get_string = get_str

def __repr__(self):
return self.get_str()

Expand Down
6 changes: 3 additions & 3 deletions pymatgen/phonon/gruneisen.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ def average_gruneisen(
limit_frequencies: Literal["debye", "acoustic"] | None = None,
) -> float:
"""Calculates the average of the Gruneisen based on the values on the regular grid.
If squared is True the average will use the squared value of the Gruneisen and a squared root
If squared is True, the average will use the squared value of the Gruneisen and a squared root
is performed on the final result.
Values associated to negative frequencies will be ignored.
See Scripta Materialia 129, 88 for definitions.
Values associated with negative frequencies will be ignored.
See Nath et al. _Scripta Materialia_ **2017**, _129_, 88 for the definitions.
Adapted from classes in abipy that have been written by Guido Petretto (UCLouvain).
Args:
Expand Down
4 changes: 2 additions & 2 deletions pymatgen/util/testing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
MODULE_DIR = Path(__file__).absolute().parent
STRUCTURES_DIR = MODULE_DIR / ".." / "structures"
TEST_FILES_DIR = Path(SETTINGS.get("PMG_TEST_FILES_DIR", f"{ROOT}/tests/files"))
VASP_IN_DIR = f"{TEST_FILES_DIR}/vasp/inputs"
VASP_OUT_DIR = f"{TEST_FILES_DIR}/vasp/outputs"
VASP_IN_DIR = f"{TEST_FILES_DIR}/io/vasp/inputs"
VASP_OUT_DIR = f"{TEST_FILES_DIR}/io/vasp/outputs"
# fake POTCARs have original header information, meaning properties like number of electrons,
# nuclear charge, core radii, etc. are unchanged (important for testing) while values of the and
# pseudopotential kinetic energy corrections are scrambled to avoid VASP copyright infringement
Expand Down
4 changes: 2 additions & 2 deletions tests/alchemy/test_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def test_as_from_dict(self):

class TestRemoveDuplicatesFilter(TestCase):
def setUp(self):
with open(f"{TEST_FILES_DIR}/TiO2_entries.json") as file:
with open(f"{TEST_FILES_DIR}/entries/TiO2_entries.json") as file:
entries = json.load(file, cls=MontyDecoder)
self._struct_list = [entry.structure for entry in entries]
self._sm = StructureMatcher()
Expand All @@ -91,7 +91,7 @@ def test_as_from_dict(self):

class TestRemoveExistingFilter(TestCase):
def setUp(self):
with open(f"{TEST_FILES_DIR}/TiO2_entries.json") as file:
with open(f"{TEST_FILES_DIR}/entries/TiO2_entries.json") as file:
entries = json.load(file, cls=MontyDecoder)
self._struct_list = [entry.structure for entry in entries]
self._sm = StructureMatcher()
Expand Down
4 changes: 3 additions & 1 deletion tests/alchemy/test_materials.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
from pymatgen.util.provenance import StructureNL
from pymatgen.util.testing import FAKE_POTCAR_DIR, TEST_FILES_DIR, PymatgenTest

TEST_DIR = f"{TEST_FILES_DIR}/alchemy"


class TestTransformedStructure(PymatgenTest):
def setUp(self):
Expand Down Expand Up @@ -61,7 +63,7 @@ def test_final_structure(self):
assert isinstance(deepcopy(self.trans), TransformedStructure)

def test_from_dict(self):
with open(f"{TEST_FILES_DIR}/transformations.json") as file:
with open(f"{TEST_DIR}/transformations.json") as file:
dct = json.load(file)
dct["other_parameters"] = {"tags": ["test"]}
ts = TransformedStructure.from_dict(dct)
Expand Down
2 changes: 1 addition & 1 deletion tests/alchemy/test_transmuters.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
class TestCifTransmuter(PymatgenTest):
def test_init(self):
trafos = [SubstitutionTransformation({"Fe": "Mn", "Fe2+": "Mn2+"})]
tsc = CifTransmuter.from_filenames([f"{TEST_FILES_DIR}/MultiStructure.cif"], trafos)
tsc = CifTransmuter.from_filenames([f"{TEST_FILES_DIR}/cif/MultiStructure.cif"], trafos)
assert len(tsc) == 2
expected = {"Mn", "O", "Li", "P"}
for s in tsc:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,7 @@ def test_real_systems(self):
assert cc.periodicity == "2D"

# Connectivity of Li4Fe3Mn1(PO4)4
struct = Structure.from_file(f"{TEST_FILES_DIR}/Li4Fe3Mn1(PO4)4.cif")
struct = Structure.from_file(f"{TEST_FILES_DIR}/cif/Li4Fe3Mn1(PO4)4.cif")
lgf.setup_structure(structure=struct)
se = lgf.compute_structure_environments(only_atoms=["Li", "Fe", "Mn", "P"], maximum_distance_factor=1.2)
lse = LightStructureEnvironments.from_structure_environments(strategy=strategy, structure_environments=se)
Expand Down Expand Up @@ -837,7 +837,7 @@ def test_real_systems(self):
assert ccs_periodicities == {"0D", "2D"}

def test_coordination_sequences(self):
BaTiO3_se_fpath = f"{TEST_FILES_DIR}/chemenv/structure_environments/se_mp-5020.json"
BaTiO3_se_fpath = f"{TEST_FILES_DIR}/analysis/chemenv/structure_environments/se_mp-5020.json"
with open(BaTiO3_se_fpath) as file:
dct = json.load(file)
struct_envs = StructureEnvironments.from_dict(dct)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

class TestStructureConnectivity(PymatgenTest):
def test_serialization(self):
BaTiO3_se_fpath = f"{TEST_FILES_DIR}/chemenv/structure_environments/se_mp-5020.json"
BaTiO3_se_fpath = f"{TEST_FILES_DIR}/analysis/chemenv/structure_environments/se_mp-5020.json"
with open(BaTiO3_se_fpath) as file:
dd = json.load(file)
struct_envs = StructureEnvironments.from_dict(dd)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

__author__ = "waroquiers"

json_dir = f"{TEST_FILES_DIR}/chemenv/json"
json_dir = f"{TEST_FILES_DIR}/analysis/chemenv/json"


class TestCoordinationGeometryFinder(PymatgenTest):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@

__author__ = "waroquiers"

json_dir = f"{TEST_FILES_DIR}/chemenv/json"
struct_env_dir = f"{TEST_FILES_DIR}/chemenv/structure_environments"
json_dir = f"{TEST_FILES_DIR}/analysis/chemenv/json"
struct_env_dir = f"{TEST_FILES_DIR}/analysis/chemenv/structure_environments"


class TestReadWriteChemenv(PymatgenTest):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@

__author__ = "waroquiers"

struct_env_dir = f"{TEST_FILES_DIR}/chemenv/structure_environments"
TEST_DIR = f"{TEST_FILES_DIR}/analysis/chemenv/structure_environments"


class TestStructureEnvironments(PymatgenTest):
def test_structure_environments(self):
with open(f"{struct_env_dir}/se_mp-7000.json") as file:
with open(f"{TEST_DIR}/se_mp-7000.json") as file:
dct = json.load(file)

struct_envs = StructureEnvironments.from_dict(dct)
Expand Down Expand Up @@ -119,7 +119,7 @@ def test_structure_environments(self):
assert ce != ce2

def test_light_structure_environments(self):
with open(f"{struct_env_dir}/se_mp-7000.json") as file:
with open(f"{TEST_DIR}/se_mp-7000.json") as file:
dct = json.load(file)

struct_envs = StructureEnvironments.from_dict(dct)
Expand Down Expand Up @@ -220,8 +220,7 @@ def test_light_structure_environments(self):

def test_from_structure_environments(self):
# https://github.com/materialsproject/pymatgen/issues/2756
mp_id = "mp-554015"
struct = Structure.from_file(f"{TEST_FILES_DIR}/{mp_id}.json.gz")
struct = Structure.from_file(f"{TEST_DIR}/mp-554015.json.gz")
strategy = SimplestChemenvStrategy(distance_cutoff=1.4, angle_cutoff=0.3)
local_geom_finder = LocalGeometryFinder()
local_geom_finder.setup_structure(structure=struct)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

__author__ = "waroquiers"

img_files_dir = f"{TEST_FILES_DIR}/chemenv/images"
img_files_dir = f"{TEST_FILES_DIR}/analysis/chemenv/images"


class TestVoronoiContainer(PymatgenTest):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

__author__ = "waroquiers"

struct_env_dir = f"{TEST_FILES_DIR}/chemenv/structure_environments"
struct_env_dir = f"{TEST_FILES_DIR}/analysis/chemenv/structure_environments"


class FakeNbSet:
Expand Down
2 changes: 1 addition & 1 deletion tests/analysis/chemenv/utils/test_chemenv_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

__author__ = "waroquiers"

config_file_dir = f"{TEST_FILES_DIR}/chemenv/config"
config_file_dir = f"{TEST_FILES_DIR}/analysis/chemenv/config"


class TestChemenvConfig(PymatgenTest):
Expand Down
12 changes: 7 additions & 5 deletions tests/analysis/elasticity/test_elastic.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
from pymatgen.core.units import FloatWithUnit
from pymatgen.util.testing import TEST_FILES_DIR, PymatgenTest

TEST_DIR = f"{TEST_FILES_DIR}/analysis/elasticity"


class TestElasticTensor(PymatgenTest):
def setUp(self):
Expand Down Expand Up @@ -65,10 +67,10 @@ def setUp(self):
)

self.elastic_tensor_1 = ElasticTensor(self.ft)
filepath = f"{TEST_FILES_DIR}/Sn_def_stress.json"
filepath = f"{TEST_DIR}/Sn_def_stress.json"
with open(filepath) as file:
self.def_stress_dict = json.load(file)
with open(f"{TEST_FILES_DIR}/test_toec_data.json") as file:
with open(f"{TEST_DIR}/test_toec_data.json") as file:
self.toec_dict = json.load(file)
self.structure = self.get_structure("Sn")

Expand Down Expand Up @@ -256,7 +258,7 @@ def test_energy_density(self):

class TestElasticTensorExpansion(PymatgenTest):
def setUp(self):
with open(f"{TEST_FILES_DIR}/test_toec_data.json") as file:
with open(f"{TEST_DIR}/test_toec_data.json") as file:
self.data_dict = json.load(file)
self.strains = [Strain(sm) for sm in self.data_dict["strains"]]
self.pk_stresses = [Stress(d) for d in self.data_dict["pk_stresses"]]
Expand Down Expand Up @@ -357,7 +359,7 @@ def test_get_yield_stress(self):

class TestNthOrderElasticTensor(PymatgenTest):
def setUp(self):
with open(f"{TEST_FILES_DIR}/test_toec_data.json") as file:
with open(f"{TEST_DIR}/test_toec_data.json") as file:
self.data_dict = json.load(file)
self.strains = [Strain(sm) for sm in self.data_dict["strains"]]
self.pk_stresses = [Stress(d) for d in self.data_dict["pk_stresses"]]
Expand Down Expand Up @@ -396,7 +398,7 @@ class TestDiffFit(PymatgenTest):
"""Tests various functions related to diff fitting."""

def setUp(self):
with open(f"{TEST_FILES_DIR}/test_toec_data.json") as file:
with open(f"{TEST_DIR}/test_toec_data.json") as file:
self.data_dict = json.load(file)
self.strains = [Strain(sm) for sm in self.data_dict["strains"]]
self.pk_stresses = [Stress(d) for d in self.data_dict["pk_stresses"]]
Expand Down
2 changes: 1 addition & 1 deletion tests/analysis/ferroelectricity/test_polarization.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from pymatgen.io.vasp.outputs import Outcar
from pymatgen.util.testing import TEST_FILES_DIR, PymatgenTest

TEST_DIR = f"{TEST_FILES_DIR}/vasp/fixtures/BTO_221_99_polarization"
TEST_DIR = f"{TEST_FILES_DIR}/io/vasp/fixtures/BTO_221_99_polarization"
bto_folders = ["nonpolar_polarization"]
bto_folders += [f"interpolation_{idx}_polarization" for idx in range(8, 0, -1)]
bto_folders += ["polar_polarization"]
Expand Down
26 changes: 15 additions & 11 deletions tests/analysis/magnetism/test_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,30 @@
from pymatgen.core import Element, Lattice, Species, Structure
from pymatgen.util.testing import TEST_FILES_DIR

TEST_DIR = f"{TEST_FILES_DIR}/analysis/magnetic_orderings"

enum_cmd = which("enum.x") or which("multienum.x")
makestr_cmd = which("makestr.x") or which("makeStr.x") or which("makeStr.py")
enumlib_present = enum_cmd and makestr_cmd


class TestCollinearMagneticStructureAnalyzer(TestCase):
def setUp(self):
self.Fe = Structure.from_file(f"{TEST_FILES_DIR}/Fe.cif", primitive=True)
self.Fe = Structure.from_file(f"{TEST_FILES_DIR}/cif/Fe.cif", primitive=True)

self.LiFePO4 = Structure.from_file(f"{TEST_FILES_DIR}/LiFePO4.cif", primitive=True)
self.LiFePO4 = Structure.from_file(f"{TEST_FILES_DIR}/cif/LiFePO4.cif", primitive=True)

self.Fe3O4 = Structure.from_file(f"{TEST_FILES_DIR}/Fe3O4.cif", primitive=True)
self.Fe3O4 = Structure.from_file(f"{TEST_FILES_DIR}/cif/Fe3O4.cif", primitive=True)

self.GdB4 = Structure.from_file(f"{TEST_FILES_DIR}/mcif/magnetic.ncl.example.GdB4.mcif", primitive=True)
self.GdB4 = Structure.from_file(f"{TEST_FILES_DIR}/io/cif/mcif/magnetic.ncl.example.GdB4.mcif", primitive=True)

self.NiO_expt = Structure.from_file(f"{TEST_FILES_DIR}/mcif/magnetic.example.NiO.mcif", primitive=True)
self.NiO_expt = Structure.from_file(f"{TEST_FILES_DIR}/io/cif/mcif/magnetic.example.NiO.mcif", primitive=True)

# CuO.mcif sourced from https://www.cryst.ehu.es/magndata/index.php?index=1.62
# doi: 10.1088/0022-3719/21/15/023
self.CuO_expt = Structure.from_file(f"{TEST_FILES_DIR}/mcif/magnetic.example.CuO.mcif.gz", primitive=True)
self.CuO_expt = Structure.from_file(
f"{TEST_FILES_DIR}/io/cif/mcif/magnetic.example.CuO.mcif.gz", primitive=True
)

lattice = Lattice.cubic(4.17)
species = ["Ni", "O"]
Expand Down Expand Up @@ -251,17 +255,17 @@ class TestMagneticStructureEnumerator:
@pytest.mark.skipif(not enumlib_present, reason="enumlib not present")
def test_ordering_enumeration(self):
# simple afm
structure = Structure.from_file(f"{TEST_FILES_DIR}/magnetic_orderings/LaMnO3.json")
structure = Structure.from_file(f"{TEST_DIR}/LaMnO3.json")
enumerator = MagneticStructureEnumerator(structure)
assert enumerator.input_origin == "afm"

# ferrimagnetic (Cr produces net spin)
structure = Structure.from_file(f"{TEST_FILES_DIR}/magnetic_orderings/Cr2NiO4.json")
structure = Structure.from_file(f"{TEST_DIR}/Cr2NiO4.json")
enumerator = MagneticStructureEnumerator(structure)
assert enumerator.input_origin == "ferri_by_Cr"

# antiferromagnetic on single magnetic site
structure = Structure.from_file(f"{TEST_FILES_DIR}/magnetic_orderings/Cr2WO6.json")
structure = Structure.from_file(f"{TEST_DIR}/Cr2WO6.json")
enumerator = MagneticStructureEnumerator(structure)
assert enumerator.input_origin == "afm_by_Cr"

Expand All @@ -275,7 +279,7 @@ def test_ordering_enumeration(self):
# assert enumerator.input_origin == "afm"

# antiferromagnetic by structural motif
structure = Structure.from_file(f"{TEST_FILES_DIR}/magnetic_orderings/Ca3Co2O6.json")
structure = Structure.from_file(f"{TEST_DIR}/Ca3Co2O6.json")
enumerator = MagneticStructureEnumerator(
structure,
strategies=("antiferromagnetic_by_motif",),
Expand All @@ -288,7 +292,7 @@ def test_ordering_enumeration(self):

class TestMagneticDeformation:
def test_magnetic_deformation(self):
test_structs = loadfn(f"{TEST_FILES_DIR}/magnetic_deformation.json")
test_structs = loadfn(f"{TEST_FILES_DIR}/analysis/magnetism/magnetic_deformation.json")
mag_def = magnetic_deformation(test_structs[0], test_structs[1])

assert mag_def.type == "NM-FM"
Expand Down
2 changes: 1 addition & 1 deletion tests/analysis/magnetism/test_heisenberg.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from pymatgen.core.structure import Structure
from pymatgen.util.testing import TEST_FILES_DIR

TEST_DIR = f"{TEST_FILES_DIR}/magnetic_orderings"
TEST_DIR = f"{TEST_FILES_DIR}/analysis/magnetic_orderings"


class TestHeisenbergMapper(TestCase):
Expand Down
4 changes: 2 additions & 2 deletions tests/analysis/magnetism/test_jahnteller.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ def test_jahn_teller_species_analysis(self):
assert magnitude == "none"

def test_jahn_teller_structure_analysis(self):
LiFePO4 = Structure.from_file(f"{TEST_FILES_DIR}/LiFePO4.cif", primitive=True)
LiFePO4 = Structure.from_file(f"{TEST_FILES_DIR}/cif/LiFePO4.cif", primitive=True)

Fe3O4 = Structure.from_file(f"{TEST_FILES_DIR}/Fe3O4.cif", primitive=True)
Fe3O4 = Structure.from_file(f"{TEST_FILES_DIR}/cif/Fe3O4.cif", primitive=True)

assert self.jt.is_jahn_teller_active(LiFePO4)
assert self.jt.is_jahn_teller_active(Fe3O4)
Expand Down
8 changes: 4 additions & 4 deletions tests/analysis/solar/test_slme.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
from __future__ import annotations

import os

from pytest import approx

from pymatgen.analysis.solar.slme import optics, slme
from pymatgen.util.testing import PymatgenTest
from pymatgen.util.testing import TEST_FILES_DIR, PymatgenTest

TEST_DIR = f"{TEST_FILES_DIR}/analysis/solar"


class TestSolar(PymatgenTest):
def test_slme_from_vasprun(self):
en, abz, dir_gap, indir_gap = optics(f"{os.path.dirname(__file__)}/vasprun.xml")
en, abz, dir_gap, indir_gap = optics(f"{TEST_DIR}/vasprun.xml")
abz = abz * 100.0
eff = slme(en, abz, indir_gap, indir_gap, plot_current_voltage=False)
assert eff == approx(27.729, abs=1e-2)
Expand Down
Loading

0 comments on commit cd69def

Please sign in to comment.