Ejemplo n.º 1
0
def _example():
    """Example of using a system"""
    from BigDFT.IO import XYZReader
    from BigDFT.Fragments import Fragment

    safe_print("Read in some files for the fragments..")
    reader = XYZReader("SiO")
    frag1 = Fragment(xyzfile=reader)
    reader = XYZReader("Si4")
    frag2 = Fragment(xyzfile=reader)

    safe_print("Now we move on to testing the system class.")
    sys = System(frag1=frag1, frag2=frag2)
    for at in sys["frag1"]:
        safe_print(dict(at))
    for at in sys["frag2"]:
        safe_print(dict(at))
    safe_print()

    safe_print("What if we want to combine two fragments together?")
    sys["frag1"] += sys.pop("frag2")
    for at in sys["frag1"]:
        safe_print(dict(at))
    safe_print("frag2" in sys)
    safe_print()

    safe_print("What if I want to split a fragment by atom indices?")
    temp_frag = sys.pop("frag1")
    sys["frag1"], sys["frag2"] = temp_frag[0:3], temp_frag[3:]
    for at in sys["frag1"]:
        safe_print(dict(at))
    for at in sys["frag2"]:
        safe_print(dict(at))
    safe_print()
Ejemplo n.º 2
0
    def set_atom_forces(self, logfile):
        """
        After a run is completed, we have the forces on each atom in the
        logfile. This routine will set those values to each atom in this sytem.

        Args:
          logfile (Logfiles.Logfile): logfile with the forces.
        """
        from BigDFT.Fragments import Fragment
        posinp = logfile.log.get('posinp')
        if posinp is not None and not isinstance(posinp, str):
            atlist = Fragment(posinp=posinp)
        else:
            atlist = Fragment(astruct=logfile.astruct)
        lookup = self.compute_matching(atlist)

        # Assign forces
        try:
            forces = logfile.forces
        except AttributeError:
            forces = logfile.astruct["forces"]
        for fragid, frag in self.items():
            for i, at in enumerate(frag):
                idx = lookup[fragid][i]
                if idx >= 0:
                    at.set_force(list(forces[idx].values())[0])
def _example():
    """Example of using OpenBabel interoperability"""
    from BigDFT.Systems import System
    from BigDFT.Fragments import Fragment
    from BigDFT.IO import XYZReader
    from os.path import join

    # Read in a system.
    sys = System()
    sys["FRA:1"] = Fragment()
    with XYZReader("CH4") as ifile:
        for at in ifile:
            sys["FRA:1"] += Fragment([at])

    # We can compute the smiles representation.
    print(compute_smiles(sys))

    # The energy.
    print(system_energy(sys, forcefield="UFF"))

    # Extract the forces.
    compute_system_forces(sys, forcefield="UFF")
    for frag in sys.values():
        for at in frag:
            print(at["force"])

    # Optimize the geometry.
    sys2 = optimize_system(sys, forcefield="UFF")
    print(system_energy(sys2, forcefield="UFF"))
Ejemplo n.º 4
0
def system_from_log(log, fragmentation=None):
    """
    This function returns a :class:`~BigDFT.Fragment.System` class out of a
    logfile. If the logfile contains information about fragmentation and atomic
    multipoles, then the system is created accordingly.
    Otherwise, the fragmentation scheme is determined by the fragmentation
    variable.

    Args:
       log (Logfile): the logfile of the QM run. In general must have been done
           with Linear Scaling formalism.
       fragmentation (str): the scheme to be used for the fragmentation in the
           case if not provided internally by the logfile.
           The possible values are ``atomic`` and ``full``, in which case the
           system as as many fragments as the number of atoms, or only one
           fragment, respectively.
    Returns:
        (BigDFT.Systems.System): The instance of the class containing
        fragments.
    """
    from BigDFT.Fragments import Fragment
    name = log.log.get('run_name', 'FULL') + ':0'

    full_system = System()
    posinp = log.log.get('posinp')
    if posinp is not None and not isinstance(posinp, str):
        full_system[name] = Fragment(posinp=posinp)
    else:
        full_system[name] = Fragment(astruct=log.astruct)

    full_system.set_logfile_info(log)

    # now we may defragment the system according to the provided scheme
    if fragmentation == 'full':
        return full_system
    elif fragmentation == 'atomic' or 'posinp' not in log.log:
        atomic_system = System()
        for iat, at in enumerate(full_system[name]):
            atomic_system['ATOM:' + str(iat)] = Fragment([at])
        return atomic_system
    else:
        posinp = log.log['posinp']
        frag_dict = {}
        for iat, tupl in enumerate(zip(posinp['positions'],
                                       full_system[name])):
            at, obj = tupl
            fragid = at.get('frag', 'ATOM:' + str(iat))
            if isinstance(fragid, list):
                fragid = ':'.join(map(str, fragid))
            if fragid not in frag_dict:
                frag_dict[fragid] = [obj]
            else:
                frag_dict[fragid].append(obj)
        frag_system = System()
        for fragid in frag_dict:
            frag_system[fragid] = Fragment(frag_dict[fragid])
        return frag_system
