@@ -348,42 +348,48 @@ def random_solar_system(
348348def miyamoto_nagai_galaxy (
349349 N_disk = 5000 ,
350350 N_halo = 8000 ,
351+ N_bulge = 2000 ,
351352 M_disk = 1.0 ,
352353 M_halo = 5.0 ,
353- a = 3.0 ,
354- b = 0.5 ,
355- halo_scale = 20.0
354+ M_bulge = 0.5 ,
355+ a = 3.0 , # MN radial scale
356+ b = 0.5 , # MN vertical scale
357+ halo_scale = 20.0 ,
358+ bulge_scale = 0.5 ,
359+ spiral_m = 2 , # number of arms
360+ spiral_eps = 0.06 ,
361+ spiral_k = 4.0
356362):
357363 """
358- Miyamoto–Nagai disk + Hernquist DM halo.
364+ Miyamoto–Nagai disk + Hernquist bulge + Hernquist DM halo.
359365 Returns particles in format:
360- (x, y, z, vx, vy, vz, mass, type)
361- type=0 -> disk (baryons )
362- type=1 -> dark matter
366+ (x, y, z, vx, vy, vz, mass, type)
367+ type=0 -> baryons (disk + bulge )
368+ type=1 -> dark matter (halo)
363369 """
364-
365370 import random , math
366371 particles = []
367372
368373 # -------------------------
369- # 1. Disk ( Miyamoto–Nagai)
374+ # 1. Disk — Miyamoto–Nagai
370375 # -------------------------
371376 for _ in range (N_disk ):
372-
373- # Sample radius from exponential-like distribution
377+ # radius sampling (exponential-like)
374378 u = random .random ()
375379 R = - a * math .log (1 - u )
376-
377380 phi = 2 * math .pi * random .random ()
378381 z = random .gauss (0 , b )
379382
380- x = R * math .cos (phi )
381- y = R * math .sin (phi )
383+ # spiral arm perturbation
384+ Rp = R * (1 + spiral_eps * math .cos (spiral_m * phi + spiral_k * math .log (R + 1e-6 )))
385+
386+ x = Rp * math .cos (phi )
387+ y = Rp * math .sin (phi )
382388
383389 # MN circular velocity
384390 B = math .sqrt (z * z + b * b )
385- denom = math .sqrt (R * R + (a + B )** 2 )
386- v_circ = math .sqrt (M_disk * R * R / (denom ** 3 + 1e-6 ))
391+ denom = math .sqrt (Rp * Rp + (a + B )** 2 )
392+ v_circ = math .sqrt (M_disk * Rp * Rp / (denom ** 3 + 1e-6 ))
387393
388394 vx = - v_circ * math .sin (phi )
389395 vy = v_circ * math .cos (phi )
@@ -392,10 +398,32 @@ def miyamoto_nagai_galaxy(
392398 particles .append ((x , y , z , vx , vy , vz , M_disk / N_disk , 0 ))
393399
394400 # -------------------------
395- # 2. Halo ( Hernquist)
401+ # 2. Bulge — Hernquist (baryons )
396402 # -------------------------
397- for _ in range (N_halo ):
403+ for _ in range (N_bulge ):
404+ u = random .random ()
405+ r = bulge_scale * math .sqrt (u ) / (1 - math .sqrt (u ))
398406
407+ theta = math .acos (2 * random .random () - 1 )
408+ phi = 2 * math .pi * random .random ()
409+
410+ x = r * math .sin (theta ) * math .cos (phi )
411+ y = r * math .sin (theta ) * math .sin (phi )
412+ z = r * math .cos (theta )
413+
414+ M_enc = M_bulge * (r * r / (r + bulge_scale )** 2 )
415+ sigma = math .sqrt (M_enc / (2 * (r + 1e-6 )))
416+
417+ vx = random .gauss (0 , sigma )
418+ vy = random .gauss (0 , sigma )
419+ vz = random .gauss (0 , sigma )
420+
421+ particles .append ((x , y , z , vx , vy , vz , M_bulge / N_bulge , 0 ))
422+
423+ # -------------------------
424+ # 3. Halo — Hernquist (DM)
425+ # -------------------------
426+ for _ in range (N_halo ):
399427 u = random .random ()
400428 r = halo_scale * math .sqrt (u ) / (1 - math .sqrt (u ))
401429
@@ -406,7 +434,6 @@ def miyamoto_nagai_galaxy(
406434 y = r * math .sin (theta ) * math .sin (phi )
407435 z = r * math .cos (theta )
408436
409- # isotropic dispersion
410437 M_enc = M_halo * (r * r / (r + halo_scale )** 2 )
411438 sigma = math .sqrt (M_enc / (2 * (r + 1e-6 )))
412439
0 commit comments