raddefects 0.1.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- raddefects-0.1.3/LICENSE +21 -0
- raddefects-0.1.3/PKG-INFO +48 -0
- raddefects-0.1.3/README.md +2 -0
- raddefects-0.1.3/docs/conf.py +82 -0
- raddefects-0.1.3/pyproject.toml +41 -0
- raddefects-0.1.3/raddefects/__init__.py +10 -0
- raddefects-0.1.3/raddefects/analysis/transition_levels.py +104 -0
- raddefects-0.1.3/raddefects/cli/__init__.py +5 -0
- raddefects-0.1.3/raddefects/cli/main.py +0 -0
- raddefects-0.1.3/raddefects/core.py +253 -0
- raddefects-0.1.3/raddefects/sxda/analysis.py +162 -0
- raddefects-0.1.3/raddefects/sxda/io.py +59 -0
- raddefects-0.1.3/raddefects.egg-info/PKG-INFO +48 -0
- raddefects-0.1.3/raddefects.egg-info/SOURCES.txt +17 -0
- raddefects-0.1.3/raddefects.egg-info/dependency_links.txt +1 -0
- raddefects-0.1.3/raddefects.egg-info/entry_points.txt +2 -0
- raddefects-0.1.3/raddefects.egg-info/requires.txt +12 -0
- raddefects-0.1.3/raddefects.egg-info/top_level.txt +3 -0
- raddefects-0.1.3/setup.cfg +4 -0
raddefects-0.1.3/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Alexander Hauck
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: raddefects
|
|
3
|
+
Version: 0.1.3
|
|
4
|
+
Summary: Framework to analyze properties of radiation-induced defects in semiconductor materials from first principles.
|
|
5
|
+
Author-email: Alexander Hauck <ash5615@psu.edu>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2024 Alexander Hauck
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Project-URL: Homepage, https://radDefects.readthedocs.io/en/latest/
|
|
29
|
+
Project-URL: Repository, https://github.com/hauck-as/radDefects
|
|
30
|
+
Classifier: Programming Language :: Python :: 3
|
|
31
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
32
|
+
Classifier: Operating System :: OS Independent
|
|
33
|
+
Requires-Python: >=3.6
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
License-File: LICENSE
|
|
36
|
+
Requires-Dist: requests
|
|
37
|
+
Requires-Dist: importlib-metadata; python_version < "3.12"
|
|
38
|
+
Requires-Dist: numpy
|
|
39
|
+
Requires-Dist: pymatgen
|
|
40
|
+
Requires-Dist: mp-api
|
|
41
|
+
Requires-Dist: vise
|
|
42
|
+
Requires-Dist: pydefect
|
|
43
|
+
Requires-Dist: sumo
|
|
44
|
+
Requires-Dist: pymatgen-analysis-defects
|
|
45
|
+
Requires-Dist: niet
|
|
46
|
+
|
|
47
|
+
# radDefects
|
|
48
|
+
Framework to analyze properties of radiation-induced defects in semiconductor materials from first principles.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Configuration file for the Sphinx documentation builder.
|
|
2
|
+
# Templated from both RTD tutorial and doped by SMTG-Bham.
|
|
3
|
+
|
|
4
|
+
# -- Project information
|
|
5
|
+
|
|
6
|
+
project = 'radDefects'
|
|
7
|
+
copyright = '2024, Alexander S. Hauck'
|
|
8
|
+
author = 'Alexander S. Hauck'
|
|
9
|
+
|
|
10
|
+
release = '0.1'
|
|
11
|
+
version = '0.1.3'
|
|
12
|
+
|
|
13
|
+
# -- General configuration
|
|
14
|
+
|
|
15
|
+
extensions = [
|
|
16
|
+
'sphinx.ext.duration',
|
|
17
|
+
'sphinx.ext.doctest',
|
|
18
|
+
'sphinx.ext.autodoc',
|
|
19
|
+
'sphinx.ext.autosummary',
|
|
20
|
+
'sphinx.ext.intersphinx',
|
|
21
|
+
'sphinx.ext.coverage',
|
|
22
|
+
'sphinx.ext.napoleon',
|
|
23
|
+
'sphinx.ext.mathjax',
|
|
24
|
+
'sphinx.ext.viewcode',
|
|
25
|
+
'sphinx.ext.autosectionlabel',
|
|
26
|
+
'sphinx_book_theme',
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
intersphinx_mapping = {
|
|
30
|
+
'python': ('https://docs.python.org/3/', None),
|
|
31
|
+
'sphinx': ('https://www.sphinx-doc.org/en/master/', None),
|
|
32
|
+
}
|
|
33
|
+
intersphinx_disabled_domains = ['std']
|
|
34
|
+
|
|
35
|
+
templates_path = ['_templates']
|
|
36
|
+
|
|
37
|
+
# -- Options for HTML output
|
|
38
|
+
|
|
39
|
+
# The theme to use for HTML and HTML Help pages. See the documentation for
|
|
40
|
+
# a list of builtin themes.
|
|
41
|
+
#
|
|
42
|
+
html_theme = 'sphinx_book_theme'
|
|
43
|
+
|
|
44
|
+
# The name of an image file (relative to this directory) to place at the top
|
|
45
|
+
# of the sidebar.
|
|
46
|
+
# html_logo = "rad-defects-logo.png"
|
|
47
|
+
html_title = "radDefects"
|
|
48
|
+
|
|
49
|
+
# If true, SmartyPants will be used to convert quotes and dashes to
|
|
50
|
+
# typographically correct entities.
|
|
51
|
+
html_use_smartypants = True
|
|
52
|
+
|
|
53
|
+
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
|
54
|
+
# html_show_sphinx = True
|
|
55
|
+
|
|
56
|
+
html_theme_options = {
|
|
57
|
+
"repository_url": "https://github.com/hauck-as/radDefects",
|
|
58
|
+
"github_repo": "https://github.com/hauck-as/radDefects",
|
|
59
|
+
"github_button": True,
|
|
60
|
+
"github_user": "hauck-as", # Username
|
|
61
|
+
"description": "Framework to analyze properties of radiation-induced defects in semiconductor materials from first principles.",
|
|
62
|
+
"repository_branch": "main",
|
|
63
|
+
"path_to_docs": "docs",
|
|
64
|
+
"use_repository_button": True,
|
|
65
|
+
"home_page_in_toc": True,
|
|
66
|
+
"launch_buttons": {
|
|
67
|
+
"binderhub_url": "https://mybinder.org",
|
|
68
|
+
"colab_url": "https://colab.research.google.com",
|
|
69
|
+
},
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
# Adding “Edit Source” links on your Sphinx theme
|
|
73
|
+
html_context = {
|
|
74
|
+
"display_github": True, # Integrate GitHub
|
|
75
|
+
"github_user": "hauck-as", # Username
|
|
76
|
+
"github_repo": "radDefects", # Repo name
|
|
77
|
+
"github_version": "main", # Version
|
|
78
|
+
"conf_py_path": "/docs/", # Path in the checkout to the docs root
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
# -- Options for EPUB output
|
|
82
|
+
epub_show_urls = 'footnote'
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "raddefects"
|
|
3
|
+
version = "0.1.3"
|
|
4
|
+
authors = [
|
|
5
|
+
{ name="Alexander Hauck", email="ash5615@psu.edu" },
|
|
6
|
+
]
|
|
7
|
+
description = "Framework to analyze properties of radiation-induced defects in semiconductor materials from first principles."
|
|
8
|
+
readme = "README.md"
|
|
9
|
+
license = {file = "LICENSE"}
|
|
10
|
+
requires-python = ">=3.6"
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Programming Language :: Python :: 3",
|
|
13
|
+
"License :: OSI Approved :: MIT License",
|
|
14
|
+
"Operating System :: OS Independent",
|
|
15
|
+
]
|
|
16
|
+
dependencies = [
|
|
17
|
+
"requests",
|
|
18
|
+
'importlib-metadata; python_version<"3.12"',
|
|
19
|
+
"numpy",
|
|
20
|
+
"pymatgen",
|
|
21
|
+
"mp-api",
|
|
22
|
+
"vise",
|
|
23
|
+
"pydefect",
|
|
24
|
+
"sumo",
|
|
25
|
+
"pymatgen-analysis-defects",
|
|
26
|
+
"niet"
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[project.urls]
|
|
30
|
+
Homepage = "https://radDefects.readthedocs.io/en/latest/"
|
|
31
|
+
Repository = "https://github.com/hauck-as/radDefects"
|
|
32
|
+
|
|
33
|
+
[project.scripts]
|
|
34
|
+
cli-name = "raddefects.cli.main:main"
|
|
35
|
+
|
|
36
|
+
[tool.setuptools.packages]
|
|
37
|
+
find = {} # Scan the project directory with the default parameters
|
|
38
|
+
|
|
39
|
+
[build-system]
|
|
40
|
+
requires = ["setuptools>=61.0"]
|
|
41
|
+
build-backend = "setuptools.build_meta"
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Copyright (c) 2024 Alexander Hauck. Distributed under the terms of the MIT License.
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
radDefects is a Python-based framework to analyze properties of radiation-induced defects in semiconductor materials from first principles.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
__author__ = "Alexander Hauck"
|
|
8
|
+
__copyright__ = "Copyright (C) 2024 Alexander Hauck"
|
|
9
|
+
__license__ = "MIT License"
|
|
10
|
+
__version__ = "0.0.1"
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"""Analysis for charge transition levels within the pydefect format."""
|
|
2
|
+
import logging
|
|
3
|
+
from typing import TYPE_CHECKING, Optional
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import glob
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
import json
|
|
9
|
+
from monty.serialization import dumpfn, loadfn
|
|
10
|
+
from monty.json import MSONable, MontyEncoder, MontyDecoder
|
|
11
|
+
|
|
12
|
+
import re
|
|
13
|
+
import pprint
|
|
14
|
+
|
|
15
|
+
import numpy as np
|
|
16
|
+
import pandas as pd
|
|
17
|
+
import matplotlib as mpl
|
|
18
|
+
import matplotlib.pyplot as plt
|
|
19
|
+
import plotly.graph_objects as go
|
|
20
|
+
import plotly.express as px
|
|
21
|
+
from plotly.subplots import make_subplots
|
|
22
|
+
import plotly.io as pio
|
|
23
|
+
|
|
24
|
+
from pydefect.analyzer.unitcell import Unitcell
|
|
25
|
+
from pydefect.analyzer.band_edge_states import BandEdgeOrbitalInfos, BandEdgeState, PerfectBandEdgeState
|
|
26
|
+
from pydefect.analyzer.defect_energy import DefectEnergyInfo, ChargeEnergies, SingleChargeEnergies, CrossPoints
|
|
27
|
+
from pydefect.analyzer.transition_levels import TransitionLevels, make_transition_levels
|
|
28
|
+
|
|
29
|
+
# Change Plotly default template to simple white and modify for
|
|
30
|
+
pl_paper_theme = pio.templates['simple_white']
|
|
31
|
+
pl_paper_theme.layout.xaxis.ticks = 'inside'
|
|
32
|
+
pl_paper_theme.layout.yaxis.ticks = 'inside'
|
|
33
|
+
pl_paper_theme.layout.xaxis.mirror = 'ticks' # True | "ticks" | False | "all" | "allticks"
|
|
34
|
+
pl_paper_theme.layout.yaxis.mirror = 'ticks' # True | "ticks" | False | "all" | "allticks"
|
|
35
|
+
pl_paper_theme.layout.font.size = 32
|
|
36
|
+
# pl_paper_theme.layout.xaxis.title.standoff = 20
|
|
37
|
+
pl_paper_theme.layout.xaxis.title.font.size = 44
|
|
38
|
+
pl_paper_theme.layout.xaxis.tickfont.size = 36
|
|
39
|
+
pl_paper_theme.layout.yaxis.title.standoff = 24
|
|
40
|
+
pl_paper_theme.layout.yaxis.title.font.size = 28
|
|
41
|
+
#pl_paper_theme.layout.coloraxis.colorbar.title.standoff = 20
|
|
42
|
+
pio.templates.default = pl_paper_theme
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def generate_transition_level_diagram(transition_levels, im_write=False, im_name='transition_levels.png'):
|
|
46
|
+
"""
|
|
47
|
+
Given a TransitionLevels object from pydefect, plots a charge transition level diagram
|
|
48
|
+
showing the Fermi energy levels and which charges for each defect calculated.
|
|
49
|
+
"""
|
|
50
|
+
# add capability to remove defects without transition levels or that are not of interest
|
|
51
|
+
# ex. transition_levels.transition_levels.pop(3)
|
|
52
|
+
defects_list = [defect.name for defect in transition_levels.transition_levels]
|
|
53
|
+
|
|
54
|
+
fig = go.Figure()
|
|
55
|
+
|
|
56
|
+
for i in range(len(defects_list)):
|
|
57
|
+
if len(transition_levels.transition_levels[i].fermi_levels) > 0:
|
|
58
|
+
for j in range(len(transition_levels.transition_levels[i].fermi_levels)):
|
|
59
|
+
defect_fermi_levels = transition_levels.transition_levels[i].fermi_levels
|
|
60
|
+
defect_fermi_levels.sort()
|
|
61
|
+
fig.add_trace(go.Scatter(x=[transition_levels.transition_levels[i].name for j in range(len(defect_fermi_levels))],
|
|
62
|
+
y=[defect_fermi_levels[j] for j in range(len(defect_fermi_levels))],
|
|
63
|
+
text=[f'{transition_levels.transition_levels[i].charges[j][0]:+}/{transition_levels.transition_levels[i].charges[j][1]:+}' for j in range(len(defect_fermi_levels))],
|
|
64
|
+
mode='markers+text',
|
|
65
|
+
marker=dict(symbol='line-ew-open',
|
|
66
|
+
size=28,
|
|
67
|
+
color=px.colors.qualitative.Plotly[i],
|
|
68
|
+
line=dict(width=6)
|
|
69
|
+
)
|
|
70
|
+
))
|
|
71
|
+
else:
|
|
72
|
+
fig.add_trace(go.Scatter(x=[transition_levels.transition_levels[i].name],
|
|
73
|
+
y=[0.],
|
|
74
|
+
marker=dict(size=0, opacity=0)
|
|
75
|
+
))
|
|
76
|
+
|
|
77
|
+
fig.update_traces(textposition='top center')
|
|
78
|
+
|
|
79
|
+
# VBM
|
|
80
|
+
fig.add_hline(y=transition_levels.supercell_vbm, line=dict(color='black', width=3, dash='dash'), annotation_text='VBM', annotation_position='bottom left')
|
|
81
|
+
fig.add_hrect(y0=transition_levels.supercell_vbm-0.2, y1=transition_levels.supercell_vbm, line_width=0, fillcolor='red', opacity=0.2)
|
|
82
|
+
|
|
83
|
+
# CBM
|
|
84
|
+
fig.add_hline(y=transition_levels.supercell_cbm, line=dict(color='black', width=3, dash='dash'), annotation_text='CBM', annotation_position='top left')
|
|
85
|
+
fig.add_hrect(y0=transition_levels.supercell_cbm, y1=transition_levels.supercell_cbm+0.2, line_width=0, fillcolor='blue', opacity=0.2)
|
|
86
|
+
|
|
87
|
+
fig.update_layout(xaxis_title=r'Defects',
|
|
88
|
+
yaxis_title=r'$\Huge{E_{F} \; [eV]}$',
|
|
89
|
+
xaxis_type='category',
|
|
90
|
+
yaxis_showticklabels=False,
|
|
91
|
+
showlegend=False,
|
|
92
|
+
margin=dict(l=20, r=20, t=20, b=20),
|
|
93
|
+
autosize=False, width = 850, height = 650
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
fig.show()
|
|
97
|
+
|
|
98
|
+
if im_write == True:
|
|
99
|
+
fig.write_image(im_name, scale=1)
|
|
100
|
+
elif im_write == False:
|
|
101
|
+
pass
|
|
102
|
+
|
|
103
|
+
return
|
|
104
|
+
|
|
File without changes
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
"""Core functions and classes for analyzing rad-induced defects from VASP."""
|
|
2
|
+
import logging
|
|
3
|
+
from typing import TYPE_CHECKING, Optional
|
|
4
|
+
import importlib.resources as ilr
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
import glob
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
import shutil
|
|
10
|
+
import json
|
|
11
|
+
from monty.serialization import dumpfn, loadfn
|
|
12
|
+
from monty.json import MSONable, MontyEncoder, MontyDecoder
|
|
13
|
+
|
|
14
|
+
import subprocess
|
|
15
|
+
import re
|
|
16
|
+
import pprint
|
|
17
|
+
|
|
18
|
+
import math as m
|
|
19
|
+
from fractions import Fraction
|
|
20
|
+
import random as rand
|
|
21
|
+
|
|
22
|
+
import numpy as np
|
|
23
|
+
import pandas as pd
|
|
24
|
+
import matplotlib as mpl
|
|
25
|
+
import matplotlib.pyplot as plt
|
|
26
|
+
|
|
27
|
+
from pymatgen.io.vasp.sets import VaspInputSet, Poscar
|
|
28
|
+
from pymatgen.io.vasp.outputs import Locpot, Outcar, Vasprun
|
|
29
|
+
from pymatgen.core import Structure, Lattice
|
|
30
|
+
from pymatgen.io.vasp.sets import MPRelaxSet
|
|
31
|
+
from pymatgen.symmetry.analyzer import *
|
|
32
|
+
from pymatgen.analysis.defects.core import DefectComplex, Substitution, Vacancy
|
|
33
|
+
from pymatgen.analysis.defects.finder import DefectSiteFinder
|
|
34
|
+
from mp_api.client import MPRester
|
|
35
|
+
|
|
36
|
+
from pydefect.analyzer.unitcell import Unitcell
|
|
37
|
+
from pydefect.analyzer.band_edge_states import BandEdgeOrbitalInfos, BandEdgeState, PerfectBandEdgeState
|
|
38
|
+
from pydefect.analyzer.calc_results import CalcResults
|
|
39
|
+
from pydefect.analyzer.defect_energy import DefectEnergyInfo
|
|
40
|
+
from pydefect.input_maker.defect_entry import DefectEntry
|
|
41
|
+
from pydefect.corrections.efnv_correction import ExtendedFnvCorrection
|
|
42
|
+
|
|
43
|
+
from doped.analysis import DefectParser, DefectsParser
|
|
44
|
+
|
|
45
|
+
# pydefect file structure
|
|
46
|
+
base_path = os.getcwd()
|
|
47
|
+
cpd_path, defects_path, unitcell_path, band_path, diele_path, dos_path, struc_opt_path = os.path.relpath('cpd'), os.path.relpath('defect'), os.path.relpath('unitcell'), os.path.relpath('unitcell/band'), os.path.relpath('unitcell/dielectric'), os.path.relpath('unitcell/dos'), os.path.relpath('unitcell/structure_opt')
|
|
48
|
+
pydefect_paths = [cpd_path, defects_path, unitcell_path, band_path, diele_path, dos_path, struc_opt_path]
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
# create pydefect file structure
|
|
52
|
+
def create_pydefect_file_structure():
|
|
53
|
+
os.makedirs([os.path.join(base_path, i) for i in pydefect_paths])
|
|
54
|
+
return
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
# maybe define class for defective supercells
|
|
58
|
+
# get defect and perfect supercells on definition
|
|
59
|
+
def get_mpid_from_supercell(perfect_poscar_path):
|
|
60
|
+
"""
|
|
61
|
+
Given a path for a perfect supercell POSCAR, determine the
|
|
62
|
+
characteristics of the unitcell and fetches from the
|
|
63
|
+
Materials Project.
|
|
64
|
+
"""
|
|
65
|
+
# read POSCAR files with pymatgen and determine unitcell from perfect supercell
|
|
66
|
+
perfect_pos = Poscar.from_file(perfect_poscar_path)
|
|
67
|
+
unitcell_strc = perfect_pos.structure.get_primitive_structure()
|
|
68
|
+
unitcell_spg = SpacegroupAnalyzer(unitcell_strc)
|
|
69
|
+
|
|
70
|
+
# query MPD to get material ID matching perfect supercell structure
|
|
71
|
+
# API key is parsed via .pmgrc.yaml
|
|
72
|
+
with MPRester() as mpr:
|
|
73
|
+
docs = mpr.materials.summary.search(
|
|
74
|
+
elements=map(str, unitcell_strc.elements),
|
|
75
|
+
num_elements=len(unitcell_strc.elements),
|
|
76
|
+
num_sites=len(unitcell_strc.sites),
|
|
77
|
+
spacegroup_symbol=unitcell_spg.get_space_group_symbol(),
|
|
78
|
+
fields=['material_id', 'composition', 'symmetry', 'band_gap', 'structure']
|
|
79
|
+
)
|
|
80
|
+
mpid_dict = {doc.material_id: [doc.composition, doc.symmetry, doc.band_gap, doc.structure] for doc in docs}
|
|
81
|
+
if len(mpid_dict.keys()) == 1:
|
|
82
|
+
unitcell_mpid = list(mpid_dict.keys())[0]
|
|
83
|
+
unitcell_info = {
|
|
84
|
+
'mpid': unitcell_mpid,
|
|
85
|
+
'composition': mpid_dict[unitcell_mpid][0],
|
|
86
|
+
'symmetry': mpid_dict[unitcell_mpid][1],
|
|
87
|
+
'band_gap': mpid_dict[unitcell_mpid][2],
|
|
88
|
+
'structure': mpid_dict[unitcell_mpid][3]
|
|
89
|
+
}
|
|
90
|
+
else:
|
|
91
|
+
raise UserWarning('Multiple matching structures were found.')
|
|
92
|
+
return unitcell_info
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
# band edge orbital infos gives fermi level, states below should be occupied and above should be unoccupied
|
|
96
|
+
# interested in occupation of states between VBM & CBM: gap states
|
|
97
|
+
def find_gap_states(pbes_path, beois_path):
|
|
98
|
+
"""
|
|
99
|
+
Given a path to the perfect band edge state and band edge orbital
|
|
100
|
+
info JSON files, determine VBM & CBM energies as well as orbital
|
|
101
|
+
energies and occupations from pydefect.
|
|
102
|
+
"""
|
|
103
|
+
pbes, beois = PerfectBandEdgeState.from_dict(json.load(open(pbes_path, 'r'))), BandEdgeOrbitalInfos.from_dict(json.load(open(beois_path, 'r')))
|
|
104
|
+
e_vbm, e_cbm = pbes.vbm_info.orbital_info.energy, pbes.cbm_info.orbital_info.energy
|
|
105
|
+
|
|
106
|
+
for s in range(len(beois.orbital_infos)): # spin up/down channels
|
|
107
|
+
for k in range(len(beois.orbital_infos[s])): # kpt idx
|
|
108
|
+
for b in range(len(beois.orbital_infos[s][k])): # band idx
|
|
109
|
+
beois_ens, beois_occs = beois.orbital_infos[s][k][b].energy, beois.orbital_infos[s][k][b].occupation
|
|
110
|
+
|
|
111
|
+
# maybe make a GapState class that incorporates the Orbital Infos plus the s/k/b for the given gap state
|
|
112
|
+
# gap state defined as energy between e_vbm and e_cbm
|
|
113
|
+
# gap state occupancy is of interest
|
|
114
|
+
# use gap state to determine charge localization?
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def get_plnr_avg_only(
|
|
118
|
+
defect_locpot: Locpot,
|
|
119
|
+
bulk_locpot: Locpot,
|
|
120
|
+
lattice: Optional[Lattice] = None
|
|
121
|
+
):
|
|
122
|
+
"""Calculates the planar average electrostatic potential.
|
|
123
|
+
Based on FNV correction function from pymatgen.analysis.defects.
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
defect_locpot:
|
|
127
|
+
Locpot of defect
|
|
128
|
+
bulk_locpot:
|
|
129
|
+
Locpot of bulk
|
|
130
|
+
lattice:
|
|
131
|
+
Lattice of the defect supercell. If None, then uses the lattice of the
|
|
132
|
+
defect_locpot.
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
Plotting data for the planar average electrostatic potential.
|
|
136
|
+
```
|
|
137
|
+
plot_plnr_avg(result.metadata[0], title="Lattice Direction 1")
|
|
138
|
+
plot_plnr_avg_only(plnr_avg_data['plot_data'][direction]['pot_plot_data'], ax=axs[direction], title=axis_label_dict[direction])
|
|
139
|
+
```
|
|
140
|
+
"""
|
|
141
|
+
|
|
142
|
+
if isinstance(defect_locpot, Locpot):
|
|
143
|
+
list_axis_grid = [*map(defect_locpot.get_axis_grid, [0, 1, 2])]
|
|
144
|
+
list_defect_plnr_avg_esp = [
|
|
145
|
+
*map(defect_locpot.get_average_along_axis, [0, 1, 2])
|
|
146
|
+
]
|
|
147
|
+
lattice_ = defect_locpot.structure.lattice.copy()
|
|
148
|
+
if lattice is not None and lattice != lattice_:
|
|
149
|
+
raise ValueError(
|
|
150
|
+
"Lattice of defect_locpot and user provided lattice do not match."
|
|
151
|
+
)
|
|
152
|
+
lattice = lattice_
|
|
153
|
+
elif isinstance(defect_locpot, dict):
|
|
154
|
+
defect_locpot_ = {int(k): v for k, v in defect_locpot.items()}
|
|
155
|
+
list_defect_plnr_avg_esp = [defect_locpot_[i] for i in range(3)]
|
|
156
|
+
list_axis_grid = [
|
|
157
|
+
*map(
|
|
158
|
+
np.linspace,
|
|
159
|
+
[0, 0, 0],
|
|
160
|
+
lattice.abc,
|
|
161
|
+
[len(i) for i in list_defect_plnr_avg_esp],
|
|
162
|
+
)
|
|
163
|
+
]
|
|
164
|
+
else:
|
|
165
|
+
raise ValueError("defect_locpot must be of type Locpot or dict")
|
|
166
|
+
|
|
167
|
+
# TODO this can be done with regridding later
|
|
168
|
+
if isinstance(bulk_locpot, Locpot):
|
|
169
|
+
list_bulk_plnr_avg_esp = [*map(bulk_locpot.get_average_along_axis, [0, 1, 2])]
|
|
170
|
+
elif isinstance(bulk_locpot, dict):
|
|
171
|
+
bulk_locpot_ = {int(k): v for k, v in bulk_locpot.items()}
|
|
172
|
+
list_bulk_plnr_avg_esp = [bulk_locpot_[i] for i in range(3)]
|
|
173
|
+
else:
|
|
174
|
+
raise ValueError("bulk_locpot must be of type Locpot or dict")
|
|
175
|
+
|
|
176
|
+
plot_data = dict()
|
|
177
|
+
|
|
178
|
+
for x, pureavg, defavg, axis in zip(
|
|
179
|
+
list_axis_grid, list_bulk_plnr_avg_esp, list_defect_plnr_avg_esp, [0, 1, 2]
|
|
180
|
+
):
|
|
181
|
+
# log plotting data:
|
|
182
|
+
metadata = dict()
|
|
183
|
+
metadata["pot_plot_data"] = {
|
|
184
|
+
"x": x,
|
|
185
|
+
"dft_diff": np.array(defavg) - np.array(pureavg)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
plot_data[axis] = metadata
|
|
189
|
+
|
|
190
|
+
corr_metadata = {"plot_data": plot_data}
|
|
191
|
+
|
|
192
|
+
return corr_metadata
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def plot_plnr_avg_only(plot_data, title=None, ax=None, style_file=None):
|
|
196
|
+
"""
|
|
197
|
+
Plots exclusively the planar-averaged electrostatic potential.
|
|
198
|
+
|
|
199
|
+
Original code templated from the original PyCDT and new
|
|
200
|
+
pymatgen.analysis.defects implementations as plot_FNV in doped.
|
|
201
|
+
Functionality for plotting only the planar-averaged electrostatic
|
|
202
|
+
potential is kept.
|
|
203
|
+
|
|
204
|
+
Args:
|
|
205
|
+
plot_data (dict):
|
|
206
|
+
Dictionary of Freysoldt correction metadata to plot
|
|
207
|
+
(i.e. defect_entry.corrections_metadata["plot_data"][axis] where
|
|
208
|
+
axis is one of [0, 1, 2] specifying which axis to plot along (a, b, c)).
|
|
209
|
+
title (str): Title for the plot. Default is no title.
|
|
210
|
+
ax (matplotlib.axes.Axes): Axes object to plot on. If None, makes new figure.
|
|
211
|
+
style_file (str):
|
|
212
|
+
Path to a mplstyle file to use for the plot. If None (default), uses
|
|
213
|
+
the default doped style (from doped/utils/doped.mplstyle).
|
|
214
|
+
"""
|
|
215
|
+
|
|
216
|
+
x = plot_data["x"]
|
|
217
|
+
dft_diff = plot_data["dft_diff"]
|
|
218
|
+
|
|
219
|
+
style_file = style_file or f"{ilr.files('doped')}/utils/doped.mplstyle"
|
|
220
|
+
plt.style.use(style_file) # enforce style, as style.context currently doesn't work with jupyter
|
|
221
|
+
with plt.style.context(style_file):
|
|
222
|
+
if ax is None:
|
|
223
|
+
plt.close("all") # close any previous figures
|
|
224
|
+
fig, ax = plt.subplots()
|
|
225
|
+
(line1,) = ax.plot(x, dft_diff, c="red", label=r"$\Delta$(Locpot)")
|
|
226
|
+
leg1 = ax.legend(handles=[line1], loc=9) # middle top legend
|
|
227
|
+
ax.add_artist(leg1) # so isn't overwritten with later legend call
|
|
228
|
+
|
|
229
|
+
ax.set_xlim(round(x[0]), round(x[-1]))
|
|
230
|
+
ymin = min(*dft_diff)
|
|
231
|
+
ymax = max(*dft_diff)
|
|
232
|
+
ax.set_ylim(-0.2 + ymin, 0.2 + ymax)
|
|
233
|
+
ax.set_xlabel(r"Distance along axis ($\AA$)")
|
|
234
|
+
ax.set_ylabel("Potential (V)")
|
|
235
|
+
ax.axhline(y=0, linewidth=0.2, color="black")
|
|
236
|
+
if title is not None:
|
|
237
|
+
ax.set_title(str(title))
|
|
238
|
+
ax.set_xlim(0, max(x))
|
|
239
|
+
|
|
240
|
+
return ax
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def plot_plnr_avg_abc(plot_data, title=None, ax=None, style_file=None):
|
|
244
|
+
axis_label_dict = {0: r"$a$-axis", 1: r"$b$-axis", 2: r"$c$-axis"}
|
|
245
|
+
fig, axs = plt.subplots(1, 3, sharey=True, figsize=(12, 3.5), dpi=600)
|
|
246
|
+
for direction in range(3):
|
|
247
|
+
plot_plnr_avg_only(
|
|
248
|
+
plot_data['plot_data'][direction]['pot_plot_data'],
|
|
249
|
+
ax=axs[direction],
|
|
250
|
+
title=axis_label_dict[direction]
|
|
251
|
+
)
|
|
252
|
+
return
|
|
253
|
+
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"""Analysis for sxdefectalign calculations using pydefect, doped, and radDefects tools."""
|
|
2
|
+
import logging
|
|
3
|
+
from typing import TYPE_CHECKING, Optional
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import glob
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
import json
|
|
9
|
+
from monty.serialization import dumpfn, loadfn
|
|
10
|
+
from monty.json import MSONable, MontyEncoder, MontyDecoder
|
|
11
|
+
|
|
12
|
+
import re
|
|
13
|
+
import pprint
|
|
14
|
+
|
|
15
|
+
import numpy as np
|
|
16
|
+
import pandas as pd
|
|
17
|
+
|
|
18
|
+
from pydefect.analyzer.unitcell import Unitcell
|
|
19
|
+
from pydefect.analyzer.band_edge_states import BandEdgeOrbitalInfos, BandEdgeState, PerfectBandEdgeState
|
|
20
|
+
from pydefect.analyzer.defect_energy import DefectEnergyInfo, ChargeEnergies, SingleChargeEnergies, CrossPoints
|
|
21
|
+
from pydefect.analyzer.transition_levels import TransitionLevels, make_transition_levels
|
|
22
|
+
|
|
23
|
+
from raddefects.sxda.io import parse_sxda_vatoms
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def sxda_transition_levels(base_path=os.getcwd(), chg_offset=0):
|
|
27
|
+
"""
|
|
28
|
+
Using sxdefectalign calculations within the pydefect structure, calculate
|
|
29
|
+
charge transition levels.
|
|
30
|
+
"""
|
|
31
|
+
# use unitcell.yaml and perfect_band_edge_state.json files to get CBM/VBM info
|
|
32
|
+
unitcell_yaml = os.path.join(base_path, 'unitcell', 'unitcell.yaml')
|
|
33
|
+
defect_path=os.path.join(base_path, 'defect')
|
|
34
|
+
perfect_band_edge_state_json = os.path.join(defect_path, 'perfect', 'perfect_band_edge_state.json')
|
|
35
|
+
uc_info, pbes = Unitcell.from_yaml(unitcell_yaml), loadfn(perfect_band_edge_state_json)
|
|
36
|
+
cbm, supercell_vbm, supercell_cbm = uc_info.cbm, pbes.vbm_info.energy, pbes.cbm_info.energy
|
|
37
|
+
cbm -= supercell_vbm
|
|
38
|
+
supercell_cbm -= supercell_vbm
|
|
39
|
+
supercell_vbm -= supercell_vbm
|
|
40
|
+
|
|
41
|
+
# gather pydefect defect directories
|
|
42
|
+
defect_paths = glob.glob(os.path.join(defect_path, '*_*/'), recursive=True)
|
|
43
|
+
|
|
44
|
+
# empty dictionaries for sxda charge energies and sxda cross points
|
|
45
|
+
sxda_single_charge_energies = {}
|
|
46
|
+
sxda_charge_energies = {}
|
|
47
|
+
sxda_cross_point_dicts = {}
|
|
48
|
+
|
|
49
|
+
for defect_dir in defect_paths:
|
|
50
|
+
# get defect type and charge from defect directory
|
|
51
|
+
defect = os.path.basename(os.path.dirname(defect_dir))
|
|
52
|
+
defect_type, defect_chg = '_'.join(defect.split('_')[0:2]), int(defect.split('_')[2])
|
|
53
|
+
|
|
54
|
+
# add defect type to single charge energies dictionary
|
|
55
|
+
if defect_type not in sxda_single_charge_energies:
|
|
56
|
+
sxda_single_charge_energies.update({defect_type: []})
|
|
57
|
+
|
|
58
|
+
# get defect.sxda filename
|
|
59
|
+
if 'FP' in defect_type:
|
|
60
|
+
if defect_chg > 0:
|
|
61
|
+
vac_chg, int_chg = chg_offset, defect_chg+chg_offset
|
|
62
|
+
elif defect_chg < 0:
|
|
63
|
+
vac_chg, int_chg = defect_chg-chg_offset, chg_offset
|
|
64
|
+
elif defect_chg == 0:
|
|
65
|
+
if float(chg_offset) == 0.:
|
|
66
|
+
vac_chg, int_chg = 0., 0.
|
|
67
|
+
else:
|
|
68
|
+
vac_chg, int_chg = -1*(chg_offset/2.), chg_offset/2.
|
|
69
|
+
else:
|
|
70
|
+
raise ValueError('Defect charge must be a valid number.')
|
|
71
|
+
|
|
72
|
+
sxda_outfile = os.path.join(defect_dir, f'{defect}_qv{vac_chg:.2f}qi{int_chg:.2f}.sxda')
|
|
73
|
+
else:
|
|
74
|
+
sxda_outfile = os.path.join(defect_dir, f'{defect}.sxda')
|
|
75
|
+
|
|
76
|
+
# compare first line of defect.sxda with defect type and charge
|
|
77
|
+
with open(sxda_outfile) as f:
|
|
78
|
+
sxda_lines = f.readlines()
|
|
79
|
+
title_line, correction_line = sxda_lines[0].strip('\n'), sxda_lines[-1]
|
|
80
|
+
|
|
81
|
+
# check if defect type is correct
|
|
82
|
+
sxda_defect_type, sxda_defect_chg = title_line.split(',')[0], int(title_line.split(',')[1].split(' = ')[1])
|
|
83
|
+
if (sxda_defect_type != defect_type) or (sxda_defect_chg != defect_chg):
|
|
84
|
+
raise ValueError('Defect type/charge does not match between pydefect and sxdefectalign')
|
|
85
|
+
|
|
86
|
+
# ensure correction line contains the correction and extract correction value
|
|
87
|
+
if 'correction' in correction_line:
|
|
88
|
+
sxda_corr = float(re.findall(r'\d[.,]?\d*', correction_line)[0])
|
|
89
|
+
else:
|
|
90
|
+
continue
|
|
91
|
+
|
|
92
|
+
bes = loadfn(os.path.join(defect_dir, 'band_edge_orbital_infos.json'))
|
|
93
|
+
fermi_level = bes.fermi_level - supercell_vbm
|
|
94
|
+
|
|
95
|
+
dei = DefectEnergyInfo.from_yaml(os.path.join(defect_dir, 'defect_energy_info.yaml'))
|
|
96
|
+
formation_en = dei.defect_energy.energy(with_correction=False)
|
|
97
|
+
formation_en_sxda = formation_en + sxda_corr
|
|
98
|
+
|
|
99
|
+
# add charge and formation energies to single charge energies dictionary
|
|
100
|
+
sxda_single_charge_energies[defect_type] += [(int(defect_chg), formation_en_sxda)]
|
|
101
|
+
|
|
102
|
+
for d_type in sxda_single_charge_energies:
|
|
103
|
+
sxda_charge_energies.update({d_type: SingleChargeEnergies(sxda_single_charge_energies[d_type])})
|
|
104
|
+
sxda_energies = ChargeEnergies(sxda_charge_energies, e_min=0., e_max=cbm)
|
|
105
|
+
|
|
106
|
+
sxda_cross_point_dicts = sxda_energies.cross_point_dicts
|
|
107
|
+
|
|
108
|
+
# create TransitionLevels object
|
|
109
|
+
sxda_tls = make_transition_levels(
|
|
110
|
+
cross_point_dicts=sxda_cross_point_dicts,
|
|
111
|
+
cbm=cbm,
|
|
112
|
+
supercell_vbm=supercell_vbm,
|
|
113
|
+
supercell_cbm=supercell_cbm
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
return sxda_tls
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def atomic_potential_convergence(base_path=os.getcwd()):
|
|
120
|
+
"""
|
|
121
|
+
Calculates the convergence for atomic site potential data from sxdefectalign
|
|
122
|
+
calculations in terms of averages and standard deviations within the sampling
|
|
123
|
+
region.
|
|
124
|
+
"""
|
|
125
|
+
# defect directory
|
|
126
|
+
defect_path=os.path.join(base_path, 'defect')
|
|
127
|
+
|
|
128
|
+
# gather pydefect defect directories
|
|
129
|
+
defect_paths = glob.glob(os.path.join(defect_path, '*_*/'), recursive=True)
|
|
130
|
+
|
|
131
|
+
# empty dictionary for alignment averages and standard deviations
|
|
132
|
+
alignment_dict = {}
|
|
133
|
+
|
|
134
|
+
for defect_dir in defect_paths:
|
|
135
|
+
# get defect type and charge from defect directory
|
|
136
|
+
defect = os.path.basename(os.path.dirname(defect_dir))
|
|
137
|
+
defect_type, defect_chg = '_'.join(defect.split('_')[0:2]), int(defect.split('_')[2])
|
|
138
|
+
|
|
139
|
+
# use parse_sxda_vatoms on directory
|
|
140
|
+
vatoms = parse_sxda_vatoms(defect_dir)
|
|
141
|
+
|
|
142
|
+
# use lattice parameters for defect region radius or use pydefect correction.json file
|
|
143
|
+
if os.path.isfile(os.path.join(defect_dir, 'correction.json')):
|
|
144
|
+
correction_json = loadfn(os.path.join(defect_dir, 'correction.json'))
|
|
145
|
+
defect_region_radius = correction_json.defect_region_radius
|
|
146
|
+
else:
|
|
147
|
+
contcar_filepath = os.path.join(filepath, 'CONTCAR')
|
|
148
|
+
contcar = Poscar.from_file(contcar_filepath)
|
|
149
|
+
abc = np.array(contcar.structure.lattice.abc)
|
|
150
|
+
abc /= 2.
|
|
151
|
+
defect_region_radius = np.min(abc)
|
|
152
|
+
|
|
153
|
+
# alignment stats (mean, stdev) from atomic site potential dataframe with r>defect_region_radius
|
|
154
|
+
vatoms_total = pd.concat((vatoms[i] for i in vatoms.keys()))
|
|
155
|
+
vatoms_sample_region = vatoms_total.where(vatoms_total['r']>defect_region_radius)
|
|
156
|
+
alignment_average = vatoms_sample_region.loc[:, 'V_defect-V_ref-V_lr'].mean(skipna=True)
|
|
157
|
+
alignment_stdev = vatoms_sample_region.loc[:, 'V_defect-V_ref-V_lr'].std(skipna=True)
|
|
158
|
+
|
|
159
|
+
alignment_dict.update({defect: (alignment_average, alignment_stdev)})
|
|
160
|
+
|
|
161
|
+
return alignment_dict
|
|
162
|
+
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"""Parsing I/O for sxdefectalign calculations."""
|
|
2
|
+
import logging
|
|
3
|
+
from typing import TYPE_CHECKING, Optional
|
|
4
|
+
from io import StringIO
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
import glob
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
import json
|
|
10
|
+
from monty.serialization import dumpfn, loadfn
|
|
11
|
+
from monty.json import MSONable, MontyEncoder, MontyDecoder
|
|
12
|
+
|
|
13
|
+
import re
|
|
14
|
+
import pprint
|
|
15
|
+
|
|
16
|
+
import numpy as np
|
|
17
|
+
import pandas as pd
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def parse_sxda_vatoms(filepath=os.getcwd()):
|
|
21
|
+
"""
|
|
22
|
+
Parses sxdefectalign vAtoms.dat files.
|
|
23
|
+
|
|
24
|
+
potential terms sxdefectalign = pydefect
|
|
25
|
+
V(long-range) = V_{PC,q}
|
|
26
|
+
V(defect)-V(ref) = V_{q/b}
|
|
27
|
+
V(defect)-V(ref)-V(long-range) = dV_{PC,q/b}
|
|
28
|
+
|
|
29
|
+
vAtoms.dat format
|
|
30
|
+
r V(long-range) V(defect)-V(ref) V(defect)-V(ref)-V(long-range) x y z ...
|
|
31
|
+
empty lines between different species (need to include in plotting now)
|
|
32
|
+
with auto_sxda, empty lines are replaced with double empty lines to enable gnuplot index use
|
|
33
|
+
"""
|
|
34
|
+
vatoms_filepath, contcar_filepath = os.path.join(filepath, 'vAtoms.dat'), os.path.join(filepath, 'CONTCAR')
|
|
35
|
+
contcar = Poscar.from_file(contcar_filepath)
|
|
36
|
+
|
|
37
|
+
vatoms_dict = {i.symbol:'' for i in contcar.structure.elements}
|
|
38
|
+
|
|
39
|
+
with open(vatoms_filepath, 'r') as va_dat:
|
|
40
|
+
va_dat_text = va_dat.read()
|
|
41
|
+
|
|
42
|
+
# find double line breaks in vatoms data file string
|
|
43
|
+
idx_split = [0]
|
|
44
|
+
idx_split += re.search(r'\n\n\n', va_dat_text).span()
|
|
45
|
+
idx_split.append(len(va_dat_text))
|
|
46
|
+
|
|
47
|
+
# create dataframes for each element's atomic site potentials
|
|
48
|
+
for i in range(int(len(idx_split)/2)):
|
|
49
|
+
atomic_site_type = contcar.structure.elements[i].symbol
|
|
50
|
+
vatoms_str = StringIO(va_dat_text[idx_split[2*i]:idx_split[2*i+1]].strip())
|
|
51
|
+
vatoms_arr = np.genfromtxt(vatoms_str)
|
|
52
|
+
vatoms_df = pd.DataFrame(
|
|
53
|
+
data=vatoms_arr,
|
|
54
|
+
columns=['r', 'V_lr', 'V_defect-V_ref', 'V_defect-V_ref-V_lr', 'x', 'y', 'z']
|
|
55
|
+
)
|
|
56
|
+
vatoms_dict.update({atomic_site_type:vatoms_df})
|
|
57
|
+
|
|
58
|
+
return vatoms_dict
|
|
59
|
+
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: raddefects
|
|
3
|
+
Version: 0.1.3
|
|
4
|
+
Summary: Framework to analyze properties of radiation-induced defects in semiconductor materials from first principles.
|
|
5
|
+
Author-email: Alexander Hauck <ash5615@psu.edu>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2024 Alexander Hauck
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Project-URL: Homepage, https://radDefects.readthedocs.io/en/latest/
|
|
29
|
+
Project-URL: Repository, https://github.com/hauck-as/radDefects
|
|
30
|
+
Classifier: Programming Language :: Python :: 3
|
|
31
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
32
|
+
Classifier: Operating System :: OS Independent
|
|
33
|
+
Requires-Python: >=3.6
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
License-File: LICENSE
|
|
36
|
+
Requires-Dist: requests
|
|
37
|
+
Requires-Dist: importlib-metadata; python_version < "3.12"
|
|
38
|
+
Requires-Dist: numpy
|
|
39
|
+
Requires-Dist: pymatgen
|
|
40
|
+
Requires-Dist: mp-api
|
|
41
|
+
Requires-Dist: vise
|
|
42
|
+
Requires-Dist: pydefect
|
|
43
|
+
Requires-Dist: sumo
|
|
44
|
+
Requires-Dist: pymatgen-analysis-defects
|
|
45
|
+
Requires-Dist: niet
|
|
46
|
+
|
|
47
|
+
# radDefects
|
|
48
|
+
Framework to analyze properties of radiation-induced defects in semiconductor materials from first principles.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
docs/conf.py
|
|
5
|
+
raddefects/__init__.py
|
|
6
|
+
raddefects/core.py
|
|
7
|
+
raddefects.egg-info/PKG-INFO
|
|
8
|
+
raddefects.egg-info/SOURCES.txt
|
|
9
|
+
raddefects.egg-info/dependency_links.txt
|
|
10
|
+
raddefects.egg-info/entry_points.txt
|
|
11
|
+
raddefects.egg-info/requires.txt
|
|
12
|
+
raddefects.egg-info/top_level.txt
|
|
13
|
+
raddefects/analysis/transition_levels.py
|
|
14
|
+
raddefects/cli/__init__.py
|
|
15
|
+
raddefects/cli/main.py
|
|
16
|
+
raddefects/sxda/analysis.py
|
|
17
|
+
raddefects/sxda/io.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|