def check_rpc_consistency(n, q): """Check if q expanding and then contracting a ring polymer is a no-op. Args: n: The number of beads in the scaled ring polymer. q: The original position array. """ rescale1 = nmtransform.nm_rescale(q.shape[0], n) rescale2 = nmtransform.nm_rescale(n, q.shape[0]) beads_n = rescale1.b1tob2(q) beads_1 = rescale1.b2tob1(beads_n) beads_2 = rescale2.b1tob2(beads_n) assert_equals(beads_1, beads_2)
def check_rpc_consistency(n, q): """Check if q expanding and then contracting a ring polymer is a no-op. Args: n: The number of beads in the scaled ring polymer. q: The original position array. """ rescale1 = nmtransform.nm_rescale(q.shape[0], n) rescale2 = nmtransform.nm_rescale(n, q.shape[0]) beads_n = rescale1.b1tob2(q) beads_1 = rescale1.b2tob1(beads_n) beads_2 = rescale2.b1tob2(beads_n) assert_almost_equal(beads_1, beads_2)
def set_vector(iif, dq, rq): """Initializes a vector from an another vector. If the first dimension is different, i.e. the two vectors correspond to a different number of beads, then the ring polymer contraction/expansion is used to rescale the original vector to the one used in the simulation, as described in the paper T. E. Markland and D. E. Manolopoulos, J. Chem. Phys. 129, 024105, (2008). Args: iif: An Initializer object specifying the value of a vector. dq: The vector to be initialized. rq: The vector to initialize from. """ (nbeads, natoms) = rq.shape natoms //= 3 (dbeads, datoms) = dq.shape datoms //= 3 # Check that indices make sense if iif.index < 0 and natoms != datoms: raise ValueError( "Initialization tries to mix up structures with different atom numbers." ) if iif.index >= datoms: raise ValueError( "Cannot initialize single atom as atom index %d is larger than the number of atoms" % iif.index ) if iif.bead >= dbeads: raise ValueError( "Cannot initialize single bead as bead index %d is larger than the number of beads" % iif.bead ) if iif.bead < 0: # we are initializing the path res = nm_rescale(nbeads, dbeads) # path rescaler if nbeads != dbeads: info( " # Initialize is rescaling from %5d beads to %5d beads" % (nbeads, dbeads), verbosity.low, ) if iif.index < 0: dq[:] = res.b1tob2(rq) else: # we are initializing a specific atom dq[:, 3 * iif.index : 3 * (iif.index + 1)] = res.b1tob2(rq) else: # we are initializing a specific bead if iif.index < 0: dq[iif.bead] = rq else: dq[iif.bead, 3 * iif.index : 3 * (iif.index + 1)] = rq
def set_vector(iif, dq, rq): """Initializes a vector from an another vector. If the first dimension is different, i.e. the two vectors correspond to a different number of beads, then the ring polymer contraction/expansion is used to rescale the original vector to the one used in the simulation, as described in the paper T. E. Markland and D. E. Manolopoulos, J. Chem. Phys. 129, 024105, (2008). Args: iif: An Initializer object specifying the value of a vector. dq: The vector to be initialized. rq: The vector to initialize from. """ (nbeads, natoms) = rq.shape natoms /= 3 (dbeads, datoms) = dq.shape datoms /= 3 # Check that indices make sense if iif.index < 0 and natoms != datoms: raise ValueError("Initialization tries to mix up structures with different atom numbers.") if iif.index >= datoms: raise ValueError("Cannot initialize single atom as atom index %d is larger than the number of atoms" % iif.index) if iif.bead >= dbeads: raise ValueError("Cannot initialize single bead as bead index %d is larger than the number of beads" % iif.bead) if iif.bead < 0: # we are initializing the path res = nm_rescale(nbeads, dbeads) # path rescaler if nbeads != dbeads: info(" # Initialize is rescaling from %5d beads to %5d beads" % (nbeads, dbeads), verbosity.low) if iif.index < 0: dq[:] = res.b1tob2(rq) else: # we are initializing a specific atom dq[:, 3 * iif.index:3 * (iif.index + 1)] = res.b1tob2(rq) else: # we are initializing a specific bead if iif.index < 0: dq[iif.bead] = rq else: dq[iif.bead, 3 * iif.index:3 * (iif.index + 1)] = rq
def check_up_and_down_scaling(n, q): """Check if q expanding and then contracting a ring polymer is a no-op. Args: n: The number of beads in the scaled ring polymer. q: The original position array. """ rescale = nmtransform.nm_rescale(q.shape[0], n) print("Initial position of the beads:") print(q, q.shape, (q.shape[0], n)) # rescale up to the n beads beads_n = rescale.b1tob2(q) print("Upscaled to %d beads:" % n) print(beads_n, beads_n.shape) beads_final = rescale.b2tob1(beads_n) print("Final position of the beads:") print(beads_final) assert_almost_equal(q, beads_final) return beads_n
def check_up_and_down_scaling(n, q): """Check if q expanding and then contracting a ring polymer is a no-op. Args: n: The number of beads in the scaled ring polymer. q: The original position array. """ rescale = nmtransform.nm_rescale(q.shape[0], n) print "Initial position of the beads:" print q, q.shape, (q.shape[0], n) # rescale up to the n beads beads_n = rescale.b1tob2(q) print "Upscaled to %d beads:" % n print beads_n, beads_n.shape beads_final = rescale.b2tob1(beads_n) print "Final position of the beads:" print beads_final assert_equals(q, beads_final) return beads_n
def bind(self, beads, cell, fcomponents, fflist): """Binds beads, cell and forces to the forcefield. Args: beads: Beads object from which the bead positions are taken. cell: Cell object from which the system box is taken. fcomponents: A list of different objects for each force type. For example, if ring polymer contraction is being used, then there may be separate forces for the long and short range part of the potential. fflist: A list of forcefield objects to use to calculate the potential, forces and virial for each force type. To clarify: fcomponents are the names and parameters of forcefields that are active for a certain system. fflist contains the overall list of force providers, and one typically has just one per force kind. """ self.natoms = beads.natoms self.nbeads = beads.nbeads self.beads = beads self.cell = cell self.bound = True self.nforces = len(fcomponents) self.fcomp = fcomponents self.ff = fflist # fflist should be a dictionary of forcefield objects self.mforces = [] self.mbeads = [] self.mrpc = [] dself = dd(self) # a "function factory" to generate functions to automatically update # contracted paths def make_rpc(rpc, beads): return lambda: rpc.b1tob2(dstrip(beads.q)) # creates new force objects, possibly acting on contracted path # representations for fc in self.fcomp: # creates an automatically-updated contracted beads object newb = fc.nbeads # if the number of beads for this force component is unspecified, # assume full force evaluation if newb == 0 or newb > beads.nbeads: newb = beads.nbeads newforce = ForceComponent(ffield=fc.ffield, name=fc.name, nbeads=newb, weight=fc.weight, mts_weights=fc.mts_weights, epsilon=fc.epsilon) newbeads = Beads(beads.natoms, newb) newrpc = nm_rescale(beads.nbeads, newb) # the beads positions for this force components are obtained # automatically, when needed, as a contraction of the full beads dd(newbeads).q._func = make_rpc(newrpc, beads) for b in newbeads: # must update also indirect access to the beads coordinates dd(b).q._func = dd(newbeads).q._func # makes newbeads.q depend from beads.q dd(beads).q.add_dependant(dd(newbeads).q) # now we create a new forcecomponent which is bound to newbeads! newforce.bind(newbeads, cell, fflist) # adds information we will later need to the appropriate lists. self.mbeads.append(newbeads) self.mforces.append(newforce) self.mrpc.append(newrpc) # now must expose an interface that gives overall forces dself.f = depend_array(name="f", value=np.zeros((self.nbeads, 3 * self.natoms)), func=self.f_combine, dependencies=[dd(ff).f for ff in self.mforces]) # collection of pots and virs from individual ff objects dself.pots = depend_array(name="pots", value=np.zeros(self.nbeads, float), func=self.pot_combine, dependencies=[dd(ff).pots for ff in self.mforces]) # must take care of the virials! dself.virs = depend_array(name="virs", value=np.zeros((self.nbeads, 3, 3), float), func=self.vir_combine, dependencies=[dd(ff).virs for ff in self.mforces]) dself.extras = depend_value(name="extras", value=np.zeros(self.nbeads, float), func=self.extra_combine, dependencies=[dd(ff).extras for ff in self.mforces]) # total potential and total virial dself.pot = depend_value(name="pot", func=(lambda: self.pots.sum()), dependencies=[dself.pots]) dself.vir = depend_array(name="vir", func=self.get_vir, value=np.zeros((3, 3)), dependencies=[dself.virs]) # SC forces and potential dself.alpha = depend_value(name="alpha", value=0.0) # The number of MTS levels dself.nmtslevels = depend_value(name="nmtslevels", value=0, func=self.get_nmtslevels) # This will be piped from normalmodes dself.omegan2 = depend_value(name="omegan2", value=0) # The Suzuki-Chin difference potential dself.potssc = depend_array(name="potssc", value=np.zeros(self.nbeads, float), dependencies=[dd(self.beads).m, dself.f, dself.pots, dself.alpha, dself.omegan2], func=self.get_potssc) dself.potsc = depend_value(name="potsc", dependencies=[dself.potssc], func=(lambda: self.potssc.sum())) # The coefficients of the physical and the |f|^2 terms dself.coeffsc_part_1 = depend_array(name="coeffsc_part_1", value=np.zeros((self.nbeads, 1), float), func=self.get_coeffsc_part_1) dself.coeffsc_part_2 = depend_array(name="coeffsc_part_2", value=np.zeros((self.nbeads, 1), float), dependencies=[dself.alpha, dself.omegan2], func=self.get_coeffsc_part_2) # A list that contains the high order component of the force and the virial dself.fvir_4th_order = depend_value(name="fvir_4th_order", value=[None, None], dependencies=[dd(self.beads).m, dself.f, dself.pots], func=self.fvir_4th_order_combine) # The high order component of the Suzuki-Chin force. dself.f_4th_order = depend_array(name="f_4th_order", value=np.zeros((self.nbeads, 3 * self.natoms), float), dependencies=[dself.fvir_4th_order], func=(lambda: self.fvir_4th_order[0])) dself.fsc_part_1 = depend_array(name="fsc_part_1", value=np.zeros((self.nbeads, 3 * self.natoms), float), dependencies=[dself.coeffsc_part_1, dself.f], func=self.get_fsc_part_1) dself.fsc_part_2 = depend_array(name="fsc_part_2", value=np.zeros((self.nbeads, 3 * self.natoms), float), dependencies=[dself.coeffsc_part_2, dself.f_4th_order], func=self.get_fsc_part_2) dself. fsc = depend_array(name="fsc", value=np.zeros((self.nbeads, 3 * self.natoms), float), dependencies=[dself.fsc_part_1, dself.fsc_part_2], func=self.get_fsc) # The high order component of the Suzuki-Chin virial. dself.virs_4th_order = depend_array(name="vir_4th_order", value=np.zeros((self.nbeads, 3, 3), float), dependencies=[dself.fvir_4th_order], func=(lambda: self.fvir_4th_order[1])) dself.virssc_part_1 = depend_array(name="virssc_part_1", value=np.zeros((self.nbeads, 3, 3), float), dependencies=[dself.coeffsc_part_1, dself.virs], func=self.get_virssc_part_1) dself.virssc_part_2 = depend_array(name="virssc_part_2", value=np.zeros((self.nbeads, 3, 3), float), dependencies=[dself.coeffsc_part_2, dself.virs_4th_order], func=self.get_virssc_part_2) dself.virssc = depend_array(name="virssc", value=np.zeros((self.nbeads, 3, 3), float), dependencies=[dself.virssc_part_1, dself.virssc_part_2], func=self.get_virssc) dself.virsc = depend_value(name="potsc", dependencies=[dself.potssc], func=(lambda: np.sum(self.virssc, axis=0))) # Add dependencies from the force weights, that are applied here when the total # force is assembled from its components for fc in self.mforces: dself.f.add_dependency(dd(fc).weight) dself.pots.add_dependency(dd(fc).weight) dself.virs.add_dependency(dd(fc).weight)
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))
nbeads = beads.nbeads q = beads.q atom = beads._blist[0] print ' ' 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()
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 bind(self, beads, cell, flist): self.natoms = beads.natoms self.nbeads = beads.nbeads self.nforces = len(flist) # flist should be a list of tuples containing ( "name", forcebeads) self.mforces = [] self.mbeads = [] self.mweights = [] self.mrpc = [] # a "function factory" to generate functions to automatically update #contracted paths def make_rpc(rpc, beads): return lambda: rpc.b1tob2(depstrip(beads.q)) # creates new force objects, possibly acting on contracted path #representations for (ftype, fbeads) in flist: # creates an automatically-updated contracted beads object newb = fbeads.nbeads newforce = fbeads.copy() newweight = fbeads.weight # if the number of beads for this force component is unspecified, #assume full force evaluation if newb == 0: newb = beads.nbeads newforce.nbeads = newb newbeads = Beads(beads.natoms, newb) newrpc = nm_rescale(beads.nbeads, newb) dget(newbeads,"q")._func = make_rpc(newrpc, beads) for b in newbeads: # must update also indirect access to the beads coordinates dget(b,"q")._func = dget(newbeads,"q")._func # makes newbeads.q depend from beads.q dget(beads,"q").add_dependant(dget(newbeads,"q")) #now we create a new forcebeads which is bound to newbeads! newforce.bind(newbeads, cell) #adds information we will later need to the appropriate lists. self.mweights.append(newweight) self.mbeads.append(newbeads) self.mforces.append(newforce) self.mrpc.append(newrpc) #now must expose an interface that gives overall forces dset(self,"f", depend_array(name="f",value=np.zeros((self.nbeads,3*self.natoms)), func=self.f_combine, dependencies=[dget(ff, "f") for ff in self.mforces] ) ) # collection of pots and virs from individual ff objects dset(self,"pots", depend_array(name="pots", value=np.zeros(self.nbeads,float), func=self.pot_combine, dependencies=[dget(ff, "pots") for ff in self.mforces]) ) # must take care of the virials! dset(self,"virs", depend_array(name="virs", value=np.zeros((self.nbeads,3,3),float), func=self.vir_combine, dependencies=[dget(ff, "virs") for ff in self.mforces]) ) dset(self,"extras", depend_value(name="extras", value=np.zeros(self.nbeads,float), func=self.extra_combine, dependencies=[dget(ff, "extras") for ff in self.mforces])) # total potential and total virial dset(self,"pot", depend_value(name="pot", func=(lambda: self.pots.sum()), dependencies=[dget(self,"pots")])) dset(self,"vir", depend_array(name="vir", func=self.get_vir, value=np.zeros((3,3)), dependencies=[dget(self,"virs")]))
atom = beads._blist[0] print(' ') print('We have a half ring polymer made of {} beads and {} atoms.'.format(nbeads, natoms)) print('We will expand the ring polymer to get a half polymer of {} beads.'.format(nbeadsNew)) # Make the rpc step (standar) # q2 = np.concatenate((q, np.flipud(q)), axis=0) # Compose the full ring polymer. # rpc = nm_rescale(2 * nbeads, 2 * nbeadsNew) # new_q = rpc.b1tob2(q2)[0:nbeadsNew] # Make the rpc step (instanton) # rpc = nm_rescale(nbeads, nbeadsNew,instanton=True) # new_q = rpc.b1tob2(q ) # Make the rpc step (open path) rpc = nm_rescale(nbeads, nbeadsNew, np.asarray(range(natoms))) 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("Don't forget to change the number of beads to the new value ({}) in your input file".format(nbeadsNew)) print('when starting your new simulation with an increased number of beads.')
def bind(self, beads, cell, fcomponents, fflist): """Binds beads, cell and forces to the forcefield. Args: beads: Beads object from which the bead positions are taken. cell: Cell object from which the system box is taken. fcomponents: A list of different objects for each force type. For example, if ring polymer contraction is being used, then there may be separate forces for the long and short range part of the potential. fflist: A list of forcefield objects to use to calculate the potential, forces and virial for each force type. To clarify: fcomponents are the names and parameters of forcefields that are active for a certain system. fflist contains the overall list of force providers, and one typically has just one per force kind. """ self.natoms = beads.natoms self.nbeads = beads.nbeads self.beads = beads self.cell = cell self.bound = True self.nforces = len(fcomponents) self.fcomp = fcomponents self.ff = fflist # fflist should be a dictionary of forcefield objects self.mforces = [] self.mbeads = [] self.mrpc = [] # a "function factory" to generate functions to automatically update #contracted paths def make_rpc(rpc, beads): return lambda: rpc.b1tob2(depstrip(beads.q)) # creates new force objects, possibly acting on contracted path #representations for fc in self.fcomp: # creates an automatically-updated contracted beads object newb = fc.nbeads # if the number of beads for this force component is unspecified, # assume full force evaluation if newb == 0: newb = beads.nbeads newforce = ForceComponent(ffield=fc.ffield, name=fc.name, nbeads=newb, weight=fc.weight, mts_weights=fc.mts_weights) newbeads = Beads(beads.natoms, newb) newrpc = nm_rescale(beads.nbeads, newb) # the beads positions for this force components are obtained # automatically, when needed, as a contraction of the full beads dget(newbeads,"q")._func = make_rpc(newrpc, beads) for b in newbeads: # must update also indirect access to the beads coordinates dget(b,"q")._func = dget(newbeads,"q")._func # makes newbeads.q depend from beads.q dget(beads,"q").add_dependant(dget(newbeads,"q")) #now we create a new forcecomponent which is bound to newbeads! newforce.bind(newbeads, cell, fflist) #adds information we will later need to the appropriate lists. self.mbeads.append(newbeads) self.mforces.append(newforce) self.mrpc.append(newrpc) #now must expose an interface that gives overall forces dset(self,"f", depend_array(name="f",value=np.zeros((self.nbeads,3*self.natoms)), func=self.f_combine, dependencies=[dget(ff, "f") for ff in self.mforces] ) ) # collection of pots and virs from individual ff objects dset(self,"pots", depend_array(name="pots", value=np.zeros(self.nbeads,float), func=self.pot_combine, dependencies=[dget(ff, "pots") for ff in self.mforces]) ) # must take care of the virials! dset(self,"virs", depend_array(name="virs", value=np.zeros((self.nbeads,3,3),float), func=self.vir_combine, dependencies=[dget(ff, "virs") for ff in self.mforces]) ) dset(self,"extras", depend_value(name="extras", value=np.zeros(self.nbeads,float), func=self.extra_combine, dependencies=[dget(ff, "extras") for ff in self.mforces])) # total potential and total virial dset(self,"pot", depend_value(name="pot", func=(lambda: self.pots.sum()), dependencies=[dget(self,"pots")])) dset(self,"vir", depend_array(name="vir", func=self.get_vir, value=np.zeros((3,3)), dependencies=[dget(self,"virs")])) # SC forces and potential dset(self, "alpha", depend_value(name="alpha", value=0.5)) # this will be piped from normalmodes dset(self, "omegan2", depend_value(name="alpha", value=0)) dset(self, "SCCALC", depend_value(name="SCCALC", func=self.sccalc, value = [None,None], dependencies=[dget(self, "f"), dget(self,"pots"), dget(self,"alpha"), dget(self,"omegan2")] ) ) dset(self, "fsc", depend_array(name="fsc",value=np.zeros((self.nbeads,3*self.natoms)), dependencies=[dget(self,"SCCALC")], func=(lambda: self.SCCALC[1] ) ) ) dset(self, "potsc", depend_value(name="potsc", dependencies=[dget(self,"SCCALC") ], func=(lambda: self.SCCALC[0] ) ) )
natoms = simulation.syslist[0].motion.beads.natoms nbeads = beads.nbeads q = beads.q atom = beads._blist[0] print ' ' 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 ''
def contract_trajectory(fns_in, fn_out_template, n_new): 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(fn) for fn in fns_in] # 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 # Consistency check. h = frames[0]["cell"].h natoms = frames[0]["atoms"].natoms for i in range(n): # Check that all the cells are the same. if (frames[i]["cell"].h != 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 frames[i]["atoms"].natoms != natoms: msg = "Different numbers fo atoms for beads {:d} and {:d} in frame {:d}." raise ValueError(msg.format(0, i, i_frame)) # Reuse the first frame for output. cell = frames[0]["cell"] atoms = frames[0]["atoms"] # Compose the ring polymer. q = np.vstack([frame["atoms"].q for frame in frames]) # 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) # Count frames and print information on progress. i_frame += 1 if i_frame % 100 == 0: print "\rframe {:d}".format(i_frame), sys.stdout.flush() for f_out in fs_out: f_out.close() print print print "Processed {:d} frames.".format(i_frame)
print(" ") print( "We have a half ring polymer made of {} beads and {} atoms.".format( nbeads, natoms ) ) print( "We will expand the ring polymer to get a half polymer of {} beads.".format( nbeadsNew ) ) # Make the rpc step (standard). It is better that open path in some corner cases. q2 = np.concatenate((q, np.flipud(q)), axis=0) # Compose the full ring polymer. rpc = nm_rescale(2 * nbeads, 2 * nbeadsNew) new_q = rpc.b1tob2(q2)[0:nbeadsNew] # Make the rpc step (open path) # rpc = nm_rescale(nbeads, nbeadsNew, np.asarray(range(natoms))) # 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}" )