.. _fields: Generating 3D Cluster Fields ---------------------------- Most of the functionality of ``cluster_generator`` assumes spherical symmetry for each cluster, and thus most applications can work with 1D models which can be mapped onto either grid cells, particles, or used of their own accord. However, for initializing the complex magnetic and velocity fields which exist in clusters for use in (magneto)hydrodynamical simulations, a full 3D implementation is required. Mathematical Overview ===================== Magnetic and velocity fields in clusters are assumed to be complex and turbulent. If one wants to include these fields in a simulation of a single cluster or a merger of clusters, these will have to be computed in a three-dimensional fashion, which is done on a uniform grid. Then, the field values will need to be interpolated onto the hydro cells or particles, depending on the nature of the code in question. A generic turbulent 3D field :math:`{\bf V}({\bf r})` can be generated by .. math:: \tilde{V_x}({\bf k}) = V_1(k)[N(u_1) + iN(u_2)] \\ \tilde{V_y}({\bf k}) = V_2(k)[N(u_3) + iN(u_4)] \\ \tilde{V_z}({\bf k}) = V_3(k)[N(u_5) + iN(u_6)] Magnetic fields require more special handling, due to the constraint that :math:`\nabla \cdot {\bf B} = 0`. The field that is generated using the above procedure in general has at least some divergence. In :math:`{\bf k}`-space, the zero-divergence condition corresponds to :math:`{\bf k} \cdot {\bf \tilde{B}} = 0`, so the divergence of the field can be removed by subtracting off the component of :math:`\tilde{\bf B}` parallel to :math:`{\bf k}`: .. math:: \tilde{\bf B} := \tilde{\bf B} - \hat{\bf k}(\hat{\bf k} \cdot {\bf \tilde{B}}) This results in zero divergence (to machine precision) on the uniform grid. If the resulting magnetic field is linearly interpolated at a later stage onto grid cells or particles, in general this linear interpolation will not be divergence-free, but will have a small divergence. If your MHD code implements divergence cleaning, this may not be a substantial concern. However, for codes using constrained transport to evolve the magnetic field on an AMR grid (e.g. FLASH, GAMER, Athena++), it is necessary to preserve the divergence-free condition on a generic grid structure. The best way to do this is to derive the magnetic vector potential :math:`{\bf A}`: .. math:: {\bf B} = \nabla \times {\bf A} \\ \tilde{\bf B} = {\bf k} \times \tilde{\bf A} Given :math:`\tilde{\bf B}`, :math:`\tilde{\bf A}` can be solved for in :math:`{\bf k}`-space and can then be transformed to :math:`{\bf A}`. Initializing a Magnetic Field ============================= Random Magnetic Fields and Vector Potentials ++++++++++++++++++++++++++++++++++++++++++++ Radial Random Magnetic Fields and Vector Potentials +++++++++++++++++++++++++++++++++++++++++++++++++++ Initializing a Velocity Field ============================= Random Velocity Fields ++++++++++++++++++++++ Radial Random Velocity Fields +++++++++++++++++++++++++++++ .. _map_field_to_particles: Mapping a Field to Particles ============================ A :class:`~cluster_generator.fields.ClusterField` object can have its field mapped to a set of particles at given positions using the :meth:`~cluster_generator.fields.ClusterField.map_field_to_particles` method. This takes as input a :class:`~cluster_generator.particles.ClusterParticles` object, and optional arguments for the particle type and the units to set the new particle field to: .. code-block:: python # parts is a ClusterParticles object ptype = "gas" # the default units = "km/s" # the default value is the already assigned units for # the field vfield.map_field_to_particles(parts, ptype=ptype, units=units) Writing a Field Out to Disk =========================== A :class:`~cluster_generator.fields.ClusterField` object can be written to disk using the :meth:`~cluster_generator.fields.ClusterField.write_to_h5` method. .. code-block:: python bfields.write_to_h5("bfield.h5")