Exemple #1
0
def vibmodes(atoms,
             startdir=None,
             mask=None,
             workhere=False,
             save=None,
             give_output=0,
             pmap=pmap3,
             **kwargs):
    """
    Wrapper around vibmode, which used the atoms objects
    The hessian is calculated by derivatef
    qfunc.fwrapper is used as a wrapper to calulate the gradients
    """
    from pts.memoize import Memoize, DirStore
    coord = atoms.get_positions()

    if mask == None:
        mask = constraints2mask(atoms)

    if mask == None:  # (if still None)
        fun = Cartesian()
    else:
        fun = Masked(Cartesian(), mask, coord.flatten())

    xcenter = fun.pinv(coord)

    myfunc = QFunc(atoms, atoms.get_calculator())

    myfunc = Memoize(myfunc, DirStore("cache.d"))

    myfunc = compose(myfunc, fun)

    pmapc = pwrapper(pmap)
    func = fwrapper(myfunc, startdir=startdir, mask=mask, workhere=workhere)

    # the derivatives are needed
    hessian = derivatef(func, xcenter, pmap=pmapc, **kwargs)

    # save is assumend to be a filename, so far only the hessian is saved:
    if save is not None:
        savetxt(save, hessian)

    mass = mass_matrix(atoms.get_masses(), mask)

    freqs, modes = vibmod(mass, hessian)

    # the output will be printed on demand, with modes if wanted
    # the output for the freqs can easily be recreated later on, but
    # for the mode vectors the mass (not included in the direct output_
    # is needed
    if VERBOSE or give_output == 2:
        output(freqs, modes, mass, mask)
    elif give_output == 1:
        output(freqs)

    return freqs, modes
Exemple #2
0
def vibmodes(atoms, startdir=None, mask=None, workhere=False, save=None, give_output = 0, pmap = pmap3, **kwargs):
    """
    Wrapper around vibmode, which used the atoms objects
    The hessian is calculated by derivatef
    qfunc.fwrapper is used as a wrapper to calulate the gradients
    """
    from pts.memoize import Memoize, DirStore
    coord = atoms.get_positions()

    if mask == None:
        mask = constraints2mask(atoms)

    if mask == None: # (if still None)
        fun = Cartesian()
    else:
        fun = Masked(Cartesian(), mask, coord.flatten())

    xcenter = fun.pinv(coord)

    myfunc = QFunc(atoms, atoms.get_calculator())

    myfunc = Memoize(myfunc, DirStore("cache.d"))

    myfunc = compose( myfunc, fun)

    pmapc = pwrapper(pmap)
    func = fwrapper(myfunc, startdir = startdir, mask = mask, workhere = workhere)

    # the derivatives are needed
    hessian = derivatef( func, xcenter, pmap = pmapc, **kwargs)

    # save is assumend to be a filename, so far only the hessian is saved:
    if save is not None:
        savetxt(save, hessian)

    mass = mass_matrix (atoms.get_masses(), mask)

    freqs, modes = vibmod(mass, hessian)

    # the output will be printed on demand, with modes if wanted
    # the output for the freqs can easily be recreated later on, but
    # for the mode vectors the mass (not included in the direct output_
    # is needed
    if VERBOSE or give_output == 2:
        output(freqs, modes, mass, mask)
    elif give_output == 1:
        output(freqs)


    return freqs, modes
Exemple #3
0
def main(argv):
    format = None
    zmat = None

    while argv[0].startswith("--"):
        if argv[0] == '--format':
            format = argv[1]
            argv = argv[2:]
        elif argv[0] == '--zmatrix':
            __, zmat, v_name, __, __, __, __ = read_zmt_from_file(argv[1])
            argv = argv[2:]
        elif argv[0] == '--help':
            print __doc__
            return

    geo1 = read(argv[0], format=format)
    geos = [read(arg, format=format) for arg in argv[1:]]

    if zmat == None:
        fun = Cartesian()
    else:
        fun = ZMat(zmat)

    symbols = geo1.get_chemical_symbols()
    assert len(geos) > 0

    for geo in geos:
        assert geo.get_chemical_symbols() == symbols
        compare(geo1.get_positions(), geo.get_positions(), symbols, fun)
