Exemple #1
0
def process_units(comment, cell, data, names, masses, natoms, dimension="automatic", units="automatic", cell_units="automatic", mode="xyz"):
    """Convert the data in the file according to the units written in the i-PI format.

    Args:
        comment:
        cell:
        data:
        names:
        masses:
        output:

    Returns:

    """
    dimension, units, cell_units = auto_units(comment, dimension, units, cell_units, mode)

    info("Interpreting input with dimension %s, units %s and cell units %s" % (dimension, units, cell_units), verbosity.high)

    # Units transformation
    cell *= unit_to_internal('length', cell_units, 1)  # cell units transformation
    data *= unit_to_internal(dimension, units, 1)  # units transformation

    # Return data as i-PI structures
    cell = Cell(cell)
    atoms = Atoms(natoms)
    atoms.q[:] = data
    atoms.names[:] = names
    atoms.m[:] = masses

    return {
        "atoms": atoms,
      "cell": cell,
    }
Exemple #2
0
    def __init__(
        self,
        latency=1.0e-3,
        name="",
        pars=None,
        dopbc=False,
        threaded=False,
        init_file="",
        plumeddat="",
        plumedstep=0,
    ):
        """Initialises FFPlumed.

        Args:
           pars: Optional dictionary, giving the parameters needed by the driver.
        """

        # a socket to the communication library is created or linked
        if plumed is None:
            raise ImportError(
                "Cannot find plumed libraries to link to a FFPlumed object/")
        super(FFPlumed, self).__init__(latency,
                                       name,
                                       pars,
                                       dopbc=False,
                                       threaded=threaded)
        self.plumed = plumed.Plumed()
        self.plumeddat = plumeddat
        self.plumedstep = plumedstep
        self.init_file = init_file

        if self.init_file.mode == "xyz":
            infile = open(self.init_file.value, "r")
            myframe = read_file(self.init_file.mode, infile)
            myatoms = myframe["atoms"]
            mycell = myframe["cell"]
            myatoms.q *= unit_to_internal("length", self.init_file.units, 1.0)
            mycell.h *= unit_to_internal("length", self.init_file.units, 1.0)

        self.natoms = myatoms.natoms
        self.plumed.cmd("setNatoms", self.natoms)
        self.plumed.cmd("setPlumedDat", self.plumeddat)
        self.plumed.cmd("setTimestep", 1.0)
        self.plumed.cmd(
            "setMDEnergyUnits", 2625.4996
        )  # Pass a pointer to the conversion factor between the energy unit used in your code and kJ mol-1
        self.plumed.cmd(
            "setMDLengthUnits", 0.052917721
        )  # Pass a pointer to the conversion factor between the length unit used in your code and nm
        self.plumed.cmd("setMDTimeUnits", 2.4188843e-05)
        self.plumedrestart = False
        if self.plumedstep > 0:
            # we are restarting, signal that PLUMED should continue
            self.plumedrestart = True
            self.plumed.cmd("setRestart", 1)
        self.plumed.cmd("init")
        self.charges = dstrip(myatoms.q) * 0.0
        self.masses = dstrip(myatoms.m)
        self.lastq = np.zeros(3 * self.natoms)
Exemple #3
0
    def fetch(self):
        """Returns the stored data in the user defined units."""

        super(InputValue, self).fetch()

        if self._dimension != "undefined":
            print "returning ", self.value * unit_to_internal(
                self._dimension, self.units.fetch(), 1.0)
            return self.value * unit_to_internal(self._dimension,
                                                 self.units.fetch(), 1.0)
        else:
            return self.value
Exemple #4
0
    def step(self, step=None):
        """Does one replay time step."""

        self.ptime = 0.0
        self.ttime = 0.0
        self.qtime = -time.time()

        while True:
            self.rstep += 1
            try:
                if self.intraj.mode == "xyz":
                    for b in self.beads:
                        myframe = read_file("xyz", self.rfile)
                        myatoms = myframe["atoms"]
                        mycell = myframe["cell"]
                        myatoms.q *= unit_to_internal("length",
                                                      self.intraj.units, 1.0)
                        mycell.h *= unit_to_internal("length",
                                                     self.intraj.units, 1.0)
                        b.q[:] = myatoms.q
                    self.cell.h[:] = mycell.h
                elif self.intraj.mode == "pdb":
                    for b in self.beads:
                        myatoms, mycell = read_file("pdb", self.rfile)
                        myatoms.q *= unit_to_internal("length",
                                                      self.intraj.units, 1.0)
                        mycell.h *= unit_to_internal("length",
                                                     self.intraj.units, 1.0)
                        b.q[:] = myatoms.q
                    self.cell.h[:] = mycell.h
                elif self.intraj.mode == "chk" or self.intraj.mode == "checkpoint":

                    # TODO: Adapt the new `Simulation.load_from_xml`?

                    # reads configuration from a checkpoint file
                    xmlchk = xml_parse_file(self.rfile)  # Parses the file.

                    from ipi.inputs.simulation import InputSimulation

                    simchk = InputSimulation()
                    simchk.parse(xmlchk.fields[0][1])
                    mycell = simchk.cell.fetch()
                    mybeads = simchk.beads.fetch()
                    self.cell.h[:] = mycell.h
                    self.beads.q[:] = mybeads.q
                    softexit.trigger(" # Read single checkpoint")
            except EOFError:
                softexit.trigger(" # Finished reading re-run trajectory")
            if (step is None) or (self.rstep > step):
                break

        self.qtime += time.time()
Exemple #5
0
 def __call__(self, cell, pos):
     """Get energies, forces, and stresses from the librascal model"""
     pos_rascal = unit_to_user("length", "angstrom", pos)
     cell_rascal = unit_to_user("length", "angstrom", cell)
     # Do the actual calculation
     pot, force, stress = self.rascal_calc.calculate(
         pos_rascal, cell_rascal)
     pot_ipi = unit_to_internal("energy", "electronvolt", pot)
     force_ipi = unit_to_internal("force", "ev/ang", force)
     # The rascal stress is normalized by the cell volume (in rascal units)
     vir_rascal = -1 * stress * det_ut3x3(cell_rascal)
     vir_ipi = unit_to_internal("energy", "electronvolt", vir_rascal)
     extras = ""
     return pot_ipi, force_ipi, vir_ipi, extras
Exemple #6
0
def process_units(
    comment,
    cell,
    data,
    names,
    masses,
    natoms,
    dimension="automatic",
    units="automatic",
    cell_units="automatic",
    mode="xyz",
):
    """Convert the data in the file according to the units written in the i-PI format.

    Args:
        comment:
        cell:
        data:
        names:
        masses:
        output:

    Returns:

    """
    dimension, units, cell_units = auto_units(comment, dimension, units,
                                              cell_units, mode)

    info(
        " # Interpreting input with dimension %s, units %s and cell units %s" %
        (dimension, units, cell_units),
        verbosity.high,
    )

    # Units transformation
    cell *= unit_to_internal("length", cell_units,
                             1)  # cell units transformation
    data *= unit_to_internal(dimension, units, 1)  # units transformation

    # Return data as i-PI structures
    cell = Cell(cell)
    atoms = Atoms(natoms)
    atoms.q[:] = data
    atoms.names[:] = names
    atoms.m[:] = masses

    return {
        "atoms": atoms,
        "cell": cell,
    }
Exemple #7
0
def gleacf(path2iipi, path2ivvac, oprefix, action, nrows, stride, dparam):

    # opens & parses the i-pi input file
    ifile = open(path2iipi, "r")
    xmlrestart = io_xml.xml_parse_file(ifile)
    ifile.close()

    isimul = InputSimulation()
    isimul.parse(xmlrestart.fields[0][1])
    simul = isimul.fetch()

    # parses the drift and diffusion matrices of the GLE thermostat.
    ttype = str(type(simul.syslist[0].motion.thermostat).__name__)
    kbT = float(simul.syslist[0].ensemble.temp)
    simul.syslist[0].motion.thermostat.temp = kbT

    if (ttype == "ThermoGLE"):
        Ap = simul.syslist[0].motion.thermostat.A * unit_to_internal(
            "time", dt[1], float(dt[0]))
        Cp = simul.syslist[0].motion.thermostat.C / kbT
        Dp = np.dot(Ap, Cp) + np.dot(Cp, Ap.T)
    elif (ttype == "ThermoLangevin"):
        Ap = np.asarray(
            [1.0 / simul.syslist[0].motion.thermostat.tau]).reshape(
                (1, 1)) * unit_to_internal("time", dt[1], float(dt[0]))
        Cp = np.asarray([1.0]).reshape((1, 1))
        Dp = np.dot(Ap, Cp) + np.dot(Cp, Ap.T)

    # imports the vvac function.
    ivvac = input_vvac(path2ivvac, nrows, stride)
    ix = ivvac[:, 0]
    iy = ivvac[:, 1]

    # computes the vvac kernel
    print "# computing the kernel."
    ker = gleKernel(ix, Ap, Dp)

    # (de-)convolutes the spectrum
    if (action == "conv"):
        print "# printing the output spectrum."
        output_vvac((ix, np.dot(iy, ker.T)), oprefix,
                    input_vvac(path2ivvac, nrows, 1))
    elif (action == "deconv"):
        print "# deconvoluting the input spectrum."
        oy = ISRA(ix, ker, iy, dparam, oprefix)
Exemple #8
0
    def fetch(self):
        """Returns the stored data in the user defined units."""

        super(InputValue, self).fetch()

        rval = self.value
        if self._dimension != "undefined":
            rval *= unit_to_internal(self._dimension, self.units.fetch(), 1.0)
        return rval
Exemple #9
0
    def fetch(self):
        """Returns the stored data in the user defined units."""

        super(InputValue, self).fetch()

        rval = self.value
        if self._dimension != "undefined":
            rval *= unit_to_internal(self._dimension, self.units.fetch(), 1.0)
        return rval
Exemple #10
0
def process_units(comment, cell, qatoms, names, masses, output='objects'):
    """ Converts the data in the file according to the units written in the ipi format.
    """
    # Extracting trajectory units
    family, unit = 'undefined', ''
    is_comment_useful = filter(None, [key.search(comment.strip())
                                      for key in traj_re])
    if len(is_comment_useful) > 0:
        traj = is_comment_useful[0].group()[:-1].split('{')
        family, unit = traj_dict[traj[0]]['dimension'], traj[1]

    # Extracting cell units
    cell_unit = ''
    tmp = cell_unit_re.search(comment)
    if tmp is not None:
        cell_unit = tmp.group(1)

    # Units transformation
    cell *= unit_to_internal('length', cell_unit, 1) # cell units transformation
    qatoms *= unit_to_internal(family, unit, 1) # units transformation
    if output == 'objects':

        cell = Cell(cell)
        atoms = Atoms(len(names))
        atoms.q[:] = qatoms
        atoms.names[:] = names
        atoms.m[:] = masses

        return {
          "atoms": atoms,
          "cell": cell,
        }

    else:

        return {
          "data": qatoms,
          "masses": masses,
          "names": names,
          "natoms": len(names),
          "cell": cell,
        }
Exemple #11
0
    def __init__(self, latency=1.0e-3, name="", pars=None, dopbc=False, init_file="", plumeddat="", precision=8, plumedstep=0):
        """Initialises FFPlumed.

        Args:
           pars: Optional dictionary, giving the parameters needed by the driver.
        """

        # a socket to the communication library is created or linked
        if plumed is None:
            raise ImportError("Cannot find plumed libraries to link to a FFPlumed object/")
        super(FFPlumed, self).__init__(latency, name, pars, dopbc=False)
        self.plumed = plumed.Plumed(precision)
        self.precision = precision
        self.plumeddat = plumeddat
        self.plumedstep = plumedstep
        self.init_file = init_file

        if self.init_file.mode == "xyz":
            infile = open(self.init_file.value, "r")
            myframe = read_file(self.init_file.mode, infile)
            myatoms = myframe['atoms']
            mycell = myframe['cell']
            myatoms.q *= unit_to_internal("length", self.init_file.units, 1.0)
            mycell.h *= unit_to_internal("length", self.init_file.units, 1.0)

        self.natoms = myatoms.natoms
        self.plumed.cmd("setNatoms", self.natoms)
        self.plumed.cmd("setPlumedDat", self.plumeddat)
        self.plumed.cmd("setTimestep", 1.)
        self.plumed.cmd("setMDEnergyUnits", 2625.4996)        # Pass a pointer to the conversion factor between the energy unit used in your code and kJ mol-1
        self.plumed.cmd("setMDLengthUnits", 0.052917721)        # Pass a pointer to the conversion factor between the length unit used in your code and nm
        self.plumed.cmd("setMDTimeUnits", 2.4188843e-05)
        self.plumedrestart = False
        if self.plumedstep > 0:
            # we are restarting, signal that PLUMED should continue
            self.plumedrestart = True
            self.plumed.cmd("setRestart", 1)
        self.plumed.cmd("init")
        self.charges = dstrip(myatoms.q) * 0.0
        self.masses = dstrip(myatoms.m)
        self.lastq = np.zeros(3 * self.natoms)