Ejemplo n.º 5
0
def ase_to_bigdft(mol):
    """
    Given an ASE collection of atoms, this transforms that collection into
    a BigDFT fragment.

    Args:
      mol (ase.Atoms): a collection of atoms used by ASE.

    Returns:
      (BigDFT.Fragments.Fragment): a BigDFT fragment.
    """
    from BigDFT.Fragments import Fragment
    from BigDFT.Atoms import Atom

    frag = Fragment()
    for at in mol:
        frag += [
            Atom({
                "sym": at.symbol,
                "r": at.position,
                "units": "angstroem"
            })
        ]

    return frag
def _example():
    """Example of using PSI4 interoperability"""
    from BigDFT.IO import XYZReader
    from BigDFT.Systems import System
    from BigDFT.Fragments import Fragment
    from os.path import join
    from copy import deepcopy

    # Create a system.
    reader = XYZReader(join("Database", "XYZs", "He.xyz"))
    fsys = System()
    fsys["FRA:1"] = Fragment(xyzfile=reader)
    fsys["FRA:2"] = deepcopy(fsys["FRA:1"])
    fsys["FRA:2"].translate([-2, 0, 0])

    # Create a calculator.
    code = PSI4Calculator()
    log = code.run(sys=fsys, action="energy", basis="jun-cc-pvdz",
                   psi4_options={"scf_type": "direct"}, method="scf",
                   name="test")
    print(log)

    # The raw logfile is also available.
    print(log.log[4])

    # Geometry optimization.
    log = code.run(sys=fsys, action="optimize", basis="jun-cc-pvdz",
                   method="scf", name="test-opt")
    print(log)

    # SAPT
    log = code.run(sys=fsys, action="energy", basis="jun-cc-pvdz",
                   method="sapt0", name="test-sapt")
    print(log)
Ejemplo n.º 7
0
    def ase_potential_energy(self, ase_calculator):
        """
        Given a ASE calculator, calculates the potential energy
        of the system.

        Args:
            ase_calculator (ase.calculators.calculator.Calculator): ASE
              calculator.

        Returns:
            float: the potential energy, in Hartree
        """
        from Fragments import Fragment
        from ASEInterop import ase_potential_energy as asepot
        bigfrag = Fragment(system=self)
        return asepot(bigfrag, ase_calculator)
def _example():
    """Visualization Example"""
    from BigDFT.Systems import System
    from BigDFT.Fragments import Fragment
    from BigDFT.IO import XYZReader

    # Read in a system.
    sys = System()
    with XYZReader("SiO") as ifile:
        for i, at in enumerate(ifile):
            sys["FRA:" + str(i)] = Fragment([at])

    # Display the system.
    viz = InlineVisualizer(400, 300)
    viz.display_system(sys)

    # Change the colors
    colordict = get_distinct_colors(list(sys))
    viz.display_system(sys, colordict=colordict)
Ejemplo n.º 9
0
def system_from_dict_positions(posinp, units='angstroem'):
    """
    Build a system from a set of positions from a dictionary whose yaml
    serialisation is compliant with the BigDFT yaml position format

    Args:
       posinp (list): list of the atomic specifications
    Returns:
       BigDFT.Systems.System: an instance of the system class.
          The employed fragment specification is specified in the file.
    """
    from BigDFT.Atoms import Atom
    from BigDFT.Fragments import Fragment
    sys = System()
    for iat, at in enumerate(posinp):
        frag = GetFragId(at, iat)
        if frag not in sys:
            sys[frag] = Fragment()
        sys[frag].append(Atom(at, units=units))
    return sys
