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 exchange(s):
    # Functions of cartesian coordinates:
    ra = Distance([0, 3])
    rb = Distance([0, 18])
    # rc = Difference (ra, rb)
    rc = ra
    f0 = Server(cmd)
    h0 = Server(alt)
    F0 = QFunc(atoms, ParaGauss(cmdline=qmd, input="6w,c1.scm"))
    with f0 as f0, h0 as h0, F0 as F0:
        f1 = Memoize(f0, DirStore(salt=cmd + "TESTING"))
        h1 = Memoize(h0, DirStore(salt=alt + "TESTING"))
        F1 = Memoize(F0, DirStore(salt=qmd + "XXX4 50/291"))

        # A  Func  of cartesian  coordinates,  stretching and  bending
        # parameters  as  tuples.  Parameters  not  hashed, beware  of
        # memoization of this term!:
        if uo2 is not None:
            f1 = f1 + uo2

        f = compose(f1, trafo)
        h = compose(h1, trafo)
        c = compose(rc, trafo)
        F = compose(F1, trafo)
        B = compose(bias, trafo)

        refine = True
        if False:
            ss = loadtxt("ss,initial.txt")
            qs = array(map(c, ss))
            print("qs=", qs)
            print("dq=", qs[1:] - qs[:-1])
            if False:
                P = Path(ss, qs)
                C = compose(c, P)
                print("q=", qs)

                def solve(q):
                    x = q
                    while abs(C(x) - q) > 1.0e-10:
                        f, fprime = C.taylor(x)
                        df = f - q
                        x = x - df / fprime
                    return x

                xs = []
                for q in linspace(qs[0], qs[-1], 21):
                    x = solve(q)
                    print("x=", x, "C(x)=", C(x), "q=", q)
                    xs.append(x)
                ss = array(map(P, xs))
                qs = array(map(c, ss))
                print("qs=", qs)
                print("dq=", qs[1:] - qs[:-1])
            p = Path(ss, qs)

        if False:
            qs, ss = initial_path(f + B, s, c)
            savetxt("ss-initial.txt", ss)
            p = Path(ss, qs)

        if False:
            for i, q in enumerate(qs):
                write_xyz("in-%03d.xyz" % i, trafo(p(q)))

        if False:
            # Energy profile, smooth:
            with open("profile-initial.txt", "w") as file:
                print("# q, ra(q), rb(q), E(q), E_qm(q), B(q)", file=file)
                for q in linspace(qs[0], qs[-1], 100):
                    print(q,
                          ra(trafo(p(q))),
                          rb(trafo(p(q))),
                          f(p(q)),
                          B(p(q)),
                          file=file)

        if False:
            # Energy profile, coarse, with dG(q):
            with open("./profile,intial.txt", "w") as file:
                print("# q, ra(q), rb(q), F(q)", file=file)
                # print ("# q, ra(q), rb(q), E(q), dG(q), F(q)", file=file)
                for q in qs:
                    print(q,
                          ra(trafo(p(q))),
                          rb(trafo(p(q))),
                          F(p(q)),
                          file=file)
                    # print (q, ra (trafo (p(q))), rb (trafo (p (q))), f(p(q)), h(p(q)), F(p(q)), file=file)

        # with f + h as e:
        with F + h + B as e:
            print("XXX")
            if False:
                p1 = Path(loadtxt("sxy.txt", ndmin=2))
                c1 = compose(c, p1)
                q1 = linspace(0., 1., 21)
                for i, q in enumerate(q1):
                    write_xyz("interp-%03d.xyz" % i, trafo(p1(q)))
                print("c=", [c1(q) for q in q1])
                Q1 = Inverse(c1)
                q2 = [Q1(c_) for c_ in [3.05]]
                print("q=", q2, "c=", [c1(q) for q in q2])
                s2 = array([p1(q) for q in q2])
                savetxt("sxy1.txt", s2)
                exit(0)

            def opt(s):
                sm, info = minimize(e,
                                    s,
                                    maxit=50,
                                    ftol=1.0e-2,
                                    xtol=1.0e-2,
                                    algo=1)
                print("converged=", info["converged"], "in",
                      info["iterations"])
                return sm

            if True:
                # Unconstrained termnals:
                sab = loadtxt("sab,initial.txt", ndmin=2)
                # sab = (ss[0], ss[-1])

                print("before: q=", map(c, sab))
                sab = map(opt, sab)
                print("after: q=", map(c, sab))
                savetxt("sab.txt", sab)

                for i, s in enumerate(sab):
                    write_xyz("min-%03d.xyz" % i, trafo(s))
                exit(0)

            def copt(s, maxit):
                sm, info = cminimize(e,
                                     s,
                                     Array(c),
                                     maxit=maxit,
                                     ftol=1.0e-3,
                                     xtol=1.0e-3,
                                     algo=0)
                print("converged=", info["converged"], "in",
                      info["iterations"])
                return sm

            maxit = [30] * len(ss)
            ss = array(map(copt, ss, maxit))
            savetxt("ss.txt", ss)

            # Energy profile:
            with open("./profile,rs.txt", "w") as file:
                print("# Optimized profile:", file=file)
                # print (qa, f(sa), h(sa), e(sa), file=file)
                for q, s in zip(qs, ss):
                    print(q, f(s), h(s), e(s), file=file)
                # print (qb, f(sb), h(sb), e(sb), file=file)

            for i, s in enumerate(ss):
                write_xyz("KH-%03d.xyz" % i, trafo(s))

            if False:
                p = Path(ss, qs)
                with open("./profile,rs,interp.txt", "w") as file:
                    print("# Interpolated profile:", file=file)
                    for q in linspace(qs[0], qs[-1], 3 * len(qs)):
                        print(q, f(p(q)), h(p(q)), e(p(q)), file=file)
