Skip to content

Commit

Permalink
Add kwargs to draw_displaced_parabolas
Browse files Browse the repository at this point in the history
  • Loading branch information
gmatteo committed Sep 27, 2023
1 parent 1fcdd87 commit 7088751
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 123 deletions.
78 changes: 5 additions & 73 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ in the form of pre-compiled packages that can be easily installed with e.g.::

conda install numpy scipy netcdf4

Create a new conda_ environment (let's call it ``abienv``) based on e.g. python3.6 with::
Create a new conda_ environment (let's call it ``abienv``) with::

conda create --name abienv python=3.6
conda create --name abienv

and activate it with::

Expand Down Expand Up @@ -116,10 +116,9 @@ For pip, use::
pip install -r requirements.txt
pip install -r requirements-optional.txt

If you are using conda_ (see `Installing conda`_ to install conda itself), create a new environment (``abienv``)
based on python3.9 with::
If you are using conda_ (see `Installing conda`_ to install conda itself), create a new environment (``abienv``) with::

conda create -n abienv python=3.9
conda create -n abienv
source activate abienv

Add ``conda-forge``, and ``abinit`` to your channels with::
Expand Down Expand Up @@ -407,7 +406,7 @@ A brief install guide, in case you have not yet used conda ... For a more extens
`Anaconda Howto <http://abinit.github.io/abipy/installation#anaconda-howto>`_.

Download the `miniconda installer <https://conda.io/miniconda.html>`_.
Select python3.6 and the version corresponding to your operating system.
Select the version corresponding to your operating system.

As an example, if you are a Linux user, download and install `miniconda` on your local machine with::

Expand All @@ -431,73 +430,6 @@ Source your ``.bashrc`` file to activate the changes done by ``miniconda`` to yo

.. _troubleshooting:

Troubleshooting
===============

GLIBC error
-----------

The python interpreter may raise the following exception when importing one of the pymatgen modules::

from pymatgen.util.coord import pbc_shortest_vectors
File "/python3.6/site-packages/pymatgen/util/coord.py", line 11, in <module>
from . import coord_cython as cuc
ImportError: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by /python3.6/site-packages/pymatgen/util/coord_cython.cpython-36m-x86_64-linux-gnu.so)`

This means that the pre-compiled version of pymatgen is not compatible with the GLIBC version available on your machine.
To solve the problem, we suggest to build and install pymatgen from source using the local version of GLIBC and the gcc compiler.
In the example below, we use a conda environment to install most of the dependencies with the exception of pymatgen and abipy.

Let's start by creating a conda environment with::

conda create -n glibc_env python=3.6
source activate glibc_env
conda config --add channels conda-forge

Use pip to install spglib::

pip install spglib

and try to ``import spglib`` inside the python terminal.

Download the pymatgen repository from github with::

git clone https://github.com/materialsproject/pymatgen.git
cd pymatgen

If git is not installed, use ``conda install git``

Now use conda to install the pymatgen requirements listed in ``requirements.txt``
but before that make sure that ``gcc`` is in ``$PATH``.
If you are working on a cluster, you may want to issue::

module purge

to avoid compiling C code with the intel compiler (it's possible to use ``icc`` but ``gcc`` is less problematic).

Remove the line::

enum34==1.1.6; python_version < '3.4'

from ``requirements.txt`` as this syntax is not supported by conda then issue::

conda install -y --file requirements.txt

At this point, we can build pymatgen and the C extensions::

python setup.py install

then ``cd`` to another directory (important) and test the build inside the python terminal with::

import spglib
import pymatgen

Finally, we can install Abipy from source with::

git clone https://github.com/abinit/abipy.git
cd abipy && conda install -y --file ./requirements.txt


License
=======

Expand Down
90 changes: 43 additions & 47 deletions abipy/lumi/deltaSCF.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import numpy as np
import json
from abipy.core.structure import Structure
Expand All @@ -15,10 +17,10 @@

class DeltaSCF():
"""
Object to post-process the results from a LumiWork, following a one-effective phonon mode model (1D-CCM).
For equations, notations and formalism, please refer to :
Object to post-process the results from a LumiWork, following a one-effective phonon mode model (1D-CCM).
For equations, notations and formalism, please refer to :
https://doi.org/10.1103/PhysRevB.96.125132
https://doi.org/10.1002/adom.202100649
https://doi.org/10.1002/adom.202100649
"""

@classmethod
Expand Down Expand Up @@ -203,7 +205,7 @@ def get_dict_per_atom(self,index,defect_symbol):
def get_dataframe_atoms(self,defect_symbol):
"""
Panda dataframe with relevant properties per atom.
units used are
units used are
mass - amu
DeltaR - Angstrom
DeltaQ^2 - amu.Angstrom^2
Expand All @@ -229,11 +231,11 @@ def get_dict_per_specie(self,specie):
d[r"$\Delta Q^2$"]=specie.atomic_mass*sum(dr_sp)

return d

def get_dataframe_species(self):
"""
Panda dataframe with relevant properties per species.
units used are
units used are
mass - amu
DeltaR - Angstrom
DeltaQ^2 - amu.Angstrom^2
Expand Down Expand Up @@ -265,7 +267,7 @@ def amu_list(self):

def delta_q(self,unit='atomic'):
"""
Total Delta_Q
Total Delta_Q
Args:
unit: amu^1/2.Angstrom if unit = 'atomic', kg^1/2.m if 'SI'
"""
Expand Down Expand Up @@ -363,7 +365,7 @@ def S_abs(self):

def FWHM_1D(self,T=0):
"""
Full width at half-maximum following a semi-classical approx in the 1D-CCM
Full width at half-maximum following a semi-classical approx in the 1D-CCM
(eq.20-21 of https://doi.org/10.1103/PhysRevB.96.125132)
Args:
T: Temperature
Expand All @@ -380,15 +382,15 @@ def FC_factor_approx(self,n):
"""
FC factor between initial vib. state m=0 to final vib. state n
approx of same eff frequency in gs and ex and T = 0K.
See eq. (9) of https://doi.org/10.1002/adom.202100649
See eq. (9) of https://doi.org/10.1002/adom.202100649
"""
FC = np.exp(self.S_em()) * self.S_em() ** n / math.factorial(n)
return FC

def lineshape_1D_zero_temp(self,energy_range=[0.5,5],max_m=25,phonon_width=0.01,with_omega_cube=True,normalized='Area'):
"""
Compute the emission lineshape following the effective phonon 1D-CCM at T=0K.
See eq. (9) of https://doi.org/10.1002/adom.202100649
See eq. (9) of https://doi.org/10.1002/adom.202100649
Args:
energy_range: Energy range at which the intensities are computed, ex : [0.5,5]
max_m: Maximal vibrational state m considered
Expand All @@ -404,7 +406,7 @@ def lineshape_1D_zero_temp(self,energy_range=[0.5,5],max_m=25,phonon_width=0.01,
E_x = np.linspace(energy_range[0], energy_range[1], n_x)

list_n = np.arange(0, max_m)
A = np.zeros(n_x)
A = np.zeros(n_x)
sigma = phonon_width / (2.35482)
for n in list_n:
#gaussian_1D = np.zeros(n_x)
Expand All @@ -418,12 +420,12 @@ def lineshape_1D_zero_temp(self,energy_range=[0.5,5],max_m=25,phonon_width=0.01,
A=A*E_x**3

if normalized=="Area":
C = 1 / (simps(A, E_x))
C = 1 / (simps(A, E_x))
if normalized=="Sum":
C=1/(max(A))

return E_x, C*A

@add_fig_kwargs
def plot_lineshape_1D_zero_temp(self,energy_range=[0.5,5],max_m=25,phonon_width=0.01,with_omega_cube="True",
normalized='Area', ax=None, **kwargs):
Expand All @@ -437,7 +439,7 @@ def plot_lineshape_1D_zero_temp(self,energy_range=[0.5,5],max_m=25,phonon_width=
with_omega_cube: Considered or not the omega^3 dependence of the intensity
normlized: Normalisation procedure. 'Area' if Area under the curve = 1
'Sum' if maximum of the curve = 1.
Returns: |matplotlib-Figure|
"""
ax, fig, plt = get_ax_fig_plt(ax=ax)
Expand All @@ -448,7 +450,7 @@ def plot_lineshape_1D_zero_temp(self,energy_range=[0.5,5],max_m=25,phonon_width=
ax.set_xlabel(r'Energy (eV)')
ax.set_ylabel(r'Intensity ')
return fig


def get_dict_results(self):
d=dict([
Expand All @@ -470,8 +472,8 @@ def get_dict_results(self):
def get_dataframe(self,label=None):
"""
Panda dataframe with the main results of a LumiWork : transition energies, delta Q, Huang Rhys factor,...
Units used are Angstrom, eV, amu.
DeltaSCF object should be instantiated with the four points files, not with relax files only.
Units used are Angstrom, eV, amu.
DeltaSCF object should be instantiated with the four points files, not with relax files only.
"""
rows=[]
index=[]
Expand All @@ -482,15 +484,15 @@ def get_dataframe(self,label=None):
df=pd.DataFrame(rows,index=index)

return df

@add_fig_kwargs
def displacements_visu(self,a_g=10,**kwargs):
"""
Make a 3d visualisation of the displacements induced by the electronic transition =
Difference between ground state and excited state atomic positions.
The colors of the atoms are based on Delta_Q_^2 per atom.
For displacement visualisation with VESTA, check https://github.com/lucydot/vesta_vectors
Args:
a_g = coefficient that multiplies the displacement magnitudes
Returns: |matplotlib-Figure|
Expand Down Expand Up @@ -526,9 +528,9 @@ def plot_delta_R_distance(self, defect_symbol,colors=["k","r","g","b","c","m"],a
Plot \DeltaR vs distance from defect for each atom, colored by species.
Args:
ax: |matplotlib-Axes| or None if a new figure should be created.
defect_symbol: defect_symbol, defect location will be the reference
defect_symbol: defect_symbol, defect location will be the reference
colors: list of colors for the species
Returns: |matplotlib-Figure|
"""

Expand All @@ -542,25 +544,25 @@ def plot_delta_R_distance(self, defect_symbol,colors=["k","r","g","b","c","m"],a
dfs.append(df.loc[df['symbol'] == symbol])
xs.append(dfs[i]["dist. from defect"])
ys.append(dfs[i]["$\\Delta R$"])

ax, fig, plt = get_ax_fig_plt(ax=ax)
for i, symbol in enumerate(symbols):
ax.stem(xs[i], ys[i], label=symbol, linefmt=colors[i], markerfmt="o" + colors[i],**kwargs)
ax.set_xlabel(r'Distance from defect ($\AA$)')
ax.set_ylabel(r'$\Delta R $ ($\AA$)')
ax.legend()

return fig

@add_fig_kwargs
def plot_delta_F_distance(self, defect_symbol,colors=["k","r","g","b","c","m"],ax=None, **kwargs):
"""
Plot \DeltaF vs distance from defect for each atom, colored by species.
Args:
ax: |matplotlib-Axes| or None if a new figure should be created.
defect_symbol: defect_symbol, defect location will be the reference
defect_symbol: defect_symbol, defect location will be the reference
colors: list of colors for the species
Returns: |matplotlib-Figure|
"""

Expand All @@ -574,16 +576,16 @@ def plot_delta_F_distance(self, defect_symbol,colors=["k","r","g","b","c","m"],a
dfs.append(df.loc[df['symbol'] == symbol])
xs.append(dfs[i]["dist. from defect"])
ys.append(dfs[i]["$\\Delta F$"])

ax, fig, plt = get_ax_fig_plt(ax=ax)
for i, symbol in enumerate(symbols):
ax.stem(xs[i], ys[i], label=symbol, linefmt=colors[i], markerfmt="o" + colors[i],**kwargs)
ax.set_xlabel(r'Distance from defect ($\AA$)')
ax.set_ylabel(r'$\Delta F$ ($eV/\AA$)')
ax.legend()

return fig

@add_fig_kwargs
def plot_four_BandStructures(self,nscf_files,ax_mat=None,ylims=[-5,5],**kwargs):
""""
Expand All @@ -597,31 +599,31 @@ def plot_four_BandStructures(self,nscf_files,ax_mat=None,ylims=[-5,5],**kwargs):

ax_mat, fig, plt = get_axarray_fig_plt(ax_mat, nrows=1, ncols=4,
sharex=True, sharey=True, squeeze=False)

titles = [r'$A_g$', r'$A_g^*$', r'$A_e^*$', r'$A_e$']
e0 = ebands[0].fermie

for i,eband in enumerate(ebands):
eband.plot_ax(ax=ax_mat[0,i],spin=0, e0=e0,color="k",**kwargs)
eband.plot_ax(ax=ax_mat[0,i],spin=1, e0=e0,color="r",**kwargs)
eband.decorate_ax(ax=ax_mat[0,i],title=titles[i])

ax_mat[0,0].set_ylim(ylims)
ax_mat[0,1].set_ylabel("")
ax_mat[0,2].set_ylabel("")
ax_mat[0,3].set_ylabel("")

return fig

@add_fig_kwargs
def draw_displaced_parabolas(self,ax=None,scale_eff_freq=4,font_size=8):
def draw_displaced_parabolas(self,ax=None,scale_eff_freq=4,font_size=8, **kwargs):
"""
Draw the four points diagram with relevant transition energies.
Args:
ax: |matplotlib-Axes| or None if a new figure should be created.
scale_eff_freq: scaling factor to adjust the parabolas curvatures.
scale_eff_freq: scaling factor to adjust the parabolas curvatures.
font_size: font size for the annotations
Returns: |matplotlib-Figure|
"""
ax,fig,plt=get_ax_fig_plt(ax=ax)
Expand All @@ -638,7 +640,7 @@ def draw_displaced_parabolas(self,ax=None,scale_eff_freq=4,font_size=8):

E_gs=0.5*omega_gs_sq.real*(Qs)**2+0 # ref at (0,0)
E_ex=0.5*omega_ex_sq.real*(Qs-delta_Q)**2+ self.E_zpl()# min at (delta_Q,ae_energy)


# parabolas
ax.plot(Qs,E_gs,'k',zorder=1)
Expand All @@ -650,8 +652,8 @@ def draw_displaced_parabolas(self,ax=None,scale_eff_freq=4,font_size=8):

ax.scatter(xs,ys,s=50,color='k',zorder=2)

# arrows
# arrows

ax.annotate("", xy=(0, E_zpl+0.95*new_FC_ex), xytext=(0, 0),
arrowprops=dict(arrowstyle="->",color="b",lw=1))
ax.annotate(r' $E_{abs}$='+format(self.E_abs(),".2f")+' eV ', xy=(0,(E_zpl+new_FC_ex)/2),ha='left',fontsize=font_size)
Expand All @@ -676,7 +678,7 @@ def draw_displaced_parabolas(self,ax=None,scale_eff_freq=4,font_size=8):
ax.annotate("", xy=(0, -new_FC_gs*0.2), xytext=(delta_Q, -new_FC_gs*0.2),
arrowprops=dict(arrowstyle="<->",color="k",lw=0.6))
ax.annotate(r'$\Delta Q$ ='+format(self.delta_q(),".2f"), xy=(delta_Q/2, -new_FC_gs*0.4),ha='center',fontsize=font_size)

ax.set_ylim(-new_FC_gs*1.5,E_zpl+2*new_FC_ex)
ax.set_xlim(-0.5*delta_Q,2*delta_Q)

Expand All @@ -693,9 +695,3 @@ def draw_displaced_parabolas(self,ax=None,scale_eff_freq=4,font_size=8):

return fig







Loading

0 comments on commit 7088751

Please sign in to comment.