Ejemplo n.º 10
0
 def __init__(self, name):
     import os
     from BigDFT.Fragments import Fragment
     from BigDFT.Systems import System
     from BigDFT.IO import XYZReader
     # import the positions of the molecules from the XYZ directory
     dirXYZ = os.path.join(os.path.dirname(__file__), 'XYZs')
     filename = os.path.abspath(os.path.join(dirXYZ, name + '.xyz'))
     if not os.path.isfile(filename):
         raise ValueError('Molecule not available')
     ff = XYZReader(filename)
     frag = Fragment(xyzfile=ff)
     system = System({'molecule:0': frag})
     self.update(system.get_posinp())
     # temporary change of the keys 'values' into 'positions'
     if 'values' in self:
         self['positions'] = self.pop('values')
     if 'positions' in self:
         for at in self['positions']:
             if 'r' in at:
                 at.pop('r')
Ejemplo n.º 11
0
    def generate_link_atoms(self, fullsys, subsys, distcut=6.0):
        """
        This routine adds link atoms to a subsystem based on the bond
        order of a full system. Link atom positions are automatically adjusted
        based on the length of some standard bonds.

        Args:
          fullsys (BigDFT.Systems.System): the full system that the subsystem
            is embedded into.
          subsys (BigDFT.Systems.System): the embedded system which needs
            link atoms.
          distcut (float): this cutoff is the largest distance value we expect
            allow a bond to be.

        Returns:
          (BigDFT.Systems.System): the subsystem with link atoms added.
          (BigDFT.Systems.System): a system which has the atoms that were
            removed and replaced with link atoms.
        """
        from BigDFT.Systems import System
        from BigDFT.Fragments import Fragment
        from copy import deepcopy
        from numpy.linalg import norm
        from numpy import array
        from warnings import warn

        # Bond lengths for link atoms.
        bond_lengths = {
            "C": 2.0598,
            "N": 1.90862,
            "O": 1.81414,
            "F": 1.73855,
            "P": 2.68341,
            "S": 2.53223,
            "Cl": 2.39995,
            "Br": 2.66451,
            "I": 3.04246
        }

        if fullsys.conmat is None:
            raise ValueError("Generating link atoms requires connectivity"
                             " information")

        linksys = deepcopy(subsys)
        removesys = System()

        # Loop over atoms and look for bonds running out of the QM system.
        for fragid in subsys:
            linklist = []
            for i in range(0, len(fullsys[fragid])):
                for ft, bv in fullsys.conmat[fragid][i].items():
                    if ft[0] in subsys.keys():
                        continue
                    if bv == 1:
                        newat = deepcopy(fullsys[ft[0]][ft[1]])
                        # Change the symbol to hydrogen
                        newat.sym = "H"
                        newat.is_link = True
                        # If possible we adjust the position for a reasonable
                        # bond length
                        conat = fullsys[fragid][i]
                        if conat.sym in bond_lengths:
                            pos1 = array(conat.get_position("bohr"))
                            pos2 = array(newat.get_position("bohr"))
                            vec = pos2 - pos1
                            vec *= bond_lengths[conat.sym] / norm(vec)
                            newpos = [x + y for x, y in zip(pos1, vec)]
                            newat.set_position(newpos, units="bohr")
                        else:
                            warn(conat.sym + "bondlength unknown", UserWarning)
                        linklist.append(newat)
                    elif bv > 1:
                        print("Not yet implemented double/triple bonds.", bv)
                        raise NotImplementedError
                    if ft[0] not in removesys:
                        removesys[ft[0]] = Fragment()
                    removesys[ft[0]] += [fullsys[ft[0]][ft[1]]]

            # Add those atoms to the fragment
            for link in linklist:
                linksys[fragid] += [link]

        return linksys, removesys