Exemple #3
0
#
# Build  a  Func  of  cartesian coordinates,  stretching  and  bending
# parameters as tuples.  Parameters not hashed, beware of memoization!
#
if flexible != 0:
    from pts.pes.ab2 import AB2
    # Base units here: A, radians, eV:
    if True:
        # PM13 soft uranyl:
        uo2 = AB2((1.76, 64.50), (pi, 2.05))  # Ref. [1]
    if False:
        # KL13 aka GW hard uranyl:
        uo2 = AB2((1.80, 43.364), (pi, 13.009))  # Ref. [2]
    if False:
        print("CMDLINE=", qmd)
        uo2 = QFunc(atoms, ParaGauss(cmdline=qmd, input="6w,c1.scm"))
else:
    uo2 = None


def test_uranyl():
    e = compose(uo2, uranyl)
    e = Memoize(e, DirStore(salt="XXX YYY"))
    # s = array ([1.79, 1.79, pi])
    s = zeros(6)  # + 0.1
    print(uranyl(s))
    # print (e(s))
    # exit (0)
    sm, info = minimize(e, s, ftol=1.0e-2, xtol=1.0e-2, algo=1)
    print(uranyl(sm))
    print("e(0)=", e(s), "e(1)=", e(sm), "iterations=", info["iterations"])