Exemple #12
0
    def step(self):
        """Does one simulation time step."""

        self.ptime = self.ttime = 0
        self.qtime = -time.time()

        try:
            if (self.intraj.mode == "xyz"):
                for b in self.beads:
                    myatoms = read_xyz(self.rfile)
                    myatoms.q *= unit_to_internal("length", self.intraj.units,
                                                  1.0)
                    b.q[:] = myatoms.q
            elif (self.intraj.mode == "pdb"):
                for b in self.beads:
                    myatoms, mycell = read_pdb(self.rfile)
                    myatoms.q *= unit_to_internal("length", self.intraj.units,
                                                  1.0)
                    mycell.h *= unit_to_internal("length", self.intraj.units,
                                                 1.0)
                    b.q[:] = myatoms.q
                self.cell.h[:] = mycell.h
            elif (self.intraj.mode == "chk"
                  or self.intraj.mode == "checkpoint"):
                # reads configuration from a checkpoint file
                xmlchk = xml_parse_file(self.rfile)  # Parses the file.

                from ipi.inputs.simulation import InputSimulation
                simchk = InputSimulation()
                simchk.parse(xmlchk.fields[0][1])
                mycell = simchk.cell.fetch()
                mybeads = simchk.beads.fetch()
                self.cell.h[:] = mycell.h
                self.beads.q[:] = mybeads.q
                softexit.trigger(" # Read single checkpoint")
        except EOFError:
            softexit.trigger(" # Finished reading re-run trajectory")

        self.qtime += time.time()
Exemple #13
0
    def step(self):
        """Does one simulation time step."""

        self.ptime = self.ttime = 0
        self.qtime = -time.time()

        try:
            if self.intraj.mode == "xyz":
                for b in self.beads:
                    myatoms = read_xyz(self.rfile)
                    myatoms.q *= unit_to_internal("length", self.intraj.units, 1.0)
                    b.q[:] = myatoms.q
            elif self.intraj.mode == "pdb":
                for b in self.beads:
                    myatoms, mycell = read_pdb(self.rfile)
                    myatoms.q *= unit_to_internal("length", self.intraj.units, 1.0)
                    mycell.h *= unit_to_internal("length", self.intraj.units, 1.0)
                    b.q[:] = myatoms.q
                self.cell.h[:] = mycell.h
            elif self.intraj.mode == "chk" or self.intraj.mode == "checkpoint":
                # reads configuration from a checkpoint file
                xmlchk = xml_parse_file(self.rfile)  # Parses the file.

                from ipi.inputs.simulation import InputSimulation

                simchk = InputSimulation()
                simchk.parse(xmlchk.fields[0][1])
                mycell = simchk.cell.fetch()
                mybeads = simchk.beads.fetch()
                self.cell.h[:] = mycell.h
                self.beads.q[:] = mybeads.q
                softexit.trigger(" # Read single checkpoint")
        except EOFError:
            softexit.trigger(" # Finished reading re-run trajectory")

        self.qtime += time.time()
Exemple #14
0
def gleacf(path2iipi, path2ivvac, oprefix, action, nrows, stride, dparam):

    # opens & parses the i-pi input file
    ifile = open(path2iipi, "r")
    xmlrestart = io_xml.xml_parse_file(ifile)
    ifile.close()

    isimul = InputSimulation()
    isimul.parse(xmlrestart.fields[0][1])
    simul = isimul.fetch()

    # parses the drift and diffusion matrices of the GLE thermostat.
    ttype = str(type(simul.syslist[0].motion.thermostat).__name__)
    kbT = float(simul.syslist[0].ensemble.temp)
    simul.syslist[0].motion.thermostat.temp = kbT

    if(ttype == "ThermoGLE"):
        Ap = simul.syslist[0].motion.thermostat.A * unit_to_internal("time", dt[1], float(dt[0]))
        Cp = simul.syslist[0].motion.thermostat.C / kbT
        Dp = np.dot(Ap, Cp) + np.dot(Cp, Ap.T)
    elif(ttype == "ThermoLangevin"):
        Ap = np.asarray([1.0 / simul.syslist[0].motion.thermostat.tau]).reshape((1, 1)) * unit_to_internal("time", dt[1], float(dt[0]))
        Cp = np.asarray([1.0]).reshape((1, 1))
        Dp = np.dot(Ap, Cp) + np.dot(Cp, Ap.T)

    # imports the vvac function.
    ivvac = input_vvac(path2ivvac, nrows, stride)
    ix = ivvac[:, 0]
    iy = ivvac[:, 1]

    # computes the vvac kernel
    print "# computing the kernel."
    ker = gleKernel(ix, Ap, Dp)

    # (de-)convolutes the spectrum
    if(action == "conv"):
        print "# printing the output spectrum."
        output_vvac((ix, np.dot(iy, ker.T)), oprefix, input_vvac(path2ivvac, nrows, 1))
    elif(action == "deconv"):
        print "# deconvoluting the input spectrum."
        oy = ISRA(ix, ker, iy, dparam, oprefix)
def read_U(filedesc, potentialEnergyUnit, potentialEnergy_index, time_index):
    """Takes a file which contains simulation time and potential energy information and
       returns these data. Potential energy is transformed into internal units.

    Args:
       filedesc: An open readable file object.

    Returns:
       The simulation time and potential energy of the system.
    """

    line = filedesc.readline()
    if line == "":
        raise EOFError("The file descriptor hit EOF.")

    line = line.strip().split()
    time = float(line[time_index])
    U = float(line[potentialEnergy_index])
    U = unit_to_internal("energy", potentialEnergyUnit, U)

    return U, time
Exemple #16
0
def read_U(filedesc, potentialEnergyUnit, potentialEnergy_index, time_index):
    """Takes a file which contains simulation time and potential energy information and
       returns these data. Potential energy is transformed into internal units.

    Args:
       filedesc: An open readable file object.

    Returns:
       The simulation time and potential energy of the system.
    """

    line = filedesc.readline()
    if line == "":
        raise EOFError("The file descriptor hit EOF.")

    line = line.strip().split()
    time = float(line[time_index])
    U = float(line[potentialEnergy_index])
    U = unit_to_internal("energy", potentialEnergyUnit, U)

    return U, time
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
Exemple #18
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
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
Exemple #20
0
def main(inputfile, prefix="PTW-", ttemp="300.0", skip="2000"):
    txtemp = ttemp
    ttemp = unit_to_internal("energy", "kelvin", float(ttemp))
    skip = int(skip)

    # opens & parses the input file
    ifile = open(inputfile, "r")
    verbosity.level = "quiet"
    verbosity.lock = True
    xmlrestart = io_xml.xml_parse_file(ifile)  # Parses the file.
    ifile.close()

    isimul = InputSimulation()
    isimul.parse(xmlrestart.fields[0][1])
    verbosity.level = "quiet"
    banner()
    print(
        "# Printing out temperature re-weighing factors for a parallel tempering simulation"
    )
    simul = isimul.fetch()

    if simul.mode != "paratemp":
        raise ValueError(
            "Simulation does not look like a parallel tempering one.")

    # reconstructs the list of the property and trajectory files that have been output
    # and that should be re-ordered
    lprop = []  # list of property files
    # ltraj = []  # list of trajectory files
    tlist = simul.paratemp.temp_list
    nsys = len(simul.syslist)
    for o in simul.outtemplate:
        if (type(o) is CheckpointOutput
            ):  # properties and trajectories are output per system
            pass
        elif type(o) is PropertyOutput:
            nprop = []
            isys = 0
            for s in simul.syslist:  # create multiple copies
                if s.prefix != "":
                    filename = s.prefix + "_" + o.filename
                else:
                    filename = o.filename
                ofilename = (prefix + (("%0" + str(
                    int(1 + np.floor(np.log(len(simul.syslist)) / np.log(10))))
                                        + "d") % (isys)) + "_" + o.filename)
                nprop.append({
                    "filename": filename,
                    "ofilename": ofilename,
                    "stride": o.stride,
                    "ifile": open(filename, "r"),
                    "ofile": None,
                })
                isys += 1
            lprop.append(nprop)

    ptfile = open("PARATEMP", "r")

    # these are variables used to compute the weighting factors
    tprops = []
    vfields = []
    refpots = []
    vunits = []
    nw = []
    tw = []
    tw2 = []

    repot = re.compile(" ([0-9]*) *--> potential")
    reunit = re.compile("{(.*)}")

    # now reads files one frame at a time, and re-direct output to the appropriate location
    irep = np.zeros(nsys, int)
    while True:
        # reads one line from PARATEMP index file
        line = ptfile.readline()
        line = line.split()

        try:
            if len(line) == 0:
                raise EOFError

            step = int(line[0])
            irep[:] = line[1:]

            wk = 0
            for prop in lprop:
                for isys in range(nsys):
                    sprop = prop[isys]
                    if step % sprop["stride"] == 0:  # property transfer
                        iline = sprop["ifile"].readline()
                        if len(iline) == 0:
                            raise EOFError
                        while iline[
                                0] == "#":  # fast forward if line is a comment
                            # checks if we have one single file with potential energies
                            rm = repot.search(iline)
                            if not (rm is None) and not (prop in tprops):
                                tprops.append(prop)
                                for p in prop:
                                    p["ofile"] = open(p["ofilename"], "w")
                                    p["ofile"].write(
                                        "# column   1     --> ptlogweight: ln of re-weighing factor with target temperature %s K\n"
                                        % (txtemp))
                                vfields.append(int(rm.group(1)) - 1)
                                refpots.append(np.zeros(nsys))
                                nw.append(np.zeros(nsys))
                                tw.append(np.zeros(nsys))
                                tw2.append(np.zeros(nsys))
                                rm = reunit.search(iline)
                                if rm:
                                    vunits.append(rm.group(1))
                                else:
                                    vunits.append("atomic_unit")
                            iline = sprop["ifile"].readline()
                        if prop in tprops:  # do temperature weighing
                            pot = unit_to_internal(
                                "energy", vunits[wk],
                                float(iline.split()[vfields[wk]]))
                            ir = irep[isys]
                            if nw[wk][ir] == 0:
                                refpots[wk][
                                    ir] = pot  # picks the first value as a reference potential to avoid insane absolute values of the logweight
                            temp = tlist[ir]
                            lw = (pot - refpots[wk][ir]) * (1 / temp -
                                                            1 / ttemp)
                            if (
                                    step > skip
                            ):  # computes trajectory weights avoiding the initial - possibly insane - values
                                if nw[wk][ir] == 0:
                                    tw[wk][ir] = lw
                                    tw2[wk][ir] = lw
                                else:
                                    tw[wk][ir] = logsumlog((tw[wk][ir], 1),
                                                           (lw, 1))[0]
                                    tw2[wk][ir] = logsumlog((tw2[wk][ir], 1),
                                                            (2 * lw, 1))[0]
                                nw[wk][ir] += 1
                            prop[ir]["ofile"].write("%15.7e\n" % (lw))
                            if isys == nsys - 1:
                                wk += 1
        except EOFError:
            # print out trajectory weights based on PRSA 2011, assuming that observables and weights are weakly correlated
            wk = 0
            fpw = open(prefix + "WEIGHTS", "w")
            fpw.write("# Global trajectory weights for temperature %s K\n" %
                      (txtemp))
            fpw.write(
                "# Please cite M. Ceriotti, G. A. Brain, O. Riordan, D.E. Manolopoulos, "
                +
                "The inefficiency of re-weighted sampling and the curse of system size in high-order path integration. "
                +
                "Proceedings of the Royal Society A, 468(2137), 2-17  (2011) \n"
            )
            for prop in lprop:
                if prop in tprops:
                    for ir in range(nsys):
                        fpw.write("%s   %15.7e \n" % (
                            prop[ir]["ofilename"],
                            1.0 / (np.exp(tw2[wk][ir] - 2 * tw[wk][ir]) *
                                   nw[wk][ir]),
                        ))
                    wk += 1
            break
