diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index 1f20498..f0a2973 100755
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -37,7 +37,7 @@ jobs:
- name: ruff
run: |
ruff --version
- ruff --fix shakenbreak
+ ruff check --fix shakenbreak
- name: check docstrings
run: |
@@ -53,4 +53,4 @@ jobs:
- name: flake8
run: |
flake8 --version
- flake8 --max-line-length 107 --color always --ignore=E121,E123,E126,E203,E226,E24,E704,W503,W504,F401,E203 shakenbreak
\ No newline at end of file
+ flake8 --max-line-length 107 --color always --ignore=E121,E123,E126,E203,E226,E24,E704,W503,W504,F401,E203 shakenbreak
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 0f5d629..90eeb66 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,6 +1,11 @@
Change Log
==========
+v3.3.6
+----------
+- Add `py.typed` to properly detect type hints by @Andrew-S-Rosen
+- `snb-run` updates to improve efficiency
+
v3.3.5
----------
- Enforce ``doped>=2.4.4`` requirement.
diff --git a/README.md b/README.md
index 079ec42..db69515 100644
--- a/README.md
+++ b/README.md
@@ -102,7 +102,7 @@ pip install --upgrade pymatgen shakenbreak
`ShakeNBreak` can take `pymatgen` `Defect` objects as input (to then generate the trial distorted structures),
**_but also_** can take in `pymatgen` `Structure` objects, `doped` defects or structure files
(e.g. `POSCAR`s for `VASP`) as inputs. As such, it should be compatible with any defect code
-(such as [`doped`](https://doped.readthedocs.io/en/latest/index.html), [`pydefect`](https://github.com/kumagai-group/pydefect),
+(such as [`doped`](https://doped.readthedocs.io), [`pydefect`](https://github.com/kumagai-group/pydefect),
[`PyCDT`](https://github.com/mbkumar/pycdt), [`PyLada`](https://github.com/pylada/pylada-defects),
[`DASP`](http://hzwtech.com/files/software/DASP/htmlEnglish/index.html), [`Spinney`](https://gitlab.com/Marrigoni/spinney/-/tree/master),
[`DefAP`](https://github.com/DefAP/defap), [`PyDEF`](https://github.com/PyDEF2/PyDEF-2.0)...) that generates these files.
@@ -128,10 +128,15 @@ Automatic testing is run on the master and develop branches using Github Actions
## Studies using `ShakeNBreak`
+- Z. Yuan & G. Hautier **_First-principles study of defects and doping limits in CaO_** [_Applied Physics Letters_](https://doi.org/10.1063/5.0211707) 2024
- B. E. Murdock et al. **_Li-Site Defects Induce Formation of Li-Rich Impurity Phases: Implications for Charge Distribution and Performance of LiNi0.5-xMxMn1.5O4 Cathodes (M = Fe and Mg; x = 0.05–0.2)_** [_Advanced Materials_](https://doi.org/10.1002/adma.202400343) 2024
-- A. G. Squires et al. **_Oxygen dimerization as a defect-driven process in bulk LiNiO22_** [_ChemRxiv_](https://doi.org/10.26434/chemrxiv-2024-lcmkj) 2024
+- Y. Fu & H. Lohan et al. **_Factors Enabling Delocalized Charge-Carriers in Pnictogen-Based
+Solar Absorbers: In-depth Investigation into CuSbSe2_** [_arXiv_](https://doi.org/10.48550/arXiv.2401.02257) 2024
+- S. Hachmioune et al. **_Exploring the Thermoelectric Potential of MgB4: Electronic Band Structure, Transport Properties, and Defect Chemistry_** [_Chemistry of Materials_](https://doi.org/10.1021/acs.chemmater.4c00584) 2024
+- J. Hu et al. **_Enabling ionic transport in Li3AlP2 the roles of defects and disorder_** [_ChemRxiv_](https://doi.org/10.26434/chemrxiv-2024-3s0kh) 2024
+- A. G. Squires et al. **_Oxygen dimerization as a defect-driven process in bulk LiNiO22_** [_ACS Energy Letters_](https://pubs.acs.org/doi/10.1021/acsenergylett.4c01307) 2024
- X. Wang et al. **_Upper efficiency limit of Sb2Se3 solar cells_** [_Joule_](https://doi.org/10.1016/j.joule.2024.05.004) 2024
-- I. Mosquera-Lois et al. **_Machine-learning structural reconstructions for accelerated point defect calculations_** [_arXiv_](https://doi.org/10.48550/arXiv.2401.12127) 2024
+- I. Mosquera-Lois et al. **_Machine-learning structural reconstructions for accelerated point defect calculations_** [_npj Computational Materials_](https://doi.org/10.1038/s41524-024-01303-9) 2024
- S. R. Kavanagh et al. **_doped: Python toolkit for robust and repeatable charged defect supercell calculations_** [_Journal of Open Source Software_](https://doi.org/10.21105/joss.06433) 2024
- K. Li et al. **_Computational Prediction of an Antimony-based n-type Transparent Conducting Oxide: F-doped Sb2O5_** [_Chemistry of Materials_](https://doi.org/10.1021/acs.chemmater.3c03257) 2024
- X. Wang et al. **_Four-electron negative-U vacancy defects in antimony selenide_** [_Physical Review B_](https://journals.aps.org/prb/abstract/10.1103/PhysRevB.108.134102) 2023
diff --git a/docs/Analysis.rst b/docs/Analysis.rst
index 7af8d52..3bcdd04 100644
--- a/docs/Analysis.rst
+++ b/docs/Analysis.rst
@@ -248,11 +248,11 @@ Further Defect Analysis
-------------------------
Once the ground state (and metastable) defect structures have been identified, we will want to compute
their formation energies using our final fully-converged calculation parameters (i.e. plane-wave cutoff
-and k-point sampling). This can be done using `doped `_,
+and k-point sampling). This can be done using `doped `_,
manually (not recommended) or using the other defect codes listed on the
`Code Compatibility `_ page.
-As shown in the `doped `_ tutorials and docs, you may
+As shown in the `doped `_ tutorials and docs, you may
want to further analyse the behaviour and impact on material properties of your defects using advanced
defect analysis codes such as `easyunfold `_ (to analyse the
electronic structure of defects in your material),
diff --git a/docs/Code_Compatibility.rst b/docs/Code_Compatibility.rst
index 9f74fc5..18e9dd2 100644
--- a/docs/Code_Compatibility.rst
+++ b/docs/Code_Compatibility.rst
@@ -14,7 +14,7 @@ most recent version of :code:`pymatgen`. If you are receiving :code:`pymatgen`-r
:code:`ShakeNBreak` can take :code:`pymatgen` :code:`DefectEntry` objects as input (to then generate the trial distorted
structures), **but also** can take in :code:`pymatgen` :code:`Structure` objects, :code:`doped` defect dictionaries or
structure files (e.g. :code:`POSCAR`\s for :code:`VASP`) as inputs. As such, it should be compatible with any defect code
-(such as `doped `_, `pydefect `_,
+(such as `doped `_, `pydefect `_,
`PyCDT `_, `PyLada `_,
`DASP `_, `Spinney `_,
`DefAP `_, `PyDEF `_...) that generates these files.
diff --git a/docs/ShakeNBreak_Example_Workflow.ipynb b/docs/ShakeNBreak_Example_Workflow.ipynb
index a61a15b..517a8ed 100644
--- a/docs/ShakeNBreak_Example_Workflow.ipynb
+++ b/docs/ShakeNBreak_Example_Workflow.ipynb
@@ -130,7 +130,7 @@
"id": "9a98b5d2-c17f-4d00-8a0f-b5dfe8997420",
"metadata": {},
"source": [
- "## 1. Generate defects with [`doped`](https://doped.readthedocs.io/en/latest/)/`pymatgen`"
+ "## 1. Generate defects with [`doped`](https://doped.readthedocs.io)/`pymatgen`"
]
},
{
@@ -139,9 +139,9 @@
"metadata": {},
"source": [
"The input defect objects for `ShakeNBreak` can be generated using either\n",
- "[`doped`](https://doped.readthedocs.io/en/latest/), `pymatgen` or alternatively just\n",
+ "[`doped`](https://doped.readthedocs.io), `pymatgen` or alternatively just\n",
" the bulk and defect structures can be provided. Below we show how to generate the defect `python`\n",
- " objects using [`doped`](https://doped.readthedocs.io/en/latest/) (Section\n",
+ " objects using [`doped`](https://doped.readthedocs.io) (Section\n",
" 1.1) and `pymatgen` (Section 1.1).\n",
"\n",
"In this case we take CdTe as our example system:"
@@ -163,7 +163,7 @@
"metadata": {},
"source": [
"To generate defects with doped, we can use the code below. This procedure is described in much more\n",
- "detail on the [`doped` docs](https://doped.readthedocs.io/en/latest/), which also shows how to generate\n",
+ "detail on the [`doped` docs](https://doped.readthedocs.io), which also shows how to generate\n",
"and calculate the chemical potential terms (needed for defect formation energies), perform defect\n",
"supercell (finite-size) charge\n",
" corrections, calculate & plot the final defect formation energy diagram, and perform further defect\n",
@@ -960,7 +960,7 @@
" folder names will be set equal to `DefectEntry.name` if the `name`\n",
" attribute is set for all input `DefectEntry`s, otherwise generated\n",
" according to the `doped` convention\n",
- " (see: https://doped.readthedocs.io/en/latest/dope_workflow_example.html).\n",
+ " (see: https://doped.readthedocs.io/en/latest/generation_tutorial.html).\n",
"\n",
" Defect charge states (from which bond distortions are determined) are\n",
" taken from the `DefectEntry.charge_state` property.\n",
@@ -3946,9 +3946,9 @@
"metadata": {},
"source": [
"### Further Defect Analysis\n",
- "Once the ground state (and metastable) defect structures have been identified, we will want to compute their formation energies using our final fully-converged calculation parameters (i.e. plane-wave cutoff and k-point sampling). This can be done using [`doped`](https://doped.readthedocs.io/en/latest/), manually (not recommended) or using the other defect codes listed on the [Code Compatibility](https://shakenbreak.readthedocs.io/en/latest/Code_Compatibility.html) page.\n",
+ "Once the ground state (and metastable) defect structures have been identified, we will want to compute their formation energies using our final fully-converged calculation parameters (i.e. plane-wave cutoff and k-point sampling). This can be done using [`doped`](https://doped.readthedocs.io), manually (not recommended) or using the other defect codes listed on the [Code Compatibility](https://shakenbreak.readthedocs.io/en/latest/Code_Compatibility.html) page.\n",
"\n",
- "As shown in the [`doped`](https://doped.readthedocs.io/en/latest/) examples and docs, you may want to further analyse the behaviour and impact on material properties of your defects using advanced defect analysis codes such as [`easyunfold`](https://smtg-bham.github.io/easyunfold/) (to analyse the electronic structure of defects in your material), [`py-sc-fermi`](https://py-sc-fermi.readthedocs.io/en/latest/) (to analyse defect concentrations, doping and Fermi level tuning), or [`nonrad`](https://nonrad.readthedocs.io/en/latest/)/[`CarrierCapture.jl`](https://wmd-group.github.io/CarrierCapture.jl/dev/) (to analyse non-radiative electron-hole recombination at defects)."
+ "As shown in the [`doped`](https://doped.readthedocs.io) examples and docs, you may want to further analyse the behaviour and impact on material properties of your defects using advanced defect analysis codes such as [`easyunfold`](https://smtg-bham.github.io/easyunfold/) (to analyse the electronic structure of defects in your material), [`py-sc-fermi`](https://py-sc-fermi.readthedocs.io/en/latest/) (to analyse defect concentrations, doping and Fermi level tuning), or [`nonrad`](https://nonrad.readthedocs.io/en/latest/)/[`CarrierCapture.jl`](https://wmd-group.github.io/CarrierCapture.jl/dev/) (to analyse non-radiative electron-hole recombination at defects)."
]
},
{
diff --git a/docs/Tips.rst b/docs/Tips.rst
index 9073038..5062744 100644
--- a/docs/Tips.rst
+++ b/docs/Tips.rst
@@ -220,7 +220,7 @@ message about the origin of the problem, it is likely to be an issue with your v
If this does not solve your issue, please check the specific cases noted below. If your issue still isn't
solved, then please contact the developers through the ``GitHub``
-`Issues `_ page, or by email.
+`Issues `_ page.
- A current known issue with ``numpy``/``pymatgen`` is that it might give an error similar to this:
diff --git a/docs/conf.py b/docs/conf.py
index 09c1dbc..1057987 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -25,7 +25,7 @@
author = 'Irea Mosquera-Lois, Seán R. Kavanagh'
# The full version, including alpha/beta/rc tags
-release = '3.3.5'
+release = '3.3.6'
# -- General configuration ---------------------------------------------------
diff --git a/docs/index.rst b/docs/index.rst
index 1cd2301..a318a60 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -171,7 +171,7 @@ Code Compatibility
:code:`ShakeNBreak` can take :code:`pymatgen` :code:`Defect` objects as input (to then generate the trial distorted
structures), **but also** can take in :code:`pymatgen` :code:`Structure` objects, :code:`doped` defect dictionaries or
structure files (e.g. :code:`POSCAR`\s for :code:`VASP`) as inputs. As such, it should be compatible with any defect code
-(such as `doped `_, `pydefect `_,
+(such as `doped `_, `pydefect `_,
`PyCDT `_, `PyLada `_,
`DASP `_, `Spinney `_,
`DefAP `_, `PyDEF `_...) that generates these files.
@@ -211,10 +211,14 @@ run tests and add new tests for any new features whenever submitting pull reques
Studies using ``ShakeNBreak``
=============================
+- Z\. Yuan & G. Hautier **First-principles study of defects and doping limits in CaO** `Applied Physics Letters `_ 2024
- B\. E. Murdock et al. **Li-Site Defects Induce Formation of Li-Rich Impurity Phases: Implications for Charge Distribution and Performance of LiNi** :sub:`0.5-x` **M** :sub:`x` **Mn** :sub:`1.5` **O** :sub:`4` **Cathodes (M = Fe and Mg; x = 0.05–0.2)** `Advanced Materials `_ 2024
-- A\. G. Squires et al. **Oxygen dimerization as a defect-driven process in bulk LiNiO₂** `ChemRxiv `_ 2024
+- A\. G. Squires et al. **Oxygen dimerization as a defect-driven process in bulk LiNiO₂** `ACS Energy Letters `__ 2024
+- Y\. Fu & H. Lohan et al. **Factors Enabling Delocalized Charge-Carriers in Pnictogen-Based Solar Absorbers: In-depth Investigation into CuSbSe2** `arXiv `_ 2024
+- S\. Hachmioune et al. **Exploring the Thermoelectric Potential of MgB4: Electronic Band Structure, Transport Properties, and Defect Chemistry** `Chemistry of Materials `_ 2024
+- J\. Hu et al. **Enabling ionic transport in Li3AlP2 the roles of defects and disorder** `ChemRxiv `_ 2024
- X\. Wang et al. **Upper efficiency limit of Sb₂Se₃ solar cells** `Joule `_ 2024
-- I\. Mosquera-Lois et al. **Machine-learning structural reconstructions for accelerated point defect calculations** `arXiv `_ 2024
+- I\. Mosquera-Lois et al. **Machine-learning structural reconstructions for accelerated point defect calculations** `npj Computational Materials `_ 2024
- S\. R. Kavanagh et al. **doped: Python toolkit for robust and repeatable charged defect supercell calculations** `Journal of Open Source Software `_ 2024
- K\. Li et al. **Computational Prediction of an Antimony-based n-type Transparent Conducting Oxide: F-doped Sb₂O₅** `Chemistry of Materials `_ 2024
- X\. Wang et al. **Four-electron negative-U vacancy defects in antimony selenide** `Physical Review B `_ 2023
diff --git a/setup.py b/setup.py
index 16807d9..3e0ba5a 100644
--- a/setup.py
+++ b/setup.py
@@ -131,7 +131,7 @@ def package_files(directory):
setup(
name="shakenbreak",
- version="3.3.5",
+ version="3.3.6",
description="Package to generate and analyse distorted defect structures, in order to "
"identify ground-state and metastable defect configurations.",
long_description=long_description,
diff --git a/shakenbreak/SnB_run.sh b/shakenbreak/SnB_run.sh
index 64eb165..eecb0ad 100755
--- a/shakenbreak/SnB_run.sh
+++ b/shakenbreak/SnB_run.sh
@@ -41,7 +41,7 @@ check_multiple_single_step_outcars() {
counter=0
# Iterate over all OUTCAR*on* files in the current directory
- for file in OUTCAR*on*
+ for file in OUTCAR*
do
# Check if file is a regular file
if [[ -f $file ]]; then
@@ -85,16 +85,23 @@ SnB_run_loop() {
if [[ "$i" == *"_High_Energy"* ]]; then
continue
fi
- if [ ! -f "${i}"/OUTCAR ] || ( ! grep -q "required accuracy" "${i}"/OUTCAR && ! grep -q "considering this converged" "${i}"/OUTCAR ); then # check calculation not converged
+ if [ ! -f "${i}"/OUTCAR ] || { ! grep -q "required accuracy" "${i}"/OUTCAR && ! grep -q "considering this converged" "${i}"/OUTCAR; }; then # check calculation not converged
builtin cd "$i" || return
if [ ! -f "${job_filepath}" ] && [ ! "$job_in_cwd" = false ]; then
"cp" ../"${job_filepath}" "./${job_filename}" 2>/dev/null || "cp" ../../"${job_filepath}" "./${job_filename}" 2>/dev/null || return
fi
+ if [ -f "../Unperturbed/OUTCAR" ] && (($(grep -c entropy= ../Unperturbed/OUTCAR) > 0)); then
+ unperturbed_energy=$(grep entropy= ../Unperturbed/OUTCAR | awk '{print $NF}' | tail -1)
+ else
+ unperturbed_energy=-10000
+ fi
if [ -f OUTCAR ]; then # if OUTCAR exists so rerunning rather than 1st run
# count number of ionic steps with positive energies, after the first 5 ionic steps
- pos_energies=$(grep entropy= OUTCAR | awk 'FNR>5 && $NF !~ /^-/{print $0}' | wc -l)
+ pos_energies=$(grep "entropy=" OUTCAR | awk 'FNR>5 && $NF !~ /^-/' | grep -cE '[-+]?[0-9]*\.?[0-9]+$') # second grep ensures only lines that end in numbers are matched
errors=$(grep -Ec "(EDDDAV|ZHEGV|CNORMN|ZPOTRF|ZTRTRI|FEXC)" OUTCAR)
- if ((pos_energies > 0)) || ((errors > 0)); then # if there are positive energies or errors in OUTCAR
+ last_energy=$(grep entropy= OUTCAR | awk '{print $NF}' | tail -1)
+ energy_diff_to_unperturbed=$(echo "$last_energy - $unperturbed_energy" | bc)
+ if ((errors > 0)) || { ((pos_energies > 0)) && { (($(echo "$energy_diff_to_unperturbed > 1" | bc -l))) || [[ "$i" == *"Unperturbed"* ]]; }; }; then # if there are positive energies or errors in OUTCAR, and at least 1 eV higher than Unperturbed
if [[ "$i" == *"Unperturbed"* ]]; then
# positive energies / errors for Unperturbed structure, indicates pathological defect structure
echo "Positive energies or forces error encountered for ${i%/}. "
@@ -142,7 +149,7 @@ SnB_run_loop() {
fi
# check if multiple <=single-step OUTCARs present, and CONTCAR empty/less than 9 lines or same as POSCAR
- if check_multiple_single_step_outcars && { ( [[ -f "CONTCAR" ]] && [[ $(wc -l < "CONTCAR") -le 9 ]] ) || ( [[ -f "CONTCAR" ]] && diff -q "POSCAR" "CONTCAR" >/dev/null ) || [[ ! -f "CONTCAR" ]]; }; then
+ if check_multiple_single_step_outcars && { [[ ! -f "CONTCAR" ]] || { [[ -f "CONTCAR" ]] && { [[ $(wc -l < "CONTCAR") -le 9 ]] || diff -q "POSCAR" "CONTCAR" >/dev/null; }; }; }; then
echo "Previous run for ${i%?} did not yield more than one ionic step, and multiple OUTCARs with <=1 ionic "
echo "steps present, suggesting poor convergence. Recommended to manually check the VASP output files for this!"
fi
@@ -152,18 +159,12 @@ SnB_run_loop() {
# echo "More than 2 OUTCARs present for ${i%?}, suggesting tricky relaxation. "
#sed -i.bak 's/IBRION.*/IBRION = 1/g' INCAR && rm -f INCAR.bak # sometimes helps to change IBRION if relaxation taking long
# Check total number of ionic steps in all OUTCARs
- num_ionic_steps=$(grep entropy= OUTCAR* | wc -l)
+ num_ionic_steps=$(grep entropy= OUTCAR* | wc -l) # use wc -l rather than grep -c because multiple files
if [ -f ../Unperturbed/OUTCAR ]; then # only compare if Unperturbed folder present
# If equal or higher than 150, compare to final energy in Unperturbed OUTCAR
if ((num_ionic_steps >= 150)); then
- # Get final energy from Unperturbed OUTCAR
- final_energy=$(grep entropy= ../Unperturbed/OUTCAR | awk '{print $NF}' | tail -1)
- # Get final energy from last OUTCAR
- last_energy=$(grep entropy= OUTCAR | awk '{print $NF}' | tail -1)
- # Calculate difference between final energies
- energy_diff=$(echo "$final_energy - $last_energy" | bc)
- # If difference is higher than 2 eV, rename to _High_Energy and continue
- if (($(echo "${energy_diff#-} > 2" | bc -l))); then
+ # If energy difference to Unperturbed is higher than 2 eV, rename to _High_Energy and continue
+ if (($(echo "$energy_diff_to_unperturbed > 1" | bc -l))); then
echo "More than 150 ionic steps present for ${i%?}. The energy difference to last structure in Unperturbed relaxation"
echo "is higher than 2 eV, indicating that ${i%?} is stuck in a high energy basin. "
echo "Renaming to ${i%?}_High_Energy and continuing."
@@ -192,9 +193,9 @@ SnB_run_loop() {
# save_vasp_files:
current_time=$(date +%H_%M_%Son%d_%m_%y)
for vasp_file in {CONTCAR,OUTCAR,XDATCAR,POSCAR,INCAR,OSZICAR,vasprun.xml}; do
- cp ${vasp_file} ${vasp_file}_${current_time}
+ cp "${vasp_file}" "${vasp_file}_${current_time}" 2>/dev/null
done
- gzip vasprun.xml_${current_time} # gzip to save file space
+ gzip "vasprun.xml_${current_time}" # gzip to save file space
if [[ -f "CONTCAR" ]] && [[ $(wc -l < "CONTCAR") -ge 9 ]]; then # CONTCAR exists and greater than 9 lines
"cp" CONTCAR POSCAR
@@ -212,14 +213,14 @@ SnB_run_loop() {
echo "Running job for ${i%?}"
folder_shortname="${i#*_*_}"
# Remove % from folder_shortname as messes with some HPC schedulers
- if ! ( "${job_submit_command}" "${job_name_option}" "${defect_name%?}"_"${folder_shortname%?}" "${job_filename}" 2>/dev/null || \
- "${job_submit_command}" "${job_name_option}" "${defect_name%?}"_"${folder_shortname%??}" "${job_filename}" ); then
+ if ! { "${job_submit_command}" "${job_name_option}" "${defect_name%?}"_"${folder_shortname%?}" "${job_filename}" 2>/dev/null || \
+ "${job_submit_command}" "${job_name_option}" "${defect_name%?}"_"${folder_shortname%??}" "${job_filename}"; }; then
if ! [ "$current_time" == false ]; then
- rm *_"${current_time}" # only save over files if job submit command is successful (to prevent unwanted duplication of files)
+ rm ./*_"${current_time}" # only save over files if job submit command is successful (to prevent unwanted duplication of files)
fi
fi
- else
- rm *_"${current_time}" # only save over files if job successfully submitted
+ elif ! [ "$current_time" == false ]; then
+ rm ./*_"${current_time}" 2>/dev/null # only save over files if job successfully submitted
fi
builtin cd .. || return
else
diff --git a/shakenbreak/energy_lowering_distortions.py b/shakenbreak/energy_lowering_distortions.py
index 51feeea..c857347 100644
--- a/shakenbreak/energy_lowering_distortions.py
+++ b/shakenbreak/energy_lowering_distortions.py
@@ -273,6 +273,13 @@ def _prune_dict_across_charges(
defect_species_snb_name = f"{defect}_{'+' if charge > 0 else ''}{charge}"
for i in ["+", "", "+"]: # back to SnB name with "+" if all fail
defect_species = defect_species_snb_name.replace("+", i) # try with and without '+'
+ distorted_struct = distortion_dict["structures"][0]
+ if not isinstance(distorted_struct, Structure):
+ raise ValueError(
+ f"Distorted structure for {defect_species} was not correctly parsed. Instead "
+ f"of a pymatgen Structure object, got: {type(distorted_struct)}; "
+ f"{distorted_struct}"
+ )
comparison_results = compare_struct_to_distortions(
distortion_dict["structures"][0],
defect_species,
@@ -460,7 +467,7 @@ def get_energy_lowering_distortions(
structure_filename=structure_filename,
) # get the final structure of the
# energy lowering distortion
- if any(warning.category == UserWarning for warning in w):
+ if any(issubclass(warning.category, UserWarning) for warning in w):
# problem parsing structure, user will have received appropriate
# warning from io.read_vasp_structure()
print(
@@ -532,7 +539,7 @@ def get_energy_lowering_distortions(
structure_path=f"{output_path}/{defect_species}/{bond_distortion}",
structure_filename=structure_filename,
)
- if any(warning.category == UserWarning for warning in w):
+ if any(issubclass(warning.category, UserWarning) for warning in w):
# problem parsing structure, user will have received appropriate
# warning from io.read_vasp_structure()
print(
diff --git a/shakenbreak/input.py b/shakenbreak/input.py
index a2aa93a..86fc805 100644
--- a/shakenbreak/input.py
+++ b/shakenbreak/input.py
@@ -1740,7 +1740,7 @@ def __init__(
folder names will be set equal to `DefectEntry.name` if the `name`
attribute is set for all input `DefectEntry`s, otherwise generated
according to the `doped` convention
- (see: https://doped.readthedocs.io/en/latest/dope_workflow_example.html).
+ (see: https://doped.readthedocs.io/en/latest/generation_tutorial.html).
Defect charge states (from which bond distortions are determined) are
taken from the `DefectEntry.charge_state` property.
diff --git a/shakenbreak/py.typed b/shakenbreak/py.typed
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/shakenbreak/py.typed
@@ -0,0 +1 @@
+
diff --git a/tests/test_energy_lowering_distortions.py b/tests/test_energy_lowering_distortions.py
index d00f118..5c50570 100644
--- a/tests/test_energy_lowering_distortions.py
+++ b/tests/test_energy_lowering_distortions.py
@@ -45,13 +45,13 @@ def setUp(self):
self.FHI_AIMS_DATA_DIR = os.path.join(self.DATA_DIR, "fhi_aims")
self.ESPRESSO_DATA_DIR = os.path.join(self.DATA_DIR, "quantum_espresso")
self.V_Cd_minus_0pt55_structure = Structure.from_file(
- self.VASP_CDTE_DATA_DIR + "/vac_1_Cd_0/Bond_Distortion_-55.0%/CONTCAR"
+ f"{self.VASP_CDTE_DATA_DIR}/vac_1_Cd_0/Bond_Distortion_-55.0%/CONTCAR"
)
# create fake distortion folders for testing functionality:
for defect_dir in ["Int_Cd_2_+1", "vac_1_Cd_-1", "vac_1_Cd_-2"]:
if not os.path.exists(f"{self.VASP_CDTE_DATA_DIR}/{defect_dir}"):
- os.mkdir(self.VASP_CDTE_DATA_DIR + f"/{defect_dir}")
+ os.mkdir(f"{self.VASP_CDTE_DATA_DIR}/{defect_dir}")
# Int_Cd_2_+1 without data, to test warnings
V_Cd_1_dict = {"distortions": {-0.075: -205.740}, "Unperturbed": -205.800}
dumpfn(
@@ -79,16 +79,10 @@ def setUp(self):
"sub_1_In_on_Cd_+1",
]
- self.orig_castep_0pt3_files = os.listdir(
- self.CASTEP_DATA_DIR + "/vac_1_Cd_0/Bond_Distortion_30.0%"
- )
- self.orig_cp2k_0pt3_files = os.listdir(self.CP2K_DATA_DIR + "/vac_1_Cd_0/Bond_Distortion_30.0%")
- self.orig_fhi_aims_0pt3_files = os.listdir(
- self.FHI_AIMS_DATA_DIR + "/vac_1_Cd_0/Bond_Distortion_30.0%"
- )
- self.orig_espresso_0pt3_files = os.listdir(
- self.ESPRESSO_DATA_DIR + "/vac_1_Cd_0/Bond_Distortion_30.0%"
- )
+ self.orig_castep_0pt3_files = os.listdir(f"{self.CASTEP_DATA_DIR}/vac_1_Cd_0/Bond_Distortion_30.0%")
+ self.orig_cp2k_0pt3_files = os.listdir(f"{self.CP2K_DATA_DIR}/vac_1_Cd_0/Bond_Distortion_30.0%")
+ self.orig_fhi_aims_0pt3_files = os.listdir(f"{self.FHI_AIMS_DATA_DIR}/vac_1_Cd_0/Bond_Distortion_30.0%")
+ self.orig_espresso_0pt3_files = os.listdir(f"{self.ESPRESSO_DATA_DIR}/vac_1_Cd_0/Bond_Distortion_30.0%")
def tearDown(self):
# removed generated folders
@@ -228,6 +222,7 @@ def test_get_energy_lowering_distortions(self):
low_energy_defects_dict = energy_lowering_distortions.get_energy_lowering_distortions(
self.defect_charges_dict, self.VASP_CDTE_DATA_DIR
)
+ print([str(warning.message) for warning in w]) # for debugging
mock_print.assert_any_call("\nvac_1_Cd")
mock_print.assert_any_call(
"vac_1_Cd_0: Energy difference between minimum, found with -0.55 bond distortion, "