Exemple #4
0
def pathsearcher(atoms, init_path, trafo, **kwargs):
    """
    MUSTDIE: from  python code use  a PES method  find_path(pes, path,
             ...), for command  line there is call_with_pes(find_path,
             sys.argv[1:])   See   call_with_pes()   and   find_path()
             instead.

    Only used in ./tests.

    It  is possible  to use  the pathsearcher()  function in  a python
    script. It looks like:

      from pts.inputs import pathsearcher

      pathsearcher(atoms, init_path, trafo, **kwargs)

    * atoms is  an ASE atoms object  used to calculate  the forces and
      energies of a given (Cartesian) geometry. Be aware that it needs
      to have an  calculator attached to it, which  will do the actual
      transformation.  Another possibility is  to give the calculator
      separately as an option.

    * init_path is an array containting  for each bead of the starting
      path the internal coordinates.

    * trafo is a Func to transform internal to Cartesian coordinates.

    * the other  parameters give the possibility to  overwrite some of
      the default behaviour of the module, They are provided as kwargs
      in here.  For a list  of them see  defaults.py They can  be also
      specified in an input file given as paramfile.
    """
    # most parameters are stored in a dictionary, default parameters are stored in
    # defaults.py
    para_dict = create_params_dict(kwargs)

    # calculator from kwargs, if valid, has precedence over
    if "calculator" in para_dict:
        # the associated (or not) with the atoms:
        if para_dict["calculator"] is not None:
            atoms.set_calculator(para_dict["calculator"])

        # calculator is not used below:
        del para_dict["calculator"]

    # print parameters to STDOUT:
    tell_params(para_dict)

    #
    # PES to be used for  energy, forces. FIXME: maybe adapt QFunc not
    # to default to LJ, but rather keep atoms as is?
    #
    pes = QFunc(atoms, atoms.get_calculator())

    #
    # Memoize early, PES as a function of cartesian coordiantes is the
    # lowest  denominator.  The  cache  store used  here should  allow
    # concurrent writes  and reads from  multiple processes eventually
    # running on different nodes  --- DirStore() keeps everything in a
    # dedicated directory on disk or on an NFS share:
    #
    pes = Memoize(pes, DirStore("cache.d"))

    #
    # PES as  a funciton of  optimization variables, such  as internal
    # coordinates:
    #
    pes = compose(pes, trafo)

    # This parallel mapping function puts every single point calculation in
    # its own subfolder
    strat = Strategy(para_dict["cpu_architecture"], para_dict["pmin"], para_dict["pmax"])
    del para_dict["cpu_architecture"]
    del para_dict["pmin"]
    del para_dict["pmax"]
    if "pmap" not in para_dict:
        para_dict["pmap"] = PMap3(strat=strat)

    para_dict["trafo"] = trafo
    para_dict["symbols"] = atoms.get_chemical_symbols()

    # this operates with PES in internals:
    convergence, optimized_path = find_path(pes, init_path, **para_dict)

    # print user-friendly output, including cartesian geometries:
    output(optimized_path, trafo, para_dict["output_level"], para_dict["output_geo_format"], atoms)

    return convergence, optimized_path
Exemple #5
0
def call_with_pes(method, args):
    """
    Interprete  command line  args and  call a  method() with  PES and
    other input  constructed according to  the command line.  A method
    should have an interface as

        method(pes, geometries, **kw)

    Return value(s) of the method are passed up the caller chain. Most
    path searcher algorithms can be made to fit this interface.

    For  use in  scripts. Note  that args  is a  list of  strings from
    sys.args.

    To invoke a method(pes, path, **rest) do this:

        from pts.path_searcher import call_with_pes

        results = call_with_pes(method, sys.argv[1:])

    The  rest  is  a  slightly   misplaced  doc  copied  from  a  more
    specialized code:

    * atoms is  an ASE atoms object  used to calculate  the forces and
      energies of a given (Cartesian) geometry. Be aware that it needs
      to have an  calculator attached to it, which  will do the actual
      transformation.  Another possibility is  to give a file in which
      calculator is  specified separately as  parameter.  (FIXME: this
      another possibility is vaguely specified)

    * geometries is an array containting for each bead of the starting
      path the internal coordinates.

    * trafo is a Func to transform internal to Cartesian coordinates.

    * the other  parameters give the possibility to  overwrite some of
      the default behaviour of the module, They are provided as kwargs
      in here.  For a list  of them see  defaults.py They can  be also
      specified in an input file given as paramfile.
    """

    # this interpretes the command line:
    atoms, geometries, trafo, kwargs = interprete_input(args)

    # most parameters  are stored in a  dictionary, default parameters
    # are stored in defaults.py
    kw = create_params_dict(kwargs)

    # calculator from kwargs, if valid, has precedence over
    if "calculator" in kw:
        # the associated (or not) with the atoms:
        if kw["calculator"] is not None:
            atoms.set_calculator(kw["calculator"])

        # calculator is not used below:
        del kw["calculator"]

    #
    # Print parameters  to STDOUT.  This  was a habit when  doing path
    # searcher calculations.  So for  backwards compatibility do it in
    # this  case, but  only in  this case  (unless a  yet non-existent
    # command line option requires that explicitly):
    #
    if method is pes_method:
        tell_params(kw)

    #
    # PES to be used for  energy, forces. FIXME: maybe adapt QFunc not
    # to default to LJ, but rather keep atoms as is?
    #
    pes = QFunc(atoms, atoms.get_calculator())

    #
    # Memoize early, PES as a function of cartesian coordiantes is the
    # lowest  denominator.  The  cache  store used  here should  allow
    # concurrent writes  and reads from  multiple processes eventually
    # running on different nodes  --- DirStore() keeps everything in a
    # dedicated directory on disk or on an NFS share:
    #
    pes = Memoize(pes, DirStore("cache.d"))

    #
    # PES as  a funciton of  optimization variables, such  as internal
    # coordinates:
    #
    pes = compose(pes, trafo)

    # This parallel mapping function puts every single point calculation in
    # its own subfolder
    if "pmap" not in kw:
        strat = Strategy(kw["cpu_architecture"], kw["pmin"], kw["pmax"])
        kw["pmap"] = PMap3(strat=strat)

    del kw["cpu_architecture"]
    del kw["pmin"]
    del kw["pmax"]

    # some methds think they need to know atomic details of the PES:
    kw["atoms"] = atoms
    kw["trafo"] = trafo
    kw["symbols"] = atoms.get_chemical_symbols()

    # this operates with PES in internal variables:
    return method(pes, geometries, **kw)
