Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vectorize BadELF #606

Merged
merged 51 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
325de04
Add matrix property to grid
SWeav02 Jan 23, 2024
ad37fe9
Update partitioning scheme
SWeav02 Jan 23, 2024
8938b1b
Update Voxel Assignment Scheme
SWeav02 Jan 25, 2024
02674ef
Fix bug in partitioning
SWeav02 Jan 26, 2024
39b1101
Small updates to voxel assignment
SWeav02 Feb 1, 2024
655f6df
update indexing in partitioning
SWeav02 Feb 2, 2024
478b378
Add partitioning refinement
SWeav02 Feb 2, 2024
6873a78
Fix bug with calculating voxel frac coords
SWeav02 Feb 2, 2024
bdb2382
Small documentation improvement
SWeav02 Feb 2, 2024
a6fce78
Small documentation improvement
SWeav02 Feb 2, 2024
0adc4b7
Small bug fix
SWeav02 Feb 2, 2024
860afd6
Fix major error in voxel assignment
SWeav02 Feb 5, 2024
5a32408
black and isort
SWeav02 Feb 5, 2024
f5dcabb
Update Voxel Assignment Doc Strings
SWeav02 Feb 5, 2024
ccb0841
Update remaining Doc strings
SWeav02 Feb 5, 2024
7bf5ed4
Remove plane reduction method
SWeav02 Feb 5, 2024
87f0349
Fix plane selection bug in voxel assignment
SWeav02 Feb 5, 2024
4376a27
Fix bug in electride voxel assignment
SWeav02 Feb 6, 2024
ce003b2
Merge pull request #2 from SWeav02/simple_plane_split
SWeav02 Feb 6, 2024
e045feb
Add backup for when voxels are assigned to multiple sites
SWeav02 Feb 6, 2024
faed091
Fix bug in electride finder
SWeav02 Feb 6, 2024
47571c2
Remove Core parameter
SWeav02 Feb 7, 2024
84da132
Add matrix property to grid
SWeav02 Jan 23, 2024
87f6ffb
Update partitioning scheme
SWeav02 Jan 23, 2024
58d33f9
Update Voxel Assignment Scheme
SWeav02 Jan 25, 2024
cabafd2
Fix bug in partitioning
SWeav02 Jan 26, 2024
370d31c
Small updates to voxel assignment
SWeav02 Feb 1, 2024
aa58f73
update indexing in partitioning
SWeav02 Feb 2, 2024
ba9f0eb
Add partitioning refinement
SWeav02 Feb 2, 2024
e43dec7
Fix bug with calculating voxel frac coords
SWeav02 Feb 2, 2024
43c129a
Small documentation improvement
SWeav02 Feb 2, 2024
c39c48c
Small documentation improvement
SWeav02 Feb 2, 2024
bfc09f6
Small bug fix
SWeav02 Feb 2, 2024
8129d62
Fix major error in voxel assignment
SWeav02 Feb 5, 2024
a249dd5
black and isort
SWeav02 Feb 5, 2024
128693b
Update Voxel Assignment Doc Strings
SWeav02 Feb 5, 2024
f2cff94
Update remaining Doc strings
SWeav02 Feb 5, 2024
a0cc19f
Remove plane reduction method
SWeav02 Feb 5, 2024
03e6a60
Fix plane selection bug in voxel assignment
SWeav02 Feb 5, 2024
85b2adf
Fix bug in electride voxel assignment
SWeav02 Feb 6, 2024
cb91ae4
Add backup for when voxels are assigned to multiple sites
SWeav02 Feb 6, 2024
a9be298
Fix bug in electride finder
SWeav02 Feb 6, 2024
6213707
Remove Core parameter
SWeav02 Feb 7, 2024
d8e3a10
Merge remote-tracking branch 'origin/vectorize_badelf' into vectorize…
SWeav02 Feb 7, 2024
9efa05f
supress warnings in context
SWeav02 Feb 7, 2024
391ec1f
Add BadelfConfig line when registering badelf
SWeav02 Feb 7, 2024
8842f23
Remove cores parameter documentation
SWeav02 Feb 7, 2024
d3472d6
supress warning in context
SWeav02 Feb 7, 2024
7e9baf2
Merge branch 'main' into vectorize_badelf
SWeav02 Feb 7, 2024
aac8ed9
run black
jacksund Feb 12, 2024
38975d1
Merge branch 'main' into vectorize_badelf
jacksund Feb 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion docs/apps/badelf.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ workflow_name: bad-elf.badelf.badelf
directory: /path/to/folder

