Exemplo n.º 1
0
def kineticEnergy(prefix, temp, ss=0, unit=""):
    """
    Computes the virial centroid estimator for the kinetic energy and PPI correction.
    """

    # Adding fortran functions (when exist)
    sys.path.append(os.path.abspath(os.path.dirname(sys.argv[0]))[:-2] + "f90")
    fast_code = True
    try:
        import fortran
    except ImportError:
        fast_code = False
        print(
            "WARNING: No compiled fortran module for fast calculations have been found.\n"
            "Calculations will use a slower python script.")

    temperature = unit_to_internal("temperature", "kelvin",
                                   float(temp))  # simulation temperature
    skipSteps = int(ss)  # steps to skip for thermalization

    f2_av, KPa_av, KVir_av, f2KPa_av = 0.0, 0.0, 0.0, 0.0  # some required sums

    fns_pos = sorted(glob.glob(prefix + ".pos*"))
    fns_for = sorted(glob.glob(prefix + ".for*"))
    fns_iU = glob.glob(prefix + ".out")[0]
    fn_out_en = prefix + ".kinetic_energy.dat"

    # check that we found the same number of positions and forces files
    nbeads = len(fns_pos)
    if nbeads != len(fns_for):
        print(fns_pos)
        print(fns_for)
        raise ValueError(
            "Mismatch between number of input files for forces and positions.")

    # print some information
    print("temperature = {:f} K".format(float(temp)))
    print()
    print("number of beads = {:d}".format(nbeads))
    print()
    print("positions and forces file names:")
    for fn_pos, fn_for in zip(fns_pos, fns_for):
        print("{:s}   {:s}".format(fn_pos, fn_for))
    print()
    print("potential energy file: {:s}".format(fns_iU))
    print()
    print("output file name:")
    print(fn_out_en)
    print()

    # open input and output files
    ipos = [open(fn, "r") for fn in fns_pos]
    ifor = [open(fn, "r") for fn in fns_for]
    iU = open(fns_iU, "r")
    iE = open(fn_out_en, "w")

    # Some constants
    beta = 1.0 / (Constants.kb * temperature)
    const_1 = 0.5 * nbeads / (beta * Constants.hbar)**2
    const_2 = 1.5 * nbeads / beta
    const_3 = 1.5 / beta
    const_4 = Constants.kb**2 / Constants.hbar**2
    const_5 = Constants.hbar**2 * beta**3 / (24.0 * nbeads**3)

    timeUnit, potentialEnergyUnit, time_index = extractUnits(
        iU)  # extracting simulation time
    # and potential energy units

    # Defining the output energy unit
    if unit == "":
        unit = potentialEnergyUnit

    iE.write(
        "# Simulation time (in %s), virial kinetic energy and PPI kinetic energy corrections (in %s)\n"
        % (timeUnit, unit))

    natoms = 0
    ifr = 0
    time0 = 0
    q, f, m = None, None, None
    while True:  # Reading input files and calculating PPI correction

        if ifr % 100 == 0:
            print("\rProcessing frame {:d}".format(ifr), end=" ")
            sys.stdout.flush()

        try:
            for i in range(nbeads):
                ret = read_file("xyz", ipos[i], output="arrays")
                if natoms == 0:
                    m, natoms = ret["masses"], ret["natoms"]
                    q = np.zeros((nbeads, 3 * natoms))
                    f = np.zeros((nbeads, 3 * natoms))
                q[i, :] = ret["data"]
                f[i, :] = read_file("xyz", ifor[i], output="arrays")["data"]
            time = read_time(iU, time_index)
        except EOFError:  # finished reading files
            sys.exit(0)

        if ifr < skipSteps:

            time0 = time

        if ifr >= skipSteps:  # PPI correction

            time -= time0

            KPa, f2, KVir = 0.0, 0.0, 0.0

            if not fast_code:

                for j in range(nbeads):
                    for i in range(natoms):
                        f2 += (np.dot(f[j, i * 3:i * 3 + 3],
                                      f[j, i * 3:i * 3 + 3]) / m[i])
                for i in range(natoms):
                    KPa -= (np.dot(
                        q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3],
                        q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3],
                    ) * m[i])
                for j in range(nbeads - 1):
                    for i in range(natoms):
                        KPa -= (np.dot(
                            q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3],
                            q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3],
                        ) * m[i])
                rc = np.zeros(3)
                for i in range(natoms):
                    rc[:] = 0.0
                    for j in range(nbeads):
                        rc[:] += q[j, i * 3:i * 3 + 3]
                    rc[:] /= nbeads
                    for j in range(nbeads):
                        KVir += np.dot(rc[:] - q[j, i * 3:i * 3 + 3],
                                       f[j, i * 3:i * 3 + 3])

                KPa *= const_1
                KPa += const_2 * natoms
                KVir /= 2.0 * nbeads
                KVir += const_3 * natoms

            else:

                f2 = fortran.f2divm(np.array(f, order="F"),
                                    np.array(m, order="F"), natoms, nbeads)
                KPa = fortran.findcoupling(
                    np.array(q, order="F"),
                    np.array(m, order="F"),
                    temperature,
                    natoms,
                    nbeads,
                )
                KVir = fortran.findcentroidvirialkineticenergy(
                    np.array(f, order="F"), np.array(q, order="F"), natoms,
                    nbeads)

                KPa *= const_4
                KPa += const_2 * natoms
                KVir += const_3 * natoms

            f2_av += f2
            KPa_av += KPa
            f2KPa_av += f2 * KPa
            KVir_av += KVir
            ifr += 1

            norm = float(ifr - skipSteps)

            dK = (Constants.kb * temperature +
                  KPa_av / norm) * f2_av / norm - f2KPa_av / norm
            dK *= const_5

            dK = unit_to_user("energy", unit, dK)
            eVir = unit_to_user("energy", unit, KVir_av / norm)

            iE.write("%f    %f     %f\n" % (time, eVir, dK))

        else:
            ifr += 1