Ejemplo n.º 12
0
def _example():
    """
    Postprocessing Example
    """
    from BigDFT.Systems import System, FragmentView
    from BigDFT.Fragments import Fragment
    from BigDFT.IO import XYZReader
    from BigDFT.Calculators import SystemCalculator
    from BigDFT.Inputfiles import Inputfile
    from scipy.linalg import eigh
    from copy import deepcopy

    # Create a system
    sys = System()
    sys["FRA:0"] = Fragment()
    with XYZReader("CH2") as ifile:
        for at in ifile:
            sys["FRA:0"].append(at)
    sys["FRA:1"] = Fragment()
    with XYZReader("CH3") as ifile:
        for at in ifile:
            sys["FRA:1"].append(at)
    sys["FRA:1"].translate([0, 0, -3])
    sys["FRA:2"] = deepcopy(sys["FRA:0"])
    sys["FRA:2"].translate([0, 0, 3])
    sys["FRA:2"].rotate(y=150, units="degrees")
    sys["FRA:3"] = deepcopy(sys["FRA:0"])
    sys["FRA:3"].translate([3, 0, 1.5])

    print(list(sys))

    # Run a calculation. `write_support_function_matrices` and `linear` are
    # key. You also should be sure to set the atom multipoles.
    inp = Inputfile()
    inp.set_xc("PBE")
    inp.set_hgrid(0.4)
    inp.write_support_function_matrices()
    inp["import"] = "linear"

    code = SystemCalculator()
    code.update_global_options(verbose=False)
    log = code.run(input=inp, posinp=sys.get_posinp(), run_dir="work")
    sys.set_atom_multipoles(log)

    # Create the post processing tool.
    from BigDFT.PostProcessing import BigDFTool
    btool = BigDFTool()

    # Purity
    purity = btool.run_compute_purity(sys, log)
    print(purity)

    # Charges
    charges = {
        fragid: sum(at.nel for at in frag)
        for fragid, frag in sys.items()
    }

    # Bond Orders
    bo = btool.fragment_bond_order(sys, sys.keys(), sys.keys(), log)

    # Population values.
    population = btool.fragment_population(sys, log)
    print(population)

    # These three things define a fragment view.
    view = FragmentView(purity, bo, charges)

    # Auto Fragmentation
    mapping = btool.auto_fragment(sys, view, 0.10)
    print(mapping)

    # This defines a new view.
    new_view = view.refragment(mapping)
    print(new_view.purities)

    # Eigenvalues.
    H = btool.get_matrix_h(log)
    S = btool.get_matrix_s(log)
    w = eigh(H.todense(), b=S.todense(), eigvals_only=True)
    print(w)
Ejemplo n.º 13
0
def _example():
    """Test the XYZ Module"""
    from BigDFT.Systems import System
    from BigDFT.Fragments import Fragment
    from BigDFT.UnitCells import UnitCell
    file = "Si4"

    safe_print("First let's try reading an XYZ file.")
    atom_list = []
    with XYZReader(file) as reader:
        safe_print(reader.closed)
        for at in reader:
            atom_list.append(at)
    safe_print(reader.closed)
    safe_print(atom_list)
    safe_print()

    safe_print("Now let's try writing an XYZ file.")
    safe_print()
    with XYZWriter("test.xyz", len(atom_list),
                   units=reader.units) as writer:
        safe_print(writer.closed)
        for at in atom_list:
            writer.write(at)
    safe_print(writer.closed)
    safe_print()
    with open("test.xyz") as ifile:
        for line in ifile:
            safe_print(line, end='')
    safe_print()

    safe_print("Print with various boundary conditions")
    with XYZWriter("test.xyz", len(atom_list), reader.units,
                   cell=UnitCell()) as writer:
        for at in atom_list:
            writer.write(at)
    with XYZReader("test.xyz") as ifile:
        print(ifile.cell.get_boundary_condition())

    with XYZWriter("test.xyz", len(atom_list), reader.units,
                   cell=UnitCell([5, 5, 5])) as writer:
        for at in atom_list:
            writer.write(at)
    with XYZReader("test.xyz") as ifile:
        print(ifile.cell.get_boundary_condition())

    with XYZWriter("test.xyz", len(atom_list), reader.units,
                   cell=UnitCell([5, float("inf"), 5])) as writer:
        for at in atom_list:
            writer.write(at)
    with XYZReader("test.xyz") as ifile:
        print(ifile.cell.get_boundary_condition())

    with XYZWriter("test.xyz", len(atom_list), reader.units,
                   cell=UnitCell([float("inf"), float("inf"), 5])) as writer:
        for at in atom_list:
            writer.write(at)
    with XYZReader("test.xyz") as ifile:
        print(ifile.cell.get_boundary_condition())
    safe_print()

    safe_print("Now let's demonstrate the pdb and mol2 writer")
    sys = System()
    sys["FRAG:0"] = Fragment(atom_list)
    with open("test.pdb", "w") as ofile:
        write_pdb(sys, ofile)
    with open("test.pdb") as ifile:
        for line in ifile:
            safe_print(line, end='')
    safe_print()

    with open("test.mol2", "w") as ofile:
        write_mol2(sys, ofile)
    with open("test.mol2") as ifile:
        for line in ifile:
            safe_print(line, end='')
    safe_print()