Exemple #21
0
    def init_stage1(self, simul):
        """Initializes the simulation -- first stage.

        Takes a simulation object, and uses all the data in the initialization
        queue to fill up the beads and cell data needed to run the simulation.

        Args:
           simul: A simulation object to be initialized.

        Raises:
           ValueError: Raised if there is a problem with the initialization,
              if something that should have been has not been, or if the objects
              that have been specified are not compatible with each other.
        """

        if simul.beads.nbeads == 0:
            fpos = fmom = fmass = flab = fcell = False   # we don't have an explicitly defined beads object yet
        else:
            fpos = fmom = fmass = flab = fcell = True

        for (k, v) in self.queue:
            info(" # Initializer (stage 1) parsing " + str(k) + " object.", verbosity.high)

            if k == "cell":
                if v.mode == "manual":
                    rh = v.value.reshape((3, 3)) * unit_to_internal("length", v.units, 1.0)
                elif v.mode == "chk":
                    rh = init_chk(v.value)[1].h
                elif init_file(v.mode, v.value)[1].h.trace() == -3:
                    # In case the file do not contain any
                    # + cell parameters, the diagonal elements of the cell will be
                    # +set to -1 from the io_units and nothing is read here.
                    continue
                else:
                    rh = init_file(v.mode, v.value, cell_units=v.units)[1].h

                if fcell:
                    warning("Overwriting previous cell parameters", verbosity.low)

                simul.cell.h = rh
                if simul.cell.V == 0.0:
                    ValueError("Cell provided has zero volume")

                fcell = True
            elif k == "masses":
                if simul.beads.nbeads == 0:
                    raise ValueError("Cannot initialize the masses before the size of the system is known")
                if fmass:
                    warning("Overwriting previous atomic masses", verbosity.medium)
                if v.mode == "manual":
                    rm = v.value * unit_to_internal("mass", v.units, 1.0)
                else:
                    rm = init_beads(v, self.nbeads).m

                if v.bead < 0:   # we are initializing the path
                    if (fmom and fmass):
                        warning("Rescaling momenta to make up for changed mass", verbosity.medium)
                        simul.beads.p /= simul.beads.sm3   # go to mass-scaled momenta, that are mass-invariant
                    if v.index < 0:
                        simul.beads.m = rm
                    else:  # we are initializing a specific atom
                        simul.beads.m[v.index:v.index + 1] = rm
                    if (fmom and fmass):  # finishes correcting the momenta
                        simul.beads.p *= simul.beads.sm3  # back to normal momenta
                else:
                    raise ValueError("Cannot change the mass of a single bead")
                fmass = True

            elif k == "labels":
                if simul.beads.nbeads == 0:
                    raise ValueError("Cannot initialize the labels before the size of the system is known")
                if flab:
                    warning("Overwriting previous atomic labels", verbosity.medium)
                if v.mode == "manual":
                    rn = v.value
                else:
                    rn = init_beads(v, self.nbeads).names

                if v.bead < 0:   # we are initializing the path
                    if v.index < 0:
                        simul.beads.names = rn
                    else:  # we are initializing a specific atom
                        simul.beads.names[v.index:v.index + 1] = rn
                else:
                    raise ValueError("Cannot change the label of a single bead")
                flab = True

            elif k == "positions":
                if fpos:
                    warning("Overwriting previous atomic positions", verbosity.medium)
                # read the atomic positions as a vector

                rq = init_vector(v, self.nbeads, dimension="length", units=v.units)

                nbeads, natoms = rq.shape
                natoms /= 3

                # check if we must initialize the simulation beads
                if simul.beads.nbeads == 0:
                    if v.index >= 0:
                        raise ValueError("Cannot initialize single atoms before the size of the system is known")
                    simul.beads.resize(natoms, self.nbeads)

                set_vector(v, simul.beads.q, rq)
                fpos = True

            elif (k == "velocities" or k == "momenta") and v.mode == "thermal":   # intercept here thermal initialization, so we don't need to check further down
                if fmom:
                    warning("Overwriting previous atomic momenta", verbosity.medium)
                if simul.beads.natoms == 0:
                    raise ValueError("Cannot initialize momenta before the size of the system is known.")
                if not fmass:
                    raise ValueError("Trying to resample velocities before having masses.")

                rtemp = v.value * unit_to_internal("temperature", v.units, 1.0)
                if rtemp <= 0:
                    warning("Using the simulation temperature to resample velocities", verbosity.low)
                    rtemp = simul.ensemble.temp
                else:
                    info(" # Resampling velocities at temperature %s %s" % (v.value, v.units), verbosity.low)

                # pull together a mock initialization to get NM masses right
                # without too much code duplication
                if v.bead >= 0:
                    raise ValueError("Cannot thermalize a single bead")
                if v.index >= 0:
                    rnatoms = 1
                else:
                    rnatoms = simul.beads.natoms
                rbeads = Beads(rnatoms, simul.beads.nbeads)
                if v.index < 0:
                    rbeads.m[:] = simul.beads.m
                else:
                    rbeads.m[:] = simul.beads.m[v.index]
                rnm = NormalModes(mode=simul.nm.mode, transform_method=simul.nm.transform_method, freqs=simul.nm.nm_freqs)
                rens = Ensemble(temp=simul.ensemble.temp)
                rmv = Motion()
                rnm.bind(rens, rmv, rbeads)
                # then we exploit the sync magic to do a complicated initialization
                # in the NM representation
                # with (possibly) shifted-frequencies NM
                rnm.pnm = simul.prng.gvec((rbeads.nbeads, 3 * rbeads.natoms)) * np.sqrt(rnm.dynm3) * np.sqrt(rbeads.nbeads * rtemp * Constants.kb)

                if v.index < 0:
                    simul.beads.p = rbeads.p
                else:
                    simul.beads.p[:, 3 * v.index:3 * (v.index + 1)] = rbeads.p
                fmom = True

            elif k == "momenta":
                if fmom:
                    warning("Overwriting previous atomic momenta", verbosity.medium)
                # read the atomic momenta as a vector
                rp = init_vector(v, self.nbeads, momenta=True, dimension="momentum", units=v.units)
                nbeads, natoms = rp.shape
                natoms /= 3

                # checks if we must initialize the simulation beads
                if simul.beads.nbeads == 0:
                    if v.index >= 0:
                        raise ValueError("Cannot initialize single atoms before the size of the system is known")
                    simul.beads.resize(natoms, self.nbeads)

                rp *= np.sqrt(self.nbeads / nbeads)
                set_vector(v, simul.beads.p, rp)
                fmom = True
            elif k == "velocities":
                if fmom:
                    warning("Overwriting previous atomic momenta", verbosity.medium)
                # read the atomic velocities as a vector
                rv = init_vector(v, self.nbeads, dimension="velocity", units=v.units)
                nbeads, natoms = rv.shape
                natoms /= 3

                # checks if we must initialize the simulation beads
                if simul.beads.nbeads == 0 or not fmass:
                    ValueError("Cannot initialize velocities before the masses of the atoms are known")
                    simul.beads.resize(natoms, self.nbeads)

                warning("Initializing from velocities uses the previously defined masses -- not the masses inferred from the file -- to build momenta", verbosity.low)
                if v.index >= 0:
                    rv *= simul.beads.m[v.index]
                else:
                    for ev in rv:
                        ev *= simul.beads.m3[0]
                rv *= np.sqrt(self.nbeads / nbeads)
                set_vector(v, simul.beads.p, rv)
                fmom = True
            elif k == "gle": pass   # thermostats must be initialised in a second stage

        if simul.beads.natoms == 0:
            raise ValueError("Initializer could not initialize the atomic positions")
        if simul.cell.V == 0:
            raise ValueError("Initializer could not initialize the cell")
        for i in range(simul.beads.natoms):
            if simul.beads.m[i] <= 0:
                raise ValueError("Initializer could not initialize the masses")
            if simul.beads.names[i] == "":
                raise ValueError("Initializer could not initialize the atom labels")
        if not fmom:
            warning("Momenta not specified in initialize. Will start with zero velocity if they are not specified in beads.", verbosity.low)
Exemple #22
0
def contract_trajectory(fns_in, fn_out_template, n_new, cell_units_in, cell_units_out):

    verbosity.level = "low"
    n = len(fns_in)

    # Generate output file names.
    if n_new == 1:
        fns_out = [fn_out_template]
    else:
        fns_out = [fn_out_template.format(i) for i in range(n_new)]

    print("Contracting {:d} beads to {:d} beads.".format(n, n_new))
    print()

    print("input file names:")
    for fn in fns_in:
        print(fn)
    print()

    print("output file names:")
    for fn in fns_out:
        print(fn)
    print()

    # Open input trajectory iterators.
    trjs_in = [iter_file_name_raw(fn) for fn in fns_in]
    mode = os.path.splitext(fn)[-1]

    # Open output files.
    fs_out = [open_backup(fn, "w") for fn in fns_out]
    mode_out = os.path.splitext(fn_out_template)[-1]

    # prepare ring polymer rescaler
    rescale = nm_rescale(n, n_new)

    # Loop over all frames.
    i_frame = 0
    while True:
        try:
            # Get the frames for all beads.
            frames = [trj.next() for trj in trjs_in]
        except StopIteration:
            # Stop when any of the trajectories runs out of frames.
            break

        # gets units from first frame
        dimension, units, cell_units = auto_units(comment=frames[0]["comment"], cell_units=cell_units_in)
        if cell_units_out == "automatic": cell_units_out = cell_units  # re-use units unless otherwise specified

        # Consistency check.
        h = frames[0]["cell"]
        natoms = len(frames[0]["data"]) / 3
        for i in range(n):

            # Check that all the cells are the same.
            if (frames[i]["cell"] != h).any():
                msg = "Cell for beads {:d} and {:d} differ in frame {:d}."
                raise ValueError(msg.format(0, i, i_frame))

            # Check that the numbers of atoms are the same.
            if len(frames[i]["data"]) != 3 * natoms:
                msg = "Different numbers of atoms for beads {:d} and {:d} in frame {:d}."
                raise ValueError(msg.format(0, i, i_frame))

        cell = Cell()
        cell.h = frames[0]["cell"]
        atoms = Atoms(natoms)
        atoms.names = frames[0]["names"]

        # Compose the ring polymer.
        q = np.vstack([frame["data"] for frame in frames]) * unit_to_internal(dimension, units, 1)  # units transformation

        # Contract the coordinates to `n_new` beads.
        q_c = rescale.b1tob2(q)

        # Save the output data.
        for i, f_out in enumerate(fs_out):
            atoms.q = q_c[i, :]
            print_file(mode_out, atoms, cell, f_out, dimension=dimension, units=units, cell_units=cell_units_out)

        # Count frames and print information on progress.
        i_frame += 1
        if i_frame % 100 == 0:
            print("\rframe {:d}".format(i_frame), end="")
        sys.stdout.flush()

    for f_out in fs_out:
        f_out.close()

    print()
    print()
    print("Processed {:d} frames.".format(i_frame))