Exemplo n.º 2
0
def heatCapacity(prefix, temp, ss=0):
    """
    Computes a primitive estimator for the heat capacity and PPI correction.
    """

    # Adding fortran functions (when exist)
    sys.path.append(os.path.abspath(os.path.dirname(sys.argv[0]))[:-2] + "f90")
    fast_code = True
    try:
        import fortran
    except ImportError:
        fast_code = False
        print(
            "WARNING: No compiled fortran module for fast calculations have been found.\n"
            "Calculations will use a slower python script."
        )

    temperature = unit_to_internal(
        "temperature", "kelvin", float(temp)
    )  # simulation temperature
    skipSteps = int(ss)  # steps to skip for thermalization

    # some required sums
    KPa_av, U_av, f2_av, f2KPa_av, f2U_av, E2_av, f2E_av, f2E2_av = (
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
    )

    fns_pos = sorted(glob.glob(prefix + ".pos*"))
    fns_for = sorted(glob.glob(prefix + ".for*"))
    fns_iU = glob.glob(prefix + ".out")[0]
    fn_out_en = prefix + ".heat_capacity.dat"

    # check that we found the same number of positions and forces files
    nbeads = len(fns_pos)
    if nbeads != len(fns_for):
        print(fns_pos)
        print(fns_for)
        raise ValueError(
            "Mismatch between number of input files for forces and positions."
        )

    # print some information
    print("temperature = {:f} K".format(float(temp)))
    print()
    print("number of beads = {:d}".format(nbeads))
    print()
    print("positions and forces file names:")
    for fn_pos, fn_for in zip(fns_pos, fns_for):
        print("{:s}   {:s}".format(fn_pos, fn_for))
    print()
    print("potential energy file: {:s}".format(fns_iU))
    print()
    print("output file name:")
    print(fn_out_en)
    print()

    # open input and output files
    ipos = [open(fn, "r") for fn in fns_pos]
    ifor = [open(fn, "r") for fn in fns_for]
    iU = open(fns_iU, "r")
    iC = open(fn_out_en, "w")

    # Some constants
    beta = 1.0 / (Constants.kb * temperature)
    const_1 = 0.5 * nbeads / (beta * Constants.hbar) ** 2
    const_2 = 1.5 * nbeads / beta
    const_3 = Constants.kb ** 2 / Constants.hbar ** 2
    const_4 = Constants.hbar ** 2 * beta ** 2 / (24.0 * nbeads ** 3)
    const_5 = Constants.kb * beta ** 2

    timeUnit, potentialEnergyUnit, potentialEnergy_index, time_index = extractUnits(
        iU
    )  # extracting simulation time
    # and potential energy units

    iC.write(
        "# Simulation time (in %s), improved heat capacity estimator, primitive heat capacity estimator, "
        "and PPI correction for the heat capacity\n" % timeUnit
    )
    iC.close()

    natoms = 0
    ifr = 0
    time0 = 0
    q, f, m = None, None, None
    while True:  # Reading input files and calculating PPI correction

        if ifr % 100 == 0:
            print("\rProcessing frame {:d}".format(ifr), end=" ")
            sys.stdout.flush()

        try:
            for i in range(nbeads):
                ret = read_file("xyz", ipos[i], dimension="length")["atoms"]
                if natoms == 0:
                    m, natoms = ret.m, ret.natoms
                    q = np.zeros((nbeads, 3 * natoms))
                    f = np.zeros((nbeads, 3 * natoms))
                q[i, :] = ret.q
                f[i, :] = read_file("xyz", ifor[i], dimension="force")["atoms"].q
            U, time = read_U(iU, potentialEnergyUnit, potentialEnergy_index, time_index)
        except EOFError:  # finished reading files
            sys.exit(0)

        if ifr < skipSteps:

            time0 = time

        if ifr >= skipSteps:  # PPI correction

            time -= time0

            KPa, f2 = 0.0, 0.0

            if not fast_code:

                for j in range(nbeads):
                    for i in range(natoms):
                        f2 += (
                            np.dot(f[j, i * 3 : i * 3 + 3], f[j, i * 3 : i * 3 + 3])
                            / m[i]
                        )
                for i in range(natoms):
                    KPa -= (
                        np.dot(
                            q[0, i * 3 : i * 3 + 3] - q[nbeads - 1, i * 3 : i * 3 + 3],
                            q[0, i * 3 : i * 3 + 3] - q[nbeads - 1, i * 3 : i * 3 + 3],
                        )
                        * m[i]
                    )
                for j in range(nbeads - 1):
                    for i in range(natoms):
                        KPa -= (
                            np.dot(
                                q[j + 1, i * 3 : i * 3 + 3] - q[j, i * 3 : i * 3 + 3],
                                q[j + 1, i * 3 : i * 3 + 3] - q[j, i * 3 : i * 3 + 3],
                            )
                            * m[i]
                        )

                KPa *= const_1
                KPa += const_2 * natoms

            else:

                f2 = fortran.f2divm(
                    np.array(f, order="F"), np.array(m, order="F"), natoms, nbeads
                )
                KPa = fortran.findcoupling(
                    np.array(q, order="F"),
                    np.array(m, order="F"),
                    temperature,
                    natoms,
                    nbeads,
                )

                KPa *= const_3
                KPa += const_2 * natoms

            f2_av += f2
            KPa_av += KPa
            f2KPa_av += f2 * KPa
            U_av += U
            f2U_av += f2 * U
            E2_av += (KPa + U) ** 2
            f2E2_av += f2 * (KPa + U) ** 2
            ifr += 1

            norm = float(ifr - skipSteps)

            dU = 2 * f2_av / norm - beta * (f2U_av / norm - f2_av * U_av / norm ** 2)
            dU *= const_4

            dK = f2_av / norm - beta * (f2KPa_av / norm - f2_av * KPa_av / norm ** 2)
            dK *= const_4

            C = (
                E2_av / norm
                - ((KPa_av + U_av) / norm) ** 2
                + (2.0 / beta) * KPa_av / norm
                - 1.5 * nbeads * natoms / beta ** 2
            )
            C *= const_5

            dC = (
                2
                * (5 + 3 * beta * (KPa_av + U_av) / norm)
                * beta
                * f2_av
                * const_4
                / norm
                - 2 * (3 + beta * (KPa_av + U_av) / norm) * beta * (dK + dU)
                + 2 * beta * dK
                - const_4 * (f2E2_av / norm - f2_av * E2_av / norm ** 2) * beta ** 3
            )

            iC = open(fn_out_en, "a")
            iC.write("%f    %f     %f     %f\n" % (time, C + dC, C, dC))
            iC.close()

        else:
            ifr += 1
