def runParallelSims(simnumber): # Define particle list, sometimes begin in unbound state (or transition region) and sometimes in state A or B. seed = int(simnumber) random.seed(seed) choice = random.randint(1, 3) if choice == 1: partlist = particleTools.randomParticleList(Nparticles, boxsize, separationDistance, D, Drot, seed) if choice == 2: partlist = generateParticleList('A', boxsize, D, Drot, seed) if choice == 3: partlist = generateParticleList('B', boxsize, D, Drot, seed) # Integrator definition seed = int( -1 * simnumber ) # random seed (negative and different for every simulation, good for parallelization) integrator = odLangevin(dt, seed, bodytype) integrator.setBoundary(boxBoundary) integrator.setPairPotential(potentialPatchyParticleAngular) # Creates simulation sim = msmrd2.simulation(integrator) # Output filename definition filename = basefilename + "_{:04d}".format(simnumber) # Runs simulation sim.run(partlist, timesteps, stride, bufferSize, filename, outTxt, outH5, outChunked, trajtype) print("Simulation " + str(simnumber) + ", done.")
def simulationFPT(trajectorynum): ''' Calculates first passage time of a trajectory with random initial conditions and final state a bound state :param trajectorynum: number of trajectories on which to calculate the FPT :return: state, first passage time ''' # Define dummy trajectory to extract bound states from python (needed to use getState function) dummyTraj = msmrd2.trajectories.patchyDimer(2, 1, radialBounds[0], minimumUnboundRadius) # Define simulation boundaries (choose either spherical or box) boxBoundary = msmrd2.box(boxsize, boxsize, boxsize, 'periodic') # Define potential potentialPatchyParticleAngular = patchyParticleAngular(sigma, strength, angularStrength, patchesCoordinates) # Define integrator and boundary (over-damped Langevin) seed = int(-1*trajectorynum) # Negative seed, uses random device as seed integrator = odLangevin(dt, seed, bodytype) integrator.setBoundary(boxBoundary) integrator.setPairPotential(potentialPatchyParticleAngular) # Generate random position and orientation particle list with two particles seed = int(trajectorynum) partlist = generateParticleList(initialState, boxsize, D, Drot, seed) # Calculates the first passage times for a given bound state. Each trajectory is integrated until # the target bound state is reached. The output in the files is the elapsed time. intransition = True while(intransition): integrator.integrate(partlist) currentState = dummyTraj.getState(partlist[0], partlist[1]) if targetState == 'A' and currentState in boundStatesA: intransition = False return 'A', integrator.clock elif targetState == 'B' and currentState in boundStatesB: intransition = False return 'B', integrator.clock elif integrator.clock >= 10000.0: intransition = False return 'Failed at:', integrator.clock
def calculateDiffusionCoefficeints(numparticles): ''' :param numparticles: must have a value between 1 and 5 :return: translational diffusion coefficeint and rotational diffusion coefficient ''' simulationSuccess = False # Define particle list with between two and five particles to estimate the diffusion # of dimers/ trimers / cuatrimers? and pentamer pyPartlist = [] # Position List for pentamer IC for i in range(numparticles): position = 0.85 * np.array([np.cos(th * i), np.sin(th * i), 0.0]) orientation = np.array([ np.cos(0.5 * (thextra - th * i)), 0, 0, np.sin(0.5 * (thextra - th * i)) ]) part = msmrd2.particle(D, Drot, position, quats.conjugate(orientation)) pyPartlist.append(part) # Create list of particles that can be read from msmrd # Note the particles in this list will be independent from the python list. partlist = msmrd2.integrators.particleList(pyPartlist) # Over-damped Langevin integrator definition #0.000005 seed = -1 #1 #-1 # Negative seed, uses random device as seed bodytype = 'rigidbody' integrator = odLangevin(dt, seed, bodytype) # Define Patchy Particle potential if numparticles > 1: potentialPatchyParticleAngular2 = patchyParticleAngular2( sigma, strength, angularStrength, patchesCoordinates) integrator.setPairPotential(potentialPatchyParticleAngular2) # Define arrays to calculate autocorrelation functions pentamerPositionArray = [] pentamerOrientationArray = [] #Integrate particle list and print only positions cross = [None] * 2 if outputVMD: datafile = open('../../data/vmd/pentamerTest.xyz', 'w') for i in range(timesteps): if i % stride == 0: if outputVMD: datafile.write(str(3 * len(partlist) + 3) + '\n') datafile.write(str(0) + '\n') if numparticles == 1: pentamerPositionArray.append(partlist[0].position) pentamerOrientationArray.append(partlist[0].orientation) else: # Calculate and plot center of pentamer position relpos = partlist[1].position - partlist[0].position relposnorm = np.linalg.norm(relpos) if (relposnorm >= 1.5): return simulationSuccess, 0, 0 relpos = relpos / relposnorm patch1 = 0.5 * sigma * quats.rotateVec(patchesCoordinates[0], partlist[0].orientation) patch2 = 0.5 * sigma * quats.rotateVec(patchesCoordinates[1], partlist[0].orientation) cross[0] = np.cross(relpos, patch1) cross[1] = np.cross(relpos, patch2) maxIndex = np.argmax(np.linalg.norm(cross, axis=1)) rotAxis = cross[maxIndex] / np.linalg.norm(cross[maxIndex]) rotation = 3 * np.pi * rotAxis / 10.0 quatRotation = quats.angle2quat(rotation) pentamerCenter = 0.85 * quats.rotateVec(relpos, quatRotation) pentamerCenter = pentamerCenter + partlist[0].position pentamerPositionArray.append(pentamerCenter) # Calculate and plot orientation of pentamer (using only the orientation of particle 0) orientation0 = np.array( [np.cos(0.5 * (thextra)), 0, 0, np.sin(0.5 * (thextra))]) vec1 = 0.85 * np.array( [1., 0., 0.]) + 0.5 * sigma * quats.rotateVec( patchesCoordinates[0], orientation0) vec2 = 0.85 * np.array( [1., 0., 0.]) + 0.5 * sigma * quats.rotateVec( patchesCoordinates[1], orientation0) rotVec1 = partlist[0].position + 0.5 * sigma * quats.rotateVec( patchesCoordinates[0], partlist[0].orientation) rotVec2 = partlist[0].position + 0.5 * sigma * quats.rotateVec( patchesCoordinates[1], partlist[0].orientation) pentamerOrientation = quats.recoverRotationFromVectors(np.array([0.,0.,0.]), vec1, vec2, \ pentamerCenter, rotVec1, rotVec2) pentamerOrientationArray.append(pentamerOrientation) if outputVMD: # Calculate cross reference v0 = pentamerCenter v1 = v0 + 0.25 * quats.rotateVec(refVec4, pentamerOrientation) v2 = v0 + 0.25 * quats.rotateVec(refVec5, pentamerOrientation) # Plot cross reference datafile.write('type_2' + ' ' + ' '.join(map(str, v0)) + '\n') datafile.write('type_3' + ' ' + ' '.join(map(str, v1)) + '\n') datafile.write('type_3' + ' ' + ' '.join(map(str, v2)) + '\n') if outputVMD: for j, part in enumerate(partlist): if i % stride == 0: v0 = part.position v1 = v0 + 0.5 * sigma * quats.rotateVec( patchesCoordinates[0], part.orientation) v2 = v0 + 0.5 * sigma * quats.rotateVec( patchesCoordinates[1], part.orientation) datafile.write('type_0' + ' ' + ' '.join(map(str, v0)) + '\n') datafile.write('type_1' + ' ' + ' '.join(map(str, v1)) + '\n') datafile.write('type_1' + ' ' + ' '.join(map(str, v2)) + '\n') integrator.integrate(partlist) if i % 10000 == 0: print("Percentage complete: ", 100 * i / timesteps, "%", end="\r") if outputVMD: datafile.close() # Generate TCL script to visualize with VMD msmrdvis.generateTCL_pentamerTest( numparticles=numparticles, outfname='pentamerTest', tclfname='../../data/vmd/pentamerTest_2vmd.tcl') print("Simulation complete: ", 100, " % w/", numparticles, " particles") # Calculate auto-correlation/mean-square displacement for several lagtimes tsteps = len(pentamerPositionArray) lagtimesIndexes = np.arange(100, 2000, 100) #np.arange(1,20,1) lagtimes = np.zeros(len(lagtimesIndexes) + 1) MSD_3D = np.zeros(len(lagtimesIndexes) + 1) MSD_3D_orientation = np.zeros(len(lagtimesIndexes) + 1) for i, lagtimeIndex in enumerate(lagtimesIndexes): lagtimes[i + 1] = dt * lagtimeIndex * stride MSD = 0.0 MSD_orientation = 0.0 for j in range(tsteps - lagtimeIndex): dr = pentamerPositionArray[j + lagtimeIndex] - pentamerPositionArray[j] dq = pentamerOrientationArray[ j + lagtimeIndex] - pentamerOrientationArray[j] MSD += dr * dr MSD_orientation += dq * dq MSD = MSD / (tsteps - lagtimeIndex + 1) MSD_3D[i + 1] = sum(MSD) # D = sum(MSD)/(6*lagtime) MSD_orientation = MSD_orientation / (tsteps - lagtimeIndex + 1) MSD_3D_orientation[i + 1] = sum(MSD_orientation[1:]) # Least square approximation with numpy A = np.vstack([lagtimes, np.ones(len(lagtimes))]).T slope, b = np.linalg.lstsq(A, MSD_3D / 6, rcond=None)[0] #print(slope,b) # Least square approximation with numpy (rotation) y = -np.log(1 - 4 * MSD_3D_orientation / 3.0) / 2 slope2, b2 = np.linalg.lstsq(A, y, rcond=None)[0] #print(slope2,b2) print("Estimated diffusion coefficients") # Plot MSD against lagtime and fits plt.plot(lagtimes, MSD_3D / 6, 'o', label='position') plt.plot(lagtimes, -np.log(1 - 4 * MSD_3D_orientation / 3.0) / 2, 'o', label='orientation') plt.plot(lagtimes, slope * lagtimes + b, '-', label='position fit') plt.plot(lagtimes, slope2 * lagtimes + b2, '-', label='orientation fit') plt.legend() plt.savefig(Diffdirectory + 'diffusionFitPentamer_' + str(numparticles) + 'particles.pdf', bbox_inches='tight') plt.close() print("Finished plots") Dapprox = slope DrotApprox = slope2 simulationSuccess = True return simulationSuccess, Dapprox, DrotApprox