Exemple #6
0
def read_dimer_input(rest, name):
    """
    This function is similar to the one for pathsearcher
    """
    from pts.ui.read_inputs import from_params_file
    from pts.ui.read_COS import geo_params
    from pts.defaults import are_strings
    from pts.common import file2str
    from pts.func import compose
    from pts.qfunc import QFunc
    from pts.memoize import Memoize, FileStore
    from pts.defaults import di_default_params, qn_default_params, ln_default_params
    from pts.trajectories import dimer_log
    from pts.defaults import di_default_params, qn_default_params, di_default_params_rot
    #This variables will be needed afterwards anyway
    # independent of beeing given by user
    geo_dict = {"format": None, "zmt_format": "direct"}
    add_param = {}
    paramfile = None
    zmatrix = []
    geo = None
    mode = None
    as_pickle = False
    ts_estim = None
    accept_all = False

    give_help_if_needed(rest, name)

    if rest[0] == "--accept_all":
        rest = rest[1:]
        accept_all = True

    defaults_available = True
    if name in ["dimer"]:
        default_params = di_default_params
    elif name in ["lanczos"]:
        default_params = ln_default_params
    elif name in ["lanczos-rotate", "dimer-rotate"]:
        default_params = di_default_params_rot
    elif name in ["qn", "simple_qn", "quasi-newton"]:
        default_params = qn_default_params
    else:
        print >> stderr, "WARNING: No default parameter for specific method found"
        print >> stderr, "         There will be no test if the given parameter make sense"
        default_params = {}
        accept_all = True
        defaults_available = False

    if "--defaults" in rest:
        if defaults_available:
            print "The default parameters for the algorithm ", name, " are:"
            for param, value in default_params.iteritems():
                print "    %s = %s" % (str(param), str(value))
        else:
            print "No default values available for the specific method", name
        exit()

    for i in range(len(rest)):
        if rest == []:
            break

        # filter out all the options
        if rest[0].startswith("--"):
            o = rest[0][2:]
            a = rest[1]
            # filter out the special ones
            if o == "paramfile":
                # file containing parameters
                paramfile = file2str(a)
            elif o in ("zmatrix"):
                # zmatrix if given separate to the geometries
                zmatrix.append(a)
            elif o in ("pickle"):
                as_pickle = True
                ts_estim = a
            elif o in geo_params:
                # only needed to build up the geometry
                if o in ("mask"):
                    # needed to build up the geometry and wanted for params output
                    geo_dict[o] = get_mask(a)
                elif o in ("cell", "pbc"):
                    geo_dict[o] = eval(a)
                else:
                    geo_dict[o] = a
            else:
                # suppose that the rest are setting parameters
                # we do not have a complete list of them
                if not accept_all:
                    assert o in default_params or o == "rot_method", "Parameter %s" % (
                        o)

                if o in are_strings:
                    add_param[o] = a
                else:
                    add_param[o] = eval(a)
            rest = rest[2:]
        else:
            # This two files are needed any way: one geometry file and one
            # for the modevector, expect the geoemtry file to be given first
            if geo == None:
                # For reusing pathsearcher routines with several geoemtries for input
                geo = [rest[0]]
            else:
                mode = rest[0]
            rest = rest[1:]

    if paramfile == None:
        params_dict = add_param
        geo_dict_dim = geo_dict
    else:
        if accept_all:
            params_dict, geo_dict_dim = from_params_file_dimer(paramfile)
        else:
            params_dict, geo_dict_dim = from_params_file(
                paramfile, default_params)
        params_dict.update(add_param)
        geo_dict_dim.update(geo_dict)

    if as_pickle:
        start_geo, init_mode, funcart, atoms = read_from_pickle(
            geo[0], ts_estim, geo_dict_dim)
    else:
        start_geo, funcart, atoms = build_new(geo, geo_dict_dim, zmatrix)
        if name in ["lanczos", "dimer", "lanczos-rotate", "dimer-rotate"]:
            init_mode = build_mode(mode, start_geo, funcart)
        else:
            assert mode == None
            init_mode = None

    # Build up the qfunc, calculator is included in atoms already
    pes = compose(QFunc(atoms, calc=atoms.get_calculator()), funcart)

    if "cache" in params_dict:
        if params_dict["cache"] == None:
            pes = Memoize(pes, FileStore("%s.ResultDict.pickle" % (name)))
        else:
            pes = Memoize(pes, FileStore(params_dict["cache"]))
    else:
        pes = Memoize(pes, FileStore("%s.ResultDict.pickle" % (name)))

    #Attention inital mode need not be normed (and cannot as metric is not yet known)
    return pes, start_geo, init_mode, params_dict, atoms, funcart
