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)
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')
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))