Пример #1
0
    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
Пример #4
0
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
Пример #5
0
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]
Пример #6
0
    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
Пример #7
0
    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
Пример #8
0
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]
Пример #9
0
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]
Пример #10
0
    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)
Пример #11
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]
Пример #12
0
    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])
Пример #13
0
    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.)
Пример #14
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')
Пример #15
0
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
Пример #16
0
    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)
Пример #20
0
    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
Пример #22
0
            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])
Пример #24
0
                        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,
Пример #25
0
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
Пример #26
0
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