def potentialEnergy(prefix, temp, ss=0, unit=''):
    """
    Computes the estimator for the potential 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, U_av, f2U_av = 0.0, 0.0, 0.0  # some required sums

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

    # Extracting the number of beads
    nbeads = len(fns_for)

    # print some information
    print 'temperature = {:f} K'.format(float(temp))
    print
    print 'number of beads = {:d}'.format(nbeads)
    print
    print 'forces file names:'
    for fn_for in fns_for:
        print '{:s}'.format(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
    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 = 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), potential energy and PPI potential energy corrections (in %s)\n" %
             (timeUnit, unit))

    natoms = 0
    ifr = 0
    time0 = 0
    f, m = 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", ifor[i], output='arrays')
                if natoms == 0:
                    m, natoms = ret["masses"], ret["natoms"]
                    f = np.zeros((nbeads, 3 * natoms))
                f[i, :] = ret["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

            f2 = 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]

            else:
                f2 = fortran.f2divm(np.array(f, order='F'), np.array(m, order='F'), natoms, nbeads)

            U_av += U
            f2_av += f2
            f2U_av += f2 * U
            ifr += 1

            norm = float(ifr - skipSteps)

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

            dU = unit_to_user("energy", unit, dU)
            U = unit_to_user("energy", unit, U_av / float(ifr - skipSteps))

            iE.write("%f    %f     %f\n" % (time, U, dU))

        else:
            ifr += 1
Exemple #24
0
def test_case_insensitive():

    angstrom = units.unit_to_internal('length', 'angstrom', 1.0)
    Angstrom = units.unit_to_internal('length', 'Angstrom', 1.0)
Exemple #25
0
def RDF(prefix, temp, A, B, nbins, r_min, r_max, ss=0, unit='angstrom'):

    # Adding fortran functions (when exist)
    sys.path.append(os.path.abspath(os.path.dirname(sys.argv[0]))[:-2] + 'f90')
    try:
        import fortran
    except:
        print(
            'WARNING: No compiled fortran module for fast calculations have been found.\n'
            'Proceeding the calculations is not possible.')
        sys.exit(0)

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

    fns_pos = sorted(glob.glob(prefix + ".pos*"))
    fns_for = sorted(glob.glob(prefix + ".for*"))
    fn_out_rdf, fn_out_rdf_q = prefix + '.' + A + B + ".rdf.dat", prefix + '.' + A + B + ".rdf-ppi.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 'output file names:'
    print fn_out_rdf
    print fn_out_rdf_q
    print

    # open input and output files
    ipos = [open(fn, "r") for fn in fns_pos]
    ifor = [open(fn, "r") for fn in fns_for]
    #iRDF, iRDFq = open(fn_out_rdf, "w"), open(fn_out_rdf_q, "w")

    # Species for RDF
    species = (A, B)
    speciesMass = np.array(
        [Elements.mass(species[0]),
         Elements.mass(species[1])], order='F')

    r_min = unit_to_internal('length', unit,
                             float(r_min))  # Minimal distance for RDF
    r_max = unit_to_internal('length', unit,
                             float(r_max))  # Maximal distance for RDF
    dr = (r_max - r_min) / nbins  # RDF step
    rdf = np.array([[r_min + (0.5 + i) * dr, 0] for i in range(nbins)],
                   order='F')  # conventional RDF

    # RDF auxiliary variables
    cell = None  # simulation cell matrix
    inverseCell = None  # inverse simulation sell matrix
    cellVolume = None  # simulation cell volume
    natomsA = 0  # the total number of A type particles in the system
    natomsB = 0  # the total number of B type particles in the system
    # Here A and B are the types of elements used for RDF calculations

    # temp variables
    f2 = 0.0  # the sum of square forces divided by corresponding masses (f2/m)
    f2rdf = np.zeros(
        nbins,
        order='F')  # the sum f2/m multiplied by the rdf at each time step
    frdf = np.zeros(
        nbins, order='F'
    )  # the sum of f/m multiplied by the rdf derivative at each time step

    natoms = 0  # total number of atoms
    ifr = 0  # time frame number
    pos, force, mass = None, None, None  # positions, forces, and mass arrays
    noteof = True  # end of file test variable

    while noteof:  # 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])
                if natoms == 0:
                    mass, natoms = ret["atoms"].m, ret["atoms"].natoms
                    pos = np.zeros((nbeads, 3 * natoms), order='F')
                    force = np.zeros((nbeads, 3 * natoms), order='F')
                cell = ret["cell"].h
                inverseCell = ret["cell"].get_ih()
                cellVolume = ret["cell"].get_volume()
                pos[i, :] = ret["atoms"].q
                force[i, :] = read_file("xyz", ifor[i])["atoms"].q
        except EOFError:  # finished reading files
            noteof = False

        if noteof:
            if ifr >= skipSteps:  # RDF calculations

                species_A = [
                    3 * i + j for i in np.where(mass == speciesMass[0])[0]
                    for j in range(3)
                ]
                species_B = [
                    3 * i + j for i in np.where(mass == speciesMass[1])[0]
                    for j in range(3)
                ]
                natomsA = len(species_A)
                natomsB = len(species_B)
                posA = np.zeros((nbeads, natomsA), order='F')
                posB = np.zeros((nbeads, natomsB), order='F')
                forA = np.zeros((nbeads, natomsA), order='F')
                forB = np.zeros((nbeads, natomsB), order='F')
                for bead in range(nbeads):
                    posA[bead, :] = pos[bead, species_A]
                    forA[bead, :] = force[bead, species_A]
                    posB[bead, :] = pos[bead, species_B]
                    forB[bead, :] = force[bead, species_B]

                # RDF amd PPI RDF calculations
                f2temp = fortran.f2divm(force, mass, natoms, nbeads)
                f2 += f2temp
                fortran.updateqrdf(rdf, f2rdf, frdf, posA, posB, forA, forB,
                                   natomsA / 3, natomsB / 3, nbins, r_min,
                                   r_max, cell, inverseCell, nbeads, f2temp,
                                   speciesMass[0], speciesMass[1])

                ifr += 1

            else:
                ifr += 1

    # Some constants
    const = 1.0 / float(ifr - skipSteps)
    alpha = Constants.hbar**2 / (24.0 * nbeads**3 *
                                 (temperature * Constants.kb)**3)
    beta = Constants.hbar**2 / (12.0 * nbeads**3 *
                                (temperature * Constants.kb)**2)

    # Normalization
    rdf[:, 1] *= const / nbeads
    f2 *= alpha * const
    f2rdf[:] *= alpha * const
    frdf[:] *= beta * const

    # PPI correction
    rdfQ = np.copy(rdf)
    for bin in range(nbins):
        rdfQ[bin, 1] += (rdf[bin, 1] * f2 - f2rdf[bin] / nbeads)
        rdfQ[bin, 1] -= frdf[bin] / 2.0

    # Creating RDF from N(r)
    const, dr = cellVolume / (4 * np.pi / 3.0), rdf[1, 0] - rdf[0, 0]
    for bin in range(nbins):
        rdf[bin, 1] = const * rdf[bin, 1] / ((rdf[bin, 0] + 0.5 * dr)**3 -
                                             (rdf[bin, 0] - 0.5 * dr)**3)
        rdfQ[bin, 1] = const * rdfQ[bin, 1] / ((rdfQ[bin, 0] + 0.5 * dr)**3 -
                                               (rdfQ[bin, 0] - 0.5 * dr)**3)
    for bin in range(nbins):
        rdf[bin, 0] = unit_to_user('length', unit, rdf[bin, 0])
        rdfQ[bin, 0] = unit_to_user('length', unit, rdfQ[bin, 0])

    # Writing the results into files
    np.savetxt(fn_out_rdf, rdf)
    np.savetxt(fn_out_rdf_q, rdfQ)
Exemple #26
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
Exemple #27
0
def main(prefix, temp):

    T = float(temp)
    fns_pos = sorted(glob.glob(prefix + ".pos*"))
    fns_for = sorted(glob.glob(prefix + ".for*"))
    fn_out_kin = prefix + ".kin.xyz"
    fn_out_kod = prefix + ".kod.xyz"

    # 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(T)
    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 'output file names:'
    print fn_out_kin
    print fn_out_kod
    print

    temp = unit_to_internal("energy", "kelvin", T)

    # open input and output files
    ipos = [open(fn, "r") for fn in fns_pos]
    ifor = [open(fn, "r") for fn in fns_for]
    ikin = open(fn_out_kin, "w")
    ikod = open(fn_out_kod, "w")

    natoms = 0
    ifr = 0
    while True:

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

        # load one frame
        try:
            for i in range(nbeads):
                ret = read_file("xyz", ipos[i])
                pos = ret["atoms"]
                ret = read_file("xyz", ifor[i])
                force = ret["atoms"]
                if natoms == 0:
                    natoms = pos.natoms
                    beads = Beads(natoms, nbeads)
                    forces = Beads(natoms, nbeads)
                    kcv = np.zeros((natoms, 6), float)
                beads[i].q = pos.q
                forces[i].q = force.q
        except EOFError:
            # finished reading files
            break

        # calculate kinetic energies
        q = dstrip(beads.q)
        f = dstrip(forces.q)
        qc = dstrip(beads.qc)
        kcv[:] = 0
        for j in range(nbeads):
            for i in range(natoms):
                kcv[i,
                    0] += (q[j, i * 3 + 0] - qc[i * 3 + 0]) * f[j, i * 3 + 0]
                kcv[i,
                    1] += (q[j, i * 3 + 1] - qc[i * 3 + 1]) * f[j, i * 3 + 1]
                kcv[i,
                    2] += (q[j, i * 3 + 2] - qc[i * 3 + 2]) * f[j, i * 3 + 2]
                kcv[i, 3] += (
                    q[j, i * 3 + 0] - qc[i * 3 + 0]) * f[j, i * 3 + 1] + (
                        q[j, i * 3 + 1] - qc[i * 3 + 1]) * f[j, i * 3 + 0]
                kcv[i, 4] += (
                    q[j, i * 3 + 0] - qc[i * 3 + 0]) * f[j, i * 3 + 2] + (
                        q[j, i * 3 + 2] - qc[i * 3 + 2]) * f[j, i * 3 + 0]
                kcv[i, 5] += (
                    q[j, i * 3 + 1] - qc[i * 3 + 1]) * f[j, i * 3 + 2] + (
                        q[j, i * 3 + 2] - qc[i * 3 + 2]) * f[j, i * 3 + 1]
        kcv *= -0.5 / nbeads
        kcv[:, 0:3] += 0.5 * Constants.kb * temp
        kcv[:, 3:6] *= 0.5

        # write output
        ikin.write(
            "%d\n# Centroid-virial kinetic energy estimator [a.u.] - diagonal terms: xx yy zz\n"
            % natoms)
        ikod.write(
            "%d\n# Centroid-virial kinetic energy estimator [a.u.] - off-diag terms: xy xz yz\n"
            % natoms)
        for i in range(natoms):
            ikin.write("%8s %12.5e %12.5e %12.5e\n" %
                       (pos.names[i], kcv[i, 0], kcv[i, 1], kcv[i, 2]))
            ikod.write("%8s %12.5e %12.5e %12.5e\n" %
                       (pos.names[i], kcv[i, 3], kcv[i, 4], kcv[i, 5]))

        ifr += 1

    print '\rProcessed {:d} frames.'.format(ifr)

    ikin.close()
    ikod.close()
Exemple #28
0
    def step(self, step=None):
        """Does one replay time step."""

        self.ptime = 0.0
        self.ttime = 0.0
        self.qtime = -time.time()

        # If wildcard is used, check that it is consistent with Nbeads
        wildcard_used = False
        if any(char in self.intraj.value for char in "*?[]"):
            wildcard_used = True
            if len(self.rfile) != len(self.beads):
                info(
                    "Error: if a wildcard is used for replay, then "
                    "the number of files should be equal to the number of beads.",
                    verbosity.low,
                )
                softexit.trigger(" # Error in replay input.")
        while True:
            self.rstep += 1
            try:
                if self.intraj.mode == "xyz":
                    for bindex, b in enumerate(self.beads):
                        if wildcard_used:
                            myframe = read_file("xyz", self.rfile[bindex])
                        else:
                            myframe = read_file("xyz", self.rfile)
                        myatoms = myframe["atoms"]
                        mycell = myframe["cell"]
                        myatoms.q *= unit_to_internal("length",
                                                      self.intraj.units, 1.0)
                        mycell.h *= unit_to_internal("length",
                                                     self.intraj.units, 1.0)
                        b.q[:] = myatoms.q
                elif self.intraj.mode == "pdb":
                    for bindex, b in enumerate(self.beads):
                        if wildcard_used:
                            myatoms, mycell = read_file(
                                "pdb", self.rfile[bindex])
                        else:
                            myatoms, mycell = read_file("pdb", self.rfile)
                        myatoms.q *= unit_to_internal("length",
                                                      self.intraj.units, 1.0)
                        mycell.h *= unit_to_internal("length",
                                                     self.intraj.units, 1.0)
                        b.q[:] = myatoms.q
                elif self.intraj.mode == "chk" or self.intraj.mode == "checkpoint":
                    # TODO: Adapt the new `Simulation.load_from_xml`?
                    # reads configuration from a checkpoint file
                    xmlchk = xml_parse_file(self.rfile)  # Parses the file.

                    from ipi.inputs.simulation import InputSimulation

                    simchk = InputSimulation()
                    simchk.parse(xmlchk.fields[0][1])
                    mycell = simchk.cell.fetch()
                    mybeads = simchk.beads.fetch()
                    self.beads.q[:] = mybeads.q
                    softexit.trigger(" # Read single checkpoint")
                # do not assign cell if it contains an invalid value (typically missing cell in the input)
                if mycell.V > 0:
                    self.cell.h[:] = mycell.h
            except EOFError:
                softexit.trigger(" # Finished reading re-run trajectory")
            if (step is None) or (self.rstep > step):
                break

        self.qtime += time.time()
Exemple #29
0
def compute_acf(input_file, output_prefix, maximum_lag, block_length, length_zeropadding, spectral_windowing, labels, timestep, skip, der):

    # stores the arguments
    ifile = str(input_file)
    ofile = str(output_prefix)
    mlag = int(maximum_lag)
    bsize = int(block_length)
    npad = int(length_zeropadding)
    ftbox = str(spectral_windowing)
    labels = str(labels)
    timestep = str(timestep).split()
    fskip = int(skip)

    # checks for errors
    if(mlag <= 0):
        raise ValueError("MAXIMUM_LAG should be a non-negative integer.")
    if(npad < 0):
        raise ValueError("LENGTH_ZEROPADDING should be a non-negative integer.")
    if(bsize < 2 * mlag):
        if(bsize == -1):
            bsize = 2 * mlag
        else:
            raise ValueError("LENGTH_BLOCK should be greater than or equal to 2 * MAXIMUM_LAG.")

    # reads one frame.
    ff = open(ifile)
    rr = read_file_raw("xyz", ff)
    ff.close()

    # appends "der" to output file in case the acf of the derivative is desired
    if(der == True):
        ofile = ofile + "_der"

    # stores the indices of the "chosen" atoms.
    ndof = len(rr['data'])
    if("*" in labels):
        labelbool = np.ones(ndof / 3, bool)
    else:
        labelbool = np.zeros(ndof / 3, bool)
        for l in labels:
            labelbool = np.logical_or(labelbool, rr['names'] == l)
    nspecies = labelbool.sum()

    # initializes variables.
    nblocks = 0
    dt = unit_to_internal("time", timestep[1], float(timestep[0]))
    data = np.zeros((bsize, nspecies, 3), float)
    fvvacf = np.zeros(bsize / 2 + 1, float)
    time = np.asarray(range(mlag + 1)) * dt
    omega = np.asarray(range(2 * (mlag + npad))) / float(2 * (mlag + npad)) * (2 * np.pi / dt)

    # selects window function for fft.
    if(ftbox == "none"):
        win = np.ones(2 * mlag + 1, float)
    elif(ftbox == "cosine-hanning"):
        win = np.hanning(2 * mlag + 1)
    elif(ftbox == "cosine-hamming"):
        win = np.hamming(2 * mlag + 1)
    elif(ftbox == "cosine-blackman"):
        win = np.blackman(2 * mlag + 1)
    elif(ftbox == "triangle-bartlett"):
        win = np.bartlett(2 * mlag + 1)

    ff = open(ifile)
    # Skips the first fskip frames
    for x in xrange(fskip):
        rr = read_file_raw("xyz", ff)

    while True:

        try:
            # Reads the data in blocks.
            for i in range(bsize):
                rr = read_file_raw("xyz", ff)
                data[i] = rr['data'].reshape((ndof / 3, 3))[labelbool]

            if(der == True):
                data = np.gradient(data, axis=0) / dt

            # Computes the Fourier transform of the data.
            fdata = np.fft.rfft(data, axis=0)

            # Computes the Fourier transform of the vvac applying the convolution theorem.
            tfvvacf = fdata * np.conjugate(fdata)

            # Averages over all species and sums over the x,y,z directions. Also multiplies with the time step and a prefactor of (2pi)^-1.
            macf = 3.0 * np.real(np.mean(tfvvacf, axis=(1, 2))) * dt / (2 * np.pi) / bsize
            fvvacf += macf
            nblocks += 1

        except EOFError:
            break
    ff.close()

    # Performs the block average of the Fourier transform.
    fvvacf = fvvacf / nblocks

    # Computes the inverse Fourier transform to get the vvac.
    vvacf = np.fft.irfft(fvvacf)[:mlag + 1]
    np.savetxt(ofile + "_acf.data", np.vstack((time, vvacf)).T[:mlag + npad])

    # Applies window in one direction and pads the vvac with zeroes.
    pvvacf = np.append(vvacf * win[mlag:], np.zeros(npad))

    # Recomputes the Fourier transform assuming the data is an even function of time.
    fpvvacf = np.fft.hfft(pvvacf)
    np.savetxt(ofile + "_facf.data", np.vstack((omega, fpvvacf)).T[:mlag + npad])
    print 'We have a half ring polymer made of %i beads and %i atoms.' % (nbeads, natoms)
    print 'We will expand the ring polymer to get a half polymer of %i beads.' % nbeadsNew

    # Compose the full ring polymer.
    #q2 = np.concatenate((q, np.flipud(q)), axis=0)

    # Make the rpc step
    #rpc = nm_rescale(2 * nbeads, 2 * nbeadsNew)
    #new_q = rpc.b1tob2(q2)[0:nbeadsNew]
    rpc = nm_rescale(nbeads, nbeadsNew, np.asarray(range(natoms)))  # We use open path RPC
    new_q = rpc.b1tob2(q)

    # Print
    out = open("NEW_INSTANTON.xyz", "w")
    for i in range(nbeadsNew):
        atom.q = new_q[i] / unit_to_internal("length", "angstrom", 1.0)  # Go back to angstrom
        print_file("xyz", atom, cell, out, title='cell{atomic_unit}  Traj: positions{angstrom}')
        # print_file("xyz",pos[0],cell,out,title='cell  }')
    out.close()

    print 'The new Instanton geometry (half polymer) was generated'
    print 'Check NEW_INSTANTON.xyz'
    print ''
    print 'Remeber to change the number of beads (%i) in your input' % nbeadsNew
    print ''

if input_hess != 'None' or chk != 'None':

    if manual:
        if (os.path.exists(input_hess)):
            hess = open(input_hess, "r")
Exemple #31
0
def main(inputfile, prefix="PTW-", ttemp="300.0", skip="2000"):
    txtemp = ttemp
    ttemp = unit_to_internal("energy", "kelvin", float(ttemp))
    skip = int(skip)

    # opens & parses the input file
    ifile = open(inputfile, "r")
    verbosity.level = "quiet"
    verbosity.lock = True
    xmlrestart = io_xml.xml_parse_file(ifile)  # Parses the file.
    ifile.close()

    isimul = InputSimulation()
    isimul.parse(xmlrestart.fields[0][1])
    verbosity.level = "quiet"
    banner()
    print "# Printing out temperature re-weighing factors for a parallel tempering simulation"
    simul = isimul.fetch()

    if simul.mode != "paratemp":
        raise ValueError("Simulation does not look like a parallel tempering one.")

    # reconstructs the list of the property and trajectory files that have been output
    # and that should be re-ordered
    lprop = []  # list of property files
    ltraj = []  # list of trajectory files
    tlist = simul.paratemp.temp_list
    nsys = len(simul.syslist)
    for o in simul.outtemplate:
        if type(o) is CheckpointOutput:   # properties and trajectories are output per system
            pass
        elif type(o) is PropertyOutput:
            nprop = []
            isys = 0
            for s in simul.syslist:   # create multiple copies
                if s.prefix != "":
                    filename = s.prefix + "_" + o.filename
                else: filename = o.filename
                ofilename = prefix + (("%0" + str(int(1 + np.floor(np.log(len(simul.syslist)) / np.log(10)))) + "d") % (isys)) + "_" + o.filename
                nprop.append({"filename": filename, "ofilename": ofilename, "stride": o.stride,
                              "ifile": open(filename, "r"), "ofile": None
                              })
                isys += 1
            lprop.append(nprop)

    ptfile = open("PARATEMP", "r")

    # these are variables used to compute the weighting factors
    tprops = []
    vfields = []
    refpots = []
    vunits = []
    nw = []
    tw = []
    tw2 = []

    repot = re.compile(' ([0-9]*) *--> potential')
    reunit = re.compile('{(.*)}')

    # now reads files one frame at a time, and re-direct output to the appropriate location
    irep = np.zeros(nsys, int)
    while True:
        # reads one line from PARATEMP index file
        line = ptfile.readline()
        line = line.split()

        try:
            if len(line) == 0: raise EOFError

            step = int(line[0])
            irep[:] = line[1:]

            wk = 0
            for prop in lprop:
                for isys in range(nsys):
                    sprop = prop[isys]
                    if step % sprop["stride"] == 0:  # property transfer
                        iline = sprop["ifile"].readline()
                        if len(iline) == 0: raise EOFError
                        while iline[0] == "#":  # fast forward if line is a comment
                            # checks if we have one single file with potential energies
                            rm = repot.search(iline)
                            if not (rm is None) and not (prop in tprops):
                                tprops.append(prop)
                                for p in prop:
                                    p["ofile"] = open(p["ofilename"], "w")
                                    p["ofile"].write("# column   1     --> ptlogweight: ln of re-weighing factor with target temperature %s K\n" % (txtemp))
                                vfields.append(int(rm.group(1)) - 1)
                                refpots.append(np.zeros(nsys))
                                nw.append(np.zeros(nsys))
                                tw.append(np.zeros(nsys))
                                tw2.append(np.zeros(nsys))
                                rm = reunit.search(iline)
                                if rm: vunits.append(rm.group(1))
                                else: vunits.append("atomic_unit")
                            iline = sprop["ifile"].readline()
                        if prop in tprops:  # do temperature weighing
                            pot = unit_to_internal("energy", vunits[wk], float(iline.split()[vfields[wk]]))
                            ir = irep[isys]
                            if (nw[wk][ir] == 0):
                                refpots[wk][ir] = pot  # picks the first value as a reference potential to avoid insane absolute values of the logweight
                            temp = tlist[ir]
                            lw = (pot - refpots[wk][ir]) * (1 / temp - 1 / ttemp)
                            if step > skip:  # computes trajectory weights avoiding the initial - possibly insane - values
                                if nw[wk][ir] == 0:
                                    tw[wk][ir] = lw
                                    tw2[wk][ir] = lw
                                else:
                                    tw[wk][ir] = logsumlog((tw[wk][ir], 1), (lw, 1))[0]
                                    tw2[wk][ir] = logsumlog((tw2[wk][ir], 1), (2 * lw, 1))[0]
                                nw[wk][ir] += 1
                            prop[ir]["ofile"].write("%15.7e\n" % (lw))
                            if isys == nsys - 1: wk += 1
        except EOFError:
            # print out trajectory weights based on PRSA 2011, assuming that observables and weights are weakly correlated
            wk = 0
            fpw = open(prefix + "WEIGHTS", "w")
            fpw.write("# Global trajectory weights for temperature %s K\n" % (txtemp))
            fpw.write("# Please cite M. Ceriotti, G. A. Brain, O. Riordan, D.E. Manolopoulos, " +
                      "The inefficiency of re-weighted sampling and the curse of system size in high-order path integration. " +
                      "Proceedings of the Royal Society A, 468(2137), 2-17  (2011) \n")
            for prop in lprop:
                if prop in tprops:
                    for ir in range(nsys):
                        fpw.write("%s   %15.7e \n" % (prop[ir]["ofilename"], 1.0 / (np.exp(tw2[wk][ir] - 2 * tw[wk][ir]) * nw[wk][ir])))
                    wk += 1
            break
Exemple #32
0
# See the "licenses" directory for full license information.


import filecmp
import os

import numpy as np
from numpy.testing import assert_equal

from common import local
from ipi.utils.units import unit_to_internal
from ipi.utils.io import iter_file, read_file, print_file


pos_xyz = np.array([i for i in range(3 * 3)])
pos_pdb = unit_to_internal("length", "angstrom", pos_xyz)


def test_read_xyz():
    """Tests that xyz files are read correctly."""

    with open(local("test.pos_0.xyz"), "r") as f:
        ret = read_file("xyz", f)
        atoms = ret["atoms"]
        assert len(atoms) == 3
        assert_equal(pos_xyz, atoms.q)


def test_iter_xyz():
    """Tests that xyz files with multiple frames are read correctly."""
def effectiveTemperatures(prefix, temp, ss=0):
    """
    Computes effective temperatures for a given (PI)MD dynamics.
    """

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

    f2_av = None  # average square forces array
    names = None

    fns_for = sorted(glob.glob(prefix + ".for*"))
    fn_out = prefix + ".effective_temperatures.dat"

    nbeads = len(fns_for)

    # print some information
    print 'temperature = {:f} K'.format(float(temp))
    print
    print 'number of beads = {:d}'.format(nbeads)
    print
    print 'forces file names:'
    for fn_for in fns_for:
        print '{:s}'.format(fn_for)
    print
    print 'output file name:'
    print fn_out
    print

    # open input and output files
    ifor = [open(fn, "r") for fn in fns_for]
    iOut = open(fn_out, "w")

    # Some constants
    const = Constants.hbar**2 / (12.0 * (nbeads * Constants.kb * temperature)**3)

    iOut.write("# Atom, Cartesian components of the effective temperature, average effective temperature (in Kelvin)\n")

    natoms = 0
    ifr = 0
    f, m = 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", ifor[i], dimension='force')["atoms"]
                if natoms == 0:
                    m, natoms, names = ret.m, ret.natoms, ret.names
                    f = np.zeros((nbeads, 3 * natoms))
                    f2_av = np.zeros(3 * natoms)
                f[i, :] = ret.q
        except EOFError:  # finished reading files
            break

        if ifr >= skipSteps:  # PPI correction

            f2 = np.zeros(3 * natoms)
            for i in range(natoms):
                for j in range(nbeads):
                    f2[i * 3:i * 3 + 3] += f[j, i * 3:i * 3 + 3]**2 / m[i]

            f2_av[:] += f2[:]
            ifr += 1

        else:
            ifr += 1

    dT = const * f2_av / float(ifr - skipSteps)

    temperature = unit_to_user("temperature", "kelvin", temperature)

    for i in range(natoms):
        iOut.write("%s    %f     %f     %f     %f\n" % (names[i], temperature * (1 + dT[i * 3]), temperature * (1 + dT[i * 3 + 1]),
                                                        temperature * (1 + dT[i * 3 + 2]), temperature * (1 + np.sum(dT[i * 3:i * 3 + 3]) / 3.0)))

    for f in ifor:
        f.close()

    iOut.close()
Exemple #34
0
def totalEnergy(prefix, temp, ss=0):
    """
    Computes the virial centroid estimator for the total energy and PPI correction.
    """

    global temperature, skipSteps

    temperature = unit_to_internal("temperature", "kelvin", float(temp))
    skipSteps = int(ss)

    f2_av, ePA_av, eVir_av, f2ePA_av = (
        0.0,
        0.0,
        0.0,
        0.0,
    )  # average square forces, virial and primitive energy
    # estimators, and the product of the primitive energy estimator and square forces

    ipos = []  # input positions files
    for filename in sorted(glob.glob(prefix + ".pos*")):
        ipos.append(open(filename, "r"))

    ifor = []  # input forces files
    for filename in sorted(glob.glob(prefix + ".for*")):
        ifor.append(open(filename, "r"))

    iU = None  # input potential energy and simulation time file
    for filename in sorted(glob.glob(prefix + ".out")):
        iU = open(filename, "r")

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

    iE = open(prefix + ".energy" + ".dat", "w")
    iE.write(
        "# Simulation time (in %s), virial total energy and PPI energy correction (in %s)\n"
        % (timeUnit, potentialEnergyUnit))

    nbeads = len(ipos)
    if nbeads != len(ifor):
        raise ValueError(
            "Mismatch between number of output files for forces and positions")
    natoms = 0
    ifr = 0
    time0 = 0
    q, f, m = None, None, None
    while True:  # Reading input files and calculating PPI correction
        try:
            for i in range(nbeads):
                ret = read_file("xyz", ipos[i])
                m, n = ret["masses"], ret["atoms"].natoms
                pos = unit_to_internal(ret["units"][0], ret["units"][1],
                                       ret["atoms"].q)
                ret = read_file("xyz", ifor[i])
                force = unit_to_internal(ret["units"][0], ret["units"][1],
                                         ret["atoms"].q)
                if natoms == 0:
                    natoms = n
                    q = np.zeros((nbeads, 3 * natoms))
                    f = np.zeros((nbeads, 3 * natoms))
                q[i, :] = pos
                f[i, :] = force
            time, U = read_U(iU)
        except EOFError:  # finished reading files
            sys.exit(0)

        if ifr < skipSteps:
            time0 = time

        if ifr >= skipSteps:  # PPI correction
            time -= time0

            ePA, f2, f2ePA = 0.0, 0.0, 0.0
            eVir, rc = 0.0, np.zeros(3)

            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])
            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 *= (0.5 * nbeads * (Constants.kb * temperature)**2 /
                    Constants.hbar**2)
            ePA += 0.5 * nbeads * (3 * natoms) * Constants.kb * temperature + U
            f2ePA = f2 * ePA
            eVir /= 2.0 * nbeads
            eVir += 0.5 * (3 * natoms) * Constants.kb * temperature + U

            ePA_av += ePA
            f2_av += f2
            f2ePA_av += f2ePA
            eVir_av += eVir
            ifr += 1
            print((ifr - skipSteps
                   ))  # Printing current time frame (excluding thermalization)

            dE = (3.0 * Constants.kb * temperature +
                  ePA_av / float(ifr - skipSteps)) * f2_av / float(
                      ifr - skipSteps) - f2ePA_av / float(ifr - skipSteps)
            dE *= Constants.hbar**2 / (
                24.0 * (nbeads * Constants.kb * temperature)**3)

            dE = unit_to_user(
                "energy", potentialEnergyUnit,
                dE)  # Output in the same unit as potential energy
            eVir = unit_to_user(
                "energy", potentialEnergyUnit,
                eVir_av / float(ifr - skipSteps))  # Output in the same unit
            # as potential energy

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

        else:
            ifr += 1
def potentialEnergy(prefix, temp, ss=0, unit=''):
    """
    Computes the estimator for the potential 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, U_av, f2U_av = 0.0, 0.0, 0.0  # some required sums

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

    # Extracting the number of beads
    nbeads = len(fns_for)

    # print some information
    print 'temperature = {:f} K'.format(float(temp))
    print
    print 'number of beads = {:d}'.format(nbeads)
    print
    print 'forces file names:'
    for fn_for in fns_for:
        print '{:s}'.format(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
    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 = 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), potential energy and PPI potential energy corrections (in %s)\n"
        % (timeUnit, unit))

    natoms = 0
    ifr = 0
    time0 = 0
    f, m = 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", ifor[i], output='arrays')
                if natoms == 0:
                    m, natoms = ret["masses"], ret["natoms"]
                    f = np.zeros((nbeads, 3 * natoms))
                f[i, :] = ret["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

            f2 = 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]

            else:
                f2 = fortran.f2divm(np.array(f, order='F'),
                                    np.array(m, order='F'), natoms, nbeads)

            U_av += U
            f2_av += f2
            f2U_av += f2 * U
            ifr += 1

            norm = float(ifr - skipSteps)

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

            dU = unit_to_user("energy", unit, dU)
            U = unit_to_user("energy", unit, U_av / float(ifr - skipSteps))

            iE.write("%f    %f     %f\n" % (time, U, dU))

        else:
            ifr += 1
