예제 #1
0
def mass_inside(R, clusrx, clusry, clusrz, density, cellsrx, cellsry, cellsrz,
                npatch, size, nmax):
    """
        Computes the mass inside a radius R sphere centered on (clusrx, clusry, clusrz), from the density field.
        Note that user can either supply:
            - Comoving density and comoving size (most common)
            - Physical density and physical size

        Args:
            R: radius of the considered sphere
            clusrx, clusry, clusrz: comoving coordinates of the center of the sphere
            density: density field, already cleaned from refinements and overlaps (but not masked!)
            cellsrx, cellsry, cellsrz: position fields
            npatch: number of patches in each level, starting in l=0
            size: comoving size of the simulation box
            nmax: cells at base level

        Returns:
            Field containing the mask as described.
    """
    levels = tools.create_vector_levels(npatch)
    cells_volume = (size / nmax / 2**levels)**3

    if np.isnan(R):
        R = 0

    mask = mask_sphere(R, clusrx, clusry, clusrz, cellsrx, cellsry, cellsrz)

    cellmasses = [d * m * cv for d, m, cv in zip(density, mask, cells_volume)]
    mass = sum([cm.sum() for cm in cellmasses])

    return mass
예제 #2
0
def compute_position_fields(patchnx,
                            patchny,
                            patchnz,
                            patchrx,
                            patchry,
                            patchrz,
                            npatch,
                            size,
                            nmax,
                            ncores=1):
    """
    Returns 3 fields (as usually defined) containing the x, y and z position for each of our cells centres.
    Args:
        patchnx, patchny, patchnz: x-extension of each patch (in level l cells) (and Y and Z)
        patchrx, patchry, patchrz: physical position of the center of each patch first ¡l-1! cell
        (and Y and Z)
        npatch: number of patches in each level, starting in l=0
        size: comoving size of the simulation box
        nmax: cells at base level
        ncores:

    Returns:
        3 fields as described above
    """
    levels = tools.create_vector_levels(npatch)
    if ncores == 1 or ncores == 0 or ncores is None:
        cellsrx = []
        cellsry = []
        cellsrz = []
        for ipatch in range(npatch.sum() + 1):
            patches = compute_position_field_onepatch(
                (patchnx[ipatch], patchny[ipatch], patchnz[ipatch],
                 patchrx[ipatch], patchry[ipatch], patchrz[ipatch],
                 levels[ipatch], size, nmax))
            cellsrx.append(patches[0])
            cellsry.append(patches[1])
            cellsrz.append(patches[2])
    else:
        with Pool(ncores) as p:
            positions = p.map(
                compute_position_field_onepatch,
                [(patchnx[ipatch], patchny[ipatch], patchnz[ipatch],
                  patchrx[ipatch], patchry[ipatch], patchrz[ipatch],
                  levels[ipatch], size, nmax)
                 for ipatch in range(len(patchnx))])

        cellsrx = [p[0] for p in positions]
        cellsry = [p[1] for p in positions]
        cellsrz = [p[2] for p in positions]

    return cellsrx, cellsry, cellsrz
예제 #3
0
def load_grids(it, path='', digits=5):
    """
    This function creates a list of dictionaries containing the information requiered for yt's load_amr_grids
    to build the grid structure of a simulations performed by MASCLET.

    Args:
        it: iteration number (int)
        path: path of the grids file in the system (str)
        digits: number of digits the filename is written with (int)

    Returns:
        grid_data: list of dictionaries, each containing the information about one refinement patch (left_edge,
        right_edge, level and dimensions [number of cells])
        bbox: bounds of the simulation box in physical coordinates (typically Mpc or kpc)

    """
    nmax, nmay, nmaz, nlevels, namrx, namry, namrz, size = parameters.read_parameters(load_npalev=False)
    irr, t, nl, mass_dmpart, zeta, npatch, npart, patchnx, patchny, patchnz, patchx, patchy, patchz, pare = \
        read_masclet.read_grids(it, path=path, read_patchposition=False, digits=digits)

    # l=0 (whole box)
    grid_data = [dict(left_edge=[-size / 2, -size / 2, -size / 2],
                      right_edge=[size / 2, size / 2, size / 2],
                      level=0,
                      dimensions=[nmax, nmay, nmaz])]

    levels = tools.create_vector_levels(npatch)
    left = np.array([tools.find_absolute_real_position(i, size, nmax, npatch, patchx, patchy, patchz, pare) for i in
                     range(1, levels.size)])
    left = np.vstack([[-size / 2, -size / 2, -size / 2], left])
    right = left + np.array([patchnx / 2 ** levels, patchny / 2 ** levels, patchnz / 2 ** levels]).transpose()[:, :] \
        * size / nmax

    for i in range(1, levels.size):
        grid_data.append(dict(left_edge=left[i, :].tolist(),
                              right_edge=right[i, :].tolist(),
                              level=levels[i],
                              dimensions=[patchnx[i], patchny[i], patchnz[i]]))

    bbox = np.array([[-size / 2, size / 2], [-size / 2, size / 2], [-size / 2, size / 2]])

    return grid_data, bbox