Ejemplo n.º 14
0
def read_pdb(ifile, include_chain=False, disable_warnings=False):
    """
    Read a system from a PDB file.

    Args:
      ifile (TextIOBase): the file to read from.
      disable_warnings (bool): whether to print warnings about possible file
        issues.
      include_chain (bool): include the chain id if True

    Warning:
       This will read in the connectivity information from the pdb as well.
       However, a pdb file does not provide any information about the bond
       order. Thus, the bond order of each bond will be set to one.

    Returns:
      (BigDFT.Systems.System): the system file.
    """
    from BigDFT.Fragments import Fragment
    from BigDFT.Systems import System
    from warnings import warn
    from BigDFT.UnitCells import UnitCell

    # First pass read in the atoms.
    sys = System()
    lookup = {}
    sys.conmat = {}
    found = False

    for line in ifile:
        try:  # See if there is an atom on this line
            if line[:4] == "ATOM" or line[:6] == "HETATM":
                at, atid, fragid = _process_atom(line,
                                                 include_chain=include_chain)

                # We can ignore lone pairs
                if at.sym == "Lp":
                    continue

                # Add to the system
                if fragid not in sys:
                    sys[fragid] = Fragment()
                sys[fragid] += [at]

                # Build the lookup table
                lookup[atid] = (fragid, len(sys[fragid]) - 1)

            elif line[:6] == "CONECT":
                found = True
                split = _split_line(line, len(lookup))
                (fragid, atnum) = lookup[int(split[1])]

                for at2 in split[2:]:
                    fragid2, atnum2 = lookup[int(at2)]

                    if fragid not in sys.conmat:
                        sys.conmat[fragid] = []
                        for i in range(0, len(sys[fragid])):
                            sys.conmat[fragid].append({})

                    sys.conmat[fragid][atnum][(fragid2, atnum2)] = 1.0

            elif line[:6] == "CRYST1":
                a = float(line[7:15])
                b = float(line[16:24])
                c = float(line[25:33])
                alpha = float(line[34:40])
                beta = float(line[41:47])
                gamma = float(line[48:54])

                sys.cell = UnitCell([a, b, c], units="angstroem")

                if not disable_warnings:
                    if (alpha != 90 or beta != 90 or gamma != 90):
                        warn("Cell angles must be 90 degrees", UserWarning)

        except IndexError:  # For shorter lines
            continue

    if not found:
        sys.conmat = None
    else:
        # for any connectivity not specified we give default values.
        for fragid in sys:
            if fragid not in sys.conmat:
                sys.conmat[fragid] = []
                for i in range(0, len(sys[fragid])):
                    sys.conmat[fragid].append({})

    if not disable_warnings:
        if sum([len(x) for x in sys.values()]) == 0:
            warn("Warning: zero atoms found", UserWarning)

    return sys