Exemple #7
0
"""
#test_what = "contraforce"

# specify which testfunction == first input argument
try:
    testfun = argv[1]
except IndexError:
    testfun = "zmat"

# The ASE atoms object for calculating the forces
ar4 = Atoms("Ar4")

ar4.set_calculator(LennardJones())

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

# some variables for the starting values
# length
var1 = 1.12246195815

# and angles (in rad)
var3 = 60.0 / 180. * pi
var4 = 70.5287791696 / 180. * pi
var6 = 59.0020784259 / 180. * pi
var7 = 60.4989607871 / 180 * pi
var8 = pi

td_s = var1

def reduce(vec, mask):
Exemple #8
0
x = atoms.get_positions()

#
# Z-matrix for water:
#
zmt = ZMat([(None, None, None), (1, None, None), (1, 2, None)], base=1)

#
# Initial values of internal coordinates:
#
s = zmt.pinv(x)
assert max(abs(s - zmt.pinv(zmt(s)))) < 1.0e-10

clean()

with QFunc(atoms, calc) as f:
    f = Memoize(f, DirStore(salt="h2o, qm"))
    e = compose(f, zmt)

    print s, e(s)
    s, info = minimize(e, s, algo=1, ftol=1.0e-2, xtol=1.0e-2)
    print s, e(s), info["converged"]

#
# Internal coordinates:
#
# In:  0.97843364  0.97826543  1.87152024
# Out: 0.98477091  0.98477695  1.88111918
#
# Rigid water with optimized internal coordinates:
#
Exemple #9
0
# 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)

# The starting geometries in flattened Cartesian coordinates
min1 = array([ 1.3979501064058020,  0.8071068702470560,  1.0232994778890470,
  0.0000000000000000, 0.0000000000000000, 0.0000000000000000,