コード例 #1
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
コード例 #2
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
コード例 #3
0
    # 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,
コード例 #4
0
                                                                         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)
コード例 #5
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