コード例 #1
0
ファイル: p3m.py プロジェクト: pec27/lizard
def _grid_accel_deriv(pos, wts, vel, fft_wts, log):
    """ Accel and rate of change on the grid using the given FFT weights """
    pos = array(pos)
    fft_size = fft_wts.shape[0]
    # extra fft_size so that finite difference is grad (dx = 1/fft_size)
    nwts = array(wts) * fft_size

    print('Doing {:,}^3 CIC'.format(fft_size), file=log)
    # momenta in grid coords
    if isscalar(nwts):
        mom = vel * nwts * fft_size
    else:
        mom = vel * reshape(nwts, (len(nwts), 1)) * fft_size

    cic = get_cic(pos * fft_size, fft_size, mass=nwts, mom=mom)
    print('Total mass on grid %3e. Doing FFT of weights.' % cic.sum().real,
          file=log)
    modes = fftn(cic)
    print(MU.OKBLUE + 'Inverse {:,}^3 FFT'.format(fft_size) + MU.ENDC,
          file=log)
    pot_times_n = ifftn(modes * fft_wts)  # imaginary part contains dpot/dt
    print('Gradient via finite-differences of accel', file=log)
    acc = gradient_5pt_3d(pot_times_n.real)  # dx = 1/ngrid
    print('Gradient for da/dt', file=log)
    da_dt = gradient_5pt_3d(pot_times_n.imag)  # dx = 1/ngrid
    print('RMS and maximum', file=log)
    rms_acc = (3 * square(acc).mean())**0.5
    max_da_dt = square(da_dt).sum(3).max()**0.5
    if max_da_dt <= 0:
        raise Exception(
            'Zero acceleration rate => zero vel or floating point problem?')
    dt_est = rms_acc / max_da_dt
    return dt_est, acc, da_dt
コード例 #2
0
ファイル: p3m.py プロジェクト: pec27/lizard
def test_grad(mode):
    """
    Plot acceleration split into long and short range split
    """
    import sys
    ngrid = 64
    r_fine = 6.0 / ngrid

    fs = get_force_split(r_fine, mode=mode)  # 'cubic', 'quartic'

    fft_wts = fs.get_fft_wts(sys.stdout)
    kernel = ifftn(fft_wts).real
    acc = sqrt(square(gradient_5pt_3d(kernel) * ngrid).sum(3).ravel())

    import numpy as np

    import pylab as pl
    from lizard.grid import make_k_values
    r = make_k_values(1.0, ngrid)[1]
    r *= 1.0 / (ngrid * 2 * pi)
    #    pl.semilogy(r.ravel(),abs(kernel.ravel()), 'k,')
    pl.semilogy(r.ravel(), acc, 'k,')
    pl.axvline(r_fine, c='k', ls=':')

    acc_from_pp = fs.get_kernel(
        1e-3, 200)  # these are multipliers that you multiply by r
    r = (arange(len(acc_from_pp)) + 1) * r_fine / len(acc_from_pp)
    acc_from_pp = 1 / (r * r) + (acc_from_pp * r)  #- 1/(r*r)
    pl.semilogy(r, acc_from_pp, 'b')

    r = np.linspace(r_fine, 0.75**0.5, 200)
    acc_cubic_mid = -1.0 / (r * r)  # + (4*r*r_coarse - 3*r*r)/(r_coarse**4)
    pl.semilogy(r, abs(acc_cubic_mid), 'g')
    pl.show()