# all parameters below are optional
cores: 4
find_electrides: true
min_elf: 0.5
algorithm: badelf
Expand Down
19 changes: 0 additions & 19 deletions docs/parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -321,25 +321,6 @@ For evolutionary searches, the search will be considered converged when the best

--------------------------

## cores
This parameter is exclusive to the BadELF workflows in the warrenapp. It specifies the number of computer cores that the BadELF algorithm can utilize. Note that this refers specifically to cores and not threads.

=== "yaml"
``` yaml
cores: 10
```
=== "toml"
``` toml
cores = 10
```
=== "python"
``` python
cores = 10
```

--------------------------


## copy_previous_directory
This parameter determines whether to copy the directory from the previous calculation (if one exists) and use it as a starting point for the new calculation. This is only possible if you provided an input that points to a previous calculation. For instance, `structure` would need to use a database-like input:

Expand Down
472 changes: 216 additions & 256 deletions src/simmate/apps/badelf/core/badelf.py

Large diffs are not rendered by default.

120 changes: 73 additions & 47 deletions src/simmate/apps/badelf/core/electride_finder.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
import logging
import math
import warnings
from functools import cached_property
from pathlib import Path

Expand Down Expand Up @@ -39,16 +40,18 @@ def local_maxima(self):
"""
return self.find_local_maxima()

def find_local_maxima(self, neighborhood_size=1, threshold=None):
def find_local_maxima(self, neighborhood_size: int = 2, threshold: float = None):
"""
Find local maxima in a 3D numpy array.

Args:
- neighborhood_size: Size of the neighborhood for finding local maxima
- threshold: Threshold for considering a point as a local maximum
neighborhood_size (int):
Size of the neighborhood for finding local maxima
threshold (float):
Threshold for considering a point as a local maximum

Returns:
- List of tuples containing the coordinates of local maxima
List of tuples containing the coordinates of local maxima
"""
grid = self.grid.copy()
grid.regrid(desired_resolution=1000)
Expand Down Expand Up @@ -93,7 +96,17 @@ def find_local_maxima(self, neighborhood_size=1, threshold=None):
return maxima_cart_coords, maxima_values

@staticmethod
def to_number_from_roman_numeral(roman_num):
def to_number_from_roman_numeral(roman_num: str):
"""
Converts from a roman numeral to an integer

Args:
roman_num (str):
The roman numeral to convert from

Returns:
The integer representation of the roman numeral
"""
lookup = {
"X": 10,
"V": 5,
Expand Down Expand Up @@ -121,6 +134,9 @@ def shannon_radii_estimate(self):
"""
Gets the shannon crystal radii for each atom in the structure. The
oxidation states are estimated using traditional bader.

Returns:
A dictionary connecting atomic sites to oxidation states
"""
directory = self.directory
structure = self.grid.structure
Expand Down Expand Up @@ -148,7 +164,11 @@ def shannon_radii_estimate(self):
# radius. For electrides we'll often get estimated oxidation states
# that are far from accurate, so we get the closest available radius
oxidation_state = oxidation_states[site_index]
coord_env = cnn.get_cn(structure, site_index)
with warnings.catch_warnings():
warnings.filterwarnings(
"ignore", category=UserWarning, module="pymatgen"
)
coord_env = cnn.get_cn(structure, site_index)

available_ox_state = species_dict.keys()
# We find the closest oxidation state to the one we got from bader.
Expand Down Expand Up @@ -181,6 +201,9 @@ def shannon_radii_estimate(self):
def elf_radii(self):
"""
Gets the elf radius of each atom in the structure

