def main(): from pyphare.cpp import cpp_lib cpp = cpp_lib() from pyphare.pharesee.run import Run from pyphare.pharesee.hierarchy import flat_finest_field config() Simulator(gv.sim).run() if cpp.mpi_rank() == 0: vphi, t, phi, a, k = phase_speed(".", 0.01, 1000) r = Run(".") t = get_times_from_h5("EM_B.h5") fig, ax = plt.subplots(figsize=(9, 5), nrows=1) B = r.GetB(t[int(len(t) / 2)]) by, xby = flat_finest_field(B, "By") ax.plot(xby, by, label="t = 500", alpha=0.6) sorted_patches = sorted(B.patch_levels[1].patches, key=lambda p: p.box.lower[0]) x0 = sorted_patches[0].patch_datas["By"].x[0] x1 = sorted_patches[-1].patch_datas["By"].x[-1] B = r.GetB(t[-1]) by, xby = flat_finest_field(B, "By") ax.plot(xby, by, label="t = 1000", alpha=0.6) ax.plot(xby, wave(xby, 0.01, 2 * np.pi / 1000., 2 * np.pi / 1000 * 500), color="k", ls="--", label="T=500 (theory)") B = r.GetB(t[0]) by, xby = flat_finest_field(B, "By") ax.plot(xby, by, label="t = 0", color="k") ax.set_xlabel("x") ax.set_ylabel(r"$B_y$") ax.legend(ncol=4, loc="upper center") ax.set_ylim((-0.012, 0.013)) ax.set_title(r"$V_\phi = {:6.4f}$".format(vphi.mean())) ax.axvspan(x0, x1, alpha=0.2) fig.tight_layout() fig.savefig("alfven_wave.png", dpi=200) assert np.mean(np.abs(vphi - 1) < 5e-2)
def energies(path, kkind="iso"): """ This loops over all times of a given run and return the magnetic and kinetic energy as a function of time. """ r = Run(path) times = get_times_from_h5(r.path+"/EM_B.h5") Bnrj = np.zeros_like(times) K = np.zeros_like(times) for it,t in enumerate(times): B = r.GetB(t) protons = r.GetParticles(t, "protons") Bnrj[it] = mag_energy(B) K[it] = total_kinetic(protons,kind=kkind) return r, Bnrj, K, times
def growth_b_right_hand(run_path): file = os.path.join(run_path, "EM_B.h5") times = get_times_from_h5(file) r = Run(run_path) first_mode = np.array([]) from scipy.optimize import curve_fit for time in times: B_hier = r.GetB(time, merged=True, interp="linear") by_interpolator, xyz_finest = B_hier["By"] bz_interpolator, xyz_finest = B_hier["Bz"] # remove the last point so that "x" is periodic wo. last point = first point x = xyz_finest[0][:-1] by = by_interpolator(x) bz = by_interpolator(x) # get the mode 1, as it is the most unstable in a box of length 33 mode1 = np.absolute(np.fft.fft(by-1j*bz)[1]) first_mode = np.append(first_mode, mode1) popt, pcov = curve_fit(yaebx, times, first_mode, p0=[0.08, 0.09]) # now the signal is stripped from its exponential part damped_mode=first_mode*yaebx(times, 1/popt[0], -popt[1]) # find the omega for which "damped_mode" is the largest : # this term is twice the one it should be because "mode1" resulting from # an absolute value, this (cosx)^2 = cos(2x) then appears at the 2nd # harmonoic (hence the factor 0.5 to get "omega") # the factor "+1" is because we remove the DC component, so the value # given by argmax has also to miss this value omegas = np.fabs(np.fft.fft(damped_mode).real) omega = 0.5*(omegas[1:omegas.size//2].argmax()+1)*2*np.pi/times[-1] print(omegas[0:6]) print(omegas[1:omegas.size//2].argmax()) print(2*np.pi/times[-1]) print(0.5*(omegas[1:omegas.size//2].argmax()+1)*2*np.pi/times[-1]) return times, first_mode, popt[0], popt[1], damped_mode, omega
def phase_speed(run_path, ampl, xmax): from scipy.signal import medfilt from scipy.optimize import curve_fit import os time = get_times_from_h5(os.path.join(run_path, "EM_B.h5")) r = Run(run_path) phase = np.zeros_like(time) amplitude = np.zeros_like(time) wave_vec = np.zeros_like(time) for it, t in enumerate(time): B = r.GetB(t) by, xby = finest_field(B, "By") a, k, phi = curve_fit(wave, xby, by, p0=(ampl, 2 * np.pi / xmax, 0))[0] phase[it] = phi amplitude[it] = a wave_vec[it] = k vphi = medfilt(np.gradient(phase, time) / wave_vec, kernel_size=7) return vphi, time, phase, amplitude, wave_vec
def make_figure(): from scipy.optimize import curve_fit from pyphare.pharesee.hierarchy import finest_field rwT = Run("./withTagging") rNoRef = Run("./noRefinement") plot_time = 11 v = 2 BwT = rwT.GetB(plot_time) BNoRef = rNoRef.GetB(plot_time) JwT = rwT.GetJ(plot_time) JNoRef = rNoRef.GetJ(plot_time) bywT, xbywT = finest_field(BwT, "By") byNoRef, xbyNoRef = finest_field(BNoRef, "By") jzwT, xjzwT = finest_field(JwT, "Jz") jzNoRef, xjzNoRef = finest_field(JNoRef, "Jz") fig, axarr = plt.subplots(nrows=3, figsize=(8, 8)) def S(x, x0, l): return 0.5 * (1 + np.tanh((x - x0) / l)) def by(x): L = 200 v1 = -1 v2 = 1 return v1 + (v2 - v1) * (S(x, L * 0.25, 1) - S(x, L * 0.75, 1)) wT0 = 150. ax0, ax1, ax2 = axarr ax0.plot(xbywT, bywT) ax0.plot(xbyNoRef, byNoRef, color="k", alpha=0.6) ax0.plot(xbyNoRef, by(xbyNoRef), ls='--') ax1.plot(xbywT, bywT) ax1.plot(xbyNoRef, byNoRef, color='k') ax1.set_xlim((wT0, 195)) ax1.set_ylim((-1.5, 2)) ax2.plot(xjzwT, jzwT) ax2.plot(xjzNoRef, jzNoRef, color='k') ax2.set_xlim((wT0, 195)) ax2.set_ylim((-1.5, 0.5)) # draw level patches for ilvl, level in BwT.levels().items(): for patch in level.patches: dx = patch.layout.dl[0] x0 = patch.origin[0] x1 = (patch.box.upper[0] + 1) * patch.layout.dl[0] for ax in (ax1, ax2, ax0): ax.axvspan(x0, x1, color='b', ec='k', alpha=0.2, ymin=ilvl / 4, ymax=(ilvl + 1) / 4) from pyphare.pharesee.plotting import zoom_effect zoom_effect(ax0, ax1, wT0, 195) for ax in (ax0, ax1, ax2): ax.axvline(wT0 + plot_time * v, color="r") # select data around the rightward TD idx = np.where((xbywT > 150) & (xbywT < 190)) xx = xbywT[idx] bby = bywT[idx] # now we will fit by_fit to the data # and we expect to find x0=172 and L=1 # or close enough def by_fit(x, x0, L): v1 = 1 v2 = -1 return v1 + (v2 - v1) * S(x, x0, L) popt, pcov = curve_fit(by_fit, xx, bby, p0=(150, 1)) x0, L = popt if np.abs(L - 1) > 0.5: raise RuntimeError(f"L (={L}) too far from 1.O") if np.abs(x0 - (150 + plot_time * v)) > 0.5: raise RuntimeError(f"x0 (={x0}) too far from 172")
def finest_field_plot(run_path, qty, **kwargs): """ plot the given quantity (qty) at 'run_path' with only the finest data * run_path : the path of the run * qty : ['Bx', 'By', 'Bz', 'Ex', 'Ey', 'Ez', 'Fx', 'Fy', 'Fz', 'Vx', 'Vy', 'Vz', 'rho'] kwargs: * ax : the handle for the fig axes * time : time (that should be in the time_stamps of the run) * interp : the type of interpolation for the interpolator * draw_style : steps-mid ou default... only for 1d * title : (str) title of the plot * xlabel, ylabel * xlim, ylim * filename : (str) if exists, save plot to figure under that name return value : fig,ax """ import os from pyphare.pharesee.hierarchy import get_times_from_h5 from pyphare.pharesee.run import Run from mpl_toolkits.axes_grid1 import make_axes_locatable import pyphare.core.gridlayout as gridlayout r = Run(run_path) time = kwargs.get("time", None) dim = r.GetDl('finest', time).shape[0] interp = kwargs.get("interp", "nearest") domain = r.GetDomainSize() if qty in ['Bx', 'By', 'Bz']: file = os.path.join(run_path, "EM_B.h5") if time is None: times = get_times_from_h5(file) time = times[0] interpolator, finest_coords = r.GetB(time, merged=True,\ interp=interp)[qty] elif qty in ['Ex', 'Ey', 'Ez']: file = os.path.join(run_path, "EM_E.h5") if time is None: times = get_times_from_h5(file) time = times[0] interpolator, finest_coords = r.GetE(time, merged=True,\ interp=interp)[qty] elif qty in ['Vx', 'Vy', 'Vz']: file = os.path.join(run_path, "ions_bulkVelocity.h5") if time is None: times = get_times_from_h5(file) time = times[0] interpolator, finest_coords = r.GetVi(time, merged=True,\ interp=interp)[qty] elif qty == 'rho': file = os.path.join(run_path, "ions_density.h5") if time is None: times = get_times_from_h5(file) time = times[0] interpolator, finest_coords = r.GetNi(time, merged=True,\ interp=interp)[qty] elif qty in ("Jx", "Jy", "Jz"): file = os.path.join(run_path, "EM_B.h5") if time is None: times = get_times_from_h5(file) time = times[0] interpolator, finest_coords = r.GetJ(time, merged=True,\ interp=interp)[qty] else: # ___ TODO : should also include the files for a given population raise ValueError( "qty should be in ['Bx', 'By', 'Bz', 'Ex', 'Ey', 'Ez', 'Fx', 'Fy', 'Fz', 'Vx', 'Vy', 'Vz', 'rho']" ) if "ax" not in kwargs: fig, ax = plt.subplots() else: ax = kwargs["ax"] fig = ax.figure if dim == 1: drawstyle = kwargs.get("drawstyle", "steps-mid") ax.plot(finest_coords[0], interpolator(finest_coords[0]),\ drawstyle=drawstyle) elif dim == 2: x = finest_coords[0] y = finest_coords[1] dx = x[1] - x[0] dy = y[1] - y[0] # pcolormesh considers DATA_ij to be the center of the pixel # and X,Y are the corners so XY need to be made 1 value larger # and shifted around DATA_ij x -= dx / 2 x = np.append(x, x[-1] + dx) y -= dy / 2 y = np.append(y, y[-1] + dy) X, Y = np.meshgrid(x, y) DATA = interpolator(X, Y) vmin = kwargs.get("vmin", np.nanmin(DATA)) vmax = kwargs.get("vmax", np.nanmax(DATA)) cmap = kwargs.get("cmap", 'Spectral_r') im = ax.pcolormesh(x, y, DATA, cmap=cmap, vmin=vmin, vmax=vmax) ax.set_aspect("equal") divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.08) cb = plt.colorbar(im, ax=ax, cax=cax) else: raise ValueError("finest_field_plot not yet ready for 3d") ax.set_title(kwargs.get("title", "")) ax.set_xlabel(kwargs.get("xlabel", "$x c / \omega_p$")) ax.set_ylabel(kwargs.get("ylabel", "$y c / \omega_p$")) if "xlim" in kwargs: ax.set_xlim(kwargs["xlim"]) if "ylim" in kwargs: ax.set_ylim(kwargs["ylim"]) if "filename" in kwargs: fig.savefig(kwargs["filename"]) return fig, ax
def test_restarts(self, dim, interp, simInput): print(f"test_restarts dim/interp:{dim}/{interp}") simput = copy.deepcopy(simInput) for key in ["cells", "dl", "boundary_types"]: simput[key] = [simput[key]] * dim if "refinement" not in simput: b0 = [[10 for i in range(dim)], [19 for i in range(dim)]] simput["refinement_boxes"] = {"L0": {"B0": b0}} else: # https://github.com/LLNL/SAMRAI/issues/199 # tagging can handle more than one timestep as it does not # appear subject to regridding issues, so we make more timesteps # to confirm simulations are still equivalent simput["time_step_nbr"] = 10 # if restart time exists it "loads" from restart file # otherwise just saves restart files based on timestamps assert "restart_time" not in simput["restart_options"] simput["interp_order"] = interp time_step = simput["time_step"] time_step_nbr = simput["time_step_nbr"] restart_idx = 4 restart_time = time_step * restart_idx timestamps = [time_step * restart_idx, time_step * time_step_nbr] # first simulation local_out = f"{out}/test/{dim}/{interp}/mpi_n/{cpp.mpi_size()}/id{self.ddt_test_id()}" simput["restart_options"]["dir"] = local_out simput["diag_options"]["options"]["dir"] = local_out ph.global_vars.sim = None ph.global_vars.sim = ph.Simulation(**simput) assert "restart_time" not in ph.global_vars.sim.restart_options model = setup_model() dump_all_diags(model.populations, timestamps=np.array(timestamps)) Simulator(ph.global_vars.sim).run().reset() self.register_diag_dir_for_cleanup(local_out) diag_dir0 = local_out # second restarted simulation local_out = f"{local_out}_n2" simput["diag_options"]["options"]["dir"] = local_out simput["restart_options"]["restart_time"] = restart_time ph.global_vars.sim = None ph.global_vars.sim = ph.Simulation(**simput) assert "restart_time" in ph.global_vars.sim.restart_options model = setup_model() dump_all_diags(model.populations, timestamps=np.array(timestamps)) Simulator(ph.global_vars.sim).run().reset() self.register_diag_dir_for_cleanup(local_out) diag_dir1 = local_out def check(qty0, qty1, checker): checks = 0 for ilvl, lvl0 in qty0.patch_levels.items(): patch_level1 = qty1.patch_levels[ilvl] for p_idx, patch0 in enumerate(lvl0): patch1 = patch_level1.patches[p_idx] for pd_key, pd0 in patch0.patch_datas.items(): pd1 = patch1.patch_datas[pd_key] self.assertNotEqual(id(pd0), id(pd1)) checker(pd0, pd1) checks += 1 return checks def check_particles(qty0, qty1): return check( qty0, qty1, lambda pd0, pd1: self.assertEqual(pd0.dataset, pd1.dataset)) def check_field(qty0, qty1): return check( qty0, qty1, lambda pd0, pd1: np.testing.assert_equal( pd0.dataset[:], pd1.dataset[:])) def count_levels_and_patches(qty): n_levels = len(qty.patch_levels) n_patches = 0 for ilvl, lvl in qty.patch_levels.items(): n_patches += len(qty.patch_levels[ilvl].patches) return n_levels, n_patches n_quantities_per_patch = 20 pops = model.populations for time in timestamps: checks = 0 run0 = Run(diag_dir0) run1 = Run(diag_dir1) checks += check_particles(run0.GetParticles(time, pops), run1.GetParticles(time, pops)) checks += check_field(run0.GetB(time), run1.GetB(time)) checks += check_field(run0.GetE(time), run1.GetE(time)) checks += check_field(run0.GetNi(time), run1.GetNi(time)) checks += check_field(run0.GetVi(time), run1.GetVi(time)) for pop in pops: checks += check_field(run0.GetFlux(time, pop), run1.GetFlux(time, pop)) checks += check_field(run0.GetN(time, pop), run1.GetN(time, pop)) n_levels, n_patches = count_levels_and_patches(run0.GetB(time)) self.assertEqual(n_levels, 2) # at least 2 levels self.assertGreaterEqual(n_patches, n_levels) # at least one patch per level self.assertEqual(checks, n_quantities_per_patch * n_patches)
def main(): import os import subprocess import glob import shlex for interp_order in (1, 2, 3): config(interp_order) Simulator(gv.sim).run() if cpp.mpi_rank() == 0: from pyphare.pharein.global_vars import sim from pyphare.pharesee.run import Run dt = 10 * sim.time_step nt = sim.final_time / dt + 1 times = dt * np.arange(nt) r = Run("shock_{}".format(interp_order)) for it, t in enumerate(times): fig, ax = plt.subplots() B = r.GetB(t, merged=True) title = "interp order {} - t = {:06.3f}".format( interp_order, t) x = B["By"][1][0] By = B["By"][0] ax.plot(x, By(x), color="k") ax.set_title(title) ax.set_ylim((-0.2, 5)) ax.set_xlim((0, 250)) fig.savefig("shock_{}/shock_By_{}_{:04d}.png".format( interp_order, interp_order, it)) plt.close(fig) cmd = shlex.split( "ffmpeg -r 10 -y -pattern_type glob -i 'shock_{}/shock_By_{}_*.png' -c:v libx264 -crf 0 shock_interp{}.mp4" .format(interp_order, interp_order, interp_order)) subprocess.call(cmd) gv.sim = None pngs = glob.glob("shock*/*.png") for png in pngs: os.remove(png) if cpp.mpi_rank() == 0: from pyphare.pharein.global_vars import sim from pyphare.pharesee.run import Run t = 30 runs = [Run(f"shock_{i+1}") for i in range(3)] fig, ax = plt.subplots() colors = ["k", "r", "b"] for r, color, interp_order in zip(runs, colors, (1, 2, 3)): print(r.path) B = r.GetB(t, merged=True) x = B["By"][1][0] By = B["By"][0] ax.plot(x, By(x), color=color, label=f"interp order {interp_order}") title = "interp order {} - t = {:06.3f}".format(interp_order, t) ax.set_title(title) ax.set_ylim((-0.2, 5)) ax.set_xlim((0, 250)) ax.legend() fig.savefig("shock_By.png")