Exemplo n.º 3
0
def energies(prefix, temp, ss=0, unit=''):
    """
    Computes the virial centroid estimator for the total energy and PPI correction.
    """

    # Adding fortran functions (when exist)
    sys.path.append(os.path.abspath(os.path.dirname(sys.argv[0]))[:-2] + 'f90')
    fast_code = True
    try:
        import fortran
    except:
        fast_code = False
        print(
            'WARNING: No compiled fortran module for fast calculations have been found.\n'
            'Calculations will use a slower python script.')

    temperature = unit_to_internal("temperature", "kelvin",
                                   float(temp))  # simulation temperature
    skipSteps = int(ss)  # steps to skip for thermalization

    KPa_av, KVir_av, U_av, f2_av, f2KPa_av, f2U_av = 0.0, 0.0, 0.0, 0.0, 0.0, 0.0  # some required sums

    fns_pos = sorted(glob.glob(prefix + ".pos*"))
    fns_for = sorted(glob.glob(prefix + ".for*"))
    fns_iU = glob.glob(prefix + ".out")[0]
    fn_out_en = prefix + ".energies.dat"

    # check that we found the same number of positions and forces files
    nbeads = len(fns_pos)
    if nbeads != len(fns_for):
        print(fns_pos)
        print(fns_for)
        raise ValueError(
            "Mismatch between number of input files for forces and positions.")

    # print some information
    print('temperature = {:f} K'.format(float(temp)))
    print()
    print('number of beads = {:d}'.format(nbeads))
    print()
    print('positions and forces file names:')
    for fn_pos, fn_for in zip(fns_pos, fns_for):
        print('{:s}   {:s}'.format(fn_pos, fn_for))
    print()
    print('potential energy file: {:s}'.format(fns_iU))
    print()
    print('output file name:')
    print(fn_out_en)
    print()

    # open input and output files
    ipos = [open(fn, "r") for fn in fns_pos]
    ifor = [open(fn, "r") for fn in fns_for]
    iU = open(fns_iU, "r")
    iE = open(fn_out_en, "w")

    # Some constants
    beta = 1.0 / (Constants.kb * temperature)
    const_1 = 0.5 * nbeads / (beta * Constants.hbar)**2
    const_2 = 1.5 * nbeads / beta
    const_3 = 1.5 / beta
    const_4 = Constants.kb**2 / Constants.hbar**2
    const_5 = Constants.hbar**2 * beta**3 / (24.0 * nbeads**3)
    const_6 = Constants.hbar**2 * beta**2 / (24.0 * nbeads**3)

    timeUnit, potentialEnergyUnit, potentialEnergy_index, time_index = extractUnits(
        iU)  # extracting simulation time
    # and potential energy units

    # Defining the output energy unit
    if unit == '':
        unit = potentialEnergyUnit

    iE.write(
        "# Simulation time (in %s), improved total energy estimator, virial total energy estimator, and PPI "
        "correction for the total energy; improved potential energy estimator, potential energy estimatorand, "
        "PPI correction for the potential energy; improved kinetic energy estimator, virial kinetic energy "
        "estimator, and PPI correction for the kinetic energy (all in %s)\n" %
        (timeUnit, unit))
    iE.close()

    natoms = 0
    ifr = 0
    time0 = 0
    q, f, m = None, None, None
    while True:  # Reading input files and calculating PPI correction

        if ifr % 100 == 0:
            print('\rProcessing frame {:d}'.format(ifr), end=' ')
            sys.stdout.flush()

        try:
            for i in range(nbeads):
                ret = read_file("xyz", ipos[i], dimension='length')["atoms"]
                if natoms == 0:
                    m, natoms = ret.m, ret.natoms
                    q = np.zeros((nbeads, 3 * natoms))
                    f = np.zeros((nbeads, 3 * natoms))
                q[i, :] = ret.q
                f[i, :] = read_file("xyz", ifor[i],
                                    dimension='force')["atoms"].q
            U, time = read_U(iU, potentialEnergyUnit, potentialEnergy_index,
                             time_index)
        except EOFError:  # finished reading files
            sys.exit(0)

        if ifr < skipSteps:

            time0 = time

        if ifr >= skipSteps:  # PPI correction

            time -= time0

            KPa, f2, KVir = 0.0, 0.0, 0.0

            if not fast_code:

                for j in range(nbeads):
                    for i in range(natoms):
                        f2 += np.dot(f[j, i * 3:i * 3 + 3],
                                     f[j, i * 3:i * 3 + 3]) / m[i]
                for i in range(natoms):
                    KPa -= np.dot(
                        q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3],
                        q[0, i * 3:i * 3 + 3] -
                        q[nbeads - 1, i * 3:i * 3 + 3]) * m[i]
                for j in range(nbeads - 1):
                    for i in range(natoms):
                        KPa -= np.dot(
                            q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3],
                            q[j + 1, i * 3:i * 3 + 3] -
                            q[j, i * 3:i * 3 + 3]) * m[i]
                rc = np.zeros(3)
                for i in range(natoms):
                    rc[:] = 0.0
                    for j in range(nbeads):
                        rc[:] += q[j, i * 3:i * 3 + 3]
                    rc[:] /= nbeads
                    for j in range(nbeads):
                        KVir += np.dot(rc[:] - q[j, i * 3:i * 3 + 3],
                                       f[j, i * 3:i * 3 + 3])

                KPa *= const_1
                KPa += const_2 * natoms
                KVir /= 2.0 * nbeads
                KVir += const_3 * natoms

            else:

                f2 = fortran.f2divm(np.array(f, order='F'),
                                    np.array(m, order='F'), natoms, nbeads)
                KPa = fortran.findcoupling(np.array(q, order='F'),
                                           np.array(m, order='F'), temperature,
                                           natoms, nbeads)
                KVir = fortran.findcentroidvirialkineticenergy(
                    np.array(f, order='F'), np.array(q, order='F'), natoms,
                    nbeads)

                KPa *= const_4
                KPa += const_2 * natoms
                KVir += const_3 * natoms

            f2_av += f2
            KPa_av += KPa
            f2KPa_av += f2 * KPa
            U_av += U
            f2U_av += f2 * U
            KVir_av += KVir
            ifr += 1

            norm = float(ifr - skipSteps)

            dU = 2 * f2_av / norm - beta * (f2U_av / norm -
                                            f2_av * U_av / norm**2)
            dU *= const_6
            dU = unit_to_user("energy", unit, dU)

            dK = (Constants.kb * temperature +
                  KPa_av / norm) * f2_av / norm - f2KPa_av / norm
            dK *= const_5
            dK = unit_to_user("energy", unit, dK)

            U = unit_to_user("energy", unit, U_av / norm)
            KVir = unit_to_user("energy", unit, KVir_av / norm)

            iE = open(fn_out_en, "a")
            iE.write(
                "%f    %f     %f     %f     %f    %f     %f     %f     %f     %f\n"
                % (time, KVir + U + dK + dU, KVir + U, dK + dU, U + dU, U, dU,
                   KVir + dK, KVir, dK))
            iE.close()

        else:
            ifr += 1
