def x(posdata, a1_index, a2_index): (sphere_sizes, sphere_positions, sphere_rotations, dumbbell_sizes, dumbbell_positions, dumbbell_deltax, num_spheres, num_dumbbells, element_sizes, element_positions, element_deltax, num_elements, num_elements_array, element_type, uv_start, uv_size, element_start_count) = posdata_data(posdata) return (element_positions[a2_index] - element_positions[a1_index])
def generate_output_FTSUOE(posdata, frameno, timestep, input_number, last_generated_Minfinity_inverse, regenerate_Minfinity, input_form, cutoff_factor, printout, use_XYZd_values, use_drag_Minfinity, use_Minfinity_only, extract_force_on_wall_due_to_dumbbells, last_velocities, last_velocity_vector, checkpoint_start_from_frame, box_bottom_left, box_top_right, feed_every_n_timesteps=0): (sphere_sizes, sphere_positions, sphere_rotations, dumbbell_sizes, dumbbell_positions, dumbbell_deltax, num_spheres, num_dumbbells, element_sizes, element_positions, element_deltax, num_elements, num_elements_array, element_type, uv_start, uv_size, element_start_count) = posdata_data(posdata) # Get inputs first time in "video" mode, i.e. no complex calculations for Fa_in, etc. This is really just to get the values of box_bottom_left and box_top_right. (Fa_in, Ta_in, Sa_in, Sa_c_in, Fb_in, DFb_in, Ua_in, Oa_in, Ea_in, Ea_c_in, Ub_in, DUb_in, input_description, U_infinity, O_infinity, centre_of_background_flow, amplitude, frequency, box_bottom_left, box_top_right, mu) = input_ftsuoe(input_number, posdata, frameno, timestep, last_velocities, input_form=input_form, video=True) solve_time_start = time.time() force_on_wall_due_to_dumbbells = 0 if input_form == "stokes_drag_dumbbells_only": Fbeads = 0.5 * np.concatenate([ np.array(Fb_in) + np.array(DFb_in), np.array(Fb_in) - np.array(DFb_in) ]) a = dumbbell_sizes[0] drag_coeff = mu * a Ubeads = Fbeads / drag_coeff Nbeads = len(Fbeads) (Fa_out, Ta_out, Sa_out, Fb_out, DFb_out) = (Fa_in[:], Ta_in[:], Sa_in[:], Fb_in[:], DFb_in[:]) (Ua_out, Oa_out, Ea_out) = (Fa_in[:], Fa_in[:], Ea_in[:]) Ub_out = 0.5 * (Ubeads[:Nbeads / 2] + Ubeads[Nbeads / 2:]) DUb_out = 0.5 * ( Ubeads[:Nbeads / 2] - Ubeads[Nbeads / 2:] ) # Because DUb is actually Half Delta Ub (shit notation, I know) gen_times = [0, 0, 0] else: if not np.array_equal(box_bottom_left - box_top_right, np.array([0, 0, 0])): # periodic (grand_resistance_matrix, heading, last_generated_Minfinity_inverse, gen_times) = generate_grand_resistance_matrix_periodic( posdata, last_generated_Minfinity_inverse, box_bottom_left, box_top_right, regenerate_Minfinity=regenerate_Minfinity, cutoff_factor=cutoff_factor, printout=printout, use_XYZd_values=use_XYZd_values, use_drag_Minfinity=use_drag_Minfinity, use_Minfinity_only=use_Minfinity_only, frameno=frameno, checkpoint_start_from_frame=checkpoint_start_from_frame, feed_every_n_timesteps=feed_every_n_timesteps, O_infinity=O_infinity, E_infinity=Ea_in[0], timestep=timestep, centre_of_background_flow=centre_of_background_flow, mu=mu, amplitude=amplitude, frequency=frequency) else: # non-periodic (grand_resistance_matrix, heading, last_generated_Minfinity_inverse, gen_times) = generate_grand_resistance_matrix( posdata, last_generated_Minfinity_inverse, regenerate_Minfinity=regenerate_Minfinity, cutoff_factor=cutoff_factor, printout=printout, use_XYZd_values=use_XYZd_values, use_drag_Minfinity=use_drag_Minfinity, use_Minfinity_only=use_Minfinity_only, frameno=frameno, checkpoint_start_from_frame=checkpoint_start_from_frame, feed_every_n_timesteps=feed_every_n_timesteps, mu=mu) num_spheres = len(Ua_in) num_dumbbells = len(Ub_in) if input_form == 'fts': try: force_vector = construct_force_vector_from_fts( posdata, Fa_in, Ta_in, Sa_in, Fb_in, DFb_in) except: throw_error( "FTS mode has been selected but not all values of F, T and S have been provided." ) velocity_vector = np.linalg.solve(grand_resistance_matrix, force_vector) (Ua_out, Oa_out, Ea_out, Ub_out, DUb_out) = deconstruct_velocity_vector_for_fts( posdata, velocity_vector) (Fa_out, Ta_out, Sa_out, Fb_out, DFb_out) = (Fa_in[:], Ta_in[:], Sa_in[:], Fb_in[:], DFb_in[:]) if num_spheres == 0: Ea_out = Ea_in elif input_form == 'fte': # Call this the same name to reduce memory requirements (no need to reproduce) grand_resistance_matrix = fts_to_fte_matrix( posdata, grand_resistance_matrix) # Get inputs a second time not in video mode, putting in the grand resistance matrix which is needed for some calculations with friction. (Fa_in, Ta_in, Sa_in, Sa_c_in, Fb_in, DFb_in, Ua_in, Oa_in, Ea_in, Ea_c_in, Ub_in, DUb_in, input_description, U_infinity, O_infinity, centre_of_background_flow, amplitude, frequency, box_bottom_left, box_top_right, mu) = input_ftsuoe( input_number, posdata, frameno, timestep, last_velocities, input_form=input_form, grand_resistance_matrix_fte=grand_resistance_matrix) try: force_vector = construct_force_vector_from_fts( posdata, Fa_in, Ta_in, Ea_in, Fb_in, DFb_in) except: throw_error( "FTE mode has been selected but not all values of F, T and E have been provided." ) velocity_vector = np.linalg.solve(grand_resistance_matrix, force_vector) (Ua_out, Oa_out, Sa_out, Ub_out, DUb_out) = deconstruct_velocity_vector_for_fts( posdata, velocity_vector) (Fa_out, Ta_out, Ea_out, Fb_out, DFb_out) = (Fa_in[:], Ta_in[:], Ea_in[:], Fb_in[:], DFb_in[:]) if num_spheres == 0: Ea_out = Ea_in elif input_form == 'ufte': num_fixed_velocity_spheres = num_spheres - Ua_in.count( ['pippa', 'pippa', 'pippa']) try: force_vector = construct_force_vector_from_fts( posdata, Ua_in[0:num_fixed_velocity_spheres] + Fa_in[num_fixed_velocity_spheres:num_spheres], Ta_in, Ea_in, Fb_in, DFb_in) except: throw_error( "UFTE mode has been selected but not enough values of U, F, T and E have been provided. At a guess, not all your spheres have either a U or an F." ) force_vector = np.array(force_vector, np.float) grand_resistance_matrix_fte = fts_to_fte_matrix( posdata, grand_resistance_matrix) grand_resistance_matrix_ufte = fte_to_ufte_matrix( num_fixed_velocity_spheres, posdata, grand_resistance_matrix_fte) if extract_force_on_wall_due_to_dumbbells: grand_mobility_matrix_ufte = np.linalg.inv( grand_resistance_matrix_ufte) velocity_vector = np.dot(grand_mobility_matrix_ufte, force_vector) else: velocity_vector = np.linalg.solve(grand_resistance_matrix_ufte, force_vector) (FUa_out, Oa_out, Sa_out, Ub_out, DUb_out) = deconstruct_velocity_vector_for_fts( posdata, velocity_vector) Fa_out = [['chen', 'chen', 'chen'] for i in xrange(num_spheres)] Ua_out = [['chen', 'chen', 'chen'] for i in xrange(num_spheres)] Fa_out[0:num_fixed_velocity_spheres] = FUa_out[ 0:num_fixed_velocity_spheres] Fa_out[num_fixed_velocity_spheres:num_spheres] = Fa_in[ num_fixed_velocity_spheres:num_spheres] Ua_out[0:num_fixed_velocity_spheres] = Ua_in[ 0:num_fixed_velocity_spheres] Ua_out[num_fixed_velocity_spheres:num_spheres] = FUa_out[ num_fixed_velocity_spheres:num_spheres] (Ta_out, Ea_out, Fb_out, DFb_out) = (Ta_in[:], Ea_in[:], Fb_in[:], DFb_in[:]) if extract_force_on_wall_due_to_dumbbells: # For finding effect of the dumbbells on the measured Force on the walls. # Since Fafixed = ()Uafixed + ()Fafree + ()Ta + ()E + ()Fb + ()DFb , # | want this bit | force_on_wall_due_to_dumbbells_matrix = grand_mobility_matrix_ufte[: num_fixed_velocity_spheres * 3, 11 * num_spheres:] dumbbell_forces = force_vector[11 * num_spheres:] force_on_wall_due_to_dumbbells_flat = np.dot( force_on_wall_due_to_dumbbells_matrix, dumbbell_forces) force_on_wall_due_to_dumbbells = force_on_wall_due_to_dumbbells_flat.reshape( len(force_on_wall_due_to_dumbbells_flat) / 3, 3) elif input_form == 'ufteu': num_fixed_velocity_spheres = num_spheres - Ua_in.count( ['pippa', 'pippa', 'pippa']) num_fixed_velocity_dumbbells = num_dumbbells - Ub_in.count( ['pippa', 'pippa', 'pippa']) try: force_vector = construct_force_vector_from_fts( posdata, Ua_in[0:num_fixed_velocity_spheres] + Fa_in[num_fixed_velocity_spheres:num_spheres], Ta_in, Ea_in, Ub_in[0:num_fixed_velocity_dumbbells] + Fb_in[num_fixed_velocity_dumbbells:num_dumbbells], DUb_in[0:num_fixed_velocity_dumbbells] + DFb_in[num_fixed_velocity_dumbbells:num_dumbbells]) except: throw_error( "UFTEU mode has been selected but not enough values of U, F, T and E and U(dumbbell) have been provided. At a guess, not all your spheres/dumbbells have either a U or an F." ) force_vector = np.array(force_vector, np.float) grand_resistance_matrix_fte = fts_to_fte_matrix( posdata, grand_resistance_matrix) grand_resistance_matrix_ufte = fte_to_ufte_matrix( num_fixed_velocity_spheres, posdata, grand_resistance_matrix_fte) grand_resistance_matrix_ufteu = ufte_to_ufteu_matrix( num_fixed_velocity_dumbbells, num_fixed_velocity_spheres, posdata, grand_resistance_matrix_ufte) velocity_vector = np.linalg.solve(grand_resistance_matrix_ufteu, force_vector) (FUa_out, Oa_out, Sa_out, FUb_out, DFUb_out) = deconstruct_velocity_vector_for_fts( posdata, velocity_vector) Fa_out = [['chen', 'chen', 'chen'] for i in xrange(num_spheres)] Ua_out = [['chen', 'chen', 'chen'] for i in xrange(num_spheres)] Fa_out[0:num_fixed_velocity_spheres] = FUa_out[ 0:num_fixed_velocity_spheres] Fa_out[num_fixed_velocity_spheres:num_spheres] = Fa_in[ num_fixed_velocity_spheres:num_spheres] Ua_out[0:num_fixed_velocity_spheres] = Ua_in[ 0:num_fixed_velocity_spheres] Ua_out[num_fixed_velocity_spheres:num_spheres] = FUa_out[ num_fixed_velocity_spheres:num_spheres] (Ta_out, Ea_out) = (Ta_in[:], Ea_in[:]) Fb_out = [['chen', 'chen', 'chen'] for i in xrange(num_dumbbells)] Ub_out = [['chen', 'chen', 'chen'] for i in xrange(num_dumbbells)] Fb_out[0:num_fixed_velocity_dumbbells] = FUb_out[ 0:num_fixed_velocity_dumbbells] Fb_out[num_fixed_velocity_dumbbells:num_dumbbells] = Fb_in[ num_fixed_velocity_dumbbells:num_dumbbells] Ub_out[0:num_fixed_velocity_dumbbells] = Ub_in[ 0:num_fixed_velocity_dumbbells] Ub_out[num_fixed_velocity_dumbbells:num_dumbbells] = FUb_out[ num_fixed_velocity_dumbbells:num_dumbbells] DFb_out = [['chen', 'chen', 'chen'] for i in xrange(num_dumbbells)] DUb_out = [['chen', 'chen', 'chen'] for i in xrange(num_dumbbells)] DFb_out[0:num_fixed_velocity_dumbbells] = DFUb_out[ 0:num_fixed_velocity_dumbbells] DFb_out[num_fixed_velocity_dumbbells:num_dumbbells] = DFb_in[ num_fixed_velocity_dumbbells:num_dumbbells] DUb_out[0:num_fixed_velocity_dumbbells] = DUb_in[ 0:num_fixed_velocity_dumbbells] DUb_out[num_fixed_velocity_dumbbells:num_dumbbells] = DFUb_out[ num_fixed_velocity_dumbbells:num_dumbbells] if extract_force_on_wall_due_to_dumbbells: print "WARNING: Cannot extract force on wall due to dumbbells in UFTEU mode. Use UFTE mode instead." elif input_form == 'duf': #Dumbbells only, some imposed velocities num_fixed_velocity_dumbbells = num_dumbbells - Ub_in.count( ['pippa', 'pippa', 'pippa']) try: force_vector = construct_force_vector_from_fts( posdata, Fa_in, Ta_in, Ea_in, Ub_in[0:num_fixed_velocity_dumbbells] + Fb_in[num_fixed_velocity_dumbbells:num_dumbbells], DUb_in[0:num_fixed_velocity_dumbbells] + DFb_in[num_fixed_velocity_dumbbells:num_dumbbells]) except: throw_error( "DUF mode has been selected but not enough values of U (dumbbell) and F (dumbbell) have been provided. At a guess, not all your dumbbells have either a U or an F." ) force_vector = np.array(force_vector, np.float) grand_resistance_matrix_duf = fts_to_duf_matrix( num_fixed_velocity_dumbbells, posdata, grand_resistance_matrix) velocity_vector = np.linalg.solve(grand_resistance_matrix_duf, force_vector) (Fa_out, Oa_out, Sa_out, FUb_out, DFUb_out) = deconstruct_velocity_vector_for_fts( posdata, velocity_vector) Fb_out = [['chen', 'chen', 'chen'] for i in xrange(num_dumbbells)] Ub_out = [['chen', 'chen', 'chen'] for i in xrange(num_dumbbells)] DFb_out = [['chen', 'chen', 'chen'] for i in xrange(num_dumbbells)] DUb_out = [['chen', 'chen', 'chen'] for i in xrange(num_dumbbells)] Fb_out[0:num_fixed_velocity_dumbbells] = FUb_out[ 0:num_fixed_velocity_dumbbells] Fb_out[num_fixed_velocity_dumbbells:num_dumbbells] = Fb_in[ num_fixed_velocity_dumbbells:num_dumbbells] Ub_out[0:num_fixed_velocity_dumbbells] = Ub_in[ 0:num_fixed_velocity_dumbbells] Ub_out[num_fixed_velocity_dumbbells:num_dumbbells] = FUb_out[ num_fixed_velocity_dumbbells:num_dumbbells] DFb_out[0:num_fixed_velocity_dumbbells] = DFUb_out[ 0:num_fixed_velocity_dumbbells] DFb_out[num_fixed_velocity_dumbbells:num_dumbbells] = DFb_in[ num_fixed_velocity_dumbbells:num_dumbbells] DUb_out[0:num_fixed_velocity_dumbbells] = DUb_in[ 0:num_fixed_velocity_dumbbells] DUb_out[num_fixed_velocity_dumbbells:num_dumbbells] = DFUb_out[ num_fixed_velocity_dumbbells:num_dumbbells] (Fa_out, Ta_out, Ea_out) = (Fa_in[:], Ta_in[:], Ea_in[:]) Ua_out, Oa_out = np.array([]), np.array([]) Fa_out = np.asarray(Fa_out, np.float) Ta_out = np.asarray(Ta_out, np.float) Ea_out = np.asarray(Ea_out, np.float) Ua_out = np.asarray(Ua_out, np.float) Oa_out = np.asarray(Oa_out, np.float) Ub_out = np.asarray(Ub_out, np.float) DUb_out = np.asarray(DUb_out, np.float) elapsed_solve_time = time.time() - solve_time_start gen_times.append(elapsed_solve_time) if (printout > 0): print "Velocities on particles 0-9" print np.asarray(Ua_out[0:10]) print np.asarray(Ub_out[0:10]) print "Half Delta U velocity 0-9" print np.asarray(DUb_out[0:10]) print "Omegas on particles 0-9" print np.asarray(Oa_out[0:10]) print "Forces 0-9 (F)" print np.asarray(Fa_out[0:10]) print np.asarray(Fb_out[0:10]) print "Delta F forces 0-9 (DF)" print np.asarray(DFb_out[0:10]) print "Torques 0-9 (T)" print np.asarray(Ta_out[0:10]) print "Strain rate" print np.asarray(Ea_out) print "Stresslets 0-9 (S)" print np.asarray(Sa_out[0:10]) return Fa_out, Ta_out, Sa_out, Fb_out, DFb_out, Ua_out, Oa_out, Ea_out, Ub_out, DUb_out, last_generated_Minfinity_inverse, gen_times, U_infinity, O_infinity, centre_of_background_flow, force_on_wall_due_to_dumbbells, last_velocity_vector
def generate_R2Bexact(posdata, printout=0, cutoff_factor=2, frameno=0, checkpoint_start_from_frame=0, feed_every_n_timesteps=0, mu=1): from functions_shared import close_particles global fully_2d_problem, size_ratio_matrix, average_size_matrix, upper_triangle (sphere_sizes, sphere_positions, sphere_rotations, dumbbell_sizes, dumbbell_positions, dumbbell_deltax, num_spheres, num_dumbbells, element_sizes, element_positions, element_deltax, num_elements, num_elements_array, element_type, uv_start, uv_size, element_start_count) = posdata_data(posdata) R2Bexact_sidelength = 11 * num_spheres + 6 * num_dumbbells R2Bexact = lil_matrix((R2Bexact_sidelength, R2Bexact_sidelength), dtype=np.float) bead_positions = np.concatenate([ sphere_positions, dumbbell_positions - 0.5 * dumbbell_deltax, dumbbell_positions + 0.5 * dumbbell_deltax ]) bead_sizes = np.concatenate([sphere_sizes, dumbbell_sizes, dumbbell_sizes]) if printout > 0 and feed_every_n_timesteps > 0: print "number of dumbbells in functions_generate_R2Bexact: ", dumbbell_sizes.shape, num_dumbbells closer_than_cutoff_pairs_scaled, displacements_pairs_scaled, distances_pairs_scaled, size_ratios = close_particles( bead_positions, bead_sizes, cutoff_factor) uv_power = [[1, 2, 2, 1, 1], [2, 3, 3, 2, 2], [2, 3, 3, 2, 2], [1, 2, 2, 1, 1], [1, 2, 2, 1, 1]] ii = 0 for a1_index, a2_index in closer_than_cutoff_pairs_scaled: r = displacements_pairs_scaled[ii] # vector r s_dash = distances_pairs_scaled[ii] # np.linalg.norm(x) if a1_index != a2_index: d = r / s_dash lam = size_ratios[ii] lam_index = np.where(lam_range_with_reciprocals == lam)[0][0] lam_index_recip = np.where(lam_range_with_reciprocals == 1. / lam)[0][0] largest_size = max(bead_sizes[a1_index], bead_sizes[a2_index]) if a1_index < num_spheres and a2_index < num_spheres: # Sphere to sphere A_coords = np.s_[a1_index * 3:(a1_index + 1) * 3, a2_index * 3:(a2_index + 1) * 3] Bt_coords = np.s_[a1_index * 3:(a1_index + 1) * 3, 3 * num_spheres + a2_index * 3:3 * num_spheres + (a2_index + 1) * 3] Bt_coords_21 = np.s_[a2_index * 3:(a2_index + 1) * 3, 3 * num_spheres + a1_index * 3:3 * num_spheres + (a1_index + 1) * 3] Gt_coords = np.s_[a1_index * 3:(a1_index + 1) * 3, 6 * num_spheres + a2_index * 5:6 * num_spheres + (a2_index + 1) * 5] Gt_coords_21 = np.s_[a2_index * 3:(a2_index + 1) * 3, 6 * num_spheres + a1_index * 5:6 * num_spheres + (a1_index + 1) * 5] C_coords = np.s_[3 * num_spheres + a1_index * 3:3 * num_spheres + (a1_index + 1) * 3, 3 * num_spheres + a2_index * 3:3 * num_spheres + (a2_index + 1) * 3] Ht_coords = np.s_[3 * num_spheres + a1_index * 3:3 * num_spheres + (a1_index + 1) * 3, 6 * num_spheres + a2_index * 5:6 * num_spheres + (a2_index + 1) * 5] Ht_coords_21 = np.s_[3 * num_spheres + a2_index * 3:3 * num_spheres + (a2_index + 1) * 3, 6 * num_spheres + a1_index * 5:6 * num_spheres + (a1_index + 1) * 5] M_coords = np.s_[6 * num_spheres + a1_index * 5:6 * num_spheres + (a1_index + 1) * 5, 6 * num_spheres + a2_index * 5:6 * num_spheres + (a2_index + 1) * 5] if a1_index == a2_index: nearby_beads = [] nearby_beads_displacements = [] nearby_beads_distances = [] for kk in xrange(len(closer_than_cutoff_pairs_scaled)): (i, j) = closer_than_cutoff_pairs_scaled[kk] if (i == a1_index and i != j): nearby_bead = j nearby_beads_displacements.append( displacements_pairs_scaled[kk]) nearby_beads.append(nearby_bead) nearby_beads_distances.append( distances_pairs_scaled[kk]) if (j == a1_index and i != j): nearby_bead = i nearby_beads_displacements.append( -displacements_pairs_scaled[kk]) # Note minus sign nearby_beads.append(nearby_bead) nearby_beads_distances.append( distances_pairs_scaled[kk]) A_sum = 0 Bt_sum = 0 C_sum = 0 Gt_sum = 0 Ht_sum = 0 M_sum = 0 pp = 0 for p_index in nearby_beads: lam_p = bead_sizes[p_index] / bead_sizes[a1_index] largest_size_p = max(bead_sizes[a1_index], bead_sizes[p_index]) if lam_p not in lam_range_with_reciprocals: print "ERROR (Code point D): lambda not in the table of calculated values" lam_index_p = np.where( lam_range_with_reciprocals == lam_p)[0][0] lam_index_recip_p = np.where( lam_range_with_reciprocals == 1. / lam_p)[0][0] r_p = nearby_beads_displacements[pp] s_dash_p = nearby_beads_distances[pp] d_p = r_p / s_dash_p A_sum = A_sum + np.asarray([[ Af(0, d_p, lam_index_p, s_dash_p, i, j, fully_2d_problem) * largest_size_p**uv_power[0][0] for j in xrange(3) ] for i in xrange(3)]) Bt_sum = Bt_sum + np.asarray([[ Bf(0, d_p, lam_index_p, s_dash_p, j, i, fully_2d_problem) * largest_size_p**uv_power[0][1] for j in xrange(3) ] for i in xrange(3)]) C_sum = C_sum + np.asarray([[ Cf(0, d_p, lam_index_p, s_dash_p, i, j, fully_2d_problem) * largest_size_p**uv_power[1][1] for j in xrange(3) ] for i in xrange(3)]) Gt_sum = Gt_sum + np.asarray([[ con_Gf(0, d_p, lam_index_p, s_dash_p, j, i, fully_2d_problem) * largest_size_p**uv_power[0][2] for j in xrange(5) ] for i in xrange(3)]) Ht_sum = Ht_sum + np.asarray([[ con_Hf(0, d_p, lam_index_p, s_dash_p, j, i, fully_2d_problem) * largest_size_p**uv_power[1][2] for j in xrange(5) ] for i in xrange(3)]) M_sum = M_sum + np.asarray([[ con_Mf(0, d_p, lam_index_p, s_dash_p, i, j, fully_2d_problem) * largest_size_p**uv_power[2][2] for j in xrange(5) ] for i in xrange(5)]) pp = pp + 1 R2Bexact[A_coords] = A_sum R2Bexact[Bt_coords] = Bt_sum R2Bexact[C_coords] = C_sum R2Bexact[Gt_coords] = Gt_sum R2Bexact[Ht_coords] = Ht_sum R2Bexact[M_coords] = M_sum else: R2Bexact[A_coords] = [[ Af(1, d, lam_index, s_dash, i, j, fully_2d_problem) * largest_size**uv_power[0][0] for j in xrange(3) ] for i in xrange(3)] R2Bexact[Bt_coords] = [[ Bf(1, -d, lam_index_recip, s_dash, j, i, fully_2d_problem) * largest_size**uv_power[0][1] for j in xrange(3) ] for i in xrange(3)] R2Bexact[C_coords] = [[ Cf(1, d, lam_index, s_dash, i, j, fully_2d_problem) * largest_size**uv_power[1][1] for j in xrange(3) ] for i in xrange(3)] R2Bexact[Gt_coords] = [[ con_Gf(1, -d, lam_index_recip, s_dash, j, i, fully_2d_problem) * largest_size**uv_power[0][2] for j in xrange(5) ] for i in xrange(3)] R2Bexact[Ht_coords] = [[ con_Hf(1, -d, lam_index_recip, s_dash, j, i, fully_2d_problem) * largest_size**uv_power[1][2] for j in xrange(5) ] for i in xrange(3)] R2Bexact[M_coords] = [[ con_Mf(1, d, lam_index, s_dash, i, j, fully_2d_problem) * largest_size**uv_power[2][2] for j in xrange(5) ] for i in xrange(5)] if lam == 1: R2Bexact[Bt_coords_21] = -R2Bexact[Bt_coords] R2Bexact[Gt_coords_21] = -R2Bexact[Gt_coords] R2Bexact[Ht_coords_21] = R2Bexact[Ht_coords] else: R2Bexact[Bt_coords_21] = [[ Bf(1, d, lam_index, s_dash, j, i, fully_2d_problem) * largest_size**uv_power[0][1] for j in xrange(3) ] for i in xrange(3)] R2Bexact[Gt_coords_21] = [[ con_Gf(1, d, lam_index, s_dash, j, i, fully_2d_problem) * largest_size**uv_power[0][2] for j in xrange(5) ] for i in xrange(3)] R2Bexact[Ht_coords_21] = [[ con_Hf(1, d, lam_index, s_dash, j, i, fully_2d_problem) * largest_size**uv_power[1][2] for j in xrange(5) ] for i in xrange(3)] elif a1_index < num_spheres and a2_index >= num_spheres and a2_index < num_spheres + num_dumbbells: # Sphere to dumbbell bead 1 a2_index_d = a2_index - num_spheres R14_coords = np.s_[a1_index * 3:(a1_index + 1) * 3, 11 * num_spheres + a2_index_d * 3:11 * num_spheres + (a2_index_d + 1) * 3] R24_coords = np.s_[3 * num_spheres + a1_index * 3:3 * num_spheres + (a1_index + 1) * 3, 11 * num_spheres + a2_index_d * 3:11 * num_spheres + (a2_index_d + 1) * 3] R34_coords = np.s_[6 * num_spheres + a1_index * 5:6 * num_spheres + (a1_index + 1) * 5, 11 * num_spheres + a2_index_d * 3:11 * num_spheres + (a2_index_d + 1) * 3] R2Bexact[R14_coords] = [[ Af(1, d, lam_index, s_dash, i, j, fully_2d_problem) * largest_size**uv_power[0][0] for j in xrange(3) ] for i in xrange(3)] R2Bexact[R24_coords] = [[ Bf(1, d, lam_index, s_dash, i, j, fully_2d_problem) * largest_size**uv_power[0][1] for j in xrange(3) ] for i in xrange(3)] R2Bexact[R34_coords] = [[ con_Gf(1, d, lam_index, s_dash, i, j, fully_2d_problem) * largest_size**uv_power[0][2] for j in xrange(3) ] for i in xrange(5)] elif a1_index < num_spheres and a2_index >= num_spheres + num_dumbbells: # Sphere to dumbbell bead 2 a2_index_d = a2_index - num_spheres - num_dumbbells R15_coords = np.s_[a1_index * 3:(a1_index + 1) * 3, 11 * num_spheres + 3 * num_dumbbells + a2_index_d * 3:11 * num_spheres + 3 * num_dumbbells + (a2_index_d + 1) * 3] R25_coords = np.s_[3 * num_spheres + a1_index * 3:3 * num_spheres + (a1_index + 1) * 3, 11 * num_spheres + 3 * num_dumbbells + a2_index_d * 3:11 * num_spheres + 3 * num_dumbbells + (a2_index_d + 1) * 3] R35_coords = np.s_[6 * num_spheres + a1_index * 5:6 * num_spheres + (a1_index + 1) * 5, 11 * num_spheres + 3 * num_dumbbells + a2_index_d * 3:11 * num_spheres + 3 * num_dumbbells + (a2_index_d + 1) * 3] R2Bexact[R15_coords] = [[ Af(1, d, lam_index, s_dash, i, j, fully_2d_problem) * largest_size**uv_power[0][0] for j in xrange(3) ] for i in xrange(3)] R2Bexact[R25_coords] = [[ Bf(1, d, lam_index, s_dash, i, j, fully_2d_problem) * largest_size**uv_power[0][1] for j in xrange(3) ] for i in xrange(3)] R2Bexact[R35_coords] = [[ con_Gf(1, d, lam_index, s_dash, i, j, fully_2d_problem) * largest_size**uv_power[0][2] for j in xrange(3) ] for i in xrange(5)] elif a1_index >= num_spheres and a1_index < num_spheres + num_dumbbells and a2_index >= num_spheres and a2_index < num_spheres + num_dumbbells: # Dumbbell bead 1 to dumbbell bead 1 a1_index_d = a1_index - num_spheres a2_index_d = a2_index - num_spheres R44_coords = np.s_[11 * num_spheres + a1_index_d * 3:11 * num_spheres + (a1_index_d + 1) * 3, 11 * num_spheres + a2_index_d * 3:11 * num_spheres + (a2_index_d + 1) * 3] if a1_index == a2_index: nearby_beads = [] nearby_beads_displacements = [] nearby_beads_distances = [] for kk in xrange(len(closer_than_cutoff_pairs_scaled)): (i, j) = closer_than_cutoff_pairs_scaled[kk] if (i == a1_index and i != j): nearby_bead = j nearby_beads_displacements.append( displacements_pairs_scaled[kk]) nearby_beads.append(nearby_bead) nearby_beads_distances.append( distances_pairs_scaled[kk]) if (j == a1_index and i != j): nearby_bead = i nearby_beads_displacements.append( -displacements_pairs_scaled[kk]) # Note minus sign nearby_beads.append(nearby_bead) nearby_beads_distances.append( distances_pairs_scaled[kk]) A_sum = 0 pp = 0 for p_index in nearby_beads: lam_p = bead_sizes[p_index] / bead_sizes[ a1_index] # size_ratio_matrix[a1_index,p_index] largest_size_p = max(bead_sizes[a1_index], bead_sizes[p_index]) if lam_p not in lam_range_with_reciprocals: print "ERROR (Code point D): lambda not in the table of calculated values" lam_index_p = np.where( lam_range_with_reciprocals == lam_p)[0][0] lam_index_recip_p = np.where( lam_range_with_reciprocals == 1. / lam_p)[0][0] r_p = nearby_beads_displacements[pp] s_dash_p = nearby_beads_distances[pp] d_p = r_p / s_dash_p A_sum = A_sum + np.asarray([[ Af(0, d_p, lam_index_p, s_dash_p, i, j, fully_2d_problem) * largest_size_p**uv_power[0][0] for j in xrange(3) ] for i in xrange(3)]) pp = pp + 1 R2Bexact[R44_coords] = A_sum else: if bead_bead_interactions: R2Bexact[R44_coords] = [[ Af(1, d, lam_index, s_dash, i, j, fully_2d_problem) * largest_size**uv_power[0][0] for j in xrange(3) ] for i in xrange(3)] elif a1_index >= num_spheres and a1_index < num_spheres + num_dumbbells and a2_index >= num_spheres + num_dumbbells: # Dumbbell bead 1 to dumbbell bead 2 if bead_bead_interactions: a1_index_d = a1_index - num_spheres a2_index_d = a2_index - num_spheres - num_dumbbells R45_coords = np.s_[11 * num_spheres + a1_index_d * 3:11 * num_spheres + (a1_index_d + 1) * 3, 11 * num_spheres + 3 * num_dumbbells + a2_index_d * 3:11 * num_spheres + 3 * num_dumbbells + (a2_index_d + 1) * 3] R2Bexact[R45_coords] = [[ Af(1, d, lam_index, s_dash, i, j, fully_2d_problem) * largest_size**uv_power[0][0] for j in xrange(3) ] for i in xrange(3)] else: # Dumbbell bead 2 to dumbbell bead 2 a1_index_d = a1_index - num_spheres - num_dumbbells a2_index_d = a2_index - num_spheres - num_dumbbells R55_coords = np.s_[11 * num_spheres + 3 * num_dumbbells + a1_index_d * 3:11 * num_spheres + 3 * num_dumbbells + (a1_index_d + 1) * 3, 11 * num_spheres + 3 * num_dumbbells + a2_index_d * 3:11 * num_spheres + 3 * num_dumbbells + (a2_index_d + 1) * 3] if a1_index == a2_index: nearby_beads = [] nearby_beads_displacements = [] nearby_beads_distances = [] for kk in xrange(len(closer_than_cutoff_pairs_scaled)): (i, j) = closer_than_cutoff_pairs_scaled[kk] if (i == a1_index and i != j): nearby_bead = j nearby_beads_displacements.append( displacements_pairs_scaled[kk]) nearby_beads.append(nearby_bead) nearby_beads_distances.append( distances_pairs_scaled[kk]) if (j == a1_index and i != j): nearby_bead = i nearby_beads_displacements.append( -displacements_pairs_scaled[kk]) # Note minus sign nearby_beads.append(nearby_bead) nearby_beads_distances.append( distances_pairs_scaled[kk]) A_sum = 0 pp = 0 for p_index in nearby_beads: lam_p = bead_sizes[p_index] / bead_sizes[ a1_index] # size_ratio_matrix[a1_index,p_index] largest_size_p = max(bead_sizes[a1_index], bead_sizes[p_index]) if lam_p not in lam_range_with_reciprocals: print "ERROR (Code point D): lambda not in the table of calculated values" lam_index_p = np.where( lam_range_with_reciprocals == lam_p)[0][0] lam_index_recip_p = np.where( lam_range_with_reciprocals == 1. / lam_p)[0][0] r_p = nearby_beads_displacements[pp] s_dash_p = nearby_beads_distances[pp] d_p = r_p / s_dash_p A_sum = A_sum + np.asarray([[ Af(0, d_p, lam_index_p, s_dash_p, i, j, fully_2d_problem) * largest_size_p**uv_power[0][0] for j in xrange(3) ] for i in xrange(3)]) pp = pp + 1 R2Bexact[R55_coords] = A_sum else: if bead_bead_interactions: R2Bexact[R55_coords] = [[ Af(1, d, lam_index, s_dash, i, j, fully_2d_problem) * largest_size**uv_power[0][0] for j in xrange(3) ] for i in xrange(3)] ii = ii + 1 # Scale by 6pi R2Bexact = R2Bexact * 6 * np.pi # symmetrise R2Bexact = sparse.triu(R2Bexact) + sparse.triu(R2Bexact, k=1).transpose() # Row and column ops I want are equivalent to doing # [ 1 0 0 ] [ a b c ] [ 1 0 0 ] # [ 0 1 1 ] . [ d e f ] . [ 0 1 -1 ] # [ 0 -1 1 ] [ g h i ] [ 0 1 1 ] # "L" "R" # I know that we could generate L and R elsewhere rather than doing it every timestep but it takes 0.01s for a few thousand dumbbells so for now I don't mind Lrow = np.array([i for i in xrange(11 * num_spheres + 6 * num_dumbbells)] + [i + 11 * num_spheres for i in xrange(3 * num_dumbbells)] + [ i + 11 * num_spheres + 3 * num_dumbbells for i in xrange(3 * num_dumbbells) ]) Lcol = np.array([i for i in xrange(11 * num_spheres + 6 * num_dumbbells)] + [ i + 11 * num_spheres + 3 * num_dumbbells for i in xrange(3 * num_dumbbells) ] + [i + 11 * num_spheres for i in xrange(3 * num_dumbbells)]) Ldata = np.array([1 for i in xrange(11 * num_spheres + 9 * num_dumbbells)] + [-1 for i in xrange(3 * num_dumbbells)]) L = coo_matrix((Ldata, (Lrow, Lcol)), shape=(11 * num_spheres + 6 * num_dumbbells, 11 * num_spheres + 6 * num_dumbbells)) R = L.transpose() return (mu * (L * R2Bexact * R), "R2Bexact")
def fts_to_fte_matrix(posdata, grand_mobility_matrix): (sphere_sizes, sphere_positions, sphere_rotations, dumbbell_sizes, dumbbell_positions, dumbbell_deltax, num_spheres, num_dumbbells, element_sizes, element_positions, element_deltax, num_elements, num_elements_array, element_type, uv_start, uv_size, element_start_count) = posdata_data(posdata) M = grand_mobility_matrix C0 = 0 C1 = 3*num_spheres C2 = 6*num_spheres C3 = 11*num_spheres C4 = 11*num_spheres + 3*num_dumbbells C5 = 11*num_spheres + 6*num_dumbbells gt = M[C0:C1,C2:C3] g = gt.transpose() ht = M[C1:C2,C2:C3] h = ht.transpose() m = M[C2:C3,C2:C3] m34= M[C2:C3,C3:C4] m43 = m34.transpose() m35= M[C2:C3,C4:C5] m53 = m35.transpose() # Not possible to have dumbbells only because this is an FTS to FTE conversion, and E is only there for spheres. if num_spheres > 0 and num_dumbbells > 0: items_in_vector = 5 else: items_in_vector = 3 starts = [C0,C1,C2,C3,C4,C5] m_inv = np.linalg.inv(m) crosspoint = 2 #corresponds to the ghm row/col if num_spheres > 0 and num_dumbbells > 0: vec1 = [gt,ht,m,m43,m53] vec2 = [g, h, m,m34,m35] if num_spheres > 0 and num_dumbbells == 0: vec1 = [gt,ht,m] vec2 = [g, h, m] MFTE = M - vecmat_mat_vecmat(vec1,m_inv,vec2,C5,items_in_vector,starts) - vec_mat_cross(vec1,m_inv,vec2,C5,items_in_vector,starts,crosspoint) return MFTE
def input_ftsuoe(n,posdata,frameno,timestep,last_velocities,input_form='undefined',video=False,grand_resistance_matrix_fte=0): # Initialise all vectors in the left and right-hand sides. Then define num_spheres and num_dumbbells (Fa_in, Ta_in, Sa_in, Sa_c_in, Fb_in, DFb_in, Ua_in, Oa_in, Ea_in, Ea_c_in, Ub_in, DUb_in) = empty_vectors(posdata) (sphere_sizes, sphere_positions, sphere_rotations, dumbbell_sizes, dumbbell_positions, dumbbell_deltax, num_spheres, num_dumbbells, element_sizes, element_positions, element_deltax, num_elements, num_elements_array, element_type, uv_start, uv_size, element_start_count) = posdata_data(posdata) # Fa_in: Forces on spheres # Ta_in: Torque on spheres # Sa_in: Stresslets on spheres # Fb_in: Forces on dumbbells (total force on dumbbell, F1+F2) # DFb_in: Internal force on dumbbells (Delta F = F2-F1) # Ua_in: Velocity of spheres # Oa_in: Angular velocity of spheres # Ea_in: Rate of strain, E^infinity # Ub_in: Velocity of dumbbells # DUb_in: HALF the velocity difference of the dumbbells ((U2-U1)/2) # Give values. You must give at least half the total number of U/O/E/F/T/S values. # If you are giving a mix of F and U values for spheres, you must put label the spheres s.t. the fixed velocity spheres are numbered first. # If you are giving a mix of F and U values for dumbbells, you must put label the dumbbells s.t. the fixed velocity dumbbells are numbered first. # Defaults mu = 1 desc = "" box_bottom_left = np.array([0,0,0]) box_top_right = np.array([0,0,0]) # Background velocity is given by u^infinity = U^infinity + Omega^infinity cross x + E^infinity dot x # U^infinity and O^infinity are reset here and are changed for each case if required. # E^infinity is input for each case as Ea_in, and is also reset here if you're using FTE form. U_infinity = np.array([0,0,0]) O_infinity = np.array([0,0,0]) if input_form == "fte": Fa_in[:] = [[0,0,0] for i in xrange(num_spheres)] Ta_in[:] = [[0,0,0] for i in xrange(num_spheres)] Ea_in[:] = [[[0,0,0],[0,0,0],[0,0,0]] for i in xrange(num_spheres)] Fb_in[:] = [[0,0,0] for i in xrange(num_dumbbells)] DFb_in[:] = [[0,0,0] for i in xrange(num_dumbbells)] elif input_form == "fts": Fa_in[:] = [[0,0,0] for i in xrange(num_spheres)] Ta_in[:] = [[0,0,0] for i in xrange(num_spheres)] Sa_in[:] = [[[0,0,0],[0,0,0],[0,0,0]] for i in xrange(num_spheres)] Fb_in[:] = [[0,0,0] for i in xrange(num_dumbbells)] DFb_in[:] = [[0,0,0] for i in xrange(num_dumbbells)] if input_form == "ufte": Ta_in[:] = [[0,0,0] for i in xrange(num_spheres)] Ea_in[:] = [[[0,0,0],[0,0,0],[0,0,0]] for i in xrange(num_spheres)] Fb_in[:] = [[0,0,0] for i in xrange(num_dumbbells)] DFb_in[:] = [[0,0,0] for i in xrange(num_dumbbells)] centre_of_background_flow = np.array([0,0,0]) amplitude = 0 frequency = 0 num_sphere_in_each_lid = 0 if n == 1: # Gravity Fa_in[:] = [[0,0,-1] for i in xrange(num_spheres)] desc = "gravity" elif n == 2: # Gravity in periodic domain Fa_in[:] = [[0,0,-1] for i in xrange(num_spheres)] sphere_positions,box_bottom_left,box_top_right = simple_cubic_8(8) # sphere_positions is ignored here, but to activate periodicity, you have to set box_bottom_left and box_top_right. desc = "gravity-periodic" elif n == 3: # Oscillatory background flow, about the point (2.25,0,2.25) natural_deltax = 2. spring_constant = -1 DFb_in[:] = [list(spring_constant*(dumbbell_deltax[i]-natural_deltax*dumbbell_deltax[i]/np.linalg.norm(dumbbell_deltax[i]))) for i in range(num_dumbbells)] # Simple shear with speed gammadot startfromframe = 0 # amplitude is amplitude at z = 1 (Ea_in, U_infinity, O_infinity, centre_of_background_flow, amplitude, frequency) = oscillatory_shear(amplitude=1./3., period=1, start_from_frame=0, centre_of_background_flow=np.array([2.25,0,2.25]), frameno=frameno, timestep=timestep, num_spheres=num_spheres) desc = "oscillatory-background-flow" elif n == 4: # Repulsive force (Fa_in, Fb_in, DFb_in) = repulsion_forces(100, 20, num_spheres, num_dumbbells, sphere_positions, dumbbell_positions, dumbbell_deltax, sphere_sizes, dumbbell_sizes, num_sphere_in_each_lid, Fa_in, Fb_in, DFb_in) desc = "repulsion" elif n == 5: # Force half the spheres to move to the left with a given velocity, and force the rest to move to the right. Ua_in[:] = [[-1,0,0] for i in xrange(num_spheres/2)] + [[1,0,0] for i in xrange(num_spheres/2,num_spheres)] elif n == 6: # Continuous shear gammadot = 1 O_infinity = np.array([0,0.5*gammadot,0]) Ea_in = [[[0,0,0.5*gammadot],[0,0,0],[0.5*gammadot,0,0]] for i in xrange(max(1,num_spheres))] desc = "continuous-shear" elif n == 7: # Gravity Fa_in[1] = [0,0,-1] desc = "gravity" else: Fa_in = np.array([[99999,-31415,21718]]) # Just something to flag up on the other side that there's a problem return Fa_in, Ta_in, Sa_in, Sa_c_in, Fb_in, DFb_in, Ua_in, Oa_in, Ea_in, Ea_c_in, Ub_in, DUb_in, desc, U_infinity, O_infinity, centre_of_background_flow, amplitude, frequency, box_bottom_left, box_top_right, mu
def construct_force_vector_from_fts(posdata, f_spheres, t_spheres, s_spheres, f_dumbbells, deltaf_dumbbells): (sphere_sizes, sphere_positions, sphere_rotations, dumbbell_sizes, dumbbell_positions, dumbbell_deltax, num_spheres, num_dumbbells, element_sizes, element_positions, element_deltax, num_elements, num_elements_array, element_type, uv_start, uv_size, element_start_count) = posdata_data(posdata) s_spheres_condensed = [['pippa' for i in xrange(5)] for j in xrange(num_spheres)] for i in xrange(num_spheres): for j in xrange(5): s_spheres_condensed[i][j] = sum([sum([contraction(j,k,l)*s_spheres[i][k][l] for k in xrange(3)]) for l in xrange(3)]) if num_spheres == 0 and num_dumbbells == 0: force_vector = np.array([]) if num_spheres > 0 and num_dumbbells == 0: fs = [item for sublist in f_spheres for item in sublist] ts = [item for sublist in t_spheres for item in sublist] ss = [item for sublist in s_spheres_condensed for item in sublist] force_vector = np.fromiter(chain.from_iterable(np.array([fs, ts, ss]).flatten()),float) if num_spheres == 0 and num_dumbbells > 0: force_vector = np.array([f_dumbbells, deltaf_dumbbells]).flatten() if num_spheres > 0 and num_dumbbells > 0: fs = [item for sublist in f_spheres for item in sublist] ts = [item for sublist in t_spheres for item in sublist] ss = [item for sublist in s_spheres_condensed for item in sublist] fd = [item for sublist in f_dumbbells for item in sublist] dfd= [item for sublist in deltaf_dumbbells for item in sublist] force_vector = np.hstack(np.array([fs, ts, ss, fd, dfd]).flat) return force_vector
def deconstruct_velocity_vector_for_fts(posdata, velocity_vector): (sphere_sizes, sphere_positions, sphere_rotations, dumbbell_sizes, dumbbell_positions, dumbbell_deltax, num_spheres, num_dumbbells, element_sizes, element_positions, element_deltax, num_elements, num_elements_array, element_type, uv_start, uv_size, element_start_count) = posdata_data(posdata) N1 = 3*num_spheres N2 = 6*num_spheres N3 = 11*num_spheres N4 = 11*num_spheres + 3*num_dumbbells N5 = 11*num_spheres + 6*num_dumbbells u_spheres = velocity_vector[0:N1].reshape(num_spheres,3) o_spheres = velocity_vector[N1:N2].reshape(num_spheres,3) e_spheres_condensed = velocity_vector[N2:N3].reshape(num_spheres,5) u_dumbbells = velocity_vector[N3:N4].reshape(num_dumbbells,3) half_deltau_dumbbells = velocity_vector[N4:N5].reshape(num_dumbbells,3) e_spheres = np.zeros([num_spheres,3,3]) for i in xrange(num_spheres): e_spheres[i,0,0] = (np.sqrt(3)+3)/6. * e_spheres_condensed[i,0] + (np.sqrt(3)-3)/6. * e_spheres_condensed[i,2] e_spheres[i,0,1] = e_spheres_condensed[i,1]/np.sqrt(2) e_spheres[i,0,2] = e_spheres_condensed[i,3]/np.sqrt(2) e_spheres[i,1,0] = e_spheres[i,0,1] e_spheres[i,1,1] = (np.sqrt(3)-3)/6. * e_spheres_condensed[i,0] + (np.sqrt(3)+3)/6. * e_spheres_condensed[i,2] e_spheres[i,1,2] = e_spheres_condensed[i,4]/np.sqrt(2) e_spheres[i,2,0] = e_spheres[i,0,2] e_spheres[i,2,1] = e_spheres[i,1,2] e_spheres[i,2,2] = -e_spheres[i,1,1] - e_spheres[i,0,0] return (u_spheres, o_spheres, e_spheres, u_dumbbells, half_deltau_dumbbells)
def ufte_to_ufteu_matrix(num_fixed_velocity_dumbbells,num_fixed_velocity_spheres,posdata, grand_mobility_matrix_ufte): (sphere_sizes, sphere_positions, sphere_rotations, dumbbell_sizes, dumbbell_positions, dumbbell_deltax, num_spheres, num_dumbbells, element_sizes, element_positions, element_deltax, num_elements, num_elements_array, element_type, uv_start, uv_size, element_start_count) = posdata_data(posdata) M = grand_mobility_matrix_ufte C0 = 0 C05= 3*num_fixed_velocity_spheres C1 = 3*num_spheres C2 = 6*num_spheres C3 = 11*num_spheres C35 = 11*num_spheres + 3*num_fixed_velocity_dumbbells C4 = 11*num_spheres + 3*num_dumbbells C45 = 11*num_spheres + 3*num_dumbbells + 3*num_fixed_velocity_dumbbells C5 = 11*num_spheres + 6*num_dumbbells starts = [C0,C05,C1,C2,C3,C35,C4,C45,C5] # now m44 and m55 have been split up into x (fixed velocity particles) and r (free velocity particles) # M = [axx axr btx gtx m14xx m14xr m15xx m15xr] # [arx arr btr gtr m14rx m14rr m15rx m15rr] # [bx br c ht m24x m24r m25x m25r ] # [gx gr h m m34x m34r m35x m35r ] # [m41xx m41rx m42x m43x m44xx m44xr m45xx m45xr] # etc # Step 1. Swap the m44xx row and column m41xx = M[C3:C35,C0:C05] m41rx = M[C3:C35,C05:C1] m42x = M[C3:C35,C1:C2] m43x = M[C3:C35,C2:C3] m44xx = M[C3:C35,C3:C35] m44xr = M[C3:C35,C35:C4] m45xx = M[C3:C35,C4:C45] m45xr = M[C3:C35,C45:C5] m14xx = -m41xx.transpose() m14rx = m41rx.transpose() m24x = m42x.transpose() m34x = -m43x.transpose() m44rx = m44xr.transpose() m54xx = m45xx.transpose() m54rx = m45xr.transpose() # Currently I haven't put in dumbbells only because there's no point I think. Since this comes from an FTE conversion, and E is only for spheres, that would need dealing with first. # If there are no dumbbells then doing this is pointless, so I am assuming there are dumbbells. items_in_vector = 7+1 m44xx_inv = np.linalg.inv(m44xx) crosspoint=4 #corresponds to the m44xx row/col vec1 = [m14xx,m14rx,m24x,m34x,m44xx,m44rx,m54xx,m54rx] #down vec2 = [m41xx,m41rx,m42x,m43x,m44xx,m44xr,m45xx,m45xr] # across MUFTEU1 = M - vecmat_mat_vecmat(vec1,m44xx_inv,vec2,C5,items_in_vector,starts) - vec_mat_cross(vec1,m44xx_inv,vec2,C5,items_in_vector,starts,crosspoint) # Step 2. Swap the m55xx row and column M = MUFTEU1 m51xx = M[C4:C45,C0:C05] m51rx = M[C4:C45,C05:C1] m52x = M[C4:C45,C1:C2] m53x = M[C4:C45,C2:C3] m54xx = M[C4:C45,C3:C35] m54xr = M[C4:C45,C35:C4] m55xx = M[C4:C45,C4:C45] m55xr = M[C4:C45,C45:C5] m15xx = -m51xx.transpose() m15rx = m51rx.transpose() m25x = m52x.transpose() m35x = -m53x.transpose() m45xx = -m54xx.transpose() m45rx = m54xr.transpose() m55rx = m55xr.transpose() m55xx_inv = np.linalg.inv(m55xx) crosspoint=6 #corresponds to the m55xx row/col vec1 = [m15xx,m15rx,m25x,m35x,m45xx,m45rx,m55xx,m55rx] #down vec2 = [m51xx,m51rx,m52x,m53x,m54xx,m54xr,m55xx,m55xr] # across MUFTEU = M - vecmat_mat_vecmat(vec1,m55xx_inv,vec2,C5,items_in_vector,starts) - vec_mat_cross(vec1,m55xx_inv,vec2,C5,items_in_vector,starts,crosspoint) return MUFTEU
def fts_to_duf_matrix(num_fixed_velocity_dumbbells,posdata, grand_mobility_matrix_fts): (sphere_sizes, sphere_positions, sphere_rotations, dumbbell_sizes, dumbbell_positions, dumbbell_deltax, num_spheres, num_dumbbells, element_sizes, element_positions, element_deltax, num_elements, num_elements_array, element_type, uv_start, uv_size, element_start_count) = posdata_data(posdata) M = grand_mobility_matrix_fts C3 = 0 C35 = 3*num_fixed_velocity_dumbbells C4 = 3*num_dumbbells C45 = 3*num_dumbbells + 3*num_fixed_velocity_dumbbells C5 = 6*num_dumbbells starts = [C3,C35,C4,C45,C5] # now m44 and m55 have been split up into x (fixed velocity particles) and r (free velocity particles) # M = [m44xx m44xr m45xx m45xr] # [m44rx m44rr m45rx m45rr] # etc # Step 1. Swap the m44xx row and column m44xx = M[C3:C35,C3:C35] m44xr = M[C3:C35,C35:C4] m45xx = M[C3:C35,C4:C45] m45xr = M[C3:C35,C45:C5] m44rx = m44xr.transpose() m54xx = m45xx.transpose() m54rx = m45xr.transpose() # Currently I haven't put in dumbbells only because there's no point I think. Since this comes from an FTE conversion, and E is only for spheres, that would need dealing with first. # If there are no dumbbells then doing this is pointless, so I am assuming there are dumbbells. items_in_vector = 4 m44xx_inv = np.linalg.inv(m44xx) crosspoint=0 #corresponds to the m44xx row/col vec1 = [m44xx,m44rx,m54xx,m54rx] #down vec2 = [m44xx,m44xr,m45xx,m45xr] # across MDUF1 = M - vecmat_mat_vecmat(vec1,m44xx_inv,vec2,C5,items_in_vector,starts) - vec_mat_cross(vec1,m44xx_inv,vec2,C5,items_in_vector,starts,crosspoint) # Step 2. Swap the m55xx row and column M = MDUF1 m54xx = M[C4:C45,C3:C35] m54xr = M[C4:C45,C35:C4] m55xx = M[C4:C45,C4:C45] m55xr = M[C4:C45,C45:C5] m45xx = -m54xx.transpose() m45rx = m54xr.transpose() m55rx = m55xr.transpose() m55xx_inv = np.linalg.inv(m55xx) crosspoint=2 #corresponds to the m55xx row/col vec1 = [m45xx,m45rx,m55xx,m55rx] #down vec2 = [m54xx,m54xr,m55xx,m55xr] # across MDUF = M - vecmat_mat_vecmat(vec1,m55xx_inv,vec2,C5,items_in_vector,starts) - vec_mat_cross(vec1,m55xx_inv,vec2,C5,items_in_vector,starts,crosspoint) return MDUF
def empty_vectors(posdata): (sphere_sizes, sphere_positions, sphere_rotations, dumbbell_sizes, dumbbell_positions, dumbbell_deltax, num_spheres, num_dumbbells, element_sizes, element_positions, element_deltax, num_elements, num_elements_array, element_type, uv_start, uv_size, element_start_count) = posdata_data(posdata) return ([['pippa' for j in xrange(3)] for i in xrange(num_spheres)], [['pippa' for j in xrange(3)] for i in xrange(num_spheres)], [[['pippa' for k in xrange(3)] for j in xrange(3)] for i in xrange(num_spheres)], [['pippa' for j in xrange(5)] for i in xrange(num_spheres)], [['pippa' for j in xrange(3)] for i in xrange(num_dumbbells)], [['pippa' for j in xrange(3)] for i in xrange(num_dumbbells)], [['pippa' for j in xrange(3)] for i in xrange(num_spheres)], [['pippa' for j in xrange(3)] for i in xrange(num_spheres)], [[['pippa' for k in xrange(3)] for j in xrange(3)] for i in xrange(num_spheres)], [['pippa' for j in xrange(5)] for i in xrange(num_spheres)], [['pippa' for j in xrange(3)] for i in xrange(num_dumbbells)], [['pippa' for j in xrange(3)] for i in xrange(num_dumbbells)])
def fte_to_ufte_matrix(num_fixed_velocity_spheres,posdata, grand_mobility_matrix_fte): (sphere_sizes, sphere_positions, sphere_rotations, dumbbell_sizes, dumbbell_positions, dumbbell_deltax, num_spheres, num_dumbbells, element_sizes, element_positions, element_deltax, num_elements, num_elements_array, element_type, uv_start, uv_size, element_start_count) = posdata_data(posdata) M = grand_mobility_matrix_fte C0 = 0 C05= 3*num_fixed_velocity_spheres C1 = 3*num_spheres C2 = 6*num_spheres C3 = 11*num_spheres C4 = 11*num_spheres + 3*num_dumbbells C5 = 11*num_spheres + 6*num_dumbbells # a has been split up into x (fixed velocity particles) and r (free velocity particles) # M = [axx axr btx gtx m14x m15x] # [arx arr btr gtr m14r m15r] # [bx br c ht m24 m25 ] # [gx gr h m m34 m35 axx = M[C0:C05,C0:C05] axr = M[C0:C05,C05:C1] arx = M[C05:C1,C0:C05] btx = M[C0:C05,C1:C2] bx = btx.transpose() gtx = M[C0:C05,C2:C3] gx = -gtx.transpose() #note MFTE has slightly different sign symmetries m14x= M[C0:C05,C3:C4] m15x= M[C0:C05,C4:C5] m51x = m15x.transpose() # these don't need a minus sign. m41x = m14x.transpose() # # Not possible to have dumbbells only because this is an FTS to FTE conversion, and E is only there for spheres. if num_spheres > 0 and num_dumbbells > 0: items_in_vector = 5+1 else: items_in_vector = 3+1 starts = [C0,C05,C1,C2,C3,C4,C5] axx_inv = np.linalg.inv(axx) gx = np.asarray(gx) crosspoint=0 #corresponds to the ghm row/col if num_spheres > 0 and num_dumbbells > 0: vec1 = [axx,arx,bx,gx,m41x,m51x] vec2 = [axx,axr,btx,gtx,m14x,m15x] if num_spheres > 0 and num_dumbbells == 0: vec1 = [axx,arx,bx,gx] vec2 = [axx,axr,btx,gtx] MFTE = M - vecmat_mat_vecmat(vec1,axx_inv,vec2,C5,items_in_vector,starts) - vec_mat_cross(vec1,axx_inv,vec2,C5,items_in_vector,starts,crosspoint) return MFTE
def zero_force_vectors(posdata): (sphere_sizes, sphere_positions, sphere_rotations, dumbbell_sizes, dumbbell_positions, dumbbell_deltax, num_spheres, num_dumbbells, element_sizes, element_positions, element_deltax, num_elements, num_elements_array, element_type, uv_start, uv_size, element_start_count) = posdata_data(posdata) return (np.zeros([num_spheres,3]),np.zeros([num_spheres,3]),np.zeros([num_spheres,3,3]),np.zeros([num_spheres,5]),np.zeros([num_dumbbells,3]),np.zeros([num_dumbbells,3]))
def generate_grand_resistance_matrix(posdata, last_generated_Minfinity_inverse, regenerate_Minfinity=False, cutoff_factor=2, printout=0, use_XYZd_values=True, use_drag_Minfinity=False, use_Minfinity_only=False, frameno=0, checkpoint_start_from_frame=0, feed_every_n_timesteps=0, mu=1): ''' if use_XYZd_values: d = "-d" else: d = "" ''' d = "-d" Minfinity_start_time = time.time() if not (use_drag_Minfinity): if regenerate_Minfinity: (Minfinity, headingM) = generate_Minfinity(posdata, printout, frameno=frameno, mu=mu) Minfinity_elapsed_time = time.time() - Minfinity_start_time Minfinity_inverse_start_time = time.time() Minfinity_inverse = linalg.inv(Minfinity) if printout > 0: print "Minfinity[0:12]" print np.array_str(Minfinity[0:12, 0:12], max_line_width=100000) else: Minfinity_elapsed_time = time.time() - Minfinity_start_time Minfinity_inverse_start_time = time.time() Minfinity_inverse = last_generated_Minfinity_inverse Minfinity_inverse_elapsed_time = time.time( ) - Minfinity_inverse_start_time else: (sphere_sizes, sphere_positions, sphere_rotations, dumbbell_sizes, dumbbell_positions, dumbbell_deltax, num_spheres, num_dumbbells, element_sizes, element_positions, element_deltax, num_elements, num_elements_array, element_type, uv_start, uv_size, element_start_count) = posdata_data(posdata) Minfinity_inverse = mu * np.diag( [sphere_sizes[i / 3] for i in xrange(3 * num_spheres)] + [ 1 / 0.75 * sphere_sizes[i / 3]**3 for i in xrange(3 * num_spheres) ] + [ 1 / 0.9 * sphere_sizes[i / 5]**3 for i in xrange(5 * num_spheres) ] + [2 * dumbbell_sizes[i / 3] for i in xrange(3 * num_dumbbells)] + [2 * dumbbell_sizes[i / 3] for i in xrange(3 * num_dumbbells)]) Minfinity_elapsed_time = 0 Minfinity_inverse_elapsed_time = 0 if printout > 0: print "Minfinity_inverse" print np.array_str(Minfinity_inverse, max_line_width=100000) if not use_Minfinity_only: R2Bexact_start_time = time.time() # Whether we use the d values or not is selected in inputs.py where we read in XYZ_raw. if printout > 1: print "cutoff_factor is ", cutoff_factor (R2Bexact, heading) = generate_R2Bexact( posdata, printout, cutoff_factor=cutoff_factor, frameno=frameno, checkpoint_start_from_frame=checkpoint_start_from_frame, feed_every_n_timesteps=feed_every_n_timesteps, mu=mu) R2Bexact_elapsed_time = time.time() - R2Bexact_start_time if printout > 0: print "R2Bexact" print np.array_str(R2Bexact.toarray(), max_line_width=100000) grand_resistance_matrix = Minfinity_inverse + R2Bexact.toarray() if printout > 0: print "grand R" print np.array_str(grand_resistance_matrix, max_line_width=100000) else: grand_resistance_matrix = Minfinity_inverse R2Bexact = 0 heading = "" R2Bexact_elapsed_time = 0 if (printout > 1): print "M infinity" print np.array_str(Minfinity, max_line_width=100000) print "\n\nR2Bexact" print np.array_str(R2Bexact.toarray(), max_line_width=100000) print "\n\nGrand resistance matrix" print np.array_str(grand_resistance_matrix, max_line_width=100000) save_matrix(grand_resistance_matrix, "Grand Resistance Matrix", "R-" + str(frameno) + ".txt") gen_times = [ Minfinity_elapsed_time, Minfinity_inverse_elapsed_time, R2Bexact_elapsed_time ] return (grand_resistance_matrix, heading, Minfinity_inverse, gen_times)
def generate_grand_resistance_matrix_periodic( posdata, last_generated_Minfinity_inverse, box_bottom_left, box_top_right, regenerate_Minfinity=False, cutoff_factor=2, printout=0, use_XYZd_values=True, use_drag_Minfinity=False, use_Minfinity_only=False, frameno=0, checkpoint_start_from_frame=0, feed_every_n_timesteps=0, O_infinity=np.array([0, 0, 0]), E_infinity=np.array([[0, 0, 0], [0, 0, 0], [0, 0, 0]]), timestep=0.1, centre_of_background_flow=np.array([0, 0, 0]), mu=1, amplitude=1, frequency=1): d = "-d" if not (use_drag_Minfinity): # i.e. if we should do Minfinity properly: Minfinity_start_time = time.time() if regenerate_Minfinity: (Minfinity, headingM) = generate_Minfinity_periodic( posdata, box_bottom_left, box_top_right, printout, frameno=frameno, O_infinity=O_infinity, E_infinity=E_infinity, timestep=timestep, centre_of_background_flow=centre_of_background_flow, mu=mu, frequency=frequency, amplitude=amplitude) Minfinity_elapsed_time = time.time() - Minfinity_start_time Minfinity_inverse_start_time = time.time() Minfinity_inverse = linalg.inv(Minfinity) else: Minfinity_elapsed_time = time.time() - Minfinity_start_time Minfinity_inverse_start_time = time.time() Minfinity_inverse = last_generated_Minfinity_inverse Minfinity_inverse_elapsed_time = time.time( ) - Minfinity_inverse_start_time else: (sphere_sizes, sphere_positions, sphere_rotations, dumbbell_sizes, dumbbell_positions, dumbbell_deltax, num_spheres, num_dumbbells, element_sizes, element_positions, element_deltax, num_elements, num_elements_array, element_type, uv_start, uv_size, element_start_count) = posdata_data(posdata) Minfinity_inverse = mu * np.diag( [sphere_sizes[i / 3] for i in xrange(3 * num_spheres)] + [ 1 / 0.75 * sphere_sizes[i / 3]**3 for i in xrange(3 * num_spheres) ] + [ 1 / 0.9 * sphere_sizes[i / 5]**3 for i in xrange(5 * num_spheres) ] + [2 * dumbbell_sizes[i / 3] for i in xrange(3 * num_dumbbells)] + [2 * dumbbell_sizes[i / 3] for i in xrange(3 * num_dumbbells)]) Minfinity_elapsed_time = 0 Minfinity_inverse_elapsed_time = 0 if not use_Minfinity_only: R2Bexact_start_time = time.time() (R2Bexact, heading) = generate_R2Bexact_periodic( posdata, box_bottom_left, box_top_right, printout, cutoff_factor=cutoff_factor, frameno=frameno, checkpoint_start_from_frame=checkpoint_start_from_frame, feed_every_n_timesteps=feed_every_n_timesteps, O_infinity=O_infinity, E_infinity=E_infinity, timestep=timestep, centre_of_background_flow=centre_of_background_flow, mu=mu, frequency=frequency, amplitude=amplitude) R2Bexact_elapsed_time = time.time() - R2Bexact_start_time grand_resistance_matrix = Minfinity_inverse + R2Bexact.toarray() else: grand_resistance_matrix = Minfinity_inverse R2Bexact = 0 heading = "" R2Bexact_elapsed_time = 0 gen_times = [ Minfinity_elapsed_time, Minfinity_inverse_elapsed_time, R2Bexact_elapsed_time ] return (grand_resistance_matrix, heading, Minfinity_inverse, gen_times)
def generate_Minfinity_periodic(posdata, box_bottom_left, box_top_right, printout=0, cutoff_factor=2,frameno=0,O_infinity=np.array([0,0,0]),E_infinity=np.array([[0,0,0],[0,0,0],[0,0,0]]),timestep=0.1,centre_of_background_flow=np.array([0,0,0]),mu=1,frequency=1,amplitude=1): # NOTE: Centre of background flow currently not implemented - 27/1/2017 (sphere_sizes, sphere_positions, sphere_rotations, dumbbell_sizes, dumbbell_positions, dumbbell_deltax, num_spheres, num_dumbbells, element_sizes, element_positions, element_deltax, num_elements, num_elements_array, element_type, uv_start, uv_size, element_start_count) = posdata_data(posdata) R2Bexact_sidelength = 11*num_spheres + 6*num_dumbbells R2Bexact = np.zeros((R2Bexact_sidelength, R2Bexact_sidelength), dtype=np.float) bead_positions = np.concatenate([sphere_positions,dumbbell_positions - 0.5*dumbbell_deltax, dumbbell_positions + 0.5*dumbbell_deltax]) bead_sizes = np.concatenate([sphere_sizes, dumbbell_sizes, dumbbell_sizes]) c = 1./(8*pi*mu) # Set lamb, the 'switch' between real and wavespace. Beenakker says set this as lambda = sqrt(pi)/L Lx = box_top_right[0] - box_bottom_left[0] Ly = box_top_right[1] - box_bottom_left[1] Lz = box_top_right[2] - box_bottom_left[2] L = (Lx*Ly*Lz)**(1./3.) lamb = math.sqrt(math.pi)/L gridpoints_x = [i for i in range(-how_far_to_reproduce_gridpoints,how_far_to_reproduce_gridpoints+1)] gridpoints_y = [i for i in range(-how_far_to_reproduce_gridpoints,how_far_to_reproduce_gridpoints+1)] gridpoints_z = [i for i in range(-how_far_to_reproduce_gridpoints,how_far_to_reproduce_gridpoints+1)] X_lmn_canonical = np.array([[ll,mm,nn] for ll in gridpoints_x for mm in gridpoints_y for nn in gridpoints_z]) basis_canonical = np.array([[Lx,0,0],[0,Ly,0],[0,0,Lz]]) # NOTE: For CONTINUOUS shear, set the following #time_t = frameno*timestep #sheared_basis_vectors_add_on = (np.cross(np.array(O_infinity)*time_t,basis_canonical).transpose() + np.dot(np.array(E_infinity)*time_t,(basis_canonical).transpose())).transpose()# + basis_canonical # NOTE: For OSCILLATORY shear, set the following (basically there isn't a way to find out shear given E) time_t = frameno*timestep gamma = amplitude*np.sin(time_t*frequency) Ot_infinity = np.array([0,0.5*gamma,0]) Et_infinity = [[0,0,0.5*gamma],[0,0,0],[0.5*gamma,0,0]] sheared_basis_vectors_add_on = (np.cross(Ot_infinity,basis_canonical).transpose() + np.dot(Et_infinity,(basis_canonical).transpose())).transpose() sheared_basis_vectors_add_on_mod = np.mod(sheared_basis_vectors_add_on,[Lx,Ly,Lz]) sheared_basis_vectors = basis_canonical + sheared_basis_vectors_add_on_mod X_lmn_sheared = np.dot(X_lmn_canonical,sheared_basis_vectors) X_lmn_sheared_inside_radius = X_lmn_sheared[np.linalg.norm(X_lmn_sheared,axis=1)<=1.4142*how_far_to_reproduce_gridpoints*L] # NOTE: If you change this you have to change it in K_lmn as well! X_lmn = X_lmn_sheared_inside_radius Xdash_lmn = X_lmn_sheared_inside_radius[np.linalg.norm(X_lmn_sheared_inside_radius,axis=1)>0] Sdash_lmn = np.linalg.norm(Xdash_lmn,axis=1) erfcs_Sdash_lmn = [generate_erfcs(s,lamb) for s in Sdash_lmn] num_X_points = X_lmn.shape[0] num_Xdash_points = Xdash_lmn.shape[0] k_basis_vectors = 2*np.pi*L**(-3)*np.array([np.cross(sheared_basis_vectors[0],sheared_basis_vectors[2]),np.cross(sheared_basis_vectors[2],sheared_basis_vectors[1]),np.cross(sheared_basis_vectors[0],sheared_basis_vectors[1])]) K_lmn = np.dot(X_lmn_canonical,k_basis_vectors)[np.logical_and(np.linalg.norm(X_lmn_sheared,axis=1)<=1.4142*how_far_to_reproduce_gridpoints*L,np.linalg.norm(X_lmn_sheared,axis=1)>0)] Ks_lmn = np.linalg.norm(K_lmn,axis=1) num_K_points = K_lmn.shape[0] RR_K = [-8*math.pi/ks**4 * (1 + ks**2/(4*lamb**2) + ks**4/(8*lamb**4)) * math.exp(-ks**2/(4*lamb**2)) for ks in Ks_lmn] for a1_index,a2_index in [(u,v) for u in range(len(bead_sizes)) for v in range(u,len(bead_sizes))]: r = (bead_positions[a2_index] - bead_positions[a1_index]) a1 = bead_sizes[a1_index] a2 = bead_sizes[a2_index] s = norm(r) if s > 1e-8 and 2*s/(a1+a2) < 2.001: ss_out = 2.001*(a1+a2)/2 r = [r[0]*ss_out/s,r[1]*ss_out/s,r[2]*ss_out/s] s = ss_out if a1_index < num_spheres and a2_index < num_spheres: # Sphere to sphere A_coords = np.s_[ a1_index*3 : (a1_index+1)*3, a2_index*3 : (a2_index+1)*3] Bt_coords = np.s_[ a1_index*3 : (a1_index+1)*3, 3*num_spheres+a2_index*3 : 3*num_spheres+(a2_index+1)*3] Bt_coords_21 = np.s_[ a2_index*3 : (a2_index+1)*3, 3*num_spheres+a1_index*3 : 3*num_spheres+(a1_index+1)*3] Gt_coords = np.s_[ a1_index*3 : (a1_index+1)*3, 6*num_spheres+a2_index*5 : 6*num_spheres+(a2_index+1)*5] Gt_coords_21 = np.s_[ a2_index*3 : (a2_index+1)*3, 6*num_spheres+a1_index*5 : 6*num_spheres+(a1_index+1)*5] C_coords = np.s_[3*num_spheres+a1_index*3 : 3*num_spheres+(a1_index+1)*3, 3*num_spheres+a2_index*3 : 3*num_spheres+(a2_index+1)*3] Ht_coords = np.s_[3*num_spheres+a1_index*3 : 3*num_spheres+(a1_index+1)*3, 6*num_spheres+a2_index*5 : 6*num_spheres+(a2_index+1)*5] Ht_coords_21 = np.s_[3*num_spheres+a2_index*3 : 3*num_spheres+(a2_index+1)*3, 6*num_spheres+a1_index*5 : 6*num_spheres+(a1_index+1)*5] M_coords = np.s_[6*num_spheres+a1_index*5 : 6*num_spheres+(a1_index+1)*5, 6*num_spheres+a2_index*5 : 6*num_spheres+(a2_index+1)*5] erfcs = generate_erfcs(s,lamb) R2Bexact[A_coords] = [[M11(r,s,a1,a2,i,j,erfcs, L, lamb, X_lmn, Xdash_lmn, Sdash_lmn, erfcs_Sdash_lmn, K_lmn, Ks_lmn, RR_K, num_X_points, num_Xdash_points, num_K_points,c,mu) for j in range(3)] for i in range(3)] R2Bexact[Bt_coords] = [[M12(r,s,a1,a2,i,j,erfcs, L, lamb, X_lmn, Xdash_lmn, Sdash_lmn, erfcs_Sdash_lmn, K_lmn, Ks_lmn, RR_K, num_X_points, num_Xdash_points, num_K_points,c,mu) for j in range(3)] for i in range(3)] R2Bexact[Bt_coords_21] = -R2Bexact[Bt_coords] R2Bexact[C_coords] = [[M22(r,s,a1,a2,i,j,erfcs, L, lamb, X_lmn, Xdash_lmn, Sdash_lmn, erfcs_Sdash_lmn, K_lmn, Ks_lmn, RR_K, num_X_points, num_Xdash_points, num_K_points,c,mu) for j in range(3)] for i in range(3)] R2Bexact[Gt_coords] = [[con_M13(r,s,a1,a2,i,j,erfcs, L, lamb, X_lmn, Xdash_lmn, Sdash_lmn, erfcs_Sdash_lmn, K_lmn, Ks_lmn, RR_K, num_X_points, num_Xdash_points, num_K_points,c,mu) for j in range(5)] for i in range(3)] R2Bexact[Gt_coords_21] = -R2Bexact[Gt_coords] R2Bexact[Ht_coords] = [[con_M23(r,s,a1,a2,i,j,erfcs, L, lamb, X_lmn, Xdash_lmn, Sdash_lmn, erfcs_Sdash_lmn, K_lmn, Ks_lmn, RR_K, num_X_points, num_Xdash_points, num_K_points,c,mu) for j in range(5)] for i in range(3)] R2Bexact[Ht_coords_21] = R2Bexact[Ht_coords] R2Bexact[M_coords] = [[con_M33(r,s,a1,a2,i,j,erfcs, L, lamb, X_lmn, Xdash_lmn, Sdash_lmn, erfcs_Sdash_lmn, K_lmn, Ks_lmn, RR_K, num_X_points, num_Xdash_points, num_K_points,c,mu) for j in range(5)] for i in range(5)] elif a1_index < num_spheres and a2_index >= num_spheres and a2_index < num_spheres + num_dumbbells: # Sphere to dumbbell bead 1 mr = [-r[0],-r[1],-r[2]] a2_index_d = a2_index-num_spheres R14_coords = np.s_[a1_index*3:(a1_index+1)*3, 11*num_spheres+a2_index_d*3 : 11*num_spheres +(a2_index_d+1)*3] R24_coords = np.s_[3*num_spheres+a1_index*3:3*num_spheres+(a1_index+1)*3, 11*num_spheres+a2_index_d*3 : 11*num_spheres +(a2_index_d+1)*3] R34_coords = np.s_[6*num_spheres+a1_index*5:6*num_spheres+(a1_index+1)*5, 11*num_spheres+a2_index_d*3 : 11*num_spheres +(a2_index_d+1)*3] R2Bexact[R14_coords] = [[M11(r,s,a1,a2,i,j,erfcs, L, lamb, X_lmn, Xdash_lmn, Sdash_lmn, erfcs_Sdash_lmn, K_lmn, Ks_lmn, RR_K, num_X_points, num_Xdash_points, num_K_points,c,mu) for j in range(3)] for i in range(3)] R2Bexact[R24_coords] = [[M12(mr,s,a2,a1,j,i,erfcs, L, lamb, X_lmn, Xdash_lmn, Sdash_lmn, erfcs_Sdash_lmn, K_lmn, Ks_lmn, RR_K, num_X_points, num_Xdash_points, num_K_points,c,mu) for j in range(3)] for i in range(3)] R2Bexact[R34_coords] = [[con_M13(mr,s,a1,a2,j,i,erfcs, L, lamb, X_lmn, Xdash_lmn, Sdash_lmn, erfcs_Sdash_lmn, K_lmn, Ks_lmn, RR_K, num_X_points, num_Xdash_points, num_K_points,c,mu) for j in range(3)] for i in range(5)] elif a1_index < num_spheres and a2_index >= num_spheres + num_dumbbells: # Sphere to dumbbell bead 2 mr = [-r[0],-r[1],-r[2]] a2_index_d = a2_index-num_spheres-num_dumbbells R15_coords = np.s_[a1_index*3:(a1_index+1)*3, 11*num_spheres+3*num_dumbbells+a2_index_d*3 : 11*num_spheres+3*num_dumbbells+(a2_index_d+1)*3] R25_coords = np.s_[3*num_spheres+a1_index*3:3*num_spheres+(a1_index+1)*3, 11*num_spheres+3*num_dumbbells+a2_index_d*3 : 11*num_spheres+3*num_dumbbells+(a2_index_d+1)*3] R35_coords = np.s_[6*num_spheres+a1_index*5:6*num_spheres+(a1_index+1)*5, 11*num_spheres+3*num_dumbbells+a2_index_d*3 : 11*num_spheres+3*num_dumbbells+(a2_index_d+1)*3] R2Bexact[R15_coords] = [[M11(r,s,a1,a2,i,j,erfcs, L, lamb, X_lmn, Xdash_lmn, Sdash_lmn, erfcs_Sdash_lmn, K_lmn, Ks_lmn, RR_K, num_X_points, num_Xdash_points, num_K_points,c,mu) for j in range(3)] for i in range(3)] R2Bexact[R25_coords] = [[M12(mr,s,a2,a1,j,i,erfcs, L, lamb, X_lmn, Xdash_lmn, Sdash_lmn, erfcs_Sdash_lmn, K_lmn, Ks_lmn, RR_K, num_X_points, num_Xdash_points, num_K_points,c,mu) for j in range(3)] for i in range(3)] R2Bexact[R35_coords] = [[con_M13(mr,s,a1,a2,j,i,erfcs, L, lamb, X_lmn, Xdash_lmn, Sdash_lmn, erfcs_Sdash_lmn, K_lmn, Ks_lmn, RR_K, num_X_points, num_Xdash_points, num_K_points,c,mu) for j in range(3)] for i in range(5)] elif a1_index >= num_spheres and a1_index < num_spheres + num_dumbbells and a2_index >= num_spheres and a2_index < num_spheres + num_dumbbells: # Dumbbell bead 1 to dumbbell bead 1 a1_index_d = a1_index-num_spheres a2_index_d = a2_index-num_spheres if bead_bead_interactions or a1_index_d == a2_index_d: R44_coords = np.s_[11*num_spheres+a1_index_d*3:11*num_spheres+(a1_index_d+1)*3, 11*num_spheres+a2_index_d*3 : 11*num_spheres+(a2_index_d+1)*3] erfcs = generate_erfcs(s,lamb) R2Bexact[R44_coords] = [[M11(r,s,a1,a2,i,j,erfcs, L, lamb, X_lmn, Xdash_lmn, Sdash_lmn, erfcs_Sdash_lmn, K_lmn, Ks_lmn, RR_K, num_X_points, num_Xdash_points, num_K_points,c,mu) for j in range(3)] for i in range(3)] s_lmn = np.linalg.norm(r + X_lmn,axis=1) elif a1_index >= num_spheres and a1_index < num_spheres + num_dumbbells and a2_index >= num_spheres + num_dumbbells: # Dumbbell bead 1 to dumbbell bead 2 a1_index_d = a1_index-num_spheres a2_index_d = a2_index-num_spheres-num_dumbbells if bead_bead_interactions or a1_index_d == a2_index_d: R45_coords = np.s_[11*num_spheres+a1_index_d*3:11*num_spheres+(a1_index_d+1)*3, 11*num_spheres+3*num_dumbbells+a2_index_d*3 : 11*num_spheres+3*num_dumbbells+(a2_index_d+1)*3] erfcs = generate_erfcs(s,lamb) R2Bexact[R45_coords] = [[M11(r,s,a1,a2,i,j,erfcs, L, lamb, X_lmn, Xdash_lmn, Sdash_lmn, erfcs_Sdash_lmn, K_lmn, Ks_lmn, RR_K, num_X_points, num_Xdash_points, num_K_points,c,mu) for j in range(3)] for i in range(3)] else: # Dumbbell bead 2 to dumbbell bead 2 a1_index_d = a1_index-num_spheres-num_dumbbells a2_index_d = a2_index-num_spheres-num_dumbbells if bead_bead_interactions or a1_index_d == a2_index_d: R55_coords = np.s_[11*num_spheres+3*num_dumbbells+a1_index_d*3:11*num_spheres+3*num_dumbbells+(a1_index_d+1)*3, 11*num_spheres+3*num_dumbbells+a2_index_d*3 : 11*num_spheres+3*num_dumbbells+(a2_index_d+1)*3] erfcs = generate_erfcs(s,lamb) R2Bexact[R55_coords] = [[M11(r,s,a1,a2,i,j,erfcs, L, lamb, X_lmn, Xdash_lmn, Sdash_lmn, erfcs_Sdash_lmn, K_lmn, Ks_lmn, RR_K, num_X_points, num_Xdash_points, num_K_points,c,mu) for j in range(3)] for i in range(3)] #symmetrise R2Bexact = np.triu(R2Bexact) + np.triu(R2Bexact,k=1).transpose() # Row and column ops I want are equivalent to doing # [ 1 0 0 ] [ a b c ] [ 1 0 0 ] # [ 0 1/2 1/2 ] . [ d e f ] . [ 0 1/2 -1/2 ] # [ 0 -1/2 1/2 ] [ g h i ] [ 0 1/2 1/2 ] # "L" "R" # I know that we could generate L and R elsewhere rather than doing it every timestep but it takes 0.01s for a few thousand dumbbells so for now I don't mind Lrow = np.array([i for i in range(11*num_spheres + 6*num_dumbbells)] + [i + 11*num_spheres for i in range(3*num_dumbbells)] + [i + 11*num_spheres + 3*num_dumbbells for i in range(3*num_dumbbells)]) Lcol = np.array([i for i in range(11*num_spheres + 6*num_dumbbells)] + [i + 11*num_spheres + 3*num_dumbbells for i in range(3*num_dumbbells)] + [i + 11*num_spheres for i in range(3*num_dumbbells)]) Ldata = np.array([1 for i in range(11*num_spheres)] + [0.5 for i in range(9*num_dumbbells)] + [-0.5 for i in range(3*num_dumbbells)]) L = coo_matrix((Ldata, (Lrow, Lcol)), shape=(11*num_spheres+6*num_dumbbells, 11*num_spheres+6*num_dumbbells)) R = L.transpose() return ((L*R2Bexact*R), "Minfinity")
def generate_Minfinity(posdata, printout=0, cutoff_factor=2, frameno=0, mu=1): (sphere_sizes, sphere_positions, sphere_rotations, dumbbell_sizes, dumbbell_positions, dumbbell_deltax, num_spheres, num_dumbbells, element_sizes, element_positions, element_deltax, num_elements, num_elements_array, element_type, uv_start, uv_size, element_start_count) = posdata_data(posdata) R2Bexact_sidelength = 11 * num_spheres + 6 * num_dumbbells R2Bexact = np.zeros((R2Bexact_sidelength, R2Bexact_sidelength), dtype=np.float) bead_positions = np.concatenate([ sphere_positions, dumbbell_positions - 0.5 * dumbbell_deltax, dumbbell_positions + 0.5 * dumbbell_deltax ]) bead_sizes = np.concatenate([sphere_sizes, dumbbell_sizes, dumbbell_sizes]) c = 1. / (8 * pi * mu) for a1_index, a2_index in [(u, v) for u in xrange(len(bead_sizes)) for v in xrange(u, len(bead_sizes))]: r = -(bead_positions[a2_index] - bead_positions[a1_index]) a1 = bead_sizes[a1_index] a2 = bead_sizes[a2_index] s = norm(r) if s > 1e-8 and 2 * s / (a1 + a2) < 2.001: ss_out = 2.001 * (a1 + a2) / 2 r = np.array( [r[0] * ss_out / s, r[1] * ss_out / s, r[2] * ss_out / s]) s = ss_out if a1_index < num_spheres and a2_index < num_spheres: # Sphere to sphere A_coords = np.s_[a1_index * 3:(a1_index + 1) * 3, a2_index * 3:(a2_index + 1) * 3] Bt_coords = np.s_[a1_index * 3:(a1_index + 1) * 3, 3 * num_spheres + a2_index * 3:3 * num_spheres + (a2_index + 1) * 3] Bt_coords_21 = np.s_[a2_index * 3:(a2_index + 1) * 3, 3 * num_spheres + a1_index * 3:3 * num_spheres + (a1_index + 1) * 3] Gt_coords = np.s_[a1_index * 3:(a1_index + 1) * 3, 6 * num_spheres + a2_index * 5:6 * num_spheres + (a2_index + 1) * 5] Gt_coords_21 = np.s_[a2_index * 3:(a2_index + 1) * 3, 6 * num_spheres + a1_index * 5:6 * num_spheres + (a1_index + 1) * 5] C_coords = np.s_[3 * num_spheres + a1_index * 3:3 * num_spheres + (a1_index + 1) * 3, 3 * num_spheres + a2_index * 3:3 * num_spheres + (a2_index + 1) * 3] Ht_coords = np.s_[3 * num_spheres + a1_index * 3:3 * num_spheres + (a1_index + 1) * 3, 6 * num_spheres + a2_index * 5:6 * num_spheres + (a2_index + 1) * 5] Ht_coords_21 = np.s_[3 * num_spheres + a2_index * 3:3 * num_spheres + (a2_index + 1) * 3, 6 * num_spheres + a1_index * 5:6 * num_spheres + (a1_index + 1) * 5] M_coords = np.s_[6 * num_spheres + a1_index * 5:6 * num_spheres + (a1_index + 1) * 5, 6 * num_spheres + a2_index * 5:6 * num_spheres + (a2_index + 1) * 5] R2Bexact[A_coords] = [[ M11(r[i], r[j], s, a1, a2, i, j, c, mu) for j in xrange(3) ] for i in xrange(3)] R2Bexact[Bt_coords] = [[ M12(r, s, a1, a2, i, j, c, mu) for j in xrange(3) ] for i in xrange(3)] R2Bexact[C_coords] = [[ M22(r, s, a1, a2, i, j, c, mu) for j in xrange(3) ] for i in xrange(3)] R2Bexact[Gt_coords] = [[ con_M13(r, s, a1, a2, i, j, c, mu) for j in xrange(5) ] for i in xrange(3)] R2Bexact[Ht_coords] = [[ con_M23(r, s, a1, a2, i, j, c, mu) for j in xrange(5) ] for i in xrange(3)] R2Bexact[M_coords] = [[ con_M33(r, s, a1, a2, i, j, c, mu) for j in xrange(5) ] for i in xrange(5)] # NOTE Next line - and indeed all 12/21s stuff - is patently false if a1 != a2 if a1 == a2: R2Bexact[Bt_coords_21] = -R2Bexact[Bt_coords] R2Bexact[Gt_coords_21] = -R2Bexact[Gt_coords] R2Bexact[Ht_coords_21] = R2Bexact[Ht_coords] else: R2Bexact[Bt_coords_21] = [[ M12(-r, s, a2, a1, i, j, c, mu) for j in xrange(3) ] for i in xrange(3)] R2Bexact[Gt_coords_21] = [[ con_M13(-r, s, a2, a1, i, j, c, mu) for j in xrange(5) ] for i in xrange(3)] R2Bexact[Ht_coords_21] = [[ con_M23(-r, s, a2, a1, i, j, c, mu) for j in xrange(5) ] for i in xrange(3)] elif a1_index < num_spheres and a2_index >= num_spheres and a2_index < num_spheres + num_dumbbells: # Sphere to dumbbell bead 1 mr = [-r[0], -r[1], -r[2]] a2_index_d = a2_index - num_spheres R14_coords = np.s_[a1_index * 3:(a1_index + 1) * 3, 11 * num_spheres + a2_index_d * 3:11 * num_spheres + (a2_index_d + 1) * 3] R24_coords = np.s_[3 * num_spheres + a1_index * 3:3 * num_spheres + (a1_index + 1) * 3, 11 * num_spheres + a2_index_d * 3:11 * num_spheres + (a2_index_d + 1) * 3] R34_coords = np.s_[6 * num_spheres + a1_index * 5:6 * num_spheres + (a1_index + 1) * 5, 11 * num_spheres + a2_index_d * 3:11 * num_spheres + (a2_index_d + 1) * 3] R2Bexact[R14_coords] = [[ M11(r[i], r[j], s, a1, a2, i, j, c, mu) for j in xrange(3) ] for i in xrange(3)] R2Bexact[R24_coords] = [[ M12(mr, s, a2, a1, j, i, c, mu) for j in xrange(3) ] for i in xrange(3)] R2Bexact[R34_coords] = [[ con_M13(mr, s, a1, a2, j, i, c, mu) for j in xrange(3) ] for i in xrange(5)] elif a1_index < num_spheres and a2_index >= num_spheres + num_dumbbells: # Sphere to dumbbell bead 2 mr = [-r[0], -r[1], -r[2]] a2_index_d = a2_index - num_spheres - num_dumbbells R15_coords = np.s_[a1_index * 3:(a1_index + 1) * 3, 11 * num_spheres + 3 * num_dumbbells + a2_index_d * 3:11 * num_spheres + 3 * num_dumbbells + (a2_index_d + 1) * 3] R25_coords = np.s_[3 * num_spheres + a1_index * 3:3 * num_spheres + (a1_index + 1) * 3, 11 * num_spheres + 3 * num_dumbbells + a2_index_d * 3:11 * num_spheres + 3 * num_dumbbells + (a2_index_d + 1) * 3] R35_coords = np.s_[6 * num_spheres + a1_index * 5:6 * num_spheres + (a1_index + 1) * 5, 11 * num_spheres + 3 * num_dumbbells + a2_index_d * 3:11 * num_spheres + 3 * num_dumbbells + (a2_index_d + 1) * 3] R2Bexact[R15_coords] = [[ M11(r[i], r[j], s, a1, a2, i, j, c, mu) for j in xrange(3) ] for i in xrange(3)] R2Bexact[R25_coords] = [[ M12(mr, s, a2, a1, j, i, c, mu) for j in xrange(3) ] for i in xrange(3)] R2Bexact[R35_coords] = [[ con_M13(mr, s, a1, a2, j, i, c, mu) for j in xrange(3) ] for i in xrange(5)] elif a1_index >= num_spheres and a1_index < num_spheres + num_dumbbells and a2_index >= num_spheres and a2_index < num_spheres + num_dumbbells: # Dumbbell bead 1 to dumbbell bead 1 a1_index_d = a1_index - num_spheres a2_index_d = a2_index - num_spheres if bead_bead_interactions or a1_index_d == a2_index_d: R44_coords = np.s_[11 * num_spheres + a1_index_d * 3:11 * num_spheres + (a1_index_d + 1) * 3, 11 * num_spheres + a2_index_d * 3:11 * num_spheres + (a2_index_d + 1) * 3] R2Bexact[R44_coords] = [[ M11(r[i], r[j], s, a1, a2, i, j, c, mu) for j in xrange(3) ] for i in xrange(3)] elif a1_index >= num_spheres and a1_index < num_spheres + num_dumbbells and a2_index >= num_spheres + num_dumbbells: if bead_bead_interactions: # Dumbbell bead 1 to dumbbell bead 2 a1_index_d = a1_index - num_spheres a2_index_d = a2_index - num_spheres - num_dumbbells R45_coords = np.s_[11 * num_spheres + a1_index_d * 3:11 * num_spheres + (a1_index_d + 1) * 3, 11 * num_spheres + 3 * num_dumbbells + a2_index_d * 3:11 * num_spheres + 3 * num_dumbbells + (a2_index_d + 1) * 3] R2Bexact[R45_coords] = [[ M11(r[i], r[j], s, a1, a2, i, j, c, mu) for j in xrange(3) ] for i in xrange(3)] else: # Dumbbell bead 2 to dumbbell bead 2 a1_index_d = a1_index - num_spheres - num_dumbbells a2_index_d = a2_index - num_spheres - num_dumbbells if bead_bead_interactions or a1_index_d == a2_index_d: R55_coords = np.s_[11 * num_spheres + 3 * num_dumbbells + a1_index_d * 3:11 * num_spheres + 3 * num_dumbbells + (a1_index_d + 1) * 3, 11 * num_spheres + 3 * num_dumbbells + a2_index_d * 3:11 * num_spheres + 3 * num_dumbbells + (a2_index_d + 1) * 3] R2Bexact[R55_coords] = [[ M11(r[i], r[j], s, a1, a2, i, j, c, mu) for j in xrange(3) ] for i in xrange(3)] #symmetrise R2Bexact = np.triu(R2Bexact) + np.triu(R2Bexact, k=1).transpose() # Row and column ops I want are equivalent to doing # [ 1 0 0 ] [ a b c ] [ 1 0 0 ] # [ 0 1/2 1/2 ] . [ d e f ] . [ 0 1/2 -1/2 ] # [ 0 -1/2 1/2 ] [ g h i ] [ 0 1/2 1/2 ] # "L" "R" # I know that we could generate L and R elsewhere rather than doing it every timestep but it takes 0.01s for a few thousand dumbbells so for now I don't mind Lrow = np.array([i for i in xrange(11 * num_spheres + 6 * num_dumbbells)] + [i + 11 * num_spheres for i in xrange(3 * num_dumbbells)] + [ i + 11 * num_spheres + 3 * num_dumbbells for i in xrange(3 * num_dumbbells) ]) Lcol = np.array([i for i in xrange(11 * num_spheres + 6 * num_dumbbells)] + [ i + 11 * num_spheres + 3 * num_dumbbells for i in xrange(3 * num_dumbbells) ] + [i + 11 * num_spheres for i in xrange(3 * num_dumbbells)]) Ldata = np.array([1 for i in xrange(11 * num_spheres)] + [0.5 for i in xrange(9 * num_dumbbells)] + [-0.5 for i in xrange(3 * num_dumbbells)]) L = coo_matrix((Ldata, (Lrow, Lcol)), shape=(11 * num_spheres + 6 * num_dumbbells, 11 * num_spheres + 6 * num_dumbbells)) R = L.transpose() return ((L * R2Bexact * R), "Minfinity")