def execute(self, obj, event): print self.timer_count self.textActor.SetInput('Time: %s' % self.timer_count) r_vectors = bm.get_boomerang_r_vectors_15( self.locations[self.n * TIME_SKIP], Quaternion(self.orientations[self.n * TIME_SKIP])) for k in range(N_SPHERES): self.sources[k].SetCenter(r_vectors[k][0], r_vectors[k][1], r_vectors[k][2]) if DRAW_COH: coh = bm.calculate_boomerang_coh( self.locations[self.n * TIME_SKIP], Quaternion(self.orientations[self.n * TIME_SKIP])) cod = bm.calculate_boomerang_cod( self.locations[self.n * TIME_SKIP], Quaternion(self.orientations[self.n * TIME_SKIP])) self.coh_source.SetCenter(coh) self.cod_source.SetCenter(cod) iren = obj iren.GetRenderWindow().Render() if WRITE: self.w2if.Update() self.w2if.Modified() self.lwr.SetFileName( os.path.join('.', 'figures', 'frame' + ('%03d' % self.n) + '.png')) self.lwr.Write() self.timer_count += 0.01 * TIME_SKIP self.n += 1
def non_sphere_rejection(partitionZ): # generate heights and their corresponding probabilities until a height passes unrejected orientation = Quaternion([0.,0.,0.,0.]) new_location = np.array([0., 0., 0.]) while True: orientation.random_orientation() new_location[2] = np.random.uniform(A, max_height-A) acceptance_prob = non_sphere_GB(new_location, orientation) / partitionZ if acceptance_prob > 1: raise InvalidProbability('Acceptance Probability is greater than 1') if np.random.uniform(0., 1.) < acceptance_prob: # the rejection part of the algorithm. return [new_location, orientation]
def generate_non_sphere_partition(partition_steps): partitionZ = 0. #for i in range(100): # new_location = [0., 0., np.random.uniform(A, max_height)] # partitionZ += non_sphere_GB(location,new_location) orientation = Quaternion([0,0,0,0]) new_location = np.array([0., 0., 0.]) for i in range(partition_steps): orientation.random_orientation() new_location[2] = np.random.uniform(A, max_height) sample = non_sphere_GB(new_location, orientation) if sample > partitionZ: partitionZ = sample return partitionZ
def generate_non_sphere_partition(partition_steps): partitionZ = 0. #for i in range(100): # new_location = [0., 0., np.random.uniform(A, max_height)] # partitionZ += non_sphere_GB(location,new_location) orientation = Quaternion([0, 0, 0, 0]) new_location = np.array([0., 0., 0.]) for i in range(partition_steps): orientation.random_orientation() new_location[2] = np.random.uniform(A, max_height) sample = non_sphere_GB(new_location, orientation) if sample > partitionZ: partitionZ = sample return partitionZ
def non_sphere_rejection(partitionZ): # generate heights and their corresponding probabilities until a height passes unrejected orientation = Quaternion([0., 0., 0., 0.]) new_location = np.array([0., 0., 0.]) while True: orientation.random_orientation() new_location[2] = np.random.uniform(A, max_height - A) acceptance_prob = non_sphere_GB(new_location, orientation) / partitionZ if acceptance_prob > 1: raise InvalidProbability( 'Acceptance Probability is greater than 1') if np.random.uniform( 0., 1.) < acceptance_prob: # the rejection part of the algorithm. return [new_location, orientation]
def Update_Bodies_no_lub(self, FT_calc): ''' Euler Maruyama method with no lubrication corrections (just RPY) ''' r_vecs_np = [b.location for b in self.bodies] r_vecs = self.put_r_vecs_in_periodic_box(r_vecs_np, self.periodic_length) FT = FT_calc(self.bodies, r_vecs) FT = FT.flatten() FT = FT[:, np.newaxis] velocities = self.Stochastic_Velocity_From_FT_no_lub(FT) for k, b in enumerate(self.bodies): b.location_new = b.location + velocities[6 * k:6 * k + 3] * self.dt quaternion_dt = Quaternion.from_rotation( (velocities[6 * k + 3:6 * k + 6]) * self.dt) b.orientation_new = quaternion_dt * b.orientation reject_wall = 0 reject_jump = 0 reject_wall, reject_jump = self.Check_Update_With_Jump() self.num_rejections_wall += reject_wall self.num_rejections_jump += reject_jump if (reject_wall + reject_jump) == 0: L = self.periodic_length for b in self.bodies: b.location = b.location_new b.orientation = b.orientation_new return reject_wall, reject_jump
def Update_Bodies(self, FT): ''' Updates the positions and orientations of the bodies using stochastic velocity from Euler Maruyama (computed from `Stochastic_Velocity_From_FT') ''' velocities = self.Stochastic_Velocity_From_FT(FT) for k, b in enumerate(self.bodies): b.location_new = b.location + velocities[6 * k:6 * k + 3] * self.dt quaternion_dt = Quaternion.from_rotation( (velocities[6 * k + 3:6 * k + 6]) * self.dt) b.orientation_new = quaternion_dt * b.orientation reject_wall = 0 reject_jump = 0 reject_wall, reject_jump = self.Check_Update_With_Jump() self.num_rejections_wall += reject_wall self.num_rejections_jump += reject_jump if (reject_wall + reject_jump) == 0: L = self.periodic_length for b in self.bodies: b.location = b.location_new b.orientation = b.orientation_new self.Set_R_Mats() ######## VERY IMPORTANT return reject_wall, reject_jump
def calculate_mu_friction_and_height_distribution(bin_width, height_histogram): ''' Calculate average mu parallel and fricton using rectangle rule. Populate height histogram with equilibrium distribution. TODO: Make this use trapezoidal rule. ''' for k in range(len(height_histogram)): h = sph.A + bin_width * (k + 0.5) height_histogram[k] = gibbs_boltzmann_distribution([0., 0., h]) # Normalize to get ~PDF. height_histogram /= sum(height_histogram) * bin_width # Calculate Mu and gamma. average_mu = 0. average_gamma = 0. # Just choose an arbitrary orientation, since it won't affect the # distribution. initial_orientation = [Quaternion([1., 0., 0., 0.])] for k in range(len(height_histogram)): h = sph.A + bin_width * (k + 0.5) mobility = sph.sphere_mobility([np.array([0., 0., h])], initial_orientation) average_mu += (mobility[0, 0] + mobility[1, 1]) * height_histogram[k] * bin_width average_gamma += height_histogram[k] * bin_width / mobility[0, 0] return [average_mu, average_gamma]
def generate_boomerang_equilibrium_sample(n_precompute=20000): ''' Use accept-reject to generate a sample with location and orientation from the Gibbs Boltzmann distribution for the Boomerang. This function is best used to generate many samples at once, as there is significant overhead involved in precomputing the normalization factor. normalization_constants is a dictionary that stores an estimated normalization constant for each value of the sum of mass. ''' max_height = KT / sum(M) * 12 + A + 4. * DEBYE_LENGTH # TODO: Figure this out a better way that includes repulsion. # Get a rough upper bound on max height. norm_constants = generate_boomerang_equilibrium_sample.normalization_constants if sum(M) in norm_constants.keys(): normalization_factor = norm_constants[sum(M)] else: # Estimate normalization constant from random samples # and store it. max_normalization = 0. for k in range(n_precompute): theta = np.random.normal(0., 1., 4) orientation = Quaternion(theta / np.linalg.norm(theta)) location = [0., 0., np.random.uniform(A, max_height)] accept_prob = boomerang_gibbs_boltzmann_distribution( location, orientation) if accept_prob > max_normalization: max_normalization = accept_prob norm_constants[sum(M)] = max_normalization normalization_factor = max_normalization while True: theta = np.random.normal(0., 1., 4) orientation = Quaternion(theta / np.linalg.norm(theta)) location = [0., 0., np.random.uniform(A, max_height)] accept_prob = boomerang_gibbs_boltzmann_distribution( location, orientation) / (2.5 * normalization_factor) if accept_prob > 1.: print('Accept probability %s is greater than 1' % accept_prob) if np.random.uniform(0., 1.) < accept_prob: return [location, orientation]
def test_get_boomerang_r_vectors(self): ''' Test that we get the correct R vectors for some simple orientations.''' # pi/2 rotation around the x axis. theta = Quaternion([np.cos(np.pi / 4.), np.sin(np.pi / 4.), 0., 0.]) location = [0., 0., 5.] r_vectors = bmr.get_boomerang_r_vectors(location, theta) self.assertAlmostEqual(r_vectors[0][0], 1.575) self.assertAlmostEqual(r_vectors[0][1], 0.0) self.assertAlmostEqual(r_vectors[0][2], 5.0) self.assertAlmostEqual(r_vectors[4][0], 0.0) self.assertAlmostEqual(r_vectors[4][1], 0.0) self.assertAlmostEqual(r_vectors[4][2], 5.525) self.assertAlmostEqual(r_vectors[6][0], 0.0) self.assertAlmostEqual(r_vectors[6][1], 0.0) self.assertAlmostEqual(r_vectors[6][2], 6.575) # pi/2 rotation around the y axis. theta = Quaternion([np.cos(np.pi / 4.), 0., np.sin(np.pi / 4.), 0.]) r_vectors = bmr.get_boomerang_r_vectors(location, theta) self.assertAlmostEqual(r_vectors[0][0], 0.0) self.assertAlmostEqual(r_vectors[0][1], 0.0) self.assertAlmostEqual(r_vectors[0][2], 5.0 - 1.575) self.assertAlmostEqual(r_vectors[4][0], 0.0) self.assertAlmostEqual(r_vectors[4][1], 0.525) self.assertAlmostEqual(r_vectors[4][2], 5.0) self.assertAlmostEqual(r_vectors[6][0], 0.0) self.assertAlmostEqual(r_vectors[6][1], 1.575) self.assertAlmostEqual(r_vectors[6][2], 5.0) # pi/2 rotation around the z axis. theta = Quaternion([np.cos(np.pi / 4.), 0., 0., np.sin(np.pi / 4.)]) r_vectors = bmr.get_boomerang_r_vectors(location, theta) self.assertAlmostEqual(r_vectors[0][0], 0.0) self.assertAlmostEqual(r_vectors[0][1], 1.575) self.assertAlmostEqual(r_vectors[0][2], 5.0) self.assertAlmostEqual(r_vectors[4][0], -0.525) self.assertAlmostEqual(r_vectors[4][1], 0.0) self.assertAlmostEqual(r_vectors[4][2], 5.0) self.assertAlmostEqual(r_vectors[6][0], -1.575) self.assertAlmostEqual(r_vectors[6][1], 0.0) self.assertAlmostEqual(r_vectors[6][2], 5.0)
def load_equilibrium_sample(f): ''' Load an equilibrium sample from a given file. f = file object. should be opened, and parameters should already be read through. File is generated by the populate_gibbs_sample.py script. ''' line = f.readline() items = line.split(',') position = [float(x) for x in items[0:3]] orientation = Quaternion([float(x) for x in items[3:7]]) return [position, orientation]
def test_boomerang_mobility_spd(self): ''' Test that the mobility is SPD for random configuration. ''' theta = np.random.normal(0., 1., 4) theta = Quaternion(theta / np.linalg.norm(theta)) location = [np.random.uniform(2.5, 4.) for _ in range(3)] mobility = bmr.boomerang_mobility([location], [theta]) def is_pos_def(x): return np.all(np.linalg.eigvals(x) > 0) self.assertTrue(is_pos_def(mobility)) for j in range(6): for k in range(j + 1, 6): self.assertAlmostEqual(mobility[j][k], mobility[k][j])
def test_sphere_mobility_entries_make_sense(self): #'''Test that we get the expected sign for the entries of the sphere mobility.''' print(' sphere_mobility_entries_make_sense') location = [np.random.normal(4.0, 1.0, 3)] theta = np.random.normal(0., 1., 4) theta = Quaternion(theta / np.linalg.norm(theta)) mobility = sph.sphere_mobility(location, theta) # Check that translation results are positive self.assertTrue(mobility[0, 0] > 0.) self.assertAlmostEqual(mobility[0, 0], mobility[1, 1]) self.assertTrue(mobility[2, 2] > 0.) # Check rotation results are positive self.assertTrue(mobility[3, 3] > 0.) self.assertAlmostEqual(mobility[4, 4], mobility[3, 3]) self.assertTrue(mobility[5, 5] > 0.)
def test_sphere_mobility_spd(self): '''Test that the sphere mobility is SPD.''' location = [np.random.normal(4.0, 1.0, 3)] theta = np.random.normal(0., 1., 4) theta = Quaternion(theta / np.linalg.norm(theta)) mobility = sph.sphere_mobility(location, theta) def is_pos_def(x): return np.all(np.linalg.eigvals(x) > 0) self.assertTrue(is_pos_def(mobility)) for j in range(6): for k in range(j + 1, 6): self.assertAlmostEqual(mobility[j][k], mobility[k, j]) print(' test_sphere_mobility_spd')
def read_clones_file(name_file): ''' It reads a file with the initial locations and orientation of the rigid bodies. Input: name_file = string. Output: locations = locations of rigid bodies, numpy array shape (Nbodies, 3). orientations = orientations of rigid bodies, numpy array of Quaternions, shape (Nbodies). ''' comment_symbols = ['#'] with open(name_file, 'r') as f: locations = [] orientations = [] i = 0 for line in f: # Strip comments if comment_symbols[0] in line: line, comment = line.split(comment_symbols[0], 1) # Ignore blank lines line = line.strip() if line != '': if i == 0: number_of_bodies = int(line.split()[0]) else: data = line.split() location = [float(data[0]), float(data[1]), float(data[2])] orientation = [ float(data[3]), float(data[4]), float(data[5]), float(data[6]) ] norm_orientation = np.linalg.norm(orientation) q = Quaternion(orientation / norm_orientation) locations.append(location) orientations.append(q) i += 1 # Creat and return numpy arrays locations = np.array(locations) orientations = np.array(orientations) return number_of_bodies, locations, orientations
def test_change_mobility_origin(self): ''' This tests the function in utils.py that transforms a mobility about one point to a mobility about another. ''' # Random location and orientation location = [[0., 0., np.random.uniform(4., 7.)]] orientation = np.random.normal(0., 1., 4) orientation = [Quaternion(orientation / np.linalg.norm(orientation))] mobility = bmr.boomerang_mobility(location, orientation) # Choose a random other point, evaluate mobility. point = location[0] + np.random.normal(0., 1., 3) mobility_2 = bmr.boomerang_mobility_at_arbitrary_point( location, orientation, point) # Transfer mobility to point using util function. transferred_mobility_2 = transfer_mobility(mobility, location[0], point) # Compare results. for j in range(0, 6): for k in range(0, 6): self.assertAlmostEqual(mobility_2[j, k], transferred_mobility_2[j, k])
# Set some more variables max_translation = max_body_length * 5.0 print(' max_translation = ', max_translation) num_of_body_types = len(read.structure_names) num_bodies = bodies.size Nblobs = sum([x.Nblobs for x in bodies]) max_angle_shift = max_translation / max_body_length accepted_moves = 0 acceptance_ratio = 0.5 # Create blobs coordinates array sample_r_vectors = get_blobs_r_vectors(bodies, Nblobs) # quaternion to be used for disturbing the orientation of each body quaternion_shift = Quaternion(np.array([1, 0, 0, 0])) # Estimate partition function for i, ID in enumerate(read.structures_ID): name = read.output_name + '.' + ID + '.config' status = 'w' with open(name, status) as f_ID: f_ID.write(str('')) start_time = time.time() minimum_energy = 1.0e+99 for step in range(np.maximum(read.n_steps // 100, 100000)): blob_index = 0 for i, body in enumerate(bodies): body.location_new = np.random.uniform(0.0, max_translation, 3) body.orientation_new.random_orientation() sample_r_vectors[blob_index:blob_index +
outFile = 'ns_rejection_locations.txt' # constants listed for convenience, none here are changed from what is in non_sphere.py num_blobs = 7 s.A = 0.265*np.sqrt(3./2.) # radius of blob in um s.VISCOSITY = 8.9e-4 s.BLOB_WEIGHT = 1.*0.0000000002*(9.8*1e6) s.WEIGHT = [s.BLOB_WEIGHT/num_blobs for i in range(num_blobs)] # weight of entire boomerang particle s.KT = 300.*1.3806488e-5 s.REPULSION_STRENGTH = 7.5 * s.KT s.DEBYE_LENGTH = 0.5*s.A # initial configuration theta = (1, 0, 0, 0) orientation = Quaternion(theta/np.linalg.norm(theta)) # orientation is a quaternion object location = [0., 0., 1.1] # the position of the particle #sample = [location, orientation] n_steps = 10000 # the number of height positions to be generated f = open(outFile, 'w') start_time = time.time() # generate a normalization constant # the partition_constant is used to make the partition function value generated by # generate_non_sphere_partition() more safe to use (i.e. greater than any acceptance # probability generated by non_sphere_rejection) partition_steps = 10000 partition_constant = 1.1 partitionZ = s.generate_non_sphere_partition(partition_steps) * partition_constant
weight = weight, blob_radius = blob_radius) # quaternion to be used for disturbing the orientation of each body quaternion_shift = Quaternion(np.array([1,0,0,0])) # for each step in the Markov chain, disturb each body's location and orientation and obtain the new list of r_vectors # of each blob. Calculate the potential of the new state, and accept or reject it according to the Markov chain rules: # 1. if Ej < Ei, always accept the state 2. if Ej < Ei, accept the state according to the probability determined by # exp(-(Ej-Ei)/kT). Then record data. # Important: record data also when staying in the same state (i.e. when a sample state is rejected) for step in range(read.initial_step, read.n_steps): blob_index = 0 for i, body in enumerate(bodies): # distrub bodies body.location_new = body.location + np.random.uniform(-max_translation, max_translation, 3) # make small change to location quaternion_shift = Quaternion.from_rotation(np.random.normal(0,1,3) * max_angle_shift) body.orientation_new = quaternion_shift * body.orientation sample_r_vectors[blob_index : blob_index + bodies[i].Nblobs] = body.get_r_vectors(body.location_new, body.orientation_new) blob_index += body.Nblobs # calculate potential of proposed new state sample_state_energy = many_body_potential_pycuda.compute_total_energy(bodies, sample_r_vectors, periodic_length = periodic_length, debye_length_wall = read.debye_length_wall, repulsion_strength_wall = read.repulsion_strength_wall, debye_length = read.debye_length, repulsion_strength = read.repulsion_strength, weight = weight, blob_radius = blob_radius)
def Update_Bodies_Trap(self, FT_calc, Omega=None, Out_Torque=False, Cut_Torque=None): L = self.periodic_length # Save initial configuration for k, b in enumerate(self.bodies): np.copyto(b.location_old, b.location) b.orientation_old = copy.copy(b.orientation) # compute forces for predictor step r_vecs_np = [b.location for b in self.bodies] r_vecs = self.put_r_vecs_in_periodic_box(r_vecs_np, self.periodic_length) start = time.time() FT = FT_calc(self.bodies, r_vecs) end = time.time() print(('F calc time : ' + str((end - start)))) FT = FT.flatten() FT = FT[:, np.newaxis] # If Omega Specified, add torques VO_guess = None if Omega is not None: FTrs = np.reshape(FT, (len(self.bodies), 6)) F = FTrs[:, 0:3] start = time.time() T_omega, VO_guess = self.Torque_from_Omega(Omega, F) if Cut_Torque is not None: Tn = np.linalg.norm(T_omega, axis=1) NewNorm = np.minimum(Tn, Cut_Torque) / Tn T_omega = NewNorm[:, None] * T_omega end = time.time() print(('Omega time : ' + str((end - start)))) FTrs[:, 3::] += T_omega FT = np.reshape(FTrs, (6 * len(self.bodies), 1)) # compute relevant matrix root for pred. and corr. steps start = time.time() Root_Xm, Root_X = self.Lub_Mobility_Root_RHS() X = Root_X[:, np.newaxis] MXm = self.Wall_Mobility_Mult(Root_Xm) MXm = MXm[:, np.newaxis] Mhalf = X + MXm end = time.time() print(('root time : ' + str((end - start)))) # compute predictor velocities and update positions start = time.time() vel_p, res_p = self.Lubrucation_solve(X=Mhalf, Xm=FT, X0=VO_guess) end = time.time() print(('solve 1 : ' + str((end - start)))) for k, b in enumerate(self.bodies): b.location = b.location_old + vel_p[6 * k:6 * k + 3] * self.dt quaternion_dt = Quaternion.from_rotation( (vel_p[6 * k + 3:6 * k + 6]) * self.dt) b.orientation = quaternion_dt * b.orientation_old r_vecs_np = [b.location for b in self.bodies] r_vecs_c = self.put_r_vecs_in_periodic_box(r_vecs_np, self.periodic_length) self.Set_R_Mats(r_vecs_np=r_vecs_c) # VERY IMPORTANT # compute rfd for M W = np.random.randn(6 * r_vecs.shape[0], 1) Wrfd = np.reshape(W, (r_vecs.shape[0], 6)) Wrfd = Wrfd[:, 0:3] Qp = r_vecs + (self.delta / 2.0) * Wrfd Qm = r_vecs - (self.delta / 2.0) * Wrfd MpW = self.Wall_Mobility_Mult(W, r_vecs_np=Qp) MmW = self.Wall_Mobility_Mult(W, r_vecs_np=Qm) D_M = 2.0 * (self.kT / self.delta) * (MpW - MmW) D_M = D_M[:, np.newaxis] # compute RHSs for the corr. step RHS_X_C = D_M + Mhalf start = time.time() FT_C = FT_calc(self.bodies, r_vecs_c) end = time.time() print(('F calc time : ' + str((end - start)))) FT_C = FT_C.flatten() FT_C = FT_C[:, np.newaxis] # If Omega Specified, add torques VO_guessc = vel_p second_order = False if Omega is not None: FTrsc = np.reshape(FT_C, (len(self.bodies), 6)) Fc = FTrsc[:, 0:3] if second_order: # you could use the previous Torque_from_Omega solve as an initial guess here and it should work very well Tc, VO_guessc = self.Torque_from_Omega(Omega, Fc) if Cut_Torque is not None: Tn = np.linalg.norm(Tc, axis=1) NewNorm = np.minimum(Tn, Cut_Torque) / Tn Tc = NewNorm[:, None] * Tc else: Tc = T_omega FTrsc[:, 3::] += Tc FT_C = np.reshape(FTrsc, (6 * len(self.bodies), 1)) RHS_Xm_C = FT_C # compute for corrected velocity and update positions start = time.time() vel_c, res_c = self.Lubrucation_solve(X=RHS_X_C, Xm=RHS_Xm_C, X0=VO_guessc) end = time.time() print(('solve 2 : ' + str((end - start)))) vel_trap = 0.5 * (vel_c + vel_p) for k, b in enumerate(self.bodies): b.location_new = b.location_old + vel_trap[6 * k:6 * k + 3] * self.dt quaternion_dt = Quaternion.from_rotation( (vel_trap[6 * k + 3:6 * k + 6]) * self.dt) b.orientation_new = quaternion_dt * b.orientation_old reject_wall = 0 reject_jump = 0 reject_wall, reject_jump = self.Check_Update_With_Jump_Trap() self.num_rejections_wall += reject_wall self.num_rejections_jump += reject_jump if (reject_wall + reject_jump) == 0: for b in self.bodies: np.copyto(b.location, b.location_new) b.orientation = copy.copy(b.orientation_new) else: for b in self.bodies: np.copyto(b.location, b.location_old) b.orientation = copy.copy(b.orientation_old) self.Set_R_Mats() ######## VERY IMPORTANT if Out_Torque: return reject_wall, reject_jump, T_omega.flatten() else: return reject_wall, reject_jump
# begin MCMC # get energy of the current state before jumping into the loop start_time = time.time() current_state_energy = many_body_potential_pycuda.compute_total_energy( bodies, sample_r_vectors, periodic_length=periodic_length, debye_length_wall=read.debye_length_wall, repulsion_strength_wall=read.repulsion_strength_wall, debye_length=read.debye_length, repulsion_strength=read.repulsion_strength, weight=weight, blob_radius=blob_radius) # quaternion to be used for disturbing the orientation of each body quaternion_shift = Quaternion(np.array([1, 0, 0, 0])) # for each step in the Markov chain, disturb each body's location and orientation and obtain the new list of r_vectors # of each blob. Calculate the potential of the new state, and accept or reject it according to the Markov chain rules: # 1. if Ej < Ei, always accept the state 2. if Ej < Ei, accept the state according to the probability determined by # exp(-(Ej-Ei)/kT). Then record data. # Important: record data also when staying in the same state (i.e. when a sample state is rejected) for step in range(read.initial_step, read.n_steps): blob_index = 0 for i, body in enumerate(bodies): # distrub bodies body.location_new = body.location + np.random.uniform( -max_translation, max_translation, 3) # make small change to location quaternion_shift = Quaternion.from_rotation( np.random.normal(0, 1, 3) * max_angle_shift) body.orientation_new = quaternion_shift * body.orientation
self.lwr.Write() self.timer_count += 0.01 * TIME_SKIP self.n += 1 if __name__ == '__main__': # Data file name where trajectory data is stored. data_name = sys.argv[1] ####### data_file_name = os.path.join(DATA_DIR, 'boomerang', data_name) params, locations, orientations = read_trajectory_from_txt(data_file_name) initial_r_vectors = bm.get_boomerang_r_vectors_15( locations[0], Quaternion(orientations[0])) # Create blobs blob_sources = [] for k in range(N_SPHERES): blob_sources.append(vtk.vtkSphereSource()) blob_sources[k].SetCenter(initial_r_vectors[0][0], initial_r_vectors[0][1], initial_r_vectors[0][2]) blob_sources[k].SetRadius(bm.A) if DRAW_COH: coh_source = vtk.vtkSphereSource() coh_point = bm.calculate_boomerang_coh(locations[0], Quaternion(orientations[0])) coh_source.SetCenter(coh_point)
for step in range(n_steps / n_save + 1): # Read bodies data = f.readline() if data == '' or data.isspace(): break print num_blobs_ID print '#' r_vectors = [] for k, b in enumerate(bodies): if b.ID == name_ID: data = f.readline().split() b.location = [ float(data[0]), float(data[1]), float(data[2]) ] b.orientation = Quaternion([ float(data[3]), float(data[4]), float(data[5]), float(data[6]) ]) r_vectors.append(b.get_r_vectors()) r_vectors = np.array(r_vectors) r_vectors = np.reshape(r_vectors, (r_vectors.size / 3, 3)) for i in range(len(r_vectors)): print name_ID[0].upper() + ' ' + str( r_vectors[i, 0]) + ' ' + str(r_vectors[i, 1]) + ' ' + str( r_vectors[i, 2])
type=int, help='Number of steps to take for runs.') parser.add_argument('-end', dest='end_time', type=float, default=128.0, help='How far to calculate the time dependent MSD.') parser.add_argument('--data-name', dest='data_name', type=str, default='', help='Optional name added to the end of the ' 'data file. Useful for multiple runs ' '(--data_name=run-1).') args = parser.parse_args() initial_orientation = [Quaternion([1., 0., 0., 0.])] initial_location = [np.array([0., 0., sph.H])] scheme = 'RFD' dt = args.dt end_time = args.end_time n_steps = args.n_steps bin_width = 1. / 10. buckets = np.arange(0, int(20. / bin_width)) * bin_width + bin_width / 2. log_filename = './logs/sphere-rotation-dt-%f-N-%d-%s.log' % ( dt, n_steps, args.data_name) progress_logger = logging.getLogger('Progress Logger') progress_logger.setLevel(logging.INFO) # Add the log message handler to the logger logging.basicConfig(filename=log_filename, level=logging.INFO,
def analytical_distribution_non_sphere(num_points): # heights are sampled evenly from the chosen bounds, using linspace # because linspace includes starting value A, the first index in x is ignored # if x[0] is included, then in the calculation of potential energy U, h-A = 0 # and an exception will be thrown # x = np.linspace(A, max_height, num_points) # orientations = [] # for i in range(num_points): # theta = np.random.normal(0., 1., 4) # orientations.append(Quaternion(theta/np.linalg.norm(theta))) # y = [] # deltaX = x[1] - x[0] # numerator, denominator = 0., 0. # # # add the bounds to the integral value # # ignore x[0] = A # integral = 0.5*(non_sphere_GB([0., 0., x[1]], orientations[0]) + # non_sphere_GB([0., 0., max_height], orientations[num_points-1])) # # iterate over the rest of the heights # for k in range(2, num_points): # integral += non_sphere_GB([0., 0., x[k]], orientations[k]) # # multiply by the change in x to complete the integral calculation # integral *= deltaX # # # now that we have the partition function that the integral represents # # we can calculate all the y positions of the distribution # # again ignore x[0] = A # j = 0 # for h in x[1:]: # numerator = non_sphere_GB([0., 0., h], orientations[j]) # y.append(numerator/integral) # j+=1 x = np.linspace(A, max_height, num_points) y = np.zeros(num_points - 1, dtype=float) num_angles = 1000 deltaX = x[1] - x[0] integral = .0 firstBar, lastBar = 0., 0. orientation = Quaternion([0, 0, 0, 0]) # create a quaternion object for i in range(num_angles): orientation.random_orientation() firstBar += non_sphere_GB([0, 0, x[1]], orientation) firstBar /= num_angles for i in range(num_angles): orientation.random_orientation() lastBar += non_sphere_GB([0, 0, x[num_points - 1]], orientation) lastBar /= num_angles integral += (firstBar + lastBar) * .5 sample_GB = np.zeros(num_angles, dtype=float) for i in range(2, num_points - 1): for j in range(num_angles): orientation.random_orientation() sample_GB[j] = non_sphere_GB(np.array([0, 0, x[i]]), orientation) integral += np.average(sample_GB) integral *= deltaX for i in range(x[1:].size): numerator = 0. for j in range(num_angles): orientation.random_orientation() numerator += non_sphere_GB([0., 0., x[i + 1]], orientation) numerator /= num_angles y[i] = (numerator / integral) return x[1:], y
if __name__ == '__main__': # Define Levi-Civita symbol eijk = np.zeros( (3, 3, 3) ) eijk[0,1,2] = 1 eijk[1,2,0] = 1 eijk[2,0,1] = 1 eijk[1,0,2] = -1 eijk[0,2,1] = -1 eijk[2,1,0] = -1 # Define location and orientation location = [0., 0., 100000.] theta = np.random.normal(0., 1., 4) #orientation = Quaternion(theta/np.linalg.norm(theta)) orientation = Quaternion([1., 0., 0., 0.]) # Get blobs vectors r_vectors = bm.get_boomerang_r_vectors_15(location, orientation) # Compute mobility at the cross point mobility = bm.force_and_torque_boomerang_mobility(r_vectors, location) # Get sub-matrix M^wF mobility_wF = mobility[3:6, 0:3] # Get sub-matrix M^wT mobility_wT = mobility[3:6, 3:6] # Compute matrix A = M^wF - (M^wF).T A = mobility_wF - mobility_wF.T
def analytical_distribution_non_sphere(num_points): # heights are sampled evenly from the chosen bounds, using linspace # because linspace includes starting value A, the first index in x is ignored # if x[0] is included, then in the calculation of potential energy U, h-A = 0 # and an exception will be thrown # x = np.linspace(A, max_height, num_points) # orientations = [] # for i in range(num_points): # theta = np.random.normal(0., 1., 4) # orientations.append(Quaternion(theta/np.linalg.norm(theta))) # y = [] # deltaX = x[1] - x[0] # numerator, denominator = 0., 0. # # # add the bounds to the integral value # # ignore x[0] = A # integral = 0.5*(non_sphere_GB([0., 0., x[1]], orientations[0]) + # non_sphere_GB([0., 0., max_height], orientations[num_points-1])) # # iterate over the rest of the heights # for k in range(2, num_points): # integral += non_sphere_GB([0., 0., x[k]], orientations[k]) # # multiply by the change in x to complete the integral calculation # integral *= deltaX # # # now that we have the partition function that the integral represents # # we can calculate all the y positions of the distribution # # again ignore x[0] = A # j = 0 # for h in x[1:]: # numerator = non_sphere_GB([0., 0., h], orientations[j]) # y.append(numerator/integral) # j+=1 x = np.linspace(A, max_height, num_points) y = np.zeros(num_points-1, dtype = float) num_angles = 1000 deltaX = x[1] - x[0] integral = .0 firstBar, lastBar = 0., 0. orientation = Quaternion([0,0,0,0]) # create a quaternion object for i in range(num_angles): orientation.random_orientation() firstBar += non_sphere_GB([0, 0, x[1]], orientation) firstBar /= num_angles for i in range(num_angles): orientation.random_orientation() lastBar += non_sphere_GB([0, 0, x[num_points-1]], orientation) lastBar /= num_angles integral += (firstBar + lastBar) *.5 sample_GB = np.zeros(num_angles, dtype = float) for i in range(2, num_points-1): for j in range(num_angles): orientation.random_orientation() sample_GB[j] = non_sphere_GB(np.array([0, 0, x[i]]), orientation) integral += np.average(sample_GB) integral *= deltaX for i in range(x[1:].size): numerator = 0. for j in range(num_angles): orientation.random_orientation() numerator += non_sphere_GB([0., 0., x[i+1]], orientation) numerator /= num_angles y[i] = (numerator/integral) return x[1:], y