def test_rfftn(self):
        force = np.zeros([2 * r for r in self.res])

        force[:self.res[0], :self.res[1]] = np.random.random(self.res)
        from muFFT import FFT
        ref = rfftn(force.T).T
        fftengine = FFT([2 * r for r in self.res], fft="serial")
        fftengine.create_plan(1)
        tested = np.zeros(fftengine.nb_fourier_grid_pts,
                          order='f',
                          dtype=complex)
        fftengine.fft(force, tested)
        np.testing.assert_allclose(ref.real, tested.real)
        np.testing.assert_allclose(ref.imag, tested.imag)
Exemple #2
0
def test_save_and_load(comm):
    nb_grid_pts = (128, 128)
    size = (3, 3)

    np.random.seed(1)
    t = fourier_synthesis(nb_grid_pts, size, 0.8, rms_slope=0.1, unit='µm')

    fft = FFT(nb_grid_pts, communicator=comm, fft="mpi")
    fft.create_plan(1)
    dt = t.domain_decompose(fft.subdomain_locations,
                            fft.nb_subdomain_grid_pts,
                            communicator=comm)
    assert t.unit == 'µm'
    assert dt.unit == 'µm'
    assert t.info['unit'] == 'µm'
    assert dt.info['unit'] == 'µm'
    if comm.size > 1:
        assert dt.is_domain_decomposed

    # Save file
    dt.to_netcdf('parallel_save_test.nc')

    # Attempt to open full file on each MPI process
    t2 = read_topography('parallel_save_test.nc')

    assert t.physical_sizes == t2.physical_sizes
    assert t.unit == t2.unit
    assert t.info['unit'] == t2.info['unit']
    np.testing.assert_array_almost_equal(t.heights(), t2.heights())

    # Attempt to open file in parallel
    r = NCReader('parallel_save_test.nc', communicator=comm)

    assert r.channels[0].nb_grid_pts == nb_grid_pts

    t3 = r.topography(subdomain_locations=fft.subdomain_locations,
                      nb_subdomain_grid_pts=fft.nb_subdomain_grid_pts)

    assert t.physical_sizes == t3.physical_sizes
    assert t.unit == t3.unit
    assert t.info['unit'] == t3.info['unit']
    np.testing.assert_array_almost_equal(dt.heights(), t3.heights())

    assert t3.is_periodic

    comm.barrier()
    if comm.rank == 0:
        os.remove('parallel_save_test.nc')
Exemple #3
0
def test_sineWave_disp(comm, pnp, nx, ny, basenpoints):
    """
    for given sinusoidal displacements, compares the pressures and the energies
    to the analytical solutions

    Special cases at the edges of the fourier domain are done

    Parameters
    ----------
    comm
    pnp
    fftengine_class
    nx
    ny
    basenpoints

    Returns
    -------

    """
    nx += basenpoints
    ny += basenpoints
    sx = 2.45  # 30.0
    sy = 1.0

    # equivalent Young's modulus
    E_s = 1.0

    for k in [(1, 0), (0, 1), (1, 2), (nx // 2, 0), (1, ny // 2), (0, 2),
              (nx // 2, ny // 2), (0, ny // 2)]:
        # print("testing wavevector ({}* np.pi * 2 / sx,
        # {}* np.pi * 2 / sy) ".format(*k))
        qx = k[0] * np.pi * 2 / sx
        qy = k[1] * np.pi * 2 / sy
        q = np.sqrt(qx**2 + qy**2)

        Y, X = np.meshgrid(
            np.linspace(0, sy, ny + 1)[:-1],
            np.linspace(0, sx, nx + 1)[:-1])
        disp = np.cos(qx * X + qy * Y) + np.sin(qx * X + qy * Y)

        refpressure = -disp * E_s / 2 * q

        substrate = PeriodicFFTElasticHalfSpace((nx, ny),
                                                E_s, (sx, sy),
                                                fft='mpi',
                                                communicator=comm)
        fftengine = FFT((nx, ny), fft='mpi', communicator=comm)
        fftengine.create_plan(1)

        kpressure = substrate.evaluate_k_force(
            disp[substrate.subdomain_slices]) / substrate.area_per_pt / (nx *
                                                                         ny)
        expected_k_disp = np.zeros((nx // 2 + 1, ny), dtype=complex)
        expected_k_disp[k[0], k[1]] += .5 - .5j

        # add the symetrics
        if k[0] == 0:
            expected_k_disp[0, -k[1]] += .5 + .5j
        if k[0] == nx // 2 and nx % 2 == 0:
            expected_k_disp[k[0], -k[1]] += .5 + .5j

        fft_disp = np.zeros(substrate.nb_fourier_grid_pts,
                            order='f',
                            dtype=complex)
        fftengine.fft(disp[substrate.subdomain_slices], fft_disp)
        np.testing.assert_allclose(fft_disp / (nx * ny),
                                   expected_k_disp[substrate.fourier_slices],
                                   rtol=1e-7,
                                   atol=1e-10)

        expected_k_pressure = -E_s / 2 * q * expected_k_disp
        np.testing.assert_allclose(
            kpressure,
            expected_k_pressure[substrate.fourier_slices],
            rtol=1e-7,
            atol=1e-10)

        computedpressure = substrate.evaluate_force(
            disp[substrate.subdomain_slices]) / substrate.area_per_pt
        np.testing.assert_allclose(computedpressure,
                                   refpressure[substrate.subdomain_slices],
                                   atol=1e-10,
                                   rtol=1e-7)

        computedenergy_kspace = \
            substrate.evaluate(disp[substrate.subdomain_slices], pot=True,
                               forces=False)[0]
        computedenergy = \
            substrate.evaluate(disp[substrate.subdomain_slices], pot=True,
                               forces=True)[0]
        refenergy = E_s / 8 * 2 * q * sx * sy

        # print(substrate.nb_domain_grid_pts[-1] % 2)
        # print(substrate.nb_fourier_grid_pts)
        # print(substrate.fourier_locations[-1] +
        # substrate.nb_fourier_grid_pts[-1] - 1)
        # print(substrate.nb_domain_grid_pts[-1] // 2 )
        # print(computedenergy)
        # print(computedenergy_kspace)
        # print(refenergy)
        np.testing.assert_allclose(
            computedenergy,
            refenergy,
            rtol=1e-10,
            err_msg="wavevektor {} for nb_domain_grid_pts {}, "
            "subdomain nb_grid_pts {}, nb_fourier_grid_pts {}".format(
                k, substrate.nb_domain_grid_pts,
                substrate.nb_subdomain_grid_pts,
                substrate.nb_fourier_grid_pts))
        np.testing.assert_allclose(
            computedenergy_kspace,
            refenergy,
            rtol=1e-10,
            err_msg="wavevektor {} for nb_domain_grid_pts {}, "
            "subdomain nb_grid_pts {}, nb_fourier_grid_pts {}".format(
                k, substrate.nb_domain_grid_pts,
                substrate.nb_subdomain_grid_pts,
                substrate.nb_fourier_grid_pts))