jaxion 0.0.6__py3-none-any.whl → 0.0.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
jaxion/defaults.json CHANGED
@@ -48,6 +48,10 @@
48
48
  "default": 1.0,
49
49
  "description": "simulation end time [kpc/(km/s)] or [redshift] (cosmology=true)."
50
50
  },
51
+ "safety_factor": {
52
+ "default": 1.0,
53
+ "description": "safety factor for time stepping."
54
+ },
51
55
  "adaptive": {
52
56
  "default": false,
53
57
  "description": "switch on for adaptive time stepping."
@@ -95,6 +99,10 @@
95
99
  "particle_mass": {
96
100
  "default": 1.0,
97
101
  "description": "particle mass [M_sun]."
102
+ },
103
+ "accrete_gas": {
104
+ "default": false,
105
+ "description": "switch on to accrete gas."
98
106
  }
99
107
  },
100
108
  "cosmology": {
jaxion/particles.py CHANGED
@@ -18,7 +18,7 @@ def get_cic_indices_and_weights(pos, dx, resolution):
18
18
  return i, ip1, weight_i, weight_ip1
19
19
 
20
20
 
21
- def bin_particles(pos, dx, resolution, m_particle):
21
+ def bin_particles(pos, m_particles, dx, resolution, multiple_masses):
22
22
  """Bin the particles into the grid using cloud-in-cell weights."""
23
23
  nx = resolution
24
24
  n_particle = pos.shape[0]
@@ -27,6 +27,10 @@ def bin_particles(pos, dx, resolution, m_particle):
27
27
 
28
28
  def deposit_particle(s, rho):
29
29
  """Deposit the particle mass into the grid."""
30
+ if multiple_masses:
31
+ m_particle = m_particles[s]
32
+ else:
33
+ m_particle = m_particles
30
34
  fac = m_particle / (dx * dx * dx)
31
35
  rho = rho.at[i[s, 0], i[s, 1], i[s, 2]].add(
32
36
  w_i[s, 0] * w_i[s, 1] * w_i[s, 2] * fac
@@ -112,3 +116,102 @@ def particles_drift(pos, vel, dt, box_size):
112
116
  pos = jnp.mod(pos, jnp.array([box_size, box_size, box_size]))
113
117
 
114
118
  return pos
119
+
120
+
121
+ def particles_accrete_gas(mass, rho, pos, G, sound_speed, dx, dt):
122
+ """Accrete gas onto particles (Bondi)."""
123
+ n_particle = pos.shape[0]
124
+ resolution = rho.shape[0]
125
+ i, ip1, w_i, w_ip1 = get_cic_indices_and_weights(pos, dx, resolution)
126
+ d_mass = jnp.zeros_like(mass)
127
+ d_rho = jnp.zeros_like(rho)
128
+ lam = jnp.exp(1.5) / 4.0 # ≈ 1.12
129
+ vol = dx**3
130
+
131
+ def accrete(s, deltas):
132
+ """Deposit the particle mass into the grid."""
133
+ d_mass, d_rho = deltas
134
+ dM_fac = dt * 4.0 * jnp.pi * lam * (G * mass[s]) ** 2 / sound_speed**3
135
+ # dM = dM_fac * rho
136
+
137
+ dm = w_i[s, 0] * w_i[s, 1] * w_i[s, 2] * dM_fac * rho[i[s, 0], i[s, 1], i[s, 2]]
138
+ d_rho = d_rho.at[i[s, 0], i[s, 1], i[s, 2]].add(-dm / vol)
139
+ d_mass = d_mass.at[s].add(dm)
140
+
141
+ dm = (
142
+ w_ip1[s, 0]
143
+ * w_i[s, 1]
144
+ * w_i[s, 2]
145
+ * dM_fac
146
+ * rho[ip1[s, 0], i[s, 1], i[s, 2]]
147
+ )
148
+ d_rho = d_rho.at[ip1[s, 0], i[s, 1], i[s, 2]].add(-dm / vol)
149
+ d_mass = d_mass.at[s].add(dm)
150
+
151
+ dm = (
152
+ w_i[s, 0]
153
+ * w_ip1[s, 1]
154
+ * w_i[s, 2]
155
+ * dM_fac
156
+ * rho[i[s, 0], ip1[s, 1], i[s, 2]]
157
+ )
158
+ d_rho = d_rho.at[i[s, 0], ip1[s, 1], i[s, 2]].add(-dm / vol)
159
+ d_mass = d_mass.at[s].add(dm)
160
+
161
+ dm = (
162
+ w_i[s, 0]
163
+ * w_i[s, 1]
164
+ * w_ip1[s, 2]
165
+ * dM_fac
166
+ * rho[i[s, 0], i[s, 1], ip1[s, 2]]
167
+ )
168
+ d_rho = d_rho.at[i[s, 0], i[s, 1], ip1[s, 2]].add(-dm / vol)
169
+ d_mass = d_mass.at[s].add(dm)
170
+
171
+ dm = (
172
+ w_ip1[s, 0]
173
+ * w_ip1[s, 1]
174
+ * w_i[s, 2]
175
+ * dM_fac
176
+ * rho[ip1[s, 0], ip1[s, 1], i[s, 2]]
177
+ )
178
+ d_rho = d_rho.at[ip1[s, 0], ip1[s, 1], i[s, 2]].add(-dm / vol)
179
+ d_mass = d_mass.at[s].add(dm)
180
+
181
+ dm = (
182
+ w_ip1[s, 0]
183
+ * w_i[s, 1]
184
+ * w_ip1[s, 2]
185
+ * dM_fac
186
+ * rho[ip1[s, 0], i[s, 1], ip1[s, 2]]
187
+ )
188
+ d_rho = d_rho.at[ip1[s, 0], i[s, 1], ip1[s, 2]].add(-dm / vol)
189
+ d_mass = d_mass.at[s].add(dm)
190
+
191
+ dm = (
192
+ w_i[s, 0]
193
+ * w_ip1[s, 1]
194
+ * w_ip1[s, 2]
195
+ * dM_fac
196
+ * rho[i[s, 0], ip1[s, 1], ip1[s, 2]]
197
+ )
198
+ d_rho = d_rho.at[i[s, 0], ip1[s, 1], ip1[s, 2]].add(-dm / vol)
199
+ d_mass = d_mass.at[s].add(dm)
200
+
201
+ dm = (
202
+ w_ip1[s, 0]
203
+ * w_ip1[s, 1]
204
+ * w_ip1[s, 2]
205
+ * dM_fac
206
+ * rho[ip1[s, 0], ip1[s, 1], ip1[s, 2]]
207
+ )
208
+ d_rho = d_rho.at[ip1[s, 0], ip1[s, 1], ip1[s, 2]].add(-dm / vol)
209
+ d_mass = d_mass.at[s].add(dm)
210
+
211
+ return d_mass, d_rho
212
+
213
+ d_mass, d_rho = jax.lax.fori_loop(0, n_particle, accrete, (d_mass, d_rho))
214
+ mass = mass + d_mass
215
+ rho = rho + d_rho
216
+
217
+ return mass, rho
jaxion/simulation.py CHANGED
@@ -9,7 +9,12 @@ from .constants import constants
9
9
  from .quantum import quantum_kick, quantum_drift, quantum_velocity
10
10
  from .gravity import calculate_gravitational_potential
11
11
  from .hydro import hydro_fluxes, hydro_accelerate
12
- from .particles import particles_accelerate, particles_drift, bin_particles
12
+ from .particles import (
13
+ particles_accelerate,
14
+ particles_drift,
15
+ particles_accrete_gas,
16
+ bin_particles,
17
+ )
13
18
  from .cosmology import get_supercomoving_time_interval, get_next_scale_factor
14
19
  from .utils import (
15
20
  set_up_parameters,
@@ -95,7 +100,7 @@ class Simulation:
95
100
  xones, static_argnums=0, in_shardings=None, out_shardings=sharding
96
101
  )
97
102
 
98
- # customfunctions
103
+ # custom functions
99
104
  self.custom_kick = None
100
105
  self.custom_drift = None
101
106
  self.custom_density = None
@@ -126,6 +131,11 @@ class Simulation:
126
131
  if self.params["physics"]["particles"]:
127
132
  self.state["pos"] = jnp.zeros((self.num_particles, 3))
128
133
  self.state["vel"] = jnp.zeros((self.num_particles, 3))
134
+ if self.params["particles"]["accrete_gas"]:
135
+ self.state["mass"] = (
136
+ jnp.zeros(self.num_particles)
137
+ + self.params["particles"]["particle_mass"]
138
+ )
129
139
 
130
140
  if load_from_checkpoint:
131
141
  options = ocp.CheckpointManagerOptions()
@@ -262,17 +272,19 @@ class Simulation:
262
272
  if self.params["physics"]["hydro"]:
263
273
  rho_bar += jnp.mean(state["rho"])
264
274
  if self.params["physics"]["particles"]:
265
- m_particle = self.params["particles"]["particle_mass"]
266
- n_particles = self.num_particles
267
275
  box_size = self.box_size
268
- rho_bar += m_particle * n_particles / box_size
276
+ if self.params["particles"]["accrete_gas"]:
277
+ rho_bar += jnp.sum(state["mass"]) / box_size**3
278
+ else:
279
+ m_particle = self.params["particles"]["particle_mass"]
280
+ n_particles = self.num_particles
281
+ rho_bar += m_particle * n_particles / box_size**3
269
282
  if self.custom_density is not None:
270
283
  rho_bar += jnp.mean(self.custom_density(state))
271
284
  return rho_bar
272
285
 
273
286
  def _calc_grav_potential(self, state, k_sq):
274
287
  G = constants["gravitational_constant"]
275
- m_particle = self.params["particles"]["particle_mass"]
276
288
  rho_bar = self._calc_rho_bar(state)
277
289
  rho_tot = 0.0
278
290
  if self.params["physics"]["quantum"]:
@@ -280,7 +292,17 @@ class Simulation:
280
292
  if self.params["physics"]["hydro"]:
281
293
  rho_tot += state["rho"]
282
294
  if self.params["physics"]["particles"]:
283
- rho_tot += bin_particles(state["pos"], self.dx, self.resolution, m_particle)
295
+ multiple_masses = self.params["particles"]["accrete_gas"]
296
+ if multiple_masses:
297
+ m_particles = state["mass"]
298
+ rho_tot += bin_particles(
299
+ state["pos"], m_particles, self.dx, self.resolution, multiple_masses
300
+ )
301
+ else:
302
+ m_particles = self.params["particles"]["particle_mass"]
303
+ rho_tot += bin_particles(
304
+ state["pos"], m_particles, self.dx, self.resolution, multiple_masses
305
+ )
284
306
  if self.custom_density is not None:
285
307
  rho_tot += self.custom_density(state)
286
308
  if self.params["physics"]["cosmology"]:
@@ -319,8 +341,8 @@ class Simulation:
319
341
  num_cells = self.resolution**3
320
342
  m_per_hbar = self.m_per_hbar
321
343
 
322
- dt_fac = 1.0
323
- dt_kin = dt_fac * (m_per_hbar / 6.0) * (dx * dx)
344
+ safety = self.params["time"]["safety_factor"]
345
+ dt_kin = safety * (m_per_hbar / 6.0) * (dx * dx)
324
346
  t_start = self.params["time"]["start"]
325
347
  t_end = self.params["time"]["end"]
326
348
  t_span = t_end - t_start
@@ -332,6 +354,7 @@ class Simulation:
332
354
  use_particles = self.params["physics"]["particles"]
333
355
  use_cosmology = self.params["physics"]["cosmology"]
334
356
  use_external_potential = self.params["physics"]["external_potential"]
357
+ accrete_gas = self.params["particles"]["accrete_gas"]
335
358
  save = self.params["output"]["save"]
336
359
  use_custom = self.custom_kick is not None or self.custom_drift is not None
337
360
  if use_custom:
@@ -435,6 +458,11 @@ class Simulation:
435
458
  state["pos"] = particles_drift(state["pos"], state["vel"], dt, box_size)
436
459
  if use_custom:
437
460
  state = custom_drift(state, k_sq, dt)
461
+ if use_hydro and accrete_gas:
462
+ G = constants["gravitational_constant"]
463
+ state["mass"], state["rho"] = particles_accrete_gas(
464
+ state["mass"], state["rho"], state["pos"], G, c_sound, dx, dt
465
+ )
438
466
 
439
467
  return state
440
468
 
jaxion/visualization.py CHANGED
@@ -82,6 +82,14 @@ def plot_sim(state, checkpoint_dir, i, params):
82
82
  vmax=vmax,
83
83
  extent=[0, nx, 0, nx],
84
84
  )
85
+ if params["physics"]["particles"]:
86
+ # draw particles
87
+ box_size = params["domain"]["box_size"]
88
+ sx = (state["pos"][:, 0] / box_size) * nx
89
+ sy = (state["pos"][:, 1] / box_size) * nx
90
+ plt.plot(
91
+ sx, sy, color="red", marker=".", linestyle="None", markersize=5
92
+ )
85
93
  ax.set_aspect("equal")
86
94
  ax.get_xaxis().set_visible(False)
87
95
  ax.get_yaxis().set_visible(False)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jaxion
3
- Version: 0.0.6
3
+ Version: 0.0.7
4
4
  Summary: A differentiable simulation library for fuzzy dark matter in JAX
5
5
  Author-email: Philip Mocz <philip.mocz@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -2,16 +2,16 @@ jaxion/__init__.py,sha256=Hdji1UQ47lG24Pqcy6UUq9L0-qy6m9Ax41L0vIYzBto,164
2
2
  jaxion/analysis.py,sha256=4YT9Z2dkFoXwft3fQM1HyynVPlIdtRd80VtI2vWTyq4,1568
3
3
  jaxion/constants.py,sha256=HyY2ktKQakv78jD1yQvFdM3sklUJcPgDMYlTsSPQTxI,512
4
4
  jaxion/cosmology.py,sha256=UC1McXNTXGoPRYXn0nI2-csVkJWL-ZBNoCa44oU1b4w,2681
5
- jaxion/defaults.json,sha256=EqFHV9HlLIRvTJrfbT5-AI0GfCLBd0ViwTeUV_B8YIw,2883
5
+ jaxion/defaults.json,sha256=MZraX_f5we3tLKBgpngy5hn0SUVznZkgmNEsGclgNUg,3093
6
6
  jaxion/gravity.py,sha256=2smqy_jjmr0VkMGzLPMYjLahHBMfZ2nNUx0gUiTWcDI,293
7
7
  jaxion/hydro.py,sha256=KoJ02tRpAc4V3Ofzw4zbHLRaE2GdIatbOBE04_LsSRw,6980
8
- jaxion/particles.py,sha256=pMopGvoZ0J_3EviD0WnTMmiebU9h2_8IO-p6I-E5DEU,3980
8
+ jaxion/particles.py,sha256=AD3VlomC_VPOcHalAlZo8kcGFV5pui9tCnKkenm6DxE,7026
9
9
  jaxion/quantum.py,sha256=GWOpN6ipfEw-6Ah2zQpxS3oqeSt_iHMDSgnVYSjXY5E,3321
10
- jaxion/simulation.py,sha256=rxncry9xPAVpohGkLqSo9vft-qaGTnh4f-wKk-A-Y2A,18496
10
+ jaxion/simulation.py,sha256=pr-vXn-4PncGREKUJ8BS7dntMDoG2xiAi_zsJ3FGCnk,19665
11
11
  jaxion/utils.py,sha256=OCpJ3crZqr5VFacymYzi5BkRqFCVBcneoS44wV9mZPg,4087
12
- jaxion/visualization.py,sha256=Vx_xuEE7BB1AkEGaY9KHNSIIDxJzUVT104o-3uglW8o,2966
13
- jaxion-0.0.6.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
14
- jaxion-0.0.6.dist-info/METADATA,sha256=uNykshiiqSIPVw2UM44_zREemfnkaJlGdVqZKyi7X-8,6440
15
- jaxion-0.0.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
16
- jaxion-0.0.6.dist-info/top_level.txt,sha256=S1OV2VdlDG_9UwpKOIji4itQGOS-VWUOWUi3GeXWzt0,7
17
- jaxion-0.0.6.dist-info/RECORD,,
12
+ jaxion/visualization.py,sha256=D0Nr5vhuqxL50MBIPD2ZMOdFDmG6zbCEiH1RemXtn_M,3346
13
+ jaxion-0.0.7.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
14
+ jaxion-0.0.7.dist-info/METADATA,sha256=a7kkiMRk4Gv0FMyEjIFZpnF2nI-5F2Yuvn-5SmZKCxc,6440
15
+ jaxion-0.0.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
16
+ jaxion-0.0.7.dist-info/top_level.txt,sha256=S1OV2VdlDG_9UwpKOIji4itQGOS-VWUOWUi3GeXWzt0,7
17
+ jaxion-0.0.7.dist-info/RECORD,,
File without changes