Ejemplo n.º 15
0
def read_mol2(ifile, disable_warnings=False):
    """
    Read a system from a mol2 file.

    Args:
      ifile (TextIOBase): the file to read from.
      disable_warnings (bool): whether to print warnings about possible file
        issues.

    Returns:
      (BigDFT.Systems.System): the system file.
    """
    from BigDFT.Systems import System
    from BigDFT.Fragments import Fragment
    from BigDFT.Atoms import Atom
    from BigDFT.UnitCells import UnitCell
    from warnings import warn

    sys = System()

    # Just go ahead and read the whole file into a string.
    lines = [x for x in ifile]

    # First pass, read in the number of atoms.
    for start, line in enumerate(lines):
        if ("@<TRIPOS>MOLECULE" in line):
            break
    start += 1

    split = lines[start+1].split()
    natoms = int(split[0])
    nbonds = int(split[1])

    # Second pass read in the atoms.
    for start, line in enumerate(lines):
        if ("@<TRIPOS>ATOM" in line):
            break
    start += 1

    lookup = []
    for i in range(0, natoms):
        split = lines[start + i].split()
        pos = [float(x) for x in split[2:5]]
        name = split[5]
        sym = name.split(".")[0]
        fragid = split[7] + ":" + split[6]
        charge = [float(split[8])]

        # Add fragment
        if fragid not in sys:
            sys[fragid] = Fragment()
        at = Atom({sym: pos, "units": "angstroem", "q0":
                   charge, "name": name})
        sys[fragid] += [at]

        # Lookup table for connectivity
        lookup.append((fragid, len(sys[fragid]) - 1))

    # Third pass reads the connectivity.
    for start, line in enumerate(lines):
        if ("@<TRIPOS>BOND" in line):
            break
    start += 1

    if start < len(lines):
        sys.conmat = {}
        for fragid, frag in sys.items():
            sys.conmat[fragid] = []
            for i in range(0, len(frag)):
                sys.conmat[fragid].append({})

    bowarn = False
    for i in range(0, nbonds):
        split = lines[start + i].split()
        frag1, at1 = lookup[int(split[1])-1]
        frag2, at2 = lookup[int(split[2])-1]
        bo = split[3]
        try:
            bo = float(split[3])
        except ValueError:
            bowarn = True
            bo = 1
        sys.conmat[frag1][at1][(frag2, at2)] = bo

        # Since mol2 doesn't include the symmetric bonds.
        if frag1 != frag2 or at1 != at2:
            sys.conmat[frag2][at2][(frag1, at1)] = bo

    # Fourth path reads the unit cell.
    for start, line in enumerate(lines):
        if ("@<TRIPOS>CRYSIN" in line):
            break
    start += 1

    if start < len(lines):
        split = lines[start].split()
        a = float(split[0])
        b = float(split[1])
        c = float(split[2])
        alpha = float(split[3])
        beta = float(split[4])
        gamma = float(split[5])

        sys.cell = UnitCell([a, b, c], units="angstroem")

        if not disable_warnings:
            if (alpha != 90 or beta != 90 or gamma != 90):
                warn("Cell angles must be 90 degrees", UserWarning)

    if not disable_warnings:
        if sum([len(x) for x in sys.values()]) == 0:
            warn("Warning: zero atoms found", UserWarning)
        if bowarn:
            warn("Unsupported bond type had to be set to 1 (i.e. aromatic)",
                 UserWarning)

    return sys
def read_polaris_pdb(pdbfile, chain_as_letter=False, slefile=None):
    """
    Read coordinates in the PDB format of POLARIS

    Args:
       pdbfile (str): path of the input file
       chain_as_letter (bool): If True, the fifth column
           is assumed to contain a letter
       slefile (str): path of the file ``.sle`` of Polaris from which
           to extract the system's attributes.

    Warning:
       Assumes Free Boundary conditions for the molecule.
       Only accepts atoms that have one letter in the symbol.
       Switch representation if there is a single letter in the fifth column

    Returns:
       System: A system class
    """
    from BigDFT.Fragments import Fragment
    from BigDFT.Systems import System, GetFragId
    from BigDFT.Atoms import Atom
    sys = System()
    units = 'angstroem'
    with open(pdbfile) as ifile:
        for line in ifile:
            if 'ATOM' not in line:
                continue
            atomline = line.split()
            if chain_as_letter:
                iat, name, frag, lett, ifrag, x, y, z, sn = atomline[1:10]
                chain = lett
                segname = sn
            else:
                iat, name, frag, ifrag, x, y, z, chlett = atomline[1:9]
                chain = chlett[2]
                segname = chlett
            atdict = {
                str(name[:1]): map(float, [x, y, z]),
                'frag': [chain + '-' + frag, int(ifrag)],
                'name': name,
                'iat': int(iat),
                'segname': segname
            }
            fragid = GetFragId(atdict, iat)
            if fragid not in sys:
                sys[fragid] = Fragment()
            sys[fragid].append(Atom(atdict, units=units))
    if slefile is None:
        return sys
    attributes = read_polaris_sle(slefile)
    from BigDFT import Systems as S, Fragments as F, Atoms as A
    system = S.System()
    for name, frag in sys.items():
        refrag = F.Fragment()
        for at in frag:
            atdict = at.dict()
            att = attributes[atdict['iat'] - 1]
            assert att['name'] == atdict['name']
            atdict.update(att)
            refrag.append(A.Atom(atdict))
        system[name] = refrag
    return system
    def visualize_fragments(self,
                            system,
                            scriptfile,
                            geomfile,
                            fragcolors=None):
        """
        This generates a script for visualizing the fragmentation of a
        system using VMD.

        Args:
          system (BigDFT.Systems.System): the system to visualize.
          scriptfile (str): the name of the file to write the vmd script
            to (usually has extension .tcl)
          geomfile (str): the filename for where to write an xyz file
            of the system.
          fragcolors (dict): optionally, a dictionary from fragment ids to
            fragment colors. Colors are integers between 0 and 32.
        """
        from BigDFT.Fragments import Fragment
        from BigDFT.IO import XYZWriter

        # To create the XYZ file, we first make one big fragment.
        geomorder = Fragment()
        for fragid, frag in system.items():
            geomorder += frag

        # Then write it to file.
        with XYZWriter(geomfile, len(geomorder)) as ofile:
            for at in geomorder:
                ofile.write(at)

        # Get the matching so we can write the correct atom indices.
        matching = system.compute_matching(geomorder)

        # If fragcolors is not specified, we will generate it ourselves.
        if fragcolors is None:
            fragcolors = {}
            for i, s in enumerate(system):
                # 16 is black, which we will reserve.
                if i % 32 == 16:
                    c = str(32)
                else:
                    c = str(i % 32)
                fragcolors[s] = c

        # The header of the script file draws the whole system in black.
        outstr = self._get_default_header(geomfile)

        # This part colors individual fragments.
        modid = 1
        for fragid, frag in system.items():
            if fragid not in fragcolors:
                continue
            outstr += "mol addrep 0\n"
            outstr += """mol modselect """ + str(modid) + """ 0 index """
            outstr += " ".join([str(x) for x in matching[fragid]])
            outstr += "\n"
            outstr += """mol modcolor """
            outstr += str(modid) + """ 0 ColorID """ + \
                str(fragcolors[fragid]) + """\n"""
            modid += 1

        # Finally, write to file.
        with open(scriptfile, "w") as ofile:
            ofile.write(outstr)
