|
1 | | -Tutorial 5: Multiple GPUs |
| 1 | +Tutorial 5: Custom Fields |
2 | 2 | ========================= |
3 | 3 |
|
4 | | -TODO XXX |
| 4 | +This tutorial describes how to create custom quantum dark matter fields in Jaxion simulations. |
| 5 | +An example is provided in `examples/two_field <https://github.com/JaxionProject/jaxion/tree/main/examples/two_field>`_ |
| 6 | + |
| 7 | +First, ``params["physics"]["quantum"]`` should be set to ``False`` since we will be adding out own fields. |
| 8 | + |
| 9 | +For example, to create a two-field simulation, we can add the simulation states: |
| 10 | +``sim.state["psi1"]`` and ``sim.state["psi2"]``. |
| 11 | + |
| 12 | +Then, we need to define custom kick, drift, and total density functions, and attach them to the simulation object: |
| 13 | + |
| 14 | +.. code-block:: python |
| 15 | +
|
| 16 | + def custom_density(state): |
| 17 | + return jnp.abs(state["psi1"]) ** 2 + jnp.abs(state["psi2"]) ** 2 |
| 18 | +
|
| 19 | + def custom_kick(state, V, dt): |
| 20 | + state["psi1"] = jnp.exp(-1j * m1_per_hbar * dt * V) * state["psi1"] |
| 21 | + state["psi2"] = jnp.exp(-1j * m2_per_hbar * dt * V) * state["psi2"] |
| 22 | +
|
| 23 | + return state |
| 24 | +
|
| 25 | + def custom_drift(state, k_sq, dt): |
| 26 | + psi1_hat = jd.fft.pfft3d(state["psi1"]) |
| 27 | + psi1_hat = jnp.exp(dt * (-1.0j * k_sq / m1_per_hbar / 2.0)) * psi1_hat |
| 28 | + state["psi1"] = jd.fft.pifft3d(psi1_hat) |
| 29 | +
|
| 30 | + psi2_hat = jd.fft.pfft3d(state["psi2"]) |
| 31 | + psi2_hat = jnp.exp(dt * (-1.0j * k_sq / m2_per_hbar / 2.0)) * psi2_hat |
| 32 | + state["psi2"] = jd.fft.pifft3d(psi2_hat) |
| 33 | +
|
| 34 | + return state |
| 35 | +
|
| 36 | + sim.custom_density = custom_density |
| 37 | + sim.custom_kick = custom_kick |
| 38 | + sim.custom_drift = custom_drift |
| 39 | +
|
| 40 | +In this example, the custom density function is used to compute the total density from both fields. |
| 41 | +The custom kick and drift functions are used to update the fields during the simulation. |
| 42 | + |
| 43 | +The simulation can then be run as usual with ``sim.run()``. |
| 44 | + |
| 45 | +It is also possible to add custom plotting for these fields by defining a custom plotting function and attaching it to the simulation object: |
| 46 | +``custom_plot(state, checkpoint_dir, i, params)``. |
| 47 | + |
| 48 | +The Two-Field example evolves two quantum fields with different masses that interact gravitationally, and looks something like this: |
| 49 | + |
| 50 | +.. figure:: ../../examples/two_field/rho1_070.png |
| 51 | + :width: 300px |
| 52 | + :align: center |
| 53 | + :alt: two_field field 1 |
| 54 | + |
| 55 | +.. figure:: ../../examples/two_field/rho2_070.png |
| 56 | + :width: 300px |
| 57 | + :align: center |
| 58 | + :alt: two_field field 2 |
0 commit comments