Skip to content

Commit

Permalink
Now abiml.py relax Prints the initial and final structure
Browse files Browse the repository at this point in the history
  • Loading branch information
gmatteo committed Jul 13, 2024
1 parent e5c95b2 commit ad859c4
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 23 deletions.
18 changes: 5 additions & 13 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,8 @@ The installation process is greatly simplified if you install the required
python packages through `Anaconda <https://continuum.io/downloads>`_ (or conda).
See `Installing conda`_ to install conda itself.
We routinely use conda_ to test new developments with multiple Python versions and multiple virtual environments.
The anaconda distribution already provides the most critical dependencies (matplotlib_, scipy_, numpy_, netcdf4-python_)
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``) with::
Create a new conda_ environment based on python 3.11 (let's call it ``abienv``) with::

conda create --name abienv python=3.11

Expand All @@ -89,15 +85,11 @@ and activate it with::

You should see the name of the conda environment in the shell prompt.

Now add ``conda-forge`` to your conda channels with::

conda config --add channels conda-forge

This is the channel from which we will download pymatgen, abipy and abinit.

Finally, install AbiPy with::

conda install abipy
conda install abipy -c conda-forge

Please note that, at present, conda-forge does not provide executables

Additional information on the steps required to install AbiPy with anaconda are available
in the `anaconda howto <http://abinit.github.io/abipy/installation#anaconda-howto>`_.
Expand Down Expand Up @@ -199,7 +191,6 @@ Otherwise, follow the usual abinit installation instructions, and make sure abin

abinit --version


Configuration files for Abipy
=============================

Expand Down Expand Up @@ -379,6 +370,7 @@ The following scripts can be invoked directly from the terminal:
* ``abirun.py`` Execute AbiPy flow from terminal.
* ``abidoc.py`` Document Abinit input variables and Abipy configuration files.
* ``abinp.py`` Build input files (simplified interface for the AbiPy factory functions).
* ``abipsp.py`` Download pseudopotential tables from the PseudoDojo.

Use ``SCRIPT --help`` to get the list of supported commands and
``SCRIPT COMMAND --help`` to get the documentation for ``COMMAND``.
Expand Down
2 changes: 1 addition & 1 deletion abipy/abio/robots.py
Original file line number Diff line number Diff line change
Expand Up @@ -1266,7 +1266,7 @@ def plot_abs_conv(ax1, ax2, xs, yvals, abs_conv, xlabel, fontsize, hatch, **kwar
"""
y_xmax = yvals[-1]
span_style = dict(alpha=0.2, color="green", hatch=hatch)
ax1.axhspan(y_xmax - abs_conv, y_xmax + abs_conv, label=r"$|y-y(x_{max})}| \leq %s$" % abs_conv, **span_style)
ax1.axhspan(y_xmax - abs_conv, y_xmax + abs_conv, label=r"$|y-y(x_{max})| \leq %s$" % abs_conv, **span_style)

# Plot |y - y_xmax| in log scale on ax2.
ax2.plot(xs, np.abs(yvals - y_xmax), **kwargs)
Expand Down
22 changes: 20 additions & 2 deletions abipy/ml/aseml.py
Original file line number Diff line number Diff line change
Expand Up @@ -1011,8 +1011,24 @@ def traj(self):
raise RuntimeError("Cannot read ASE traj as traj_path is None")
return read(self.traj_path, index=":")

#def __str__(self):
#def to_string(self, verbose=0)
def __str__(self) -> str:
return to_string()

def to_string(self, verbose: int = 0) -> str:
"""
String representation with verbosity level verbose
"""
lines = []
app = lines.append
app("Initial structure:")
s0 = Structure.as_structure(self.r0.atoms)
app(str(s0))
app("")
app("Relaxed structure:")
s1 = Structure.as_structure(self.r1.atoms)
app(str(s1))

return "\n".join(lines)

def summarize(self, tags=None, mode="smart", stream=sys.stdout):
""""""
Expand Down Expand Up @@ -2042,6 +2058,8 @@ def run(self):
relax = relax_atoms(self.atoms, **relax_kws)
relax.summarize(tags=["unrelaxed", "relaxed"])

print(relax.to_string(verbose=self.verbose))

# Write files with final structure and dynamics.
formats = ["poscar",]
outpath_fmt = write_atoms(self.atoms, workdir, self.verbose, formats=formats)
Expand Down
24 changes: 23 additions & 1 deletion abipy/scripts/abicomp.py
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,25 @@ def abicomp_abiwan(options):
return _invoke_robot(options)


def abicomp_abiwan_ebands(options):
"""
Compare Wannier-interpolated band structure with ab-initio results.
"""
if len(options.paths) != 2:
raise ValueError("Two arguments with ABIWAN.nc and nc file with ElectronBands are required.")
from abipy.wannier90 import AbiwanFile
abiwan_path, ebands_path = options.paths[0], options.paths[1]
if not abiwan_path.endswith("ABIWAN.nc"):
abiwan_path, ebands_path = ebands_path, abiwan_path

abiwan = AbiwanFile(abiwan_path)
print(abiwan)
abiwan.hwan.plot()
abiwan.plot_with_ebands(ebands_path)

return 0


def abicomp_pseudos(options):
""""Compare multiple pseudos and print table to terminal."""
# Make sure entries in index are unique.
Expand Down Expand Up @@ -841,6 +860,7 @@ def get_epilog():
abicomp.py edos *_WFK.nc -nb => Compare electron DOS in the jupyter notebook.
abicomp.py optic DIR -nb => Compare optic results in the jupyter notebook.
abicomp.py abiwan *_ABIWAN.nc --expose => Compare ABIWAN results, produce matplotlib figures.
abicomp.py abiwan_ebands out_ABIWAN.nc out_GSR.nc --expose => Compare Wannier-interpolated band structure with ab-initio results.
#########
# Phonons
Expand Down Expand Up @@ -995,7 +1015,6 @@ def get_parser(with_epilog=False):

# Parent parser for commands supporting expose
expose_parser = argparse.ArgumentParser(add_help=False)

expose_parser.add_argument("-e", '--expose', default=False, action="store_true",
help='Execute robot.expose to produce a pre-defined list of (matplotlib|plotly) figures.')
expose_parser.add_argument("-s", "--slide-mode", default=False, action="store_true",
Expand Down Expand Up @@ -1148,6 +1167,9 @@ def get_parser(with_epilog=False):
p_abiwan = subparsers.add_parser('abiwan', parents=robot_parents, help=abicomp_abiwan.__doc__)
p_gwr = subparsers.add_parser('gwr', parents=robot_parents, help=abicomp_gwr.__doc__)

# Subparser for abiwan_ebands command.
p_abiwan_ebands = subparsers.add_parser('abiwan_ebands', parents=[copts_parser], help=abicomp_abiwan_ebands.__doc__)

# Subparser for pseudos command.
p_pseudos = subparsers.add_parser('pseudos', parents=[copts_parser], help=abicomp_pseudos.__doc__)
p_pspsp = subparsers.add_parser('psps', parents=robot_parents, help=abicomp_psps.__doc__)
Expand Down
14 changes: 12 additions & 2 deletions abipy/wannier90/abiwan.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,16 @@ def interpolate_ebands(self, vertices_names=None, line_density=20,
occfacts, self.ebands.nelect, self.nspinor, self.nspden,
smearing=self.ebands.smearing)

@add_fig_kwargs
def plot_with_ebands(self, ebands, **kwargs):
"""
Receiven an ab-initio electronic strucuture, interpolate the energies on the same list of k-points
and compare the two.
"""
plotter = self.get_plotter_from_ebands(ebands)
linestyle_dict = {"Interpolated": dict(linewidth=0, color="red", marker="o")}
return plotter.combiplot(linestyle_dict=linestyle_dict, **kwargs)

def get_plotter_from_ebands(self, ebands: ElectronBands) -> ElectronBandsPlotter:
"""
Interpolate energies using the k-points given in input |ElectronBands| ebands.
Expand Down Expand Up @@ -608,7 +618,7 @@ def get_interpolated_ebands_plotter(self, vertices_names=None, knames=None, line
diff_str = self.has_different_structures()
if diff_str: cprint(diff_str, "yellow")

# Need KpointList object (assume same structures in Robot)
# Need KpointList object (assuming same structures in the Robot)
nc0 = self.abifiles[0]
if kpoints is None:
if ngkpt is not None:
Expand Down Expand Up @@ -658,6 +668,6 @@ def write_notebook(self, nbpath=None) -> str:

# Mixins
#nb.cells.extend(self.get_baserobot_code_cells())
#nb.cells.extend(self.get_ebands_code_cells())
#nb.cells.extend(self.get_ebands_code_cells())wannier90.wout

return self._write_nb_nbpath(nb, nbpath)
15 changes: 13 additions & 2 deletions abipy/wannier90/win.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
from abipy.abio.inputs import AbstractInput
#from abipy.tools.typing import Figure

import abipy.core.abinit_units as abu

def structure2wannier90(structure) -> str:

def structure2wannier90(structure, units="Bohr") -> str:
"""
Return string with stucture in wannier90 format.
"""
Expand All @@ -27,8 +29,17 @@ def structure2wannier90(structure) -> str:
# Write lattice vectors.
# Set small values to zero. This usually happens when the CIF file
# does not give structure parameters with enough digits.
app("begin unit_cell_cart\nAng")
if units == "Bohr":
fact = abu.Ang_Bohr
app("begin unit_cell_cart\nBohr")
elif units == "Ang":
fact = 1.0
app("begin unit_cell_cart\nAng")
else:
raise ValueError(f"Invalid {units =}")

for r in np.where(np.abs(structure.lattice.matrix) > 1e-8, structure.lattice.matrix, 0.0):
r = r * fact
app(" %.10f %.10f %.10f" % (r[0], r[1], r[2]))
app("end unit_cell_cart\n")
app("begin atoms_frac")
Expand Down
4 changes: 2 additions & 2 deletions abipy/wannier90/wout.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def __init__(self, filepath):
def close(self) -> None:
"""Close file. Required by abc protocol."""

def __str__(self) ->str:
def __str__(self) -> str:
return self.to_string()

def to_string(self, verbose=0) -> str:
Expand Down Expand Up @@ -337,7 +337,7 @@ def plot(self, fontsize=8, **kwargs) -> Figure:
def plot_centers_spread(self, fontsize=8, **kwargs) -> Figure:
"""
Plot the convergence of the Wannier centers and spread
as function of iteration number
as a function of the iteration number
Args:
fontsize: legend and label fontsize.
Expand Down

0 comments on commit ad859c4

Please sign in to comment.