Exemple #36
0
def test_case_insensitive():

    angstrom = units.unit_to_internal("length", "angstrom", 1.0)
    Angstrom = units.unit_to_internal("length", "Angstrom", 1.0)
    if angstrom != Angstrom:
        raise ValueError("angstrom != Angstrom")
Exemple #37
0
def test_case_insensitive():

    angstrom = units.unit_to_internal('length', 'angstrom', 1.0)
    Angstrom = units.unit_to_internal('length', 'Angstrom', 1.0)
Exemple #38
0
    def init_stage1(self, simul):
        """Initializes the simulation -- first stage.

      Takes a simulation object, and uses all the data in the initialization
      queue to fill up the beads and cell data needed to run the simulation.

      Args:
         simul: A simulation object to be initialized.

      Raises:
         ValueError: Raised if there is a problem with the initialization,
            if something that should have been has not been, or if the objects
            that have been specified are not compatible with each other.
      """

        if simul.beads.nbeads == 0:
            fpos = fmom = fmass = flab = fcell = False  # we don't have an explicitly defined beads object yet
        else:
            fpos = fmom = fmass = flab = fcell = True

        for (k, v) in self.queue:
            info(" # Initializer (stage 1) parsing " + str(k) + " object.",
                 verbosity.high)

            if k == "cell":
                if fcell:
                    warning("Overwriting previous cell parameters",
                            verbosity.medium)
                if v.mode == "pdb":
                    rh = init_pdb(v.value)[1].h
                elif v.mode == "chk":
                    rh = init_chk(v.value)[1].h
                else:
                    rh = v.value.reshape((3, 3))
                rh *= unit_to_internal("length", v.units, 1.0)

                simul.cell.h = rh
                if simul.cell.V == 0.0:
                    ValueError("Cell provided has zero volume")

                fcell = True
            elif k == "masses":
                if simul.beads.nbeads == 0:
                    raise ValueError(
                        "Cannot initialize the masses before the size of the system is known"
                    )
                if fmass:
                    warning("Overwriting previous atomic masses",
                            verbosity.medium)
                if v.mode == "manual":
                    rm = v.value
                else:
                    rm = init_beads(v, self.nbeads).m
                rm *= unit_to_internal("mass", v.units, 1.0)

                if v.bead < 0:  # we are initializing the path
                    if (fmom and fmass):
                        warning(
                            "Rescaling momenta to make up for changed mass",
                            verbosity.medium)
                        simul.beads.p /= simul.beads.sm3  # go to mass-scaled momenta, that are mass-invariant
                    if v.index < 0:
                        simul.beads.m = rm
                    else:  # we are initializing a specific atom
                        simul.beads.m[v.index:v.index + 1] = rm
                    if (fmom and fmass):  # finishes correcting the momenta
                        simul.beads.p *= simul.beads.sm3  # back to normal momenta
                else:
                    raise ValueError("Cannot change the mass of a single bead")
                fmass = True

            elif k == "labels":
                if simul.beads.nbeads == 0:
                    raise ValueError(
                        "Cannot initialize the labels before the size of the system is known"
                    )
                if flab:
                    warning("Overwriting previous atomic labels",
                            verbosity.medium)
                if v.mode == "manual":
                    rn = v.value
                else:
                    rn = init_beads(v, self.nbeads).names

                if v.bead < 0:  # we are initializing the path
                    if v.index < 0:
                        simul.beads.names = rn
                    else:  # we are initializing a specific atom
                        simul.beads.names[v.index:v.index + 1] = rn
                else:
                    raise ValueError(
                        "Cannot change the label of a single bead")
                flab = True

            elif k == "positions":
                if fpos:
                    warning("Overwriting previous atomic positions",
                            verbosity.medium)
                # read the atomic positions as a vector
                rq = init_vector(v, self.nbeads)
                rq *= unit_to_internal("length", v.units, 1.0)
                (nbeads, natoms) = rq.shape
                natoms /= 3

                # check if we must initialize the simulation beads
                if simul.beads.nbeads == 0:
                    if v.index >= 0:
                        raise ValueError(
                            "Cannot initialize single atoms before the size of the system is known"
                        )
                    simul.beads.resize(natoms, self.nbeads)

                set_vector(v, simul.beads.q, rq)
                fpos = True

            elif (
                    k == "velocities" or k == "momenta"
            ) and v.mode == "thermal":  # intercept here thermal initialization, so we don't need to check further down
                if fmom:
                    warning("Overwriting previous atomic momenta",
                            verbosity.medium)
                if simul.beads.natoms == 0:
                    raise ValueError(
                        "Cannot initialize momenta before the size of the system is known."
                    )
                if not fmass:
                    raise ValueError(
                        "Trying to resample velocities before having masses.")

                rtemp = v.value * unit_to_internal("temperature", v.units, 1.0)
                if rtemp <= 0:
                    warning(
                        "Using the simulation temperature to resample velocities",
                        verbosity.low)
                    rtemp = simul.ensemble.temp
                else:
                    info(
                        " # Resampling velocities at temperature %s %s" %
                        (v.value, v.units), verbosity.low)

                # pull together a mock initialization to get NM masses right
                #without too much code duplication
                if v.bead >= 0:
                    raise ValueError("Cannot thermalize a single bead")
                if v.index >= 0:
                    rnatoms = 1
                else:
                    rnatoms = simul.beads.natoms
                rbeads = Beads(rnatoms, simul.beads.nbeads)
                if v.index < 0:
                    rbeads.m[:] = simul.beads.m
                else:
                    rbeads.m[:] = simul.beads.m[v.index]
                rnm = NormalModes(mode=simul.nm.mode,
                                  transform_method=simul.nm.transform_method,
                                  freqs=simul.nm.nm_freqs)
                rens = Ensemble(dt=simul.ensemble.dt, temp=simul.ensemble.temp)
                rnm.bind(rbeads, rens)
                # then we exploit the sync magic to do a complicated initialization
                # in the NM representation
                # with (possibly) shifted-frequencies NM
                rnm.pnm = simul.prng.gvec(
                    (rbeads.nbeads, 3 * rbeads.natoms)) * np.sqrt(
                        rnm.dynm3) * np.sqrt(
                            rbeads.nbeads * rtemp * Constants.kb)

                if v.index < 0:
                    simul.beads.p = rbeads.p
                else:
                    simul.beads.p[:, 3 * v.index:3 * (v.index + 1)] = rbeads.p
                fmom = True

            elif k == "momenta":
                if fmom:
                    warning("Overwriting previous atomic momenta",
                            verbosity.medium)
                # read the atomic momenta as a vector
                rp = init_vector(v, self.nbeads, momenta=True)
                rp *= unit_to_internal("momentum", v.units, 1.0)
                (nbeads, natoms) = rp.shape
                natoms /= 3

                # checks if we must initialize the simulation beads
                if simul.beads.nbeads == 0:
                    if v.index >= 0:
                        raise ValueError(
                            "Cannot initialize single atoms before the size of the system is known"
                        )
                    simul.beads.resize(natoms, self.nbeads)

                rp *= np.sqrt(self.nbeads / nbeads)
                set_vector(v, simul.beads.p, rp)
                fmom = True

            elif k == "velocities":
                if fmom:
                    warning("Overwriting previous atomic momenta",
                            verbosity.medium)
                # read the atomic velocities as a vector
                rv = init_vector(v, self.nbeads)
                rv *= unit_to_internal("velocity", v.units, 1.0)
                (nbeads, natoms) = rv.shape
                natoms /= 3

                # checks if we must initialize the simulation beads
                if simul.beads.nbeads == 0 or not fmass:
                    ValueError(
                        "Cannot initialize velocities before the masses of the atoms are known"
                    )
                    simul.beads.resize(natoms, self.nbeads)

                warning(
                    "Initializing from velocities uses the previously defined masses -- not the masses inferred from the file -- to build momenta",
                    verbosity.low)
                if v.index >= 0:
                    rv *= simul.beads.m[v.index]
                elif v.bead >= 0:
                    rv *= simul.beads.m3[0]
                else:
                    rv *= simul.beads.m3
                rv *= np.sqrt(self.nbeads / nbeads)
                set_vector(v, simul.beads.p, rv)
                fmom = True
            elif k == "thermostat":
                pass  # thermostats must be initialized in a second stage

        if simul.beads.natoms == 0:
            raise ValueError(
                "Initializer could not initialize the atomic positions")
        if simul.cell.V == 0:
            raise ValueError("Initializer could not initialize the cell")
        for i in range(simul.beads.natoms):
            if simul.beads.m[i] <= 0:
                raise ValueError("Initializer could not initialize the masses")
            if simul.beads.names[i] == "":
                raise ValueError(
                    "Initializer could not initialize the atom labels")
        if not fmom:
            warning(
                "Momenta not specified in initialize. Will start with zero velocity if they are not specified in beads.",
                verbosity.low)