Exemplo n.º 4
0
def totalEnergy(prefix, temp, ss=0, unit=''):
    """
    Computes the virial centroid estimator for the total energy and PPI correction.
    """

    # Adding fortran functions (when exist)
    sys.path.append(os.path.abspath(os.path.dirname(sys.argv[0]))[:-2] + 'f90')
    fast_code = True
    try:
        import fortran
    except:
        fast_code = False
        print('WARNING: No compiled fortran module for fast calculations have been found.\n'
              'Calculations will use a slower python script.')

    temperature = unit_to_internal("temperature", "kelvin", float(temp))  # simulation temperature
    skipSteps = int(ss)                                                  # steps to skip for thermalization

    f2_av, ePA_av, eVir_av, f2ePA_av = 0.0, 0.0, 0.0, 0.0  # some required sums

    fns_pos = sorted(glob.glob(prefix + ".pos*"))
    fns_for = sorted(glob.glob(prefix + ".for*"))
    fns_iU = glob.glob(prefix + ".out")[0]
    fn_out_en = prefix + ".total_energy.dat"

    # check that we found the same number of positions and forces files
    nbeads = len(fns_pos)
    if nbeads != len(fns_for):
        print fns_pos
        print fns_for
        raise ValueError("Mismatch between number of input files for forces and positions.")

    # print some information
    print 'temperature = {:f} K'.format(float(temp))
    print
    print 'number of beads = {:d}'.format(nbeads)
    print
    print 'positions and forces file names:'
    for fn_pos, fn_for in zip(fns_pos, fns_for):
        print '{:s}   {:s}'.format(fn_pos, fn_for)
    print
    print 'potential energy file: {:s}'.format(fns_iU)
    print
    print 'output file name:'
    print fn_out_en
    print

    # open input and output files
    ipos = [open(fn, "r") for fn in fns_pos]
    ifor = [open(fn, "r") for fn in fns_for]
    iU = open(fns_iU, "r")
    iE = open(fn_out_en, "w")

    # Some constants
    beta = 1.0 / (Constants.kb * temperature)
    const_1 = 0.5 * nbeads / (beta * Constants.hbar)**2
    const_2 = 1.5 * nbeads / beta
    const_3 = 1.5 / beta
    const_4 = Constants.kb**2 / Constants.hbar**2
    const_5 = Constants.hbar**2 * beta**3 / (24.0 * nbeads**3)

    timeUnit, potentialEnergyUnit, potentialEnergy_index, time_index = extractUnits(iU)  # extracting simulation time
    # and potential energy units

    # Defining the output energy unit
    if unit == '':
        unit = potentialEnergyUnit

    iE.write("# Simulation time (in %s), virial total energy and PPI energy correction (in %s)\n" %
             (timeUnit, unit))

    natoms = 0
    ifr = 0
    time0 = 0
    q, f, m = None, None, None
    while True:  # Reading input files and calculating PPI correction

        if ifr % 100 == 0:
            print '\rProcessing frame {:d}'.format(ifr),
            sys.stdout.flush()

        try:
            for i in range(nbeads):
                ret = read_file("xyz", ipos[i], output='arrays')
                if natoms == 0:
                    m, natoms = ret["masses"], ret["natoms"]
                    q = np.zeros((nbeads, 3 * natoms))
                    f = np.zeros((nbeads, 3 * natoms))
                q[i, :] = ret["data"]
                f[i, :] = read_file("xyz", ifor[i], output='arrays')["data"]
            U, time = read_U(iU, potentialEnergyUnit, potentialEnergy_index, time_index)
        except EOFError:  # finished reading files
            sys.exit(0)

        if ifr < skipSteps:

            time0 = time

        if ifr >= skipSteps:  # PPI correction

            time -= time0

            ePA, f2, f2ePA, eVir = 0.0, 0.0, 0.0, 0.0

            if not fast_code:

                for j in range(nbeads):
                    for i in range(natoms):
                        f2 += np.dot(f[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3]) / m[i]
                for i in range(natoms):
                    ePA -= np.dot(q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3], q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3]) * m[i]
                for j in range(nbeads - 1):
                    for i in range(natoms):
                        ePA -= np.dot(q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3], q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3]) * m[i]
                rc = np.zeros(3)
                for i in range(natoms):
                    rc[:] = 0.0
                    for j in range(nbeads):
                        rc[:] += q[j, i * 3:i * 3 + 3]
                    rc[:] /= nbeads
                    for j in range(nbeads):
                        eVir += np.dot(rc[:] - q[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3])

                ePA *= const_1
                ePA += const_2 * natoms + U
                f2ePA = f2 * ePA
                eVir /= 2.0 * nbeads
                eVir += const_3 * natoms + U

            else:
                f2 = fortran.f2divm(np.array(f, order='F'), np.array(m, order='F'), natoms, nbeads)
                ePA = fortran.findcoupling(np.array(q, order='F'), np.array(m, order='F'), temperature, natoms, nbeads)
                eVir = fortran.findcentroidvirialkineticenergy(np.array(f, order='F'), np.array(q, order='F'), natoms, nbeads)

                ePA *= const_4
                ePA += const_2 * natoms + U
                f2ePA = f2 * ePA
                eVir += const_3 * natoms + U

            ePA_av += ePA
            f2_av += f2
            f2ePA_av += f2ePA
            eVir_av += eVir
            ifr += 1

            norm = float(ifr - skipSteps)

            dE = (3.0 * Constants.kb * temperature + ePA_av / norm) * f2_av / norm - f2ePA_av / norm
            dE *= const_5

            dE = unit_to_user("energy", unit, dE)
            eVir = unit_to_user("energy", unit, eVir_av / norm)

            iE.write("%f    %f     %f\n" % (time, eVir, dE))

        else:
            ifr += 1