Exemple #4
0
def read_path_fix(symbfile, zmatifiles = None, maskfile = None, maskedgeo = None):
    """
    If not stored in a pickle.path it does not makes too much sense to give
    unchangeable things for every geoemtry, thus separate them

    Here the symbols (define the system) are read in, the function to tranform into cartesian
    is also generated, uses zmat files to build the same system as before, if the coordinates
    are with a mask, here is the possibility to set this also
    """
    # loadtxt (and especially savetxt) do not seems to like strings
    f = open(symbfile, "r")
    sr = f.read()
    f.close()
    symbols = sr.split()


    if len(zmatifiles)==0:
        trafo = Cartesian()
    else:
        trafo, __, __, __, __ = get_transformation(zmatifiles, len(symbols) * 3, "direct")

    if maskfile is not None:
        assert (maskedgeo is not None)
        f = open(maskfile, "r")
        sr = f.read()
        f.close()
        mask = get_mask(sr)
        geo_raw = loadtxt(maskedgeo)
        trafo = Masked(trafo, mask, geo_raw)

    return symbols, trafo
Exemple #5
0
def get_geos(geos, dc, zmi):
    """
    Creates the inital path, the atoms object and the
    function for changing between internal and Cartesian
    (Cartesian to be fed into atoms object)
    """
    at, geo_carts = get_cartesian_geos(geos, dc)
    # RETURN POINT: only Cartesian geometry
    if zmi == []:
        geo_int = array([ge.flatten() for ge in geo_carts])
        return at, geo_int, Cartesian(), [[]], [False], [
            len(geo_carts[0].flatten())
        ], None

    func, d_nums, quats, size_nums, mask1 = get_transformation(
        zmi, len(geo_carts[0].flatten()), dc["zmt_format"])
    # transform Cartesians to internals (all functions used
    # till know have pseudoinverse)
    geo_int = [func.pinv(geo) for geo in geo_carts]
    return at, geo_int, func, d_nums, quats, size_nums, mask1
Exemple #6
0
def make_uranyl(x, flexible=6):
    """
    Return the "best" linear approximation to the uranyl geometry as a
    Fixed() func.
    """
    from pts.zmat import ZMat

    # Make uranyl linear:
    zmt = ZMat([(None, None, None), (1, None, None), (1, 2, None)], base=1)

    # Bond length and the bond angle for uranyl, use the same Z-matrix
    # for uranyl:
    s = zmt.pinv(x)

    # Set the bond  lengths equal and 180 degrees  angle. Note that if
    # you plug these internal variables into z-matrix you will not get
    # zmt(s) ~  x even when s was  derived from x. That  is because of
    # the default orientation z-matrix chooses:
    s_bond = 1.79  # A or sum (s[:2]) / 2
    s = [s_bond, s_bond, pi]

    # Uranyl  may or  may not  be  fixed, but  to adjust  orientation,
    # rotate a rigid object:
    Y = Rigid(zmt(s))
    y = Y(Y.pinv(x))

    if flexible == 0:
        return Fixed(y)  # 0 dof
    elif flexible == 2:
        # liear uranyl with flexible bonds:
        def f(x):
            ra, rb = x
            return array([[0., 0., 0.], [0., 0., ra], [0., 0., -rb]])

        return Affine(f, array([0., 0.]))  # 2 dof
    elif flexible == 6:
        # return Move (relate (x, zmt (s)), zmt)
        return ManyBody(Fixed(x[0:1]), Cartesian(x[1:3]), dof=[0, 6])
    else:
        assert False