예제 #4
0
def several_radial_profiles_vw(fields,
                               clusrx,
                               clusry,
                               clusrz,
                               rmin,
                               rmax,
                               nbins,
                               logbins,
                               cellsrx,
                               cellsry,
                               cellsrz,
                               cr0amr,
                               solapst,
                               npatch,
                               size,
                               nmax,
                               up_to_level=1000,
                               verbose=False):
    """
    Computes a (volume-weighted) radial profile of the quantity given in the "field" argument, taking center in
    (clusrx, clusry, clusrz).

    Args:
        fields: set of fields (already cleaned) whose profile wants to be got
        clusrx, clusry, clusrz: comoving coordinates of the center for the profile
        rmin: starting radius of the profile
        rmax: final radius of the profile
        nbins: number of points for the profile
        logbins: if False, radial shells are spaced linearly. If True, they're spaced logarithmically. Not that, if
                 logbins = True, rmin cannot be 0.
        cellsrx, cellsry, cellsrz: position fields
        cr0amr: field containing the refinements of the grid (1: not refined; 0: refined)
        solapst: field containing the overlaps (1: keep; 0: not keep)
        npatch: number of patches in each level, starting in l=0
        size: comoving size of the simulation box
        nmax: cells at base level
        up_to_level: maximum AMR level to be considered for the profile
        verbose: if True, prints the patch being opened at a time

    Returns:
        Two lists. One of them contains the center of each radial cell. The other contains the value of the field
        averaged across all the cells of the shell.

    """
    # getting the bins
    try:
        assert (rmax > rmin)
    except AssertionError:
        print('You would like to input rmax > rmin...')
        return

    if logbins:
        try:
            assert (rmin > 0)
        except AssertionError:
            print('Cannot use rmin=0 with logarithmic binning...')
            return
        bin_bounds = np.logspace(np.log10(rmin), np.log10(rmax), nbins + 1)

    else:
        bin_bounds = np.linspace(rmin, rmax, nbins + 1)

    bin_centers = (bin_bounds[1:] + bin_bounds[:-1]) / 2

    # finding the volume-weighted mean
    levels = tools.create_vector_levels(npatch)
    cell_volume = (size / nmax / 2**levels)**3

    fields_vw = [[f * cv for f, cv in zip(field, cell_volume)]
                 for field in fields]

    if rmin > 0:
        cells_outer = mask_sphere(rmin, clusrx, clusry, clusrz, cellsrx,
                                  cellsry, cellsrz)
    else:
        cells_outer = [
            np.zeros(patch.shape, dtype='bool') for patch in fields[0]
        ]

    profiles = []
    for r_out in bin_bounds[1:]:
        if verbose:
            print('Working at outer radius {} Mpc'.format(r_out))
        cells_inner = cells_outer
        cells_outer = mask_sphere(r_out, clusrx, clusry, clusrz, cellsrx,
                                  cellsry, cellsrz)
        shell_mask = [
            inner ^ outer for inner, outer in zip(cells_inner, cells_outer)
        ]
        shell_mask = tools.clean_field(shell_mask,
                                       cr0amr,
                                       solapst,
                                       npatch,
                                       up_to_level=up_to_level)
        sum_vw = sum([(sm * cv).sum()
                      for sm, cv in zip(shell_mask, cell_volume)])

        profile_thisr = [
            (sum([(fvw * sm).sum()
                  for fvw, sm in zip(field_vw, shell_mask)]) / sum_vw)
            for field_vw in fields_vw
        ]

        profiles.append(profile_thisr)

    profiles = np.asarray(profiles)
    profiles_split = tuple([profiles[:, i] for i in range(profiles.shape[1])])

    return bin_centers, profiles_split