def genDMG(n, M=sc.Msgra, R=1, RD=sc.RDmw/sc.RCmw, spherical=False, nDM=0, rho0=1, Rs=10, c=12): """Generate a galaxy (Bodylist) of a massive black hole M and n stars, with initial positions, velocities and masses randomly distributed""" theta = np.random.uniform(0, 2 * np.pi, n) if spherical == True: phi = np.pi/2 - np.random.normal(0,0.1,n) else: phi = np.pi/2 r = rd.radSample(R,RD,n) x = r * np.cos(theta) * np.sin(phi) y = r * np.sin(theta) * np.sin(phi) z = r * np.cos(phi) posarray = np.column_stack((x, y, z)) v = np.sqrt(sc.G*M*(1/r)) v_x = -np.sin(theta) * v v_y = np.cos(theta) * v v_z = np.zeros(n) velarray = np.column_stack((v_x, v_y, v_z)) massarray = md.massSample(n) bodies = [cs.Body3(pos=np.zeros(3), vel=np.zeros(3), mass=M)] for i in range(1,n): bodies.append(cs.Body3(pos=posarray[i], vel=velarray[i], mass=massarray[i])) thetaDM = np.random.uniform(0,2*np.pi,nDM) phiDM = np.random.uniform(0,np.pi,nDM) rDM = DMrd.DMradSample(nDM, rho0, Rs, c) xDM = rDM * np.cos(thetaDM) * np.sin(phiDM) yDM = rDM * np.sin(thetaDM) * np.sin(phiDM) zDM = rDM * np.cos(phiDM) posarrayDM = np.column_stack((xDM, yDM, zDM)) vDM = np.sqrt(sc.G*M*(1/rDM)) v_xDM = -np.sin(thetaDM) * vDM v_yDM = np.cos(thetaDM) * vDM v_zDM = np.zeros(nDM) velarrayDM = np.column_stack((v_xDM, v_yDM, v_zDM)) massarrayDM = 100*md.massSample(nDM) bodiesDM = [] for i in range(0, nDM): bodiesDM.append(cs.Body3(pos=posarrayDM[i], vel=velarrayDM[i], mass=massarrayDM[i])) allbodies = np.concatenate((bodies,bodiesDM)) print(len(allbodies)) return cs.BodyList3(np.array(allbodies))
def genDMGalaxy(n_stars, m_star, m_bh, DM_mass): # masses = np.array([m_bh] + [m_star]*n_stars) # masses = np.array([m_star]*n_stars) masses = np.insert(MassDist.massSample(n_stars), 0, m_bh) r = np.sort(RadDist.radSample(size=n_stars)) theta = np.random.uniform(0, 2 * np.pi, n_stars) x = r * np.cos(theta) y = r * np.sin(theta) z = np.zeros(n_stars) positions = np.column_stack((x, y, z)) r_max = r[-1] norm_const = r_max / sc.RCmw - np.arctan(r_max / sc.RCmw) v_norm = np.sqrt(sc.G * np.cumsum(masses)[:-1] / r + sc.G * DM_mass / r * (r / sc.RCmw - np.arctan(r / sc.RCmw)) / norm_const) plt.plot([sc.RCmw, sc.RCmw], [0, 3e4]) plt.plot(r, v_norm) plt.xlim(0, 2.4e19) plt.ylim(0, 3e4) plt.show() v_unit_vec = np.column_stack( (-np.sin(theta), np.cos(theta), np.zeros(n_stars))) velocities = v_norm.reshape((n_stars, 1)) * v_unit_vec positions = np.insert(positions, 0, np.zeros(3), 0) # add black hole (already present in masses) velocities = np.insert(velocities, 0, -np.sum(velocities * m_star, axis=0) / m_bh, 0) return utils.zip_to_bodylist(positions, velocities, masses)
def genEGalaxy(n,M=sc.Msgra,R=1,RD=sc.RDmw/sc.RCmw,space=False,elliptical=False,spiralarms=1): """Generate a galaxy (Bodylist) of a massive black hole M and n stars, with initial positions, velocities and masses randomly distributed""" massarray = md.massSample(n) if space == True: phi = np.pi/2 - np.random.normal(0,0.1,n) else: phi = np.pi/2 if elliptical == True: spiral = 1 e = 0.5*np.ones(n)+np.random.normal(0,0.005,n) else: spiral = 0 e = np.zeros(n) r = rd.radSample(n,R,RD) for i in range(len(r)): if r[i] <= sc.RCmw: theta = np.random.uniform(0,2*np.pi,n) else: theta = (1-spiral) * np.random.uniform(0, 2 * np.pi, n) + spiral * (-2*np.pi*r/np.amax(r)+np.pi/10*np.random.normal(0,1,n)+np.pi*np.random.randint(0,2,n)) a = r/(1+e) x = r * np.cos(theta) * np.sin(phi) y = r * np.sin(theta) * np.sin(phi) z = r * np.cos(phi) posarray = np.column_stack((x, y, z)) plt.scatter(x,y) plt.show() v = np.sqrt(sc.G*(M+massarray)*(2/r-1/a)) v_x = -np.sin(theta) * v v_y = np.cos(theta) * v v_z = np.zeros(n) velarray = np.column_stack((v_x, v_y, v_z)) plt.scatter(v_x, v_y) plt.show() bodies = [cs.Body3(pos=np.zeros(3), vel=np.zeros(3), mass=M)] for i in range(1,n): bodies.append(cs.Body3(pos=posarray[i], vel=velarray[i], mass=massarray[i])) return cs.BodyList3(np.array(bodies))
# plt.xlim(0, 2.4e19) # plt.ylim(0, 3e4) # plt.show() v_unit_vec = np.column_stack((-np.sin(theta), np.cos(theta), np.zeros(n_stars))) velocities = v_norm.reshape((n_stars, 1)) * v_unit_vec positions = np.insert(positions, 0, np.zeros(3), 0) # add black hole (already present in masses) momentum = velocities*np.expand_dims(m_stars, axis=1) velocities = np.insert(velocities, 0, np.zeros(3), 0) # -np.sum(momentum, axis=0)/m_bh, 0) return utils.zip_to_bodylist(positions, velocities, masses), r, v_norm thetamax = 0.7 n_steps = 5000 n_stars = 10000 # m_star = sc.Msol # 3.181651515706176e+30 m_stars = MassDist.massSample(n_stars) print(sum(m_stars)/len(m_stars)) m_BH = sc.Msgra # / 1e4 mass_ratio = (sc.Mlummw - m_BH)/sum(m_stars) print(mass_ratio) m_stars = mass_ratio*m_stars m_DM = (np.sum(m_stars) + m_BH)*5 galaxy, r_, vnorm = genDMGalaxy(10000, m_stars, m_BH, m_DM) result = cs.LeapFrogSaveC(galaxy, dt=1e12, n_steps=1, thetamax=thetamax, G=sc.G, save_every=1, epsilon=4e18, DM_mass=m_DM).numpy() r = utils.get_positions(result) r = np.linalg.norm(r[0], axis=1) g = utils.get_vec_attribute(result, 'g') plt.subplot(1,2,1)
def create_galaxy(n_stars, n_DM_particles, visible_mass, DM_mass, BH_mass, R, R_bulge, R_halo, thetamax=0.7, spherical=True, epsilon=4e16, factor=0.8, random_DM=True): # generate particle masses m_stars = md.massSample(n_stars) print('mass_ratio =', visible_mass / sum(m_stars)) m_stars = m_stars * visible_mass / sum(m_stars) DM_mass = np.sum(m_stars) * DM_mass / visible_mass m_DM = np.ones(n_DM_particles) * DM_mass / n_DM_particles # generate positions of visible matter theta = np.random.uniform(0, 2 * np.pi, n_stars) r = np.sort( rd.radSample(size=n_stars, r_char=R / 5, r_bulge=R_bulge, rad_min=R_bulge / 20)) x = r * np.cos(theta) y = r * np.sin(theta) if spherical: alpha = R_bulge * (0.05 + 0.4 / (1 + (r / R_bulge)**2.5)) z = np.random.uniform(-alpha, alpha, n_stars) else: z = np.zeros(n_stars) posarray = np.column_stack((x, y, z)) # generate positions of dark matter thetaDM = np.random.uniform(0, 2 * np.pi, n_DM_particles) phiDM = np.arccos(np.random.uniform(-1, 1, n_DM_particles)) rDM = DMrd.PIradSample(n_DM_particles, R_bulge, R_halo) xDM = rDM * np.cos(thetaDM) * np.sin(phiDM) yDM = rDM * np.sin(thetaDM) * np.sin(phiDM) zDM = rDM * np.cos(phiDM) posarrayDM = np.column_stack((xDM, yDM, zDM)) # generate dummy for determining initial velocity norms dummy = gen_dummy(posarray, posarrayDM, m_stars, m_DM, BH_mass) # result = cs.LeapFrogSaveC(dummy, dt=0, n_steps=1, thetamax=thetamax, G=sc.G, save_every=1, epsilon=epsilon).numpy() # g = np.linalg.norm(utils.get_vec_attribute(result, 'g')[0], axis=1)[1:] cs.acceleratedAccelerationsC(dummy, thetamax=thetamax, G=sc.G, epsilon=epsilon) g = np.linalg.norm([b.g for b in dummy], axis=1)[1:] v_norm_vis = np.sqrt(r * g[0:n_stars]) v_norm_DM = np.sqrt(rDM * g[n_stars:]) # calculate velocity vector for visible matter v_unit_vec_vis = np.column_stack( (-np.sin(theta), np.cos(theta), np.zeros(n_stars))) velocities_vis = v_norm_vis.reshape((n_stars, 1)) * v_unit_vec_vis # calculate velocity vector for dark matter if random_DM: gamma = np.random.uniform(0, 2 * np.pi, n_DM_particles) v_unit_vec_DM = [] for i, pos in enumerate(posarrayDM): b1 = np.array([pos[2], 0, -pos[0]]) b1 /= np.linalg.norm(b1) b2 = np.array([0, pos[2], -pos[1]]) b2 /= np.linalg.norm(b2) attenuation_z = (abs(pos[2]) / np.linalg.norm(pos))**0.5 v_unit_vec_DM.append( np.array([1, 1, factor**(1 - attenuation_z)]) * (np.cos(gamma[i]) * b1 + np.sin(gamma[i]) * b2)) else: v_unit_vec_DM = np.column_stack( (-np.sin(thetaDM), np.cos(thetaDM), np.zeros(n_DM_particles))) v_unit_vec_DM = np.array(v_unit_vec_DM) velocities_DM = v_norm_DM.reshape((n_DM_particles, 1)) * v_unit_vec_DM return gen_galaxy(posarray, posarrayDM, m_stars, m_DM, BH_mass, velocities_vis, velocities_DM)
dark_matter=True)) allbodies = np.concatenate((bodies, bodiesDM)) print(len(allbodies)) return cs.BodyList3(np.array(allbodies)) print('start') thetamax = 0.7 n_steps = 15000 save_steps = 5000 n_stars = 3000 n_DM_particles = 3000 m_stars = md.massSample(n_stars) m_stars = m_stars * sc.Mlummw / sum(m_stars) DM_mass = np.sum(m_stars) * 5 m_DM = np.ones(n_DM_particles) * DM_mass / n_DM_particles spherical = True theta = np.random.uniform(0, 2 * np.pi, n_stars) if spherical == True: phi = np.pi / 2 - np.random.normal(0, 0.1, n_stars) else: phi = np.pi / 2 r = np.sort(rd.radSample(size=n_stars, rad_min=sc.RCmw / 20)) x = r * np.cos(theta) * np.sin(phi) y = r * np.sin(theta) * np.sin(phi) z = r * np.cos(phi)