コード例 #3
0
ファイル: p3m.py プロジェクト: pec27/lizard
def test_inter():

    ngrid = 96
    r_fine = 6.0 / ngrid
    r_coarse = 40.0 / ngrid
    fft_wts = _inter_cubic_fft_wts(ngrid, r_coarse, r_fine)

    kernel = ifftn(fft_wts).real
    acc = sqrt(square(gradient_5pt_3d(kernel) * ngrid).sum(3).ravel())

    import pylab as pl
    #    pl.imshow(kernel[0])

    from lizard.grid import make_k_values
    r = make_k_values(1.0, ngrid)[1]
    r *= 1.0 / (ngrid * 2 * pi)
    #    pl.semilogy(r.ravel(),abs(kernel.ravel()), 'k,')
    pl.semilogy(r.ravel(), acc, 'k,')
    pl.axvline(r_fine, c='k', ls=':')
    pl.axvline(r_coarse, c='k', ls=':')

    acc_from_pp = _newton_soft_cubic_kernel(
        r_fine, None, 200)  # these are multipliers that you multiply by r
    r = (arange(len(acc_from_pp)) + 1) * r_fine / len(acc_from_pp)
    acc_from_pp = abs(acc_from_pp * r + 1 / (r * r))
    pl.semilogy(r, acc_from_pp)
    import numpy as np
    r = np.linspace(r_fine, r_coarse, 200)
    acc_cubic_mid = -1.0 / (r * r) + (4 * r * r_coarse - 3 * r * r) / (r_coarse
                                                                       **4)
    pl.semilogy(r, abs(acc_cubic_mid))
    pl.show()
コード例 #4
0
ファイル: p3m.py プロジェクト: pec27/lizard
def _inter_pm_accel(pos,
                    wts,
                    topleft,
                    width,
                    fft_wts,
                    idx_nonghosts,
                    ncell_ghost,
                    log,
                    ncell_grad=2):
    """ Force on the grid using the given FFT weights """

    fft_size = fft_wts.shape[0]
    grid_pos = array(pos) - topleft
    grid_pos = (fft_size / width) * (grid_pos - floor(grid_pos))
    print('Isolated PM force on {:,} grid'.format(fft_size), file=log)
    # Check ghosts are far enough from boundary to avoid periodic effects
    ghost_range = ncell_grad // 2
    if grid_pos.min() < ghost_range or grid_pos.max() > fft_size - ghost_range:
        print('Grid pos in',
              grid_pos.min(axis=0),
              grid_pos.max(axis=0),
              file=log)

        raise Exception('Ghosts too close to boundary to be isolated')

    print('Doing {:,}^3 CIC'.format(fft_size), file=log)
    cic = get_cic(grid_pos, fft_size, wts)
    print('Total mass on grid %3f. Doing FFT of weights.' % cic.sum(),
          file=log)
    modes = fftn(cic)
    print('Inverse {:,}^3 FFT'.format(fft_size), file=log)
    pot = ifftn(modes * fft_wts).real
    print('Gradient via finite-differences', file=log)

    clip = int(
        ncell_ghost
    ) - ncell_grad  # Clip off boundaries that were only used for ghosts & gradients
    scale = fft_size / (
        width * width
    )  # dx = 1/ngrid, then because we scaled all the positions, we diluted the r^-2 force, need to rescale back
    pot = pot[clip:-clip, clip:-clip, clip:-clip] * scale
    accel_grid = gradient_5pt_3d(pot)

    pos_ng = grid_pos[idx_nonghosts] - clip
    print('interpolating {:,} points'.format(len(pos_ng)), file=log)
    if pos_ng.min() < 0.0 or pos_ng.max() > fft_size - 2 * clip:
        print('Grid pos non-ghost in',
              pos_ng.min(axis=0),
              pos_ng.max(axis=0),
              file=log)
        raise Exception(
            'Real particles outside central region of isolated grid')

    return interp_vec3(accel_grid, pos_ng)
コード例 #5
0
ファイル: p3m.py プロジェクト: pec27/lizard
def _grid_accel(pos, wts, fft_wts, log):
    """ Acceleration on PM grid using the given FFT weights """

    fft_size = fft_wts.shape[0]
    npos = array(pos) * fft_size
    print('Doing {:,}^3 CIC'.format(fft_size), file=log)
    # extra fft_size in wts to make finite difference the grad (dx = 1/fft_size)
    wts = array(wts) * fft_size
    cic = get_cic(npos, fft_size, wts)
    print('Total mass on grid %3f. Doing FFT of weights.' % cic.sum(),
          file=log)
    modes = fftn(cic)
    print(MU.OKBLUE + 'Inverse {:,}^3 FFT'.format(fft_size) + MU.ENDC,
          file=log)
    npot = ifftn(modes * fft_wts).real  # potential * fft_size
    print('Gradient via finite-differences', file=log)
    grad = gradient_5pt_3d(npot)
    print('interpolating {:,} points'.format(len(pos)), file=log)
    accel_long = interp_vec3(grad, npos)
    return accel_long