Exemplo n.º 5
0
def heatCapacity(prefix, temp, ss=0):
    """
    Computes a primitive estimator for the heat capacity and PPI correction.
    """

    # Adding fortran functions (when exist)
    sys.path.append(os.path.abspath(os.path.dirname(sys.argv[0]))[:-2] + 'f90')
    fast_code = True
    try:
        import fortran
    except:
        fast_code = False
        print('WARNING: No compiled fortran module for fast calculations have been found.\n'
              'Calculations will use a slower python script.')

    temperature = unit_to_internal("temperature", "kelvin", float(temp))  # simulation temperature
    skipSteps = int(ss)                                                  # steps to skip for thermalization

    # some required sums
    KPa_av, U_av, f2_av, f2KPa_av, f2U_av, E2_av, f2E_av, f2E2_av = 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0

    fns_pos = sorted(glob.glob(prefix + ".pos*"))
    fns_for = sorted(glob.glob(prefix + ".for*"))
    fns_iU = glob.glob(prefix + ".out")[0]
    fn_out_en = prefix + ".heat_capacity.dat"

    # check that we found the same number of positions and forces files
    nbeads = len(fns_pos)
    if nbeads != len(fns_for):
        print fns_pos
        print fns_for
        raise ValueError("Mismatch between number of input files for forces and positions.")

    # print some information
    print 'temperature = {:f} K'.format(float(temp))
    print
    print 'number of beads = {:d}'.format(nbeads)
    print
    print 'positions and forces file names:'
    for fn_pos, fn_for in zip(fns_pos, fns_for):
        print '{:s}   {:s}'.format(fn_pos, fn_for)
    print
    print 'potential energy file: {:s}'.format(fns_iU)
    print
    print 'output file name:'
    print fn_out_en
    print

    # open input and output files
    ipos = [open(fn, "r") for fn in fns_pos]
    ifor = [open(fn, "r") for fn in fns_for]
    iU = open(fns_iU, "r")
    iC = open(fn_out_en, "w")

    # Some constants
    beta = 1.0 / (Constants.kb * temperature)
    const_1 = 0.5 * nbeads / (beta * Constants.hbar)**2
    const_2 = 1.5 * nbeads / beta
    const_3 = Constants.kb**2 / Constants.hbar**2
    const_4 = Constants.hbar**2 * beta**2 / (24.0 * nbeads**3)
    const_5 = Constants.kb * beta**2

    timeUnit, potentialEnergyUnit, potentialEnergy_index, time_index = extractUnits(iU)  # extracting simulation time
    # and potential energy units

    iC.write("# Simulation time (in %s), improved heat capacity estimator, primitive heat capacity estimator, "
             "and PPI correction for the heat capacity\n" % timeUnit)
    iC.close()

    natoms = 0
    ifr = 0
    time0 = 0
    q, f, m = None, None, None
    while True:  # Reading input files and calculating PPI correction

        if ifr % 100 == 0:
            print '\rProcessing frame {:d}'.format(ifr),
            sys.stdout.flush()

        try:
            for i in range(nbeads):
                ret = read_file("xyz", ipos[i], dimension='length')["atoms"]
                if natoms == 0:
                    m, natoms = ret.m, ret.natoms
                    q = np.zeros((nbeads, 3 * natoms))
                    f = np.zeros((nbeads, 3 * natoms))
                q[i, :] = ret.q
                f[i, :] = read_file("xyz", ifor[i], dimension='force')["atoms"].q
            U, time = read_U(iU, potentialEnergyUnit, potentialEnergy_index, time_index)
        except EOFError:  # finished reading files
            sys.exit(0)

        if ifr < skipSteps:

            time0 = time

        if ifr >= skipSteps:  # PPI correction

            time -= time0

            KPa, f2 = 0.0, 0.0

            if not fast_code:

                for j in range(nbeads):
                    for i in range(natoms):
                        f2 += np.dot(f[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3]) / m[i]
                for i in range(natoms):
                    KPa -= np.dot(q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3], q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3]) * m[i]
                for j in range(nbeads - 1):
                    for i in range(natoms):
                        KPa -= np.dot(q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3], q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3]) * m[i]

                KPa *= const_1
                KPa += const_2 * natoms

            else:

                f2 = fortran.f2divm(np.array(f, order='F'), np.array(m, order='F'), natoms, nbeads)
                KPa = fortran.findcoupling(np.array(q, order='F'), np.array(m, order='F'), temperature, natoms, nbeads)

                KPa *= const_3
                KPa += const_2 * natoms

            f2_av += f2
            KPa_av += KPa
            f2KPa_av += f2 * KPa
            U_av += U
            f2U_av += f2 * U
            E2_av += (KPa + U)**2
            f2E2_av += f2 * (KPa + U)**2
            ifr += 1

            norm = float(ifr - skipSteps)

            dU = 2 * f2_av / norm - beta * (f2U_av / norm - f2_av * U_av / norm**2)
            dU *= const_4

            dK = f2_av / norm - beta * (f2KPa_av / norm - f2_av * KPa_av / norm**2)
            dK *= const_4

            C = E2_av / norm - ((KPa_av + U_av) / norm)**2 + (2.0 / beta) * KPa_av / norm - 1.5 * nbeads * natoms / beta**2
            C *= const_5

            dC = 2 * (5 + 3 * beta * (KPa_av + U_av) / norm) * beta * f2_av * const_4 / norm - \
                2 * (3 + beta * (KPa_av + U_av) / norm) * beta * (dK + dU) + 2 * beta * dK - \
                const_4 * (f2E2_av / norm - f2_av * E2_av / norm**2) * beta**3

            iC = open(fn_out_en, "a")
            iC.write("%f    %f     %f     %f\n" % (time, C + dC, C, dC))
            iC.close()

        else:
            ifr += 1