Ejemplo n.º 18
0
def _example():
    """Example of using ASE interoperability"""
    from BigDFT.IO import XYZReader
    from BigDFT.Inputfiles import Inputfile
    from BigDFT.Calculators import SystemCalculator
    from BigDFT.Fragments import Fragment
    from BigDFT.Systems import System
    from ase.calculators.lj import LennardJones
    from BigDFT.UnitCells import UnitCell
    from ase.units import Hartree
    from ase.optimize import BFGS
    from os.path import join
    from copy import deepcopy

    # Create a system.
    sys = System()
    reader = XYZReader("Ar")
    sys["FRA:1"] = Fragment(xyzfile=reader)
    sys["FRA:2"] = deepcopy(sys["FRA:1"])
    sys["FRA:2"].translate([-2, 0, 0])

    # Skip straight to the potential energy.
    print(ase_potential_energy(sys, LennardJones()))

    # Advanced used.
    asys = bigdft_to_ase(sys)
    asys.set_calculator(LennardJones())
    dyn = BFGS(asys)
    dyn.run(fmax=0.05)
    print(asys.get_potential_energy() / Hartree)

    # Unit cells
    sys.cell = UnitCell([5, 5, 5], units="bohr")
    print(ase_potential_energy(sys, LennardJones()))
    sys.cell = UnitCell([5, float("inf"), 5], units="bohr")
    print(ase_potential_energy(sys, LennardJones()))
    sys.cell = UnitCell([float("inf"), float("inf"), 5], units="bohr")
    print(ase_potential_energy(sys, LennardJones()))

    # We can also use BigDFT with ase.
    inp = Inputfile()
    inp.set_xc("PBE")
    inp.set_hgrid(0.4)
    code = SystemCalculator(verbose=False)
    sys.cell = UnitCell()
    print(
        ase_potential_energy(
            sys, BigASECalculator(inp,
                                  code,
                                  directory="work",
                                  label="ase-free")))
    sys.cell = UnitCell([5, 5, 5], units="bohr")
    print(
        ase_potential_energy(
            sys,
            BigASECalculator(inp, code, directory="work",
                             label="ase-periodic")))
    sys.cell = UnitCell([5, float("inf"), 5], units="bohr")
    print(
        ase_potential_energy(
            sys,
            BigASECalculator(inp, code, directory="work",
                             label="ase-surface")))
    sys.cell = UnitCell([float("inf"), float("inf"), 5], units="bohr")
    print(
        ase_potential_energy(
            sys, BigASECalculator(inp,
                                  code,
                                  directory="work",
                                  label="ase-wire")))