Returns:
A dictionary connecting atomic sites to their elf ionic radii
"""
grid = self.grid.copy()
structure = grid.structure.copy()
Expand All @@ -194,10 +217,11 @@ def elf_radii(self):
# structure if it exists (or itself if its the earliest equivalent one).
# Now we want to get the ELF radius for each unique atom. We iterate over
# each unique atom to get its radius and add it to a dictionary.
partitioning_toolkit = PartitioningToolkit(grid)
unique_atoms = np.unique(equivalent_atoms)
unique_atom_radii = {}
for atom in unique_atoms:
radius = PartitioningToolkit(grid).get_elf_ionic_radius(
radius = partitioning_toolkit.get_elf_ionic_radius(
site_index=atom,
structure=structure,
)
Expand All @@ -220,14 +244,15 @@ def get_ionic_radii(
"""
Gets the radius for each atom in the structure.

Parameters
----------
Args:
method (str):
The method used to find the radii. Options are "elf" or "shannon".
elf will use the provided grid to find the radius of each atom and
shannon will use bader oxidation states and the closest available
tabulated shannon crystal radius.

method : str, optional
The method used to find the radii. Options are "elf" or "shannon".
elf will use the provided grid to find the radius of each atom and
shannon will use bader oxidation states and the closest available
tabulated shannon crystal radius.
Returns:
A dictionary of radii for each atom in the structure.
"""
if method == "elf":
atom_radii = self.elf_radii
Expand All @@ -244,7 +269,7 @@ def get_ionic_radii(
def get_electride_structure(
self,
electride_finder_cutoff: float = 0.5,
min_electride_radius: float = 0.9,
min_electride_radius: float = 0.0,
atom_radius_method: str = "elf",
remove_old_electrides: bool = False,
local_maxima_coords: list = None,
Expand All @@ -255,37 +280,34 @@ def get_electride_structure(
"""
Finds the electrides in a structure using an ELF grid.

Parameters
----------

electride_finder_cutoff : float, optional
The minimum elf value at the site to be considered a possible
electride. The default is 0.5.
min_electride_radius : float, optional
The minimum elf radius around the maximum for it to be considered
an electride. The default is 0.9 which is somewhat arbitrarily chosen.
An goold alternative is 1.19 which is the average radius of fluoride
in a 6 coordination environment.
atom_radius_method : str, optional
The method used to find the radii. Options are "elf" or "shannon".
elf will use the provided grid to find the radius of each atom and
shannon will use bader oxidation states and the closest available
tabulated shannon crystal radius.
local_maxima_coords : list, optional
The coordinates of all local maxima in the grid. This will be found
automatically if not set.
local_maxima_values : list, optional
The values at the local maxima. This will be found automatically if
not set.
remove_old_electrides : bool, optional
Whether or not to remove any other electrides already placed in
the system. It is generally recommended that structures without
electrides are provided.

Returns
-------
A structure object with the found electride sites labeled with "He"
dummy atoms.
Args:
electride_finder_cutoff (float):
The minimum elf value at the site to be considered a possible
electride. The default is 0.5.
min_electride_radius (float):
The minimum elf radius around the maximum for it to be considered
an electride. The default is 0 allowing any possible site.
An good alternative is 1.19 which is the average radius of fluoride
in a 6 coordination environment.
atom_radius_method (str):
The method used to find the radii. Options are "elf" or "shannon".
elf will use the provided grid to find the radius of each atom and
shannon will use bader oxidation states and the closest available
tabulated shannon crystal radius.
local_maxima_coords (list):
The coordinates of all local maxima in the grid. This will be found
automatically if not set.
local_maxima_values (list):
The values at the local maxima. This will be found automatically if
not set.
remove_old_electrides (bool):
Whether or not to remove any other electrides already placed in
the system. It is generally recommended that structures without
electrides are provided.

Returns:
A structure object with the found electride sites labeled with "He"
dummy atoms.
"""
logging.info("Finding electride sites")
# Get the coordinates and values of each local maximum in the grid
Expand Down Expand Up @@ -327,7 +349,11 @@ def get_electride_structure(
# Get the nearest neighbors of the electride. cnn will return a dict
# with multiple keys. These might be different methods of finding neighbors?
# I pick the one with the most neighbors
_, _, electride_neighbors = cnn.get_nn_data(electride_structure, n=-1)
with warnings.catch_warnings():
warnings.filterwarnings(
"ignore", category=UserWarning, module="pymatgen"
)
_, _, electride_neighbors = cnn.get_nn_data(electride_structure, n=-1)
most_neighbors = max(electride_neighbors)
electride_neighbors = electride_neighbors[most_neighbors]

Expand Down
Loading
Loading