Skip to content

Commit

Permalink
Mineral name.
Browse files Browse the repository at this point in the history
  • Loading branch information
knc6 committed Apr 16, 2024
1 parent d45593c commit b4bf120
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 21 deletions.
149 changes: 140 additions & 9 deletions jarvis/core/atoms.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,19 @@
import string
import datetime
from collections import defaultdict
from jarvis.db.jsonutils import loadjson

amu_gm = 1.66054e-24
ang_cm = 1e-8

mineral_json_file = loadjson(
str(
os.path.join(os.path.dirname(__file__), "mineral_name_prototype.json")
# os.path.join(os.path.dirname(__file__), "min.json")
# os.path.join(os.path.dirname(__file__), "mineral_dbj.json")
)
)


class Atoms(object):
"""
Expand Down Expand Up @@ -1168,6 +1177,90 @@ def packing_fraction(self):
pf = np.array([4 * np.pi * total_rad / (3 * self.volume)])
return round(pf[0], 5)

def get_alignn_feats(
self,
model_name="jv_formation_energy_peratom_alignn",
max_neighbors=12,
neighbor_strategy="k-nearest",
use_canonize=True,
atom_features="cgcnn",
line_graph=True,
cutoff=8,
model="",
):
"""Get ALIGNN features."""

def get_val(model, g, lg):
activation = {}

def getActivation(name):
# the hook signature
def hook(model, input, output):
activation[name] = output.detach()

return hook

h = model.readout.register_forward_hook(getActivation("readout"))
out = model([g, lg])
h.remove()
return activation["readout"][0]

from alignn.graphs import Graph
from alignn.pretrained import get_figshare_model

g, lg = Graph.atom_dgl_multigraph(
self,
cutoff=cutoff,
atom_features=atom_features,
max_neighbors=max_neighbors,
neighbor_strategy=neighbor_strategy,
compute_line_graph=line_graph,
use_canonize=use_canonize,
)
if model == "":
model = get_figshare_model(
model_name="jv_formation_energy_peratom_alignn"
)
h = get_val(model, g, lg)
return h

def get_prototype_name(self, include_c_over_a=False, digits=3):
from jarvis.analysis.structure.spacegroup import Spacegroup3D

spg = Spacegroup3D(self)
number = spg.space_group_number
cnv_atoms = spg.conventional_standard_structure
n_conv = cnv_atoms.num_atoms
# hall_number=str(spg._dataset['hall_number'])
wyc = "".join(list((sorted(set(spg._dataset["wyckoffs"])))))
name = (
(self.composition.prototype)
+ "_"
+ str(number)
+ "_"
+ str(wyc)
+ "_"
+ str(n_conv)
)
# if include_com:
if include_c_over_a:
# print(cnv_atoms)
abc = cnv_atoms.lattice.abc
ca = round(abc[2] / abc[0], digits)
# com_positions = "_".join(map(str,self.get_center_of_mass()))
# round(np.sum(spg._dataset['std_positions']),round_digit)
name += "_" + str(ca)
# name+="_"+str(com_positions)
return name

def get_minaral_name(self):
"""Get mineral prototype."""
name = self.get_prototype_name()
if name in mineral_json_file:
return mineral_json_file[name]
else:
return None

def lattice_points_in_supercell(self, supercell_matrix):
"""
Adapted from Pymatgen.
Expand Down Expand Up @@ -1236,6 +1329,7 @@ def describe(
"""Describe for NLP applications."""
from jarvis.analysis.diffraction.xrd import XRD

min_name = self.get_minaral_name()
if include_spg:
from jarvis.analysis.structure.spacegroup import Spacegroup3D

Expand Down Expand Up @@ -1264,6 +1358,7 @@ def describe(
fracs[i] = round(j, 3)
info = {}
chem_info = {
"mineral_name": min_name,
"atomic_formula": self.composition.reduced_formula,
"prototype": self.composition.prototype,
"molecular_weight": round(self.composition.weight / 2, 2),
Expand Down Expand Up @@ -1307,9 +1402,9 @@ def describe(
list(set(spg._dataset["wyckoffs"]))
)
struct_info["natoms_primitive"] = spg.primitive_atoms.num_atoms
struct_info[
"natoms_conventional"
] = spg.conventional_standard_structure.num_atoms
struct_info["natoms_conventional"] = (
spg.conventional_standard_structure.num_atoms
)
info["chemical_info"] = chem_info
info["structure_info"] = struct_info
line = "The number of atoms are: " + str(
Expand Down Expand Up @@ -1372,8 +1467,30 @@ def describe(
+ struct_info["wyckoff"]
+ "."
)
if min_name is not None:
line3 = (
chem_info["atomic_formula"]
+ " is "
+ min_name
+ "-derived structured and"
+ " crystallizes in the "
+ struct_info["crystal_system"]
+ " "
+ str(struct_info["spg_symbol"])
+ " spacegroup."
)
else:
line3 = (
chem_info["atomic_formula"]
+ " crystallizes in the "
+ struct_info["crystal_system"]
+ " "
+ str(struct_info["spg_symbol"])
+ " spacegroup."
)
info["desc_1"] = line1
info["desc_2"] = line2
info["desc_3"] = line3
return info

def make_supercell_matrix(self, scaling_matrix):
Expand Down Expand Up @@ -2037,18 +2154,18 @@ def to_optimade(
info_at["cartesian_site_positions"] = atoms.cart_coords[order].tolist()
info_at["nperiodic_dimensions"] = 3
# info_at["species"] = atoms.elements
info_at[
"species"
] = self.get_optimade_species() # dict(atoms.composition.to_dict())
info_at["species"] = (
self.get_optimade_species()
) # dict(atoms.composition.to_dict())
info_at["elements_ratios"] = list(
atoms.composition.atomic_fraction.values()
)
info_at["structure_features"] = []
info_at["last_modified"] = str(now)
# info_at["more_data_available"] = True
info_at[
"chemical_formula_descriptive"
] = atoms.composition.reduced_formula
info_at["chemical_formula_descriptive"] = (
atoms.composition.reduced_formula
)
info_at["dimension_types"] = [1, 1, 1]
info["attributes"] = info_at
return info
Expand Down Expand Up @@ -2146,6 +2263,20 @@ def build_xanes_poscar(
return atoms


if __name__ == "__main__":
box = [[2.715, 2.715, 0], [0, 2.715, 2.715], [2.715, 0, 2.715]]
coords = [[0, 0, 0], [0.25, 0.25, 0.25]]
elements = ["Si", "Si"]
Si = Atoms(
lattice_mat=box, coords=coords, elements=elements
).make_supercell_matrix([3, 3, 3])
# Si = Atoms.from_poscar("POSCAR")
print(Si.get_prototype_name())
print("min name", Si.get_minaral_name())
# afeats = Si.get_alignn_feats()
# print('afeats',afeats)
# print(Si.describe()['desc_3'])

# ['Mn ', 'Mn ', 'Ru ', 'U ']
#
# def clear_elements(atoms=None):
Expand Down
21 changes: 16 additions & 5 deletions jarvis/core/composition.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Modules handling chemical composition."""

# from math import gcd
import string
from jarvis.core.specie import Specie
Expand Down Expand Up @@ -72,13 +73,23 @@ def prototype(self):
"""Get chemical prototypes such as A, AB etc."""
proto = ""
all_upper = string.ascii_uppercase

# print('reduce',self.reduce())
reduced, repeat = self.reduce()
items = sorted(list(reduced.values()), reverse=True)
# print('items',items)
N = 0
for specie, count in reduced.items():
proto = proto + str(all_upper[N]) + str(round(count, 3))
N = N + 1
return proto.replace("1", "")
for c in items:
if c == 1:
proto = proto + str(all_upper[N])
N = N + 1
else:
proto = proto + str(all_upper[N]) + str(round(c, 3))
N = N + 1

# for specie, count in reduced.items():
# proto = proto + str(all_upper[N]) + str(round(count, 3))
# N = N + 1
return proto # .replace("1", "")

def to_dict(self):
"""Return dictionary format."""
Expand Down
1 change: 1 addition & 0 deletions jarvis/core/mineral_name_prototype.json

Large diffs are not rendered by default.

18 changes: 11 additions & 7 deletions jarvis/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,16 +249,13 @@ def operate_affine(cart_coord=[], affine_matrix=[]):

def gaussian(x, sigma):
"""Get Gaussian profile."""
return np.exp(-(x ** 2) / (2 * sigma ** 2))
return np.exp(-(x**2) / (2 * sigma**2))


def lorentzian2(x, gamma):
"""Get Lorentziann profile."""
return (
gamma
/ 2
/ (np.pi * (x ** 2 + (gamma / 2) ** 2))
/ (2 / (np.pi * gamma))
gamma / 2 / (np.pi * (x**2 + (gamma / 2) ** 2)) / (2 / (np.pi * gamma))
)


Expand All @@ -275,7 +272,14 @@ def digitize_array(values=[], max_len=10):


def bond_angle(
dist1, dist2, bondx1, bondx2, bondy1, bondy2, bondz1, bondz2,
dist1,
dist2,
bondx1,
bondx2,
bondy1,
bondy2,
bondz1,
bondz2,
):
"""Get an angle."""
nm = dist1 * dist2
Expand Down Expand Up @@ -324,7 +328,7 @@ def volumetric_grid_reshape(data=[], final_grid=[50, 50, 50]):

def cos_formula(a, b, c):
"""Get angle between three edges for oblique triangles."""
res = (a ** 2 + b ** 2 - c ** 2) / (2 * a * b)
res = (a**2 + b**2 - c**2) / (2 * a * b)
res = -1.0 if res < -1.0 else res
res = 1.0 if res > 1.0 else res
return np.arccos(res)
Expand Down

0 comments on commit b4bf120

Please sign in to comment.