19
19
import numpy as np
20
20
from monty .dev import deprecated , requires
21
21
from monty .serialization import loadfn
22
- from ruamel .yaml import YAML
23
- from scipy .spatial import Voronoi
24
-
25
22
from pymatgen .analysis .bond_valence import BV_PARAMS , BVAnalyzer
26
23
from pymatgen .analysis .graphs import MoleculeGraph , StructureGraph
27
24
from pymatgen .analysis .molecule_structure_comparator import CovalentRadius
28
25
from pymatgen .core import Element , IStructure , PeriodicNeighbor , PeriodicSite , Site , Species , Structure
26
+ from ruamel .yaml import YAML
27
+ from scipy .spatial import Voronoi
29
28
30
29
try :
31
30
from openbabel import openbabel
35
34
if TYPE_CHECKING :
36
35
from typing import Any
37
36
38
- from typing_extensions import Self
39
-
40
37
from pymatgen .core .composition import SpeciesLike
41
38
from pymatgen .util .typing import Tuple3Ints
39
+ from typing_extensions import Self
42
40
43
41
44
42
__author__ = "Shyue Ping Ong, Geoffroy Hautier, Sai Jayaraman, "
@@ -1161,7 +1159,7 @@ def _is_in_targets(site, targets):
1161
1159
targets ([Element]) List of elements
1162
1160
1163
1161
Returns:
1164
- bool : Whether this site contains a certain list of elements
1162
+ boolean : Whether this site contains a certain list of elements
1165
1163
"""
1166
1164
elems = _get_elements (site )
1167
1165
return all (elem in targets for elem in elems )
@@ -1218,7 +1216,7 @@ def __init__(
1218
1216
1219
1217
# Update any user preference elemental radii
1220
1218
if el_radius_updates :
1221
- self .el_radius |= el_radius_updates
1219
+ self .el_radius . update ( el_radius_updates )
1222
1220
1223
1221
@property
1224
1222
def structures_allowed (self ) -> bool :
@@ -1984,7 +1982,7 @@ def get_okeeffe_distance_prediction(el1, el2):
1984
1982
"""Get an estimate of the bond valence parameter (bond length) using
1985
1983
the derived parameters from 'Atoms Sizes and Bond Lengths in Molecules
1986
1984
and Crystals' (O'Keeffe & Brese, 1991). The estimate is based on two
1987
- experimental parameters: r and c. The value for r is based off radius,
1985
+ experimental parameters: r and c. The value for r is based off radius,
1988
1986
while c is (usually) the Allred-Rochow electronegativity. Values used
1989
1987
are *not* generated from pymatgen, and are found in
1990
1988
'okeeffe_params.json'.
@@ -2755,7 +2753,7 @@ def get_type(self, index):
2755
2753
raise ValueError ("Index for getting order parameter type out-of-bounds!" )
2756
2754
return self ._types [index ]
2757
2755
2758
- def get_parameters (self , index : int ) -> list [ float ] :
2756
+ def get_parameters (self , index ) :
2759
2757
"""Get list of floats that represents
2760
2758
the parameters associated
2761
2759
with calculation of the order
@@ -2764,10 +2762,12 @@ def get_parameters(self, index: int) -> list[float]:
2764
2762
inputted because of processing out of efficiency reasons.
2765
2763
2766
2764
Args:
2767
- index (int): index of order parameter for which to return associated params.
2765
+ index (int):
2766
+ index of order parameter for which associated parameters
2767
+ are to be returned.
2768
2768
2769
2769
Returns:
2770
- list [float]: parameters of a given OP.
2770
+ [float]: parameters of a given OP.
2771
2771
"""
2772
2772
if index < 0 or index >= len (self ._types ):
2773
2773
raise ValueError ("Index for getting parameters associated with order parameter calculation out-of-bounds!" )
@@ -3990,7 +3990,7 @@ def get_nn_data(self, structure: Structure, n: int, length=None):
3990
3990
nn_info .append (entry )
3991
3991
cn = len (nn_info )
3992
3992
cn_nninfo [cn ] = nn_info
3993
- cn_weights [cn ] = self ._semicircle_integral (dist_bins , idx )
3993
+ cn_weights [cn ] = self ._quadrant_integral (dist_bins , idx )
3994
3994
3995
3995
# add zero coord
3996
3996
cn0_weight = 1 - sum (cn_weights .values ())
@@ -4047,10 +4047,13 @@ def get_cn_dict(self, structure: Structure, n: int, use_weights: bool = False, *
4047
4047
return super ().get_cn_dict (structure , n , use_weights )
4048
4048
4049
4049
@staticmethod
4050
- def _semicircle_integral (dist_bins , idx ) :
4050
+ def _semicircle_integral (dist_bins : list , idx : int ) -> float :
4051
4051
"""
4052
4052
An internal method to get an integral between two bounds of a unit
4053
4053
semicircle. Used in algorithm to determine bond probabilities.
4054
+ This function has an issue, which is detailed at
4055
+ https://github.com/materialsproject/pymatgen/issues/3973.
4056
+ Therefore, _quadrant_integral is now the method of choice.
4054
4057
4055
4058
Args:
4056
4059
dist_bins: (float) list of all possible bond weights
@@ -4075,6 +4078,35 @@ def _semicircle_integral(dist_bins, idx):
4075
4078
4076
4079
return (area1 - area2 ) / (0.25 * math .pi * radius ** 2 )
4077
4080
4081
+ @staticmethod
4082
+ def _quadrant_integral (dist_bins : list , idx : int ) -> float :
4083
+ """
4084
+ An internal method to get an integral between two bounds of a unit
4085
+ quadrant. Used in algorithm to determine bond probabilities.
4086
+
4087
+ Args:
4088
+ dist_bins: (float) list of all possible bond weights
4089
+ idx: (float) index of starting bond weight
4090
+
4091
+ Returns:
4092
+ float: integral of portion of unit quadrant
4093
+ """
4094
+ radius = 1
4095
+
4096
+ x1 = dist_bins [idx ]
4097
+ x2 = dist_bins [idx + 1 ]
4098
+
4099
+ areaquarter = 0.25 * math .pi * radius ** 2
4100
+
4101
+ area1 = areaquarter - 0.5 * (radius ** 2 * math .acos (
4102
+ 1 - x1 / radius ) - (radius - x1 ) * math .sqrt (
4103
+ 2 * radius * x1 - x1 ** 2 ))
4104
+ area2 = areaquarter - 0.5 * (radius ** 2 * math .acos (
4105
+ 1 - x2 / radius ) - (radius - x2 ) * math .sqrt (
4106
+ 2 * radius * x2 - x2 ** 2 ))
4107
+
4108
+ return (area2 - area1 ) / areaquarter
4109
+
4078
4110
@staticmethod
4079
4111
def transform_to_length (nn_data , length ):
4080
4112
"""
0 commit comments