Exemplo n.º 6
0
def energies(prefix, temp, ss=0, unit=''):
    """
    Computes the virial centroid estimator for the total energy and PPI correction.
    """

    # Adding fortran functions (when exist)
    sys.path.append(os.path.abspath(os.path.dirname(sys.argv[0]))[:-2] + 'f90')
    fast_code = True
    try:
        import fortran
    except:
        fast_code = False
        print('WARNING: No compiled fortran module for fast calculations have been found.\n'
              'Calculations will use a slower python script.')

    temperature = unit_to_internal("temperature", "kelvin", float(temp))  # simulation temperature
    skipSteps = int(ss)                                                  # steps to skip for thermalization

    KPa_av, KVir_av, U_av, f2_av, f2KPa_av, f2U_av = 0.0, 0.0, 0.0, 0.0, 0.0, 0.0  # some required sums

    fns_pos = sorted(glob.glob(prefix + ".pos*"))
    fns_for = sorted(glob.glob(prefix + ".for*"))
    fns_iU = glob.glob(prefix + ".out")[0]
    fn_out_en = prefix + ".energies.dat"

    # check that we found the same number of positions and forces files
    nbeads = len(fns_pos)
    if nbeads != len(fns_for):
        print fns_pos
        print fns_for
        raise ValueError("Mismatch between number of input files for forces and positions.")

    # print some information
    print 'temperature = {:f} K'.format(float(temp))
    print
    print 'number of beads = {:d}'.format(nbeads)
    print
    print 'positions and forces file names:'
    for fn_pos, fn_for in zip(fns_pos, fns_for):
        print '{:s}   {:s}'.format(fn_pos, fn_for)
    print
    print 'potential energy file: {:s}'.format(fns_iU)
    print
    print 'output file name:'
    print fn_out_en
    print

    # open input and output files
    ipos = [open(fn, "r") for fn in fns_pos]
    ifor = [open(fn, "r") for fn in fns_for]
    iU = open(fns_iU, "r")
    iE = open(fn_out_en, "w")

    # Some constants
    beta = 1.0 / (Constants.kb * temperature)
    const_1 = 0.5 * nbeads / (beta * Constants.hbar)**2
    const_2 = 1.5 * nbeads / beta
    const_3 = 1.5 / beta
    const_4 = Constants.kb**2 / Constants.hbar**2
    const_5 = Constants.hbar**2 * beta**3 / (24.0 * nbeads**3)
    const_6 = Constants.hbar**2 * beta**2 / (24.0 * nbeads**3)

    timeUnit, potentialEnergyUnit, potentialEnergy_index, time_index = extractUnits(iU)  # extracting simulation time
    # and potential energy units

    # Defining the output energy unit
    if unit == '':
        unit = potentialEnergyUnit

    iE.write("# Simulation time (in %s), improved total energy estimator, virial total energy estimator, and PPI "
             "correction for the total energy; improved potential energy estimator, potential energy estimatorand, "
             "PPI correction for the potential energy; improved kinetic energy estimator, virial kinetic energy "
             "estimator, and PPI correction for the kinetic energy (all in %s)\n" % (timeUnit, unit))
    iE.close()

    natoms = 0
    ifr = 0
    time0 = 0
    q, f, m = None, None, None
    while True:  # Reading input files and calculating PPI correction

        if ifr % 100 == 0:
            print '\rProcessing frame {:d}'.format(ifr),
            sys.stdout.flush()

        try:
            for i in range(nbeads):
                ret = read_file("xyz", ipos[i], dimension='length')["atoms"]
                if natoms == 0:
                    m, natoms = ret.m, ret.natoms
                    q = np.zeros((nbeads, 3 * natoms))
                    f = np.zeros((nbeads, 3 * natoms))
                q[i, :] = ret.q
                f[i, :] = read_file("xyz", ifor[i], dimension='force')["atoms"].q
            U, time = read_U(iU, potentialEnergyUnit, potentialEnergy_index, time_index)
        except EOFError:  # finished reading files
            sys.exit(0)

        if ifr < skipSteps:

            time0 = time

        if ifr >= skipSteps:  # PPI correction

            time -= time0

            KPa, f2, KVir = 0.0, 0.0, 0.0

            if not fast_code:

                for j in range(nbeads):
                    for i in range(natoms):
                        f2 += np.dot(f[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3]) / m[i]
                for i in range(natoms):
                    KPa -= np.dot(q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3], q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3]) * m[i]
                for j in range(nbeads - 1):
                    for i in range(natoms):
                        KPa -= np.dot(q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3], q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3]) * m[i]
                rc = np.zeros(3)
                for i in range(natoms):
                    rc[:] = 0.0
                    for j in range(nbeads):
                        rc[:] += q[j, i * 3:i * 3 + 3]
                    rc[:] /= nbeads
                    for j in range(nbeads):
                        KVir += np.dot(rc[:] - q[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3])

                KPa *= const_1
                KPa += const_2 * natoms
                KVir /= 2.0 * nbeads
                KVir += const_3 * natoms

            else:

                f2 = fortran.f2divm(np.array(f, order='F'), np.array(m, order='F'), natoms, nbeads)
                KPa = fortran.findcoupling(np.array(q, order='F'), np.array(m, order='F'), temperature, natoms, nbeads)
                KVir = fortran.findcentroidvirialkineticenergy(np.array(f, order='F'), np.array(q, order='F'), natoms, nbeads)

                KPa *= const_4
                KPa += const_2 * natoms
                KVir += const_3 * natoms

            f2_av += f2
            KPa_av += KPa
            f2KPa_av += f2 * KPa
            U_av += U
            f2U_av += f2 * U
            KVir_av += KVir
            ifr += 1

            norm = float(ifr - skipSteps)

            dU = 2 * f2_av / norm - beta * (f2U_av / norm - f2_av * U_av / norm**2)
            dU *= const_6
            dU = unit_to_user("energy", unit, dU)

            dK = (Constants.kb * temperature + KPa_av / norm) * f2_av / norm - f2KPa_av / norm
            dK *= const_5
            dK = unit_to_user("energy", unit, dK)

            U = unit_to_user("energy", unit, U_av / norm)
            KVir = unit_to_user("energy", unit, KVir_av / norm)

            iE = open(fn_out_en, "a")
            iE.write("%f    %f     %f     %f     %f    %f     %f     %f     %f     %f\n"
                     % (time, KVir + U + dK + dU, KVir + U, dK + dU, U + dU, U, dU, KVir + dK, KVir, dK))
            iE.close()

        else:
            ifr += 1
