Source code for airsspy.build

###########################################################################
# airss-ase                                                               #
# Copyright (C) 2019  Bonan Zhu                                           #
#                                                                         #
# This program is free software; you can redistribute it and/or modify    #
# it under the terms of the GNU General Public License as published by    #
# the Free Software Foundation; either version 2 of the License, or       #
# (at your option) any later version.                                     #
#                                                                         #
# This program is distributed in the hope that it will be useful,         #
# but WITHOUT ANY WARRANTY; without even the implied warranty of          #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           #
# GNU General Public License for more details.                            #
#                                                                         #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., #
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.             #
###########################################################################
"""
Module for building the random cell
"""

import subprocess as sbp
from typing import TYPE_CHECKING, Optional, Union

from ase import Atoms
from ase.atoms import Atoms as ASEAtoms
from castepinput import CellInput
from castepinput.parser import PlainParser

from .common import BuildcellError

if TYPE_CHECKING:
    from .seed import SeedAtoms


[docs] class Buildcell: """ File based inteface to the buildcell program which is part of Ab inito Radnom Structure Searhcing (AIRSS) package """ def __init__(self, atoms: Union["SeedAtoms", ASEAtoms]) -> None: """Initialise an Buildcell object""" self.atoms = atoms self.proc: Optional[sbp.Popen] = None self.res_atoms: Optional[ASEAtoms] = None # Input and output from the buildcell program self.bc_out: Optional[str] = None self.bc_err: Optional[str] = None self.bc_in: Optional[str] = None
[docs] def generate(self, timeout: int = 10, write_cell: Optional[str] = None) -> ASEAtoms: """Generate a random atom based on a template timeout: time to wait for buildcell binary write_seed : Name of the output cell to be written""" bc_proc = sbp.Popen( "buildcell", universal_newlines=True, stdin=sbp.PIPE, stdout=sbp.PIPE, stderr=sbp.PIPE, ) self.proc = bc_proc cell = "\n".join(self.atoms.get_cell_inp_lines()) # type: ignore[union-attr] self.bc_in = cell try: self.bc_out, self.bc_err = bc_proc.communicate(input=cell, timeout=timeout) except sbp.TimeoutExpired as excep: bc_proc.kill() self.bc_out, self.bc_err = bc_proc.communicate() raise BuildcellError() from excep # Write the output from buildcell if write_cell: with open(write_cell + ".cell", "w") as output: output.write(self.bc_out) # Process the result outlines = self.bc_out.split("\n") parser = PlainParser(outlines) parser.parse() cellout = CellInput() for k, value in parser.get_dict().items(): cellout.__setitem__(k, value) cell = cellout.get_cell() elements, positions, _ = cellout.get_positions() atoms = Atoms(symbols=elements, cell=cell, positions=positions, pbc=True) self.res_atoms = atoms return atoms
[docs] def write_seed(self, seedname: str) -> None: """Write the seed for buildcell to the disk""" self.atoms.write_seed(seedname) # type: ignore[union-attr]
[docs] def gen_and_view( self, viewer: Optional[str] = None, wrap: bool = False, timeout: int = 20 ) -> None: """Geneate one and view with viewer immediately. Wrap if needed.""" from ase.visualize import view atoms = self.generate(timeout=timeout) if not atoms: return if wrap: atoms.wrap() if viewer: view(atoms, viewer=viewer) else: view(atoms)