Exemple #39
0
def totalEnergy(prefix, temp, ss=0):
    """
    Computes the virial centroid estimator for the total energy and PPI correction.
    """

    global temperature, skipSteps

    temperature = unit_to_internal("temperature", "kelvin", float(temp))
    skipSteps = int(ss)

    f2_av, ePA_av, eVir_av, f2ePA_av = 0.0, 0.0, 0.0, 0.0  # average square forces, virial and primitive energy
    # estimators, and the product of the primitive energy estimator and square forces

    ipos = []  # input positions files
    for filename in sorted(glob.glob(prefix + ".pos*")):
        ipos.append(open(filename, "r"))

    ifor = []  # input forces files
    for filename in sorted(glob.glob(prefix + ".for*")):
        ifor.append(open(filename, "r"))

    iU = None  # input potential energy and simulation time file
    for filename in sorted(glob.glob(prefix + ".out")):
        iU = open(filename, "r")

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

    iE = open(prefix + ".energy" + ".dat", "w")
    iE.write("# Simulation time (in %s), virial total energy and PPI energy correction (in %s)\n" %
             (timeUnit, potentialEnergyUnit))

    nbeads = len(ipos)
    if (nbeads != len(ifor)): raise ValueError("Mismatch between number of output files for forces and positions")
    natoms = 0
    ifr = 0
    time0 = 0
    q, f, m = None, None, None
    while True:  # Reading input files and calculating PPI correction
        try:
            for i in range(nbeads):
                ret = read_file("xyz", ipos[i])
                m, n = ret["masses"], ret["atoms"].natoms
                pos = unit_to_internal(ret["units"][0], ret["units"][1], ret["atoms"].q)
                ret = read_file("xyz", ifor[i])
                force = unit_to_internal(ret["units"][0], ret["units"][1], ret["atoms"].q)
                if natoms == 0:
                    natoms = n
                    q = np.zeros((nbeads, 3 * natoms))
                    f = np.zeros((nbeads, 3 * natoms))
                q[i, :] = pos
                f[i, :] = force
            time, U = read_U(iU)
        except EOFError:  # finished reading files
            sys.exit(0)

        if ifr < skipSteps:
            time0 = time

        if ifr >= skipSteps:  # PPI correction
            time -= time0

            ePA, f2, f2ePA = 0.0, 0.0, 0.0
            eVir, rc = 0.0, np.zeros(3)

            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]
            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 *= 0.5 * nbeads * (Constants.kb * temperature)**2 / Constants.hbar**2
            ePA += 0.5 * nbeads * (3 * natoms) * Constants.kb * temperature + U
            f2ePA = f2 * ePA
            eVir /= 2.0 * nbeads
            eVir += 0.5 * (3 * natoms) * Constants.kb * temperature + U

            ePA_av += ePA
            f2_av += f2
            f2ePA_av += f2ePA
            eVir_av += eVir
            ifr += 1
            print(ifr - skipSteps)  # Printing current time frame (excluding thermalization)

            dE = (3.0 * Constants.kb * temperature + ePA_av / float(ifr - skipSteps)) * f2_av / float(ifr - skipSteps) - \
                f2ePA_av / float(ifr - skipSteps)
            dE *= Constants.hbar**2 / (24.0 * (nbeads * Constants.kb * temperature)**3)

            dE = unit_to_user("energy", potentialEnergyUnit, dE)  # Output in the same unit as potential energy
            eVir = unit_to_user("energy", potentialEnergyUnit, eVir_av / float(ifr - skipSteps))  # Output in the same unit
            # as potential energy

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

        else:
            ifr += 1
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
Exemple #41
0
# This file is part of i-PI.
# i-PI Copyright (C) 2014-2015 i-PI developers
# See the "licenses" directory for full license information.