Exemplo n.º 7
0
def heat_capacity(prefix, temp, ss=0):
    """
  Computes a virial centroid estimator for the heat capacity and PPI correction.
  """

    # Adding fortran functions (when exist)
    sys.path.append(os.path.abspath(os.path.dirname(sys.argv[0]))[:-2] + 'f90')
    fast_code = True
    try:
        import fortran
    except:
        fast_code = False
        print(
            'WARNING: No compiled fortran module for fast calculations have been found.\n'
            'Calculations will use a slower python script.')

    temperature = unit_to_internal("temperature", "kelvin",
                                   float(temp))  # simulation temperature
    skipSteps = int(ss)  # steps to skip for thermalization

    # some required sums
    KPa_av, KVir_av, U_av, f2_av, f2KPa_av, f2U_av, EVir_av, EEVir_av, f2E_av, f2E2_av = \
      0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0

    fns_pos = sorted(glob.glob(prefix + ".pos*"))
    fns_for = sorted(glob.glob(prefix + ".for*"))
    fns_iU = glob.glob(prefix + ".out")[0]
    fn_out_en = prefix + ".heat_capacity.dat"

    # check that we found the same number of positions and forces files
    nbeads = len(fns_pos)
    if nbeads != len(fns_for):
        print fns_pos
        print fns_for
        raise ValueError(
            "Mismatch between number of input files for forces and positions.")

    # print some information
    print 'temperature = {:f} K'.format(float(temp))
    print
    print 'number of beads = {:d}'.format(nbeads)
    print
    print 'positions and forces file names:'
    for fn_pos, fn_for in zip(fns_pos, fns_for):
        print '{:s}   {:s}'.format(fn_pos, fn_for)
    print
    print 'potential energy file: {:s}'.format(fns_iU)
    print
    print 'output file name:'
    print fn_out_en
    print

    # open input and output files
    ipos = [open(fn, "r") for fn in fns_pos]
    ifor = [open(fn, "r") for fn in fns_for]
    iU = open(fns_iU, "r")
    iC = open(fn_out_en, "w")

    # Some constants
    beta = 1.0 / (Constants.kb * temperature)
    const_1 = 0.5 * nbeads / (beta * Constants.hbar)**2
    const_2 = 1.5 * nbeads / beta
    const_3 = 1.5 / beta
    const_4 = Constants.kb**2 / Constants.hbar**2
    const_5 = Constants.hbar**2 * beta**3 / (24.0 * nbeads**3)
    const_6 = Constants.hbar**2 * beta**2 / (24.0 * nbeads**3)
    const_7 = Constants.kb * beta**2

    timeUnit, potentialEnergyUnit, potentialEnergy_index, time_index = extractUnits(
        iU)  # extracting simulation time
    # and potential energy units

    iC.write(
        "# Simulation time (in %s), centroid virial heat capacity estimator and PPI correction\n"
        % timeUnit)

    natoms = 0
    ifr = 0
    time0 = 0
    q, f, m = None, None, None
    while True:  # Reading input files and calculating PPI correction

        if ifr % 100 == 0:
            print '\rProcessing frame {:d}'.format(ifr),
            sys.stdout.flush()

        try:
            for i in range(nbeads):
                ret = read_file("xyz", ipos[i], output='arrays')
                if natoms == 0:
                    m, natoms = ret["masses"], ret["natoms"]
                    q = np.zeros((nbeads, 3 * natoms))
                    f = np.zeros((nbeads, 3 * natoms))
                q[i, :] = ret["data"]
                f[i, :] = read_file("xyz", ifor[i], output='arrays')["data"]
            U, time = read_U(iU, potentialEnergyUnit, potentialEnergy_index,
                             time_index)
        except EOFError:  # finished reading files
            sys.exit(0)

        if ifr < skipSteps:

            time0 = time

        if ifr >= skipSteps:  # PPI correction

            time -= time0

            KPa, f2, KVir = 0.0, 0.0, 0.0

            if not fast_code:

                for j in range(nbeads):
                    for i in range(natoms):
                        f2 += np.dot(f[j, i * 3:i * 3 + 3],
                                     f[j, i * 3:i * 3 + 3]) / m[i]
                for i in range(natoms):
                    KPa -= np.dot(
                        q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3],
                        q[0, i * 3:i * 3 + 3] -
                        q[nbeads - 1, i * 3:i * 3 + 3]) * m[i]
                for j in range(nbeads - 1):
                    for i in range(natoms):
                        KPa -= np.dot(
                            q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3],
                            q[j + 1, i * 3:i * 3 + 3] -
                            q[j, i * 3:i * 3 + 3]) * m[i]
                rc = np.zeros(3)
                for i in range(natoms):
                    rc[:] = 0.0
                    for j in range(nbeads):
                        rc[:] += q[j, i * 3:i * 3 + 3]
                    rc[:] /= nbeads
                    for j in range(nbeads):
                        KVir += np.dot(rc[:] - q[j, i * 3:i * 3 + 3],
                                       f[j, i * 3:i * 3 + 3])

                KPa *= const_1
                KPa += const_2 * natoms
                KVir /= 2.0 * nbeads
                KVir += const_3 * natoms

            else:

                f2 = fortran.f2divm(np.array(f, order='F'),
                                    np.array(m, order='F'), natoms, nbeads)
                KPa = fortran.findcoupling(np.array(q, order='F'),
                                           np.array(m, order='F'), temperature,
                                           natoms, nbeads)
                KVir = fortran.findcentroidvirialkineticenergy(
                    np.array(f, order='F'), np.array(q, order='F'), natoms,
                    nbeads)

                KPa *= const_4
                KPa += const_2 * natoms
                KVir += const_3 * natoms

            f2_av += f2
            KPa_av += KPa
            f2KPa_av += f2 * KPa
            U_av += U
            f2U_av += f2 * U
            KVir_av += KVir
            EVir_av += KVir + U
            EEVir_av += (KVir + U) * (KPa + U)
            f2E_av += f2 * (KPa + U)
            f2E2_av += f2 * (KPa + U)**2
            ifr += 1

            norm = float(ifr - skipSteps)

            dU = 2 * f2_av / norm - beta * (f2U_av / norm -
                                            f2_av * U_av / norm**2)
            dU *= const_6

            dK = (Constants.kb * temperature +
                  KPa_av / norm) * f2_av / norm - f2KPa_av / norm
            dK *= const_5

            C = EEVir_av / norm - (EVir_av / norm)**2 + 1.5 * natoms / beta**2
            C *= const_7

            dC = (10 + C + 3*beta*EVir_av/norm)*beta*f2_av*const_6/norm - \
                 (6 + beta*EVir_av/norm)*beta*(dK + dU) + 2*beta*dK - \
                 const_6*(f2E2_av/norm - f2E_av*(KPa_av + U_av)/norm**2)*beta**3

            iC.write("%f    %f     %f\n" % (time, C, dC))

        else:
            ifr += 1