Exemple #7
0
def get_transformation(zmi, len_carts, zmt_format):
    # extract data from (several) zmatrices
    if zmt_format == "gx":
        datas = [read_zmt_from_gx(zm) for zm in zmi]
    elif zmt_format == "gauss":
        datas = [read_zmt_from_gauss(zm) for zm in zmi]
    else:
        datas = [read_zmt_from_file(zm) for zm in zmi]

    names, zmat, var_nums, mult, d_nums, size_sys, size_nums, size_carts, mask1 = restructure(
        datas)

    # decide if global positioning is needed
    # it is needed if there are more than one option, first one checks for
    # if there are cartesian coordinates
    with_globs = (len_carts > size_sys) or len(zmat) > 1
    # gx mask, only valid if gx's zmat is for complete system
    if with_globs:
        mask1 = None
    else:
        mask1 = mask1[0]

    # first only the zmatrix functions, allow multiple use of variables
    funcs = []
    quats = []

    # build function for every zmatrix
    for i, zm, va_nm, mul in zip(range(len(var_nums)), zmat, var_nums, mult):
        fun = ZMat(zm)

        # some variables are used several times
        if mul > 0:
            fun = With_equals(fun, va_nm)

        # global positioning needed
        if with_globs:
            fun = With_globals(fun)
            quats.append(True)
            # attention, this changes number of internal coordinates
            # belonging to this specific zmatrix
            size_nums[i] = size_nums[i] + 6
        else:
            quats.append(False)

        funcs.append(fun)

    # if not all variables are used up, the rest are in Cartesians
    if len_carts > size_sys:
        funcs.append(Cartesian())
        # there is also some need to specify their sizes
        size_nums.append(len_carts - size_sys)
        size_carts.append(len_carts - size_sys)
        quats.append(False)
        d_nums.append([])

    # how many atoms per single function
    # needed for Mergefuncs.pinv
    size_carts = [s / 3. for s in size_carts]

    # now merge the functions to one:
    if len(size_nums) > 1:
        func = Mergefuncs(funcs, size_nums, size_carts)
    else:
        # no need to merge a single function
        func = funcs[0]

    return func, d_nums, quats, size_nums, mask1
Exemple #8
0

    # Here the different ways of using the different functions are given
    if choice == 0:
        """
        Cartesian is used for only rearranging the input variables.
        From our functions we expect ouput of the three Cartesian coordinates
        for each atom in an array of the kind (N, 3)

        For further use in our pathsearcher we need the function itself
        and the two minima

        Cartesian expects its input vector to be a one-dimensional array, as
        does pathsearcher.
        """
        func = Cartesian()
        min1 = func.pinv(m1)
        min2 = func.pinv(m2)

    elif choice == 1:
        """
        It is intended for real internal coordinates: but works with every function:
        With_globals adds paramter for global rotation and translation.
        Notice that here the start geometries have 6 parameter more each.
        The first three of them describe an quaternion (or the vector v of unit quaternion
        e^iv. The rotation by this is obtained to every atom alone.
        The other three describe the global translation.
        """
        func = With_globals(Cartesian())

        # Trick as there are not enough coordinates to revert them
Exemple #9
0
    """
    func = diagsandhight()

    der = 1.0
    #       diag1, diag2, hight
    min1 = [td_s, td_s, td_s / sqrt(2.)]
    min2 = [td_s, td_s, -td_s / sqrt(2.)]
    middle = [td_s * der, td_s * sqrt(4. - der**2.) , 0.]

elif testfun == "carts":
    """
    The  starting  geometries  are  provided  by  the  diag  and  high
    function.  See case "diaghigh".  The optimization and else is done
    in Cartesian coordinates.
    """
    func = Cartesian()

    # generate   starting  geometries  with   the  help   of  function
    # diagsandhight:
    func_h = diagsandhight()
    min1 = func_h(asarray([td_s, td_s, td_s / sqrt(2.)])).flatten()
    min2 = func_h(asarray([td_s, td_s, -td_s / sqrt(2.)])).flatten()
    middle = func_h(asarray([td_s, td_s * sqrt(3.) , 0.])).flatten()

elif testfun == "cartsred":
    """
    Same starting situation as in case "carts", only that in this case
    some coordinates are fixed (y,z) direction for first two atoms and
    (x) for the last two.
    """
    func2 = Cartesian()
Exemple #10
0
           , lwave  = False
           , kpts   = (5,5,1)
           )

# Atoms object needs to have all these in order to be able to run correctly:
PdH.set_calculator(calculator)
PdH.set_pbc(True)
sc =  5.59180042562320832916
cell =  [[1.0000000000000000,  0.0000000000000000,  0.0000000000000000],
         [0.5000000000000000,  0.8660254037844386,  0.0000000000000000],
         [0.0000000000000000,  0.0000000000000000,  1.0000000000000000]]
cell = array(cell) * sc
PdH.set_cell(cell)

# Do calculation in Cartesian coordinates
fun1 = Cartesian()

# PES in cartesian coordiantes:
pes = QFunc(PdH, PdH.get_calculator())

def reduce(vec, mask):
    """
    Function for generating starting values.
    Use a mask to reduce the complete vector.
    """
    vec_red = []
    for i, m in enumerate(mask):
         if m:
             vec_red.append(vec[i])
    return array(vec_red)