Example #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
Example #2
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]
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]
Example #6
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
Example #7
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]
    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_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')
Example #10
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.)
Example #11
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
    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])
Example #13
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,
Example #14
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
Example #15
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)
    # 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
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
Example #18
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
        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])