def Stochastic_Velocity_From_FT_no_lub(self, FT):
   '''
   Performs one step of Euler Maruyama WITHOUT using 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)
   W = np.random.randn(6*r_vecs.shape[0],1)
   W2 = 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)
   
   drift = (self.kT/self.delta)*(MpW-MmW)
   
   def MobV(v):
     Mv = self.Wall_Mobility_Mult(v)
     return Mv
   
   Mhalf, it_lanczos = stochastic.stochastic_forcing_lanczos(factor = np.sqrt(2*self.kT / self.dt),
                                                                   tolerance = self.tolerance, 
                                                                   dim = 6*r_vecs.shape[0], 
                                                                   mobility_mult = MobV,
                                                                   L_mult = None,
                                                                   print_residual = False) 
   
   MF = MobV(FT)
   vel = MF + drift + Mhalf
   return vel
Example #2
0
  def compute_stochastic_linear_velocity(self, dt):
    '''
    Compute stochastic linear velocity
    
    v_stoch = sqrt(2*kT) * M_tt^{1/2}*W + kT*div_t(M_tt).

    This function returns the stochastic velocity v_stoch.
    '''
    # Create auxiliar variables
    Nblobs = len(self.bodies)

    # Get blobs coordinates
    r_vectors_blobs = np.empty((Nblobs, 3))
    for k, b in enumerate(self.bodies):
      r_vectors_blobs[k] = b.location

    # Generate random vector
    z = np.random.randn(3 * Nblobs)
    
    # Define mobility matrix
    def mobility_matrix(force, r_vectors = None, eta = None, a = None, periodic_length = None):
      return self.mobility_trans_times_force(r_vectors, force, eta, a, periodic_length = periodic_length)
    partial_mobility_matrix = partial(mobility_matrix, 
                                            r_vectors = r_vectors_blobs, 
                                            eta = self.eta, 
                                            a = self.a,
                                            periodic_length = self.periodic_length)

    # Generate noise term sqrt(2*kT) * N^{1/2} * z
    velocities_noise, it_lanczos = stochastic.stochastic_forcing_lanczos(factor = np.sqrt(2*self.kT / dt),
                                                                         tolerance = self.tolerance, 
                                                                         dim = self.Nblobs * 3, 
                                                                         mobility_mult = partial_mobility_matrix,
                                                                         z = z,
                                                                         print_residual = self.print_residual)
    self.stoch_iterations_count += it_lanczos

    # Compute divergence term div_t(M_tt)
    # 1. Generate random displacement
    if self.kT > 0.0 and self.domain != 'no_wall':
      dx_stoch = np.reshape(np.random.randn(Nblobs * 3), (Nblobs, 3))
      # 2. Displace blobs
      r_vectors_blobs += dx_stoch * (self.rf_delta * self.a * 0.5)
      # 3. Compute M_tt(r+0.5*dx) * dx_stoch
      div_M_tt = self.mobility_trans_times_force(r_vectors_blobs, np.reshape(dx_stoch, dx_stoch.size), self.eta, self.a, 
                                                                   periodic_length = self.periodic_length)
      # 4. Displace blobs in the other direction
      r_vectors_blobs -= dx_stoch * self.rf_delta * self.a
      # 5. Compute -M_tt(r-0.5*dx) * dx_stoch
      div_M_tt -= self.mobility_trans_times_force(r_vectors_blobs, np.reshape(dx_stoch, dx_stoch.size), self.eta, self.a, 
                                                                    periodic_length = self.periodic_length)
      # Reset blobs location
      r_vectors_blobs += dx_stoch * (self.rf_delta * self.a * 0.5)
    else:
      div_M_tt = np.zeros(velocities_noise.size)

    # Compute stochastic velocity v_stoch = sqrt(2*kT/dt) * M_tt^{1/2}*W + kT*div_t(M_tt).
    return velocities_noise + (self.kT / (self.rf_delta * self.a)) * div_M_tt 
Example #3
0
    def compute_stochastic_linear_velocity_without_drift(self, dt):
        '''
    Compute stochastic linear velocity
    
    v_stoch = sqrt(2*kT) * M_tt^{1/2}*W 

    This function returns the stochastic velocity v_stoch.
    '''
        # Create auxiliar variables
        Nblobs = len(self.bodies)

        # Get blobs coordinates
        r_vectors_blobs = np.empty((Nblobs, 3))
        for k, b in enumerate(self.bodies):
            r_vectors_blobs[k] = b.location

        # Generate random vector
        z = np.random.randn(3 * Nblobs)

        # Define mobility matrix
        def mobility_matrix(force,
                            r_vectors=None,
                            eta=None,
                            a=None,
                            periodic_length=None):
            return self.mobility_trans_times_force(
                r_vectors, force, eta, a, periodic_length=periodic_length)

        partial_mobility_matrix = partial(mobility_matrix,
                                          r_vectors=r_vectors_blobs,
                                          eta=self.eta,
                                          a=self.a,
                                          periodic_length=self.periodic_length)

        # Generate noise term sqrt(2*kT) * N^{1/2} * z
        velocities_noise, it_lanczos = stochastic.stochastic_forcing_lanczos(
            factor=np.sqrt(2 * self.kT / dt),
            tolerance=self.tolerance,
            dim=self.Nblobs * 3,
            mobility_mult=partial_mobility_matrix,
            z=z,
            print_residual=self.print_residual)
        self.stoch_iterations_count += it_lanczos

        # Return velocity
        return velocities_noise
 def Lub_Mobility_Root_RHS(self, print_res=False):
   '''
   Returns both DR^{1/2} and M_RPY^{1/2} to be used in the function Lubrucation_solve to compute the square root of the lubrication corrected mobility
   '''
   Dim = self.Delta_R.shape[1]
   
   W1 = np.transpose(np.random.randn(1, Dim))
   W2 = np.transpose(np.random.randn(1, Dim))
   
   start = time.time()
   small = 6.0*np.pi*self.eta*self.a*self.tolerance
   Eig_Shift_DR_cut = self.Delta_R + sp.diags(small*np.ones(Dim),0,format='csc')
   factor = cholesky(Eig_Shift_DR_cut)
   DRL = factor.L()
   DRhalf = factor.apply_Pt(DRL.dot(W1))
   end = time.time()
   #print 'time for DR root: '+ str((end - start)) 
   
   
   
   start = time.time()
   
   WallCutHalf, it_lanczos = stochastic.stochastic_forcing_lanczos(factor = 1.0,
                                                                   tolerance = self.tolerance, 
                                                                   dim = Dim, 
                                                                   mobility_mult = self.Wall_Mobility_Mult,
                                                                   L_mult = None,
                                                                   print_residual = print_res, 
                                                                   z=W2)
   end = time.time()
   #print 'time for M + MDRM root: '+ str((end - start))
   
   RHS_Xm = np.sqrt(2*self.kT / self.dt)*(DRhalf)
   RHS_X = np.sqrt(2*self.kT / self.dt)*(WallCutHalf)
   
   return RHS_Xm, RHS_X
Example #5
0
  def compute_stochastic_velocity(self, dt):
    '''
    Compute stochastic torque and velocity. First,
    solve for the torque
    
    M_rr * T = -kT*div_t(M_rt) - sqrt(2*kT) * (N^{1/2}*W)_r,

    then set linear velocity
    
    v_stoch = M_tr * T + sqrt(2*kT) * (N^{1/2}*W)_t + kT*div_t(M_tt).

    Here N = (M_tt M_tr; M_rt M_rr) is the grand mobility matrix.
    We use random finite difference to compute the divergence
    terms. Note that in principle we should include the term
    div_r(M_rr) in the torque equation and div_r(M_tr) in the
    velocity equation but they are zero for a roller.

    This function returns the stochastic velocity v_stoch.
    '''
    # Create auxiliar variables
    Nblobs = len(self.bodies)
    blob_mass = 1.0

    # Get blobs coordinates
    r_vectors_blobs = np.empty((Nblobs, 3))
    for k, b in enumerate(self.bodies):
      r_vectors_blobs[k] = b.location

    # Generate random vector
    z = np.random.randn(6 * Nblobs)
    
    # Define grand mobility matrix
    def grand_mobility_matrix(force_torque, r_vectors = None, eta = None, a = None, periodic_length = None):
      half_size = force_torque.size / 2
      # velocity = self.mobility_trans_times_force_torque(r_vectors, force_torque[0:half_size], force_torque[half_size:], eta, a, periodic_length = periodic_length)
      velocity  = self.mobility_trans_times_force(r_vectors, force_torque[0:half_size], eta, a, periodic_length = periodic_length)
      velocity += self.mobility_trans_times_torque(r_vectors, force_torque[half_size:], eta, a, periodic_length = periodic_length)
      angular_velocity  = self.mobility_rot_times_force(r_vectors, force_torque[0:half_size], eta, a, periodic_length = periodic_length)
      angular_velocity += self.mobility_rot_times_torque(r_vectors, force_torque[half_size:], eta, a, periodic_length = periodic_length)      
      return np.concatenate([velocity, angular_velocity])
    partial_grand_mobility_matrix = partial(grand_mobility_matrix, 
                                            r_vectors = r_vectors_blobs, 
                                            eta = self.eta, 
                                            a = self.a,
                                            periodic_length = self.periodic_length)

    # Generate noise term sqrt(2*kT) * N^{1/2} * z
    velocities_noise, it_lanczos = stochastic.stochastic_forcing_lanczos(factor = np.sqrt(2*self.kT / dt),
                                                                         tolerance = self.tolerance, 
                                                                         dim = self.Nblobs * 6, 
                                                                         mobility_mult = partial_grand_mobility_matrix,
                                                                         z = z,
                                                                         print_residual = self.print_residual)
    self.stoch_iterations_count += it_lanczos

    # Compute divergence terms div_t(M_rt) and div_t(M_tt)
    if self.kT > 0.0 and self.domain != 'no_wall':
      # 1. Generate random displacement
      dx_stoch = np.reshape(np.random.randn(Nblobs * 3), (Nblobs, 3))
      # 2. Displace blobs
      r_vectors_blobs += dx_stoch * (self.rf_delta * self.a * 0.5)
      # 3. Compute M_rt(r+0.5*dx) * dx_stoch
      div_M_rt = self.mobility_rot_times_force(r_vectors_blobs, np.reshape(dx_stoch, dx_stoch.size), self.eta, self.a, 
                                                                 periodic_length = self.periodic_length)
      div_M_tt = self.mobility_trans_times_force(r_vectors_blobs, np.reshape(dx_stoch, dx_stoch.size), self.eta, self.a, 
                                                                   periodic_length = self.periodic_length)
      # 4. Displace blobs in the other direction
      r_vectors_blobs -= dx_stoch * self.rf_delta * self.a 

      # 5. Compute -M_rt(r-0.5*dx) * dx_stoch
      div_M_rt -= self.mobility_rot_times_force(r_vectors_blobs, np.reshape(dx_stoch, dx_stoch.size), self.eta, self.a, 
                                                                  periodic_length = self.periodic_length)
      div_M_tt -= self.mobility_trans_times_force(r_vectors_blobs, np.reshape(dx_stoch, dx_stoch.size), self.eta, self.a, 
                                                                    periodic_length = self.periodic_length)
    
      # Reset blobs location
      r_vectors_blobs += dx_stoch * (self.rf_delta * self.a * 0.5)
    else:
      div_M_rt = np.zeros(Nblobs * 3)
      div_M_tt = np.zeros(Nblobs * 3)

    # Use constraint motion or free kinematics
    if self.free_kinematics == 'False':
       # Set RHS = -kT*div_t(M_rt) - sqrt(2*kT) * (N^{1/2}*W)_r,
      RHS = -velocities_noise[velocities_noise.size / 2:] - div_M_rt * (self.kT / (self.rf_delta * self.a))

      # Set linear operator
      system_size = 3 * len(self.bodies)
      def mobility_rot_torque(torque, r_vectors = None, eta = None, a = None, periodic_length = None):
        return self.mobility_rot_times_torque(r_vectors, torque, eta, a, periodic_length = periodic_length)
      linear_operator_partial = partial(mobility_rot_torque, r_vectors = r_vectors_blobs, eta = self.eta, a = self.a, periodic_length = self.periodic_length)
      A = spla.LinearOperator((system_size, system_size), matvec = linear_operator_partial, dtype='float64')

      # Scale RHS to norm 1
      RHS_norm = np.linalg.norm(RHS)
      if RHS_norm > 0:
        RHS = RHS / RHS_norm

      # Solve linear system 
      counter = gmres_counter(print_residual = self.print_residual)
      (sol_precond, info_precond) = utils.gmres(A, 
                                                RHS, 
                                                tol=self.tolerance, 
                                                maxiter=1000,
                                                callback=counter) 
      self.det_iterations_count += counter.niter

      # Scale solution with RHS norm
      if RHS_norm > 0:
        sol_precond = sol_precond * RHS_norm
    else:
      # This is free kinematics, stochastic torque set to zero
      # because we only care for the translational degrees of freedom
      sol_precond = np.zeros(3 * Nblobs)

    # Compute stochastic velocity v_stoch = M_tr * T + sqrt(2*kT) * (N^{1/2}*W)_t + kT*div_t(M_tt).
    v_stoch = self.mobility_trans_times_torque(r_vectors_blobs, sol_precond, self.eta, self.a, periodic_length = self.periodic_length)
    v_stoch += velocities_noise[0 : velocities_noise.size / 2] + (self.kT / (self.rf_delta * self.a)) * div_M_tt 
    return v_stoch