Skip to content

Commit 2df6fdd

Browse files
Update icbuilder.py
1 parent cece3d2 commit 2df6fdd

File tree

1 file changed

+59
-71
lines changed

1 file changed

+59
-71
lines changed

tools/icbuilder.py

Lines changed: 59 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -344,80 +344,68 @@ def random_solar_system(
344344
particles.append((mx, my, mz, mvx, mvy, mvz, mm, 0))
345345

346346
return particles
347-
348-
def spiral_ic(N, A=1.0, B=1.0, arms=2, mass=1.0, noise=0.02):
347+
348+
def spiral_galaxy_ic(N_disk=3000, N_halo=3000,
349+
disk_mass=1.0, halo_mass=5.0,
350+
_a=10.0,
351+
a=3.0, b=0.3, halo m=2, k=5.0, epsilon=0.07):
349352
"""
350-
Generates baryons along the Ringermacher-Mead spiral:
351-
r(phi) = A * log( B * tan(phi / (2*arms)) )
352-
- N: number of particles
353-
- A, B: spiral parameters
354-
- arms: number of spiral arms
355-
- mass: total mass
356-
- noise: random positional jitter
357-
type = 0 (baryons)
353+
Generates a spiral galaxy with:
354+
- Miyamoto–Nagai=0) with spiral arms disk (baryons, type1)
355+
- N_disk: number of disk particles
356+
- Hernquist halo (DM, type=
357+
- N_halo: number of halo particles
358+
- disk_mass mass
359+
- halo: total baryonic_mass: total DM mass height
360+
- halo_a: Hernquist scale radius
361+
- m: number of spiral arms
362+
- k: spiral
363+
- a, b: disk scale length and pitch parameter
364+
- epsilon: spiral
358365
"""
359-
import math, random
360-
particles = []
361-
count = 0
362-
while count < N:
363-
phi = random.uniform(0.001, math.pi * arms - 0.001)
364-
val = B * math.tan(phi / (2 * arms))
365-
if val <= 0:
366-
continue # skip invalid domain
367-
r = A * math.log(val)
368-
x = r * math.cos(phi) + noise * (random.random() - 0.5)
369-
y = r * math.sin(phi) + noise * (random.random() - 0.5)
370-
z = noise * (random.random() - 0.5)
371-
particles.append((x, y, z, 0, 0, 0, mass / N, 0))
372-
count += 1
373-
return particles
366+
particles perturbation amplitude = []
374367

375-
def spiral_dm_ic(N, A=1.0, B=1.0, arms=2,
376-
mass=1.0, dm_fraction=0.85,
377-
noise=0.02, dm_scale=1.5):
378-
"""
379-
Spiral ICs with baryons (type=0) and DM (type=1) using:
380-
r(phi) = A * log( B * tan(phi / (2*arms)) )
381-
- N: number of baryon particles (DM will also be N)
382-
- A, B: spiral parameters
383-
- arms: number of spiral arms
384-
- mass: total mass (baryons + DM)
385-
- dm_fraction: fraction of mass in dark matter
386-
- noise: positional jitter
387-
- dm_scale: DM radius multiplier (DM more extended)
388-
"""
389-
import math, random
390-
particles = []
391-
M_b = mass * (1 - dm_fraction)
392-
M_dm = mass * dm_fraction
368+
# --- Disk ---
369+
for _ in range(N_disk):
370+
u = random.random()
371+
R = -a * math.log(1 - u)
372+
phi = 2 * math.pi * random.random()
393373

394-
# Baryons
395-
count = 0
396-
while count < N:
397-
phi = random.uniform(0.001, math.pi * arms - 0.001)
398-
val = B * math.tan(phi / (2 * arms))
399-
if val <= 0:
400-
continue
401-
r = A * math.log(val)
402-
x = r * math.cos(phi) + noise * (random.random() - 0.5)
403-
y = r * math.sin(phi) + noise * (random.random() - 0.5)
404-
z = noise * (random.random() - 0.5)
405-
particles.append((x, y, z, 0, 0, 0, M_b / N, 0))
406-
count += 1
407-
408-
# Dark Matter
409-
count = 0
410-
while count < N:
411-
phi = random.uniform(0.001, math.pi * arms - 0.001)
412-
val = B * math.tan(phi / (2 * arms))
413-
if val <= 0:
414-
continue
415-
r = dm_scale * A * math.log(val)
416-
x = r * math.cos(phi) + noise * (random.random() - 0.5)
417-
y = r * math.sin(phi) + noise * (random.random() - 0.5)
418-
z = noise * (random.random() - 0.5)
419-
particles.append((x, y, z, 0, 0, 0, M_dm / N, 1))
420-
count += 1
374+
# Spiral perturbation
375+
* math.cos(m * phi + k * math.log(R R *= 1 + epsilon + 1e-3))
421376

422-
return particles
377+
x = R * math.cos(phi)
378+
y = R * math.sin(phi)
379+
z = random zd = math.gauss(0, b / 2)
380+
381+
.sqrt(z**2 + b**2)
382+
denom = (R**2 + (a + zd.sin(phi)
383+
vy = v_circ * math.cos(phi)
384+
vz = random.gauss)**2)**1.5
385+
v_circ = math.sqrt(disk_mass * R**2 / denom)
386+
387+
vx = -v_circ * math.append((x, y, z(0, 0.05 * v_circ)
388+
389+
particles, vx, vy, vz, disk_mass / N_disk, 0))
423390

391+
# --- Halo ---
392+
for _ in range(N_halo):
393+
u = random.random()
394+
theta = math.ac() - 1)
395+
phi r = halo_a * math.sqrt(u) / (1 - math.sqrt(u))
396+
os(2 * random.random = 2 * math.pi * random.random()
397+
398+
x = r * math.sin(theta) * math.cos(phi)
399+
y = r * math.sin(theta) * math.sin(phi)
400+
z =)
401+
402+
M_enc = halo_mass * ( r * math.cos(thetar**2 / (r + halo_a)**2)
403+
sigma / (2 * (r + 1e-6)))
404+
405+
vx = random.gauss( = math.sqrt(M_enc0, sigma)
406+
vy = random.gauss(0, sigma)
407+
(0, sigma)
408+
409+
((x, y, z, vx, vy vz = random.gauss particles.append, vz, halo_mass / N_halo, 1))
410+
411+
return particles

0 commit comments

Comments
 (0)