import filecmp
import os

import numpy as np
from numpy.testing import assert_equal

from ipi_tests.unit_tests.common.folder import local
from ipi.utils.units import unit_to_internal
from ipi.utils.io import iter_file, read_file, print_file

pos_xyz = np.array([i for i in range(3 * 3)])
pos_pdb = unit_to_internal("length", "angstrom", pos_xyz)


def test_read_xyz():
    """Tests that xyz files are read correctly."""

    with open(local("test.pos_0.xyz"), "r") as f:
        ret = read_file("xyz", f)
        atoms = ret["atoms"]
        assert len(atoms) == 3
        assert_equal(pos_xyz, atoms.q)


def test_iter_xyz():
    """Tests that xyz files with multiple frames are read correctly."""
def main(prefix, temp):

    T = float(temp)
    fns_pos = sorted(glob.glob(prefix + ".pos*"))
    fns_for = sorted(glob.glob(prefix + ".for*"))
    fn_out_kin = prefix + ".kin.xyz"
    fn_out_kod = prefix + ".kod.xyz"

    # 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(T)
    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 'output file names:'
    print fn_out_kin
    print fn_out_kod
    print

    temp = unit_to_internal("energy", "kelvin", T)

    # open input and output files
    ipos = [open(fn, "r") for fn in fns_pos]
    ifor = [open(fn, "r") for fn in fns_for]
    ikin = open(fn_out_kin, "w")
    ikod = open(fn_out_kod, "w")

    natoms = 0
    ifr = 0
    while True:

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

        # load one frame
        try:
            for i in range(nbeads):
                ret = read_file("xyz", ipos[i])
                pos = ret["atoms"]
                ret = read_file("xyz", ifor[i])
                force = ret["atoms"]
                if natoms == 0:
                    natoms = pos.natoms
                    beads = Beads(natoms, nbeads)
                    forces = Beads(natoms, nbeads)
                    kcv = np.zeros((natoms, 6), float)
                beads[i].q = pos.q
                forces[i].q = force.q
        except EOFError:
            # finished reading files
            break

        # calculate kinetic energies
        q = dstrip(beads.q)
        f = dstrip(forces.q)
        qc = dstrip(beads.qc)
        kcv[:] = 0
        for j in range(nbeads):
            for i in range(natoms):
                kcv[i, 0] += (q[j, i * 3 + 0] - qc[i * 3 + 0]) * f[j, i * 3 + 0]
                kcv[i, 1] += (q[j, i * 3 + 1] - qc[i * 3 + 1]) * f[j, i * 3 + 1]
                kcv[i, 2] += (q[j, i * 3 + 2] - qc[i * 3 + 2]) * f[j, i * 3 + 2]
                kcv[i, 3] += (q[j, i * 3 + 0] - qc[i * 3 + 0]) * f[j, i * 3 + 1] + (q[j, i * 3 + 1] - qc[i * 3 + 1]) * f[j, i * 3 + 0]
                kcv[i, 4] += (q[j, i * 3 + 0] - qc[i * 3 + 0]) * f[j, i * 3 + 2] + (q[j, i * 3 + 2] - qc[i * 3 + 2]) * f[j, i * 3 + 0]
                kcv[i, 5] += (q[j, i * 3 + 1] - qc[i * 3 + 1]) * f[j, i * 3 + 2] + (q[j, i * 3 + 2] - qc[i * 3 + 2]) * f[j, i * 3 + 1]
        kcv *= -0.5 / nbeads
        kcv[:, 0:3] += 0.5 * Constants.kb * temp
        kcv[:, 3:6] *= 0.5

        # write output
        ikin.write("%d\n# Centroid-virial kinetic energy estimator [a.u.] - diagonal terms: xx yy zz\n" % natoms)
        ikod.write("%d\n# Centroid-virial kinetic energy estimator [a.u.] - off-diag terms: xy xz yz\n" % natoms)
        for i in range(natoms):
            ikin.write("%8s %12.5e %12.5e %12.5e\n" % (pos.names[i], kcv[i, 0], kcv[i, 1], kcv[i, 2]))
            ikod.write("%8s %12.5e %12.5e %12.5e\n" % (pos.names[i], kcv[i, 3], kcv[i, 4], kcv[i, 5]))

        ifr += 1

    print '\rProcessed {:d} frames.'.format(ifr)

    ikin.close()
    ikod.close()
Exemple #43
0
# if not (os.path.exists(ipi_path)):
#    print 'We can not find ipi in %s' %ipi_path
#    print 'Please correct the path'
#    sys.exit()
# sys.path.insert(0, ipi_path)

from ipi.engine.simulation import Simulation
from ipi.utils.units import unit_to_internal, Constants
from ipi.utils.instools import red2comp
from ipi.utils.hesstools import clean_hessian
from ipi.engine.motion.instanton import SpringMapper

# np.set_printoptions(precision=6, suppress=True, threshold=np.nan)

# UNITS
K2au = unit_to_internal("temperature", "kelvin", 1.0)
kb = Constants.kb
hbar = Constants.hbar
eV2au = unit_to_internal("energy", "electronvolt", 1.0)
cal2au = unit_to_internal("energy", "cal/mol", 1.0)
cm2au = unit_to_internal("frequency", "hertz", 1.0) * 3e10

