diff --git a/src/pymatgen/alchemy/filters.py b/src/pymatgen/alchemy/filters.py index eef85beec54..6cadf8211f1 100644 --- a/src/pymatgen/alchemy/filters.py +++ b/src/pymatgen/alchemy/filters.py @@ -3,6 +3,7 @@ from __future__ import annotations import abc +import math from collections import defaultdict from typing import TYPE_CHECKING @@ -285,7 +286,7 @@ def __init__(self): def test(self, structure: Structure): """True if structure is neutral.""" - return structure.charge == 0.0 + return math.isclose(structure.charge, 0.0) class SpeciesMaxDistFilter(AbstractStructureFilter): diff --git a/src/pymatgen/core/bonds.py b/src/pymatgen/core/bonds.py index 6c1ced8fa47..21cefa59f35 100644 --- a/src/pymatgen/core/bonds.py +++ b/src/pymatgen/core/bonds.py @@ -134,7 +134,10 @@ def obtain_all_bond_lengths( If None, a ValueError will be thrown. Returns: - A dict mapping bond order to bond length in angstrom + dict[float, float]: mapping bond order to bond length in Angstrom. + + Todo: + it's better to avoid using float as dict keys. """ if isinstance(sp1, Element): sp1 = sp1.symbol diff --git a/src/pymatgen/electronic_structure/plotter.py b/src/pymatgen/electronic_structure/plotter.py index 1443694d386..45d8398440c 100644 --- a/src/pymatgen/electronic_structure/plotter.py +++ b/src/pymatgen/electronic_structure/plotter.py @@ -1245,7 +1245,7 @@ def get_elt_projected_plots_color( proj[b][str(spin)][band_idx][j][str(el)][o] for o in proj[b][str(spin)][band_idx][j][str(el)] ) - if sum_e == 0.0: + if math.isclose(sum_e, 0.0): color = [0.0] * len(elt_ordered) else: color = [ diff --git a/src/pymatgen/io/aims/inputs.py b/src/pymatgen/io/aims/inputs.py index 9b7ff838bc3..adf14144798 100644 --- a/src/pymatgen/io/aims/inputs.py +++ b/src/pymatgen/io/aims/inputs.py @@ -560,7 +560,7 @@ def get_content( magmom = structure.site_properties.get("magmom", spins) if ( parameters.get("spin", "") == "collinear" - and np.all(magmom == 0.0) + and np.allclose(magmom, 0.0) and ("default_initial_moment" not in parameters) ): warn( diff --git a/src/pymatgen/io/cp2k/outputs.py b/src/pymatgen/io/cp2k/outputs.py index ee01c1db302..d9b879e4cb8 100644 --- a/src/pymatgen/io/cp2k/outputs.py +++ b/src/pymatgen/io/cp2k/outputs.py @@ -1317,10 +1317,16 @@ def parse_bandstructure(self, bandstructure_filename=None) -> None: else: eigenvals = {Spin.up: bands_data.reshape((nbands, nkpts))} - occ = bands_data[:, 1][bands_data[:, -1] != 0.0] + # Filter out occupied and unoccupied states + occupied_mask = ~np.isclose(bands_data[:, -1], 0.0) + unoccupied_mask = np.isclose(bands_data[:, -1], 0.0) + + occ = bands_data[:, 1][occupied_mask] homo = np.max(occ) - unocc = bands_data[:, 1][bands_data[:, -1] == 0.0] + + unocc = bands_data[:, 1][unoccupied_mask] lumo = np.min(unocc) + efermi = (lumo + homo) / 2 self.efermi = efermi diff --git a/src/pymatgen/io/vasp/outputs.py b/src/pymatgen/io/vasp/outputs.py index 14b116ffcbf..5c5f2c6260f 100644 --- a/src/pymatgen/io/vasp/outputs.py +++ b/src/pymatgen/io/vasp/outputs.py @@ -778,13 +778,13 @@ def run_type(self) -> str: 4: "dDsC", } - if self.parameters.get("AEXX", 1.00) == 1.00: + if math.isclose(self.parameters.get("AEXX", 1.00), 1.00): run_type = "HF" - elif self.parameters.get("HFSCREEN", 0.30) == 0.30: + elif math.isclose(self.parameters.get("HFSCREEN", 0.30), 0.30): run_type = "HSE03" - elif self.parameters.get("HFSCREEN", 0.20) == 0.20: + elif math.isclose(self.parameters.get("HFSCREEN", 0.20), 0.20): run_type = "HSE06" - elif self.parameters.get("AEXX", 0.20) == 0.20: + elif math.isclose(self.parameters.get("AEXX", 0.20), 0.20): run_type = "B3LYP" elif self.parameters.get("LHFCALC", True): run_type = "PBEO or other Hybrid Functional" @@ -1020,7 +1020,7 @@ def get_band_structure( if (hybrid_band or force_hybrid_mode) and not use_kpoints_opt: start_bs_index = 0 for i in range(len(self.actual_kpoints)): - if self.actual_kpoints_weights[i] == 0.0: + if math.isclose(self.actual_kpoints_weights[i], 0.0): start_bs_index = i break for i in range(start_bs_index, len(kpoint_file.kpts)): @@ -5273,8 +5273,11 @@ def get_parchg( Returns: A Chgcar object. """ - if phase and not np.all(self.kpoints[kpoint] == 0.0): - warnings.warn("phase is True should only be used for the Gamma kpoint! I hope you know what you're doing!") + if phase and not np.allclose(self.kpoints[kpoint], 0.0): + warnings.warn( + "phase is True should only be used for the Gamma kpoint! I hope you know what you're doing!", + stacklevel=2, + ) # Scaling of ng for the fft grid, need to restore value at the end temp_ng = self.ng diff --git a/src/pymatgen/transformations/advanced_transformations.py b/src/pymatgen/transformations/advanced_transformations.py index 2537241b653..8e4bbc248f2 100644 --- a/src/pymatgen/transformations/advanced_transformations.py +++ b/src/pymatgen/transformations/advanced_transformations.py @@ -48,6 +48,8 @@ from collections.abc import Callable, Iterable, Sequence from typing import Any, Literal + from numpy.typing import NDArray + __author__ = "Shyue Ping Ong, Stephen Dacek, Anubhav Jain, Matthew Horton, Alex Ganose" @@ -67,6 +69,9 @@ def __init__(self, charge_balance_sp): """ self.charge_balance_sp = str(charge_balance_sp) + def __repr__(self): + return f"Charge Balance Transformation : Species to remove = {self.charge_balance_sp}" + def apply_transformation(self, structure: Structure): """Apply the transformation. @@ -86,9 +91,6 @@ def apply_transformation(self, structure: Structure): trans = SubstitutionTransformation({self.charge_balance_sp: {self.charge_balance_sp: 1 - removal_fraction}}) return trans.apply_transformation(structure) - def __repr__(self): - return f"Charge Balance Transformation : Species to remove = {self.charge_balance_sp}" - class SuperTransformation(AbstractTransformation): """This is a transformation that is inherently one-to-many. It is constructed @@ -110,6 +112,9 @@ def __init__(self, transformations, nstructures_per_trans=1): self._transformations = transformations self.nstructures_per_trans = nstructures_per_trans + def __repr__(self): + return f"Super Transformation : Transformations = {' '.join(map(str, self._transformations))}" + def apply_transformation(self, structure: Structure, return_ranked_list: bool | int = False): """Apply the transformation. @@ -139,11 +144,8 @@ def apply_transformation(self, structure: Structure, return_ranked_list: bool | ) return structures - def __repr__(self): - return f"Super Transformation : Transformations = {' '.join(map(str, self._transformations))}" - @property - def is_one_to_many(self) -> bool: + def is_one_to_many(self) -> Literal[True]: """Transform one structure to many.""" return True @@ -191,6 +193,9 @@ def __init__( self.charge_balance_species = charge_balance_species self.order = order + def __repr__(self): + return f"Multiple Substitution Transformation : Substitution on {self.sp_to_replace}" + def apply_transformation(self, structure: Structure, return_ranked_list: bool | int = False): """Apply the transformation. @@ -234,11 +239,8 @@ def apply_transformation(self, structure: Structure, return_ranked_list: bool | outputs.append({"structure": new_structure}) return outputs - def __repr__(self): - return f"Multiple Substitution Transformation : Substitution on {self.sp_to_replace}" - @property - def is_one_to_many(self) -> bool: + def is_one_to_many(self) -> Literal[True]: """Transform one structure to many.""" return True @@ -323,6 +325,9 @@ def __init__( if max_cell_size and max_disordered_sites: raise ValueError("Cannot set both max_cell_size and max_disordered_sites!") + def __repr__(self): + return "EnumerateStructureTransformation" + def apply_transformation( self, structure: Structure, return_ranked_list: bool | int = False ) -> Structure | list[dict]: @@ -468,11 +473,8 @@ def sort_func(struct): return self._all_structures[:num_to_return] return self._all_structures[0]["structure"] - def __repr__(self): - return "EnumerateStructureTransformation" - @property - def is_one_to_many(self) -> bool: + def is_one_to_many(self) -> Literal[True]: """Transform one structure to many.""" return True @@ -494,6 +496,9 @@ def __init__(self, threshold=1e-2, scale_volumes=True, **kwargs): self.scale_volumes = scale_volumes self._substitutor = SubstitutionPredictor(threshold=threshold, **kwargs) + def __repr__(self): + return "SubstitutionPredictorTransformation" + def apply_transformation(self, structure: Structure, return_ranked_list: bool | int = False): """Apply the transformation. @@ -528,11 +533,8 @@ def apply_transformation(self, structure: Structure, return_ranked_list: bool | outputs.append(output) return outputs - def __repr__(self): - return "SubstitutionPredictorTransformation" - @property - def is_one_to_many(self) -> bool: + def is_one_to_many(self) -> Literal[True]: """Transform one structure to many.""" return True @@ -893,7 +895,7 @@ def key(struct: Structure) -> int: return self._all_structures[:num_to_return] # type: ignore[return-value] @property - def is_one_to_many(self) -> bool: + def is_one_to_many(self) -> Literal[True]: """Transform one structure to many.""" return True @@ -982,15 +984,19 @@ def __init__( self.allowed_doping_species = allowed_doping_species self.kwargs = kwargs - def apply_transformation(self, structure: Structure, return_ranked_list: bool | int = False): + def apply_transformation( + self, + structure: Structure, + return_ranked_list: bool | int = False, + ) -> list[dict[Literal["structure", "energy"], Structure | float]] | Structure: """ Args: - structure (Structure): Input structure to dope - return_ranked_list (bool | int, optional): If return_ranked_list is int, that number of structures. - is returned. If False, only the single lowest energy structure is returned. Defaults to False. + structure (Structure): Input structure to dope. + return_ranked_list (bool | int, optional): If is int, that number of structures is returned. + If False, only the single lowest energy structure is returned. Defaults to False. Returns: - list[dict] | Structure: each dict has shape {"structure": Structure, "energy": float}. + list[dict] | Structure: each dict as {"structure": Structure, "energy": float}. """ comp = structure.composition logger.info(f"Composition: {comp}") @@ -1123,7 +1129,7 @@ def apply_transformation(self, structure: Structure, return_ranked_list: bool | return all_structures[0]["structure"] @property - def is_one_to_many(self) -> bool: + def is_one_to_many(self) -> Literal[True]: """Transform one structure to many.""" return True @@ -1251,7 +1257,7 @@ def apply_transformation(self, structure: Structure, return_ranked_list: bool | return disordered_structures @property - def is_one_to_many(self) -> bool: + def is_one_to_many(self) -> Literal[True]: """Transform one structure to many.""" return True @@ -1712,7 +1718,7 @@ def apply_transformation(self, structure: Structure, return_ranked_list: bool | return [{"structure": structure} for structure in structures[:return_ranked_list]] @property - def is_one_to_many(self) -> bool: + def is_one_to_many(self) -> Literal[True]: """Transform one structure to many.""" return True @@ -1866,16 +1872,25 @@ def apply_transformation( return [{"structure": structure} for structure in structures[:return_ranked_list]] @property - def is_one_to_many(self) -> bool: + def is_one_to_many(self) -> Literal[True]: """Transform one structure to many.""" return True -def _proj(b, a): - """Get vector projection (np.ndarray) of vector b (np.ndarray) - onto vector a (np.ndarray). +def _proj(b: NDArray, a: NDArray) -> NDArray: + """Get vector projection of vector b onto vector a. + + Args: + b (NDArray): Vector to be projected. + a (NDArray): Vector onto which `b` is projected. + + Returns: + NDArray: Projection of `b` onto `a`. """ - return (b.T @ (a / np.linalg.norm(a))) * (a / np.linalg.norm(a)) + a = np.asarray(a) + b = np.asarray(b) + + return (np.dot(b, a) / np.dot(a, a)) * a class SQSTransformation(AbstractTransformation): @@ -2144,7 +2159,7 @@ def _get_unique_best_sqs_structs(sqs, best_only, return_ranked_list, remove_dupl return to_return @property - def is_one_to_many(self) -> bool: + def is_one_to_many(self) -> Literal[True]: """Transform one structure to many.""" return True @@ -2193,6 +2208,9 @@ def __init__(self, rattle_std: float, min_distance: float, seed: int | None = No self.random_state = np.random.RandomState(seed) self.kwargs = kwargs + def __repr__(self): + return f"{__name__} : rattle_std = {self.rattle_std}" + def apply_transformation(self, structure: Structure) -> Structure: """Apply the transformation. @@ -2214,6 +2232,3 @@ def apply_transformation(self, structure: Structure) -> Structure: structure.cart_coords + displacements, coords_are_cartesian=True, ) - - def __repr__(self): - return f"{__name__} : rattle_std = {self.rattle_std}" diff --git a/src/pymatgen/transformations/transformation_abc.py b/src/pymatgen/transformations/transformation_abc.py index 59a4163345b..6f314abd664 100644 --- a/src/pymatgen/transformations/transformation_abc.py +++ b/src/pymatgen/transformations/transformation_abc.py @@ -3,11 +3,13 @@ from __future__ import annotations import abc -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING from monty.json import MSONable if TYPE_CHECKING: + from typing import Any, Literal + from pymatgen.core import Structure __author__ = "Shyue Ping Ong" @@ -55,7 +57,7 @@ def inverse(self) -> AbstractTransformation | None: """ @property - def is_one_to_many(self) -> bool: + def is_one_to_many(self) -> Literal[False]: """Determine if a Transformation is a one-to-many transformation. In that case, the apply_transformation method should have a keyword arg "return_ranked_list" which allows for the transformed structures to be returned as a ranked list. @@ -64,7 +66,7 @@ def is_one_to_many(self) -> bool: return False @property - def use_multiprocessing(self) -> bool: + def use_multiprocessing(self) -> Literal[False]: """Indicates whether the transformation can be applied by a subprocessing pool. This should be overridden to return True for transformations that the transmuter can parallelize. diff --git a/tests/analysis/chemenv/coordination_environments/test_coordination_geometries.py b/tests/analysis/chemenv/coordination_environments/test_coordination_geometries.py index 18fc1675835..2d0877d4cdc 100644 --- a/tests/analysis/chemenv/coordination_environments/test_coordination_geometries.py +++ b/tests/analysis/chemenv/coordination_environments/test_coordination_geometries.py @@ -89,7 +89,7 @@ def test_coordination_geometry(self): assert cg_oct.IUCr_symbol_str == "[6o]" cg_oct.permutations_safe_override = True - assert cg_oct.number_of_permutations == 720.0 + assert cg_oct.number_of_permutations == 720 assert cg_oct.ref_permutation([0, 3, 2, 4, 5, 1]) == (0, 3, 1, 5, 2, 4) sites = [FakeSite(coords=pp) for pp in cg_oct.points] diff --git a/tests/analysis/chemenv/coordination_environments/test_structure_environments.py b/tests/analysis/chemenv/coordination_environments/test_structure_environments.py index 3f8bde41636..018107482fd 100644 --- a/tests/analysis/chemenv/coordination_environments/test_structure_environments.py +++ b/tests/analysis/chemenv/coordination_environments/test_structure_environments.py @@ -4,7 +4,7 @@ import os import numpy as np -from numpy.testing import assert_allclose +from numpy.testing import assert_allclose, assert_array_equal from pytest import approx from pymatgen.analysis.chemenv.coordination_environments.chemenv_strategies import ( @@ -170,7 +170,7 @@ def test_light_structure_environments(self): assert_allclose(neighb_indices, [sai["index"] for sai in nb_sai]) nb_iai = nb_set.neighb_indices_and_images assert_allclose(neighb_indices, [iai["index"] for iai in nb_iai]) - np.testing.assert_array_equal(neighb_images, [iai["image_cell"] for iai in nb_iai]) + assert_array_equal(neighb_images, [iai["image_cell"] for iai in nb_iai]) assert len(nb_set) == 4 assert hash(nb_set) == 4 diff --git a/tests/analysis/chemenv/utils/test_func_utils.py b/tests/analysis/chemenv/utils/test_func_utils.py index 5109f69f5b4..7d269242abb 100644 --- a/tests/analysis/chemenv/utils/test_func_utils.py +++ b/tests/analysis/chemenv/utils/test_func_utils.py @@ -85,7 +85,7 @@ def test_csm_infinite_ratio_function(self): # csm_infinite_ratio = CSMInfiniteRatioFunction(function='power2_inverse_decreasing') assert csm_infinite_ratio.evaluate(0) == np.inf assert csm_infinite_ratio.evaluate(2) == approx(2.25) - assert csm_infinite_ratio.evaluate(4) == 0.5 + assert csm_infinite_ratio.evaluate(4) == approx(0.5) assert csm_infinite_ratio.evaluate(8) == 0 assert csm_infinite_ratio.evaluate(9) == 0 @@ -145,7 +145,7 @@ def test_delta_csm_ratio_function(self): ) assert delta_csm_ratio_function.evaluate(0) == 0 assert delta_csm_ratio_function.evaluate(1) == 0 - assert delta_csm_ratio_function.evaluate(2.5) == 0.5 + assert delta_csm_ratio_function.evaluate(2.5) == approx(0.5) assert delta_csm_ratio_function.evaluate(4) == 1 assert delta_csm_ratio_function.evaluate(5) == 1 @@ -155,6 +155,6 @@ def test_delta_csm_ratio_function(self): ) assert delta_csm_ratio_function.evaluate(0) == 0 assert delta_csm_ratio_function.evaluate(2) == 0 - assert delta_csm_ratio_function.evaluate(5) == 0.5 + assert delta_csm_ratio_function.evaluate(5) == approx(0.5) assert delta_csm_ratio_function.evaluate(8) == 1 assert delta_csm_ratio_function.evaluate(12) == 1 diff --git a/tests/analysis/chemenv/utils/test_math_utils.py b/tests/analysis/chemenv/utils/test_math_utils.py index d3583a24851..fd17b37ce96 100644 --- a/tests/analysis/chemenv/utils/test_math_utils.py +++ b/tests/analysis/chemenv/utils/test_math_utils.py @@ -66,7 +66,7 @@ def test_math_utils(self): 560, ] center = get_center_of_arc([0.0, 0.0], [1.0, 0.0], 0.5) - assert center == (0.5, 0.0) + assert_allclose(center, (0.5, 0.0)) def test_linearly_independent_vectors(self): v1, v2, v3 = np.eye(3) @@ -87,100 +87,121 @@ def test_scale_and_clamp(self): clamp0 = 0.0 clamp1 = 1.0 vals = np.linspace(5.0, 12.0, num=8) - assert scale_and_clamp(vals, edge0, edge1, clamp0, clamp1).tolist() == [ - 0.0, - 0.0, - 0.0, - 0.25, - 0.5, - 0.75, - 1.0, - 1.0, - ] + assert_allclose( + scale_and_clamp(vals, edge0, edge1, clamp0, clamp1), + [ + 0.0, + 0.0, + 0.0, + 0.25, + 0.5, + 0.75, + 1.0, + 1.0, + ], + ) def test_smoothstep(self): vals = np.linspace(5.0, 12.0, num=8) - assert smoothstep(vals, edges=[0.0, 1.0]).tolist() == [1.0] * 8 - assert smoothstep(vals, edges=[7.0, 11.0]).tolist() == [ - 0.0, - 0.0, - 0.0, - 0.15625, - 0.5, - 0.84375, - 1.0, - 1.0, - ] + assert_allclose(smoothstep(vals, edges=[0.0, 1.0]), [1.0] * 8) + assert_allclose( + smoothstep(vals, edges=[7.0, 11.0]), + [ + 0.0, + 0.0, + 0.0, + 0.15625, + 0.5, + 0.84375, + 1.0, + 1.0, + ], + ) def test_smootherstep(self): vals = np.linspace(5.0, 12.0, num=8) - assert smootherstep(vals, edges=[0.0, 1.0]).tolist() == [1.0] * 8 - assert smootherstep(vals, edges=[7.0, 11.0]).tolist() == [ - 0.0, - 0.0, - 0.0, - 0.103515625, - 0.5, - 0.896484375, - 1.0, - 1.0, - ] + assert_allclose(smootherstep(vals, edges=[0.0, 1.0]), [1.0] * 8) + assert_allclose( + smootherstep(vals, edges=[7.0, 11.0]), + [ + 0.0, + 0.0, + 0.0, + 0.103515625, + 0.5, + 0.896484375, + 1.0, + 1.0, + ], + ) def test_power3_step(self): vals = np.linspace(5.0, 12.0, num=8) - assert power3_step(vals, edges=[0.0, 1.0]).tolist() == [1.0] * 8 - assert power3_step(vals, edges=[7.0, 11.0]).tolist() == [ - 0.0, - 0.0, - 0.0, - 0.15625, - 0.5, - 0.84375, - 1.0, - 1.0, - ] + assert_allclose(power3_step(vals, edges=[0.0, 1.0]), [1.0] * 8) + assert_allclose( + power3_step(vals, edges=[7.0, 11.0]), + [ + 0.0, + 0.0, + 0.0, + 0.15625, + 0.5, + 0.84375, + 1.0, + 1.0, + ], + ) def test_cosinus_step(self): vals = np.linspace(5.0, 12.0, num=8) - assert cosinus_step(vals, edges=[0.0, 1.0]).tolist() == [1.0] * 8 + assert_allclose(cosinus_step(vals, edges=[0.0, 1.0]), [1.0] * 8) assert_allclose( - cosinus_step(vals, edges=[7.0, 11.0]).tolist(), + cosinus_step(vals, edges=[7.0, 11.0]), [0.0, 0.0, 0.0, 0.14644660940672616, 0.5, 0.8535533905932737, 1.0, 1.0], 5, ) def test_powern_parts_step(self): vals = np.linspace(5.0, 12.0, num=8) - assert powern_parts_step(vals, edges=[0.0, 1.0], nn=2).tolist() == [1.0] * 8 - assert powern_parts_step(vals, edges=[0.0, 1.0], nn=3).tolist() == [1.0] * 8 - assert powern_parts_step(vals, edges=[0.0, 1.0], nn=4).tolist() == [1.0] * 8 - assert powern_parts_step(vals, edges=[7.0, 11.0], nn=2).tolist() == [ - 0.0, - 0.0, - 0.0, - 0.125, - 0.5, - 0.875, - 1.0, - 1.0, - ] - assert powern_parts_step(vals, edges=[7.0, 11.0], nn=3).tolist() == [ - 0.0, - 0.0, - 0.0, - 0.0625, - 0.5, - 0.9375, - 1.0, - 1.0, - ] - assert powern_parts_step(vals, edges=[7.0, 11.0], nn=4).tolist() == [ - 0.0, - 0.0, - 0.0, - 0.03125, - 0.5, - 0.96875, - 1.0, - 1.0, - ] + assert_allclose(powern_parts_step(vals, edges=[0.0, 1.0], nn=2), [1.0] * 8) + assert_allclose(powern_parts_step(vals, edges=[0.0, 1.0], nn=3), [1.0] * 8) + assert_allclose(powern_parts_step(vals, edges=[0.0, 1.0], nn=4), [1.0] * 8) + assert_allclose( + powern_parts_step(vals, edges=[7.0, 11.0], nn=2), + [ + 0.0, + 0.0, + 0.0, + 0.125, + 0.5, + 0.875, + 1.0, + 1.0, + ], + ) + assert_allclose( + powern_parts_step(vals, edges=[7.0, 11.0], nn=3), + [ + 0.0, + 0.0, + 0.0, + 0.0625, + 0.5, + 0.9375, + 1.0, + 1.0, + ], + ) + assert_allclose( + powern_parts_step(vals, edges=[7.0, 11.0], nn=4), + [ + 0.0, + 0.0, + 0.0, + 0.03125, + 0.5, + 0.96875, + 1.0, + 1.0, + ], + ) diff --git a/tests/analysis/diffraction/test_tem.py b/tests/analysis/diffraction/test_tem.py index c8cfee3b1d5..f51e7a3f6af 100644 --- a/tests/analysis/diffraction/test_tem.py +++ b/tests/analysis/diffraction/test_tem.py @@ -199,7 +199,7 @@ def test_get_first_point(self): points = tem_calc.generate_points(-2, 2) cubic = Structure(lattice, ["Cs", "Cl"], [[0, 0, 0], [0.5, 0.5, 0.5]]) first_pt = tem_calc.get_first_point(cubic, points) - assert 4.209 in first_pt.values() + assert any(val == approx(4.209) for val in first_pt.values()) def test_interplanar_angle(self): # test interplanar angles. Reference values from KW Andrews, diff --git a/tests/analysis/elasticity/test_elastic.py b/tests/analysis/elasticity/test_elastic.py index 699f97d4061..737ee682b0d 100644 --- a/tests/analysis/elasticity/test_elastic.py +++ b/tests/analysis/elasticity/test_elastic.py @@ -311,7 +311,7 @@ def test_gruneisen(self): # Get heat capacity c0 = self.exp_cu.get_heat_capacity(0, self.cu, [1, 0, 0], [0, 1, 0]) - assert c0 == 0.0 + assert c0 == approx(0.0) c = self.exp_cu.get_heat_capacity(300, self.cu, [1, 0, 0], [0, 1, 0]) assert c == approx(8.285611958) diff --git a/tests/analysis/elasticity/test_stress.py b/tests/analysis/elasticity/test_stress.py index 9d1dc98ad33..6195160ae40 100644 --- a/tests/analysis/elasticity/test_stress.py +++ b/tests/analysis/elasticity/test_stress.py @@ -54,7 +54,7 @@ def test_properties(self): [[0.377226, 2.1358, 2.2679], [2.1358, 5.14, 5.07], [2.2679, 5.07, 5.33]], ) # voigt - assert list(self.symm_stress.voigt) == [0.51, 5.14, 5.33, 5.07, 2.42, 2.29] + assert_allclose(self.symm_stress.voigt, [0.51, 5.14, 5.33, 5.07, 2.42, 2.29]) with pytest.warns( UserWarning, diff --git a/tests/analysis/magnetism/test_heisenberg.py b/tests/analysis/magnetism/test_heisenberg.py index 248bb559227..2347c20083f 100644 --- a/tests/analysis/magnetism/test_heisenberg.py +++ b/tests/analysis/magnetism/test_heisenberg.py @@ -3,6 +3,7 @@ from unittest import TestCase import pandas as pd +from pytest import approx from pymatgen.analysis.magnetism.heisenberg import HeisenbergMapper from pymatgen.core.structure import Structure @@ -47,7 +48,7 @@ def test_nn_interactions(self): assert n_interacts == 3 dists = hm.dists - assert dists["nn"] == 2.51 + assert dists["nn"] == approx(2.51) def test_exchange_params(self): for hm in self.hms: diff --git a/tests/analysis/test_chempot_diagram.py b/tests/analysis/test_chempot_diagram.py index 43dfd957b0d..1b0c11a8343 100644 --- a/tests/analysis/test_chempot_diagram.py +++ b/tests/analysis/test_chempot_diagram.py @@ -1,6 +1,7 @@ from __future__ import annotations import numpy as np +from numpy.testing import assert_allclose from plotly.graph_objects import Figure from pytest import approx @@ -222,7 +223,7 @@ def test_domains(self): dom = self.cpd_ternary.domains[formula] dom = dom.round(6) # to get rid of numerical errors from qhull actual_domain_sorted = dom[np.lexsort((dom[:, 2], dom[:, 1], dom[:, 0]))] - assert actual_domain_sorted == approx(np.array(domain)) + assert_allclose(actual_domain_sorted, domain) formal_domains = { "FeO": [ @@ -307,7 +308,7 @@ def test_domains(self): for formula, domain in formal_domains.items(): dom = self.cpd_ternary_formal.domains[formula] dom = dom.round(6) # to get rid of numerical errors from qhull - assert dom == approx(np.array(domain), abs=1e-5) + assert_allclose(dom, domain, atol=1e-5) def test_formal_chempots_get_plot(self): elems = [Element("Fe"), Element("O")] diff --git a/tests/analysis/test_ewald.py b/tests/analysis/test_ewald.py index 285152bb8fd..fddc9b37abb 100644 --- a/tests/analysis/test_ewald.py +++ b/tests/analysis/test_ewald.py @@ -114,6 +114,6 @@ def test_site(self): # Comparison to LAMMPS result ham = EwaldSummation(struct, compute_forces=True) - assert approx(ham.total_energy, abs=1e-3) == -1226.3335 - assert approx(ham.get_site_energy(0), abs=1e-3) == -45.8338 - assert approx(ham.get_site_energy(8), abs=1e-3) == -27.2978 + assert ham.total_energy == approx(-1226.3335, abs=1e-3) + assert ham.get_site_energy(0) == approx(-45.8338, abs=1e-3) + assert ham.get_site_energy(8) == approx(-27.2978, abs=1e-3) diff --git a/tests/analysis/test_graphs.py b/tests/analysis/test_graphs.py index ad42533435c..766e1ba13f3 100644 --- a/tests/analysis/test_graphs.py +++ b/tests/analysis/test_graphs.py @@ -161,7 +161,7 @@ def test_edge_editing(self): new_edge_properties={"foo": "bar"}, ) new_edge = square.graph.get_edge_data(0, 0)[0] - assert new_edge["weight"] == 0.0 + assert new_edge["weight"] == approx(0.0) assert new_edge["foo"] == "bar" square.break_edge(0, 0, to_jimage=(1, 0, 0)) @@ -231,7 +231,7 @@ def test_substitute(self): sg_with_graph = StructureGraph.from_local_env_strategy(structure_copy_graph, MinimumDistanceNN()) sg_with_graph.substitute_group(1, "methyl", MinimumDistanceNN, graph_dict=graph_dict) edge = sg_with_graph.graph.get_edge_data(11, 13)[0] - assert edge["weight"] == 0.5 + assert edge["weight"] == approx(0.5) def test_auto_image_detection(self): struct_graph = StructureGraph.from_empty_graph(self.structure) @@ -658,7 +658,7 @@ def test_edge_editing(self): cyclohexene = copy.deepcopy(self.cyclohexene) cyclohexene.alter_edge(0, 1, new_weight=0.0, new_edge_properties={"foo": "bar"}) new_edge = cyclohexene.graph.get_edge_data(0, 1)[0] - assert new_edge["weight"] == 0.0 + assert new_edge["weight"] == approx(0.0) assert new_edge["foo"] == "bar" cyclohexene.break_edge(0, 1) @@ -893,7 +893,7 @@ def test_substitute(self): # Check that MoleculeGraph input is handled properly eth_graph.substitute_group(5, molecule, MinimumDistanceNN, graph_dict=graph_dict) eth_mg.substitute_group(5, mol_graph, MinimumDistanceNN) - assert eth_graph.graph.get_edge_data(5, 6)[0]["weight"] == 1.0 + assert eth_graph.graph.get_edge_data(5, 6)[0]["weight"] == approx(1.0) assert eth_mg == eth_graph def test_replace(self): diff --git a/tests/analysis/test_local_env.py b/tests/analysis/test_local_env.py index ac2ab8b099d..2c5c4d6039b 100644 --- a/tests/analysis/test_local_env.py +++ b/tests/analysis/test_local_env.py @@ -168,7 +168,7 @@ def test_nn_shell(self): # Weight of getting back on to own site # Square-square hop: 6*5 options times (0.125/0.32476)^2 weight each # Hex-hex hop: 8*7 options times 1 weight each - assert approx(np.sum([x["weight"] for x in nns if x["site_index"] == 0]), abs=1e-3) == 60.4444 + assert np.sum([x["weight"] for x in nns if x["site_index"] == 0]) == approx(60.4444, abs=1e-3) def test_adj_neighbors(self): # Make a simple cubic structure diff --git a/tests/analysis/test_phase_diagram.py b/tests/analysis/test_phase_diagram.py index 934ba59fa9d..73c77eaea49 100644 --- a/tests/analysis/test_phase_diagram.py +++ b/tests/analysis/test_phase_diagram.py @@ -51,8 +51,8 @@ def test_get_chemical_energy(self): assert self.gp_entry.chemical_energy == 3, "Wrong energy!" def test_get_energy_per_atom(self): - assert self.entry.energy_per_atom == 53.0 / 4, "Wrong energy per atom!" - assert self.gp_entry.energy_per_atom == 50.0 / 2, "Wrong energy per atom!" + assert self.entry.energy_per_atom == approx(53.0 / 4), "Wrong energy per atom!" + assert self.gp_entry.energy_per_atom == approx(50.0 / 2), "Wrong energy per atom!" def test_get_name(self): assert self.entry.name == "mp-757614" @@ -88,10 +88,10 @@ def test_as_from_dict(self): entry = PDEntry.from_dict(dct) assert entry.name == "mp-757614" - assert entry.energy_per_atom == 53.0 / 4 + assert entry.energy_per_atom == approx(53.0 / 4) gp_entry = GrandPotPDEntry.from_dict(gpd) assert gp_entry.name == "mp-757614" - assert gp_entry.energy_per_atom == 50.0 / 2 + assert gp_entry.energy_per_atom == approx(50.0 / 2) d_anon = dct.copy() del d_anon["name"] diff --git a/tests/analysis/test_piezo.py b/tests/analysis/test_piezo.py index bf3eb7534c2..caeb1f77097 100644 --- a/tests/analysis/test_piezo.py +++ b/tests/analysis/test_piezo.py @@ -4,7 +4,7 @@ import numpy as np import pytest -from numpy.testing import assert_allclose, assert_array_equal +from numpy.testing import assert_allclose from pymatgen.analysis.piezo import PiezoTensor from pymatgen.util.testing import PymatgenTest @@ -50,15 +50,15 @@ def test_new(self): def test_from_voigt(self): bad_voigt = np.zeros((3, 7)) pt = PiezoTensor.from_voigt(self.voigt_matrix) - assert_array_equal(pt, self.full_tensor_array) + assert_allclose(pt, self.full_tensor_array) with pytest.raises(ValueError, match="Invalid shape for Voigt matrix"): PiezoTensor.from_voigt(bad_voigt) - assert_array_equal(self.voigt_matrix, pt.voigt) + assert_allclose(self.voigt_matrix, pt.voigt) def test_from_vasp_voigt(self): bad_voigt = np.zeros((3, 7)) pt = PiezoTensor.from_vasp_voigt(self.vasp_matrix) - assert_array_equal(pt, self.full_tensor_array) + assert_allclose(pt, self.full_tensor_array) with pytest.raises(ValueError, match="Invalid shape for Voigt matrix"): PiezoTensor.from_voigt(bad_voigt) - assert_array_equal(self.voigt_matrix, pt.voigt) + assert_allclose(self.voigt_matrix, pt.voigt) diff --git a/tests/analysis/test_pourbaix_diagram.py b/tests/analysis/test_pourbaix_diagram.py index 22066499257..4127c2c75fb 100644 --- a/tests/analysis/test_pourbaix_diagram.py +++ b/tests/analysis/test_pourbaix_diagram.py @@ -36,7 +36,7 @@ def test_pourbaix_entry(self): assert self.px_sol.entry.name == "Mn2O3", "Wrong Entry!" # assert self.PxIon.energy == 25, "Wrong Energy!" # assert self.PxSol.energy == 49, "Wrong Energy!" - assert self.px_ion.concentration == 1e-4, "Wrong concentration!" + assert self.px_ion.concentration == approx(1e-4), "Wrong concentration!" def test_calc_coeff_terms(self): assert self.px_ion.npH == -8, "Wrong npH!" diff --git a/tests/analysis/test_quasi_harmonic_debye_approx.py b/tests/analysis/test_quasi_harmonic_debye_approx.py index 6c0c5816d2d..2716aa1b29e 100644 --- a/tests/analysis/test_quasi_harmonic_debye_approx.py +++ b/tests/analysis/test_quasi_harmonic_debye_approx.py @@ -2,7 +2,6 @@ from unittest import TestCase -import numpy as np from numpy.testing import assert_allclose from pymatgen.analysis.eos import EOS @@ -189,7 +188,7 @@ def test_optimum_volume(self): def test_debye_temperature(self): theta = self.qhda.debye_temperature(self.opt_vol) - np.testing.assert_approx_equal(theta, 601.239096, 4) + assert_allclose(theta, 601.239096, 4) def test_gruneisen_parameter(self): gamma = self.qhda.gruneisen_parameter(0, self.qhda.ev_eos_fit.v0) diff --git a/tests/analysis/test_quasirrho.py b/tests/analysis/test_quasirrho.py index 63cd0015ad4..769904d467f 100644 --- a/tests/analysis/test_quasirrho.py +++ b/tests/analysis/test_quasirrho.py @@ -2,7 +2,8 @@ from unittest import TestCase -import pytest +from numpy.testing import assert_allclose +from pytest import approx from pymatgen.analysis.quasirrho import QuasiRRHO, get_avg_mom_inertia from pymatgen.io.gaussian import GaussianOutput @@ -28,8 +29,8 @@ def test_qrrho_gaussian(self): correct_g = -884.776886 correct_stot = 141.584080 qrrho = QuasiRRHO.from_gaussian_output(self.gout) - assert correct_stot == pytest.approx(qrrho.entropy_quasiRRHO, 0.1), "Incorrect total entropy" - assert correct_g == pytest.approx(qrrho.free_energy_quasiRRHO), "Incorrect Quasi-RRHO free energy" + assert correct_stot == approx(qrrho.entropy_quasiRRHO, rel=0.1), "Incorrect total entropy" + assert correct_g == approx(qrrho.free_energy_quasiRRHO), "Incorrect Quasi-RRHO free energy" def test_qrrho_qchem(self): """ @@ -42,8 +43,8 @@ def test_qrrho_qchem(self): # HO total entropy from QChem = 106.521 qrrho = QuasiRRHO.from_qc_output(self.qout) - assert correct_stot == pytest.approx(qrrho.entropy_quasiRRHO, 0.1), "Incorrect total entropy" - assert correct_g == pytest.approx(qrrho.free_energy_quasiRRHO), "Incorrect Quasi-RRHO free energy" + assert correct_stot == approx(qrrho.entropy_quasiRRHO, rel=0.1), "Incorrect total entropy" + assert correct_g == approx(qrrho.free_energy_quasiRRHO), "Incorrect Quasi-RRHO free energy" def test_rrho_manual(self): """ @@ -56,8 +57,8 @@ def test_rrho_manual(self): correct_g = -884.776886 correct_stot = 141.584080 qrrho = QuasiRRHO(mol=mol, energy=e_final, frequencies=vib_freqs, mult=1) - assert correct_stot == pytest.approx(qrrho.entropy_quasiRRHO, 0.1), "Incorrect total entropy" - assert correct_g == pytest.approx(qrrho.free_energy_quasiRRHO), "Incorrect Quasi-RRHO free energy" + assert correct_stot == approx(qrrho.entropy_quasiRRHO, rel=0.1), "Incorrect total entropy" + assert correct_g == approx(qrrho.free_energy_quasiRRHO), "Incorrect Quasi-RRHO free energy" def test_rrho_linear(self): """Test on a linear CO2 molecule from Gaussian Output file. @@ -68,18 +69,18 @@ def test_rrho_linear(self): correct_g_ho = -187.642070 correct_g_qrrho = -187.642725 qrrho = QuasiRRHO.from_gaussian_output(self.linear_gout) - assert correct_g_ho == pytest.approx( + assert correct_g_ho == approx( qrrho.free_energy_ho, rel=1e-5 ), f"Incorrect harmonic oscillator free energy, {correct_g_ho} != {qrrho.free_energy_ho}" - assert correct_g_qrrho == pytest.approx(qrrho.free_energy_quasiRRHO), "Incorrect Quasi-RRHO free energy" + assert correct_g_qrrho == approx(qrrho.free_energy_quasiRRHO), "Incorrect Quasi-RRHO free energy" def test_extreme_temperature_and_pressure(self): qrrho = QuasiRRHO.from_gaussian_output(self.gout, temp=0.1, press=1e9) - assert qrrho.temp == 0.1 - assert qrrho.press == 1e9 + assert qrrho.temp == approx(0.1) + assert qrrho.press == approx(1e9) def test_get_avg_mom_inertia(self): mol = self.gout.final_structure avg_mom_inertia, inertia_eigen_vals = get_avg_mom_inertia(mol) - assert avg_mom_inertia == pytest.approx(0) - assert inertia_eigen_vals == pytest.approx([0, 0, 0]) + assert avg_mom_inertia == approx(0) + assert_allclose(inertia_eigen_vals, [0, 0, 0], rtol=1e-6, atol=1e-12) diff --git a/tests/analysis/test_structure_analyzer.py b/tests/analysis/test_structure_analyzer.py index a7da910eff0..d49368d96ec 100644 --- a/tests/analysis/test_structure_analyzer.py +++ b/tests/analysis/test_structure_analyzer.py @@ -48,10 +48,10 @@ def setUp(self): def test_vol_and_para_changes(self): for val in self.analyzer.get_percentage_lattice_parameter_changes().values(): - assert approx(val) == -0.0092040921155279731 + assert val == approx(-0.0092040921155279731) latt_change = val vol_change = self.analyzer.get_percentage_volume_change() - assert approx(vol_change) == -0.0273589101391 + assert vol_change == approx(-0.0273589101391) # This is a simple cubic cell, so the latt and vol change are simply # Related. So let's test that. assert (1 + latt_change) ** 3 - 1 == approx(vol_change) @@ -59,7 +59,7 @@ def test_vol_and_para_changes(self): def test_get_percentage_bond_dist_changes(self): for v in self.analyzer.get_percentage_bond_dist_changes().values(): for v2 in v.values(): - assert approx(v2) == -0.009204092115527862 + assert v2 == approx(-0.009204092115527862) class TestVoronoiConnectivity(PymatgenTest): diff --git a/tests/analysis/test_surface_analysis.py b/tests/analysis/test_surface_analysis.py index 5492d9aefa6..0bdcb65deff 100644 --- a/tests/analysis/test_surface_analysis.py +++ b/tests/analysis/test_surface_analysis.py @@ -358,7 +358,7 @@ def test_scaled_wulff(self): w2 = self.nanoscale_stability.scaled_wulff(fcc_wulff, 10) assert w1.effective_radius == approx(w2.effective_radius) assert w1.effective_radius == approx(10) - assert approx(w2.effective_radius) == 10 + assert w2.effective_radius == approx(10) def get_entry_dict(filename): diff --git a/tests/analysis/xas/test_spectrum.py b/tests/analysis/xas/test_spectrum.py index 92a04879dc3..5c6e7ed8345 100644 --- a/tests/analysis/xas/test_spectrum.py +++ b/tests/analysis/xas/test_spectrum.py @@ -5,7 +5,7 @@ import numpy as np import pytest from monty.json import MontyDecoder -from numpy.testing import assert_allclose, assert_array_equal +from numpy.testing import assert_allclose from pytest import approx from pymatgen.analysis.xas.spectrum import XAS, site_weighted_spectrum @@ -14,17 +14,17 @@ TEST_DIR = f"{TEST_FILES_DIR}/analysis/spectrum_test" -with open(f"{TEST_DIR}/LiCoO2_k_xanes.json") as file: +with open(f"{TEST_DIR}/LiCoO2_k_xanes.json", encoding="utf-8") as file: k_xanes_dict = json.load(file, cls=MontyDecoder) -with open(f"{TEST_DIR}/LiCoO2_k_exafs.json") as file: +with open(f"{TEST_DIR}/LiCoO2_k_exafs.json", encoding="utf-8") as file: k_exafs_dict = json.load(file, cls=MontyDecoder) -with open(f"{TEST_DIR}/ZnO_l2_xanes.json") as file: +with open(f"{TEST_DIR}/ZnO_l2_xanes.json", encoding="utf-8") as file: l2_xanes_dict = json.load(file, cls=MontyDecoder) -with open(f"{TEST_DIR}/ZnO_l3_xanes.json") as file: +with open(f"{TEST_DIR}/ZnO_l3_xanes.json", encoding="utf-8") as file: l3_xanes_dict = json.load(file, cls=MontyDecoder) -with open(f"{TEST_DIR}/site1_k_xanes.json") as file: +with open(f"{TEST_DIR}/site1_k_xanes.json", encoding="utf-8") as file: site1_xanes_dict = json.load(file, cls=MontyDecoder) -with open(f"{TEST_DIR}/site2_k_xanes.json") as file: +with open(f"{TEST_DIR}/site2_k_xanes.json", encoding="utf-8") as file: site2_xanes_dict = json.load(file, cls=MontyDecoder) @@ -38,7 +38,7 @@ def setUp(self): self.site2_xanes = XAS.from_dict(site2_xanes_dict) def test_e0(self): - assert approx(self.k_xanes.e0) == 7728.565 + assert self.k_xanes.e0 == approx(7728.565) def test_k(self): assert len(self.k_xanes.x) == len(self.k_xanes.k) @@ -46,22 +46,22 @@ def test_k(self): def test_normalization(self): self.k_xanes.normalize(mode="sum") - assert approx(np.sum(self.k_xanes.y)) == 1.0 + assert np.sum(self.k_xanes.y) == approx(1.0) def test_add_mul(self): scaled_spect = self.k_xanes + self.k_xanes scaled_spect2 = self.k_xanes * 3 assert_allclose(scaled_spect.y, 2 * self.k_xanes.y) assert_allclose(scaled_spect2.y, 3 * self.k_xanes.y) - assert approx(self.k_xanes.get_interpolated_value(7720.422), abs=1e-3) == 0.274302 + assert self.k_xanes.get_interpolated_value(7720.422) == approx(0.274302, abs=1e-3) def test_as_from_dict(self): xas = XAS.from_dict(self.k_xanes.as_dict()) assert_allclose(xas.y, self.k_xanes.y) def test_attributes(self): - assert_array_equal(self.k_xanes.energy, self.k_xanes.x) - assert_array_equal(self.k_xanes.intensity, self.k_xanes.y) + assert_allclose(self.k_xanes.energy, self.k_xanes.x) + assert_allclose(self.k_xanes.intensity, self.k_xanes.y) def test_str(self): assert str(self.k_xanes) == "Co K Edge XANES for LiCoO2: , >" diff --git a/tests/command_line/test_chargemol_caller.py b/tests/command_line/test_chargemol_caller.py index dd9c5d2c605..0916864e180 100644 --- a/tests/command_line/test_chargemol_caller.py +++ b/tests/command_line/test_chargemol_caller.py @@ -1,5 +1,8 @@ from __future__ import annotations +from numpy.testing import assert_allclose +from pytest import approx + from pymatgen.command_line.chargemol_caller import ChargemolAnalysis from pymatgen.core import Element from pymatgen.util.testing import TEST_FILES_DIR @@ -11,20 +14,20 @@ class TestChargemolAnalysis: def test_parse_chargemol(self): test_dir = f"{TEST_DIR}/spin_unpolarized" ca = ChargemolAnalysis(path=test_dir, run_chargemol=False) - assert ca.ddec_charges == [0.8432, -0.8432] - assert ca.get_partial_charge(0) == 0.8432 - assert ca.get_partial_charge(0, charge_type="cm5") == 0.420172 - assert ca.get_charge_transfer(0) == -0.8432 - assert ca.get_charge_transfer(0, charge_type="cm5") == -0.420172 - assert ca.get_charge(0, nelect=1) == 1 - 0.8432 - assert ca.get_charge(0, nelect=1, charge_type="cm5") == 1 - 0.420172 - assert ca.dipoles == [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] + assert_allclose(ca.ddec_charges, [0.8432, -0.8432]) + assert ca.get_partial_charge(0) == approx(0.8432) + assert ca.get_partial_charge(0, charge_type="cm5") == approx(0.420172) + assert ca.get_charge_transfer(0) == approx(-0.8432) + assert ca.get_charge_transfer(0, charge_type="cm5") == approx(-0.420172) + assert ca.get_charge(0, nelect=1) == approx(1 - 0.8432) + assert ca.get_charge(0, nelect=1, charge_type="cm5") == approx(1 - 0.420172) + assert_allclose(ca.dipoles, [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]) assert ca.ddec_spin_moments is None - assert ca.bond_order_sums == [0.53992, 0.901058] - assert ca.ddec_rsquared_moments == [8.261378, 34.237274] - assert ca.ddec_rcubed_moments == [14.496002, 88.169236] - assert ca.ddec_rfourth_moments == [37.648248, 277.371929] - assert ca.cm5_charges == [0.420172, -0.420172] + assert_allclose(ca.bond_order_sums, [0.53992, 0.901058]) + assert_allclose(ca.ddec_rsquared_moments, [8.261378, 34.237274]) + assert_allclose(ca.ddec_rcubed_moments, [14.496002, 88.169236]) + assert_allclose(ca.ddec_rfourth_moments, [37.648248, 277.371929]) + assert_allclose(ca.cm5_charges, [0.420172, -0.420172]) assert ca.summary["ddec"]["partial_charges"] == ca.ddec_charges assert ca.summary["ddec"]["dipoles"] == ca.dipoles assert ca.summary["ddec"]["bond_order_sums"] == ca.bond_order_sums @@ -50,13 +53,16 @@ def test_parse_chargemol(self): def test_parse_chargemol2(self): test_dir = f"{TEST_DIR}/spin_polarized" ca = ChargemolAnalysis(path=test_dir, run_chargemol=False) - assert ca.ddec_spin_moments == [0.201595, 0.399203, 0.399203] - assert ca.dipoles == [ - [-0.0, 0.0, -0.127251], - [0.0, -0.027857, -0.010944], - [0.0, 0.027857, -0.010944], - ] - assert ca.summary["ddec"]["bond_order_dict"][0]["bonded_to"][0]["spin_polarization"] == 0.0490 + assert_allclose(ca.ddec_spin_moments, [0.201595, 0.399203, 0.399203]) + assert_allclose( + ca.dipoles, + [ + [-0.0, 0.0, -0.127251], + [0.0, -0.027857, -0.010944], + [0.0, 0.027857, -0.010944], + ], + ) + assert ca.summary["ddec"]["bond_order_dict"][0]["bonded_to"][0]["spin_polarization"] == approx(0.0490) assert ca.summary["ddec"]["spin_moments"] == ca.ddec_spin_moments assert ca.natoms is None assert ca.structure is None diff --git a/tests/command_line/test_gulp_caller.py b/tests/command_line/test_gulp_caller.py index 192c06ef453..951d1782e0e 100644 --- a/tests/command_line/test_gulp_caller.py +++ b/tests/command_line/test_gulp_caller.py @@ -8,12 +8,12 @@ import os import sys -import unittest from shutil import which from unittest import TestCase import numpy as np import pytest +from pytest import approx from pymatgen.analysis.bond_valence import BVAnalyzer from pymatgen.command_line.gulp_caller import ( @@ -132,11 +132,11 @@ def test_structure_lines_no_frac_coords(self): assert "cell" not in inp_str assert "cart" in inp_str - @unittest.skip("Not Implemented yet") + @pytest.mark.skip("Not Implemented yet") def test_specie_potential(self): pass - @unittest.expectedFailure + @pytest.mark.xfail def test_library_line_explicit_path(self): gin = self.gio.library_line("/Users/mbkumar/Research/Defects/GulpExe/Libraries/catlow.lib") assert "lib" in gin @@ -267,7 +267,7 @@ def test_get_energy(self): Non-primitive unit cell = -16311.9732 kJ/(mole unit cells) --------------------------------------------------------------------------------""" energy = self.gio.get_energy(out_str) - assert energy == -169.06277218 + assert energy == approx(-169.06277218) def test_get_relaxed_structure(self): # Output string obtained from running GULP on a terminal @@ -277,10 +277,10 @@ def test_get_relaxed_structure(self): struct = self.gio.get_relaxed_structure(out_str) assert isinstance(struct, Structure) assert len(struct) == 8 - assert struct.lattice.a == 4.212 - assert struct.lattice.alpha == 90 + assert struct.lattice.a == approx(4.212) + assert struct.lattice.alpha == approx(90) - @unittest.skip("Test later") + @pytest.mark.skip("Test later") def test_tersoff_input(self): self.gio.tersoff_input(self.structure) diff --git a/tests/command_line/test_vampire_caller.py b/tests/command_line/test_vampire_caller.py index e2e55a18486..5df98fe1ad4 100644 --- a/tests/command_line/test_vampire_caller.py +++ b/tests/command_line/test_vampire_caller.py @@ -44,4 +44,4 @@ def test_vampire(self): user_input_settings=settings, ) - assert approx(vc.output.critical_temp) == 400 + assert vc.output.critical_temp == approx(400) diff --git a/tests/core/test_bonds.py b/tests/core/test_bonds.py index fb75a2b11e2..ca9d6b9f815 100644 --- a/tests/core/test_bonds.py +++ b/tests/core/test_bonds.py @@ -18,14 +18,14 @@ class TestCovalentBond: def test_length(self): site1 = Site("C", [0, 0, 0]) site2 = Site("H", [0, 0.7, 0.6]) - assert approx(CovalentBond(site1, site2).length - 0.92195444572928864) == 0 + assert CovalentBond(site1, site2).length == approx(0.92195444572928864) def test_get_bond_order(self): site1 = Site("C", [0, 0, 0]) site2 = Site("H", [0, 0, 1.08]) - assert approx(CovalentBond(site1, site2).get_bond_order() - 1) == 0 + assert CovalentBond(site1, site2).get_bond_order() == approx(1) bond = CovalentBond(Site("C", [0, 0, 0]), Site("Br", [0, 0, 2])) - assert approx(bond.get_bond_order(0.5, 1.9) - 0.894736842105263) == 0 + assert bond.get_bond_order(0.5, 1.9) == approx(0.894736842105263) def test_is_bonded(self): site1 = Site("C", [0, 0, 0]) @@ -46,34 +46,34 @@ def test_str(self): class TestFunc: def test_get_bond_length(self): - assert approx(get_bond_length("C", "C", 1) - 1.54) == 0 - assert approx(get_bond_length("C", "C", 2) - 1.34) == 0 - assert approx(get_bond_length("C", "H", 1) - 1.08) == 0 - assert get_bond_length("C", "H", 2) == 0.95 - assert approx(get_bond_length("C", "Br", 1) - 1.85) == 0 + assert get_bond_length("C", "C", 1) == approx(1.54) + assert get_bond_length("C", "C", 2) == approx(1.34) + assert get_bond_length("C", "H", 1) == approx(1.08) + assert get_bond_length("C", "H", 2) == approx(0.95) + assert get_bond_length("C", "Br", 1) == approx(1.85) def test_obtain_all_bond_lengths(self): - assert obtain_all_bond_lengths("C", "C") == {1.0: 1.54, 2.0: 1.34, 3.0: 1.2} + assert obtain_all_bond_lengths("C", "C") == approx({1.0: 1.54, 2.0: 1.34, 3.0: 1.2}) with pytest.raises(ValueError, match="No bond data for elements Br - C"): obtain_all_bond_lengths("Br", Element("C")) - assert obtain_all_bond_lengths("C", Element("Br"), 1.76) == {1: 1.76} + assert obtain_all_bond_lengths("C", Element("Br"), 1.76) == approx({1: 1.76}) bond_lengths_dict = obtain_all_bond_lengths("C", "N") bond_lengths_dict[4] = 999 - assert obtain_all_bond_lengths("C", "N") == {1.0: 1.47, 2.0: 1.3, 3.0: 1.16} + assert obtain_all_bond_lengths("C", "N") == approx({1.0: 1.47, 2.0: 1.3, 3.0: 1.16}) def test_get_bond_order(self): - assert approx(get_bond_order("C", "C", 1) - 3) == 0 - assert approx(get_bond_order("C", "C", 1.2) - 3) == 0 - assert approx(get_bond_order("C", "C", 1.25) - 2.642857142857143) == 0 - assert approx(get_bond_order("C", "C", 1.34) - 2) == 0 - assert approx(get_bond_order("C", "C", 1.4) - 1.7) == 0 # bond length in benzene - assert approx(get_bond_order("C", "C", 1.54) - 1) == 0 - assert approx(get_bond_order("C", "C", 2.5)) == 0 - assert approx(get_bond_order("C", "C", 9999)) == 0 - assert approx(get_bond_order("C", "Br", 1.9, default_bl=1.9) - 1) == 0 - assert approx(get_bond_order("C", "Br", 2, default_bl=1.9) - 0.7368421052631575) == 0 - assert approx(get_bond_order("C", "Br", 1.9, tol=0.5, default_bl=1.9) - 1) == 0 - assert approx(get_bond_order("C", "Br", 2, tol=0.5, default_bl=1.9) - 0.894736842105263) == 0 + assert get_bond_order("C", "C", 1) == approx(3) + assert get_bond_order("C", "C", 1.2) == approx(3) + assert get_bond_order("C", "C", 1.25) == approx(2.642857142857143) + assert get_bond_order("C", "C", 1.34) == approx(2) + assert get_bond_order("C", "C", 1.4) == approx(1.7) # bond length in benzene + assert get_bond_order("C", "C", 1.54) == approx(1) + assert get_bond_order("C", "C", 2.5) == approx(0) + assert get_bond_order("C", "C", 9999) == approx(0) + assert get_bond_order("C", "Br", 1.9, default_bl=1.9) == approx(1) + assert get_bond_order("C", "Br", 2, default_bl=1.9) == approx(0.7368421052631575) + assert get_bond_order("C", "Br", 1.9, tol=0.5, default_bl=1.9) == approx(1) + assert get_bond_order("C", "Br", 2, tol=0.5, default_bl=1.9) == approx(0.894736842105263) with pytest.raises(ValueError, match="No bond data for elements Br - C"): get_bond_order("C", "Br", 1.9) - assert approx(get_bond_order("N", "N", 1.25) - 2) == 0 + assert get_bond_order("N", "N", 1.25) == approx(2) diff --git a/tests/core/test_composition.py b/tests/core/test_composition.py index 9c00c7678fd..5df8dcb8313 100644 --- a/tests/core/test_composition.py +++ b/tests/core/test_composition.py @@ -611,8 +611,8 @@ def test_negative_compositions(self): # test num_atoms c1 = Composition("Mg-1Li", allow_negative=True) assert c1.num_atoms == 2 - assert c1.get_atomic_fraction("Mg") == 0.5 - assert c1.get_atomic_fraction("Li") == 0.5 + assert c1.get_atomic_fraction("Mg") == approx(0.5) + assert c1.get_atomic_fraction("Li") == approx(0.5) assert c1.fractional_composition == Composition("Mg-0.5Li0.5", allow_negative=True) # test copy @@ -622,7 +622,7 @@ def test_negative_compositions(self): c1 = Composition({"Mg": 1, "Mg2+": -1}, allow_negative=True) assert c1.num_atoms == 2 assert c1.element_composition == Composition("Mg-1", allow_negative=True) - assert c1.average_electroneg == 0.655 + assert c1.average_electroneg == approx(0.655) def test_special_formulas(self): special_formulas = { diff --git a/tests/core/test_interface.py b/tests/core/test_interface.py index c2563cd2a7a..6bc9601a6a9 100644 --- a/tests/core/test_interface.py +++ b/tests/core/test_interface.py @@ -343,9 +343,9 @@ def test_basic_props(self): assert len(interface.film_indices) == 36 assert len(interface.film_sites) == len(interface.film_indices) assert len(interface.substrate_sites) == len(interface.substrate_indices) - assert interface.gap == 2.0 + assert interface.gap == approx(2) assert_allclose(interface.in_plane_offset, [0, 0]) - assert interface.vacuum_over_film == 20.0 + assert interface.vacuum_over_film == approx(20) assert interface.film_termination == "O2_P6/mmm_4" assert interface.substrate_termination == "Si_P6/mmm_7" assert interface.film_layers == 6 diff --git a/tests/core/test_lattice.py b/tests/core/test_lattice.py index 89a79e6330c..26061357334 100644 --- a/tests/core/test_lattice.py +++ b/tests/core/test_lattice.py @@ -150,14 +150,14 @@ def test_static_methods(self): def test_attributes(self): """Docstring for test_attributes.""" lattice = Lattice.cubic(10.0) - assert lattice.a == 10.0 - assert lattice.b == 10.0 - assert lattice.c == 10.0 - assert lattice.volume == 1000.0 + assert lattice.a == approx(10) + assert lattice.b == approx(10) + assert lattice.c == approx(10) + assert lattice.volume == approx(1000) xyz = lattice.get_cartesian_coords([0.25, 0.35, 0.45]) - assert xyz[0] == 2.5 - assert xyz[1] == 3.5 - assert xyz[2] == 4.5 + assert xyz[0] == approx(2.5) + assert xyz[1] == approx(3.5) + assert xyz[2] == approx(4.5) def test_lattice_matrices(self): """If alpha == 90 and beta == 90, two matrices are identical.""" @@ -380,7 +380,7 @@ def test_get_wigner_seitz_cell(self): ws_cell = Lattice(np.diag([10, 5, 1])).get_wigner_seitz_cell() assert len(ws_cell) == 6 for vec in ws_cell[3]: - assert [abs(i) for i in vec] == [5.0, 2.5, 0.5] + assert_allclose([abs(i) for i in vec], [5.0, 2.5, 0.5]) def test_dot_and_norm(self): frac_basis = np.eye(3) diff --git a/tests/core/test_operations.py b/tests/core/test_operations.py index 1d775b09b92..db8a16ecec6 100644 --- a/tests/core/test_operations.py +++ b/tests/core/test_operations.py @@ -2,6 +2,7 @@ import numpy as np from numpy.testing import assert_allclose +from pytest import approx from pymatgen.core.operations import MagSymmOp, SymmOp from pymatgen.electronic_structure.core import Magmom @@ -302,5 +303,5 @@ def test_inverse(self): magop = MagSymmOp.from_symmop(op, -1) assert magop.time_reversal == -1 - assert magop.tol == 0.02 + assert magop.tol == approx(0.02) assert_allclose(magop.inverse.affine_matrix, np.linalg.inv(magop.affine_matrix)) diff --git a/tests/core/test_periodic_table.py b/tests/core/test_periodic_table.py index a4a696a4f56..4fff86ce67a 100644 --- a/tests/core/test_periodic_table.py +++ b/tests/core/test_periodic_table.py @@ -346,18 +346,18 @@ def test_deepcopy(self): def test_radii(self): el = Element.Pd - assert el.atomic_radius == 1.40 - assert el.atomic_radius_calculated == 1.69 - assert el.van_der_waals_radius == 2.10 + assert el.atomic_radius == approx(1.40) + assert el.atomic_radius_calculated == approx(1.69) + assert el.van_der_waals_radius == approx(2.10) def test_data(self): - assert Element.Pd.data["Atomic radius"] == 1.4 + assert Element.Pd.data["Atomic radius"] == approx(1.4) al = Element.Al val = al.thermal_conductivity assert val == 235 assert str(val.unit) == "W K^-1 m^-1" val = al.electrical_resistivity - assert val == 2.7e-08 + assert val == approx(2.7e-08) assert str(val.unit) == "m ohm" def test_sort(self): @@ -406,8 +406,8 @@ def test_init(self): assert Species("O0+", spin=2) == Species("O", 0, spin=2) def test_ionic_radius(self): - assert self.specie2.ionic_radius == 78.5 / 100 - assert self.specie3.ionic_radius == 92 / 100 + assert self.specie2.ionic_radius == approx(78.5 / 100) + assert self.specie3.ionic_radius == approx(92 / 100) assert Species("Mn", 4).ionic_radius == approx(0.67) def test_eq(self): @@ -471,18 +471,18 @@ def test_get_crystal_field_spin(self): assert spin == 2 def test_get_nmr_mom(self): - assert Species("H").get_nmr_quadrupole_moment() == 2.860 - assert Species("Li").get_nmr_quadrupole_moment() == -0.808 - assert Species("Li").get_nmr_quadrupole_moment("Li-7") == -40.1 - assert Species("Si").get_nmr_quadrupole_moment() == 0.0 + assert Species("H").get_nmr_quadrupole_moment() == approx(2.860) + assert Species("Li").get_nmr_quadrupole_moment() == approx(-0.808) + assert Species("Li").get_nmr_quadrupole_moment("Li-7") == approx(-40.1) + assert Species("Si").get_nmr_quadrupole_moment() == approx(0) with pytest.raises(ValueError, match="No quadrupole moment for isotope='Li-109'"): Species("Li").get_nmr_quadrupole_moment("Li-109") def test_get_shannon_radius(self): - assert Species("Li", 1).get_shannon_radius("IV") == 0.59 + assert Species("Li", 1).get_shannon_radius("IV") == approx(0.59) mn2 = Species("Mn", 2) - assert mn2.get_shannon_radius("IV", "High Spin") == 0.66 - assert mn2.get_shannon_radius("V", "High Spin") == 0.75 + assert mn2.get_shannon_radius("IV", "High Spin") == approx(0.66) + assert mn2.get_shannon_radius("V", "High Spin") == approx(0.75) with pytest.warns( UserWarning, @@ -491,12 +491,12 @@ def test_get_shannon_radius(self): ) as warns: radius = mn2.get_shannon_radius("V") assert len(warns) == 1 - assert radius == 0.75 + assert radius == approx(0.75) - assert mn2.get_shannon_radius("VI", "Low Spin") == 0.67 - assert mn2.get_shannon_radius("VI", "High Spin") == 0.83 - assert mn2.get_shannon_radius("VII", "High Spin") == 0.9 - assert mn2.get_shannon_radius("VIII") == 0.96 + assert mn2.get_shannon_radius("VI", "Low Spin") == approx(0.67) + assert mn2.get_shannon_radius("VI", "High Spin") == approx(0.83) + assert mn2.get_shannon_radius("VII", "High Spin") == approx(0.9) + assert mn2.get_shannon_radius("VIII") == approx(0.96) def test_sort(self): els = map(get_el_sp, ["N3-", "Si4+", "Si3+"]) @@ -548,7 +548,7 @@ def test_stringify(self): def test_symbol_oxi_state_str(symbol_oxi, expected_element, expected_oxi_state): species = Species(symbol_oxi) assert species._el.symbol == expected_element - assert species._oxi_state == pytest.approx(expected_oxi_state, rel=1.0e-6) + assert species._oxi_state == approx(expected_oxi_state, rel=1.0e-6) def test_symbol_oxi_state_str_raises(): diff --git a/tests/core/test_sites.py b/tests/core/test_sites.py index 28fb7b07e4c..96106f4b650 100644 --- a/tests/core/test_sites.py +++ b/tests/core/test_sites.py @@ -30,8 +30,8 @@ def test_properties(self): with pytest.raises(AttributeError, match="attr='specie' not found on Site"): _ = self.disordered_site.specie assert isinstance(self.ordered_site.specie, Element) - assert self.propertied_site.properties["magmom"] == 5.1 - assert self.propertied_site.properties["charge"] == 4.2 + assert self.propertied_site.properties["magmom"] == approx(5.1) + assert self.propertied_site.properties["charge"] == approx(4.2) def test_as_from_dict(self): dct = self.disordered_site.as_dict() @@ -40,12 +40,12 @@ def test_as_from_dict(self): assert site != self.ordered_site dct = self.propertied_site.as_dict() site = Site.from_dict(dct) - assert site.properties["magmom"] == 5.1 - assert site.properties["charge"] == 4.2 + assert site.properties["magmom"] == approx(5.1) + assert site.properties["charge"] == approx(4.2) dct = self.propertied_magmom_vec_site.as_dict() site = Site.from_dict(dct) assert site.properties["magmom"] == Magmom([2.6, 2.6, 3.5]) - assert site.properties["charge"] == 4.2 + assert site.properties["charge"] == approx(4.2) dct = self.dummy_site.as_dict() site = Site.from_dict(dct) assert site.species == self.dummy_site.species @@ -72,8 +72,8 @@ def test_setters(self): assert self.disordered_site.species == Composition("Cu") self.disordered_site.x = 1.25 self.disordered_site.y = 1.35 - assert self.disordered_site.coords[0] == 1.25 - assert self.disordered_site.coords[1] == 1.35 + assert self.disordered_site.coords[0] == approx(1.25) + assert self.disordered_site.coords[1] == approx(1.35) with pytest.raises(ValueError, match="Species occupancies sum to more than 1"): self.disordered_site.species = {"Cu": 0.5, "Gd": 0.6} @@ -97,17 +97,17 @@ def setUp(self): def test_properties(self): """Test the properties for a site.""" - assert self.site.a == 0.25 - assert self.site.b == 0.35 - assert self.site.c == 0.45 - assert self.site.x == 2.5 - assert self.site.y == 3.5 - assert self.site.z == 4.5 + assert self.site.a == approx(0.25) + assert self.site.b == approx(0.35) + assert self.site.c == approx(0.45) + assert self.site.x == approx(2.5) + assert self.site.y == approx(3.5) + assert self.site.z == approx(4.5) assert self.site.is_ordered assert self.site.label == "Fe" assert not self.site2.is_ordered - assert self.propertied_site.properties["magmom"] == 5.1 - assert self.propertied_site.properties["charge"] == 4.2 + assert self.propertied_site.properties["magmom"] == approx(5.1) + assert self.propertied_site.properties["charge"] == approx(4.2) assert self.labeled_site.label == "site label" def test_distance(self): @@ -225,12 +225,12 @@ def test_setters(self): assert site.species == Composition("Cu") site.x = 1.25 site.y = 1.35 - assert site.coords[0] == 1.25 - assert site.coords[1] == 1.35 - assert site.a == 0.125 - assert site.b == 0.135 + assert site.coords[0] == approx(1.25) + assert site.coords[1] == approx(1.35) + assert site.a == approx(0.125) + assert site.b == approx(0.135) site.lattice = Lattice.cubic(100) - assert site.x == 12.5 + assert site.x == approx(12.5) with pytest.raises(ValueError, match="Species occupancies sum to more than 1"): site.species = {"Cu": 0.5, "Gd": 0.6} diff --git a/tests/core/test_structure.py b/tests/core/test_structure.py index 7cb4abcbaf3..f3589dcfa5c 100644 --- a/tests/core/test_structure.py +++ b/tests/core/test_structure.py @@ -381,14 +381,14 @@ def test_interpolate(self): for inter_struct in interpolated_structs: assert inter_struct is not None, "Interpolation Failed!" assert interpolated_structs[0].lattice == inter_struct.lattice - assert_array_equal(interpolated_structs[1][1].frac_coords, [0.725, 0.5, 0.725]) + assert_allclose(interpolated_structs[1][1].frac_coords, [0.725, 0.5, 0.725]) # test ximages interpolated_structs = struct.interpolate(struct2, nimages=np.linspace(0.0, 1.0, 3)) for inter_struct in interpolated_structs: assert inter_struct is not None, "Interpolation Failed!" assert interpolated_structs[0].lattice == inter_struct.lattice - assert_array_equal(interpolated_structs[1][1].frac_coords, [0.625, 0.5, 0.625]) + assert_allclose(interpolated_structs[1][1].frac_coords, [0.625, 0.5, 0.625]) bad_lattice = np.eye(3) struct2 = IStructure(bad_lattice, ["Si"] * 2, coords2) @@ -452,30 +452,30 @@ def test_interpolate(self): for inter_struct in interpolated_structs: assert inter_struct is not None, "Interpolation Failed!" assert interpolated_structs[0].lattice == inter_struct.lattice - assert_array_equal(interpolated_structs[0][1].frac_coords, [0.75, 0.5, 0.75]) - assert_array_equal(interpolated_structs[10][1].frac_coords, [0.5, 0.5, 0.5]) - assert_array_equal(interpolated_structs[20][1].frac_coords, [0.25, 0.5, 0.25]) + assert_allclose(interpolated_structs[0][1].frac_coords, [0.75, 0.5, 0.75]) + assert_allclose(interpolated_structs[10][1].frac_coords, [0.5, 0.5, 0.5]) + assert_allclose(interpolated_structs[20][1].frac_coords, [0.25, 0.5, 0.25]) # testing large negative values interpolated_structs = struct.interpolate(struct2, 20, end_amplitude=-2) for inter_struct in interpolated_structs: assert inter_struct is not None, "Interpolation Failed!" assert interpolated_structs[0].lattice == inter_struct.lattice - assert_array_equal(interpolated_structs[0][1].frac_coords, [0.75, 0.5, 0.75]) - assert_array_equal(interpolated_structs[10][1].frac_coords, [1.0, 0.5, 1.0]) - assert_array_equal(interpolated_structs[20][1].frac_coords, [1.25, 0.5, 1.25]) + assert_allclose(interpolated_structs[0][1].frac_coords, [0.75, 0.5, 0.75]) + assert_allclose(interpolated_structs[10][1].frac_coords, [1.0, 0.5, 1.0]) + assert_allclose(interpolated_structs[20][1].frac_coords, [1.25, 0.5, 1.25]) # testing partial interpolation interpolated_structs = struct.interpolate(struct2, 5, end_amplitude=-0.5) for inter_struct in interpolated_structs: assert inter_struct is not None, "Interpolation Failed!" assert interpolated_structs[0].lattice == inter_struct.lattice - assert_array_equal(interpolated_structs[0][1].frac_coords, [0.75, 0.5, 0.75]) - assert_array_equal(interpolated_structs[5][1].frac_coords, [0.875, 0.5, 0.875]) + assert_allclose(interpolated_structs[0][1].frac_coords, [0.75, 0.5, 0.75]) + assert_allclose(interpolated_structs[5][1].frac_coords, [0.875, 0.5, 0.875]) # testing end_amplitude=0 interpolated_structs = struct.interpolate(struct2, 5, end_amplitude=0) for inter_struct in interpolated_structs: assert inter_struct is not None, "Interpolation Failed!" assert interpolated_structs[0].lattice == inter_struct.lattice - assert_array_equal(inter_struct[1].frac_coords, [0.75, 0.5, 0.75]) + assert_allclose(inter_struct[1].frac_coords, [0.75, 0.5, 0.75]) def test_interpolate_lattice(self): coords = [[0, 0, 0], [0.75, 0.5, 0.75]] @@ -521,8 +521,8 @@ def test_interpolate_lattice(self): # Assert that volume is monotonic (should be shrinking for negative end_amplitude) assert int_s[1].volume <= struct.volume # Assert that coordinate shift is reversed - assert_array_equal(int_s[1][1].frac_coords, [0.875, 0.5, 0.875]) - assert_array_equal(int_s[2][1].frac_coords, [1.0, 0.5, 1.0]) + assert_allclose(int_s[1][1].frac_coords, [0.875, 0.5, 0.875]) + assert_allclose(int_s[2][1].frac_coords, [1.0, 0.5, 1.0]) def test_interpolate_lattice_rotation(self): l1 = Lattice(np.eye(3)) @@ -586,7 +586,7 @@ def test_primitive_with_constrained_lattice(self): struct = Structure.from_file(f"{TEST_FILES_DIR}/core/structure/Fe310.json.gz") constraints = {"a": 2.83133, "b": 4.69523, "gamma": 107.54840} prim_struct = struct.get_primitive_structure(constrain_latt=constraints) - assert {key: getattr(prim_struct.lattice, key) for key in constraints} == pytest.approx(constraints) + assert {key: getattr(prim_struct.lattice, key) for key in constraints} == approx(constraints) def test_primitive_with_similar_constraints(self): struct = Structure.from_file(f"{TEST_FILES_DIR}/core/structure/Fe310.json.gz") @@ -789,7 +789,7 @@ def test_get_symmetric_neighbor_list(self): struct = Structure.from_spacegroup(100, [[1, 0, 0], [0, 1, 0], [0, 0, 2]], ["Fe"], [[0.0, 0.0, 0.0]]) c_indices, p_indices, offsets, distances, s_indices, sym_ops = struct.get_symmetric_neighbor_list(0.8, sg=100) assert len(c_indices) == len(p_indices) == len(offsets) == len(distances) == 8 - assert c_indices == pytest.approx([0, 1, 1, 1, 0, 0, 0, 0]) + assert_array_equal(c_indices, [0, 1, 1, 1, 0, 0, 0, 0]) assert len(np.unique(s_indices)) == 1 assert s_indices[0] == 0 assert all(~np.isnan(s_indices)) @@ -1175,10 +1175,10 @@ def test_add_remove_site_property(self): struct = self.struct returned = struct.add_site_property("charge", [4.1, -5]) assert returned is struct - assert struct[0].charge == 4.1 - assert struct[1].charge == -5 + assert struct[0].charge == approx(4.1) + assert struct[1].charge == approx(-5) struct.add_site_property("magmom", [3, 2]) - assert struct[0].charge == 4.1 + assert struct[0].charge == approx(4.1) assert struct[0].magmom == 3 returned = struct.remove_site_property("magmom") assert returned is struct @@ -1351,10 +1351,13 @@ def test_apply_strain(self): initial_coord = struct[1].coords returned = struct.apply_strain(0.01) assert returned is struct - assert approx(struct.lattice.abc) == ( - 3.8785999130369997, - 3.878600984287687, - 3.8785999130549516, + assert_allclose( + struct.lattice.abc, + ( + 3.8785999130369997, + 3.878600984287687, + 3.8785999130549516, + ), ) assert_allclose(struct[1].coords, initial_coord * 1.01) a1, b1, c1 = struct.lattice.abc @@ -1678,7 +1681,7 @@ def test_merge_sites(self): navs2.insert(0, "Na", coords[0], properties={"prop1": 100.0}) navs2.merge_sites(mode="a") assert len(navs2) == 12 - assert 51.5 in [itr.properties["prop1"] for itr in navs2] + assert any(itr.properties["prop1"] == approx(51.5) for itr in navs2) def test_properties(self): assert self.struct.num_sites == len(self.struct) @@ -2122,8 +2125,8 @@ def test_site_properties(self): self.coords, site_properties={"magmom": [0.5, -0.5, 1, 2, 3]}, ) - assert propertied_mol[0].magmom == 0.5 - assert propertied_mol[1].magmom == -0.5 + assert propertied_mol[0].magmom == approx(0.5) + assert propertied_mol[1].magmom == approx(-0.5) def test_chemical_system(self): assert self.mol.chemical_system == "C-H" @@ -2280,10 +2283,10 @@ def test_as_from_dict(self): properties={"test_properties": "test"}, ) dct = propertied_mol.as_dict() - assert dct["sites"][0]["properties"]["magmom"] == 0.5 + assert dct["sites"][0]["properties"]["magmom"] == approx(0.5) mol = Molecule.from_dict(dct) assert propertied_mol == mol - assert mol[0].magmom == 0.5 + assert mol[0].magmom == approx(0.5) assert mol.formula == "H4 C1" assert mol.charge == 1 assert mol.properties == {"test_properties": "test"} @@ -2410,11 +2413,11 @@ def test_replace_species(self): def test_add_remove_site_property(self): returned = self.mol.add_site_property("charge", [4.1, -2, -2, -2, -2]) assert returned is self.mol - assert self.mol[0].charge == 4.1 - assert self.mol[1].charge == -2 + assert self.mol[0].charge == approx(4.1) + assert self.mol[1].charge == approx(-2) self.mol.add_site_property("magmom", [3, 2, 2, 2, 2]) - assert self.mol[0].charge == 4.1 + assert self.mol[0].charge == approx(4.1) assert self.mol[0].magmom == 3 returned = self.mol.remove_site_property("magmom") assert returned is self.mol diff --git a/tests/core/test_tensors.py b/tests/core/test_tensors.py index 1c840dcfa2b..2046607be4b 100644 --- a/tests/core/test_tensors.py +++ b/tests/core/test_tensors.py @@ -287,7 +287,7 @@ def test_tensor_mapping(self): tkey = Tensor.from_values_indices([0.01], [(0, 0)]) tval = reduced[tkey] for tens_1, tens_2 in zip(tval, reduced[tbs[0]], strict=True): - assert approx(tens_1) == tens_2 + assert tens_1 == approx(tens_2) # Test set reduced[tkey] = "test_val" assert reduced[tkey] == "test_val" @@ -517,8 +517,8 @@ def test_properties(self): # determinant assert self.rand_sqtensor.det == np.linalg.det(self.rand_sqtensor) - assert self.non_invertible.det == 0.0 - assert self.non_symm.det == 0.009 + assert self.non_invertible.det == approx(0) + assert self.non_symm.det == approx(0.009) # symmetrized assert self.rand_sqtensor.symmetrized == approx(0.5 * (self.rand_sqtensor + self.rand_sqtensor.trans)) diff --git a/tests/core/test_units.py b/tests/core/test_units.py index 88e06d92517..c0e2f4ccd46 100644 --- a/tests/core/test_units.py +++ b/tests/core/test_units.py @@ -66,7 +66,7 @@ def test_energy(self): d = Energy(1, "Ha") assert a + d == approx(28.311386245987997) assert a - d == approx(-26.111386245987994) - assert a + 1 == 2.1 + assert a + 1 == approx(2.1) assert str(a / d) == "1.1 eV Ha^-1" e_kj = Energy(1, "kJ") @@ -82,7 +82,7 @@ def test_time(self): b = a * 3 assert float(b) == approx(60) assert str(b.unit) == "h" - assert float(3 * a) == 60.0 + assert float(3 * a) == approx(60.0) a = Time(0.5, "d") assert float(a.to("s")) == approx(3600 * 24 * 0.5) @@ -154,8 +154,8 @@ def func5(): j_out = func5() assert j_out.unit == Unit("kg") - assert j_out[0] == 0.005 - assert j_out[1] == 0.01 + assert j_out[0] == approx(0.005) + assert j_out[1] == approx(0.01) def test_compound_operations(self): earth_acc = 9.81 * Length(1, "m") / (Time(1, "s") ** 2) @@ -207,7 +207,7 @@ def test_energy(self): e2_in_ha = EnergyArray(1, "Ha") assert (e_in_ev + e2_in_ha) == approx(28.311386245987997) assert (e_in_ev - e2_in_ha) == approx(-26.111386245987994) - assert float(e_in_ev + 1) == 2.1 + assert float(e_in_ev + 1) == approx(2.1) def test_time(self): """Similar to FloatWithUnitTest.test_time. @@ -290,7 +290,7 @@ def test_factors(self): def test_as_base_units(self): pressure_arr = ArrayWithUnit([5, 10], "MPa") - assert_array_equal(ArrayWithUnit([5000000, 10000000], "Pa"), pressure_arr.as_base_units) + assert_array_equal(ArrayWithUnit([5e6, 1e7], "Pa"), pressure_arr.as_base_units) class TestDataPersistence(PymatgenTest): diff --git a/tests/electronic_structure/test_bandstructure.py b/tests/electronic_structure/test_bandstructure.py index c5de50385ce..da27e627f02 100644 --- a/tests/electronic_structure/test_bandstructure.py +++ b/tests/electronic_structure/test_bandstructure.py @@ -38,12 +38,12 @@ def test_eq(self): assert self.kpoint != Kpoint([0.1, 0.4, -0.5], Lattice.cubic(20.0), label="X") def test_properties(self): - assert list(self.kpoint.frac_coords) == [0.1, 0.4, -0.5] - assert self.kpoint.a == 0.1 - assert self.kpoint.b == 0.4 - assert self.kpoint.c == -0.5 + assert_allclose(self.kpoint.frac_coords, [0.1, 0.4, -0.5]) + assert self.kpoint.a == approx(0.1) + assert self.kpoint.b == approx(0.4) + assert self.kpoint.c == approx(-0.5) assert self.lattice == Lattice.cubic(10.0) - assert list(self.kpoint.cart_coords) == [1.0, 4.0, -5.0] + assert_allclose(self.kpoint.cart_coords, [1.0, 4.0, -5.0]) assert self.kpoint.label == "X" def test_as_dict(self): @@ -51,20 +51,20 @@ def test_as_dict(self): assert isinstance(self.kpoint.as_dict()["ccoords"], list) assert not isinstance(self.kpoint.as_dict()["fcoords"][0], np.float64) assert not isinstance(self.kpoint.as_dict()["ccoords"][0], np.float64) - assert self.kpoint.as_dict()["fcoords"] == [0.1, 0.4, -0.5] - assert self.kpoint.as_dict()["ccoords"] == [1.0, 4.0, -5.0] + assert_allclose(self.kpoint.as_dict()["fcoords"], [0.1, 0.4, -0.5]) + assert_allclose(self.kpoint.as_dict()["ccoords"], [1.0, 4.0, -5.0]) def test_from_dict(self): dct = self.kpoint.as_dict() kpoint = Kpoint.from_dict(dct) - assert list(kpoint.frac_coords) == [0.1, 0.4, -0.5] - assert kpoint.a == 0.1 - assert kpoint.b == 0.4 - assert kpoint.c == -0.5 + assert_allclose(kpoint.frac_coords, [0.1, 0.4, -0.5]) + assert kpoint.a == approx(0.1) + assert kpoint.b == approx(0.4) + assert kpoint.c == approx(-0.5) assert kpoint.lattice == Lattice.cubic(10.0) - assert list(kpoint.cart_coords) == [1.0, 4.0, -5.0] + assert_allclose(kpoint.cart_coords, [1.0, 4.0, -5.0]) assert kpoint.label == "X" @@ -103,7 +103,7 @@ def test_basic(self): def test_properties(self): self.one_kpoint = self.bs2.kpoints[31] - assert list(self.one_kpoint.frac_coords) == [0.5, 0.25, 0.75] + assert_allclose(self.one_kpoint.frac_coords, [0.5, 0.25, 0.75]) assert self.one_kpoint.cart_coords == approx([0.64918757, 1.29837513, 0.0]) assert self.one_kpoint.label == "W" @@ -114,7 +114,7 @@ def test_get_branch(self): def test_get_direct_band_gap_dict(self): direct_dict = self.bs_diff_spins.get_direct_band_gap_dict() - assert direct_dict[Spin.down]["value"] == 4.5365 + assert direct_dict[Spin.down]["value"] == approx(4.5365) for bs in [self.bs2, self.bs_spin]: dg_dict = bs.get_direct_band_gap_dict() @@ -144,18 +144,18 @@ def test_get_cbm(self): assert cbm["energy"] == approx(5.8709), "wrong CBM energy" assert cbm["band_index"][Spin.up][0] == 8, "wrong CBM band index" assert cbm["kpoint_index"][0] == 15, "wrong CBM kpoint index" - assert cbm["kpoint"].frac_coords[0] == 0.5, "wrong CBM kpoint frac coords" - assert cbm["kpoint"].frac_coords[1] == 0.0, "wrong CBM kpoint frac coords" - assert cbm["kpoint"].frac_coords[2] == 0.5, "wrong CBM kpoint frac coords" + assert cbm["kpoint"].frac_coords[0] == approx(0.5), "wrong CBM kpoint frac coords" + assert cbm["kpoint"].frac_coords[1] == approx(0.0), "wrong CBM kpoint frac coords" + assert cbm["kpoint"].frac_coords[2] == approx(0.5), "wrong CBM kpoint frac coords" assert cbm["kpoint"].label == "X", "wrong CBM kpoint label" cbm_spin = self.bs_spin.get_cbm() assert cbm_spin["energy"] == approx(8.0458), "wrong CBM energy" assert cbm_spin["band_index"][Spin.up][0] == 12, "wrong CBM band index" assert len(cbm_spin["band_index"][Spin.down]) == 0, "wrong CBM band index" assert cbm_spin["kpoint_index"][0] == 0, "wrong CBM kpoint index" - assert cbm_spin["kpoint"].frac_coords[0] == 0.0, "wrong CBM kpoint frac coords" - assert cbm_spin["kpoint"].frac_coords[1] == 0.0, "wrong CBM kpoint frac coords" - assert cbm_spin["kpoint"].frac_coords[2] == 0.0, "wrong CBM kpoint frac coords" + assert cbm_spin["kpoint"].frac_coords[0] == approx(0.0), "wrong CBM kpoint frac coords" + assert cbm_spin["kpoint"].frac_coords[1] == approx(0.0), "wrong CBM kpoint frac coords" + assert cbm_spin["kpoint"].frac_coords[2] == approx(0.0), "wrong CBM kpoint frac coords" assert cbm_spin["kpoint"].label == "\\Gamma", "wrong CBM kpoint label" def test_get_vbm(self): @@ -164,9 +164,9 @@ def test_get_vbm(self): assert len(vbm["band_index"][Spin.up]) == 3, "wrong VBM number of bands" assert vbm["band_index"][Spin.up][0] == 5, "wrong VBM band index" assert vbm["kpoint_index"][0] == 0, "wrong VBM kpoint index" - assert vbm["kpoint"].frac_coords[0] == 0.0, "wrong VBM kpoint frac coords" - assert vbm["kpoint"].frac_coords[1] == 0.0, "wrong VBM kpoint frac coords" - assert vbm["kpoint"].frac_coords[2] == 0.0, "wrong VBM kpoint frac coords" + assert vbm["kpoint"].frac_coords[0] == approx(0.0), "wrong VBM kpoint frac coords" + assert vbm["kpoint"].frac_coords[1] == approx(0.0), "wrong VBM kpoint frac coords" + assert vbm["kpoint"].frac_coords[2] == approx(0.0), "wrong VBM kpoint frac coords" assert vbm["kpoint"].label == "\\Gamma", "wrong VBM kpoint label" vbm_spin = self.bs_spin.get_vbm() assert vbm_spin["energy"] == approx(5.731), "wrong VBM energy" @@ -174,9 +174,9 @@ def test_get_vbm(self): assert len(vbm_spin["band_index"][Spin.down]) == 0, "wrong VBM number of bands" assert vbm_spin["band_index"][Spin.up][0] == 10, "wrong VBM band index" assert vbm_spin["kpoint_index"][0] == 79, "wrong VBM kpoint index" - assert vbm_spin["kpoint"].frac_coords[0] == 0.5, "wrong VBM kpoint frac coords" - assert vbm_spin["kpoint"].frac_coords[1] == 0.5, "wrong VBM kpoint frac coords" - assert vbm_spin["kpoint"].frac_coords[2] == 0.5, "wrong VBM kpoint frac coords" + assert vbm_spin["kpoint"].frac_coords[0] == approx(0.5), "wrong VBM kpoint frac coords" + assert vbm_spin["kpoint"].frac_coords[1] == approx(0.5), "wrong VBM kpoint frac coords" + assert vbm_spin["kpoint"].frac_coords[2] == approx(0.5), "wrong VBM kpoint frac coords" assert vbm_spin["kpoint"].label == "L", "wrong VBM kpoint label" def test_get_band_gap(self): @@ -235,7 +235,7 @@ def test_old_format_load(self): with open(f"{TEST_DIR}/bs_ZnS_old.json") as file: dct = json.load(file) bs_old = BandStructureSymmLine.from_dict(dct) - assert bs_old.get_projection_on_elements()[Spin.up][0][0]["Zn"] == 0.0971 + assert bs_old.get_projection_on_elements()[Spin.up][0][0]["Zn"] == approx(0.0971) def test_apply_scissor_insulator(self): # test applying a scissor operator to a metal @@ -400,18 +400,18 @@ def test_get_cbm(self): assert cbm["energy"] == approx(6.3037028799999995), "wrong CBM energy" assert cbm["band_index"][Spin.up][0] == 24, "wrong CBM band index" assert cbm["kpoint_index"][0] == 0, "wrong CBM kpoint index" - assert cbm["kpoint"].frac_coords[0] == 0.0, "wrong CBM kpoint frac coords" - assert cbm["kpoint"].frac_coords[1] == 0.0, "wrong CBM kpoint frac coords" - assert cbm["kpoint"].frac_coords[2] == 0.0, "wrong CBM kpoint frac coords" + assert cbm["kpoint"].frac_coords[0] == approx(0.0), "wrong CBM kpoint frac coords" + assert cbm["kpoint"].frac_coords[1] == approx(0.0), "wrong CBM kpoint frac coords" + assert cbm["kpoint"].frac_coords[2] == approx(0.0), "wrong CBM kpoint frac coords" assert cbm["kpoint"].label == "\\Gamma", "wrong CBM kpoint label" cbm_spin = self.bs_spin.get_cbm() assert cbm_spin["energy"] == approx(6.30370274), "wrong CBM energy" assert cbm_spin["band_index"][Spin.up][0] == 24, "wrong CBM band index" assert len(cbm_spin["band_index"][Spin.down]) == 1, "wrong CBM band index" assert cbm_spin["kpoint_index"][0] == 0, "wrong CBM kpoint index" - assert cbm_spin["kpoint"].frac_coords[0] == 0.0, "wrong CBM kpoint frac coords" - assert cbm_spin["kpoint"].frac_coords[1] == 0.0, "wrong CBM kpoint frac coords" - assert cbm_spin["kpoint"].frac_coords[2] == 0.0, "wrong CBM kpoint frac coords" + assert cbm_spin["kpoint"].frac_coords[0] == approx(0.0), "wrong CBM kpoint frac coords" + assert cbm_spin["kpoint"].frac_coords[1] == approx(0.0), "wrong CBM kpoint frac coords" + assert cbm_spin["kpoint"].frac_coords[2] == approx(0.0), "wrong CBM kpoint frac coords" assert cbm_spin["kpoint"].label == "\\Gamma", "wrong CBM kpoint label" def test_get_vbm(self): diff --git a/tests/electronic_structure/test_boltztrap.py b/tests/electronic_structure/test_boltztrap.py index a5983320da9..924c2c21379 100644 --- a/tests/electronic_structure/test_boltztrap.py +++ b/tests/electronic_structure/test_boltztrap.py @@ -222,9 +222,9 @@ def test_check_acc_bzt_bands(self): sbs = loadfn(f"{TEST_DIR}/dft_bs_sym_line.json") sbs_bzt = self.bz_bands.get_symm_bands(structure, -5.25204548) corr, werr_vbm, werr_cbm, warn = BoltztrapAnalyzer.check_acc_bzt_bands(sbs_bzt, sbs) - assert corr[2] == 9.16851750e-05 - assert werr_vbm["K-H"] == 0.18260273521047862 - assert werr_cbm["M-K"] == 0.071552669981356981 + assert corr[2] == approx(9.16851750e-05) + assert werr_vbm["K-H"] == approx(0.18260273521047862) + assert werr_cbm["M-K"] == approx(0.071552669981356981) assert not warn def test_get_complete_dos(self): diff --git a/tests/electronic_structure/test_boltztrap2.py b/tests/electronic_structure/test_boltztrap2.py index cdb75a24532..eaaa7b7201b 100644 --- a/tests/electronic_structure/test_boltztrap2.py +++ b/tests/electronic_structure/test_boltztrap2.py @@ -61,8 +61,8 @@ def test_properties(self): assert self.loader.is_spin_polarized is False assert self.loader.fermi == approx(0.185266535678, abs=1e-5) assert self.loader.structure.lattice.a == approx(4.64303565932548, abs=1e-5) - assert self.loader.nelect_all == 20.0 - assert self.loader_sp.nelect_all == 10.0 + assert self.loader.nelect_all == approx(20.0) + assert self.loader_sp.nelect_all == approx(10.0) assert self.loader.ebands_all.shape == (20, 120) assert self.loader.ebands_all[10, 100] == approx(0.2708057, abs=1e-5) @@ -151,15 +151,15 @@ def test_properties(self): assert self.bztInterp.cband.shape == (6, 3, 3, 3, 29791) assert self.bztInterp.eband.shape == (6, 29791) assert self.bztInterp.coeffs.shape == (6, 322) - assert self.bztInterp.data.nelect == 6.0 - assert self.bztInterp.data.nelect_all == 20.0 + assert self.bztInterp.data.nelect == approx(6.0) + assert self.bztInterp.data.nelect_all == approx(20.0) assert self.bztInterp.data.ebands.shape == (6, 120) assert self.bztInterp_sp.cband.shape == (10, 3, 3, 3, 23275) assert self.bztInterp_sp.eband.shape == (10, 23275) assert self.bztInterp_sp.coeffs.shape == (10, 519) - assert self.bztInterp_sp.data.nelect == 6.0 - assert self.bztInterp_sp.data.nelect_all == 10.0 + assert self.bztInterp_sp.data.nelect == approx(6.0) + assert self.bztInterp_sp.data.nelect_all == approx(10.0) assert self.bztInterp_sp.data.ebands.shape == (10, 198) def test_get_band_structure(self): diff --git a/tests/electronic_structure/test_cohp.py b/tests/electronic_structure/test_cohp.py index 16f0ce2ca34..b286efcb214 100644 --- a/tests/electronic_structure/test_cohp.py +++ b/tests/electronic_structure/test_cohp.py @@ -4,7 +4,7 @@ from unittest import TestCase import pytest -from numpy.testing import assert_allclose, assert_array_equal +from numpy.testing import assert_allclose from pytest import approx from pymatgen.electronic_structure.cohp import ( @@ -41,8 +41,8 @@ def test_as_from_dict(self): def test_attributes(self): assert len(self.cohp.energies) == 301 - assert self.cohp.efermi == 9.75576 - assert self.coop.efermi == 5.90043 + assert self.cohp.efermi == approx(9.75576) + assert self.coop.efermi == approx(5.90043) assert not self.cohp.are_coops assert self.coop.are_coops assert not self.coop.are_cobis @@ -136,28 +136,28 @@ def test_attributes(self): assert self.icohpvalue_sp.num_bonds == 1 assert self.icohpvalue_sp.are_coops is False assert self.icohpvalue_sp.is_spin_polarized - assert self.icohpvalue.icohp == {Spin.up: -2.0} + assert self.icohpvalue.icohp == approx({Spin.up: -2.0}) # with spin polarization assert self.icohpvalue_sp.num_bonds == 1 assert self.icohpvalue_sp.are_coops is False assert self.icohpvalue_sp.is_spin_polarized - assert self.icohpvalue_sp.icohp == {Spin.up: -1.1, Spin.down: -1.0} + assert self.icohpvalue_sp.icohp == approx({Spin.up: -1.1, Spin.down: -1.0}) def test_icohpvalue(self): # without spin polarization - assert self.icohpvalue.icohpvalue(spin=Spin.up) == -2.0 + assert self.icohpvalue.icohpvalue(spin=Spin.up) == approx(-2.0) # with spin polarization - assert self.icohpvalue_sp.icohpvalue(spin=Spin.up) == -1.1 - assert self.icohpvalue_sp.icohpvalue(spin=Spin.down) == -1.0 + assert self.icohpvalue_sp.icohpvalue(spin=Spin.up) == approx(-1.1) + assert self.icohpvalue_sp.icohpvalue(spin=Spin.down) == approx(-1.0) def test_summed_icohp(self): # without spin polarization - assert self.icohpvalue.summed_icohp == -2.0 + assert self.icohpvalue.summed_icohp == approx(-2.0) # with spin polarization - assert self.icohpvalue_sp.summed_icohp == -2.1 + assert self.icohpvalue_sp.summed_icohp == approx(-2.1) def test_str(self): # without spin polarization @@ -313,50 +313,45 @@ def test_get_icohp_by_label(self): # without spin polarization # ICOHPs - assert self.icohpcollection_KF.get_icohp_by_label("1") == -0.40075 - assert self.icohpcollection_KF.get_icohp_by_label("2") == -0.40074 - assert self.icohpcollection_KF.get_icohp_by_label("3") == -0.40079 - assert self.icohpcollection_KF.get_icohp_by_label("4") == -0.40079 - assert self.icohpcollection_KF.get_icohp_by_label("5") == -0.40074 - assert self.icohpcollection_KF.get_icohp_by_label("6") == -0.40075 + assert self.icohpcollection_KF.get_icohp_by_label("1") == approx(-0.40075) + assert self.icohpcollection_KF.get_icohp_by_label("2") == approx(-0.40074) + assert self.icohpcollection_KF.get_icohp_by_label("3") == approx(-0.40079) + assert self.icohpcollection_KF.get_icohp_by_label("4") == approx(-0.40079) + assert self.icohpcollection_KF.get_icohp_by_label("5") == approx(-0.40074) + assert self.icohpcollection_KF.get_icohp_by_label("6") == approx(-0.40075) # with spin polarization # summed spin # ICOHPs - assert self.icohpcollection_Fe.get_icohp_by_label("1") == -0.10218 - 0.19701 - assert self.icohpcollection_Fe.get_icohp_by_label("2") == -0.28485 - 0.58279 + assert self.icohpcollection_Fe.get_icohp_by_label("1") == approx(-0.10218 - 0.19701) + assert self.icohpcollection_Fe.get_icohp_by_label("2") == approx(-0.28485 - 0.58279) # Spin up # ICOHPs - assert self.icohpcollection_Fe.get_icohp_by_label("1", summed_spin_channels=False) == -0.10218 - assert self.icohpcollection_Fe.get_icohp_by_label("2", summed_spin_channels=False) == -0.28485 + assert self.icohpcollection_Fe.get_icohp_by_label("1", summed_spin_channels=False) == approx(-0.10218) + assert self.icohpcollection_Fe.get_icohp_by_label("2", summed_spin_channels=False) == approx(-0.28485) # Spin down # ICOHPs - assert self.icohpcollection_Fe.get_icohp_by_label("1", summed_spin_channels=False, spin=Spin.down) == -0.19701 - assert self.icohpcollection_Fe.get_icohp_by_label("2", summed_spin_channels=False, spin=Spin.down) == -0.58279 - - # orbitalwise - assert self.icohpcollection_orbitalwise.get_icohp_by_label("1", orbitals="2s-6s") == 0.0494 - assert ( - self.icohpcollection_orbitalwise.get_icohp_by_label( - "1", orbitals="2s-6s", spin=Spin.up, summed_spin_channels=False - ) - == 0.0247 + assert self.icohpcollection_Fe.get_icohp_by_label("1", summed_spin_channels=False, spin=Spin.down) == approx( + -0.19701 ) - assert ( - self.icohpcollection_orbitalwise.get_icohp_by_label( - "1", orbitals="2s-6s", spin=Spin.down, summed_spin_channels=False - ) - == 0.0247 - ) - assert ( - self.icohpcollection_orbitalwise.get_icohp_by_label( - "2", orbitals="2s-5py", spin=Spin.up, summed_spin_channels=False - ) - == 0.5 + assert self.icohpcollection_Fe.get_icohp_by_label("2", summed_spin_channels=False, spin=Spin.down) == approx( + -0.58279 ) + # orbitalwise + assert self.icohpcollection_orbitalwise.get_icohp_by_label("1", orbitals="2s-6s") == approx(0.0494) + assert self.icohpcollection_orbitalwise.get_icohp_by_label( + "1", orbitals="2s-6s", spin=Spin.up, summed_spin_channels=False + ) == approx(0.0247) + assert self.icohpcollection_orbitalwise.get_icohp_by_label( + "1", orbitals="2s-6s", spin=Spin.down, summed_spin_channels=False + ) == approx(0.0247) + assert self.icohpcollection_orbitalwise.get_icohp_by_label( + "2", orbitals="2s-5py", spin=Spin.up, summed_spin_channels=False + ) == approx(0.5) + def test_get_summed_icohp_by_label_list(self): # without spin polarization assert self.icohpcollection_KF.get_summed_icohp_by_label_list( @@ -776,25 +771,29 @@ def test_get_icohp_dict_of_site(self): def test_extremum_icohpvalue(self): # without spin polarization # ICOHPs - assert self.icohpcollection_KF.extremum_icohpvalue() == -0.40079 + assert self.icohpcollection_KF.extremum_icohpvalue() == approx(-0.40079) # ICOOPs - assert self.icoopcollection_KF.extremum_icohpvalue() == 0.02343 + assert self.icoopcollection_KF.extremum_icohpvalue() == approx(0.02343) # with spin polarization # summed spin # ICOHPs - assert self.icohpcollection_Fe.extremum_icohpvalue() == -0.86764 + assert self.icohpcollection_Fe.extremum_icohpvalue() == approx(-0.86764) assert self.icoopcollection_Fe.extremum_icohpvalue() == approx(-0.09842999999999999) # ICOOPs # spin up # ICOHPs - assert self.icohpcollection_Fe.extremum_icohpvalue(summed_spin_channels=False) == -0.28485 + assert self.icohpcollection_Fe.extremum_icohpvalue(summed_spin_channels=False) == approx(-0.28485) # ICOOPs - assert self.icoopcollection_Fe.extremum_icohpvalue(summed_spin_channels=False) == -0.04087 + assert self.icoopcollection_Fe.extremum_icohpvalue(summed_spin_channels=False) == approx(-0.04087) # spin down # ICOHPs - assert self.icohpcollection_Fe.extremum_icohpvalue(summed_spin_channels=False, spin=Spin.down) == -0.58279 + assert self.icohpcollection_Fe.extremum_icohpvalue(summed_spin_channels=False, spin=Spin.down) == approx( + -0.58279 + ) # ICOOPs - assert self.icoopcollection_Fe.extremum_icohpvalue(summed_spin_channels=False, spin=Spin.down) == -0.05756 + assert self.icoopcollection_Fe.extremum_icohpvalue(summed_spin_channels=False, spin=Spin.down) == approx( + -0.05756 + ) class TestCompleteCohp(PymatgenTest): @@ -897,16 +896,16 @@ def test_attributes(self): assert len(self.coop_lobster.energies) == 241 assert len(self.cohp_lobster_forb.energies) == 7 - assert self.cohp_lobster.efermi == 9.75576 - assert self.cohp_lmto.efermi == -2.3433 - assert self.coop_lobster.efermi == 5.90043 - assert self.cohp_lobster_forb.efermi == 4.12875 + assert self.cohp_lobster.efermi == approx(9.75576) + assert self.cohp_lmto.efermi == approx(-2.3433) + assert self.coop_lobster.efermi == approx(5.90043) + assert self.cohp_lobster_forb.efermi == approx(4.12875) assert self.cobi.are_cobis assert not self.cobi.are_coops - assert self.cohp_lobster_forb.cohp[Spin.up][0] == 0.00000 - assert self.cohp_lobster_forb.icohp[Spin.up][0] == -0.09040 + assert self.cohp_lobster_forb.cohp[Spin.up][0] == approx(0.00000) + assert self.cohp_lobster_forb.icohp[Spin.up][0] == approx(-0.09040) def test_average_multi_center_cobi(self): # tests if the averages for a mult-center cobi are computed in the same way as in Lobster @@ -1010,17 +1009,17 @@ def test_icohp_values(self): assert val == icoop_ef def test_get_cohp_by_label(self): - assert self.cohp_orb.get_cohp_by_label("1").energies[0] == -11.7225 - assert self.cohp_orb.get_cohp_by_label("1").energies[5] == -11.47187 + assert self.cohp_orb.get_cohp_by_label("1").energies[0] == approx(-11.7225) + assert self.cohp_orb.get_cohp_by_label("1").energies[5] == approx(-11.47187) assert not self.cohp_orb.get_cohp_by_label("1").are_coops - assert self.cohp_orb.get_cohp_by_label("1").cohp[Spin.up][0] == 0.0 - assert self.cohp_orb.get_cohp_by_label("1").cohp[Spin.up][300] == 0.03392 - assert self.cohp_orb.get_cohp_by_label("average").cohp[Spin.up][230] == -0.08792 - assert self.cohp_orb.get_cohp_by_label("average").energies[230] == -0.19368000000000007 + assert self.cohp_orb.get_cohp_by_label("1").cohp[Spin.up][0] == approx(0.0) + assert self.cohp_orb.get_cohp_by_label("1").cohp[Spin.up][300] == approx(0.03392) + assert self.cohp_orb.get_cohp_by_label("average").cohp[Spin.up][230] == approx(-0.08792) + assert self.cohp_orb.get_cohp_by_label("average").energies[230] == approx(-0.19368000000000007) assert not self.cohp_orb.get_cohp_by_label("average").are_coops # test methods from super class that could be overwritten - assert self.cohp_orb.get_icohp()[Spin.up][3] == 0.0 - assert self.cohp_orb.get_cohp()[Spin.up][3] == 0.0 + assert self.cohp_orb.get_icohp()[Spin.up][3] == approx(0.0) + assert self.cohp_orb.get_cohp()[Spin.up][3] == approx(0.0) def test_get_cohp_by_label_summed_spin(self): # files without spin polarization @@ -1057,37 +1056,39 @@ def test_get_cohp_by_label_summed_spin(self): assert not self.cohp_lobster_spin_polarized.get_cohp_by_label("1", summed_spin_channels=True).are_coops def test_get_summed_cohp_by_label_list(self): - assert self.cohp_orb.get_summed_cohp_by_label_list(["1"]).energies[0] == -11.7225 - assert self.cohp_orb.get_summed_cohp_by_label_list(["1", "1"]).energies[0] == -11.7225 - assert self.cohp_orb.get_summed_cohp_by_label_list(["1"]).energies[5] == -11.47187 + assert self.cohp_orb.get_summed_cohp_by_label_list(["1"]).energies[0] == approx(-11.7225) + assert self.cohp_orb.get_summed_cohp_by_label_list(["1", "1"]).energies[0] == approx(-11.7225) + assert self.cohp_orb.get_summed_cohp_by_label_list(["1"]).energies[5] == approx(-11.47187) assert not self.cohp_orb.get_summed_cohp_by_label_list(["1"]).are_coops - assert self.cohp_orb.get_summed_cohp_by_label_list(["1"]).cohp[Spin.up][0] == 0.0 - assert self.cohp_orb.get_summed_cohp_by_label_list(["1", "1"]).cohp[Spin.up][0] == 0.0 - assert self.cohp_orb.get_summed_cohp_by_label_list(["1", "1"]).cohp[Spin.up][300] == 0.03392 * 2.0 - assert self.cohp_orb.get_summed_cohp_by_label_list(["1", "1"], divisor=2).cohp[Spin.up][300] == 0.03392 + assert self.cohp_orb.get_summed_cohp_by_label_list(["1"]).cohp[Spin.up][0] == approx(0.0) + assert self.cohp_orb.get_summed_cohp_by_label_list(["1", "1"]).cohp[Spin.up][0] == approx(0.0) + assert self.cohp_orb.get_summed_cohp_by_label_list(["1", "1"]).cohp[Spin.up][300] == approx(0.03392 * 2.0) + assert self.cohp_orb.get_summed_cohp_by_label_list(["1", "1"], divisor=2).cohp[Spin.up][300] == approx(0.03392) def test_get_summed_cohp_by_label_list_summed_spin(self): # files without spin polarization - assert self.cohp_orb.get_summed_cohp_by_label_list(["1"], summed_spin_channels=True).energies[0] == -11.7225 - assert ( - self.cohp_orb.get_summed_cohp_by_label_list(["1", "1"], summed_spin_channels=True).energies[0] == -11.7225 + assert self.cohp_orb.get_summed_cohp_by_label_list(["1"], summed_spin_channels=True).energies[0] == approx( + -11.7225 ) - assert self.cohp_orb.get_summed_cohp_by_label_list(["1"], summed_spin_channels=True).energies[5] == -11.47187 - assert not self.cohp_orb.get_summed_cohp_by_label_list(["1"], summed_spin_channels=True).are_coops - assert self.cohp_orb.get_summed_cohp_by_label_list(["1"], summed_spin_channels=True).cohp[Spin.up][0] == 0.0 - assert ( - self.cohp_orb.get_summed_cohp_by_label_list(["1", "1"], summed_spin_channels=True).cohp[Spin.up][0] == 0.0 + assert self.cohp_orb.get_summed_cohp_by_label_list(["1", "1"], summed_spin_channels=True).energies[0] == approx( + -11.7225 ) - assert ( - self.cohp_orb.get_summed_cohp_by_label_list(["1", "1"], summed_spin_channels=True).cohp[Spin.up][300] - == 0.03392 * 2.0 + assert self.cohp_orb.get_summed_cohp_by_label_list(["1"], summed_spin_channels=True).energies[5] == approx( + -11.47187 ) - assert ( - self.cohp_orb.get_summed_cohp_by_label_list(["1", "1"], summed_spin_channels=True, divisor=2).cohp[Spin.up][ - 300 - ] - == 0.03392 + assert not self.cohp_orb.get_summed_cohp_by_label_list(["1"], summed_spin_channels=True).are_coops + assert self.cohp_orb.get_summed_cohp_by_label_list(["1"], summed_spin_channels=True).cohp[Spin.up][0] == approx( + 0.0 ) + assert self.cohp_orb.get_summed_cohp_by_label_list(["1", "1"], summed_spin_channels=True).cohp[Spin.up][ + 0 + ] == approx(0.0) + assert self.cohp_orb.get_summed_cohp_by_label_list(["1", "1"], summed_spin_channels=True).cohp[Spin.up][ + 300 + ] == approx(0.03392 * 2.0) + assert self.cohp_orb.get_summed_cohp_by_label_list(["1", "1"], summed_spin_channels=True, divisor=2).cohp[ + Spin.up + ][300] == approx(0.03392) # file with spin polarization assert self.cohp_lobster_spin_polarized.get_summed_cohp_by_label_list(["1"], summed_spin_channels=False).cohp[ @@ -1124,13 +1125,13 @@ def test_get_summed_cohp_by_label_and_orbital_list(self): ) cohp_label3 = self.cohp_orb.get_summed_cohp_by_label_and_orbital_list(["1", "1"], ["4px-4pz", "4s-4px"]) - assert_array_equal(cohp_label.cohp[Spin.up], ref["COHP"][Spin.up]) - assert_array_equal(cohp_label2.cohp[Spin.up], ref["COHP"][Spin.up] * 2.0) - assert_array_equal(cohp_label3.cohp[Spin.up], ref["COHP"][Spin.up] + ref2["COHP"][Spin.up]) - assert_array_equal(cohp_label.icohp[Spin.up], ref["ICOHP"][Spin.up]) - assert_array_equal(cohp_label2.icohp[Spin.up], ref["ICOHP"][Spin.up] * 2.0) - assert_array_equal(cohp_label2x.icohp[Spin.up], ref["ICOHP"][Spin.up]) - assert_array_equal(cohp_label3.icohp[Spin.up], ref["ICOHP"][Spin.up] + ref2["ICOHP"][Spin.up]) + assert_allclose(cohp_label.cohp[Spin.up], ref["COHP"][Spin.up]) + assert_allclose(cohp_label2.cohp[Spin.up], ref["COHP"][Spin.up] * 2.0) + assert_allclose(cohp_label3.cohp[Spin.up], ref["COHP"][Spin.up] + ref2["COHP"][Spin.up]) + assert_allclose(cohp_label.icohp[Spin.up], ref["ICOHP"][Spin.up]) + assert_allclose(cohp_label2.icohp[Spin.up], ref["ICOHP"][Spin.up] * 2.0) + assert_allclose(cohp_label2x.icohp[Spin.up], ref["ICOHP"][Spin.up]) + assert_allclose(cohp_label3.icohp[Spin.up], ref["ICOHP"][Spin.up] + ref2["ICOHP"][Spin.up]) expected_msg = "label_list and orbital_list don't have the same length" with pytest.raises(ValueError, match=expected_msg): self.cohp_orb.get_summed_cohp_by_label_and_orbital_list(["1"], ["4px-4pz", "4s-4px"]) @@ -1153,13 +1154,13 @@ def test_get_summed_cohp_by_label_and_orbital_list_summed_spin_channels(self): ["1", "1"], ["4px-4pz", "4s-4px"], summed_spin_channels=True ) - assert_array_equal(cohp_label.cohp[Spin.up], ref["COHP"][Spin.up]) - assert_array_equal(cohp_label2.cohp[Spin.up], ref["COHP"][Spin.up] * 2.0) - assert_array_equal(cohp_label3.cohp[Spin.up], ref["COHP"][Spin.up] + ref2["COHP"][Spin.up]) - assert_array_equal(cohp_label.icohp[Spin.up], ref["ICOHP"][Spin.up]) - assert_array_equal(cohp_label2.icohp[Spin.up], ref["ICOHP"][Spin.up] * 2.0) - assert_array_equal(cohp_label2x.icohp[Spin.up], ref["ICOHP"][Spin.up]) - assert_array_equal(cohp_label3.icohp[Spin.up], ref["ICOHP"][Spin.up] + ref2["ICOHP"][Spin.up]) + assert_allclose(cohp_label.cohp[Spin.up], ref["COHP"][Spin.up]) + assert_allclose(cohp_label2.cohp[Spin.up], ref["COHP"][Spin.up] * 2.0) + assert_allclose(cohp_label3.cohp[Spin.up], ref["COHP"][Spin.up] + ref2["COHP"][Spin.up]) + assert_allclose(cohp_label.icohp[Spin.up], ref["ICOHP"][Spin.up]) + assert_allclose(cohp_label2.icohp[Spin.up], ref["ICOHP"][Spin.up] * 2.0) + assert_allclose(cohp_label2x.icohp[Spin.up], ref["ICOHP"][Spin.up]) + assert_allclose(cohp_label3.icohp[Spin.up], ref["ICOHP"][Spin.up] + ref2["ICOHP"][Spin.up]) expected_msg = "label_list and orbital_list don't have the same length" with pytest.raises(ValueError, match=expected_msg): self.cohp_orb.get_summed_cohp_by_label_and_orbital_list( diff --git a/tests/electronic_structure/test_core.py b/tests/electronic_structure/test_core.py index 2abad986cc4..8b39480930d 100644 --- a/tests/electronic_structure/test_core.py +++ b/tests/electronic_structure/test_core.py @@ -3,6 +3,7 @@ import numpy as np import pytest from numpy.testing import assert_allclose +from pytest import approx from pymatgen.core import Lattice from pymatgen.electronic_structure.core import Magmom, Orbital, Spin @@ -38,7 +39,7 @@ class TestMagmom: def test_init(self): # backwards compatibility for scalar-like magmoms magmom = Magmom(2.0) - assert float(magmom) == 2.0 + assert float(magmom) == approx(2.0) # backwards compatibility for list-like magmoms magmom2 = Magmom([1, 2, 3]) assert list(magmom2) == [1, 2, 3] diff --git a/tests/electronic_structure/test_dos.py b/tests/electronic_structure/test_dos.py index a7c8dec41b1..b8bdaf52ce8 100644 --- a/tests/electronic_structure/test_dos.py +++ b/tests/electronic_structure/test_dos.py @@ -77,7 +77,7 @@ def test_doping_fermi(self): assert calc_fermis[j] == approx(f_ref, abs=1e-4) sci_dos = FermiDos(self.dos, bandgap=3.0) - assert sci_dos.get_gap() == 3.0 + assert sci_dos.get_gap() == approx(3.0) old_cbm, old_vbm = self.dos.get_cbm_vbm() old_gap = old_cbm - old_vbm new_cbm, new_vbm = sci_dos.get_cbm_vbm() diff --git a/tests/electronic_structure/test_plotter.py b/tests/electronic_structure/test_plotter.py index 59763e9ea59..e1e01469cd5 100644 --- a/tests/electronic_structure/test_plotter.py +++ b/tests/electronic_structure/test_plotter.py @@ -124,7 +124,7 @@ def test_get_branch_steps(self): def test_rescale_distances(self): rescaled_distances = self.plotter_multi._rescale_distances(self.sbs_sc, self.sbs_met) assert len(rescaled_distances) == len(self.sbs_met.distance), "wrong length of distances list" - assert rescaled_distances[-1] == 6.5191398067252875, "wrong last distance value" + assert rescaled_distances[-1] == approx(6.5191398067252875), "wrong last distance value" assert rescaled_distances[148] == self.sbs_sc.distance[19], "wrong distance at high symm k-point" def test_interpolate_bands(self): @@ -156,7 +156,7 @@ def test_bs_plot_data(self): def test_get_ticks(self): assert self.plotter.get_ticks()["label"][5] == "K", "wrong tick label" - assert self.plotter.get_ticks()["distance"][5] == pytest.approx(2.406607625322699), "wrong tick distance" + assert self.plotter.get_ticks()["distance"][5] == approx(2.406607625322699), "wrong tick distance" # Minimal baseline testing for get_plot. not a true test. Just checks that # it can actually execute. @@ -165,7 +165,7 @@ def test_get_plot(self): # vbm_cbm_marker = False, smooth_tol = None ax = self.plotter.get_plot() - assert ax.get_ylim() == (-4.0, 7.6348), "wrong ylim" + assert_allclose(ax.get_ylim(), (-4.0, 7.6348)), "wrong ylim" ax = self.plotter.get_plot(smooth=True) ax = self.plotter.get_plot(vbm_cbm_marker=True) self.plotter.save_plot(f"{self.tmp_path}/bsplot.png") @@ -175,9 +175,9 @@ def test_get_plot(self): # test plotter with 2 bandstructures ax = self.plotter_multi.get_plot() assert len(ax.get_lines()) == 874, "wrong number of lines" - assert ax.get_ylim() == (-10.0, 10.0), "wrong ylim" + assert_allclose(ax.get_ylim(), (-10.0, 10.0)), "wrong ylim" ax = self.plotter_multi.get_plot(zero_to_efermi=False) - assert ax.get_ylim() == (-15.2379, 12.67141266), "wrong ylim" + assert_allclose(ax.get_ylim(), (-15.2379, 12.67141266)), "wrong ylim" ax = self.plotter_multi.get_plot(smooth=True) self.plotter_multi.save_plot(f"{self.tmp_path}/bsplot.png") assert os.path.isfile(f"{self.tmp_path}/bsplot.png") @@ -208,7 +208,7 @@ def test_methods(self): ) assert isinstance(ax, plt.Axes) assert len(ax.get_lines()) == 44_127 - assert ax.get_ylim() == pytest.approx((-4.0, 4.5047)) + assert ax.get_ylim() == approx((-4.0, 4.5047)) with pytest.raises( ValueError, @@ -311,136 +311,136 @@ def setUp(self): def test_plot_carriers(self): ax = self.plotter.plot_carriers() assert len(ax.get_lines()) == 7, "wrong number of lines" - assert ax.get_lines()[0].get_data()[0][0] == -2.0702422655947665, "wrong 0 data in line 0" - assert ax.get_lines()[0].get_data()[1][0] == 6.525490122298364e22, "wrong 1 data in line 0" + assert ax.get_lines()[0].get_data()[0][0] == approx(-2.0702422655947665), "wrong 0 data in line 0" + assert ax.get_lines()[0].get_data()[1][0] == approx(6.525490122298364e22), "wrong 1 data in line 0" plt.close() def test_plot_complexity_factor_mu(self): pytest.importorskip("fdint") ax = self.plotter.plot_complexity_factor_mu() assert len(ax.get_lines()) == 2, "wrong number of lines" - assert ax.get_lines()[0].get_data()[0][0] == -2.0702422655947665, "wrong 0 data in line 0" - assert ax.get_lines()[0].get_data()[1][0] == 0.004708835456903449, "wrong 1 data in line 0" + assert ax.get_lines()[0].get_data()[0][0] == approx(-2.0702422655947665), "wrong 0 data in line 0" + assert ax.get_lines()[0].get_data()[1][0] == approx(0.004708835456903449), "wrong 1 data in line 0" plt.close() def test_plot_conductivity_dop(self): ax = self.plotter.plot_conductivity_dop() assert len(ax.get_lines()) == 8, "wrong number of lines" - assert ax.get_lines()[0].get_data()[0][0] == 1000000000000000.0, "wrong 0 data in line 0" - assert ax.get_lines()[0].get_data()[1][0] == 0.3801957596666667, "wrong 1 data in line 0" + assert ax.get_lines()[0].get_data()[0][0] == approx(1e15), "wrong 0 data in line 0" + assert ax.get_lines()[0].get_data()[1][0] == approx(0.3801957596666667), "wrong 1 data in line 0" plt.close() def test_plot_conductivity_mu(self): ax = self.plotter.plot_conductivity_mu() assert len(ax.get_lines()) == 9, "wrong number of lines" - assert ax.get_lines()[0].get_data()[0][0] == -2.0702422655947665, "wrong 0 data in line 0" - assert ax.get_lines()[0].get_data()[1][0] == 1965.1306, "wrong 1 data in line 0" + assert ax.get_lines()[0].get_data()[0][0] == approx(-2.0702422655947665), "wrong 0 data in line 0" + assert ax.get_lines()[0].get_data()[1][0] == approx(1965.1306), "wrong 1 data in line 0" plt.close() def test_plot_conductivity_temp(self): ax = self.plotter.plot_conductivity_temp() assert len(ax.get_lines()) == 6, "wrong number of lines" - assert ax.get_lines()[0].get_data()[0][0] == 100, "wrong 0 data in line 0" - assert ax.get_lines()[0].get_data()[1][0] == 0.3801957596666667, "wrong 1 data in line 0" + assert ax.get_lines()[0].get_data()[0][0] == approx(100), "wrong 0 data in line 0" + assert ax.get_lines()[0].get_data()[1][0] == approx(0.3801957596666667), "wrong 1 data in line 0" plt.close() def test_plot_dos(self): ax = self.plotter.plot_dos() assert len(ax.get_lines()) == 3, "wrong number of lines" - assert ax.get_lines()[0].get_data()[0][0] == -2.4197044934588674, "wrong 0 data in line 0" - assert ax.get_lines()[0].get_data()[1][0] == 0.0, "wrong 1 data in line 0" + assert ax.get_lines()[0].get_data()[0][0] == approx(-2.4197044934588674), "wrong 0 data in line 0" + assert ax.get_lines()[0].get_data()[1][0] == approx(0.0), "wrong 1 data in line 0" plt.close() def test_plot_eff_mass_dop(self): ax = self.plotter.plot_eff_mass_dop() assert len(ax.get_lines()) == 8, "wrong number of lines" - assert ax.get_lines()[0].get_data()[0][0] == 1000000000000000.0, "wrong 0 data in line 0" - assert ax.get_lines()[0].get_data()[1][0] == 1.4231240011719886, "wrong 1 data in line 0" + assert ax.get_lines()[0].get_data()[0][0] == approx(1e15), "wrong 0 data in line 0" + assert ax.get_lines()[0].get_data()[1][0] == approx(1.4231240011719886), "wrong 1 data in line 0" plt.close() def test_plot_eff_mass_temp(self): ax = self.plotter.plot_eff_mass_temp() assert len(ax.get_lines()) == 6, "wrong number of lines" - assert ax.get_lines()[0].get_data()[0][0] == 100, "wrong 0 data in line 0" - assert ax.get_lines()[0].get_data()[1][0] == 1.4231240011719886, "wrong 1 data in line 0" + assert ax.get_lines()[0].get_data()[0][0] == approx(100), "wrong 0 data in line 0" + assert ax.get_lines()[0].get_data()[1][0] == approx(1.4231240011719886), "wrong 1 data in line 0" plt.close() def test_plot_hall_carriers(self): ax = self.plotter.plot_hall_carriers() assert len(ax.get_lines()) == 7, "wrong number of lines" - assert ax.get_lines()[0].get_data()[0][0] == -2.0702422655947665, "wrong 0 data in line 0" - assert ax.get_lines()[0].get_data()[1][0] == 9.538187273102463e17, "wrong 1 data in line 0" + assert ax.get_lines()[0].get_data()[0][0] == approx(-2.0702422655947665), "wrong 0 data in line 0" + assert ax.get_lines()[0].get_data()[1][0] == approx(9.538187273102463e17), "wrong 1 data in line 0" plt.close() def test_plot_power_factor_dop(self): ax = self.plotter.plot_power_factor_dop() assert len(ax.get_lines()) == 8, "wrong number of lines" - assert ax.get_lines()[0].get_data()[0][0] == 1000000000000000.0, "wrong 0 data in line 0" - assert ax.get_lines()[0].get_data()[1][0] == 0.40606868935796925, "wrong 1 data in line 0" + assert ax.get_lines()[0].get_data()[0][0] == approx(1e15), "wrong 0 data in line 0" + assert ax.get_lines()[0].get_data()[1][0] == approx(0.40606868935796925), "wrong 1 data in line 0" plt.close() def test_plot_power_factor_mu(self): ax = self.plotter.plot_power_factor_mu() assert len(ax.get_lines()) == 9, "wrong number of lines" - assert ax.get_lines()[0].get_data()[0][0] == -2.0702422655947665, "wrong 0 data in line 0" - assert ax.get_lines()[0].get_data()[1][0] == 365.5514594136157, "wrong 1 data in line 0" + assert ax.get_lines()[0].get_data()[0][0] == approx(-2.0702422655947665), "wrong 0 data in line 0" + assert ax.get_lines()[0].get_data()[1][0] == approx(365.5514594136157), "wrong 1 data in line 0" plt.close() def test_plot_power_factor_temp(self): ax = self.plotter.plot_power_factor_temp() assert len(ax.get_lines()) == 6, "wrong number of lines" - assert ax.get_lines()[0].get_data()[0][0] == 100, "wrong 0 data in line 0" - assert ax.get_lines()[0].get_data()[1][0] == 0.40606868935796925, "wrong 1 data in line 0" + assert ax.get_lines()[0].get_data()[0][0] == approx(100), "wrong 0 data in line 0" + assert ax.get_lines()[0].get_data()[1][0] == approx(0.40606868935796925), "wrong 1 data in line 0" plt.close() def test_plot_seebeck_dop(self): ax = self.plotter.plot_seebeck_dop() assert len(ax.get_lines()) == 8, "wrong number of lines" - assert ax.get_lines()[0].get_data()[0][0] == 1000000000000000.0, "wrong 0 data in line 0" - assert ax.get_lines()[0].get_data()[1][0] == 1050.8197666666667, "wrong 1 data in line 0" + assert ax.get_lines()[0].get_data()[0][0] == approx(1e15), "wrong 0 data in line 0" + assert ax.get_lines()[0].get_data()[1][0] == approx(1050.8197666666667), "wrong 1 data in line 0" plt.close() def test_plot_seebeck_eff_mass_mu(self): pytest.importorskip("fdint") ax = self.plotter.plot_seebeck_eff_mass_mu() assert len(ax.get_lines()) == 2, "wrong number of lines" - assert ax.get_lines()[0].get_data()[0][0] == -2.0702422655947665, "wrong 0 data in line 0" - assert ax.get_lines()[0].get_data()[1][0] == 6412.881888198197, "wrong 1 data in line 0" + assert ax.get_lines()[0].get_data()[0][0] == approx(-2.0702422655947665), "wrong 0 data in line 0" + assert ax.get_lines()[0].get_data()[1][0] == approx(6412.881888198197), "wrong 1 data in line 0" plt.close() def test_plot_seebeck_mu(self): ax = self.plotter.plot_seebeck_mu() assert len(ax.get_lines()) == 9, "wrong number of lines" - assert ax.get_lines()[0].get_data()[0][0] == -2.0702422655947665, "wrong 0 data in line 0" - assert ax.get_lines()[0].get_data()[1][0] == -433.11096000000003, "wrong 1 data in line 0" + assert ax.get_lines()[0].get_data()[0][0] == approx(-2.0702422655947665), "wrong 0 data in line 0" + assert ax.get_lines()[0].get_data()[1][0] == approx(-433.11096000000003), "wrong 1 data in line 0" plt.close() def test_plot_seebeck_temp(self): ax = self.plotter.plot_seebeck_temp() assert len(ax.get_lines()) == 6, "wrong number of lines" - assert ax.get_lines()[0].get_data()[0][0] == 100, "wrong 0 data in line 0" - assert ax.get_lines()[0].get_data()[1][0] == 1050.8197666666667, "wrong 1 data in line 0" + assert ax.get_lines()[0].get_data()[0][0] == approx(100), "wrong 0 data in line 0" + assert ax.get_lines()[0].get_data()[1][0] == approx(1050.8197666666667), "wrong 1 data in line 0" plt.close() def test_plot_zt_dop(self): ax = self.plotter.plot_zt_dop() assert len(ax.get_lines()) == 8, "wrong number of lines" - assert ax.get_lines()[0].get_data()[0][0] == 1000000000000000.0, "wrong 0 data in line 0" - assert ax.get_lines()[0].get_data()[1][0] == 4.060682863129955e-05, "wrong 1 data in line 0" + assert ax.get_lines()[0].get_data()[0][0] == approx(1e15), "wrong 0 data in line 0" + assert ax.get_lines()[0].get_data()[1][0] == approx(4.060682863129955e-05), "wrong 1 data in line 0" plt.close() def test_plot_zt_mu(self): ax = self.plotter.plot_zt_mu() assert len(ax.get_lines()) == 9, "wrong number of lines" - assert ax.get_lines()[0].get_data()[0][0] == -2.0702422655947665, "wrong 0 data in line 0" - assert ax.get_lines()[0].get_data()[1][0] == 0.2153839699235254, "wrong 1 data in line 0" + assert ax.get_lines()[0].get_data()[0][0] == approx(-2.0702422655947665), "wrong 0 data in line 0" + assert ax.get_lines()[0].get_data()[1][0] == approx(0.2153839699235254), "wrong 1 data in line 0" plt.close() def test_plot_zt_temp(self): ax = self.plotter.plot_zt_temp() assert len(ax.get_lines()) == 6, "wrong number of lines" - assert ax.get_lines()[0].get_data()[0][0] == 100, "wrong 0 data in line 0" - assert ax.get_lines()[0].get_data()[1][0] == 4.060682863129955e-05, "wrong 1 data in line 0" + assert ax.get_lines()[0].get_data()[0][0] == approx(100), "wrong 0 data in line 0" + assert ax.get_lines()[0].get_data()[1][0] == approx(4.060682863129955e-05), "wrong 1 data in line 0" plt.close() diff --git a/tests/entries/test_compatibility.py b/tests/entries/test_compatibility.py index 2aaa4cb02ce..14ca9fb081e 100644 --- a/tests/entries/test_compatibility.py +++ b/tests/entries/test_compatibility.py @@ -113,9 +113,9 @@ def test_correction_specificity(self): assert len(processed) == 2 - assert self.entry1.correction != 0 - assert self.entry2.correction != 0 - assert self.entry3.correction == 0.0 + assert self.entry1.correction != approx(0) + assert self.entry2.correction != approx(0) + assert self.entry3.correction == approx(0) # abstract Compatibility tests @@ -2184,9 +2184,9 @@ def test_h_h2o_energy_no_args(self): compat.process_entries([h2o_entry_1, h2o_entry_2, h2_entry_1, h2_entry_2, o2_entry_1]) - assert compat.o2_energy == -4.9276 - assert compat.h2o_energy == -5.195 - assert compat.h2o_adjustments == -0.234 + assert compat.o2_energy == approx(-4.9276) + assert compat.h2o_energy == approx(-5.195) + assert compat.h2o_adjustments == approx(-0.234) # the corrections should preserve the difference in energy among H2O and H2 polymorphs assert h2o_entry_2.energy_per_atom == approx(h2o_entry_1.energy_per_atom + 4.195) diff --git a/tests/entries/test_computed_entries.py b/tests/entries/test_computed_entries.py index 9cf63caca6f..b8f440303d3 100644 --- a/tests/entries/test_computed_entries.py +++ b/tests/entries/test_computed_entries.py @@ -86,7 +86,7 @@ def test_composition_energy_adjustment(): def test_temp_energy_adjustment(): ea = TemperatureEnergyAdjustment(-0.1, 298, 5, uncertainty_per_deg=0, name="entropy") assert ea.name == "entropy" - assert ea.value == -0.1 * 298 * 5 + assert ea.value == approx(-0.1 * 298 * 5) assert ea.n_atoms == 5 assert ea.temp == 298 assert ea.explain == "Temperature-based energy adjustment (-0.1000 eV/K/atom x 298 K x 5 atoms)" diff --git a/tests/ext/test_matproj.py b/tests/ext/test_matproj.py index 18558a41525..67c785f7da9 100644 --- a/tests/ext/test_matproj.py +++ b/tests/ext/test_matproj.py @@ -311,7 +311,7 @@ def test_get_pourbaix_entries(self): def test_get_exp_entry(self): entry = self.rester.get_exp_entry("Fe2O3") - assert entry.energy == -825.5 + assert entry.energy == approx(-825.5) @pytest.mark.skip("TODO: Need someone to fix this") def test_submit_query_delete_snl(self): @@ -773,7 +773,7 @@ def test_get_entries(self): @pytest.mark.skip("TODO: need someone to fix this") def test_get_exp_entry(self): entry = self.rester.get_exp_entry("Fe2O3") - assert entry.energy == -825.5 + assert entry.energy == approx(-825.5) @pytest.mark.skip("TODO: need someone to fix this") def test_get_stability(self): diff --git a/tests/io/abinit/test_inputs.py b/tests/io/abinit/test_inputs.py index 762ea2acad8..b3fd0271aa5 100644 --- a/tests/io/abinit/test_inputs.py +++ b/tests/io/abinit/test_inputs.py @@ -5,7 +5,8 @@ import numpy as np import pytest -from numpy.testing import assert_array_equal +from numpy.testing import assert_allclose, assert_array_equal +from pytest import approx from pymatgen.core.structure import Structure from pymatgen.io.abinit.inputs import ( @@ -52,7 +53,7 @@ def test_api(self): inp = BasicAbinitInput(structure=unit_cell, pseudos=abiref_file("14si.pspnc")) shift_k = [[0.5, 0.5, 0.5], [0.5, 0.0, 0.0], [0.0, 0.5, 0.0], [0.0, 0.0, 0.5]] - assert_array_equal(calc_shiftk(inp.structure), shift_k) + assert_allclose(calc_shiftk(inp.structure), shift_k) assert num_valence_electrons(inp.structure, inp.pseudos) == 8 assert len(inp) == 0 @@ -105,7 +106,7 @@ def test_api(self): removed = inp.pop_tolerances() assert len(removed) == 1 - assert removed["toldfe"] == 1e-6 + assert removed["toldfe"] == approx(1e-6) # Test set_spin_mode old_vars = inp.set_spin_mode("polarized") diff --git a/tests/io/abinit/test_pseudos.py b/tests/io/abinit/test_pseudos.py index 8cd9bace814..3c7f8e9f1a4 100644 --- a/tests/io/abinit/test_pseudos.py +++ b/tests/io/abinit/test_pseudos.py @@ -165,8 +165,8 @@ def test_oncvpsp_pseudo_sr(self): ger.as_tmpfile() assert ger.symbol == "Ge" - assert ger.Z == 32.0 - assert ger.Z_val == 4.0 + assert ger.Z == approx(32.0) # noqa: SIM300 + assert ger.Z_val == approx(4.0) assert ger.isnc assert not ger.ispaw assert ger.l_max == 2 @@ -189,8 +189,8 @@ def test_oncvpsp_pseudo_fr(self): self.assert_msonable(pb) assert pb.symbol == "Pb" - assert pb.Z == 82.0 - assert pb.Z_val == 14.0 + assert pb.Z == approx(82.0) # noqa: SIM300 + assert pb.Z_val == approx(14.0) assert pb.isnc assert not pb.ispaw assert pb.l_max == 2 diff --git a/tests/io/aims/test_inputs.py b/tests/io/aims/test_inputs.py index 65770bbe567..edce678c9cb 100644 --- a/tests/io/aims/test_inputs.py +++ b/tests/io/aims/test_inputs.py @@ -137,7 +137,7 @@ def test_write_spins(tmp_path: Path): assert len(magmom_lines) == 4 magmoms = np.array([float(line.strip().split()[-1]) for line in magmom_lines]) - assert np.all(magmoms == 5.0) + assert_allclose(magmoms, 5.0) mg2mn4o8 = Structure( lattice=mg2mn4o8.lattice, diff --git a/tests/io/aims/test_parsers.py b/tests/io/aims/test_parsers.py index 2975493272a..fa3d8b62b6e 100644 --- a/tests/io/aims/test_parsers.py +++ b/tests/io/aims/test_parsers.py @@ -5,6 +5,7 @@ import numpy as np import pytest from numpy.testing import assert_allclose +from pytest import approx from pymatgen.core.tensors import Tensor from pymatgen.io.aims.parsers import ( @@ -63,7 +64,7 @@ def test_missing_parameter(attr_name, empty_header_chunk): def test_default_header_electronic_temperature(empty_header_chunk): - assert empty_header_chunk.electronic_temperature == 0.0 + assert empty_header_chunk.electronic_temperature == approx(0.0) def test_default_header_initial_lattice(empty_header_chunk): @@ -141,7 +142,7 @@ def test_header_initial_lattice(header_chunk, initial_lattice): def test_header_electronic_temperature(header_chunk): - assert header_chunk.electronic_temperature == 0.05 + assert header_chunk.electronic_temperature == approx(0.05) def test_header_is_md(header_chunk): @@ -246,7 +247,7 @@ def test_header_transfer_initial_structure(empty_calc_chunk, initial_lattice): def test_header_transfer_electronic_temperature(empty_calc_chunk): - assert empty_calc_chunk.electronic_temperature == 0.05 + assert empty_calc_chunk.electronic_temperature == approx(0.05) def test_header_transfer_n_k_points(empty_calc_chunk): diff --git a/tests/io/cp2k/test_inputs.py b/tests/io/cp2k/test_inputs.py index ec0b772c617..d0e7831b2eb 100644 --- a/tests/io/cp2k/test_inputs.py +++ b/tests/io/cp2k/test_inputs.py @@ -2,7 +2,7 @@ import numpy as np import pytest -from numpy.testing import assert_allclose, assert_array_equal +from numpy.testing import assert_allclose from pytest import approx from pymatgen.core.structure import Molecule, Structure @@ -88,7 +88,7 @@ def test_basis(self): assert kw.values[0] == "SZV-MOLOPT-GTH" mol_opt.info.admm = True kw = mol_opt.get_keyword() - assert_array_equal(kw.values, ["AUX_FIT", "SZV-MOLOPT-GTH"]) + assert list(kw.values) == ["AUX_FIT", "SZV-MOLOPT-GTH"] mol_opt.info.admm = False diff --git a/tests/io/cp2k/test_outputs.py b/tests/io/cp2k/test_outputs.py index 84c3fab0e18..1586524acd6 100644 --- a/tests/io/cp2k/test_outputs.py +++ b/tests/io/cp2k/test_outputs.py @@ -37,7 +37,7 @@ def test_run_info(self): def energy_force(self): """Can get energy and forces.""" - assert self.out.final_energy == -197.40000341992783 + assert self.out.final_energy == approx(-197.40000341992783) assert_allclose( self.out.data["forces"][0], [ @@ -49,7 +49,7 @@ def energy_force(self): def test_band(self): """Can parse bandstructure files.""" assert self.out.band_structure - assert self.out.band_structure.get_band_gap().get("energy") == 0.27940141999999923 + assert self.out.band_structure.get_band_gap().get("energy") == approx(0.27940141999999923) def test_dos(self): """Can parse dos files.""" diff --git a/tests/io/feff/test_outputs.py b/tests/io/feff/test_outputs.py index 9fcadc3c5bc..d0daa58379e 100644 --- a/tests/io/feff/test_outputs.py +++ b/tests/io/feff/test_outputs.py @@ -2,6 +2,8 @@ from unittest import TestCase +from pytest import approx + from pymatgen.io.feff.outputs import LDos, Xmu from pymatgen.util.testing import TEST_FILES_DIR @@ -19,12 +21,12 @@ class TestFeffLdos(TestCase): def test_init(self): e_fermi = TestFeffLdos.ldos.complete_dos.efermi - assert e_fermi == -11.430, "Did not read correct Fermi energy from ldos file" + assert e_fermi == approx(-11.430), "Did not read correct Fermi energy from ldos file" def test_complete_dos(self): complete_dos = TestFeffLdos.ldos.complete_dos - assert ( - complete_dos.as_dict()["spd_dos"]["s"]["efermi"] == -11.430 + assert complete_dos.as_dict()["spd_dos"]["s"]["efermi"] == approx( + -11.430 ), "Failed to construct complete_dos dict properly" def test_as_dict_and_from_dict(self): @@ -35,18 +37,18 @@ def test_as_dict_and_from_dict(self): def test_reci_init(self): e_fermi = TestFeffLdos.reci_dos.complete_dos.efermi - assert e_fermi == -9.672, "Did not read correct Fermi energy from ldos file" + assert e_fermi == approx(-9.672), "Did not read correct Fermi energy from ldos file" def test_reci_complete_dos(self): complete_dos = TestFeffLdos.reci_dos.complete_dos - assert ( - complete_dos.as_dict()["spd_dos"]["s"]["efermi"] == -9.672 + assert complete_dos.as_dict()["spd_dos"]["s"]["efermi"] == approx( + -9.672 ), "Failed to construct complete_dos dict properly" def test_reci_charge(self): charge_trans = TestFeffLdos.reci_dos.charge_transfer - assert charge_trans["0"]["Na"]["s"] == 0.241 - assert charge_trans["1"]["O"]["tot"] == -0.594 + assert charge_trans["0"]["Na"]["s"] == approx(0.241) + assert charge_trans["1"]["O"]["tot"] == approx(-0.594) class TestXmu(TestCase): diff --git a/tests/io/lammps/test_data.py b/tests/io/lammps/test_data.py index 3be78db967c..c3b8fd503c8 100644 --- a/tests/io/lammps/test_data.py +++ b/tests/io/lammps/test_data.py @@ -8,7 +8,7 @@ import pandas as pd import pytest from monty.json import MontyDecoder, MontyEncoder -from numpy.testing import assert_allclose +from numpy.testing import assert_allclose, assert_array_equal from pytest import approx from ruamel.yaml import YAML @@ -55,8 +55,8 @@ def test_get_str(self): def test_get_box_shift(self): peptide = self.peptide - assert peptide.get_box_shift([1, 0, 0])[0] == 64.211560 - 36.840194 - assert peptide.get_box_shift([0, 0, -1])[-1] == 29.768095 - 57.139462 + assert peptide.get_box_shift([1, 0, 0])[0] == approx(64.211560 - 36.840194) + assert peptide.get_box_shift([0, 0, -1])[-1] == approx(29.768095 - 57.139462) quartz = self.quartz assert_allclose(quartz.get_box_shift([0, 0, 1]), [0, 0, 5.4052], 4) assert_allclose(quartz.get_box_shift([0, 1, -1]), [-2.4567, 4.2551, -5.4052], 4) @@ -303,18 +303,18 @@ def test_disassemble(self): ("O3", 15.9994), ] assert c_ff.mass_info == mass_info - np.testing.assert_array_equal(c_ff.nonbond_coeffs, c.force_field["Pair Coeffs"].values) + assert_allclose(c_ff.nonbond_coeffs, c.force_field["Pair Coeffs"].values) base_kws = ["Bond", "Angle", "Dihedral", "Improper"] rng = np.random.default_rng() for kw in base_kws: ff_kw = f"{kw} Coeffs" idx = rng.integers(0, len(c_ff.topo_coeffs[ff_kw]) - 1) sample_coeff = c_ff.topo_coeffs[ff_kw][idx] - np.testing.assert_array_equal(sample_coeff["coeffs"], c.force_field[ff_kw].iloc[idx].values, ff_kw) + assert_allclose(sample_coeff["coeffs"], c.force_field[ff_kw].iloc[idx].values, err_msg=ff_kw) topo = topos[-1] atoms = c.atoms[c.atoms["molecule-ID"] == 46] assert_allclose(topo.sites.cart_coords, atoms[["x", "y", "z"]]) - np.testing.assert_array_equal(topo.charges, atoms["q"]) + assert_allclose(topo.charges, atoms["q"]) atom_labels = [m[0] for m in mass_info] assert topo.sites.site_properties["ff_map"] == [atom_labels[i - 1] for i in atoms["type"]] shift = min(atoms.index) @@ -325,7 +325,7 @@ def test_disassemble(self): topos_df = c.topology[topo_kw] topo_df: pd.DataFrame = topos_df[topos_df["atom1"] >= shift] topo_arr = topo_df.drop("type", axis=1) - np.testing.assert_array_equal(topo.topologies[topo_kw], topo_arr - shift, topo_kw) + assert_allclose(topo.topologies[topo_kw], topo_arr - shift, err_msg=topo_kw) sample_topo = rng.choice(list(topo_df.itertuples(index=False, name=None)), 1)[0] topo_type_idx = sample_topo[0] - 1 topo_type = tuple(atom_labels[i - 1] for i in atoms.loc[list(sample_topo[1:])]["type"]) @@ -336,19 +336,19 @@ def test_disassemble(self): _, v_ff, _ = virus.disassemble(guess_element=False) assert v_ff.maps["Atoms"] == {"Qa1": 1, "Qb1": 2, "Qc1": 3, "Qa2": 4} pair_ij_coeffs = virus.force_field["PairIJ Coeffs"].drop(["id1", "id2"], axis=1) - np.testing.assert_array_equal(v_ff.nonbond_coeffs, pair_ij_coeffs.values) + assert_allclose(v_ff.nonbond_coeffs, pair_ij_coeffs.values) # test class2 ff _, e_ff, _ = self.ethane.disassemble() e_topo_coeffs = e_ff.topo_coeffs - for k in ["BondBond Coeffs", "BondAngle Coeffs"]: + for k in ("BondBond Coeffs", "BondAngle Coeffs"): assert k in e_topo_coeffs["Angle Coeffs"][0], k - for k in [ + for k in ( "MiddleBondTorsion Coeffs", "EndBondTorsion Coeffs", "AngleTorsion Coeffs", "AngleAngleTorsion Coeffs", "BondBond13 Coeffs", - ]: + ): assert k in e_topo_coeffs["Dihedral Coeffs"][0], k assert "AngleAngle Coeffs" in e_topo_coeffs["Improper Coeffs"][0] @@ -381,20 +381,20 @@ def test_from_file(self): assert ff["Dihedral Coeffs"].shape == (21, 4) assert ff["Improper Coeffs"].shape == (2, 2) # header box - np.testing.assert_array_equal( + assert_allclose( pep.box.bounds, [[36.840194, 64.211560], [41.013691, 68.385058], [29.768095, 57.139462]], ) # body - assert pep.masses.loc[7, "mass"] == 12.0110 - assert ff["Pair Coeffs"].loc[9, "coeff3"] == 0.152100 - assert ff["Bond Coeffs"].loc[5, "coeff2"] == 1.430000 - assert ff["Angle Coeffs"].loc[21, "coeff2"] == 120.000000 - assert ff["Dihedral Coeffs"].loc[10, "coeff1"] == 0.040000 - assert ff["Improper Coeffs"].loc[2, "coeff1"] == 20.000000 + assert pep.masses.loc[7, "mass"] == approx(12.0110) + assert ff["Pair Coeffs"].loc[9, "coeff3"] == approx(0.152100) + assert ff["Bond Coeffs"].loc[5, "coeff2"] == approx(1.430000) + assert ff["Angle Coeffs"].loc[21, "coeff2"] == approx(120.000000) + assert ff["Dihedral Coeffs"].loc[10, "coeff1"] == approx(0.040000) + assert ff["Improper Coeffs"].loc[2, "coeff1"] == approx(20.000000) assert pep.atoms.loc[29, "molecule-ID"] == 1 assert pep.atoms.loc[29, "type"] == 7 - assert pep.atoms.loc[29, "q"] == -0.020 + assert pep.atoms.loc[29, "q"] == approx(-0.020) assert pep.atoms.loc[29, "x"] == approx(42.96709) assert pep.atoms.loc[1808, "molecule-ID"] == 576 assert pep.atoms.loc[1808, "type"] == 14 @@ -420,18 +420,18 @@ def test_from_file(self): assert class2["Angle Coeffs"].shape == (2, 4) assert class2["Dihedral Coeffs"].shape == (1, 6) assert class2["Improper Coeffs"].shape == (2, 2) - assert class2["BondBond Coeffs"].loc[2, "coeff3"] == 1.1010 - assert class2["BondAngle Coeffs"].loc[2, "coeff4"] == 1.1010 - assert class2["AngleAngle Coeffs"].loc[2, "coeff6"] == 107.6600 - assert class2["AngleAngle Coeffs"].loc[2, "coeff6"] == 107.6600 - assert class2["AngleAngleTorsion Coeffs"].loc[1, "coeff3"] == 110.7700 - assert class2["EndBondTorsion Coeffs"].loc[1, "coeff8"] == 1.1010 - assert class2["MiddleBondTorsion Coeffs"].loc[1, "coeff4"] == 1.5300 - assert class2["BondBond13 Coeffs"].loc[1, "coeff3"] == 1.1010 - assert class2["AngleTorsion Coeffs"].loc[1, "coeff8"] == 110.7700 + assert class2["BondBond Coeffs"].loc[2, "coeff3"] == approx(1.1010) + assert class2["BondAngle Coeffs"].loc[2, "coeff4"] == approx(1.1010) + assert class2["AngleAngle Coeffs"].loc[2, "coeff6"] == approx(107.6600) + assert class2["AngleAngle Coeffs"].loc[2, "coeff6"] == approx(107.6600) + assert class2["AngleAngleTorsion Coeffs"].loc[1, "coeff3"] == approx(110.7700) + assert class2["EndBondTorsion Coeffs"].loc[1, "coeff8"] == approx(1.1010) + assert class2["MiddleBondTorsion Coeffs"].loc[1, "coeff4"] == approx(1.5300) + assert class2["BondBond13 Coeffs"].loc[1, "coeff3"] == approx(1.1010) + assert class2["AngleTorsion Coeffs"].loc[1, "coeff8"] == approx(110.7700) # tilt box and another atom_style quartz = self.quartz - np.testing.assert_array_equal(quartz.box.tilt, [-2.456700, 0.0, 0.0]) + assert_allclose(quartz.box.tilt, [-2.456700, 0.0, 0.0]) assert list(quartz.atoms.columns) == ["type", "x", "y", "z"] assert quartz.atoms.loc[7, "x"] == approx(0.299963) # PairIJ Coeffs section @@ -439,7 +439,7 @@ def test_from_file(self): pair_ij = virus.force_field["PairIJ Coeffs"] assert pair_ij.loc[7, "id1"] == 3 assert pair_ij.loc[7, "id2"] == 3 - assert pair_ij.loc[7, "coeff2"] == 2.1 + assert pair_ij.loc[7, "coeff2"] == approx(2.1) # sort_id atom_id = np.random.default_rng().integers(1, 384) assert self.tatb.atoms.loc[atom_id].name == atom_id @@ -462,17 +462,17 @@ def test_from_ff_and_topologies(self): atoms = ice.atoms bonds = ice.topology["Bonds"] angles = ice.topology["Angles"] - np.testing.assert_array_equal(atoms.index.values, np.arange(1, len(atoms) + 1)) - np.testing.assert_array_equal(bonds.index.values, np.arange(1, len(bonds) + 1)) - np.testing.assert_array_equal(angles.index.values, np.arange(1, len(angles) + 1)) + assert_array_equal(atoms.index.values, np.arange(1, len(atoms) + 1)) + assert_array_equal(bonds.index.values, np.arange(1, len(bonds) + 1)) + assert_array_equal(angles.index.values, np.arange(1, len(angles) + 1)) idx = np.random.default_rng().integers(0, len(topologies) - 1) sample = topologies[idx] in_atoms = ice.atoms[ice.atoms["molecule-ID"] == idx + 1] - np.testing.assert_array_equal(in_atoms.index.values, np.arange(3 * idx + 1, 3 * idx + 4)) - np.testing.assert_array_equal(in_atoms["type"].values, [2, 1, 1]) - np.testing.assert_array_equal(in_atoms["q"].values, sample.charges) - np.testing.assert_array_equal(in_atoms[["x", "y", "z"]].values, sample.sites.cart_coords) + assert_array_equal(in_atoms.index.values, np.arange(3 * idx + 1, 3 * idx + 4)) + assert_array_equal(in_atoms["type"].values, [2, 1, 1]) + assert_allclose(in_atoms["q"].values, sample.charges) + assert_allclose(in_atoms[["x", "y", "z"]].values, sample.sites.cart_coords) broken_topo_coeffs = { "Bond Coeffs": [{"coeffs": [176.864, 0.9611], "types": [("H", "O")]}], "Angle Coeffs": [{"coeffs": [42.1845, 109.4712], "types": [("H", "H", "H")]}], @@ -503,25 +503,25 @@ def test_from_structure(self): assert v_a == approx(lammps_data.velocities.loc[idx + 1, "vx"]) assert velocities[idx, 1] == approx(lammps_data.velocities.loc[idx + 1, "vy"]) assert_allclose(lammps_data.masses["mass"], [22.989769, 190.23, 15.9994]) - np.testing.assert_array_equal(lammps_data.atoms["type"], [2] * 4 + [3] * 16) + assert_array_equal(lammps_data.atoms["type"], [2] * 4 + [3] * 16) def test_set_charge_atom(self): peptide = self.peptide charges = {1: 0.8803} peptide.set_charge_atom(charges) - assert peptide.atoms.loc[1, "q"] == 0.8803 - assert peptide.atoms.loc[2, "q"] == -0.270 + assert peptide.atoms.loc[1, "q"] == approx(0.8803) + assert peptide.atoms.loc[2, "q"] == approx(-0.270) def test_set_charge_atom_type(self): peptide = self.peptide charges = {1: 0.8803} peptide.set_charge_atom_type(charges) - assert peptide.atoms.loc[1, "q"] == 0.8803 - assert peptide.atoms.loc[2, "q"] == -0.270 + assert peptide.atoms.loc[1, "q"] == approx(0.8803) + assert peptide.atoms.loc[2, "q"] == approx(-0.270) peptide.set_charge_atom_type({4: 2.345}) - assert peptide.atoms.loc[4, "q"] == 2.345 - assert peptide.atoms.loc[5, "q"] == 2.345 - assert peptide.atoms.loc[2004, "q"] == 0.4170 + assert peptide.atoms.loc[4, "q"] == approx(2.345) + assert peptide.atoms.loc[5, "q"] == approx(2.345) + assert peptide.atoms.loc[2004, "q"] == approx(0.4170) def test_json_dict(self): encoded = json.dumps(self.ethane.as_dict(), cls=MontyEncoder) @@ -562,18 +562,18 @@ def test_init(self): # q and v from site properties, while type from species_string topo = Topology(sites=mol) assert topo.type_by_sites == ["H"] * 10 - np.testing.assert_array_equal(topo.charges, inner_charge) - np.testing.assert_array_equal(topo.velocities, inner_velo) + assert_allclose(topo.charges, inner_charge) + assert_allclose(topo.velocities, inner_velo) # q and v from overriding, while type from site property topo_override = Topology(sites=mol, ff_label="ff_map", charges=outer_charge, velocities=outer_velo) assert topo_override.type_by_sites == ["D"] * 10 - np.testing.assert_array_equal(topo_override.charges, outer_charge) - np.testing.assert_array_equal(topo_override.velocities, outer_velo) + assert_allclose(topo_override.charges, outer_charge) + assert_allclose(topo_override.velocities, outer_velo) # test using a list of sites instead of SiteCollection topo_from_list = Topology(sites=mol.sites) assert topo_from_list.type_by_sites == topo.type_by_sites - np.testing.assert_array_equal(topo_from_list.charges, topo.charges) - np.testing.assert_array_equal(topo_from_list.velocities, topo.velocities) + assert_allclose(topo_from_list.charges, topo.charges) + assert_allclose(topo_from_list.velocities, topo.velocities) def test_from_bonding(self): # He: no bonding topologies @@ -620,7 +620,7 @@ def test_from_bonding(self): tp_etoh = topo_etoh.topologies assert len(tp_etoh["Bonds"]) == 8 etoh_bonds = [[0, 1], [0, 4], [0, 5], [0, 6], [1, 2], [1, 7], [1, 8], [2, 3]] - np.testing.assert_array_equal(tp_etoh["Bonds"], etoh_bonds) + assert_array_equal(tp_etoh["Bonds"], etoh_bonds) assert len(tp_etoh["Angles"]) == 13 etoh_angles = [ [1, 0, 4], @@ -637,7 +637,7 @@ def test_from_bonding(self): [7, 1, 8], [1, 2, 3], ] - np.testing.assert_array_equal(tp_etoh["Angles"], etoh_angles) + assert_array_equal(tp_etoh["Angles"], etoh_angles) assert len(tp_etoh["Dihedrals"]) == 12 etoh_dihedrals = [ [4, 0, 1, 2], @@ -653,7 +653,7 @@ def test_from_bonding(self): [7, 1, 2, 3], [8, 1, 2, 3], ] - np.testing.assert_array_equal(tp_etoh["Dihedrals"], etoh_dihedrals) + assert_array_equal(tp_etoh["Dihedrals"], etoh_dihedrals) assert json.dumps(topo_etoh.as_dict()) is not None # bond flag to off topo_etoh0 = Topology.from_bonding(molecule=etoh, bond=False, angle=True, dihedral=True) @@ -703,12 +703,12 @@ def test_init(self): ("C", 15.9994), ("D", 1.00794), ] - assert v.masses.loc[3, "mass"] == 15.9994 + assert v.masses.loc[3, "mass"] == approx(15.9994) v_ff = v.force_field assert isinstance(v_ff, dict) assert "Pair Coeffs" not in v_ff - assert v_ff["PairIJ Coeffs"].iloc[5, 4] == 1.93631 - assert v_ff["Bond Coeffs"].loc[2, "coeff2"] == 0.855906 + assert v_ff["PairIJ Coeffs"].iloc[5, 4] == approx(1.93631) + assert v_ff["Bond Coeffs"].loc[2, "coeff2"] == approx(0.855906) v_maps = v.maps assert v_maps["Atoms"] == {"A": 1, "B": 2, "C": 3, "D": 4} assert v_maps["Bonds"] == { @@ -719,23 +719,23 @@ def test_init(self): ("B", "C"): 2, ("C", "B"): 2, } - assert self.ethane.masses.loc[1, "mass"] == 12.01115 + assert self.ethane.masses.loc[1, "mass"] == approx(12.01115) e_ff = self.ethane.force_field assert isinstance(e_ff, dict) assert "PairIJ Coeffs" not in e_ff - assert e_ff["Pair Coeffs"].loc[1, "coeff2"] == 3.854 - assert e_ff["Bond Coeffs"].loc[2, "coeff4"] == 844.6 - assert e_ff["Angle Coeffs"].loc[2, "coeff4"] == -2.4318 - assert e_ff["Dihedral Coeffs"].loc[1, "coeff1"] == -0.1432 - assert e_ff["Improper Coeffs"].loc[2, "coeff2"] == 0.0 - assert e_ff["BondBond Coeffs"].loc[2, "coeff1"] == 5.3316 - assert e_ff["BondAngle Coeffs"].loc[1, "coeff3"] == 1.53 - assert e_ff["MiddleBondTorsion Coeffs"].loc[1, "coeff1"] == -14.261 - assert e_ff["EndBondTorsion Coeffs"].loc[1, "coeff1"] == 0.213 - assert e_ff["AngleTorsion Coeffs"].loc[1, "coeff3"] == -0.2466 - assert e_ff["AngleAngleTorsion Coeffs"].loc[1, "coeff1"] == -12.564 - assert e_ff["BondBond13 Coeffs"].loc[1, "coeff1"] == 0.0 - assert e_ff["AngleAngle Coeffs"].loc[1, "coeff2"] == -0.4825 + assert e_ff["Pair Coeffs"].loc[1, "coeff2"] == approx(3.854) + assert e_ff["Bond Coeffs"].loc[2, "coeff4"] == approx(844.6) + assert e_ff["Angle Coeffs"].loc[2, "coeff4"] == approx(-2.4318) + assert e_ff["Dihedral Coeffs"].loc[1, "coeff1"] == approx(-0.1432) + assert e_ff["Improper Coeffs"].loc[2, "coeff2"] == approx(0.0) + assert e_ff["BondBond Coeffs"].loc[2, "coeff1"] == approx(5.3316) + assert e_ff["BondAngle Coeffs"].loc[1, "coeff3"] == approx(1.53) + assert e_ff["MiddleBondTorsion Coeffs"].loc[1, "coeff1"] == approx(-14.261) + assert e_ff["EndBondTorsion Coeffs"].loc[1, "coeff1"] == approx(0.213) + assert e_ff["AngleTorsion Coeffs"].loc[1, "coeff3"] == approx(-0.2466) + assert e_ff["AngleAngleTorsion Coeffs"].loc[1, "coeff1"] == approx(-12.564) + assert e_ff["BondBond13 Coeffs"].loc[1, "coeff1"] == approx(0.0) + assert e_ff["AngleAngle Coeffs"].loc[1, "coeff2"] == approx(-0.4825) e_maps = self.ethane.maps assert e_maps["Atoms"] == {"c4": 1, "h1": 2} assert e_maps["Bonds"] == {("c4", "c4"): 1, ("c4", "h1"): 2, ("h1", "c4"): 2} @@ -763,8 +763,8 @@ def test_to_file(self): assert dct["nonbond_coeffs"] == self.virus.nonbond_coeffs def test_from_file(self): - assert self.ethane.mass_info == [("c4", 12.01115), ("h1", 1.00797)] - np.testing.assert_array_equal(self.ethane.nonbond_coeffs, [[0.062, 3.854], [0.023, 2.878]]) + assert self.ethane.mass_info == [("c4", approx(12.01115)), ("h1", approx(1.00797))] + assert_allclose(self.ethane.nonbond_coeffs, [[0.062, 3.854], [0.023, 2.878]]) e_tc = self.ethane.topo_coeffs assert "Bond Coeffs" in e_tc assert "BondAngle Coeffs" in e_tc["Angle Coeffs"][0] @@ -869,20 +869,20 @@ def test_from_files(self): assert ff["Dihedral Coeffs"].shape == (39, 6) assert ff["Improper Coeffs"].shape == (2, 3) # header box - np.testing.assert_array_equal( + assert_allclose( ec_fec.box.bounds, [[-0.597365, 54.56835], [-0.597365, 54.56835], [-0.597365, 54.56835]], ) # body - assert ec_fec.masses.loc[7, "mass"] == 1.008 - assert ff["Pair Coeffs"].loc[9, "coeff2"] == 3.750 - assert ff["Bond Coeffs"].loc[5, "coeff2"] == 1.0900 - assert ff["Angle Coeffs"].loc[24, "coeff2"] == 108.46005 + assert ec_fec.masses.loc[7, "mass"] == approx(1.008) + assert ff["Pair Coeffs"].loc[9, "coeff2"] == approx(3.750) + assert ff["Bond Coeffs"].loc[5, "coeff2"] == approx(1.0900) + assert ff["Angle Coeffs"].loc[24, "coeff2"] == approx(108.46005) assert np.isnan(ff["Dihedral Coeffs"].loc[30, "coeff6"]) - assert ff["Improper Coeffs"].loc[2, "coeff1"] == 10.5 + assert ff["Improper Coeffs"].loc[2, "coeff1"] == approx(10.5) assert ec_fec.atoms.loc[29, "molecule-ID"] == 3 assert ec_fec.atoms.loc[29, "type"] == 5 - assert ec_fec.atoms.loc[29, "q"] == 0.0755 + assert ec_fec.atoms.loc[29, "q"] == approx(0.0755) assert ec_fec.atoms.loc[29, "x"] == approx(14.442260) assert ec_fec.atoms.loc[14958, "molecule-ID"] == 1496 assert ec_fec.atoms.loc[14958, "type"] == 11 @@ -920,20 +920,20 @@ def test_from_lammpsdata(self): assert ff["Dihedral Coeffs"].shape == (39, 6) assert ff["Improper Coeffs"].shape == (2, 3) # header box - np.testing.assert_array_equal( + assert_allclose( ec_fec.box.bounds, [[-0.597365, 54.56835], [-0.597365, 54.56835], [-0.597365, 54.56835]], ) # body - assert ec_fec.masses.loc[7, "mass"] == 1.008 - assert ff["Pair Coeffs"].loc[9, "coeff2"] == 3.750 - assert ff["Bond Coeffs"].loc[5, "coeff2"] == 1.0900 - assert ff["Angle Coeffs"].loc[24, "coeff2"] == 108.46005 + assert ec_fec.masses.loc[7, "mass"] == approx(1.008) + assert ff["Pair Coeffs"].loc[9, "coeff2"] == approx(3.750) + assert ff["Bond Coeffs"].loc[5, "coeff2"] == approx(1.0900) + assert ff["Angle Coeffs"].loc[24, "coeff2"] == approx(108.46005) assert np.isnan(ff["Dihedral Coeffs"].loc[30, "coeff6"]) - assert ff["Improper Coeffs"].loc[2, "coeff1"] == 10.5 + assert ff["Improper Coeffs"].loc[2, "coeff1"] == approx(10.5) assert ec_fec.atoms.loc[29, "molecule-ID"] == 3 assert ec_fec.atoms.loc[29, "type"] == 5 - assert ec_fec.atoms.loc[29, "q"] == 0.0755 + assert ec_fec.atoms.loc[29, "q"] == approx(0.0755) assert ec_fec.atoms.loc[29, "x"] == approx(14.442260) assert ec_fec.atoms.loc[14958, "molecule-ID"] == 1496 assert ec_fec.atoms.loc[14958, "type"] == 11 @@ -984,16 +984,16 @@ def test_from_lammpsdata(self): # test data objects with different number of FF keywords li_ec = self.li_ec ec_li = self.ec_li - assert li_ec.force_field["Pair Coeffs"].loc[6, "coeff2"] == 2.42 - assert ec_li.force_field["Pair Coeffs"].loc[6, "coeff2"] == 2.87 - assert li_ec.force_field["Bond Coeffs"].loc[5, "coeff2"] == 1.09 - assert ec_li.force_field["Bond Coeffs"].loc[5, "coeff2"] == 1.09 - assert li_ec.force_field["Angle Coeffs"].loc[7, "coeff2"] == 107.80 - assert ec_li.force_field["Angle Coeffs"].loc[7, "coeff2"] == 107.80 - assert li_ec.force_field["Dihedral Coeffs"].loc[11, "coeff2"] == 0.156 - assert ec_li.force_field["Dihedral Coeffs"].loc[11, "coeff2"] == 0.156 - assert li_ec.force_field["Improper Coeffs"].loc[1, "coeff1"] == 10.5 - assert ec_li.force_field["Improper Coeffs"].loc[1, "coeff1"] == 10.5 + assert li_ec.force_field["Pair Coeffs"].loc[6, "coeff2"] == approx(2.42) + assert ec_li.force_field["Pair Coeffs"].loc[6, "coeff2"] == approx(2.87) + assert li_ec.force_field["Bond Coeffs"].loc[5, "coeff2"] == approx(1.09) + assert ec_li.force_field["Bond Coeffs"].loc[5, "coeff2"] == approx(1.09) + assert li_ec.force_field["Angle Coeffs"].loc[7, "coeff2"] == approx(107.80) + assert ec_li.force_field["Angle Coeffs"].loc[7, "coeff2"] == approx(107.80) + assert li_ec.force_field["Dihedral Coeffs"].loc[11, "coeff2"] == approx(0.156) + assert ec_li.force_field["Dihedral Coeffs"].loc[11, "coeff2"] == approx(0.156) + assert li_ec.force_field["Improper Coeffs"].loc[1, "coeff1"] == approx(10.5) + assert ec_li.force_field["Improper Coeffs"].loc[1, "coeff1"] == approx(10.5) # test combining data with no topo info li_2 = self.li_2 @@ -1079,12 +1079,12 @@ def test_disassemble(self): ("Li1", 6.94), ] assert cd_ff.mass_info == mass_info - np.testing.assert_array_equal(cd_ff.nonbond_coeffs, cd.force_field["Pair Coeffs"].values) + assert_allclose(cd_ff.nonbond_coeffs, cd.force_field["Pair Coeffs"].values) topo = topos[-1] atoms = ld.atoms[ld.atoms["molecule-ID"] == 1] assert_allclose(topo.sites.cart_coords, atoms[["x", "y", "z"]]) - np.testing.assert_array_equal(topo.charges, atoms["q"]) + assert_array_equal(topo.charges, atoms["q"]) atom_labels = [m[0] for m in mass_info] assert topo.sites.site_properties["ff_map"] == [atom_labels[i - 1] for i in atoms["type"]] @@ -1145,20 +1145,20 @@ def test_as_lammpsdata(self): assert ff["Dihedral Coeffs"].shape == (39, 6) assert ff["Improper Coeffs"].shape == (2, 3) # header box - np.testing.assert_array_equal( + assert_allclose( ec_fec.box.bounds, [[-0.597365, 54.56835], [-0.597365, 54.56835], [-0.597365, 54.56835]], ) # body - assert ec_fec.masses.loc[7, "mass"] == 1.008 - assert ff["Pair Coeffs"].loc[9, "coeff2"] == 3.750 - assert ff["Bond Coeffs"].loc[5, "coeff2"] == 1.0900 - assert ff["Angle Coeffs"].loc[24, "coeff2"] == 108.46005 + assert ec_fec.masses.loc[7, "mass"] == approx(1.008) + assert ff["Pair Coeffs"].loc[9, "coeff2"] == approx(3.750) + assert ff["Bond Coeffs"].loc[5, "coeff2"] == approx(1.0900) + assert ff["Angle Coeffs"].loc[24, "coeff2"] == approx(108.46005) assert np.isnan(ff["Dihedral Coeffs"].loc[30, "coeff6"]) - assert ff["Improper Coeffs"].loc[2, "coeff1"] == 10.5 + assert ff["Improper Coeffs"].loc[2, "coeff1"] == approx(10.5) assert ec_fec.atoms.loc[29, "molecule-ID"] == 3 assert ec_fec.atoms.loc[29, "type"] == 5 - assert ec_fec.atoms.loc[29, "q"] == 0.0755 + assert ec_fec.atoms.loc[29, "q"] == approx(0.0755) assert ec_fec.atoms.loc[29, "x"] == approx(14.442260) assert ec_fec.atoms.loc[14958, "molecule-ID"] == 1496 assert ec_fec.atoms.loc[14958, "type"] == 11 diff --git a/tests/io/lammps/test_outputs.py b/tests/io/lammps/test_outputs.py index 6d5e83c3089..05405b74b44 100644 --- a/tests/io/lammps/test_outputs.py +++ b/tests/io/lammps/test_outputs.py @@ -6,7 +6,7 @@ import numpy as np import pandas as pd -from numpy.testing import assert_allclose +from numpy.testing import assert_allclose, assert_array_equal from pymatgen.io.lammps.outputs import LammpsDump, parse_lammps_dumps, parse_lammps_log from pymatgen.util.testing import TEST_FILES_DIR @@ -27,8 +27,8 @@ def setUpClass(cls): def test_from_str(self): assert self.rdx.timestep == 100 assert self.rdx.natoms == 21 - np.testing.assert_array_equal(self.rdx.box.bounds, np.array([(35, 48)] * 3)) - np.testing.assert_array_equal(self.rdx.data.columns, ["id", "type", "xs", "ys", "zs"]) + assert_array_equal(self.rdx.box.bounds, np.array([(35, 48)] * 3)) + assert list(self.rdx.data.columns) == ["id", "type", "xs", "ys", "zs"] rdx_data = self.rdx.data.iloc[-1] rdx_data_target = [19, 2, 0.42369, 0.47347, 0.555425] assert_allclose(rdx_data, rdx_data_target) @@ -39,7 +39,7 @@ def test_from_str(self): assert_allclose(self.tatb.box.bounds, bounds) tilt = [-5.75315630927, -6.325466, 7.4257288] assert_allclose(self.tatb.box.tilt, tilt) - np.testing.assert_array_equal(self.tatb.data.columns, ["id", "type", "q", "x", "y", "z"]) + assert list(self.tatb.data.columns) == ["id", "type", "q", "x", "y", "z"] tatb_data = self.tatb.data.iloc[-1] tatb_data_target = [356, 3, -0.482096, 2.58647, 12.9577, 14.3143] assert_allclose(tatb_data, tatb_data_target) @@ -50,7 +50,7 @@ def test_json_dict(self): rdx = LammpsDump.from_dict(decoded) assert rdx.timestep == 100 assert rdx.natoms == 21 - np.testing.assert_array_equal(rdx.box.bounds, np.array([(35, 48)] * 3)) + assert_array_equal(rdx.box.bounds, np.array([(35, 48)] * 3)) pd.testing.assert_frame_equal(rdx.data, self.rdx.data) @@ -60,13 +60,13 @@ def test_parse_lammps_dumps(self): rdx_10_pattern = f"{TEST_DIR}/dump.rdx.gz" rdx_10 = list(parse_lammps_dumps(file_pattern=rdx_10_pattern)) time_steps_10 = [d.timestep for d in rdx_10] - np.testing.assert_array_equal(time_steps_10, np.arange(0, 101, 10)) + assert_array_equal(time_steps_10, np.arange(0, 101, 10)) assert rdx_10[-1].data.shape == (21, 5) # wildcard rdx_25_pattern = f"{TEST_DIR}{os.path.sep}dump.rdx_wc.*" rdx_25 = list(parse_lammps_dumps(file_pattern=rdx_25_pattern)) time_steps_25 = [d.timestep for d in rdx_25] - np.testing.assert_array_equal(time_steps_25, np.arange(0, 101, 25)) + assert_array_equal(time_steps_25, np.arange(0, 101, 25)) assert rdx_25[-1].data.shape == (21, 5) def test_parse_lammps_log(self): @@ -75,7 +75,7 @@ def test_parse_lammps_log(self): assert len(comb) == 6 # first comb run comb0 = comb[0] - np.testing.assert_array_equal(["Step", "Temp", "TotEng", "PotEng", "E_vdwl", "E_coul"], comb0.columns) + assert list(comb0.columns) == ["Step", "Temp", "TotEng", "PotEng", "E_vdwl", "E_coul"] assert len(comb0) == 6 comb0_data = [ [0, 1, -4.6295947, -4.6297237, -4.6297237, 0], @@ -84,24 +84,21 @@ def test_parse_lammps_log(self): assert_allclose(comb0.iloc[[0, -1]], comb0_data) # final comb run comb_1 = comb[-1] - np.testing.assert_array_equal( - [ - "Step", - "Lx", - "Ly", - "Lz", - "Xy", - "Xz", - "Yz", - "c_fxy[1]", - "c_fxy[2]", - "c_fxy[3]", - "c_fxy[4]", - "c_fxy[5]", - "c_fxy[6]", - ], - comb_1.columns, - ) + assert list(comb_1.columns) == [ + "Step", + "Lx", + "Ly", + "Lz", + "Xy", + "Xz", + "Yz", + "c_fxy[1]", + "c_fxy[2]", + "c_fxy[3]", + "c_fxy[4]", + "c_fxy[5]", + "c_fxy[6]", + ] assert len(comb_1) == 11 comb_1_data = [[36, 5.1293854e-06], [46, 2192.8256]] assert_allclose(comb_1.iloc[[0, -1], [0, -3]], comb_1_data) @@ -111,7 +108,7 @@ def test_parse_lammps_log(self): assert len(ehex) == 3 ehex0, ehex1, ehex2 = ehex # ehex run #1 - np.testing.assert_array_equal(["Step", "Temp", "E_pair", "E_mol", "TotEng", "Press"], ehex0.columns) + assert list(ehex0.columns) == ["Step", "Temp", "E_pair", "E_mol", "TotEng", "Press"] assert len(ehex0) == 11 ehex0_data = [ [0, 1.35, -4.1241917, 0, -2.0994448, -3.1961612], @@ -119,7 +116,7 @@ def test_parse_lammps_log(self): ] assert_allclose(ehex0.iloc[[0, -1]], ehex0_data) # ehex run #2 - np.testing.assert_array_equal(["Step", "Temp", "c_Thot", "c_Tcold"], ehex1.columns) + assert list(ehex1.columns) == ["Step", "Temp", "c_Thot", "c_Tcold"] assert len(ehex1) == 11 ehex1_data = [ [1000, 1.35, 1.431295, 1.2955644], @@ -127,7 +124,7 @@ def test_parse_lammps_log(self): ] assert_allclose(ehex1.iloc[[0, -1]], ehex1_data) # ehex run #3 - np.testing.assert_array_equal(["Step", "Temp", "c_Thot", "c_Tcold", "v_tdiff", "f_ave"], ehex2.columns) + assert list(ehex2.columns) == ["Step", "Temp", "c_Thot", "c_Tcold", "v_tdiff", "f_ave"] assert len(ehex2) == 21 ehex2_data = [ [11000, 1.3794051, 1.6903393, 1.0515688, 0, 0], @@ -138,24 +135,22 @@ def test_parse_lammps_log(self): peptide_file = "log.5Oct16.peptide.g++.1.gz" peptide = parse_lammps_log(filename=f"{TEST_DIR}/{peptide_file}") peptide0 = peptide[0] - np.testing.assert_array_equal( - [ - "Step", - "TotEng", - "KinEng", - "Temp", - "PotEng", - "E_bond", - "E_angle", - "E_dihed", - "E_impro", - "E_vdwl", - "E_coul", - "E_long", - "Press", - ], - peptide0.columns, - ) + assert list(peptide0.columns) == [ + "Step", + "TotEng", + "KinEng", + "Temp", + "PotEng", + "E_bond", + "E_angle", + "E_dihed", + "E_impro", + "E_vdwl", + "E_coul", + "E_long", + "Press", + ] + assert len(peptide0) == 7 peptide0_select = peptide0.loc[[0, 6], ["Step", "TotEng", "Press"]] peptide0_data = [[0, -5237.4580, -837.0112], [300, -5251.3637, -471.5505]] diff --git a/tests/io/lobster/test_inputs.py b/tests/io/lobster/test_inputs.py index 59960d5970f..689145ff20f 100644 --- a/tests/io/lobster/test_inputs.py +++ b/tests/io/lobster/test_inputs.py @@ -258,8 +258,8 @@ def test_standard_with_energy_range_from_vasprun(self): f"{VASP_OUT_DIR}/vasprun.C2.xml.gz", option="standard_with_energy_range_from_vasprun", ) - assert lobsterin_comp["COHPstartEnergy"] == -28.3679 - assert lobsterin_comp["COHPendEnergy"] == 32.8968 + assert lobsterin_comp["COHPstartEnergy"] == approx(-28.3679) + assert lobsterin_comp["COHPendEnergy"] == approx(32.8968) assert lobsterin_comp["COHPSteps"] == 301 def test_diff(self): @@ -299,11 +299,11 @@ def test_diff_case_insensitivity(self): def test_dict_functionality(self): for key in ("COHPstartEnergy", "COHPstartEnergy", "COhPstartenergy"): start_energy = self.Lobsterin.get(key) - assert start_energy == -15.0, f"{start_energy=}, {key=}" + assert start_energy == approx(-15.0), f"{start_energy=}, {key=}" lobsterin_copy = self.Lobsterin.copy() lobsterin_copy.update({"cohpstarteNergy": -10.00}) - assert lobsterin_copy["cohpstartenergy"] == -10.0 + assert lobsterin_copy["cohpstartenergy"] == approx(-10.0) lobsterin_copy.pop("cohpstarteNergy") assert "cohpstartenergy" not in lobsterin_copy lobsterin_copy.pop("cohpendenergY") diff --git a/tests/io/lobster/test_lobsterenv.py b/tests/io/lobster/test_lobsterenv.py index 4f9cc9959b8..1d56695803a 100644 --- a/tests/io/lobster/test_lobsterenv.py +++ b/tests/io/lobster/test_lobsterenv.py @@ -4,6 +4,7 @@ import numpy as np import pytest +from numpy.testing import assert_allclose from pytest import approx from pymatgen.analysis.graphs import StructureGraph @@ -910,5 +911,5 @@ def test_valences(self): -0.54, -0.54, ] - assert self.chem_env_w_obj.valences == [0.67] * 4 + [0.7] * 4 + [-0.7] * 4 + [-0.68] * 4 # charge_obj + assert_allclose(self.chem_env_w_obj.valences, [0.67] * 4 + [0.7] * 4 + [-0.7] * 4 + [-0.68] * 4) # charge_obj assert self.chem_env_lobster_NaSi_wo_charges.valences == [1] * 8 + [-1] * 8 # BVA diff --git a/tests/io/lobster/test_outputs.py b/tests/io/lobster/test_outputs.py index 4dac8c4a01b..aae9d1e4bb5 100644 --- a/tests/io/lobster/test_outputs.py +++ b/tests/io/lobster/test_outputs.py @@ -180,13 +180,13 @@ def test_energies(self): efermi_KF = -2.87475 elim_KF = (-11.25000 + efermi_KF, 7.5000 + efermi_KF) - assert self.cohp_bise.efermi == efermi_bise - assert self.coop_bise.efermi == efermi_bise - assert self.cohp_fe.efermi == efermi_fe - assert self.coop_fe.efermi == efermi_fe + assert self.cohp_bise.efermi == approx(efermi_bise) + assert self.coop_bise.efermi == approx(efermi_bise) + assert self.cohp_fe.efermi == approx(efermi_fe) + assert self.coop_fe.efermi == approx(efermi_fe) # Lobster 3.1 - assert self.cohp_KF.efermi == efermi_KF - assert self.coop_KF.efermi == efermi_KF + assert self.cohp_KF.efermi == approx(efermi_KF) + assert self.coop_KF.efermi == approx(efermi_KF) assert self.cohp_bise.energies[0] + self.cohp_bise.efermi == approx(elim_bise[0], abs=1e-4) assert self.cohp_bise.energies[-1] + self.cohp_bise.efermi == approx(elim_bise[1], abs=1e-4) @@ -444,9 +444,9 @@ def test_complete_dos(self): pdos_f_2px_up = [0.00000, 0.00160, 0.00000, 0.25805, 0.00000, 0.00029] pdos_f_2px_down = [0.00000, 0.00161, 0.00000, 0.25814, 0.00000, 0.00029] - assert energies_spin == self.DOSCAR_spin_pol.completedos.energies.tolist() - assert tdos_up == self.DOSCAR_spin_pol.completedos.densities[Spin.up].tolist() - assert tdos_down == self.DOSCAR_spin_pol.completedos.densities[Spin.down].tolist() + assert_allclose(energies_spin, self.DOSCAR_spin_pol.completedos.energies) + assert_allclose(tdos_up, self.DOSCAR_spin_pol.completedos.densities[Spin.up]) + assert_allclose(tdos_down, self.DOSCAR_spin_pol.completedos.densities[Spin.down]) assert fermi == approx(self.DOSCAR_spin_pol.completedos.efermi) assert_allclose( @@ -457,14 +457,14 @@ def test_complete_dos(self): self.DOSCAR_spin_pol2.completedos.structure.frac_coords, self.structure.frac_coords, ) - assert self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]["2s"][Spin.up].tolist() == pdos_f_2s_up - assert self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]["2s"][Spin.down].tolist() == pdos_f_2s_down - assert self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]["2p_y"][Spin.up].tolist() == pdos_f_2py_up - assert self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]["2p_y"][Spin.down].tolist() == pdos_f_2py_down - assert self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]["2p_z"][Spin.up].tolist() == pdos_f_2pz_up - assert self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]["2p_z"][Spin.down].tolist() == pdos_f_2pz_down - assert self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]["2p_x"][Spin.up].tolist() == pdos_f_2px_up - assert self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]["2p_x"][Spin.down].tolist() == pdos_f_2px_down + assert_allclose(self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]["2s"][Spin.up], pdos_f_2s_up) + assert_allclose(self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]["2s"][Spin.down], pdos_f_2s_down) + assert_allclose(self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]["2p_y"][Spin.up], pdos_f_2py_up) + assert_allclose(self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]["2p_y"][Spin.down], pdos_f_2py_down) + assert_allclose(self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]["2p_z"][Spin.up], pdos_f_2pz_up) + assert_allclose(self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]["2p_z"][Spin.down], pdos_f_2pz_down) + assert_allclose(self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]["2p_x"][Spin.up], pdos_f_2px_up) + assert_allclose(self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]["2p_x"][Spin.down], pdos_f_2px_down) energies_nonspin = [-11.25000, -7.50000, -3.75000, 0.00000, 3.75000, 7.50000] tdos_nonspin = [0.00000, 1.60000, 0.00000, 1.60000, 0.00000, 0.02418] @@ -473,18 +473,18 @@ def test_complete_dos(self): pdos_f_2pz = [0.00000, 0.00322, 0.00000, 0.51636, 0.00000, 0.00037] pdos_f_2px = [0.00000, 0.00322, 0.00000, 0.51634, 0.00000, 0.00037] - assert energies_nonspin == self.DOSCAR_nonspin_pol.completedos.energies.tolist() + assert_allclose(energies_nonspin, self.DOSCAR_nonspin_pol.completedos.energies) - assert tdos_nonspin == self.DOSCAR_nonspin_pol.completedos.densities[Spin.up].tolist() + assert_allclose(tdos_nonspin, self.DOSCAR_nonspin_pol.completedos.densities[Spin.up]) assert fermi == approx(self.DOSCAR_nonspin_pol.completedos.efermi) assert self.DOSCAR_nonspin_pol.completedos.structure == self.structure - assert self.DOSCAR_nonspin_pol.completedos.pdos[self.structure[0]]["2s"][Spin.up].tolist() == pdos_f_2s - assert self.DOSCAR_nonspin_pol.completedos.pdos[self.structure[0]]["2p_y"][Spin.up].tolist() == pdos_f_2py - assert self.DOSCAR_nonspin_pol.completedos.pdos[self.structure[0]]["2p_z"][Spin.up].tolist() == pdos_f_2pz - assert self.DOSCAR_nonspin_pol.completedos.pdos[self.structure[0]]["2p_x"][Spin.up].tolist() == pdos_f_2px + assert_allclose(self.DOSCAR_nonspin_pol.completedos.pdos[self.structure[0]]["2s"][Spin.up], pdos_f_2s) + assert_allclose(self.DOSCAR_nonspin_pol.completedos.pdos[self.structure[0]]["2p_y"][Spin.up], pdos_f_2py) + assert_allclose(self.DOSCAR_nonspin_pol.completedos.pdos[self.structure[0]]["2p_z"][Spin.up], pdos_f_2pz) + assert_allclose(self.DOSCAR_nonspin_pol.completedos.pdos[self.structure[0]]["2p_x"][Spin.up], pdos_f_2px) def test_pdos(self): # first for spin polarized version @@ -498,14 +498,14 @@ def test_pdos(self): pdos_f_2px_up = [0.00000, 0.00160, 0.00000, 0.25805, 0.00000, 0.00029] pdos_f_2px_down = [0.00000, 0.00161, 0.00000, 0.25814, 0.00000, 0.00029] - assert self.DOSCAR_spin_pol.pdos[0]["2s"][Spin.up].tolist() == pdos_f_2s_up - assert self.DOSCAR_spin_pol.pdos[0]["2s"][Spin.down].tolist() == pdos_f_2s_down - assert self.DOSCAR_spin_pol.pdos[0]["2p_y"][Spin.up].tolist() == pdos_f_2py_up - assert self.DOSCAR_spin_pol.pdos[0]["2p_y"][Spin.down].tolist() == pdos_f_2py_down - assert self.DOSCAR_spin_pol.pdos[0]["2p_z"][Spin.up].tolist() == pdos_f_2pz_up - assert self.DOSCAR_spin_pol.pdos[0]["2p_z"][Spin.down].tolist() == pdos_f_2pz_down - assert self.DOSCAR_spin_pol.pdos[0]["2p_x"][Spin.up].tolist() == pdos_f_2px_up - assert self.DOSCAR_spin_pol.pdos[0]["2p_x"][Spin.down].tolist() == pdos_f_2px_down + assert_allclose(self.DOSCAR_spin_pol.pdos[0]["2s"][Spin.up], pdos_f_2s_up) + assert_allclose(self.DOSCAR_spin_pol.pdos[0]["2s"][Spin.down], pdos_f_2s_down) + assert_allclose(self.DOSCAR_spin_pol.pdos[0]["2p_y"][Spin.up], pdos_f_2py_up) + assert_allclose(self.DOSCAR_spin_pol.pdos[0]["2p_y"][Spin.down], pdos_f_2py_down) + assert_allclose(self.DOSCAR_spin_pol.pdos[0]["2p_z"][Spin.up], pdos_f_2pz_up) + assert_allclose(self.DOSCAR_spin_pol.pdos[0]["2p_z"][Spin.down], pdos_f_2pz_down) + assert_allclose(self.DOSCAR_spin_pol.pdos[0]["2p_x"][Spin.up], pdos_f_2px_up) + assert_allclose(self.DOSCAR_spin_pol.pdos[0]["2p_x"][Spin.down], pdos_f_2px_down) # non spin pdos_f_2s = [0.00000, 0.00320, 0.00000, 0.00017, 0.00000, 0.00060] @@ -513,10 +513,10 @@ def test_pdos(self): pdos_f_2pz = [0.00000, 0.00322, 0.00000, 0.51636, 0.00000, 0.00037] pdos_f_2px = [0.00000, 0.00322, 0.00000, 0.51634, 0.00000, 0.00037] - assert self.DOSCAR_nonspin_pol.pdos[0]["2s"][Spin.up].tolist() == pdos_f_2s - assert self.DOSCAR_nonspin_pol.pdos[0]["2p_y"][Spin.up].tolist() == pdos_f_2py - assert self.DOSCAR_nonspin_pol.pdos[0]["2p_z"][Spin.up].tolist() == pdos_f_2pz - assert self.DOSCAR_nonspin_pol.pdos[0]["2p_x"][Spin.up].tolist() == pdos_f_2px + assert_allclose(self.DOSCAR_nonspin_pol.pdos[0]["2s"][Spin.up], pdos_f_2s) + assert_allclose(self.DOSCAR_nonspin_pol.pdos[0]["2p_y"][Spin.up], pdos_f_2py) + assert_allclose(self.DOSCAR_nonspin_pol.pdos[0]["2p_z"][Spin.up], pdos_f_2pz) + assert_allclose(self.DOSCAR_nonspin_pol.pdos[0]["2p_x"][Spin.up], pdos_f_2px) # test with DOSCAR.LCFO.lobster file pdos_1a1_AlN = [ @@ -560,9 +560,9 @@ def test_pdos(self): ] assert self.DOSCAR_lcfo._is_lcfo - assert self.DOSCAR_lcfo.pdos[0]["1a1"][Spin.down].tolist() == pdos_1a1_AlN - assert self.DOSCAR_lcfo.pdos[1]["3p_y"][Spin.down].tolist() == pdos_3py_Al - assert self.DOSCAR_lcfo.pdos[2]["2s"][Spin.down].tolist() == pdos_2s_N + assert_allclose(self.DOSCAR_lcfo.pdos[0]["1a1"][Spin.down], pdos_1a1_AlN) + assert_allclose(self.DOSCAR_lcfo.pdos[1]["3p_y"][Spin.down], pdos_3py_Al) + assert_allclose(self.DOSCAR_lcfo.pdos[2]["2s"][Spin.down], pdos_2s_N) def test_tdos(self): # first for spin polarized version @@ -571,38 +571,38 @@ def test_tdos(self): tdos_down = [0.00000, 0.79999, 0.00000, 0.79999, 0.00000, 0.02586] fermi = 0.0 - assert energies_spin == self.DOSCAR_spin_pol.tdos.energies.tolist() - assert tdos_up == self.DOSCAR_spin_pol.tdos.densities[Spin.up].tolist() - assert tdos_down == self.DOSCAR_spin_pol.tdos.densities[Spin.down].tolist() + assert_allclose(energies_spin, self.DOSCAR_spin_pol.tdos.energies) + assert_allclose(tdos_up, self.DOSCAR_spin_pol.tdos.densities[Spin.up]) + assert_allclose(tdos_down, self.DOSCAR_spin_pol.tdos.densities[Spin.down]) assert fermi == approx(self.DOSCAR_spin_pol.tdos.efermi) energies_nonspin = [-11.25000, -7.50000, -3.75000, 0.00000, 3.75000, 7.50000] tdos_nonspin = [0.00000, 1.60000, 0.00000, 1.60000, 0.00000, 0.02418] fermi = 0.0 - assert energies_nonspin == self.DOSCAR_nonspin_pol.tdos.energies.tolist() - assert tdos_nonspin == self.DOSCAR_nonspin_pol.tdos.densities[Spin.up].tolist() + assert_allclose(energies_nonspin, self.DOSCAR_nonspin_pol.tdos.energies) + assert_allclose(tdos_nonspin, self.DOSCAR_nonspin_pol.tdos.densities[Spin.up]) assert fermi == approx(self.DOSCAR_nonspin_pol.tdos.efermi) def test_energies(self): # first for spin polarized version energies_spin = [-11.25000, -7.50000, -3.75000, 0.00000, 3.75000, 7.50000] - assert energies_spin == self.DOSCAR_spin_pol.energies.tolist() + assert_allclose(energies_spin, self.DOSCAR_spin_pol.energies) energies_nonspin = [-11.25000, -7.50000, -3.75000, 0.00000, 3.75000, 7.50000] - assert energies_nonspin == self.DOSCAR_nonspin_pol.energies.tolist() + assert_allclose(energies_nonspin, self.DOSCAR_nonspin_pol.energies) def test_tdensities(self): # first for spin polarized version tdos_up = [0.00000, 0.79999, 0.00000, 0.79999, 0.00000, 0.02577] tdos_down = [0.00000, 0.79999, 0.00000, 0.79999, 0.00000, 0.02586] - assert tdos_up == self.DOSCAR_spin_pol.tdensities[Spin.up].tolist() - assert tdos_down == self.DOSCAR_spin_pol.tdensities[Spin.down].tolist() + assert_allclose(tdos_up, self.DOSCAR_spin_pol.tdensities[Spin.up]) + assert_allclose(tdos_down, self.DOSCAR_spin_pol.tdensities[Spin.down]) tdos_nonspin = [0.00000, 1.60000, 0.00000, 1.60000, 0.00000, 0.02418] - assert tdos_nonspin == self.DOSCAR_nonspin_pol.tdensities[Spin.up].tolist() + assert_allclose(tdos_nonspin, self.DOSCAR_nonspin_pol.tdensities[Spin.up]) # test with DOSCAR.LCFO.lobster file tdos_up = [ @@ -619,16 +619,16 @@ def test_tdensities(self): 1.04535, ] - assert tdos_up == self.DOSCAR_lcfo.tdensities[Spin.up].tolist() + assert_allclose(tdos_up, self.DOSCAR_lcfo.tdensities[Spin.up]) def test_itdensities(self): itdos_up = [1.99997, 4.99992, 4.99992, 7.99987, 7.99987, 8.09650] itdos_down = [1.99997, 4.99992, 4.99992, 7.99987, 7.99987, 8.09685] - assert itdos_up == self.DOSCAR_spin_pol.itdensities[Spin.up].tolist() - assert itdos_down == self.DOSCAR_spin_pol.itdensities[Spin.down].tolist() + assert_allclose(itdos_up, self.DOSCAR_spin_pol.itdensities[Spin.up]) + assert_allclose(itdos_down, self.DOSCAR_spin_pol.itdensities[Spin.down]) itdos_nonspin = [4.00000, 10.00000, 10.00000, 16.00000, 16.00000, 16.09067] - assert itdos_nonspin == self.DOSCAR_nonspin_pol.itdensities[Spin.up].tolist() + assert_allclose(itdos_nonspin, self.DOSCAR_nonspin_pol.itdensities[Spin.up]) def test_is_spin_polarized(self): # first for spin polarized version @@ -661,7 +661,7 @@ def test_attributes(self): assert self.charge_lcfo.num_atoms == 3 assert self.charge_lcfo.types == ["AlN", "Al", "N"] assert self.charge_lcfo.atomlist == ["AlN1", "Al2", "N3"] - assert self.charge_lcfo.loewdin == [0.0, 1.02, -1.02] + assert_allclose(self.charge_lcfo.loewdin, [0.0, 1.02, -1.02]) assert not self.charge_lcfo.mulliken def test_get_structure_with_charges(self): @@ -755,7 +755,7 @@ def test_attributes(self): ] ] assert self.lobsterout_normal.basis_type == ["pbeVaspFit2015"] - assert self.lobsterout_normal.charge_spilling == [0.0268] + assert_allclose(self.lobsterout_normal.charge_spilling, [0.0268]) assert self.lobsterout_normal.dft_program == "VASP" assert self.lobsterout_normal.elements == ["Ti"] assert self.lobsterout_normal.has_charge @@ -808,7 +808,7 @@ def test_attributes(self): ] ] assert self.lobsterout_fatband_grosspop_densityofenergies.basis_type == ["pbeVaspFit2015"] - assert self.lobsterout_fatband_grosspop_densityofenergies.charge_spilling == [0.0268] + assert_allclose(self.lobsterout_fatband_grosspop_densityofenergies.charge_spilling, [0.0268]) assert self.lobsterout_fatband_grosspop_densityofenergies.dft_program == "VASP" assert self.lobsterout_fatband_grosspop_densityofenergies.elements == ["Ti"] assert self.lobsterout_fatband_grosspop_densityofenergies.has_charge @@ -861,7 +861,7 @@ def test_attributes(self): ] ] assert self.lobsterout_saveprojection.basis_type == ["pbeVaspFit2015"] - assert self.lobsterout_saveprojection.charge_spilling == [0.0268] + assert_allclose(self.lobsterout_saveprojection.charge_spilling, [0.0268]) assert self.lobsterout_saveprojection.dft_program == "VASP" assert self.lobsterout_saveprojection.elements == ["Ti"] assert self.lobsterout_saveprojection.has_charge @@ -914,7 +914,7 @@ def test_attributes(self): ] ] assert self.lobsterout_skipping_all.basis_type == ["pbeVaspFit2015"] - assert self.lobsterout_skipping_all.charge_spilling == [0.0268] + assert_allclose(self.lobsterout_skipping_all.charge_spilling, [0.0268]) assert self.lobsterout_skipping_all.dft_program == "VASP" assert self.lobsterout_skipping_all.elements == ["Ti"] assert not self.lobsterout_skipping_all.has_charge @@ -1078,7 +1078,7 @@ def test_attributes(self): "user_time": {"h": "0", "min": "0", "s": "12", "ms": "370"}, "sys_time": {"h": "0", "min": "0", "s": "0", "ms": "180"}, } - assert self.lobsterout_GaAs.total_spilling[0] == approx([0.0859][0]) + assert self.lobsterout_GaAs.total_spilling[0] == approx(0.0859) assert self.lobsterout_onethread.number_of_threads == 1 # Test lobsterout of lobster-4.1.0 @@ -1292,35 +1292,35 @@ def setUp(self): self.bs_symmline_spin = self.vasprun_SiO2_p.get_band_structure(line_mode=True, force_hybrid_mode=True) def test_attributes(self): - assert list(self.fatband_SiO2_p_x.label_dict["M"]) == approx([0.5, 0.0, 0.0]) + assert_allclose(list(self.fatband_SiO2_p_x.label_dict["M"]), [0.5, 0.0, 0.0]) assert self.fatband_SiO2_p_x.efermi == self.vasprun_SiO2_p_x.efermi lattice1 = self.bs_symmline.lattice_rec.as_dict() lattice2 = self.fatband_SiO2_p_x.lattice.as_dict() for idx in range(3): assert lattice1["matrix"][idx] == approx(lattice2["matrix"][idx]) - assert self.fatband_SiO2_p_x.eigenvals[Spin.up][1][1] - self.fatband_SiO2_p_x.efermi == -18.245 + assert self.fatband_SiO2_p_x.eigenvals[Spin.up][1][1] - self.fatband_SiO2_p_x.efermi == approx(-18.245) assert self.fatband_SiO2_p_x.is_spinpolarized is False - assert self.fatband_SiO2_p_x.kpoints_array[3] == approx([0.03409091, 0, 0]) + assert_allclose(self.fatband_SiO2_p_x.kpoints_array[3], [0.03409091, 0, 0]) assert self.fatband_SiO2_p_x.nbands == 36 - assert self.fatband_SiO2_p_x.p_eigenvals[Spin.up][2][1]["Si1"]["3p_x"] == 0.002 - assert self.fatband_SiO2_p_x.structure[0].frac_coords == approx([0.0, 0.47634315, 0.666667]) + assert self.fatband_SiO2_p_x.p_eigenvals[Spin.up][2][1]["Si1"]["3p_x"] == approx(0.002) + assert_allclose(self.fatband_SiO2_p_x.structure[0].frac_coords, [0.0, 0.47634315, 0.666667]) assert self.fatband_SiO2_p_x.structure[0].species_string == "Si" - assert self.fatband_SiO2_p_x.structure[0].coords == approx([-1.19607309, 2.0716597, 3.67462144]) + assert_allclose(self.fatband_SiO2_p_x.structure[0].coords, [-1.19607309, 2.0716597, 3.67462144]) - assert list(self.fatband_SiO2_p.label_dict["M"]) == approx([0.5, 0.0, 0.0]) + assert_allclose(list(self.fatband_SiO2_p.label_dict["M"]), [0.5, 0.0, 0.0]) assert self.fatband_SiO2_p.efermi == self.vasprun_SiO2_p.efermi lattice1 = self.bs_symmline2.lattice_rec.as_dict() lattice2 = self.fatband_SiO2_p.lattice.as_dict() for idx in range(3): assert lattice1["matrix"][idx] == approx(lattice2["matrix"][idx]) - assert self.fatband_SiO2_p.eigenvals[Spin.up][1][1] - self.fatband_SiO2_p.efermi == -18.245 + assert self.fatband_SiO2_p.eigenvals[Spin.up][1][1] - self.fatband_SiO2_p.efermi == approx(-18.245) assert self.fatband_SiO2_p.is_spinpolarized is False - assert self.fatband_SiO2_p.kpoints_array[3] == approx([0.03409091, 0, 0]) + assert_allclose(self.fatband_SiO2_p.kpoints_array[3], [0.03409091, 0, 0]) assert self.fatband_SiO2_p.nbands == 36 - assert self.fatband_SiO2_p.p_eigenvals[Spin.up][2][1]["Si1"]["3p"] == 0.042 - assert self.fatband_SiO2_p.structure[0].frac_coords == approx([0.0, 0.47634315, 0.666667]) + assert self.fatband_SiO2_p.p_eigenvals[Spin.up][2][1]["Si1"]["3p"] == approx(0.042) + assert_allclose(self.fatband_SiO2_p.structure[0].frac_coords, [0.0, 0.47634315, 0.666667]) assert self.fatband_SiO2_p.structure[0].species_string == "Si" - assert self.fatband_SiO2_p.structure[0].coords == approx([-1.19607309, 2.0716597, 3.67462144]) + assert_allclose(self.fatband_SiO2_p.structure[0].coords, [-1.19607309, 2.0716597, 3.67462144]) assert self.fatband_SiO2_p.efermi == approx(1.0647039) assert list(self.fatband_SiO2_spin.label_dict["M"]) == approx([0.5, 0.0, 0.0]) @@ -1329,16 +1329,16 @@ def test_attributes(self): lattice2 = self.fatband_SiO2_spin.lattice.as_dict() for idx in range(3): assert lattice1["matrix"][idx] == approx(lattice2["matrix"][idx]) - assert self.fatband_SiO2_spin.eigenvals[Spin.up][1][1] - self.fatband_SiO2_spin.efermi == -18.245 - assert self.fatband_SiO2_spin.eigenvals[Spin.down][1][1] - self.fatband_SiO2_spin.efermi == -18.245 + assert self.fatband_SiO2_spin.eigenvals[Spin.up][1][1] - self.fatband_SiO2_spin.efermi == approx(-18.245) + assert self.fatband_SiO2_spin.eigenvals[Spin.down][1][1] - self.fatband_SiO2_spin.efermi == approx(-18.245) assert self.fatband_SiO2_spin.is_spinpolarized - assert self.fatband_SiO2_spin.kpoints_array[3] == approx([0.03409091, 0, 0]) + assert_allclose(self.fatband_SiO2_spin.kpoints_array[3], [0.03409091, 0, 0]) assert self.fatband_SiO2_spin.nbands == 36 - assert self.fatband_SiO2_spin.p_eigenvals[Spin.up][2][1]["Si1"]["3p"] == 0.042 - assert self.fatband_SiO2_spin.structure[0].frac_coords == approx([0.0, 0.47634315, 0.666667]) + assert self.fatband_SiO2_spin.p_eigenvals[Spin.up][2][1]["Si1"]["3p"] == approx(0.042) + assert_allclose(self.fatband_SiO2_spin.structure[0].frac_coords, [0.0, 0.47634315, 0.666667]) assert self.fatband_SiO2_spin.structure[0].species_string == "Si" - assert self.fatband_SiO2_spin.structure[0].coords == approx([-1.19607309, 2.0716597, 3.67462144]) + assert_allclose(self.fatband_SiO2_spin.structure[0].coords, [-1.19607309, 2.0716597, 3.67462144]) def test_raises(self): with pytest.raises(ValueError, match="vasprun_file or efermi have to be provided"): @@ -2132,19 +2132,21 @@ def test_values(self): } assert icohplist_bise == self.icohp_bise.icohplist - assert self.icohp_bise.icohpcollection.extremum_icohpvalue() == -2.38796 + assert self.icohp_bise.icohpcollection.extremum_icohpvalue() == approx(-2.38796) assert icooplist_fe == self.icoop_fe.icohplist - assert self.icoop_fe.icohpcollection.extremum_icohpvalue() == -0.29919 + assert self.icoop_fe.icohpcollection.extremum_icohpvalue() == approx(-0.29919) assert icooplist_bise == self.icoop_bise.icohplist - assert self.icoop_bise.icohpcollection.extremum_icohpvalue() == 0.24714 + assert self.icoop_bise.icohpcollection.extremum_icohpvalue() == approx(0.24714) assert self.icobi.icohplist["1"]["icohp"][Spin.up] == approx(0.58649) assert self.icobi_orbitalwise.icohplist["2"]["icohp"][Spin.up] == approx(0.58649) assert self.icobi_orbitalwise.icohplist["1"]["icohp"][Spin.up] == approx(0.58649) assert self.icobi_orbitalwise_spinpolarized.icohplist["1"]["icohp"][Spin.up] == approx(0.58649 / 2, abs=1e-3) assert self.icobi_orbitalwise_spinpolarized.icohplist["1"]["icohp"][Spin.down] == approx(0.58649 / 2, abs=1e-3) assert self.icobi_orbitalwise_spinpolarized.icohplist["2"]["icohp"][Spin.down] == approx(0.58649 / 2, abs=1e-3) - assert self.icobi.icohpcollection.extremum_icohpvalue() == 0.58649 - assert self.icobi_orbitalwise_spinpolarized.icohplist["2"]["orbitals"]["2s-6s"]["icohp"][Spin.up] == 0.0247 + assert self.icobi.icohpcollection.extremum_icohpvalue() == approx(0.58649) + assert self.icobi_orbitalwise_spinpolarized.icohplist["2"]["orbitals"]["2s-6s"]["icohp"][Spin.up] == approx( + 0.0247 + ) # >v5 ICOHPLIST assert self.icohp_aln_511_sp.icohplist["2"]["icohp"][Spin.up] == approx(-0.21482) @@ -2351,7 +2353,7 @@ def setUp(self) -> None: def test_attributes(self): # hamilton matrices - assert self.hamilton_matrices.average_onsite_energies == pytest.approx( + assert self.hamilton_matrices.average_onsite_energies == approx( { "Na1_3s": 0.58855353, "Na1_2p_y": -25.72719646, @@ -2384,7 +2386,7 @@ def test_attributes(self): ) # overlap matrices - assert self.overlap_matrices.average_onsite_overlaps == pytest.approx( + assert self.overlap_matrices.average_onsite_overlaps == approx( { "Si1_3s": 1.00000009, "Si1_3p_y": 0.99999995, @@ -2446,7 +2448,7 @@ def test_attributes(self): Spin.up, Spin.down, ] - assert self.coeff_matrices.average_onsite_coefficient == pytest.approx( + assert self.coeff_matrices.average_onsite_coefficient == approx( { "Si1_3s": 0.6232626450000001, "Si1_3p_y": -0.029367565000000012, diff --git a/tests/io/pwmat/test_inputs.py b/tests/io/pwmat/test_inputs.py index 7618e7ecdf6..3d6277562c2 100644 --- a/tests/io/pwmat/test_inputs.py +++ b/tests/io/pwmat/test_inputs.py @@ -6,6 +6,7 @@ import pytest from monty.io import zopen from numpy.testing import assert_allclose +from pytest import approx import pymatgen from pymatgen.core import Composition, Structure @@ -88,7 +89,7 @@ def test_from_structure(self): filepath = f"{TEST_DIR}/atom.config" structure = Structure.from_file(filepath) gen_kpt = GenKpt.from_structure(structure, dim=2, density=0.01) - assert gen_kpt.density == pytest.approx(0.0628318530) + assert gen_kpt.density == approx(0.0628318530) assert gen_kpt.reciprocal_lattice.shape == (3, 3) assert gen_kpt.kpath["path"] == [["GAMMA", "M", "K", "GAMMA"]] @@ -115,7 +116,7 @@ def test_from_structure(self): high_symmetry_points = HighSymmetryPoint.from_structure(structure, dim=2, density=0.01) assert list(high_symmetry_points.kpath) == ["kpoints", "path"] assert len(high_symmetry_points.kpath["path"]) == 1 - assert high_symmetry_points.density == pytest.approx(0.0628318530) + assert high_symmetry_points.density == approx(0.0628318530) assert high_symmetry_points.reciprocal_lattice.shape == (3, 3) def test_write_file(self): diff --git a/tests/io/pwmat/test_outputs.py b/tests/io/pwmat/test_outputs.py index b2a97f891fe..400cc00f5ad 100644 --- a/tests/io/pwmat/test_outputs.py +++ b/tests/io/pwmat/test_outputs.py @@ -1,5 +1,7 @@ from __future__ import annotations +from pytest import approx + from pymatgen.io.pwmat.outputs import DosSpin, Movement, OutFermi, Report from pymatgen.util.testing import TEST_FILES_DIR, PymatgenTest @@ -18,19 +20,19 @@ def test_init_and_properties(self): assert "atom_forces" in movement.ionic_steps[0] assert "virial" in movement.ionic_steps[0] assert "atom_energies" in movement.ionic_steps[0] - assert movement.e_tots == -357677.2281 + assert movement.e_tots == approx(-357677.2281) assert movement.atom_configs[0] == movement.ionic_steps[0]["atom_config"] assert list(movement.e_atoms) == [] assert movement.atom_forces.shape == (1, 72, 3) assert movement.virials.shape == (1, 3, 3) - assert movement.ionic_steps[0]["e_tot"] == -357677.2281 + assert movement.ionic_steps[0]["e_tot"] == approx(-357677.2281) class TestOutFermi(PymatgenTest): def test_init_and_properties(self): filepath = f"{TEST_DIR}/OUT.FERMI.lzma" out_fermi = OutFermi(filepath) - assert out_fermi.e_fermi == -2.359 + assert out_fermi.e_fermi == approx(-2.359) class TestReport(PymatgenTest): diff --git a/tests/io/qchem/test_outputs.py b/tests/io/qchem/test_outputs.py index 22f681f8918..d2fb8f95377 100644 --- a/tests/io/qchem/test_outputs.py +++ b/tests/io/qchem/test_outputs.py @@ -333,12 +333,12 @@ def test_multipole_parsing(self): assert len(mpoles["quadrupole"]) == 6 assert len(mpoles["octopole"]) == 10 assert len(mpoles["hexadecapole"]) == 15 - assert mpoles["quadrupole"]["XX"] == -51.3957 - assert mpoles["quadrupole"]["YZ"] == 3.5356 - assert mpoles["octopole"]["XYY"] == -15.0294 - assert mpoles["octopole"]["XZZ"] == -14.9756 - assert mpoles["hexadecapole"]["YYYY"] == -326.317 - assert mpoles["hexadecapole"]["XYZZ"] == 58.0584 + assert mpoles["quadrupole"]["XX"] == approx(-51.3957) + assert mpoles["quadrupole"]["YZ"] == approx(3.5356) + assert mpoles["octopole"]["XYY"] == approx(-15.0294) + assert mpoles["octopole"]["XZZ"] == approx(-14.9756) + assert mpoles["hexadecapole"]["YYYY"] == approx(-326.317) + assert mpoles["hexadecapole"]["XYZZ"] == approx(58.0584) opt = QCOutput(f"{NEW_QCHEM_TEST_DIR}/ts.out") mpoles = opt.data["multipoles"] @@ -373,26 +373,26 @@ def test_nbo_parsing(self): assert len(data["nbo_data"]["natural_populations"]) == 3 assert len(data["nbo_data"]["hybridization_character"]) == 6 assert len(data["nbo_data"]["perturbation_energy"]) == 2 - assert data["nbo_data"]["natural_populations"][0]["Density"][5] == -0.08624 + assert data["nbo_data"]["natural_populations"][0]["Density"][5] == approx(-0.08624) assert data["nbo_data"]["hybridization_character"][4]["atom 2 pol coeff"][35] == "-0.7059" next_to_last = list(data["nbo_data"]["perturbation_energy"][-1]["fock matrix element"])[-2] - assert data["nbo_data"]["perturbation_energy"][-1]["fock matrix element"][next_to_last] == 0.071 + assert data["nbo_data"]["perturbation_energy"][-1]["fock matrix element"][next_to_last] == approx(0.071) assert data["nbo_data"]["perturbation_energy"][0]["acceptor type"][0] == "RY*" def test_nbo7_parsing(self): data = QCOutput(f"{NEW_QCHEM_TEST_DIR}/nbo7_1.qout").data - assert data["nbo_data"]["perturbation_energy"][0]["perturbation energy"][9] == 15.73 + assert data["nbo_data"]["perturbation_energy"][0]["perturbation energy"][9] == approx(15.73) assert len(data["nbo_data"]["perturbation_energy"][0]["donor bond index"]) == 84 assert len(data["nbo_data"]["perturbation_energy"][1]["donor bond index"]) == 29 data = QCOutput(f"{NEW_QCHEM_TEST_DIR}/nbo7_2.qout").data - assert data["nbo_data"]["perturbation_energy"][0]["perturbation energy"][13] == 32.93 + assert data["nbo_data"]["perturbation_energy"][0]["perturbation energy"][13] == approx(32.93) assert data["nbo_data"]["perturbation_energy"][0]["acceptor type"][13] == "LV" assert data["nbo_data"]["perturbation_energy"][0]["acceptor type"][12] == "RY" assert data["nbo_data"]["perturbation_energy"][0]["acceptor atom 1 symbol"][12] == "Mg" data = QCOutput(f"{NEW_QCHEM_TEST_DIR}/nbo7_3.qout").data - assert data["nbo_data"]["perturbation_energy"][0]["perturbation energy"][13] == 34.54 + assert data["nbo_data"]["perturbation_energy"][0]["perturbation energy"][13] == approx(34.54) assert data["nbo_data"]["perturbation_energy"][0]["acceptor type"][13] == "BD*" assert data["nbo_data"]["perturbation_energy"][0]["acceptor atom 1 symbol"][13] == "B" assert data["nbo_data"]["perturbation_energy"][0]["acceptor atom 2 symbol"][13] == "Mg" @@ -419,41 +419,41 @@ def test_nbo7_infinite_e2pert(self): def test_cdft_parsing(self): data = QCOutput(f"{NEW_QCHEM_TEST_DIR}/cdft_simple.qout").data - assert data["cdft_becke_excess_electrons"][0][0] == 0.432641 + assert data["cdft_becke_excess_electrons"][0][0] == approx(0.432641) assert len(data["cdft_becke_population"][0]) == 12 - assert data["cdft_becke_net_spin"][0][6] == -0.000316 + assert data["cdft_becke_net_spin"][0][6] == approx(-0.000316) def test_cdft_dc_parsing(self): data = QCOutput.multiple_outputs_from_file( f"{NEW_QCHEM_TEST_DIR}/cdft_dc.qout", keep_sub_files=False, )[-1].data - assert data["direct_coupling_eV"] == 0.0103038246 + assert data["direct_coupling_eV"] == approx(0.0103038246) def test_almo_msdft2_parsing(self): data = QCOutput(f"{NEW_QCHEM_TEST_DIR}/almo.out").data assert data["almo_coupling_states"] == [[[1, 2], [0, 1]], [[0, 1], [1, 2]]] - assert data["almo_hamiltonian"][0][0] == -156.62929 + assert data["almo_hamiltonian"][0][0] == approx(-156.62929) assert data["almo_coupling_eV"] == approx(0.26895) def test_pod_parsing(self): data = QCOutput(f"{NEW_QCHEM_TEST_DIR}/pod2_gs.out").data - assert data["pod_coupling_eV"] == 0.247818 + assert data["pod_coupling_eV"] == approx(0.247818) def test_fodft_parsing(self): data = QCOutput(f"{NEW_QCHEM_TEST_DIR}/fodft.out").data - assert data["fodft_coupling_eV"] == 0.268383 + assert data["fodft_coupling_eV"] == approx(0.268383) def test_isosvp_water(self): data = QCOutput(f"{NEW_QCHEM_TEST_DIR}/isosvp_water_single.qcout").data assert data["solvent_method"] == "ISOSVP" # ISOSVP parameters - assert data["solvent_data"]["isosvp"]["isosvp_dielectric"] == 78.39 - assert data["solvent_data"]["isosvp"]["final_soln_phase_e"] == -40.4850599393 - assert data["solvent_data"]["isosvp"]["solute_internal_e"] == -40.4846329762 - assert data["solvent_data"]["isosvp"]["change_solute_internal_e"] == 0.0000121967 - assert data["solvent_data"]["isosvp"]["reaction_field_free_e"] == -0.0004269631 - assert data["solvent_data"]["isosvp"]["total_solvation_free_e"] == -0.0004147664 + assert data["solvent_data"]["isosvp"]["isosvp_dielectric"] == approx(78.39) + assert data["solvent_data"]["isosvp"]["final_soln_phase_e"] == approx(-40.4850599393) + assert data["solvent_data"]["isosvp"]["solute_internal_e"] == approx(-40.4846329762) + assert data["solvent_data"]["isosvp"]["change_solute_internal_e"] == approx(0.0000121967) + assert data["solvent_data"]["isosvp"]["reaction_field_free_e"] == approx(-0.0004269631) + assert data["solvent_data"]["isosvp"]["total_solvation_free_e"] == approx(-0.0004147664) # CMIRS parameters assert data["solvent_data"]["cmirs"]["CMIRS_enabled"] is False @@ -464,11 +464,11 @@ def test_isosvp_dielst10(self): # ISOSVP parameters assert data["solvent_data"]["isosvp"]["isosvp_dielectric"] == 10 - assert data["solvent_data"]["isosvp"]["final_soln_phase_e"] == -40.4850012952 - assert data["solvent_data"]["isosvp"]["solute_internal_e"] == -40.4846362547 - assert data["solvent_data"]["isosvp"]["change_solute_internal_e"] == 0.0000089182 - assert data["solvent_data"]["isosvp"]["reaction_field_free_e"] == -0.0003650405 - assert data["solvent_data"]["isosvp"]["total_solvation_free_e"] == -0.0003561223 + assert data["solvent_data"]["isosvp"]["final_soln_phase_e"] == approx(-40.4850012952) + assert data["solvent_data"]["isosvp"]["solute_internal_e"] == approx(-40.4846362547) + assert data["solvent_data"]["isosvp"]["change_solute_internal_e"] == approx(0.0000089182) + assert data["solvent_data"]["isosvp"]["reaction_field_free_e"] == approx(-0.0003650405) + assert data["solvent_data"]["isosvp"]["total_solvation_free_e"] == approx(-0.0003561223) # CMIRS parameters assert data["solvent_data"]["cmirs"]["CMIRS_enabled"] is False @@ -476,48 +476,48 @@ def test_isosvp_dielst10(self): def test_cmirs_benzene(self): data = QCOutput(f"{NEW_QCHEM_TEST_DIR}/cmirs_benzene_single.qcout").data assert data["solvent_method"] == "ISOSVP" - assert data["solvent_data"]["isosvp"]["isosvp_dielectric"] == 2.28 + assert data["solvent_data"]["isosvp"]["isosvp_dielectric"] == approx(2.28) assert data["solvent_data"]["cmirs"]["CMIRS_enabled"] - assert data["solvent_data"]["cmirs"]["dispersion_e"] == 0.6955542829 - assert data["solvent_data"]["cmirs"]["exchange_e"] == 0.2654553686 - assert data["solvent_data"]["cmirs"]["min_neg_field_e"] == 0.0006019665 - assert data["solvent_data"]["cmirs"]["max_pos_field_e"] == 0.0178177740 + assert data["solvent_data"]["cmirs"]["dispersion_e"] == approx(0.6955542829) + assert data["solvent_data"]["cmirs"]["exchange_e"] == approx(0.2654553686) + assert data["solvent_data"]["cmirs"]["min_neg_field_e"] == approx(0.0006019665) + assert data["solvent_data"]["cmirs"]["max_pos_field_e"] == approx(0.0178177740) def test_cmirs_dielst10(self): data = QCOutput(f"{NEW_QCHEM_TEST_DIR}/cmirs_dielst10_single.qcout").data assert data["solvent_method"] == "ISOSVP" assert data["solvent_data"]["isosvp"]["isosvp_dielectric"] == 10 assert data["solvent_data"]["cmirs"]["CMIRS_enabled"] - assert data["solvent_data"]["cmirs"]["dispersion_e"] == 0.6955550107 - assert data["solvent_data"]["cmirs"]["exchange_e"] == 0.2652679507 - assert data["solvent_data"]["cmirs"]["min_neg_field_e"] == 0.0005235850 - assert data["solvent_data"]["cmirs"]["max_pos_field_e"] == 0.0179866718 + assert data["solvent_data"]["cmirs"]["dispersion_e"] == approx(0.6955550107) + assert data["solvent_data"]["cmirs"]["exchange_e"] == approx(0.2652679507) + assert data["solvent_data"]["cmirs"]["min_neg_field_e"] == approx(0.0005235850) + assert data["solvent_data"]["cmirs"]["max_pos_field_e"] == approx(0.0179866718) def test_cmirs_water(self): data = QCOutput(f"{NEW_QCHEM_TEST_DIR}/cmirs_water_single.qcout").data assert data["solvent_method"] == "ISOSVP" # ISOSVP parameters - assert data["solvent_data"]["isosvp"]["isosvp_dielectric"] == 78.39 - assert data["solvent_data"]["isosvp"]["final_soln_phase_e"] == -40.4752415075 - assert data["solvent_data"]["isosvp"]["solute_internal_e"] == -40.4748535587 - assert data["solvent_data"]["isosvp"]["change_solute_internal_e"] == 0.0000122982 - assert data["solvent_data"]["isosvp"]["reaction_field_free_e"] == -0.0003879488 - assert data["solvent_data"]["isosvp"]["total_solvation_free_e"] == 0.0037602703 + assert data["solvent_data"]["isosvp"]["isosvp_dielectric"] == approx(78.39) + assert data["solvent_data"]["isosvp"]["final_soln_phase_e"] == approx(-40.4752415075) + assert data["solvent_data"]["isosvp"]["solute_internal_e"] == approx(-40.4748535587) + assert data["solvent_data"]["isosvp"]["change_solute_internal_e"] == approx(0.0000122982) + assert data["solvent_data"]["isosvp"]["reaction_field_free_e"] == approx(-0.0003879488) + assert data["solvent_data"]["isosvp"]["total_solvation_free_e"] == approx(0.0037602703) # CMIRS parameters assert data["solvent_data"]["cmirs"]["CMIRS_enabled"] - assert data["solvent_data"]["cmirs"]["dispersion_e"] == 0.6722278965 - assert data["solvent_data"]["cmirs"]["exchange_e"] == 0.2652032616 - assert data["solvent_data"]["cmirs"]["min_neg_field_e"] == 0.0004967767 - assert data["solvent_data"]["cmirs"]["max_pos_field_e"] == 0.0180445935 + assert data["solvent_data"]["cmirs"]["dispersion_e"] == approx(0.6722278965) + assert data["solvent_data"]["cmirs"]["exchange_e"] == approx(0.2652032616) + assert data["solvent_data"]["cmirs"]["min_neg_field_e"] == approx(0.0004967767) + assert data["solvent_data"]["cmirs"]["max_pos_field_e"] == approx(0.0180445935) def test_nbo_hyperbonds(self): data = QCOutput(f"{NEW_QCHEM_TEST_DIR}/hyper.qout").data assert len(data["nbo_data"]["hyperbonds"][0]["hyperbond index"]) == 2 assert data["nbo_data"]["hyperbonds"][0]["BD(A-B)"][1] == 106 assert data["nbo_data"]["hyperbonds"][0]["bond atom 2 symbol"][0] == "C" - assert data["nbo_data"]["hyperbonds"][0]["occ"][1] == 3.0802 + assert data["nbo_data"]["hyperbonds"][0]["occ"][1] == approx(3.0802) def test_nbo_3_c(self): data = QCOutput(f"{NEW_QCHEM_TEST_DIR}/3C.qout").data @@ -535,23 +535,23 @@ def test_nbo_3_c(self): assert perturb_ene[0]["donor atom 2 symbol"][2125] == "B12" assert perturb_ene[0]["donor atom 2 number"][2593] == "info_is_from_3C" assert perturb_ene[0]["acceptor type"][723] == "3C*" - assert perturb_ene[0]["perturbation energy"][3209] == 3.94 + assert perturb_ene[0]["perturbation energy"][3209] == approx(3.94) def test_qchem_6_1_1(self): qc_out = QCOutput(f"{TEST_DIR}/6.1.1.wb97xv.out.gz") - assert qc_out.data["final_energy"] == -76.43205015 + assert qc_out.data["final_energy"] == approx(-76.43205015) n_vals = sum(1 for val in qc_out.data.values() if val is not None) assert n_vals == 23 qc_out_read_optimization = QCOutput(f"{TEST_DIR}/6.1.1.opt.out.gz") qc_out_read_optimization._read_optimization_data() - assert qc_out_read_optimization.data["SCF_energy_in_the_final_basis_set"][-1] == -76.36097614 - assert qc_out_read_optimization.data["Total_energy_in_the_final_basis_set"][-1] == -76.36097614 + assert qc_out_read_optimization.data["SCF_energy_in_the_final_basis_set"][-1] == approx(-76.36097614) + assert qc_out_read_optimization.data["Total_energy_in_the_final_basis_set"][-1] == approx(-76.36097614) qc_out_read_frequency = QCOutput(f"{TEST_DIR}/6.1.1.freq.out.gz") qc_out_read_frequency._read_frequency_data() - assert qc_out_read_frequency.data["SCF_energy_in_the_final_basis_set"] == -76.36097614 - assert qc_out_read_frequency.data["Total_energy_in_the_final_basis_set"] == -76.36097614 + assert qc_out_read_frequency.data["SCF_energy_in_the_final_basis_set"] == approx(-76.36097614) + assert qc_out_read_frequency.data["Total_energy_in_the_final_basis_set"] == approx(-76.36097614) def test_gradient(tmp_path): diff --git a/tests/io/qchem/test_utils.py b/tests/io/qchem/test_utils.py index 4ad091b8242..d9fef5532b4 100644 --- a/tests/io/qchem/test_utils.py +++ b/tests/io/qchem/test_utils.py @@ -4,6 +4,7 @@ import pytest from monty.io import zopen +from pytest import approx from pymatgen.io.qchem.utils import lower_and_check_unique, process_parsed_hess from pymatgen.util.testing import TEST_FILES_DIR, PymatgenTest @@ -21,7 +22,7 @@ class TestUtil(PymatgenTest): def test_lower_and_check_unique(self): dct = {"sVp": {"RHOISO": 0.0009}, "jobType": "SP"} d2 = lower_and_check_unique(dct) - assert d2 == {"svp": {"RHOISO": 0.0009}, "job_type": "sp"} + assert d2 == {"svp": {"RHOISO": approx(0.0009)}, "job_type": "sp"} d3 = lower_and_check_unique(d2["svp"]) assert d3 == {"rhoiso": "0.0009"} d4 = {"jobType": "SP", "JOBtype": "SP"} diff --git a/tests/io/test_adf.py b/tests/io/test_adf.py index d3b6785320f..df253649d15 100644 --- a/tests/io/test_adf.py +++ b/tests/io/test_adf.py @@ -126,8 +126,8 @@ def test_from_str(self): k2 = AdfKey.from_str("step rad=0.15 angle=10.0") assert k2.key == "step" - assert k2.options[0] == ["rad", 0.15] - assert k2.options[1] == ["angle", 10.0] + assert k2.options[0] == ["rad", approx(0.15)] + assert k2.options[1] == ["angle", approx(10.0)] k3 = AdfKey.from_str("GEOMETRY\noptim all\niterations 100\nEND\n") assert k3.key == "GEOMETRY" @@ -145,8 +145,8 @@ def test_from_str(self): assert k4.key == "SCF" assert k4.subkeys[0].key == "iterations" assert k4.subkeys[1].key == "converge" - assert k4.subkeys[1].options[0] == 1e-7 - assert k4.subkeys[2].options[0] == 0.2 + assert k4.subkeys[1].options[0] == approx(1e-7) + assert k4.subkeys[2].options[0] == approx(0.2) def test_option_operations(self): k1 = AdfKey("Charge", [-1, 0]) @@ -157,9 +157,9 @@ def test_option_operations(self): k2 = AdfKey.from_str("step rad=0.15 angle=10.0") k2.add_option(["length", 0.1]) - assert k2.options[2] == ["length", 0.1] + assert k2.options[2] == ["length", approx(0.1)] k2.remove_option("rad") - assert k2.options[0] == ["angle", 10.0] + assert k2.options[0] == ["angle", approx(10.0)] def test_atom_block_key(self): block = AdfKey("atoms") diff --git a/tests/io/test_cif.py b/tests/io/test_cif.py index 690c67c302d..35c82053ea6 100644 --- a/tests/io/test_cif.py +++ b/tests/io/test_cif.py @@ -896,7 +896,7 @@ def test_no_check_occu(self): for tol in (1.5, 10): parser = CifParser.from_str(cif_str, occupancy_tolerance=tol) structs = parser.parse_structures(primitive=False, check_occu=False)[0] - assert structs[0].species.as_dict()["Te"] == 1.5 + assert structs[0].species.as_dict()["Te"] == approx(1.5) def test_cif_writer_write_file(self): struct1 = Structure.from_file(f"{VASP_IN_DIR}/POSCAR") @@ -1104,7 +1104,7 @@ def test_write(self): # test we're getting correct magmoms in ncl case s_ncl2 = self.mcif_ncl2.parse_structures()[0] list_magmoms = [list(m) for m in s_ncl2.site_properties["magmom"]] - assert list_magmoms[0][0] == 0.0 + assert list_magmoms[0][0] == approx(0.0) assert list_magmoms[0][1] == approx(5.9160793408726366) assert list_magmoms[1][0] == approx(-5.1234749999999991) assert list_magmoms[1][1] == approx(2.9580396704363183) diff --git a/tests/io/test_gaussian.py b/tests/io/test_gaussian.py index b44db9f2c32..69fdc0d3d16 100644 --- a/tests/io/test_gaussian.py +++ b/tests/io/test_gaussian.py @@ -312,10 +312,10 @@ def test_props(self): assert dct["input"]["functional"] == "hf" assert dct["output"]["final_energy"] == approx(-39.9768775602) assert len(gau.cart_forces) == 3 - assert gau.cart_forces[0][5] == 0.009791094 - assert gau.cart_forces[0][-1] == -0.003263698 - assert gau.cart_forces[2][-1] == -0.000000032 - assert gau.eigenvalues[Spin.up][-1] == 1.95586 + assert gau.cart_forces[0][5] == approx(0.009791094) + assert gau.cart_forces[0][-1] == approx(-0.003263698) + assert gau.cart_forces[2][-1] == approx(-0.000000032) + assert gau.eigenvalues[Spin.up][-1] == approx(1.95586) assert gau.num_basis_func == 17 assert gau.is_spin is False @@ -323,11 +323,11 @@ def test_props(self): assert len(ch2o_co2.frequencies) == 2 assert len(ch2o_co2.frequencies[0]) == 6 assert len(ch2o_co2.frequencies[1]) == 4 - assert ch2o_co2.frequencies[0][0]["frequency"] == 1203.1940 + assert ch2o_co2.frequencies[0][0]["frequency"] == approx(1203.1940) assert ch2o_co2.frequencies[0][0]["symmetry"] == 'A"' - assert ch2o_co2.frequencies[0][3]["IR_intensity"] == 60.9575 - assert ch2o_co2.frequencies[0][3]["r_mass"] == 3.7543 - assert ch2o_co2.frequencies[0][4]["f_constant"] == 5.4175 + assert ch2o_co2.frequencies[0][3]["IR_intensity"] == approx(60.9575) + assert ch2o_co2.frequencies[0][3]["r_mass"] == approx(3.7543) + assert ch2o_co2.frequencies[0][4]["f_constant"] == approx(5.4175) assert ch2o_co2.frequencies[0][1]["mode"] == [ 0.15, 0.00, @@ -354,13 +354,13 @@ def test_props(self): -0.33, ] assert ch2o_co2.frequencies[1][3]["symmetry"] == "SGU" - assert ch2o_co2.eigenvalues[Spin.up][3] == -1.18394 + assert ch2o_co2.eigenvalues[Spin.up][3] == approx(-1.18394) h2o = GaussianOutput(f"{TEST_DIR}/H2O_gau_vib.out") assert len(h2o.frequencies[0]) == 3 - assert h2o.frequencies[0][0]["frequency"] == 1662.8033 + assert h2o.frequencies[0][0]["frequency"] == approx(1662.8033) assert h2o.frequencies[0][1]["symmetry"] == "A'" - assert h2o.hessian[0, 0] == 0.356872 + assert h2o.hessian[0, 0] == approx(0.356872) assert h2o.hessian.shape == (9, 9) assert h2o.hessian[8, :].tolist() == [ -0.143692e-01, @@ -398,8 +398,8 @@ def test_pop(self): assert len(mo) == 2 # la 6 assert len(mo[Spin.down]) == 13 assert len(mo[Spin.down][0]) == 3 - assert mo[Spin.down][5][0]["1S"] == -0.08771 - assert mo[Spin.down][5][0]["2PZ"] == -0.21625 + assert mo[Spin.down][5][0]["1S"] == approx(-0.08771) + assert mo[Spin.down][5][0]["2PZ"] == approx(-0.21625) assert gau.eigenvectors[Spin.up][:, 5].tolist() == [ -0.08771, 0.10840, @@ -431,24 +431,24 @@ def test_pop(self): gau = GaussianOutput(f"{TEST_DIR}/H2O_gau_vib.out") - assert gau.bond_orders[0, 1] == 0.7582 - assert gau.bond_orders[1, 2] == 0.0002 + assert gau.bond_orders[0, 1] == approx(0.7582) + assert gau.bond_orders[1, 2] == approx(0.0002) def test_scan(self): gau = GaussianOutput(f"{TEST_DIR}/so2_scan.log") dct = gau.read_scan() - assert approx(dct["energies"][-1]) == -548.02102 + assert dct["energies"][-1] == approx(-548.02102) assert len(dct["coords"]) == 1 assert len(dct["energies"]) == len(gau.energies) assert len(dct["energies"]) == 21 gau = GaussianOutput(f"{TEST_DIR}/so2_scan_opt.log") assert len(gau.opt_structures) == 21 dct = gau.read_scan() - assert approx(dct["energies"][-1]) == -548.02336 + assert dct["energies"][-1] == approx(-548.02336) assert len(dct["coords"]) == 2 assert len(dct["energies"]) == 21 - assert approx(dct["coords"]["DSO"][6]) == 1.60000 - assert approx(dct["coords"]["ASO"][2]) == 124.01095 + assert dct["coords"]["DSO"][6] == approx(1.60000) + assert dct["coords"]["ASO"][2] == approx(124.01095) gau = GaussianOutput(f"{TEST_DIR}/H2O_scan_G16.out") assert len(gau.opt_structures) == 21 coords = [ @@ -458,16 +458,16 @@ def test_scan(self): ] assert gau.opt_structures[-1].cart_coords.tolist() == coords dct = gau.read_scan() - assert approx(dct["energies"][-1]) == -0.00523 + assert dct["energies"][-1] == approx(-0.00523) assert len(dct["coords"]) == 3 assert len(dct["energies"]) == 21 - assert approx(dct["coords"]["R1"][6]) == 0.94710 - assert approx(dct["coords"]["R2"][17]) == 0.94277 + assert dct["coords"]["R1"][6] == approx(0.94710) + assert dct["coords"]["R2"][17] == approx(0.94277) def test_geo_opt(self): """Test an optimization where no "input orientation" is outputted.""" gau = GaussianOutput(f"{TEST_DIR}/acene-n_gaussian09_opt.out") - assert approx(gau.energies[-1]) == -1812.58399675 + assert gau.energies[-1] == approx(-1812.58399675) assert len(gau.structures) == 6 # Test the first 3 atom coordinates coords = [ diff --git a/tests/io/test_lmto.py b/tests/io/test_lmto.py index 1ddc8c2abcf..c206dbce80f 100644 --- a/tests/io/test_lmto.py +++ b/tests/io/test_lmto.py @@ -3,7 +3,8 @@ import os import numpy as np -from numpy.testing import assert_array_equal +from numpy.testing import assert_allclose +from pytest import approx from pymatgen.core.structure import Structure from pymatgen.core.units import Ry_to_eV @@ -81,19 +82,19 @@ def test_cohp_data(self): labels_fe = ["Fe1-Fe1"] + [f"Fe1-Fe1-{i}" for i in range(1, 8)] assert sorted(self.copl_fe.cohp_data) == labels_fe for bond in labels_fe: - assert self.copl_fe.cohp_data[bond]["length"] == 2.482 + assert self.copl_fe.cohp_data[bond]["length"] == approx(2.482) assert self.copl_fe.cohp_data[bond]["sites"] == (0, 0) def test_energies(self): - assert self.copl_bise.efermi == -0.17223 - assert self.copl_bise_eV.efermi == -2.3433 - assert self.copl_fe.efermi == -0.085683 + assert self.copl_bise.efermi == approx(-0.17223) + assert self.copl_bise_eV.efermi == approx(-2.3433) + assert self.copl_fe.efermi == approx(-0.085683) ener_eV = np.array( [round_to_sigfigs(energy, 5) for energy in self.copl_bise.energies * Ry_to_eV], dtype=float, ) - assert_array_equal(ener_eV, self.copl_bise_eV.energies) + assert_allclose(ener_eV, self.copl_bise_eV.energies) copl_icohp = self.copl_bise.cohp_data["Bi1-Se7"]["ICOHP"][Spin.up] icohp = np.array([round_to_sigfigs(i, 5) for i in copl_icohp * Ry_to_eV], dtype=float) icohp_eV = self.copl_bise_eV.cohp_data["Bi1-Se7"]["ICOHP"][Spin.up] - assert_array_equal(icohp, icohp_eV) + assert_allclose(icohp, icohp_eV) diff --git a/tests/io/test_multiwfn.py b/tests/io/test_multiwfn.py index da8a8624ddb..25ea52966cd 100644 --- a/tests/io/test_multiwfn.py +++ b/tests/io/test_multiwfn.py @@ -3,6 +3,7 @@ import copy import pytest +from pytest import approx from pymatgen.core.structure import Molecule from pymatgen.io.multiwfn import ( @@ -34,15 +35,15 @@ def test_parse_single_cp(): assert name1 == name2 for k, v in desc1.items(): - assert desc2.get(k) == pytest.approx(v) + assert desc2.get(k) == approx(v) assert name1 == "2_N" assert desc1["cp_num"] == 102 assert desc1["element"] == "N" # TODO: should we be returning this as an integer? assert desc1["number"] == "2" - assert desc1["pos_ang"] == pytest.approx([1.626104042116, -1.859508691395, -0.405402516863]) - assert desc1["density_total"] == pytest.approx(183.1401128) + assert desc1["pos_ang"] == approx([1.626104042116, -1.859508691395, -0.405402516863]) + assert desc1["density_total"] == approx(183.1401128) assert "connected_bond_paths" not in desc1 # Test atom parsing with CP not associated with a known nucleus @@ -54,9 +55,9 @@ def test_parse_single_cp(): assert desc["cp_num"] == 142 assert desc["number"] == "Unknown" assert desc["ele"] == "Unknown" - assert desc["density_alpha"] == pytest.approx(8.066360869) - assert desc["density_alpha"] == pytest.approx(desc["density_beta"]) - assert desc["spin_density"] == pytest.approx(0.0) + assert desc["density_alpha"] == approx(8.066360869) + assert desc["density_alpha"] == approx(desc["density_beta"]) + assert desc["spin_density"] == approx(0.0) # Test bond parsing with open(base_dir / "cp_just_bond.txt") as file: @@ -65,10 +66,10 @@ def test_parse_single_cp(): assert name == "121_bond" assert "ele_info" not in desc - assert desc["Lagrangian_K"] == pytest.approx(426.4263555) - assert desc["Hamiltonian_K"] == pytest.approx(106.7023631) - assert desc["energy_density"] == pytest.approx(-106.7023631) - assert desc["lap_e_density"] == pytest.approx(1278.89597) + assert desc["Lagrangian_K"] == approx(426.4263555) + assert desc["Hamiltonian_K"] == approx(106.7023631) + assert desc["energy_density"] == approx(-106.7023631) + assert desc["lap_e_density"] == approx(1278.89597) # Test ring parsing with open(base_dir / "cp_just_ring.txt") as file: @@ -78,14 +79,14 @@ def test_parse_single_cp(): assert name == "123_ring" assert "connected_bond_paths" not in desc assert "ele_info" not in desc - assert desc["e_loc_func"] == pytest.approx(0.4201012445) - assert desc["lol"] == pytest.approx(0.4597922949) - assert desc["ave_loc_ion_E"] == pytest.approx(6.928709119) - assert desc["delta_g_promolecular"] == pytest.approx(0.001716120125) - assert desc["delta_g_hirsh"] == pytest.approx(0.003153281621) - assert desc["esp_nuc"] == pytest.approx(176.0405167) - assert desc["esp_e"] == pytest.approx(-79.88321676) - assert desc["esp_total"] == pytest.approx(96.1572999) + assert desc["e_loc_func"] == approx(0.4201012445) + assert desc["lol"] == approx(0.4597922949) + assert desc["ave_loc_ion_E"] == approx(6.928709119) + assert desc["delta_g_promolecular"] == approx(0.001716120125) + assert desc["delta_g_hirsh"] == approx(0.003153281621) + assert desc["esp_nuc"] == approx(176.0405167) + assert desc["esp_e"] == approx(-79.88321676) + assert desc["esp_total"] == approx(96.1572999) # Test cage parsing with open(base_dir / "cp_just_cage.txt") as file: @@ -95,12 +96,12 @@ def test_parse_single_cp(): assert name == "56_cage" assert "connected_bond_paths" not in desc assert "ele_info" not in desc - assert desc["grad_norm"] == pytest.approx(7.920799975e-18) - assert desc["lap_norm"] == pytest.approx(0.01583124127) - assert desc["eig_hess"] == pytest.approx(0.0158312412724) - assert desc["det_hessian"] == pytest.approx(3.943311116e-08) - assert desc["ellip_e_dens"] == pytest.approx(-0.759846) - assert desc["eta"] == pytest.approx(0.083769) + assert desc["grad_norm"] == approx(7.920799975e-18) + assert desc["lap_norm"] == approx(0.01583124127) + assert desc["eig_hess"] == approx(0.0158312412724) + assert desc["det_hessian"] == approx(3.943311116e-08) + assert desc["ellip_e_dens"] == approx(-0.759846) + assert desc["eta"] == approx(0.083769) # Test parsing with unknown/improper CP type with open(base_dir / "cp_fake_type.txt") as file: diff --git a/tests/io/test_nwchem.py b/tests/io/test_nwchem.py index 7304ec4a10e..25827e0f547 100644 --- a/tests/io/test_nwchem.py +++ b/tests/io/test_nwchem.py @@ -4,6 +4,7 @@ from unittest import TestCase import pytest +from numpy.testing import assert_allclose from pytest import approx from pymatgen.core.structure import Molecule @@ -404,17 +405,17 @@ def test_read(self): assert nw_output[0]["charge"] == 0 assert nw_output[-1]["charge"] == -1 assert len(nw_output) == 5 - assert approx(nw_output[0]["energies"][-1], abs=1e-2) == -1102.6224491715582 - assert approx(nw_output[2]["energies"][-1], abs=1e-3) == -1102.9986291578023 - assert approx(nwo_cosmo[5]["energies"][0]["cosmo scf"], abs=1e-3) == -11156.354030653656 - assert approx(nwo_cosmo[5]["energies"][0]["gas phase"], abs=1e-3) == -11153.374133394364 - assert approx(nwo_cosmo[5]["energies"][0]["sol phase"], abs=1e-2) == -11156.353632962995 - assert approx(nwo_cosmo[6]["energies"][0]["cosmo scf"], abs=1e-2) == -11168.818934311605 - assert approx(nwo_cosmo[6]["energies"][0]["gas phase"], abs=1e-2) == -11166.3624424611462 - assert approx(nwo_cosmo[6]["energies"][0]["sol phase"], abs=1e-2) == -11168.818934311605 - assert approx(nwo_cosmo[7]["energies"][0]["cosmo scf"], abs=1e-2) == -11165.227959110889 - assert approx(nwo_cosmo[7]["energies"][0]["gas phase"], abs=1e-2) == -11165.025443612385 - assert approx(nwo_cosmo[7]["energies"][0]["sol phase"], abs=1e-2) == -11165.227959110154 + assert nw_output[0]["energies"][-1] == approx(-1102.6224491715582, abs=1e-2) + assert nw_output[2]["energies"][-1] == approx(-1102.9986291578023, abs=1e-3) + assert nwo_cosmo[5]["energies"][0]["cosmo scf"] == approx(-11156.354030653656, abs=1e-3) + assert nwo_cosmo[5]["energies"][0]["gas phase"] == approx(-11153.374133394364, abs=1e-3) + assert nwo_cosmo[5]["energies"][0]["sol phase"] == approx(-11156.353632962995, abs=1e-2) + assert nwo_cosmo[6]["energies"][0]["cosmo scf"] == approx(-11168.818934311605, abs=1e-2) + assert nwo_cosmo[6]["energies"][0]["gas phase"] == approx(-11166.3624424611462, abs=1e-2) + assert nwo_cosmo[6]["energies"][0]["sol phase"] == approx(-11168.818934311605, abs=1e-2) + assert nwo_cosmo[7]["energies"][0]["cosmo scf"] == approx(-11165.227959110889, abs=1e-2) + assert nwo_cosmo[7]["energies"][0]["gas phase"] == approx(-11165.025443612385, abs=1e-2) + assert nwo_cosmo[7]["energies"][0]["sol phase"] == approx(-11165.227959110154, abs=1e-2) assert nw_output[1]["hessian"][0][0] == approx(4.60187e01) assert nw_output[1]["hessian"][1][2] == approx(-1.14030e-08) @@ -433,8 +434,8 @@ def test_read(self): ie = nw_output[4]["energies"][-1] - nw_output[2]["energies"][-1] ea = nw_output[2]["energies"][-1] - nw_output[3]["energies"][-1] - assert approx(ie) == 0.7575358648355177 - assert approx(ea, abs=1e-3) == -14.997877958701338 + assert ie == approx(0.7575358648355177) + assert ea == approx(-14.997877958701338, abs=1e-3) assert nw_output[4]["basis_set"]["C"]["description"] == "6-311++G**" nw_output = NwOutput(f"{TEST_DIR}/H4C3O3_1.nwout") @@ -453,13 +454,13 @@ def test_read(self): assert nw_output[-1]["has_error"] assert nw_output[-1]["errors"][0] == "Geometry optimization failed" nw_output = NwOutput(f"{TEST_DIR}/anthrachinon_wfs_15_carboxyl.nwout") - assert nw_output[1]["frequencies"][0][0] == -70.47 + assert nw_output[1]["frequencies"][0][0] == approx(-70.47) assert len(nw_output[1]["frequencies"][0][1]) == 27 - assert nw_output[1]["frequencies"][-1][0] == 3696.74 - assert nw_output[1]["frequencies"][-1][1][-1] == (0.20498, -0.94542, -0.00073) - assert nw_output[1]["normal_frequencies"][1][0] == -70.72 - assert nw_output[1]["normal_frequencies"][3][0] == -61.92 - assert nw_output[1]["normal_frequencies"][1][1][-1] == (0.00056, 0.00042, 0.06781) + assert nw_output[1]["frequencies"][-1][0] == approx(3696.74) + assert_allclose(nw_output[1]["frequencies"][-1][1][-1], (0.20498, -0.94542, -0.00073)) + assert nw_output[1]["normal_frequencies"][1][0] == approx(-70.72) + assert nw_output[1]["normal_frequencies"][3][0] == approx(-61.92) + assert_allclose(nw_output[1]["normal_frequencies"][1][1][-1], (0.00056, 0.00042, 0.06781)) def test_parse_tddft(self): nw_output = NwOutput(f"{TEST_DIR}/phen_tddft.log") diff --git a/tests/io/test_optimade.py b/tests/io/test_optimade.py index 13bf08ae7c3..43526847b6e 100644 --- a/tests/io/test_optimade.py +++ b/tests/io/test_optimade.py @@ -1,6 +1,7 @@ from __future__ import annotations import numpy as np +from numpy.testing import assert_allclose from pymatgen.core import Structure from pymatgen.io.optimade import OptimadeStructureAdapter @@ -18,7 +19,7 @@ def test_get_optimade_structure_roundtrip(): assert optimade_structure["attributes"]["nelements"] == 3 assert optimade_structure["attributes"]["chemical_formula_reduced"] == "FeO4P" assert optimade_structure["attributes"]["species_at_sites"] == 4 * ["Fe"] + 4 * ["P"] + 16 * ["O"] - np.testing.assert_array_almost_equal( + assert_allclose( np.abs(optimade_structure["attributes"]["lattice_vectors"]), np.abs(STRUCTURE.lattice.matrix), ) diff --git a/tests/io/test_phonopy.py b/tests/io/test_phonopy.py index 802e43049e2..1a9b37822d1 100644 --- a/tests/io/test_phonopy.py +++ b/tests/io/test_phonopy.py @@ -55,7 +55,7 @@ def test_get_ph_bs(self): [0.0 + 0.0j, 0.14166569 + 0.04098339j, -0.14166569 - 0.04098339j], ) assert ph_bs.has_eigendisplacements, True - assert_array_equal(ph_bs.min_freq()[0].frac_coords, [0, 0, 0]) + assert_allclose(ph_bs.min_freq()[0].frac_coords, [0, 0, 0]) assert ph_bs.min_freq()[1] == approx(-0.03700895020) assert ph_bs.has_imaginary_freq() assert not ph_bs.has_imaginary_freq(tol=0.5) diff --git a/tests/io/test_pwscf.py b/tests/io/test_pwscf.py index 6e39c8b4019..b341f9387be 100644 --- a/tests/io/test_pwscf.py +++ b/tests/io/test_pwscf.py @@ -389,7 +389,7 @@ def test_read_str(self): assert_allclose(lattice, pw_in.structure.lattice.matrix) assert pw_in.sections["system"]["smearing"] == "cold" - assert pw_in.sections["electrons"]["conv_thr"] == 5.3e-5 + assert pw_in.sections["electrons"]["conv_thr"] == approx(5.3e-5) assert pw_in.kpoints_mode == "automatic" assert pw_in.kpoints_grid == (4, 4, 4) assert pw_in.kpoints_shift == (1, 1, 1) diff --git a/tests/io/test_res.py b/tests/io/test_res.py index eea55f09d8c..84660ab3802 100644 --- a/tests/io/test_res.py +++ b/tests/io/test_res.py @@ -30,7 +30,7 @@ def test_moks(self, provider: AirssProvider): assert grid == (6, 6, 8) assert offset == (0, 0, 0) assert nkpts == 144 - assert spacing == 0.05 + assert spacing == approx(0.05) def test_pspots(self, provider: AirssProvider): ps_pots = provider.get_pspots() diff --git a/tests/io/test_shengbte.py b/tests/io/test_shengbte.py index 303c9d094aa..1fb2ff8bffd 100644 --- a/tests/io/test_shengbte.py +++ b/tests/io/test_shengbte.py @@ -1,7 +1,8 @@ from __future__ import annotations import pytest -from numpy.testing import assert_array_equal +from numpy.testing import assert_allclose +from pytest import approx from pymatgen.io.shengbte import Control from pymatgen.util.testing import TEST_FILES_DIR, PymatgenTest @@ -42,10 +43,10 @@ def test_from_file(self): assert io["natoms"] == 2 assert tuple(io["ngrid"]) == (25, 25, 25) assert io["norientations"] == 0 - assert io["lfactor"] == 0.1 - assert io["lattvec"][0] == [0.0, 2.734363999, 2.734363999] - assert io["lattvec"][1] == [2.734363999, 0.0, 2.734363999] - assert io["lattvec"][2] == [2.734363999, 2.734363999, 0.0] + assert io["lfactor"] == approx(0.1) + assert_allclose(io["lattvec"][0], [0.0, 2.734363999, 2.734363999]) + assert_allclose(io["lattvec"][1], [2.734363999, 0.0, 2.734363999]) + assert_allclose(io["lattvec"][2], [2.734363999, 2.734363999, 0.0]) assert isinstance(io["elements"], list | str) if isinstance(io["elements"], list): all_strings = all(isinstance(item, str) for item in io["elements"]) @@ -54,10 +55,10 @@ def test_from_file(self): if isinstance(io["types"], list): all_ints = all(isinstance(item, int) for item in io["types"]) assert all_ints - assert_array_equal(io["positions"], [[0.0, 0.0, 0.0], [0.25, 0.25, 0.25]]) + assert_allclose(io["positions"], [[0.0, 0.0, 0.0], [0.25, 0.25, 0.25]]) assert tuple(io["scell"]) == (5, 5, 5) assert io["t"] == 500 - assert io["scalebroad"] == 0.5 + assert io["scalebroad"] == approx(0.5) assert not io["isotopes"] assert not io["onlyharmonic"] assert not io["nonanalytic"] diff --git a/tests/io/test_xyz.py b/tests/io/test_xyz.py index ad57feca5af..edd9443311d 100644 --- a/tests/io/test_xyz.py +++ b/tests/io/test_xyz.py @@ -89,8 +89,8 @@ def test_from_str(self): """ xyz = XYZ.from_str(mol_str) mol = xyz.molecule - assert mol[0].z == -7.222e-06 - assert mol[1].z == -2.771e-06 + assert mol[0].z == approx(-7.222e-06) + assert mol[1].z == approx(-2.771e-06) mol_str = """3 Random diff --git a/tests/io/vasp/test_inputs.py b/tests/io/vasp/test_inputs.py index 1616ff4e5e7..89d2043ddce 100644 --- a/tests/io/vasp/test_inputs.py +++ b/tests/io/vasp/test_inputs.py @@ -395,14 +395,14 @@ def test_from_md_run(self): # Parsing from an MD type run with velocities and predictor corrector data poscar = Poscar.from_file(f"{VASP_OUT_DIR}/CONTCAR.MD", check_for_potcar=False) assert np.sum(poscar.velocities) == approx(0.0065417961324) - assert poscar.predictor_corrector[0][0][0] == 0.33387820e00 - assert poscar.predictor_corrector[0][1][1] == -0.10583589e-02 + assert poscar.predictor_corrector[0][0][0] == approx(0.33387820e00) + assert poscar.predictor_corrector[0][1][1] == approx(-0.10583589e-02) assert poscar.lattice_velocities is None # Parsing from an MD type run with velocities, predictor corrector data and lattice velocities poscar = Poscar.from_file(f"{VASP_OUT_DIR}/CONTCAR.MD.npt", check_for_potcar=False) assert np.sum(poscar.velocities) == approx(-0.06193299494) - assert poscar.predictor_corrector[0][0][0] == 0.63981833 + assert poscar.predictor_corrector[0][0][0] == approx(0.63981833) assert poscar.lattice_velocities.sum() == approx(16.49411358474) def test_write_md_poscar(self): @@ -657,7 +657,7 @@ def test_init(self): incar = self.incar incar["LDAU"] = "T" assert incar["ALGO"] == "Damped", "Wrong Algo" - assert float(incar["EDIFF"]) == 1e-4, "Wrong EDIFF" + assert float(incar["EDIFF"]) == approx(1e-4), "Wrong EDIFF" assert isinstance(incar["LORBIT"], int) def test_check_for_duplicate(self): @@ -928,7 +928,7 @@ def test_lsorbit_magmom(self): assert ans_string4_lsorbit == str(incar) incar = Incar.from_str(ans_string1) - assert incar["MAGMOM"] == [[0.0, 0.0, 3.0], [0, 1, 0], [2, 1, 2]] + assert_allclose(incar["MAGMOM"], [[0.0, 0.0, 3.0], [0, 1, 0], [2, 1, 2]]) assert incar["LANGEVIN_GAMMA"] == [10, 10, 10] incar = Incar.from_str(ans_string2) @@ -973,13 +973,13 @@ def test_types(self): SIGMA = 0.1""" incar = Incar.from_str(incar_str) assert isinstance(incar["EINT"], list) - assert incar["EINT"][0] == -0.85 + assert incar["EINT"][0] == approx(-0.85) incar_str += "\nLHFCALC = .TRUE. ; HFSCREEN = 0.2" incar_str += "\nALGO = All;" incar = Incar.from_str(incar_str) assert incar["LHFCALC"] - assert incar["HFSCREEN"] == 0.2 + assert incar["HFSCREEN"] == approx(0.2) assert incar["ALGO"] == "All" def test_proc_types(self): @@ -1047,12 +1047,18 @@ def test_init(self): filepath = f"{VASP_IN_DIR}/KPOINTS_cartesian" kpoints = Kpoints.from_file(filepath) - assert kpoints.kpts == [ - (0.25, 0, 0), - (0, 0.25, 0), - (0, 0, 0.25), - ], "Wrong kpoint lattice read" - assert kpoints.kpts_shift == (0.5, 0.5, 0.5) + ( + assert_allclose( + kpoints.kpts, + [ + (0.25, 0, 0), + (0, 0.25, 0), + (0, 0, 0.25), + ], + ), + "Wrong kpoint lattice read", + ) + assert_allclose(kpoints.kpts_shift, (0.5, 0.5, 0.5)) # Gamma-centered Kpoint grid filepath = f"{VASP_IN_DIR}/KPOINTS_gamma" @@ -1405,7 +1411,7 @@ def test_is_valid(self): # corrupt the file psingle = copy.deepcopy(self.psingle_Fe_54) - assert psingle.keywords["RCORE"] == 2.3 + assert psingle.keywords["RCORE"] == approx(2.3) psingle.keywords["RCORE"] = 2.2 assert not psingle.is_valid @@ -1550,7 +1556,7 @@ def test_init(self): "O", ], "Wrong symbols read in for POTCAR" potcar = Potcar(["Fe_pv", "O"]) - assert potcar[0].enmax == 293.238 + assert potcar[0].enmax == approx(293.238) def test_from_file(self): assert {d.header for d in self.potcar} == { diff --git a/tests/io/vasp/test_optics.py b/tests/io/vasp/test_optics.py index 3a2caf7a94a..cb31ed54957 100644 --- a/tests/io/vasp/test_optics.py +++ b/tests/io/vasp/test_optics.py @@ -4,6 +4,7 @@ import pytest import scipy.special from numpy.testing import assert_allclose +from pytest import approx from pymatgen.io.vasp.optics import DielectricFunctionCalculator, delta_func, delta_methfessel_paxton, step_func from pymatgen.io.vasp.outputs import Vasprun @@ -23,8 +24,8 @@ def test_optics(self): dfc = DielectricFunctionCalculator.from_directory(eps_data_path) egrid, eps = dfc.get_epsilon(0, 0) - assert egrid[0] == 0 - assert egrid[-1] == 59.3802 + assert egrid[0] == approx(0) + assert egrid[-1] == approx(59.3802) assert len(egrid) == len(eps) == 3000 _, eps_real_ref, eps_imag_ref = vrun.dielectric diff --git a/tests/io/vasp/test_outputs.py b/tests/io/vasp/test_outputs.py index e02b9ac027a..83b75d2fb66 100644 --- a/tests/io/vasp/test_outputs.py +++ b/tests/io/vasp/test_outputs.py @@ -50,8 +50,6 @@ TEST_DIR = f"{TEST_FILES_DIR}/io/vasp" -kpts_opt_vrun_path = f"{TEST_DIR}/fixtures/kpoints_opt/vasprun.xml.gz" - class TestVasprun(PymatgenTest): def test_vasprun_ml(self): @@ -87,7 +85,7 @@ def test_vasprun_ediffg_set_to_0(self): assert vasp_run.converged_electronic is True assert vasp_run.converged is True assert vasp_run.parameters["EDIFFG"] == 0 - assert vasp_run.parameters["EDIFF"] == 1e-5 + assert vasp_run.parameters["EDIFF"] == approx(1e-5) def test_bad_random_seed(self): vasp_run = Vasprun(f"{VASP_OUT_DIR}/vasprun.bad_random_seed.xml.gz") @@ -116,7 +114,7 @@ def test_charge_charge_dielectric(self): def test_BSE(self): vasp_run = Vasprun(f"{VASP_OUT_DIR}/vasprun.BSE.xml.gz") absorption_coeff = vasp_run.optical_absorption_coeff - assert absorption_coeff[1] == 0.8327903762077188 + assert absorption_coeff[1] == approx(0.8327903762077188) assert vasp_run.final_structure == vasp_run.initial_structure assert "freq_dependent" in vasp_run.dielectric_data @@ -213,7 +211,7 @@ def test_standard(self): assert vasp_run.parameters["NELM"] == 60 # test pDOS parsing - assert vasp_run.complete_dos.spin_polarization == 1.0 + assert vasp_run.complete_dos.spin_polarization == approx(1.0) assert Vasprun(f"{VASP_OUT_DIR}/vasprun.etest1.xml.gz").complete_dos.spin_polarization is None pdos0 = vasp_run.complete_dos.pdos[vasp_run.final_structure[0]] @@ -308,7 +306,7 @@ def test_standard(self): assert vasprun_offset.structures[0] == vasprun_skip.structures[2] assert vasprun_ggau.is_hubbard - assert vasprun_ggau.hubbards["Fe"] == 4.3 + assert vasprun_ggau.hubbards["Fe"] == approx(4.3) assert vasprun_ggau.projected_eigenvalues[Spin.up][0][0][96][0] == approx(0.0032) dct = vasprun_ggau.as_dict() assert dct["elements"] == ["Fe", "Li", "O", "P"] @@ -377,26 +375,26 @@ def test_no_projected(self): def test_dielectric(self): vasprun_diel = Vasprun(f"{VASP_OUT_DIR}/vasprun.dielectric.xml.gz", parse_potcar_file=False) - assert approx(vasprun_diel.dielectric[0][10]) == 0.4294 - assert approx(vasprun_diel.dielectric[1][51][0]) == 19.941 - assert approx(vasprun_diel.dielectric[1][51][1]) == 19.941 - assert approx(vasprun_diel.dielectric[1][51][2]) == 19.941 - assert approx(vasprun_diel.dielectric[1][51][3]) == 0.0 - assert approx(vasprun_diel.dielectric[2][85][0]) == 34.186 - assert approx(vasprun_diel.dielectric[2][85][1]) == 34.186 - assert approx(vasprun_diel.dielectric[2][85][2]) == 34.186 - assert approx(vasprun_diel.dielectric[2][85][3]) == 0.0 + assert vasprun_diel.dielectric[0][10] == approx(0.4294) + assert vasprun_diel.dielectric[1][51][0] == approx(19.941) + assert vasprun_diel.dielectric[1][51][1] == approx(19.941) + assert vasprun_diel.dielectric[1][51][2] == approx(19.941) + assert vasprun_diel.dielectric[1][51][3] == approx(0.0) + assert vasprun_diel.dielectric[2][85][0] == approx(34.186) + assert vasprun_diel.dielectric[2][85][1] == approx(34.186) + assert vasprun_diel.dielectric[2][85][2] == approx(34.186) + assert vasprun_diel.dielectric[2][85][3] == approx(0.0) def test_dielectric_vasp608(self): # test reading dielectric constant in vasp 6.0.8 vasp_xml_path = f"{VASP_OUT_DIR}/vasprun.dielectric_6.0.8.xml.gz" vasprun_diel = Vasprun(vasp_xml_path, parse_potcar_file=False) - assert approx(vasprun_diel.dielectric[0][10]) == 0.4338 - assert approx(vasprun_diel.dielectric[1][51][0]) == 5.267 - assert approx(vasprun_diel.dielectric_data["density"][0][10]) == 0.4338 - assert approx(vasprun_diel.dielectric_data["density"][1][51][0]) == 5.267 - assert approx(vasprun_diel.dielectric_data["velocity"][0][10]) == 0.4338 - assert approx(vasprun_diel.dielectric_data["velocity"][1][51][0]) == 1.0741 + assert vasprun_diel.dielectric[0][10] == approx(0.4338) + assert vasprun_diel.dielectric[1][51][0] == approx(5.267) + assert vasprun_diel.dielectric_data["density"][0][10] == approx(0.4338) + assert vasprun_diel.dielectric_data["density"][1][51][0] == approx(5.267) + assert vasprun_diel.dielectric_data["velocity"][0][10] == approx(0.4338) + assert vasprun_diel.dielectric_data["velocity"][1][51][0] == approx(1.0741) assert len(vasprun_diel.dielectric_data) == 2 def test_indirect_vasprun(self): @@ -411,18 +409,18 @@ def test_optical_vasprun(self): vasp_xml_path = f"{VASP_OUT_DIR}/vasprun.optical_transitions.xml.gz" vasprun_optical = Vasprun(vasp_xml_path, parse_potcar_file=False) optical_trans = vasprun_optical.optical_transition - assert approx(optical_trans[0][0]) == 3.084 - assert approx(optical_trans[3][0]) == 3.087 - assert approx(optical_trans[0][1]) == 0.001 - assert approx(optical_trans[1][1]) == 0.001 - assert approx(optical_trans[7][1]) == 0.001 - assert approx(optical_trans[19][1]) == 0.001 - assert approx(optical_trans[54][0]) == 3.3799999999 - assert approx(optical_trans[55][0]) == 3.381 - assert approx(optical_trans[56][0]) == 3.381 - assert approx(optical_trans[54][1]) == 10554.9860 - assert approx(optical_trans[55][1]) == 0.0 - assert approx(optical_trans[56][1]) == 0.001 + assert optical_trans[0][0] == approx(3.084) + assert optical_trans[3][0] == approx(3.087) + assert optical_trans[0][1] == approx(0.001) + assert optical_trans[1][1] == approx(0.001) + assert optical_trans[7][1] == approx(0.001) + assert optical_trans[19][1] == approx(0.001) + assert optical_trans[54][0] == approx(3.3799999999) + assert optical_trans[55][0] == approx(3.381) + assert optical_trans[56][0] == approx(3.381) + assert optical_trans[54][1] == approx(10554.9860) + assert optical_trans[55][1] == approx(0.0) + assert optical_trans[56][1] == approx(0.001) def test_force_constants(self): vasprun_fc = Vasprun(f"{VASP_OUT_DIR}/vasprun.dfpt.phonon.xml.gz", parse_potcar_file=False) @@ -757,7 +755,7 @@ def test_eigenvalue_band_properties_separate_spins(self): assert props[3][1] def test_kpoints_opt(self): - vasp_run = Vasprun(kpts_opt_vrun_path, parse_projected_eigen=True) + vasp_run = Vasprun(f"{TEST_DIR}/fixtures/kpoints_opt/vasprun.xml.gz", parse_projected_eigen=True) # This calculation was run using KPOINTS_OPT kpt_opt_props = vasp_run.kpoints_opt_props # Check the k-points were read correctly. @@ -784,7 +782,9 @@ def test_kpoints_opt(self): assert vasp_run_dct["output"]["eigenvalues_kpoints_opt"]["1"][0][0][0] == approx(-6.1536) def test_kpoints_opt_band_structure(self): - vasp_run = Vasprun(kpts_opt_vrun_path, parse_potcar_file=False, parse_projected_eigen=True) + vasp_run = Vasprun( + f"{TEST_DIR}/fixtures/kpoints_opt/vasprun.xml.gz", parse_potcar_file=False, parse_projected_eigen=True + ) bs = vasp_run.get_band_structure(f"{TEST_DIR}/fixtures/kpoints_opt/KPOINTS_OPT") assert isinstance(bs, BandStructureSymmLine) cbm = bs.get_cbm() @@ -810,7 +810,7 @@ def test_kpoints_opt_band_structure(self): # At some point we might get a healthier vasprun.xml, but the point here # is to test the parser, not VASP. projected = bs.get_projections_on_elements_and_orbitals({"Si": ["s"]}) - assert projected[Spin.up][0][58]["Si"]["s"] == -0.0271 + assert projected[Spin.up][0][58]["Si"]["s"] == approx(-0.0271) def test_parse_potcar_cwd_relative(self): # Test to ensure that common use cases of vasprun parsing work @@ -983,11 +983,11 @@ def test_polarization(self): def test_pseudo_zval(self): filepath = f"{VASP_OUT_DIR}/OUTCAR.BaTiO3.polar" outcar = Outcar(filepath) - assert outcar.zval_dict == {"Ba": 10.00, "Ti": 10.00, "O": 6.00} + assert outcar.zval_dict == approx({"Ba": 10.0, "Ti": 10.0, "O": 6.0}) filepath = f"{VASP_OUT_DIR}/OUTCAR.LaSnNO2.polar" outcar = Outcar(filepath) - assert outcar.zval_dict == {"La": 11.0, "N": 5.0, "O": 6.0, "Sn": 14.0} + assert outcar.zval_dict == approx({"La": 11.0, "N": 5.0, "O": 6.0, "Sn": 14.0}) def test_dielectric(self): filepath = f"{VASP_OUT_DIR}/OUTCAR.dielectric" @@ -1005,7 +1005,7 @@ def test_freq_dielectric(self): assert outcar.dielectric_tensor_function[0][0, 0] == approx(8.96938800) assert outcar.dielectric_tensor_function[-1][0, 0] == approx(7.36167000e-01 + 1.53800000e-03j) assert len(outcar.dielectric_energies) == len(outcar.dielectric_tensor_function) - np.testing.assert_array_equal( + assert_allclose( outcar.dielectric_tensor_function[0], outcar.dielectric_tensor_function[0].transpose(), ) @@ -1030,7 +1030,7 @@ def test_freq_dielectric_vasp544(self): assert outcar.dielectric_tensor_function[0][0, 0] == approx(12.769435 + 0j) assert outcar.dielectric_tensor_function[-1][0, 0] == approx(0.828615 + 0.016594j) assert len(outcar.dielectric_energies) == len(outcar.dielectric_tensor_function) - np.testing.assert_array_equal( + assert_allclose( outcar.dielectric_tensor_function[0], outcar.dielectric_tensor_function[0].transpose(), ) @@ -1314,13 +1314,13 @@ def test_mag_electrostatic_error(self): def test_onsite_density_matrix(self): outcar = Outcar(f"{VASP_OUT_DIR}/OUTCAR.LinearResponseU.gz") matrices = outcar.data["onsite_density_matrices"] - assert matrices[0][Spin.up][0][0] == 1.0227 + assert matrices[0][Spin.up][0][0] == approx(1.0227) assert len(matrices[0][Spin.up]) == 5 assert len(matrices[0][Spin.up][0]) == 5 assert "onsite_density_matrices" in outcar.as_dict() outcar = Outcar(f"{VASP_OUT_DIR}/OUTCAR_merged_numbers") matrices = outcar.data["onsite_density_matrices"] - assert matrices[0][Spin.up][0][-1] == 0.0 + assert matrices[0][Spin.up][0][-1] == approx(0.0) assert len(matrices[0][Spin.up]) == 7 assert len(matrices[0][Spin.up][0]) == 7 assert "onsite_density_matrices" in outcar.as_dict() @@ -1445,7 +1445,9 @@ def test_get_band_structure(self): assert "eigenvalues" in dct["output"] def test_kpoints_opt(self): - vasp_run = BSVasprun(kpts_opt_vrun_path, parse_potcar_file=False, parse_projected_eigen=True) + vasp_run = BSVasprun( + f"{TEST_DIR}/fixtures/kpoints_opt/vasprun.xml.gz", parse_potcar_file=False, parse_projected_eigen=True + ) bs = vasp_run.get_band_structure(f"{TEST_DIR}/fixtures/kpoints_opt/KPOINTS_OPT") assert isinstance(bs, BandStructureSymmLine) cbm = bs.get_cbm() @@ -1472,7 +1474,7 @@ def test_kpoints_opt(self): # At some point we might get a healthier vasprun.xml, but the point here # is to test the parser, not VASP. projected = bs.get_projections_on_elements_and_orbitals({"Si": ["s"]}) - assert projected[Spin.up][0][58]["Si"]["s"] == -0.0271 + assert projected[Spin.up][0][58]["Si"]["s"] == approx(-0.0271) vrun_dct = vasp_run.as_dict() assert {*vrun_dct["output"]} >= {"eigenvalues", "eigenvalues_kpoints_opt"} @@ -1497,7 +1499,7 @@ class TestLocpot(PymatgenTest): def test_init(self): filepath = f"{VASP_OUT_DIR}/LOCPOT.gz" locpot = Locpot.from_file(filepath) - assert approx(sum(locpot.get_average_along_axis(0))) == -217.05226954 + assert sum(locpot.get_average_along_axis(0)) == approx(-217.05226954) assert locpot.get_axis_grid(0)[-1] == approx(2.87629, abs=1e-2) assert locpot.get_axis_grid(1)[-1] == approx(2.87629, abs=1e-2) assert locpot.get_axis_grid(2)[-1] == approx(2.87629, abs=1e-2) @@ -1657,8 +1659,8 @@ def test_read_write_file(self): class TestElfcar(PymatgenTest): def test_init(self): elfcar = Elfcar.from_file(f"{VASP_OUT_DIR}/ELFCAR.gz") - assert approx(np.mean(elfcar.data["total"])) == 0.19076207645194002 - assert approx(np.mean(elfcar.data["diff"])) == 0.19076046677910055 + assert np.mean(elfcar.data["total"]) == approx(0.19076207645194002) + assert np.mean(elfcar.data["diff"]) == approx(0.19076046677910055) reconstituted = Elfcar.from_dict(elfcar.as_dict()) assert elfcar.data == reconstituted.data assert elfcar.poscar.structure == reconstituted.poscar.structure @@ -1666,11 +1668,11 @@ def test_init(self): def test_alpha(self): elfcar = Elfcar.from_file(f"{VASP_OUT_DIR}/ELFCAR.gz") alpha = elfcar.get_alpha() - assert approx(np.median(alpha.data["total"])) == 2.936678808979031 + assert np.median(alpha.data["total"]) == approx(2.936678808979031) def test_interpolation(self): elfcar = Elfcar.from_file(f"{VASP_OUT_DIR}/ELFCAR.gz") - assert approx(elfcar.value_at(0.4, 0.5, 0.6)) == 0.0918471 + assert elfcar.value_at(0.4, 0.5, 0.6) == approx(0.0918471) assert len(elfcar.linear_slice([0.0, 0.0, 0.0], [1.0, 1.0, 1.0])) == 100 @@ -1703,7 +1705,7 @@ def test_soc_procar(self): assert procar.eigenvalues[Spin.up].shape == (nk, nb) assert procar.kpoints.shape == (nk, 3) assert len(procar.weights) == nk - assert np.all(procar.kpoints[0][0] == 0.0) + assert_allclose(procar.kpoints[0][0], 0.0) assert procar.occupancies[Spin.up].shape == (nk, nb) # spot check some values: @@ -1850,7 +1852,7 @@ def test_standard(self): assert wavecar.filename == f"{VASP_OUT_DIR}/WAVECAR.N2" assert wavecar.efermi == approx(-5.7232, abs=1e-4) - assert wavecar.encut == 25.0 + assert wavecar.encut == approx(25.0) assert wavecar.nb == 9 assert wavecar.nk == 1 assert_allclose(wavecar.a, a) @@ -1866,8 +1868,8 @@ def test_standard(self): for b in range(wavecar.nb): assert len(wavecar.coeffs[k][b]) == len(wavecar.Gpoints[k]) - # Test WAVECAR with fractional encut - assert self.w_frac_encut.encut == 100.5 + # Test WAVECAR with fractional ENCUT + assert self.w_frac_encut.encut == approx(100.5) # Test malformed WAVECARs with pytest.raises(ValueError, match="Invalid rtag=.+, must be one of"): @@ -1898,7 +1900,7 @@ def test_n2_45210(self): wavecar = Wavecar(f"{VASP_OUT_DIR}/WAVECAR.N2.45210") assert wavecar.filename == f"{VASP_OUT_DIR}/WAVECAR.N2.45210" assert wavecar.efermi == approx(-5.7232, abs=1e-4) - assert wavecar.encut == 25.0 + assert wavecar.encut == approx(25.0) assert wavecar.nb == 9 assert wavecar.nk == 1 assert_allclose(wavecar.a, self.latt_mat) diff --git a/tests/io/vasp/test_sets.py b/tests/io/vasp/test_sets.py index 4509e1b95f5..c684bd418c4 100644 --- a/tests/io/vasp/test_sets.py +++ b/tests/io/vasp/test_sets.py @@ -206,7 +206,7 @@ def test_no_structure_init(self): assert vis.structure is None inputs = vis.get_input_set(structure=self.structure) assert {*inputs} == {"INCAR", "KPOINTS", "POSCAR", "POTCAR"} - assert vis.incar["LDAUU"] == [5.3, 0, 0] + assert_allclose(vis.incar["LDAUU"], [5.3, 0, 0]) assert vis.as_dict()["structure"] is not None assert "structure" not in vis.as_dict(verbosity=1) @@ -356,11 +356,11 @@ def test_estimate_nbands(self): def test_get_incar(self): incar = self.mp_set.incar - assert incar["LDAUU"] == [5.3, 0, 0] + assert_allclose(incar["LDAUU"], [5.3, 0, 0]) assert incar["EDIFF"] == approx(0.0012) incar = self.mit_set.incar - assert incar["LDAUU"] == [4.0, 0, 0] + assert_allclose(incar["LDAUU"], [4.0, 0, 0]) assert incar["EDIFF"] == approx(1e-5) si = 14 @@ -391,42 +391,42 @@ def test_get_incar(self): # check fluorides struct = Structure(lattice, ["Fe", "F"], coords) incar = MPRelaxSet(struct).incar - assert incar["LDAUU"] == [5.3, 0] - assert incar["MAGMOM"] == [5, 0.6] + assert_allclose(incar["LDAUU"], [5.3, 0]) + assert_allclose(incar["MAGMOM"], [5, 0.6]) struct = Structure(lattice, ["Fe", "F"], coords) incar = self.set(struct).incar - assert incar["LDAUU"] == [4.0, 0] + assert_allclose(incar["LDAUU"], [4.0, 0]) # This seems counterintuitive at first, but even if the prior INCAR has a MAGMOM flag, # because the structure has no site properties, the default MAGMOM is assigned from the # config dictionary. struct = Structure(lattice, ["Fe", "F"], coords) incar = MPStaticSet(struct, prev_incar=f"{VASP_IN_DIR}/INCAR").incar - assert incar["MAGMOM"] == [5, 0.6] + assert_allclose(incar["MAGMOM"], [5, 0.6]) # Make sure this works with species. struct = Structure(lattice, ["Fe2+", "O2-"], coords) incar = MPRelaxSet(struct).incar - assert incar["LDAUU"] == [5.3, 0] + assert_allclose(incar["LDAUU"], [5.3, 0]) struct = Structure(lattice, ["Fe", "Mn"], coords, site_properties={"magmom": (5.2, -4.5)}) incar = MPRelaxSet(struct).incar - assert incar["MAGMOM"] == [-4.5, 5.2] + assert_allclose(incar["MAGMOM"], [-4.5, 5.2]) incar = self.set(struct, sort_structure=False).incar - assert incar["MAGMOM"] == [5.2, -4.5] + assert_allclose(incar["MAGMOM"], [5.2, -4.5]) struct = Structure(lattice, [Species("Fe2+", spin=4.1), "Mn"], coords) incar = MPRelaxSet(struct).incar - assert incar["MAGMOM"] == [5, 4.1] + assert_allclose(incar["MAGMOM"], [5, 4.1]) struct = Structure(lattice, ["Mn3+", "Mn4+"], coords) incar = self.set(struct).incar assert incar["MAGMOM"] == [4, 3] user_set = MPRelaxSet(struct, user_incar_settings={"MAGMOM": {"Fe": 10, "S": -5, "Mn3+": 100}}) - assert user_set.incar["MAGMOM"] == [100, 0.6] + assert_allclose(user_set.incar["MAGMOM"], [100, 0.6]) no_encut_set = MPRelaxSet(struct, user_incar_settings={"ENCUT": None}) assert "ENCUT" not in no_encut_set.incar @@ -436,26 +436,26 @@ def test_get_incar(self): struct = Structure(lattice, ["Fe", "Fe", "S"], coords) incar = self.set(struct).incar - assert incar["LDAUU"] == [1.9, 0] + assert_allclose(incar["LDAUU"], [1.9, 0]) # Make sure MP sulfides are ok. assert "LDAUU" not in MPRelaxSet(struct).incar struct = Structure(lattice, ["Fe", "S", "O"], coords) incar = self.set(struct).incar - assert incar["LDAUU"] == [4.0, 0, 0] + assert_allclose(incar["LDAUU"], [4.0, 0, 0]) # Make sure MP sulfates are ok. - assert MPRelaxSet(struct).incar["LDAUU"] == [5.3, 0, 0] + assert_allclose(MPRelaxSet(struct).incar["LDAUU"], [5.3, 0, 0]) # test for default LDAUU value user_set_ldauu_fallback = MPRelaxSet(struct, user_incar_settings={"LDAUU": {"Fe": 5.0, "S": 0}}) - assert user_set_ldauu_fallback.incar["LDAUU"] == [5.0, 0, 0] + assert_allclose(user_set_ldauu_fallback.incar["LDAUU"], [5.0, 0, 0]) # Expected to be oxide (O is the most electronegative atom) struct = Structure(lattice, ["Fe", "O", "S"], coords) incar = self.set(struct).incar - assert incar["LDAUU"] == [4.0, 0, 0] + assert_allclose(incar["LDAUU"], [4.0, 0, 0]) # Expected to be chloride (Cl is the most electronegative atom) struct = Structure(lattice, ["Fe", "Cl", "S"], coords) @@ -472,8 +472,8 @@ def test_get_incar(self): "LDAUU": {"Fe": 1.8}, }, ).incar - assert incar["LDAUL"] == [3.0, 0, 0] - assert incar["LDAUU"] == [1.8, 0, 0] + assert_allclose(incar["LDAUL"], [3.0, 0, 0]) + assert_allclose(incar["LDAUU"], [1.8, 0, 0]) # test that van-der-Waals parameters are parsed correctly @@ -486,7 +486,7 @@ def test_get_incar(self): incar = self.set(struct, vdw="optB86b").incar assert incar["GGA"] == "Mk" assert incar["LUSE_VDW"] - assert incar["PARAM1"] == 0.1234 + assert incar["PARAM1"] == approx(0.1234) # Test that NELECT is updated when a charge is present si = 14 @@ -510,10 +510,10 @@ def test_get_incar(self): struct = Structure(lattice, ["Co", "O"], coords) mpr = MPRelaxSet(struct) - assert mpr.incar["MAGMOM"] == [0.6, 0.6] + assert_allclose(mpr.incar["MAGMOM"], [0.6, 0.6]) struct = Structure(lattice, ["Co4+", "O"], coords) mpr = MPRelaxSet(struct) - assert mpr.incar["MAGMOM"] == [1, 0.6] + assert_allclose(mpr.incar["MAGMOM"], [1, 0.6]) # test passing user_incar_settings and user_kpoint_settings of None for set_cls in [MPRelaxSet, MPStaticSet, MPNonSCFSet]: @@ -559,7 +559,7 @@ def test_mp_metal_relax_set(self): mp_metal_set = MPMetalRelaxSet(self.get_structure("Sn")) incar = mp_metal_set.incar assert incar["ISMEAR"] == 1 - assert incar["SIGMA"] == 0.2 + assert incar["SIGMA"] == approx(0.2) kpoints = mp_metal_set.kpoints assert_allclose(kpoints.kpts[0], (5, 5, 5)) @@ -577,7 +577,7 @@ def test_as_from_dict(self): dct = mp_set.as_dict() val = MontyDecoder().process_decoded(dct) - assert val._config_dict["INCAR"]["LDAUU"]["O"]["Fe"] == 5.3 + assert val._config_dict["INCAR"]["LDAUU"]["O"]["Fe"] == approx(5.3) dct = mp_user_set.as_dict() val = MontyDecoder().process_decoded(dct) @@ -587,7 +587,7 @@ def test_as_from_dict(self): def test_hubbard_off_and_ediff_override(self): input_set = MPRelaxSet(self.structure, user_incar_settings={"LDAU": False, "EDIFF": 1e-10}) assert "LDAUU" not in input_set.incar - assert input_set.incar["EDIFF"] == 1e-10 + assert input_set.incar["EDIFF"] == approx(1e-10) # after testing, we have determined LMAXMIX should still be 4 for d-block # even if U is turned off (thanks Andrew Rosen for reporting) assert input_set.incar["LMAXMIX"] == 4 @@ -682,7 +682,7 @@ def test_valid_magmom_struct(self): # vis.get_input_set() vis = MPRelaxSet(struct, user_potcar_settings={"Fe": "Fe"}, validate_magmom=True) - assert vis.get_input_set()["INCAR"]["MAGMOM"] == [1.0] * len(struct) + assert_allclose(vis.get_input_set()["INCAR"]["MAGMOM"], [1.0] * len(struct)) # Test the behavior of constraining the net magnetic moment with a non-integer struct = self.structure.copy() @@ -716,7 +716,7 @@ def test_get_nedos(self): # no `prev_vasprun` --> default value of NEDOS assert vis._get_nedos(0.1) == 2000 vis.prev_vasprun = vrun - assert vis._get_nedos(0.1) == pytest.approx(741, abs=1) + assert vis._get_nedos(0.1) == approx(741, abs=1) class TestMPStaticSet(PymatgenTest): @@ -756,7 +756,7 @@ def test_init(self): leps_vis = self.set.from_prev_calc(prev_calc_dir=prev_run, lepsilon=True) assert leps_vis.incar["LEPSILON"] assert leps_vis.incar["IBRION"] == 8 - assert leps_vis.incar["EDIFF"] == 1e-5 + assert leps_vis.incar["EDIFF"] == approx(1e-5) assert "NPAR" not in leps_vis.incar assert leps_vis.incar["NSW"] == 1 assert non_prev_vis.kpoints.kpts == [(11, 10, 10)] @@ -789,7 +789,7 @@ def test_user_incar_kspacing(self): # Make sure user KSPACING settings properly overrides KPOINTS. si = self.get_structure("Si") vis = self.set(si, user_incar_settings={"KSPACING": 0.22}) - assert vis.incar["KSPACING"] == 0.22 + assert vis.incar["KSPACING"] == approx(0.22) assert vis.kpoints is None def test_kspacing_override(self): @@ -880,13 +880,13 @@ def test_default(self): input_set = MatPESStaticSet(self.struct) incar = input_set.incar assert incar["ALGO"] == "Normal" - assert incar["EDIFF"] == 1.0e-05 + assert incar["EDIFF"] == approx(1.0e-05) assert incar["ENAUG"] == 1360 assert incar["ENCUT"] == 680 assert incar["GGA"] == "Pe" assert incar["ISMEAR"] == 0 assert incar["ISPIN"] == 2 - assert incar["KSPACING"] == 0.22 + assert incar["KSPACING"] == approx(0.22) assert incar["LAECHG"] assert incar["LASPH"] assert incar["LCHARG"] @@ -898,7 +898,7 @@ def test_default(self): assert incar["NELM"] == 200 assert incar["NSW"] == 0 assert incar["PREC"] == "Accurate" - assert incar["SIGMA"] == 0.05 + assert incar["SIGMA"] == approx(0.05) assert incar["LMAXMIX"] == 6 assert input_set.potcar_symbols == ["Fe_pv", "P", "O"] @@ -919,13 +919,13 @@ def test_with_prev_incar(self): assert key not in incar, f"{key=} should be absent, got {incar[key]=}" # test if default in MatPESStaticSet is prioritized. assert incar["ALGO"] == "Normal" - assert incar["EDIFF"] == 1.0e-05 + assert incar["EDIFF"] == approx(1.0e-05) assert incar["ENAUG"] == 1360 assert incar["ENCUT"] == 680 assert incar["GGA"] == "Pe" assert incar["ISMEAR"] == 0 assert incar["ISPIN"] == 2 - assert incar["KSPACING"] == 0.22 + assert incar["KSPACING"] == approx(0.22) assert incar["LAECHG"] assert incar["LASPH"] assert incar["LCHARG"] @@ -937,7 +937,7 @@ def test_with_prev_incar(self): assert incar["NELM"] == 200 assert incar["NSW"] == 0 assert incar["PREC"] == "Accurate" - assert incar["SIGMA"] == 0.05 + assert incar["SIGMA"] == approx(0.05) # test POTCAR files are default PBE_64 PSPs and functional assert default_prev.potcar_symbols == ["Fe_pv", "P", "O"] assert default_prev.potcar_functional == "PBE_64" @@ -962,7 +962,7 @@ def test_default_u(self): assert incar_u["GGA"] == "Pe" assert incar_u["ALGO"] == "Normal" # test POTCAR files are default PBE_64 PSPs and functional - assert incar_u["LDAUU"] == [5.3, 0, 0] + assert_allclose(incar_u["LDAUU"], [5.3, 0, 0]) assert default_u.potcar_symbols == ["Fe_pv", "P", "O"] assert default_u.potcar_functional == "PBE_64" assert default_u.kpoints is None @@ -1030,7 +1030,7 @@ def test_init(self): # Check that the ENCUT has been inherited. assert vis.incar["ENCUT"] == 600 # Check that the user_incar_settings works - assert vis.incar["SIGMA"] == 0.025 + assert vis.incar["SIGMA"] == approx(0.025) assert vis.kpoints.style == Kpoints.supported_modes.Reciprocal # Check as from dict. @@ -1083,7 +1083,7 @@ def test_override_from_prev(self): assert vis.incar["NSW"] == 0 assert vis.incar["ENCUT"] == 600 - assert vis.incar["SIGMA"] == 0.025 + assert vis.incar["SIGMA"] == approx(0.025) assert vis.kpoints.style == Kpoints.supported_modes.Reciprocal vis = self.set(dummy_structure, mode="Line", copy_chgcar=True) @@ -1130,7 +1130,7 @@ def test_optics(self): assert vis.incar["ISYM"] == 2 # Check OPTICS=True INCAR settings, LREAL needs to be False when LOPTICS=True - assert vis.incar["CSHIFT"] == 1e-5 + assert vis.incar["CSHIFT"] == approx(1e-5) assert vis.incar["LREAL"] is False assert vis.incar["LOPTICS"] @@ -1226,7 +1226,7 @@ def test_user_heat_speed(self): vis.nsteps = (vis.end_temp - vis.start_temp) / vis.time_step assert vis.incar["TEBEG"] == 0 assert vis.incar["TEEND"] == 1000 - assert vis.incar["POTIM"] == 0.5 + assert vis.incar["POTIM"] == approx(0.5) assert vis.incar["NSW"] == 2000 @@ -1286,20 +1286,20 @@ def test_incar_no_ts(self): assert incar["IBRION"] == 0 assert incar["ISIF"] == 0 assert incar["ISYM"] == 0 - assert incar["POTIM"] == 2.0 + assert incar["POTIM"] == approx(2.0) def test_incar_no_ts_with_h(self): mpmdset = self.mp_md_set_noTS_with_H incar = mpmdset.incar - assert incar["POTIM"] == 0.5 + assert incar["POTIM"] == approx(0.5) assert incar["NSW"] == 4000 def test_incar_ts1(self): mpmdset = self.mp_md_set_TS1 incar = mpmdset.incar - assert incar["POTIM"] == 1.0 + assert incar["POTIM"] == approx(1.0) assert incar["NSW"] == 1000 def test_as_from_dict(self): @@ -1374,7 +1374,7 @@ def test_from_prev_calc(self): assert vis.incar["ICHARG"] == 11 assert vis.incar["SAXIS"] == [1, 0, 0] assert vis.incar["MAGMOM"] == [[0, 0, 3]] - assert vis.incar["SIGMA"] == 0.025 + assert vis.incar["SIGMA"] == approx(0.025) def test_override_from_prev_calc(self): # test override_from_prev_calc @@ -1391,7 +1391,7 @@ def test_override_from_prev_calc(self): assert vis.incar["ICHARG"] == 11 assert vis.incar["SAXIS"] == [1, 0, 0] assert vis.incar["MAGMOM"] == [[0, 0, 3]] - assert vis.incar["SIGMA"] == 0.025 + assert vis.incar["SIGMA"] == approx(0.025) class TestMPNMRSet(PymatgenTest): @@ -1405,14 +1405,14 @@ def test_incar(self): vis = MPNMRSet(structure, mode="efg") assert not vis.incar.get("LCHIMAG") - assert vis.incar.get("QUAD_EFG") == [-0.808] + assert_allclose(vis.incar.get("QUAD_EFG"), [-0.808]) for q in vis.incar["QUAD_EFG"]: assert isinstance(q, float) assert not isinstance(q, FloatWithUnit) vis = MPNMRSet(structure, mode="efg", isotopes=["Li-7"]) assert not vis.incar.get("LCHIMAG") - assert vis.incar.get("QUAD_EFG") == [-40.1] + assert_allclose(vis.incar.get("QUAD_EFG"), [-40.1]) @skip_if_no_psp_dir @@ -1437,15 +1437,15 @@ def test_user_incar_settings(self): # Make sure user incar settings properly override AMIX. si = self.get_structure("Si") vis = self.set(si, user_incar_settings={"AMIX": 0.1}) - assert vis.incar["AMIX"] == 0.1 + assert vis.incar["AMIX"] == approx(0.1) def test_bulk(self): incar_bulk = self.d_bulk["INCAR"] poscar_bulk = self.d_bulk["POSCAR"] assert incar_bulk["ISIF"] == 3 - assert incar_bulk["EDIFF"] == 1e-4 - assert incar_bulk["EDIFFG"] == -0.02 + assert incar_bulk["EDIFF"] == approx(1e-4) + assert incar_bulk["EDIFFG"] == approx(-0.02) assert poscar_bulk.structure.formula == self.bulk.formula def test_slab(self): @@ -1453,9 +1453,9 @@ def test_slab(self): poscar_slab = self.d_slab["POSCAR"] potcar_slab = self.d_slab["POTCAR"] - assert incar_slab["AMIN"] == 0.01 - assert incar_slab["AMIX"] == 0.2 - assert incar_slab["BMIX"] == 0.001 + assert incar_slab["AMIN"] == approx(0.01) + assert incar_slab["AMIX"] == approx(0.2) + assert incar_slab["BMIX"] == approx(0.001) assert incar_slab["NELMIN"] == 8 # No volume relaxation during slab calculations assert incar_slab["ISIF"] == 2 @@ -1494,7 +1494,7 @@ def test_incar(self): incar = mvlparam.incar assert incar["IBRION"] == 6 assert incar["NFREE"] == 2 - assert incar["POTIM"] == 0.015 + assert incar["POTIM"] == approx(0.015) assert "NPAR" not in incar @@ -1514,7 +1514,7 @@ def test_static(self): _ = self.set(mode=mode) mvlgwsc = self.set(self.struct) incar = mvlgwsc.incar - assert incar["SIGMA"] == 0.01 + assert incar["SIGMA"] == approx(0.01) kpoints = mvlgwsc.kpoints assert kpoints.style == Kpoints.supported_modes.Gamma symbols = mvlgwsc.potcar.symbols @@ -1591,21 +1591,21 @@ def test_vdw_and_lasph_none(self): def test_vdw_and_lasph_dftd3(self): vis = self.set(self.structure, vdw="dftd3") assert vis.incar["LASPH"], "LASPH is not set to True" - assert vis.incar["VDW_SR"] == pytest.approx(1.129), "VDW_SR is not set correctly" - assert vis.incar["VDW_S8"] == pytest.approx(0.109), "VDW_S8 is not set correctly" + assert vis.incar["VDW_SR"] == approx(1.129), "VDW_SR is not set correctly" + assert vis.incar["VDW_S8"] == approx(0.109), "VDW_S8 is not set correctly" def test_vdw_and_lasph_dftd3_bj(self): vis = self.set(self.structure, vdw="dftd3-bj") assert vis.incar["LASPH"], "LASPH is not set to True" - assert vis.incar["VDW_A1"] == pytest.approx(0.383), "VDW_A1 is not set correctly" - assert vis.incar["VDW_S8"] == pytest.approx(2.310), "VDW_S8 is not set correctly" - assert vis.incar["VDW_A2"] == pytest.approx(5.685), "VDW_A2 is not set correctly" + assert vis.incar["VDW_A1"] == approx(0.383), "VDW_A1 is not set correctly" + assert vis.incar["VDW_S8"] == approx(2.310), "VDW_S8 is not set correctly" + assert vis.incar["VDW_A2"] == approx(5.685), "VDW_A2 is not set correctly" def test_user_incar_settings(self): user_incar_settings = {"LASPH": False, "VDW_SR": 1.5} vis = self.set(self.structure, vdw="dftd3", user_incar_settings=user_incar_settings) assert not vis.incar["LASPH"], "LASPH user setting not applied" - assert vis.incar["VDW_SR"] == 1.5, "VDW_SR user setting not applied" + assert vis.incar["VDW_SR"] == approx(1.5), "VDW_SR user setting not applied" @unittest.skipIf(not os.path.exists(TEST_DIR), "Test files are not present.") def test_from_prev_calc(self): @@ -1660,7 +1660,7 @@ def test_init(self): vis = self.set.from_prev_calc(prev_calc_dir=prev_run, mode="line") assert vis.incar["LHFCALC"] - assert vis.incar["HFSCREEN"] == 0.2 + assert vis.incar["HFSCREEN"] == approx(0.2) assert vis.incar["NSW"] == 0 assert vis.incar["ISYM"] == 3 assert len(vis.kpoints.kpts) == 180 @@ -1694,7 +1694,7 @@ def test_override_from_prev_calc(self): vis = self.set(dummy_structure, mode="line") vis = vis.override_from_prev_calc(prev_calc_dir=prev_run) assert vis.incar["LHFCALC"] - assert vis.incar["HFSCREEN"] == 0.2 + assert vis.incar["HFSCREEN"] == approx(0.2) assert vis.incar["NSW"] == 0 assert vis.incar["ISYM"] == 3 assert len(vis.kpoints.kpts) == 180 @@ -1716,12 +1716,12 @@ def test_incar(self): assert incar["METAGGA"] == "Scan" assert incar["ADDGRID"] is True assert incar["LASPH"] is True - assert incar["SIGMA"] == 0.05 + assert incar["SIGMA"] == approx(0.05) assert incar["ISMEAR"] == -5 assert incar["NSW"] == 500 # Test SCAN+rVV10 scan_rvv10_set = self.set(self.struct, vdw="rVV10") - assert scan_rvv10_set.incar["BPARAM"] == 15.7 + assert scan_rvv10_set.incar["BPARAM"] == approx(15.7) @skip_if_no_psp_dir def test_potcar(self): @@ -1796,9 +1796,9 @@ def test_incar(self): assert incar["ENCUT"] == 680 assert incar["NSW"] == 500 # the default POTCAR contains metals, but no prev calc set --> bandgap unknown - assert incar["KSPACING"] == 0.22 + assert incar["KSPACING"] == approx(0.22) assert incar["ISMEAR"] == 0 - assert incar["SIGMA"] == 0.2 + assert incar["SIGMA"] == approx(0.2) # https://github.com/materialsproject/pymatgen/pull/3036 for bandgap in (-1e-12, 1e-5, 1e-3): @@ -1825,7 +1825,7 @@ def test_bandgap_tol(self): incar = MPScanRelaxSet(self.struct, bandgap=0.01, bandgap_tol=bandgap_tol).incar assert incar["KSPACING"] == approx(expected_kspacing, abs=1e-5), f"{bandgap_tol=}, {bandgap=}" assert incar["ISMEAR"] == -5 if bandgap > bandgap_tol else 2 - assert incar["SIGMA"] == 0.05 if bandgap > bandgap_tol else 0.2 + assert incar["SIGMA"] == approx(0.05 if bandgap > bandgap_tol else 0.2) def test_kspacing(self): # Test that KSPACING is capped at 0.44 for insulators @@ -1841,7 +1841,7 @@ def test_kspacing(self): incar = MPScanRelaxSet(struct, bandgap=bandgap).incar assert incar["KSPACING"] == approx(expected, abs=1e-5) assert incar["ISMEAR"] == -5 if bandgap > 1e-4 else 2 - assert incar["SIGMA"] == 0.05 if bandgap > 1e-4 else 0.2 + assert incar["SIGMA"] == approx(0.05 if bandgap > 1e-4 else 0.2) def test_incar_overrides(self): # use 'user_incar_settings' to override the KSPACING, ISMEAR, and SIGMA @@ -1851,15 +1851,15 @@ def test_incar_overrides(self): user_incar_settings={"KSPACING": 0.5, "ISMEAR": 0, "SIGMA": 0.05}, ) incar = mp_scan_set2.incar - assert incar["KSPACING"] == 0.5 + assert incar["KSPACING"] == approx(0.5) assert incar["ISMEAR"] == 0 - assert incar["SIGMA"] == 0.05 + assert incar["SIGMA"] == approx(0.05) # Test SCAN+rVV10 def test_rvv10(self): scan_rvv10_set = MPScanRelaxSet(self.struct, vdw="rVV10") assert "LUSE_VDW" in scan_rvv10_set.incar - assert scan_rvv10_set.incar["BPARAM"] == 15.7 + assert scan_rvv10_set.incar["BPARAM"] == approx(15.7) def test_other_vdw(self): # should raise a warning. @@ -1918,7 +1918,7 @@ def test_init(self): # Check that ENCUT and other INCAR settings were inherited. assert vis.incar["ENCUT"] == 680 assert vis.incar["METAGGA"] == "R2scan" - assert vis.incar["KSPACING"] == 0.34292842 + assert vis.incar["KSPACING"] == approx(0.34292842) non_prev_vis = self.set( vis.structure, @@ -1932,7 +1932,7 @@ def test_init(self): # Check that ENCUT and other INCAR settings were inherited. assert non_prev_vis.incar["METAGGA"] == "R2scan" # the KSPACING will have the default value here, since no previous calc - assert non_prev_vis.incar["KSPACING"] == 0.22 + assert non_prev_vis.incar["KSPACING"] == approx(0.22) # Check that user incar settings are applied. assert non_prev_vis.incar["ENCUT"] == 800 assert non_prev_vis.incar["LORBIT"] == 12 @@ -1972,7 +1972,7 @@ def test_override_from_prev_calc(self): # Check that ENCUT and other INCAR settings were inherited. assert vis.incar["ENCUT"] == 680 assert vis.incar["METAGGA"] == "R2scan" - assert vis.incar["KSPACING"] == 0.34292842 + assert vis.incar["KSPACING"] == approx(0.34292842) # Check LCALCPOL flag lcalcpol_vis = self.set(dummy_structure, lcalcpol=True) @@ -2116,7 +2116,7 @@ def test_incar(self): assert incar1["ISMEAR"] == -5 assert incar1["ISYM"] == -1 assert incar1["ALGO"] == "Normal" - assert incar1["EDIFF"] == 1e-6 + assert incar1["EDIFF"] == approx(1e-6) incar2 = self.lobsterset2.incar assert incar2["ISYM"] == 0 assert incar2["ISMEAR"] == 0 diff --git a/tests/phonon/test_dos.py b/tests/phonon/test_dos.py index e586604d81e..b4463db9c59 100644 --- a/tests/phonon/test_dos.py +++ b/tests/phonon/test_dos.py @@ -85,7 +85,7 @@ def test_mul(self): assert dos_2x.densities == approx(2 * self.dos.densities) # test commutativity - assert dos_2x * 1.234 == 1.234 * dos_2x + assert dos_2x * 1.234 == approx(1.234 * dos_2x) def test_eq(self): assert self.dos == self.dos @@ -97,27 +97,27 @@ def test_mae(self): assert self.dos.mae(self.dos) == 0 assert self.dos.mae(self.dos + 1) == 1 assert self.dos.mae(self.dos - 1) == 1 - assert self.dos.mae(2 * self.dos) == pytest.approx(0.786546967) - assert (2 * self.dos).mae(self.dos) == pytest.approx(0.786546967) + assert self.dos.mae(2 * self.dos) == approx(0.786546967) + assert (2 * self.dos).mae(self.dos) == approx(0.786546967) # test two_sided=False after shifting DOS freqs so MAE requires interpolation dos2 = PhononDos(self.dos.frequencies + 0.01, self.dos.densities) - assert self.dos.mae(dos2 + 1, two_sided=False) == pytest.approx(0.999999999) - assert self.dos.mae(dos2 - 1, two_sided=False) == pytest.approx(1.00000000000031) - assert self.dos.mae(2 * dos2, two_sided=False) == pytest.approx(0.786546967) + assert self.dos.mae(dos2 + 1, two_sided=False) == approx(0.999999999) + assert self.dos.mae(dos2 - 1, two_sided=False) == approx(1.00000000000031) + assert self.dos.mae(2 * dos2, two_sided=False) == approx(0.786546967) def test_r2_score(self): assert self.dos.r2_score(self.dos) == 1 - assert self.dos.r2_score(self.dos + 1) == pytest.approx(-0.45647319) - assert self.dos.r2_score(self.dos - 1) == pytest.approx(-0.45647319) - assert self.dos.r2_score(2 * self.dos) == pytest.approx(-0.901056070) + assert self.dos.r2_score(self.dos + 1) == approx(-0.45647319) + assert self.dos.r2_score(self.dos - 1) == approx(-0.45647319) + assert self.dos.r2_score(2 * self.dos) == approx(-0.901056070) # check that r2_score is 0 for DOS with same mean as self.dos densities = self.dos.densities mean_dos = PhononDos(self.dos.frequencies, np.full_like(densities, densities.mean())) - assert self.dos.r2_score(mean_dos) == pytest.approx(0) + assert self.dos.r2_score(mean_dos) == approx(0) # moving away from the mean should decrease r2_score - assert self.dos.r2_score(-mean_dos) == pytest.approx(-3.604224283) + assert self.dos.r2_score(-mean_dos) == approx(-3.604224283) def test_get_last_peak(self): peak_freq = self.dos.get_last_peak() diff --git a/tests/phonon/test_gruneisen.py b/tests/phonon/test_gruneisen.py index 748fd68c8c2..a69cc103125 100644 --- a/tests/phonon/test_gruneisen.py +++ b/tests/phonon/test_gruneisen.py @@ -47,8 +47,8 @@ def test_ph_plot_w_gruneisen(self): "x": [point[0] for point in ax._children[inx].get_offsets().data], "y": [point[1] for point in ax._children[inx].get_offsets().data], } - assert band == pytest.approx(xy_data["y"]) - assert plotter._bs.distance == pytest.approx(xy_data["x"]) + assert band == approx(xy_data["y"]) + assert plotter._bs.distance == approx(xy_data["x"]) # check if color bar max value matches maximum gruneisen parameter value data = plotter.bs_plot_data() @@ -64,7 +64,7 @@ def test_ph_plot_w_gruneisen(self): linscale=1, ) - assert max(norm.inverse(ax.get_figure()._localaxes[-1].get_yticks())) == pytest.approx(max_gruneisen) + assert max(norm.inverse(ax.get_figure()._localaxes[-1].get_yticks())) == approx(max_gruneisen) assert isinstance(ax, plt.Axes) def test_as_dict_from_dict(self): diff --git a/tests/symmetry/test_analyzer.py b/tests/symmetry/test_analyzer.py index 7966c815ce9..6ab60e7c3fb 100644 --- a/tests/symmetry/test_analyzer.py +++ b/tests/symmetry/test_analyzer.py @@ -198,7 +198,7 @@ def test_get_refined_structure(self): structure.add_site_property("magmom", [1.0] * len(structure)) sg = SpacegroupAnalyzer(structure, 0.01) refined_struct = sg.get_refined_structure(keep_site_properties=True) - assert refined_struct.site_properties["magmom"] == [1.0] * len(refined_struct) + assert_allclose(refined_struct.site_properties["magmom"], [1.0] * len(refined_struct)) structure = self.get_structure("Li2O") structure.add_site_property("magmom", [1.0] * len(structure)) @@ -235,7 +235,7 @@ def test_symmetrized_structure(self): s1 = symm_struct.equivalent_sites[1][1] s2 = symm_struct[symm_struct.equivalent_indices[1][1]] assert s1 == s2 - assert self.sg4.get_symmetrized_structure()[0].magmom == 0.1 + assert self.sg4.get_symmetrized_structure()[0].magmom == approx(0.1) assert symm_struct.wyckoff_symbols[0] == "16h" # Check copying @@ -262,7 +262,7 @@ def test_find_primitive(self): structure.add_site_property("magmom", [1.0] * len(structure)) spga = SpacegroupAnalyzer(structure) primitive_structure = spga.find_primitive(keep_site_properties=True) - assert primitive_structure.site_properties["magmom"] == [1.0] * len(primitive_structure) + assert_allclose(primitive_structure.site_properties["magmom"], [1.0] * len(primitive_structure)) structure.add_site_property("magmom", [1.0] * len(structure)) spga = SpacegroupAnalyzer(structure) @@ -362,7 +362,7 @@ def test_get_conventional_standard_structure(self): structure.add_site_property("magmom", [1.0] * len(structure)) spga = SpacegroupAnalyzer(structure, symprec=1e-2) conventional = spga.get_conventional_standard_structure(keep_site_properties=True) - assert conventional.site_properties["magmom"] == [1.0] * len(conventional) + assert_allclose(conventional.site_properties["magmom"], [1.0] * len(conventional)) structure = Structure.from_file(STRUCTURE) structure.add_site_property("magmom", [1.0] * len(structure)) @@ -419,7 +419,7 @@ def test_get_primitive_standard_structure(self): structure.add_site_property("magmom", [1.0] * len(structure)) spga = SpacegroupAnalyzer(structure, symprec=1e-2) prim = spga.get_primitive_standard_structure(keep_site_properties=True) - assert prim.site_properties["magmom"] == [1.0] * len(prim) + assert_allclose(prim.site_properties["magmom"], [1.0] * len(prim)) structure = Structure.from_file(f"{TEST_FILES_DIR}/cif/rhomb_3478_conv.cif") structure.add_site_property("magmom", [1.0] * len(structure)) diff --git a/tests/transformations/test_advanced_transformations.py b/tests/transformations/test_advanced_transformations.py index 2f73ace7cd3..dba563b4e01 100644 --- a/tests/transformations/test_advanced_transformations.py +++ b/tests/transformations/test_advanced_transformations.py @@ -54,7 +54,7 @@ def get_table(): default lambda table. """ json_path = f"{TEST_FILES_DIR}/analysis/struct_predictor/test_lambda.json" - with open(json_path) as file: + with open(json_path, encoding="utf-8") as file: return json.load(file) @@ -250,7 +250,7 @@ def test_as_from_dict(self): trans = EnumerateStructureTransformation() dct = trans.as_dict() trans = EnumerateStructureTransformation.from_dict(dct) - assert trans.symm_prec == 0.1 + assert trans.symm_prec == approx(0.1) class TestSubstitutionPredictorTransformation: @@ -507,7 +507,7 @@ def test_apply_transformation(self): ss = trafo.apply_transformation(structure, 1000) assert len(ss) == n_structures for d in ss: - assert d["structure"].charge == 0 + assert d["structure"].charge == approx(0) # Aliovalent doping with codopant for dopant, n_structures in [("Al3+", 3), ("N3-", 37), ("Cl-", 37)]: @@ -521,7 +521,7 @@ def test_apply_transformation(self): ss = trafo.apply_transformation(structure, 1000) assert len(ss) == n_structures for d in ss: - assert d["structure"].charge == 0 + assert d["structure"].charge == approx(0) # Make sure compensation is done with lowest oxi state structure = PymatgenTest.get_structure("SrTiO3") @@ -599,7 +599,7 @@ def test_apply_transformation(self): output = trans.apply_transformation(struct) assert not output.is_ordered - assert output[-1].species.as_dict() == {"Ni": 0.5, "Ba": 0.5} + assert output[-1].species.as_dict() == approx({"Ni": 0.5, "Ba": 0.5}) @pytest.mark.skipif(not mcsqs_cmd, reason="mcsqs not present.") @@ -724,7 +724,7 @@ def test_apply_transformation_cubic_supercell(self): assert len(superstructure) == 448 assert_array_equal( supercell_generator.transformation_matrix, - np.array([[4, 0, 0], [1, 4, -4], [0, 0, 1]]), + [[4, 0, 0], [1, 4, -4], [0, 0, 1]], ) # Test the diagonal transformation @@ -796,7 +796,7 @@ def test_apply_transformation_orthorhombic_supercell(self): assert_array_equal( supercell_generator_orthorhombic.transformation_matrix, - np.array([[0, -2, 1], [-2, 0, 0], [0, 0, -2]]), + [[0, -2, 1], [-2, 0, 0], [0, 0, -2]], ) # make sure that the orthorhombic supercell is different from the cubic cell @@ -804,8 +804,8 @@ def test_apply_transformation_orthorhombic_supercell(self): supercell_generator_cubic.transformation_matrix, supercell_generator_orthorhombic.transformation_matrix, ) - assert transformed_cubic.lattice.angles != transformed_orthorhombic.lattice.angles - assert transformed_orthorhombic.lattice.abc != transformed_cubic.lattice.abc + assert not np.allclose(transformed_cubic.lattice.angles, transformed_orthorhombic.lattice.angles) + assert not np.allclose(transformed_orthorhombic.lattice.abc, transformed_cubic.lattice.abc) structure = self.get_structure("Si") min_atoms = 100 @@ -835,7 +835,7 @@ def test_apply_transformation_orthorhombic_supercell(self): assert_array_equal( supercell_generator_orthorhombic.transformation_matrix, - np.array([[3, 0, 0], [-2, 4, 0], [-2, 4, 6]]), + [[3, 0, 0], [-2, 4, 0], [-2, 4, 6]], ) # make sure that the orthorhombic supercell is different from the cubic cell @@ -843,9 +843,9 @@ def test_apply_transformation_orthorhombic_supercell(self): supercell_generator_cubic.transformation_matrix, supercell_generator_orthorhombic.transformation_matrix, ) - assert transformed_orthorhombic.lattice.abc != transformed_cubic.lattice.abc - # only angels are expected to be the same because of force_90_degrees = True - assert transformed_cubic.lattice.angles == transformed_orthorhombic.lattice.angles + assert not np.allclose(transformed_orthorhombic.lattice.abc, transformed_cubic.lattice.abc) + # only angels are expected to be the same because of `force_90_degrees = True` + assert_allclose(transformed_cubic.lattice.angles, transformed_orthorhombic.lattice.angles) class TestAddAdsorbateTransformation(PymatgenTest): diff --git a/tests/transformations/test_site_transformations.py b/tests/transformations/test_site_transformations.py index 0e97aceabc0..3660778e8ce 100644 --- a/tests/transformations/test_site_transformations.py +++ b/tests/transformations/test_site_transformations.py @@ -6,6 +6,7 @@ import numpy as np import pytest from numpy.testing import assert_allclose +from pytest import approx from pymatgen.core.structure import Molecule, Structure from pymatgen.transformations.site_transformations import ( @@ -323,29 +324,29 @@ def setUp(self): def test(self): trafo = RadialSiteDistortionTransformation(0, 1, nn_only=True) struct = trafo.apply_transformation(self.molecule) - assert np.array_equal(struct[0].coords, [0, 0, 0]) - assert np.array_equal(struct[1].coords, [2, 0, 0]) - assert np.array_equal(struct[2].coords, [0, 2, 0]) - assert np.array_equal(struct[3].coords, [0, 0, 2]) - assert np.array_equal(struct[4].coords, [-2, 0, 0]) - assert np.array_equal(struct[5].coords, [0, -2, 0]) - assert np.array_equal(struct[6].coords, [0, 0, -2]) + assert_allclose(struct[0].coords, [0, 0, 0]) + assert_allclose(struct[1].coords, [2, 0, 0]) + assert_allclose(struct[2].coords, [0, 2, 0]) + assert_allclose(struct[3].coords, [0, 0, 2]) + assert_allclose(struct[4].coords, [-2, 0, 0]) + assert_allclose(struct[5].coords, [0, -2, 0]) + assert_allclose(struct[6].coords, [0, 0, -2]) trafo = RadialSiteDistortionTransformation(0, 1, nn_only=True) struct = trafo.apply_transformation(self.structure) for c1, c2 in zip(self.structure[1:7], struct[1:7], strict=True): - assert c1.distance(c2) == 1.0 + assert c1.distance(c2) == approx(1.0) - assert np.array_equal(struct[0].coords, [0, 0, 0]) - assert np.array_equal(struct[1].coords, [2, 0, 0]) - assert np.array_equal(struct[2].coords, [0, 2, 0]) - assert np.array_equal(struct[3].coords, [0, 0, 2]) - assert np.array_equal(struct[4].coords, [8, 0, 0]) - assert np.array_equal(struct[5].coords, [0, 8, 0]) - assert np.array_equal(struct[6].coords, [0, 0, 8]) + assert_allclose(struct[0].coords, [0, 0, 0]) + assert_allclose(struct[1].coords, [2, 0, 0]) + assert_allclose(struct[2].coords, [0, 2, 0]) + assert_allclose(struct[3].coords, [0, 0, 2]) + assert_allclose(struct[4].coords, [8, 0, 0]) + assert_allclose(struct[5].coords, [0, 8, 0]) + assert_allclose(struct[6].coords, [0, 0, 8]) def test_second_nn(self): trafo = RadialSiteDistortionTransformation(0, 1, nn_only=False) struct = trafo.apply_transformation(self.molecule) for c1, c2 in zip(self.molecule[7:], struct[7:], strict=True): - assert abs(round(sum(c2.coords - c1.coords), 2)) == 0.33 + assert abs(round(sum(c2.coords - c1.coords), 2)) == approx(0.33) diff --git a/tests/transformations/test_standard_transformations.py b/tests/transformations/test_standard_transformations.py index 0074eece962..d8cf8cb092a 100644 --- a/tests/transformations/test_standard_transformations.py +++ b/tests/transformations/test_standard_transformations.py @@ -199,7 +199,7 @@ def test_as_from_dict(self): trafo = AutoOxiStateDecorationTransformation() dct = trafo.as_dict() trafo = AutoOxiStateDecorationTransformation.from_dict(dct) - assert trafo.analyzer.dist_scale_factor == 1.015 + assert trafo.analyzer.dist_scale_factor == approx(1.015) def test_failure(self): trafo_fail = AutoOxiStateDecorationTransformation() diff --git a/tests/util/test_coord.py b/tests/util/test_coord.py index c97914e6319..aabc9ce6334 100644 --- a/tests/util/test_coord.py +++ b/tests/util/test_coord.py @@ -15,7 +15,7 @@ class TestCoordUtils: def test_get_linear_interpolated_value(self): x_vals = [0, 1, 2, 3, 4, 5] y_vals = [3, 6, 7, 8, 10, 12] - assert coord.get_linear_interpolated_value(x_vals, y_vals, 3.6) == 9.2 + assert coord.get_linear_interpolated_value(x_vals, y_vals, 3.6) == approx(9.2) with pytest.raises(ValueError, match=r"x=6 is out of range of provided x_values \(0, 5\)"): coord.get_linear_interpolated_value(x_vals, y_vals, 6)