# INPUT
parser = argparse.ArgumentParser(
    description="""Post-processing routine in order to obtain different quantities from an instanton (or instanton related) calculation. These quantities can be used for the calculation of rates or tunneling splittings in the instanton approximation."""
)
parser.add_argument("input", help="Restart file")
parser.add_argument(
    "-c",
    "--case",
    default=False,
    print 'We will expand the ring polymer to get a half polymer of %i beads.' % nbeadsNew

    # Compose the full ring polymer.
    #q2 = np.concatenate((q, np.flipud(q)), axis=0)

    # Make the rpc step
    #rpc = nm_rescale(2 * nbeads, 2 * nbeadsNew)
    #new_q = rpc.b1tob2(q2)[0:nbeadsNew]
    rpc = nm_rescale(nbeads, nbeadsNew,
                     np.asarray(range(natoms)))  # We use open path RPC
    new_q = rpc.b1tob2(q)

    # Print
    out = open("NEW_INSTANTON.xyz", "w")
    for i in range(nbeadsNew):
        atom.q = new_q[i] / unit_to_internal("length", "angstrom",
                                             1.0)  # Go back to angstrom
        print_file("xyz",
                   atom,
                   cell,
                   out,
                   title='cell{atomic_unit}  Traj: positions{angstrom}')
        # print_file("xyz",pos[0],cell,out,title='cell  }')
    out.close()

    print 'The new Instanton geometry (half polymer) was generated'
    print 'Check NEW_INSTANTON.xyz'
    print ''
    print 'Remeber to change the number of beads (%i) in your input' % nbeadsNew
    print ''

if input_hess != 'None' or chk != 'None':
Exemple #45
0
def effectiveTemperatures(prefix, temp, ss=0):
    """
    Computes effective temperatures for a given (PI)MD dynamics.
    """

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

    f2_av = None  # average square forces array
    names = None

    fns_for = sorted(glob.glob(prefix + ".for*"))
    fn_out = prefix + ".effective_temperatures.dat"

    nbeads = len(fns_for)

    # print some information
    print("temperature = {:f} K".format(float(temp)))
    print()
    print("number of beads = {:d}".format(nbeads))
    print()
    print("forces file names:")
    for fn_for in fns_for:
        print("{:s}".format(fn_for))
    print()
    print("output file name:")
    print(fn_out)
    print()

    # open input and output files
    ifor = [open(fn, "r") for fn in fns_for]
    iOut = open(fn_out, "w")

    # Some constants
    const = Constants.hbar**2 / (12.0 * (nbeads * Constants.kb * temperature) ** 3)

    iOut.write(
        "# Atom, Cartesian components of the effective temperature, average effective temperature (in Kelvin)\n"
    )

    natoms = 0
    ifr = 0
    f, m = 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", ifor[i], dimension="force")["atoms"]
                if natoms == 0:
                    m, natoms, names = ret.m, ret.natoms, ret.names
                    f = np.zeros((nbeads, 3 * natoms))
                    f2_av = np.zeros(3 * natoms)
                f[i, :] = ret.q
        except EOFError:  # finished reading files
            break

        if ifr >= skipSteps:  # PPI correction

            f2 = np.zeros(3 * natoms)
            for i in range(natoms):
                for j in range(nbeads):
                    f2[i * 3 : i * 3 + 3] += f[j, i * 3 : i * 3 + 3] ** 2 / m[i]

            f2_av[:] += f2[:]
            ifr += 1

        else:
            ifr += 1

    dT = const * f2_av / float(ifr - skipSteps)

    temperature = unit_to_user("temperature", "kelvin", temperature)

    for i in range(natoms):
        iOut.write(
            "%s    %f     %f     %f     %f\n"
            % (
                names[i],
                temperature * (1 + dT[i * 3]),
                temperature * (1 + dT[i * 3 + 1]),
                temperature * (1 + dT[i * 3 + 2]),
                temperature * (1 + np.sum(dT[i * 3 : i * 3 + 3]) / 3.0),
            )
        )

    for f in ifor:
        f.close()

    iOut.close()
Exemple #46
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
Exemple #47
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
def contract_trajectory(fns_in, fn_out_template, n_new, cell_units_in,
                        cell_units_out):

    verbosity.level = "low"
    n = len(fns_in)

    # Generate output file names.
    if n_new == 1:
        fns_out = [fn_out_template]
    else:
        fns_out = [fn_out_template.format(i) for i in range(n_new)]

    print("Contracting {:d} beads to {:d} beads.".format(n, n_new))
    print()

    print("input file names:")
    for fn in fns_in:
        print(fn)
    print()

    print("output file names:")
    for fn in fns_out:
        print(fn)
    print()

    # Open input trajectory iterators.
    trjs_in = [iter_file_name_raw(fn) for fn in fns_in]
    mode = os.path.splitext(fn)[-1]

    # Open output files.
    fs_out = [open_backup(fn, "w") for fn in fns_out]
    mode_out = os.path.splitext(fn_out_template)[-1]

    # prepare ring polymer rescaler
    rescale = nm_rescale(n, n_new)

    # Loop over all frames.
    i_frame = 0
    while True:
        try:
            # Get the frames for all beads.
            frames = [trj.next() for trj in trjs_in]
        except StopIteration:
            # Stop when any of the trajectories runs out of frames.
            break

        # gets units from first frame
        dimension, units, cell_units = auto_units(comment=frames[0]["comment"],
                                                  cell_units=cell_units_in)
        if cell_units_out == "automatic":
            cell_units_out = cell_units  # re-use units unless otherwise specified

        # Consistency check.
        h = frames[0]["cell"]
        natoms = len(frames[0]["data"]) / 3
        for i in range(n):

            # Check that all the cells are the same.
            if (frames[i]["cell"] != h).any():
                msg = "Cell for beads {:d} and {:d} differ in frame {:d}."
                raise ValueError(msg.format(0, i, i_frame))

            # Check that the numbers of atoms are the same.
            if len(frames[i]["data"]) != 3 * natoms:
                msg = "Different numbers of atoms for beads {:d} and {:d} in frame {:d}."
                raise ValueError(msg.format(0, i, i_frame))

        cell = Cell()
        cell.h = frames[0]["cell"]
        atoms = Atoms(natoms)
        atoms.names = frames[0]["names"]

        # Compose the ring polymer.
        q = np.vstack([frame["data"] for frame in frames]) * unit_to_internal(
            dimension, units, 1)  # units transformation

        # Contract the coordinates to `n_new` beads.
        q_c = rescale.b1tob2(q)

        # Save the output data.
        for i, f_out in enumerate(fs_out):
            atoms.q = q_c[i, :]
            print_file(mode_out,
                       atoms,
                       cell,
                       f_out,
                       dimension=dimension,
                       units=units,
                       cell_units=cell_units_out)

        # Count frames and print information on progress.
        i_frame += 1
        if i_frame % 100 == 0:
            print("\rframe {:d}".format(i_frame), end="")
        sys.stdout.flush()

    for f_out in fs_out:
        f_out.close()

    print()
    print()
    print("Processed {:d} frames.".format(i_frame))
Exemple #49
0
def compute_acf(input_file, output_prefix, maximum_lag, block_length,
                length_zeropadding, spectral_windowing, labels, timestep, skip,
                der):

    # stores the arguments
    ifile = str(input_file)
    ofile = str(output_prefix)
    mlag = int(maximum_lag)
    bsize = int(block_length)
    npad = int(length_zeropadding)
    ftbox = str(spectral_windowing)
    labels = str(labels)
    timestep = str(timestep).split()
    fskip = int(skip)

    # checks for errors
    if (mlag <= 0):
        raise ValueError("MAXIMUM_LAG should be a non-negative integer.")
    if (npad < 0):
        raise ValueError(
            "LENGTH_ZEROPADDING should be a non-negative integer.")
    if (bsize < 2 * mlag):
        if (bsize == -1):
            bsize = 2 * mlag
        else:
            raise ValueError(
                "LENGTH_BLOCK should be greater than or equal to 2 * MAXIMUM_LAG."
            )

    # reads one frame.
    ff = open(ifile)
    rr = read_file_raw("xyz", ff)
    ff.close()

    # appends "der" to output file in case the acf of the derivative is desired
    if (der == True):
        ofile = ofile + "_der"

    # stores the indices of the "chosen" atoms.
    ndof = len(rr['data'])
    if ("*" in labels):
        labelbool = np.ones(ndof / 3, bool)
    else:
        labelbool = np.zeros(ndof / 3, bool)
        for l in labels:
            labelbool = np.logical_or(labelbool, rr['names'] == l)
    nspecies = labelbool.sum()

    # initializes variables.
    nblocks = 0
    dt = unit_to_internal("time", timestep[1], float(timestep[0]))
    data = np.zeros((bsize, nspecies, 3), float)
    time = np.asarray(list(range(mlag + 1))) * dt
    omega = np.asarray(list(range(2 * (mlag + npad)))) / float(
        2 * (mlag + npad)) * (2 * np.pi / dt)
    fvvacf = omega.copy() * 0.0
    fvvacf2 = fvvacf.copy() * 0.0
    vvacf = time.copy() * 0.0
    vvacf2 = time.copy() * 0.0

    # selects window function for fft.
    if (ftbox == "none"):
        win = np.ones(2 * mlag + 1, float)
    elif (ftbox == "cosine-hanning"):
        win = np.hanning(2 * mlag + 1)
    elif (ftbox == "cosine-hamming"):
        win = np.hamming(2 * mlag + 1)
    elif (ftbox == "cosine-blackman"):
        win = np.blackman(2 * mlag + 1)
    elif (ftbox == "triangle-bartlett"):
        win = np.bartlett(2 * mlag + 1)

    ff = open(ifile)
    # Skips the first fskip frames
    for x in range(fskip):
        rr = read_file_raw("xyz", ff)

    while True:

        try:
            # Reads the data in blocks.
            for i in range(bsize):
                rr = read_file_raw("xyz", ff)
                data[i] = rr['data'].reshape((ndof / 3, 3))[labelbool]

            if (der == True):
                data = np.gradient(data, axis=0) / dt

            # Computes the Fourier transform of the data.
            fdata = np.fft.rfft(data, axis=0)

            # Computes the Fourier transform of the vvac applying the convolution theorem.
            tfvvacf = fdata * np.conjugate(fdata)

            # Averages over all species and sums over the x,y,z directions. Also multiplies with the time step and a prefactor of (2pi)^-1.
            mfvvacf = 3.0 * np.real(np.mean(
                tfvvacf, axis=(1, 2))) * dt / (2 * np.pi) / bsize

            # Computes the inverse Fourier transform to get the vvac.
            mvvacf = np.fft.irfft(mfvvacf)[:mlag + 1]

            # Applies window in one direction and pads the vvac with zeroes.
            mpvvacf = np.append(mvvacf * win[mlag:], np.zeros(npad))

            # Recomputes the Fourier transform assuming the data is an even function of time.
            mfpvvacf = np.fft.hfft(mpvvacf)

            # Accumulates the (f)acfs and their squares.
            fvvacf += mfpvvacf
            fvvacf2 += mfpvvacf**2
            vvacf += mvvacf
            vvacf2 += mvvacf**2

            nblocks += 1

        except EOFError:
            break
    ff.close()

    # Performs the block average of the Fourier transform.
    fvvacf = fvvacf / nblocks
    fvvacf_err = np.sqrt(fvvacf2 / nblocks - fvvacf**2)

    np.savetxt(ofile + "_facf.data", np.c_[omega, fvvacf,
                                           fvvacf_err][:mlag + npad])

    # Computes the inverse Fourier transform to get the vvac.
    vvacf = vvacf / nblocks
    vvacf_err = np.sqrt(vvacf2 / nblocks - vvacf**2)
    np.savetxt(ofile + "_acf.data", np.c_[time, vvacf,
                                          vvacf_err][:mlag + npad])
# if not (os.path.exists(ipi_path)):
#    print 'We can not find ipi in %s' %ipi_path
#    print 'Please correct the path'
#    sys.exit()
# sys.path.insert(0, ipi_path)

from ipi.engine.simulation import Simulation
from ipi.utils.units import unit_to_internal, unit_to_user, Constants, Elements
from ipi.utils.instools import red2comp, clean_hessian
from ipi.engine.motion.instanton import SpringMapper

np.set_printoptions(precision=6, suppress=True, threshold=np.nan)

# UNITS
K2au = unit_to_internal("temperature", "kelvin", 1.0)
kb = Constants.kb
hbar = Constants.hbar
eV2au = unit_to_internal("energy", "electronvolt", 1.0)
cal2au = unit_to_internal("energy", "cal/mol", 1.0)
au2hz = unit_to_internal("frequency", "hertz", 1.0)
cm2au = au2hz * 3e10

# INPUT
parser = argparse.ArgumentParser(description="""Post-processing routine in order to obtain different quantities from an instanton (or instanton related) calculation. These quantities can be used for the calculation of rates or tunneling splittings in the instanton approximation.""")
parser.add_argument('input', help="Restart file")
parser.add_argument('-c', '--case', default=False, help="Type of the calculation to analyse. Options: 'instanton', 'reactant' or 'TS'.")
parser.add_argument('-t', '--temperature', type=float, default=0.0, help="Temperature in K.")
parser.add_argument('-asr', '--asr', default='poly', help="Removes the zero frequency vibrational modes depending on the symmerty of the system")
parser.add_argument('-e', '--energy_shift', type=float, default=0.0, help="Zero of energy in eV")
parser.add_argument('-f', '--filter', default=[], help='List of atoms indexes to filter (i.e. eliminate its componentes in the position,mass and hessian arrays. It is 0 based.', type=int, action='append')